Version 0.4.2.0 .

svn merge -r 19417:20113 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@20121 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/README b/README
index 3619ce6..9b18a3f 100644
--- a/README
+++ b/README
@@ -3,7 +3,8 @@
 
 For license information, please see LICENSE.
 
-You can find more about Dart online at dartlang.org or code.google.com/p/dart.
+You can find more about Dart online at http://dartlang.org or
+http://code.google.com/p/dart.
 
 Here's a brief guide to what's in here:
 
diff --git a/compiler/dartium.gyp b/compiler/dartium.gyp
index 3be681b..83a32e9 100644
--- a/compiler/dartium.gyp
+++ b/compiler/dartium.gyp
@@ -6,8 +6,6 @@
 # into the dartium build.
 {
   'includes': [
-    # TODO(iposva): Move shared gyp setup to a shared location.
-    '../tools/gyp/xcode.gypi',
     # TODO(mmendez): Add the appropriate gypi includes here.
   ],
   'targets': [
diff --git a/compiler/java/com/google/dart/compiler/CommandLineOptions.java b/compiler/java/com/google/dart/compiler/CommandLineOptions.java
index 6d11bbc..0e3ed28 100644
--- a/compiler/java/com/google/dart/compiler/CommandLineOptions.java
+++ b/compiler/java/com/google/dart/compiler/CommandLineOptions.java
@@ -36,6 +36,10 @@
         usage = "Format errors as normal or machine")
     private String errorFormat = "";
     
+    @Option(name = "--machine", //
+    usage = "Print errors in a format suitable for parsing")
+    private boolean machineFormat = false;
+    
     @Option(name = "--extended-exit-code",
         usage = "0 - clean; 1 - has warnings; 2 - has errors")
     private boolean extendedExitCode = false;
@@ -262,10 +266,16 @@
      * @return the format to use for printing errors
      */
     public ErrorFormat printErrorFormat() {
+      if (machineFormat) {
+        return ErrorFormat.MACHINE;
+      }
+      
       String lowerError = errorFormat.toLowerCase();
+      
       if ("machine".equals(lowerError)) {
         return ErrorFormat.MACHINE;
       }
+      
       return ErrorFormat.NORMAL;
     }
   }
diff --git a/compiler/java/com/google/dart/compiler/PackageLibraryManager.java b/compiler/java/com/google/dart/compiler/PackageLibraryManager.java
index 9a6dd3e..ddd5d8f 100644
--- a/compiler/java/com/google/dart/compiler/PackageLibraryManager.java
+++ b/compiler/java/com/google/dart/compiler/PackageLibraryManager.java
@@ -207,7 +207,12 @@
     shortUri = getRelativeUri(uri);
     if (shortUri != null){
       try {
-        return new URI(null, null, shortUri.getScheme() + ":" +  shortUri.getHost() + shortUri.getPath(),null, null);
+        if (shortUri.getHost() != null){
+          return new URI(null, null, shortUri.getScheme() + ":" +  shortUri.getHost() + shortUri.getPath(),null, null);
+        }
+        else {
+          return new URI(null, null, shortUri.getScheme() + ":" +  shortUri.getSchemeSpecificPart(), null, null);
+        }
       } catch (URISyntaxException e) {
       }
     }
diff --git a/compiler/java/com/google/dart/compiler/UrlLibrarySource.java b/compiler/java/com/google/dart/compiler/UrlLibrarySource.java
index e762294..27fce70 100644
--- a/compiler/java/com/google/dart/compiler/UrlLibrarySource.java
+++ b/compiler/java/com/google/dart/compiler/UrlLibrarySource.java
@@ -35,7 +35,7 @@
     }
     try {
       // Force the creation of an escaped relative URI to deal with spaces, etc.
-      URI uri = getImportBaseUri().resolve(new URI(null, null, relPath, null, null)).normalize();
+      URI uri = getUri().resolve(new URI(null, null, relPath, null, null)).normalize();
       String path = uri.getPath();
       // Resolve relative reference out of one system library into another
       if (PackageLibraryManager.isDartUri(uri)) {
@@ -69,7 +69,7 @@
     }
     try {
       // Force the creation of an escaped relative URI to deal with spaces, etc.
-      URI uri = getImportBaseUri().resolve(new URI(null, null, relPath, null, null)).normalize();
+      URI uri = getUri().resolve(new URI(null, null, relPath, null, null)).normalize();
       if (PackageLibraryManager.isPackageUri(uri)) {
         URI fileUri = packageLibraryManager.resolveDartUri(uri);
         if (fileUri != null) {
@@ -121,13 +121,4 @@
     String path = uri.getPath();
     return path == null || new File(path).exists();
   }
-
-  /**
-   * @return the {@link URI} to use as a base for resolving imports. Usually same as {@link #getUri()},
-   * but in case of Dart code in HTML may be mapped {@link URI}.
-   */
-  protected URI getImportBaseUri() {
-    return getUri();
-  }
-
 }
diff --git a/compiler/java/com/google/dart/compiler/ast/ASTNodes.java b/compiler/java/com/google/dart/compiler/ast/ASTNodes.java
index 88a322f..2e3b87f 100644
--- a/compiler/java/com/google/dart/compiler/ast/ASTNodes.java
+++ b/compiler/java/com/google/dart/compiler/ast/ASTNodes.java
@@ -21,7 +21,6 @@
 import com.google.dart.compiler.resolver.ElementKind;
 import com.google.dart.compiler.resolver.FieldElement;
 import com.google.dart.compiler.resolver.MethodElement;
-import com.google.dart.compiler.resolver.NodeElement;
 import com.google.dart.compiler.resolver.VariableElement;
 import com.google.dart.compiler.type.InterfaceType;
 import com.google.dart.compiler.type.Type;
@@ -196,7 +195,7 @@
    *         {@link DartIdentifier} is the field reference, or <code>null</code> in the other case.
    */
   public static FieldElement getFieldElement(DartIdentifier node) {
-    NodeElement element = node.getElement();
+    Element element = node.getElement();
     if (ElementKind.of(element) == ElementKind.FIELD) {
       return (FieldElement) element;
     }
@@ -867,7 +866,7 @@
    *         other case.
    */
   public static VariableElement getVariableElement(DartIdentifier node) {
-    NodeElement element = node.getElement();
+    Element element = node.getElement();
     if (ElementKind.of(element) == ElementKind.VARIABLE) {
       return (VariableElement) element;
     }
@@ -880,7 +879,7 @@
    *         local variable or parameter, or <code>null</code> in the other case.
    */
   public static VariableElement getVariableOrParameterElement(DartIdentifier node) {
-    NodeElement element = node.getElement();
+    Element element = node.getElement();
     if (element instanceof VariableElement) {
       return (VariableElement) element;
     }
diff --git a/compiler/java/com/google/dart/compiler/ast/DartCommentNewName.java b/compiler/java/com/google/dart/compiler/ast/DartCommentNewName.java
index 1ab676f..e1ef173 100644
--- a/compiler/java/com/google/dart/compiler/ast/DartCommentNewName.java
+++ b/compiler/java/com/google/dart/compiler/ast/DartCommentNewName.java
@@ -6,6 +6,7 @@
 
 import com.google.dart.compiler.resolver.ClassElement;
 import com.google.dart.compiler.resolver.ConstructorElement;
+import com.google.dart.compiler.util.StringInterner;
 
 /**
  * <code>[new Class.name]</code> in {@link DartComment}.
@@ -22,9 +23,9 @@
       int constructorOffset) {
     assert className != null;
     assert constructorName != null;
-    this.className = className;
+    this.className = StringInterner.intern(className);
     this.classOffset = classOffset;
-    this.constructorName = constructorName;
+    this.constructorName = StringInterner.intern(constructorName);
     this.constructorOffset = constructorOffset;
   }
 
diff --git a/compiler/java/com/google/dart/compiler/ast/DartCommentRefName.java b/compiler/java/com/google/dart/compiler/ast/DartCommentRefName.java
index 52c133e..95a1bbd 100644
--- a/compiler/java/com/google/dart/compiler/ast/DartCommentRefName.java
+++ b/compiler/java/com/google/dart/compiler/ast/DartCommentRefName.java
@@ -5,6 +5,7 @@
 package com.google.dart.compiler.ast;
 
 import com.google.dart.compiler.resolver.Element;
+import com.google.dart.compiler.util.StringInterner;
 
 /**
  * <code>[name]</code> in {@link DartComment}.
@@ -15,7 +16,7 @@
 
   public DartCommentRefName(String name) {
     assert name != null;
-    this.name = name;
+    this.name = StringInterner.intern(name);
   }
 
   @Override
diff --git a/compiler/java/com/google/dart/compiler/ast/DartIdentifier.java b/compiler/java/com/google/dart/compiler/ast/DartIdentifier.java
index 09eadc2..46ff36f 100644
--- a/compiler/java/com/google/dart/compiler/ast/DartIdentifier.java
+++ b/compiler/java/com/google/dart/compiler/ast/DartIdentifier.java
@@ -5,7 +5,7 @@
 package com.google.dart.compiler.ast;
 
 import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.NodeElement;
+import com.google.dart.compiler.util.StringInterner;
 
 /**
  * Represents a Dart identifier expression.
@@ -13,20 +13,20 @@
 public class DartIdentifier extends DartExpression {
 
   private final String name;
-  private NodeElement element;
+  private Element element;
   private boolean resolutionAlreadyReportedThatTheMethodCouldNotBeFound;
 
   public DartIdentifier(String name) {
     assert name != null;
-    this.name = name;
+    this.name = StringInterner.intern(name);
   }
 
   public DartIdentifier(DartIdentifier original) {
-    this.name = original.name;
+    this.name = StringInterner.intern(original.name);
   }
 
   @Override
-  public NodeElement getElement() {
+  public Element getElement() {
     return element;
   }
 
@@ -47,7 +47,7 @@
 
   @Override
   public void setElement(Element element) {
-    this.element = (NodeElement) element;
+    this.element = element;
   }
 
   /**
diff --git a/compiler/java/com/google/dart/compiler/ast/DartInvocation.java b/compiler/java/com/google/dart/compiler/ast/DartInvocation.java
index 477c4c3..1a3a0a2 100644
--- a/compiler/java/com/google/dart/compiler/ast/DartInvocation.java
+++ b/compiler/java/com/google/dart/compiler/ast/DartInvocation.java
@@ -5,7 +5,6 @@
 package com.google.dart.compiler.ast;
 
 import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.NodeElement;
 
 import java.util.List;
 
@@ -36,7 +35,7 @@
 public abstract class DartInvocation extends DartExpression {
 
   private final NodeList<DartExpression> arguments = NodeList.create(this);
-  private NodeElement element;
+  private Element element;
 
   public DartInvocation(List<DartExpression> arguments) {
     if (arguments != null && !arguments.isEmpty()) {
@@ -53,12 +52,12 @@
   }
 
   @Override
-  public NodeElement getElement() {
+  public Element getElement() {
     return element;
   }
 
   @Override
   public void setElement(Element element) {
-    this.element = (NodeElement) element;
+    this.element = element;
   }
 }
diff --git a/compiler/java/com/google/dart/compiler/ast/DartPropertyAccess.java b/compiler/java/com/google/dart/compiler/ast/DartPropertyAccess.java
index 3b7fb9c..9c1c903 100644
--- a/compiler/java/com/google/dart/compiler/ast/DartPropertyAccess.java
+++ b/compiler/java/com/google/dart/compiler/ast/DartPropertyAccess.java
@@ -5,7 +5,6 @@
 package com.google.dart.compiler.ast;
 
 import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.NodeElement;
 
 /**
  * Represents a Dart property access expression (a.b).
@@ -71,7 +70,7 @@
   }
 
   @Override
-  public NodeElement getElement() {
+  public Element getElement() {
     return name.getElement();
   }
 
diff --git a/compiler/java/com/google/dart/compiler/ast/DartStringLiteral.java b/compiler/java/com/google/dart/compiler/ast/DartStringLiteral.java
index e2a83bf..9aacf4e 100644
--- a/compiler/java/com/google/dart/compiler/ast/DartStringLiteral.java
+++ b/compiler/java/com/google/dart/compiler/ast/DartStringLiteral.java
@@ -6,6 +6,7 @@
 
 import com.google.common.collect.ImmutableList;
 import com.google.dart.compiler.resolver.Element;
+import com.google.dart.compiler.util.StringInterner;
 
 import java.util.List;
 
@@ -28,7 +29,7 @@
   private final List<DartStringLiteral> parts;
 
   private DartStringLiteral(String value, List<DartStringLiteral> parts) {
-    this.value = value;
+    this.value = StringInterner.intern(value);
     this.parts = parts;
   }
 
diff --git a/compiler/java/com/google/dart/compiler/resolver/AbstractNodeElement.java b/compiler/java/com/google/dart/compiler/resolver/AbstractNodeElement.java
index 50ec6a1..2c5a703 100644
--- a/compiler/java/com/google/dart/compiler/resolver/AbstractNodeElement.java
+++ b/compiler/java/com/google/dart/compiler/resolver/AbstractNodeElement.java
@@ -10,6 +10,7 @@
 import com.google.dart.compiler.common.SourceInfo;
 import com.google.dart.compiler.type.Type;
 import com.google.dart.compiler.type.Types;
+import com.google.dart.compiler.util.StringInterner;
 
 abstract class AbstractNodeElement implements Element, NodeElement {
   private final DartNode node;
@@ -20,7 +21,7 @@
     // TODO(scheglov) in the future we will not use ASTNode and remove null check
     this.sourceInfo = node != null ? node.getSourceInfo() : SourceInfo.UNKNOWN;
     this.node = node;
-    this.name = name;
+    this.name = StringInterner.intern(name);
   }
 
   @Override
diff --git a/compiler/java/com/google/dart/compiler/resolver/TypeErrorCode.java b/compiler/java/com/google/dart/compiler/resolver/TypeErrorCode.java
index 20c4aa6..c121dbe 100644
--- a/compiler/java/com/google/dart/compiler/resolver/TypeErrorCode.java
+++ b/compiler/java/com/google/dart/compiler/resolver/TypeErrorCode.java
@@ -63,7 +63,6 @@
   OPERATOR_INDEX_ASSIGN_VOID_RETURN_TYPE("operator '[]=' must have a return type of 'void'"),
   OPERATOR_WRONG_OPERAND_TYPE("operand of \"%s\" must be assignable to \"%s\", found \"%s\""),
   OVERRIDING_STATIC_MEMBER("overriding static member \"%s\" of \"%s\""),
-  PLUS_CANNOT_BE_USED_FOR_STRING_CONCAT("'%s' cannot be used for string concatentation, use string interpolation or a StringBuffer instead"),
   REDIRECTION_CONSTRUCTOR_TARGET_MUST_BE_SUBTYPE(
       "Target type of redirecting factory constructor '%s' is not subtype of '%s'"),
   SETTER_RETURN_TYPE("Specified return type of setter '%s' is non-void"),
@@ -128,4 +127,4 @@
   public boolean needsRecompilation() {
     return this.needsRecompilation;
   }
-}
\ No newline at end of file
+}
diff --git a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
index 15ee2bb..4a5539b 100644
--- a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
+++ b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
@@ -118,7 +118,6 @@
 import com.google.dart.compiler.resolver.FieldElement;
 import com.google.dart.compiler.resolver.FunctionAliasElement;
 import com.google.dart.compiler.resolver.MethodElement;
-import com.google.dart.compiler.resolver.NodeElement;
 import com.google.dart.compiler.resolver.ResolverErrorCode;
 import com.google.dart.compiler.resolver.TypeErrorCode;
 import com.google.dart.compiler.resolver.VariableElement;
@@ -268,7 +267,7 @@
     void setCurrentClass(InterfaceType type) {
       currentClass = type;
     }
-    
+
     @VisibleForTesting
     void pushBasicBlockContext() {
       blockOldTypes.addFirst(new BlockTypeContext());
@@ -379,6 +378,7 @@
         FunctionType methodType = getMethodType(lhsType, member, methodName, diagnosticNode);
         checkDeprecated(problemTarget, element);
         Type returnType = checkInvocation(Collections.<DartExpression> singletonList(rhs),
+            Collections.<Type> singletonList(rhsType),
             diagnosticNode, methodName, methodType, null);
         // tweak return type for int/int and int/double operators
         {
@@ -407,7 +407,7 @@
         return dynamicType;
       }
     }
-    
+
     private Type analyzeTernaryOperator(DartNode node, Type lhsType, Token operator,
         DartNode diagnosticNode, DartExpression arg1, DartExpression arg2) {
       String methodName = methodNameForBinaryOperator(operator);
@@ -460,9 +460,7 @@
           return rhs;
         }
 
-        case ASSIGN_ADD: {
-          checkStringConcatPlus(node, lhs);
-        }
+        case ASSIGN_ADD:
         case ASSIGN_SUB:
         case ASSIGN_MUL:
         case ASSIGN_DIV:
@@ -522,9 +520,7 @@
           }
         }
 
-        case ADD:  {
-          checkStringConcatPlus(node, lhs);
-        }
+        case ADD:
         case SUB:
         case MUL:
         case DIV:
@@ -597,14 +593,6 @@
       }
     }
 
-    private void checkStringConcatPlus(DartBinaryExpression binary, Type lhs) {
-      if (Objects.equal(lhs, stringType)) {
-        Token operator = binary.getOperator();
-        HasSourceInfo errorTarget = getOperatorHasSourceInfo(binary);
-        onError(errorTarget, TypeErrorCode.PLUS_CANNOT_BE_USED_FOR_STRING_CONCAT, operator);
-      }
-    }
-
     /**
      * @return the best guess for operator token location in the given {@link DartNode}.
      */
@@ -1025,7 +1013,7 @@
         setVariableElementType(variable, mergedType, mergedTypeQuality);
       }
     }
-    
+
     private boolean isAssignable(Type t, Type s) {
       t.getClass(); // Null check.
       s.getClass(); // Null check.
@@ -1074,7 +1062,7 @@
       }
       return functionType;
     }
-      
+
     private FunctionType getMethodType0(Type receiver, Member member, String name,
         DartNode diagnosticNode) {
       if (member == null) {
@@ -1204,7 +1192,7 @@
           argumentIndex++;
         }
       }
-      
+
       // Check named parameters.
       {
         Set<String> usedNamedParametersPositional = Sets.newHashSet();
@@ -1311,7 +1299,7 @@
         for (int i = 0; i < arguments.size(); i++) {
           Type t = bounds.get(i);
           Type s = arguments.get(i);
-          if (!types.isAssignable(t, s)) {
+          if (!types.isSubtype(s, t)) {
             onError(diagnosticNodes.get(i),
                 TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, s, t);
           }
@@ -1414,7 +1402,7 @@
       Type result = analyzeBinaryOperator(node, target, Token.INDEX, node, argKey);
       return Types.makeInferred(result, target.getQuality());
     }
-    
+
     /**
      * Asserts that given {@link DartExpression} is valid for using in "assert" statement.
      */
@@ -1787,7 +1775,7 @@
       } else {
         variableType = typeOf(node.getIdentifier());
         // in most cases variable, but sometimes field
-        NodeElement identifierElement = node.getIdentifier().getElement();
+        Element identifierElement = node.getIdentifier().getElement();
         if (identifierElement instanceof VariableElement) {
           variableElement = (VariableElement) identifierElement;
         }
@@ -1927,7 +1915,7 @@
 
         case CLASS:
           return element.getType();
-          
+
         case FIELD:
           type = typeAsMemberOf(element, currentClass);
           // try to resolve as getter/setter
@@ -2454,7 +2442,7 @@
         case FIELD:
           FieldElement fieldElement = (FieldElement) element;
           Modifiers fieldModifiers = fieldElement.getModifiers();
-          
+
           // Prepare getter/setter members.
           Member getterMember;
           Member setterMember;
@@ -2690,7 +2678,7 @@
       blockOldTypes.addFirst(new BlockTypeContext());
       return typeAsVoid(node);
     }
-    
+
     @Override
     public Type visitAssertStatement(DartAssertStatement node) {
       DartExpression condition = node.getCondition();
@@ -2780,7 +2768,7 @@
      * Report warning if given {@link Element} is deprecated.
      */
     private void checkDeprecated(HasSourceInfo nameNode, Element element) {
-      if (element != null && element.getMetadata().isDeprecated()) {
+      if (element != null && element.getMetadata() != null && element.getMetadata().isDeprecated()) {
         onError(nameNode, TypeErrorCode.DEPRECATED_ELEMENT,
             Elements.getDeprecatedElementTitle(element));
       }
@@ -2807,6 +2795,11 @@
         Type argumentType = getInvocationArgumentType(argumentNode);
         argumentTypes.add(argumentType);
       }
+      return checkInvocation(argumentNodes, argumentTypes, diagnosticNode, name, type, parameters);
+    }
+
+    private Type checkInvocation(List<DartExpression> argumentNodes, List<Type> argumentTypes,
+        DartNode diagnosticNode, String name, Type type, List<VariableElement> parameters) {
       // Check that argument types are compatible with type of invoked object.
       try {
         switch (TypeKind.of(type)) {
@@ -3121,7 +3114,7 @@
     public Type visitImportDirective(DartImportDirective node) {
       return voidType;
     }
-    
+
     @Override
     public Type visitExportDirective(DartExportDirective node) {
       return voidType;
@@ -3232,7 +3225,7 @@
             }
           }
         }
-        
+
         // visit mixins
         for (InterfaceType mixType : currentClass.getElement().getMixins()) {
           ClassElement mixElement = mixType.getElement();
@@ -3240,7 +3233,7 @@
             removeSuperMemberIfNotAbstract(member);
           }
         }
-        
+
         // Remove artificial "setter " members.
         for (String name : artificialNames) {
           superMembers.removeAll(name);
@@ -3258,7 +3251,7 @@
             }
           }
         }
-        
+
         // add abstract members of current class
         for (Element member : currentClass.getElement().getMembers()) {
           if (ElementKind.of(member) == ElementKind.FIELD && member.getModifiers().isAbstractField()) {
@@ -3275,7 +3268,7 @@
             unimplementedElements.add(member);
           }
         }
-        
+
         return null;
       }
 
@@ -3660,7 +3653,7 @@
     return type != null && TypeKind.of(type) != TypeKind.DYNAMIC
         && !TypeQuality.isInferred(type);
   }
-  
+
   /**
    * @return the {@link TypeQuality} of given {@link DartExpression}.
    */
@@ -3709,7 +3702,7 @@
     Type type = expr.getType();
     return isCoreType(type, "bool") || isCoreType(type, "int") || isCoreType(type, "double");
   }
-  
+
   private static boolean isCoreType(Type type, String name) {
     return type != null
         && Elements.isCoreLibrarySource(type.getElement().getSourceInfo().getSource())
diff --git a/compiler/java/com/google/dart/compiler/type/Types.java b/compiler/java/com/google/dart/compiler/type/Types.java
index 44f401e..8e83daf 100644
--- a/compiler/java/com/google/dart/compiler/type/Types.java
+++ b/compiler/java/com/google/dart/compiler/type/Types.java
@@ -344,6 +344,21 @@
         return isSubtype(tBound, sv);
       }
     }
+    // May be concrete InterfaceType.
+    if (t.getKind() == TypeKind.INTERFACE) {
+      InterfaceType ti = (InterfaceType) t;
+      Type sBound = sv.getTypeVariableElement().getBound();
+      if (sBound == null) {
+        return true;
+      }
+      // Prevent cycle.
+      if (sBound.equals(sv)) {
+        return false;
+      }
+      if (sBound.getKind() == TypeKind.INTERFACE) {
+        return isSubtype(ti, sBound);
+      }
+    }
     // no
     return false;
   }
diff --git a/compiler/java/com/google/dart/compiler/util/StringInterner.java b/compiler/java/com/google/dart/compiler/util/StringInterner.java
new file mode 100644
index 0000000..e33118e
--- /dev/null
+++ b/compiler/java/com/google/dart/compiler/util/StringInterner.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2013, the Dart project authors.
+ * 
+ * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.dart.compiler.util;
+
+import com.google.common.collect.Interner;
+import com.google.common.collect.Interners;
+
+public class StringInterner {
+  private static Interner<String> INTERNER = Interners.newStrongInterner();
+  
+  public static String intern(String s) {
+    if (s == null) {
+      return null;
+    }
+    s = new String(s);
+    return INTERNER.intern(s);
+//    return s;
+  }
+}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/ResolverTestCase.java b/compiler/javatests/com/google/dart/compiler/resolver/ResolverTestCase.java
index bf2ddf8..7de5552 100644
--- a/compiler/javatests/com/google/dart/compiler/resolver/ResolverTestCase.java
+++ b/compiler/javatests/com/google/dart/compiler/resolver/ResolverTestCase.java
@@ -209,7 +209,7 @@
 
       ClassElement stringElement = Elements.classNamed("String");
       stringType = Types.interfaceType(stringElement, Collections.<Type>emptyList());
-      intElement.setType(intType);
+      stringElement.setType(stringType);
 
       ClassElement functionElement = Elements.classNamed("Function");
       functionType = Types.interfaceType(functionElement, Collections.<Type>emptyList());
@@ -223,7 +223,7 @@
       ClassElement listElement = Elements.classNamed("List");
       defaultListType = Types.interfaceType(listElement, Lists.<Type>newArrayList(dynamicType));
       listElement.setType(defaultListType);
-      
+
       ClassElement typeElement = Elements.classNamed("Type");
       typeType = Types.interfaceType(typeElement, Collections.<Type>emptyList());
       listElement.setType(defaultListType);
diff --git a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
index d84e226..1e4e281 100644
--- a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
+++ b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
@@ -46,7 +46,6 @@
 import com.google.dart.compiler.resolver.FieldElement;
 import com.google.dart.compiler.resolver.LibraryElement;
 import com.google.dart.compiler.resolver.MethodElement;
-import com.google.dart.compiler.resolver.NodeElement;
 import com.google.dart.compiler.resolver.ResolverErrorCode;
 import com.google.dart.compiler.resolver.TypeErrorCode;
 import com.google.dart.compiler.resolver.VariableElement;
@@ -1553,9 +1552,9 @@
       invocation = (DartUnqualifiedInvocation) stmt.getExpression();
     }
     // Check that unqualified foo() invocation is resolved to the top-level (library) function.
-    NodeElement element = invocation.getTarget().getElement();
+    Element element = invocation.getTarget().getElement();
     assertNotNull(element);
-    assertSame(testUnit, element.getNode().getParent());
+    assertTrue(element.getEnclosingElement() instanceof LibraryElement);
   }
 
   /**
@@ -2013,6 +2012,23 @@
     assertErrors(result.getErrors());
   }
 
+  /**
+   * <p>
+   * https://codereview.chromium.org/12787002/
+   */
+  public void test_typeVariableBounds_12787002() throws Exception {
+    AnalyzeLibraryResult result =
+        analyzeLibrary(
+            "// filler filler filler filler filler filler filler filler filler filler",
+            "class A<T> {",
+            "  m() {",
+            "    B a = this;",
+            "  }",
+            "}",
+            "class B extends A<String> {}");
+    assertErrors(result.getErrors());
+  }
+
   public void test_typeVariableBoundsMismatch() throws Exception {
     AnalyzeLibraryResult result =
         analyzeLibrary(
@@ -5170,7 +5186,7 @@
       assertSame(typeA, type);
       // .named
       DartIdentifier nameNode = findNode(DartIdentifier.class, "named;");
-      NodeElement nameElement = nameNode.getElement();
+      Element nameElement = nameNode.getElement();
       assertNotNull(nameElement);
       assertSame(elementA.lookupConstructor("named"), nameElement);
     }
@@ -6510,4 +6526,16 @@
         errEx(ResolverErrorCode.CANNOT_MIXIN_CLASS_WITH_MIXINS, 2, 25, 1));
   }
 
+  public void test_StringPlus() throws Exception {
+    AnalyzeLibraryResult result = analyzeLibrary(
+        "// filler filler filler filler filler filler filler filler filler filler",
+        "main() {",
+        "  var v1 = '1' + '2';",
+        "  var v2 = '1' + 2;",
+        "}",
+        "");
+    assertErrors(
+        result.getErrors(),
+        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 4, 18, 1));
+  }
 }
diff --git a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerTest.java b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerTest.java
index 8f67edc..c2cc676f 100644
--- a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerTest.java
+++ b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerTest.java
@@ -1199,23 +1199,4 @@
     analyzeFail("while ('') {}",
       TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
   }
-
-  public void testStringConcat() {
-    Map<String, ClassNodeElement> source = loadSource(
-        "class Object {}",
-        "abstract class Foo {",
-        "  operator +(arg1);" +
-        "}",
-        "Foo a = new Foo();",
-        "Foo b = new Foo();",
-        "String s = 'foo';");
-    analyzeClasses(source);
-    analyze("{ var c = a + b; }");
-    analyzeFail("{ var c = s + b; }",
-        TypeErrorCode.PLUS_CANNOT_BE_USED_FOR_STRING_CONCAT);
-    analyzeFail("var c = 'foo' + 1;",
-        TypeErrorCode.PLUS_CANNOT_BE_USED_FOR_STRING_CONCAT);
-    analyzeFail("var c = 'foo' + 'bar';",
-        TypeErrorCode.PLUS_CANNOT_BE_USED_FOR_STRING_CONCAT);
-  }
 }
diff --git a/pkg/analyzer-experimental/lib/src/generated/engine.dart b/pkg/analyzer-experimental/lib/src/generated/engine.dart
deleted file mode 100644
index b1f1265..0000000
--- a/pkg/analyzer-experimental/lib/src/generated/engine.dart
+++ /dev/null
@@ -1,660 +0,0 @@
-// This code was auto-generated, is not intended to be edited, and is subject to
-// significant change. Please see the README file for more information.
-
-library engine;
-
-import 'java_core.dart';
-import 'dart:collection' show HasNextIterator;
-import 'error.dart';
-import 'source.dart';
-import 'scanner.dart' show Token, CharBufferScanner, StringScanner;
-import 'ast.dart' show CompilationUnit;
-import 'parser.dart' show Parser;
-import 'element.dart';
-import 'resolver.dart' show Namespace, NamespaceBuilder, LibraryResolver;
-
-/**
- * The unique instance of the class {@code AnalysisEngine} serves as the entry point for the
- * functionality provided by the analysis engine.
- */
-class AnalysisEngine {
-  /**
-   * The unique instance of this class.
-   */
-  static AnalysisEngine _UniqueInstance = new AnalysisEngine();
-  /**
-   * Return the unique instance of this class.
-   * @return the unique instance of this class
-   */
-  static AnalysisEngine get instance => _UniqueInstance;
-  /**
-   * The logger that should receive information about errors within the analysis engine.
-   */
-  Logger _logger = Logger.NULL;
-  /**
-   * Prevent the creation of instances of this class.
-   */
-  AnalysisEngine() : super() {
-  }
-  /**
-   * Create a new context in which analysis can be performed.
-   * @return the analysis context that was created
-   */
-  AnalysisContext createAnalysisContext() => new AnalysisContextImpl();
-  /**
-   * Return the logger that should receive information about errors within the analysis engine.
-   * @return the logger that should receive information about errors within the analysis engine
-   */
-  Logger get logger => _logger;
-  /**
-   * Set the logger that should receive information about errors within the analysis engine to the
-   * given logger.
-   * @param logger the logger that should receive information about errors within the analysis
-   * engine
-   */
-  void set logger(Logger logger2) {
-    this._logger = logger2 == null ? Logger.NULL : logger2;
-  }
-}
-/**
- * The interface {@code AnalysisContext} defines the behavior of objects that represent a context in
- * which analysis can be performed. The context includes such information as the version of the SDK
- * being analyzed against as well as the package-root used to resolve 'package:' URI's. This
- * information is included indirectly through the {@link SourceFactory source factory}.
- * <p>
- * Analysis engine allows for having more than one context. This can be used, for example, to
- * perform one analysis based on the state of files on disk and a separate analysis based on the
- * state of those files in open editors. It can also be used to perform an analysis based on a
- * proposed future state, such as after a refactoring.
- */
-abstract class AnalysisContext {
-  /**
-   * Clear any cached information that is dependent on resolution. This method should be invoked if
-   * the assumptions used by resolution have changed but the contents of the file have not changed.
-   * Use {@link #sourceChanged(Source)} and {@link #sourcesDeleted(SourceContainer)} to indicate
-   * when the contents of a file or files have changed.
-   */
-  void clearResolution();
-  /**
-   * Call this method when this context is no longer going to be used. At this point, the receiver
-   * may choose to push some of its information back into the global cache for consumption by
-   * another context for performance.
-   */
-  void discard();
-  /**
-   * Create a new context in which analysis can be performed. Any sources in the specified directory
-   * in the receiver will be removed from the receiver and added to the newly created context.
-   * @param directory the directory (not {@code null}) containing sources that should be removed
-   * from the receiver and added to the returned context
-   * @return the analysis context that was created (not {@code null})
-   */
-  AnalysisContext extractAnalysisContext(SourceContainer container);
-  /**
-   * Answer the collection of sources that have been added to the receiver via{@link #sourceAvailable(Source)} and not removed from the receiver via{@link #sourceDeleted(Source)} or {@link #sourcesDeleted(SourceContainer)}.
-   * @return a collection of sources (not {@code null}, contains no {@code null}s)
-   */
-  Collection<Source> get availableSources;
-  /**
-   * Return the element referenced by the given location.
-   * @param location the reference describing the element to be returned
-   * @return the element referenced by the given location
-   */
-  Element getElement(ElementLocation location);
-  /**
-   * Return an array containing all of the errors associated with the given source.
-   * @param source the source whose errors are to be returned
-   * @return all of the errors associated with the given source
-   * @throws AnalysisException if the errors could not be determined because the analysis could not
-   * be performed
-   */
-  List<AnalysisError> getErrors(Source source);
-  /**
-   * Parse and build an element model for the HTML file defined by the given source.
-   * @param source the source defining the HTML file whose element model is to be returned
-   * @return the element model corresponding to the HTML file defined by the given source
-   */
-  HtmlElement getHtmlElement(Source source);
-  /**
-   * Return the kind of the given source if it is already known, or {@code null} if the kind is not
-   * already known.
-   * @param source the source whose kind is to be returned
-   * @return the kind of the given source
-   * @see #getOrComputeKindOf(Source)
-   */
-  SourceKind getKnownKindOf(Source source);
-  /**
-   * Return the element model corresponding to the library defined by the given source. If the
-   * element model does not yet exist it will be created. The process of creating an element model
-   * for a library can long-running, depending on the size of the library and the number of
-   * libraries that are imported into it that also need to have a model built for them.
-   * @param source the source defining the library whose element model is to be returned
-   * @return the element model corresponding to the library defined by the given source or{@code null} if the element model could not be determined because the analysis could
-   * not be performed
-   */
-  LibraryElement getLibraryElement(Source source);
-  /**
-   * Return the element model corresponding to the library defined by the given source, or{@code null} if the element model does not yet exist.
-   * @param source the source defining the library whose element model is to be returned
-   * @return the element model corresponding to the library defined by the given source
-   */
-  LibraryElement getLibraryElementOrNull(Source source);
-  /**
-   * Return the kind of the given source, computing it's kind if it is not already known.
-   * @param source the source whose kind is to be returned
-   * @return the kind of the given source
-   * @see #getKnownKindOf(Source)
-   */
-  SourceKind getOrComputeKindOf(Source source);
-  /**
-   * Return an array containing all of the parsing errors associated with the given source.
-   * @param source the source whose errors are to be returned
-   * @return all of the parsing errors associated with the given source
-   * @throws AnalysisException if the errors could not be determined because the analysis could not
-   * be performed
-   */
-  List<AnalysisError> getParsingErrors(Source source);
-  /**
-   * Return an array containing all of the resolution errors associated with the given source.
-   * @param source the source whose errors are to be returned
-   * @return all of the resolution errors associated with the given source
-   * @throws AnalysisException if the errors could not be determined because the analysis could not
-   * be performed
-   */
-  List<AnalysisError> getResolutionErrors(Source source);
-  /**
-   * Return the source factory used to create the sources that can be analyzed in this context.
-   * @return the source factory used to create the sources that can be analyzed in this context
-   */
-  SourceFactory get sourceFactory;
-  /**
-   * Add the sources contained in the specified context to the receiver's collection of sources.
-   * This method is called when an existing context's pubspec has been removed, and the contained
-   * sources should be reanalyzed as part of the receiver.
-   * @param context the context being merged (not {@code null})
-   */
-  void mergeAnalysisContext(AnalysisContext context);
-  /**
-   * Parse a single source to produce an AST structure. The resulting AST structure may or may not
-   * be resolved, and may have a slightly different structure depending upon whether it is resolved.
-   * @param source the source to be parsed
-   * @return the AST structure representing the content of the source
-   * @throws AnalysisException if the analysis could not be performed
-   */
-  CompilationUnit parse(Source source);
-  /**
-   * Parse and resolve a single source within the given context to produce a fully resolved AST.
-   * @param source the source to be parsed and resolved
-   * @param library the library defining the context in which the source file is to be resolved
-   * @return the result of resolving the AST structure representing the content of the source
-   * @throws AnalysisException if the analysis could not be performed
-   */
-  CompilationUnit resolve(Source source, LibraryElement library);
-  /**
-   * Scan a single source to produce a token stream.
-   * @param source the source to be scanned
-   * @param errorListener the listener to which errors should be reported
-   * @return the head of the token stream representing the content of the source
-   * @throws AnalysisException if the analysis could not be performed
-   */
-  Token scan(Source source, AnalysisErrorListener errorListener);
-  /**
-   * Set the source factory used to create the sources that can be analyzed in this context to the
-   * given source factory.
-   * @param sourceFactory the source factory used to create the sources that can be analyzed in this
-   * context
-   */
-  void set sourceFactory(SourceFactory sourceFactory4);
-  /**
-   * Cache the fact that content for the given source is now available, is of interest to the
-   * client, and should be analyzed. Do not modify or discard any information about this source that
-   * is already cached.
-   * @param source the source that is now available
-   */
-  void sourceAvailable(Source source);
-  /**
-   * Respond to the fact that the content of the given source has changed by removing any cached
-   * information that might now be out-of-date.
-   * @param source the source whose content has changed
-   */
-  void sourceChanged(Source source);
-  /**
-   * Respond to the fact that the given source has been deleted and should no longer be analyzed by
-   * removing any cached information that might now be out-of-date.
-   * @param source the source that was deleted
-   */
-  void sourceDeleted(Source source);
-  /**
-   * Discard cached information for all files in the specified source container.
-   * @param container the source container that was deleted (not {@code null})
-   */
-  void sourcesDeleted(SourceContainer container);
-  /**
-   * Given a collection of sources with content that has changed, return an {@link Iterable}identifying the sources that need to be resolved.
-   * @param changedSources an array of sources (not {@code null}, contains no {@code null}s)
-   * @return An iterable returning the sources to be resolved
-   */
-  Iterable<Source> sourcesToResolve(List<Source> changedSources);
-}
-/**
- * Instances of the class {@code AnalysisException} represent an exception that occurred during the
- * analysis of one or more sources.
- */
-class AnalysisException extends JavaException {
-  /**
-   * Initialize a newly created exception.
-   */
-  AnalysisException() : super() {
-    _jtd_constructor_117_impl();
-  }
-  _jtd_constructor_117_impl() {
-  }
-  /**
-   * Initialize a newly created exception to have the given message.
-   * @param message the message associated with the exception
-   */
-  AnalysisException.con1(String message) : super(message) {
-    _jtd_constructor_118_impl(message);
-  }
-  _jtd_constructor_118_impl(String message) {
-  }
-  /**
-   * Initialize a newly created exception to have the given message and cause.
-   * @param message the message associated with the exception
-   * @param cause the underlying exception that caused this exception
-   */
-  AnalysisException.con2(String message, Exception cause) : super(message, cause) {
-    _jtd_constructor_119_impl(message, cause);
-  }
-  _jtd_constructor_119_impl(String message, Exception cause) {
-  }
-  /**
-   * Initialize a newly created exception to have the given cause.
-   * @param cause the underlying exception that caused this exception
-   */
-  AnalysisException.con3(Exception cause) : super.withCause(cause) {
-    _jtd_constructor_120_impl(cause);
-  }
-  _jtd_constructor_120_impl(Exception cause) {
-  }
-}
-/**
- * Instances of the class {@code AnalysisContextImpl} implement an {@link AnalysisContext analysis
- * context}.
- */
-class AnalysisContextImpl implements AnalysisContext {
-  /**
-   * The source factory used to create the sources that can be analyzed in this context.
-   */
-  SourceFactory _sourceFactory;
-  /**
-   * A cache mapping sources to the compilation units that were produced for the contents of the
-   * source.
-   */
-  Map<Source, CompilationUnit> _parseCache = new Map<Source, CompilationUnit>();
-  /**
-   * A cache mapping sources (of the defining compilation units of libraries) to the library
-   * elements for those libraries.
-   */
-  Map<Source, LibraryElement> _libraryElementCache = new Map<Source, LibraryElement>();
-  /**
-   * A cache mapping sources (of the defining compilation units of libraries) to the public
-   * namespace for that library.
-   */
-  Map<Source, Namespace> _publicNamespaceCache = new Map<Source, Namespace>();
-  /**
-   * A cache of the available sources of interest to the client. Sources are added to this
-   * collection via {@link #sourceAvailable(Source)} and removed from this collection via{@link #sourceDeleted(Source)} and {@link #directoryDeleted(File)}
-   */
-  Set<Source> _availableSources = new Set<Source>();
-  /**
-   * The object used to synchronize access to all of the caches.
-   */
-  Object _cacheLock = new Object();
-  /**
-   * The suffix used by sources that contain Dart.
-   */
-  static String _DART_SUFFIX = ".dart";
-  /**
-   * The suffix used by sources that contain HTML.
-   */
-  static String _HTML_SUFFIX = ".html";
-  /**
-   * Initialize a newly created analysis context.
-   */
-  AnalysisContextImpl() : super() {
-  }
-  void clearResolution() {
-    {
-      _parseCache.clear();
-      _libraryElementCache.clear();
-      _publicNamespaceCache.clear();
-    }
-  }
-  void discard() {
-    {
-      _parseCache.clear();
-      _libraryElementCache.clear();
-      _publicNamespaceCache.clear();
-      _availableSources.clear();
-    }
-  }
-  AnalysisContext extractAnalysisContext(SourceContainer container) {
-    AnalysisContext newContext = AnalysisEngine.instance.createAnalysisContext();
-    {
-      JavaIterator<Source> iter = new JavaIterator(_availableSources);
-      while (iter.hasNext) {
-        Source source = iter.next();
-        if (container.contains(source)) {
-          iter.remove();
-          newContext.sourceAvailable(source);
-        }
-      }
-    }
-    return newContext;
-  }
-  Collection<Source> get availableSources {
-    {
-      return new List<Source>.from(_availableSources);
-    }
-  }
-  Element getElement(ElementLocation location) {
-    throw new UnsupportedOperationException();
-  }
-  List<AnalysisError> getErrors(Source source) {
-    throw new UnsupportedOperationException();
-  }
-  HtmlElement getHtmlElement(Source source) {
-    throw new UnsupportedOperationException();
-  }
-  SourceKind getKnownKindOf(Source source) {
-    if (source.fullName.endsWith(_HTML_SUFFIX)) {
-      return SourceKind.HTML;
-    }
-    if (!source.fullName.endsWith(_DART_SUFFIX)) {
-      return SourceKind.UNKNOWN;
-    }
-    {
-      if (_libraryElementCache.containsKey(source)) {
-        return SourceKind.LIBRARY;
-      }
-      CompilationUnit unit = _parseCache[source];
-      if (unit != null && hasPartOfDirective(unit)) {
-        return SourceKind.PART;
-      }
-    }
-    return null;
-  }
-  LibraryElement getLibraryElement(Source source) {
-    {
-      LibraryElement element = _libraryElementCache[source];
-      if (element == null) {
-        RecordingErrorListener listener = new RecordingErrorListener();
-        LibraryResolver resolver = new LibraryResolver(this, listener);
-        try {
-          element = resolver.resolveLibrary(source, true);
-        } on AnalysisException catch (exception) {
-          AnalysisEngine.instance.logger.logError2("Could not resolve the library ${source.fullName}", exception);
-        }
-      }
-      return element;
-    }
-  }
-  /**
-   * Return the element model corresponding to the library defined by the given source, or{@code null} if the element model does not yet exist.
-   * @param source the source defining the library whose element model is to be returned
-   * @return the element model corresponding to the library defined by the given source
-   */
-  LibraryElement getLibraryElementOrNull(Source source) {
-    {
-      return _libraryElementCache[source];
-    }
-  }
-  SourceKind getOrComputeKindOf(Source source) {
-    SourceKind kind = getKnownKindOf(source);
-    if (kind != null) {
-      return kind;
-    }
-    try {
-      if (hasPartOfDirective(parse(source))) {
-        return SourceKind.PART;
-      }
-    } on AnalysisException catch (exception) {
-      return SourceKind.UNKNOWN;
-    }
-    return SourceKind.LIBRARY;
-  }
-  List<AnalysisError> getParsingErrors(Source source) {
-    throw new UnsupportedOperationException();
-  }
-  /**
-   * Return a namespace containing mappings for all of the public names defined by the given
-   * library.
-   * @param library the library whose public namespace is to be returned
-   * @return the public namespace of the given library
-   */
-  Namespace getPublicNamespace(LibraryElement library) {
-    Source source7 = library.definingCompilationUnit.source;
-    {
-      Namespace namespace = _publicNamespaceCache[source7];
-      if (namespace == null) {
-        NamespaceBuilder builder = new NamespaceBuilder();
-        namespace = builder.createPublicNamespace(library);
-        _publicNamespaceCache[source7] = namespace;
-      }
-      return namespace;
-    }
-  }
-  /**
-   * Return a namespace containing mappings for all of the public names defined by the library
-   * defined by the given source.
-   * @param source the source defining the library whose public namespace is to be returned
-   * @return the public namespace corresponding to the library defined by the given source
-   */
-  Namespace getPublicNamespace2(Source source) {
-    {
-      Namespace namespace = _publicNamespaceCache[source];
-      if (namespace == null) {
-        LibraryElement library = getLibraryElement(source);
-        if (library == null) {
-          return null;
-        }
-        NamespaceBuilder builder = new NamespaceBuilder();
-        namespace = builder.createPublicNamespace(library);
-        _publicNamespaceCache[source] = namespace;
-      }
-      return namespace;
-    }
-  }
-  List<AnalysisError> getResolutionErrors(Source source) {
-    throw new UnsupportedOperationException();
-  }
-  SourceFactory get sourceFactory => _sourceFactory;
-  void mergeAnalysisContext(AnalysisContext context) {
-    {
-      _availableSources.addAll(context.availableSources);
-    }
-  }
-  CompilationUnit parse(Source source) {
-    {
-      CompilationUnit unit = _parseCache[source];
-      if (unit == null) {
-        RecordingErrorListener errorListener = new RecordingErrorListener();
-        Token token = scan(source, errorListener);
-        Parser parser = new Parser(source, errorListener);
-        unit = parser.parseCompilationUnit(token);
-        unit.parsingErrors = errorListener.errors;
-        _parseCache[source] = unit;
-      }
-      return unit;
-    }
-  }
-  CompilationUnit parse2(Source source, AnalysisErrorListener errorListener) {
-    {
-      CompilationUnit unit = _parseCache[source];
-      if (unit == null) {
-        Token token = scan(source, errorListener);
-        Parser parser = new Parser(source, errorListener);
-        unit = parser.parseCompilationUnit(token);
-        _parseCache[source] = unit;
-      }
-      return unit;
-    }
-  }
-  /**
-   * Given a table mapping the source for the libraries represented by the corresponding elements to
-   * the elements representing the libraries, record those mappings.
-   * @param elementMap a table mapping the source for the libraries represented by the elements to
-   * the elements representing the libraries
-   */
-  void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
-    {
-      javaMapPutAll(_libraryElementCache, elementMap);
-    }
-  }
-  CompilationUnit resolve(Source source, LibraryElement library) => parse(source);
-  Token scan(Source source, AnalysisErrorListener errorListener) {
-    List<Token> tokens = new List<Token>(1);
-    Source_ContentReceiver receiver = new Source_ContentReceiver_1(source, errorListener, tokens);
-    try {
-      source.getContents(receiver);
-    } on JavaException catch (exception) {
-    }
-    return tokens[0];
-  }
-  void set sourceFactory(SourceFactory sourceFactory2) {
-    this._sourceFactory = sourceFactory2;
-  }
-  void sourceAvailable(Source source) {
-    {
-      javaSetAdd(_availableSources, source);
-    }
-  }
-  void sourceChanged(Source source) {
-    {
-      _parseCache.remove(source);
-      _libraryElementCache.remove(source);
-      _publicNamespaceCache.remove(source);
-    }
-  }
-  void sourceDeleted(Source source) {
-    {
-      _availableSources.remove(source);
-      sourceChanged(source);
-    }
-  }
-  void sourcesDeleted(SourceContainer container) {
-    {
-      _parseCache.clear();
-      _libraryElementCache.clear();
-      _publicNamespaceCache.clear();
-      JavaIterator<Source> iter = new JavaIterator(_availableSources);
-      while (iter.hasNext) {
-        if (container.contains(iter.next())) {
-          iter.remove();
-        }
-      }
-    }
-  }
-  Iterable<Source> sourcesToResolve(List<Source> changedSources) => JavaArrays.asList(changedSources);
-  /**
-   * Return {@code true} if the given compilation unit has a part-of directive.
-   * @param unit the compilation unit being tested
-   * @return {@code true} if the compilation unit has a part-of directive
-   */
-  bool hasPartOfDirective(CompilationUnit unit) {
-    for (Directive directive in unit.directives) {
-      if (directive is PartOfDirective) {
-        return true;
-      }
-    }
-    return false;
-  }
-}
-class Source_ContentReceiver_1 implements Source_ContentReceiver {
-  Source source;
-  AnalysisErrorListener errorListener;
-  List<Token> tokens;
-  Source_ContentReceiver_1(this.source, this.errorListener, this.tokens);
-  accept(CharBuffer contents) {
-    CharBufferScanner scanner = new CharBufferScanner(source, contents, errorListener);
-    tokens[0] = scanner.tokenize();
-  }
-  void accept2(String contents) {
-    StringScanner scanner = new StringScanner(source, contents, errorListener);
-    tokens[0] = scanner.tokenize();
-  }
-}
-/**
- * Instances of the class {@code RecordingErrorListener} implement an error listener that will
- * record the errors that are reported to it in a way that is appropriate for caching those errors
- * within an analysis context.
- */
-class RecordingErrorListener implements AnalysisErrorListener {
-  /**
-   * A list containing the errors that were collected.
-   */
-  List<AnalysisError> _errors = null;
-  /**
-   * Answer the errors collected by the listener.
-   * @return an array of errors (not {@code null}, contains no {@code null}s)
-   */
-  List<AnalysisError> get errors => _errors != null ? new List.from(_errors) : AnalysisError.NO_ERRORS;
-  void onError(AnalysisError event) {
-    if (_errors == null) {
-      _errors = new List<AnalysisError>();
-    }
-    _errors.add(event);
-  }
-}
-/**
- * The interface {@code Logger} defines the behavior of objects that can be used to receive
- * information about errors within the analysis engine. Implementations usually write this
- * information to a file, but can also record the information for later use (such as during testing)
- * or even ignore the information.
- */
-abstract class Logger {
-  static Logger NULL = new Logger_NullLogger();
-  /**
-   * Log the given message as an error.
-   * @param message an explanation of why the error occurred or what it means
-   */
-  void logError(String message);
-  /**
-   * Log the given exception as one representing an error.
-   * @param message an explanation of why the error occurred or what it means
-   * @param exception the exception being logged
-   */
-  void logError2(String message, Exception exception);
-  /**
-   * Log the given exception as one representing an error.
-   * @param exception the exception being logged
-   */
-  void logError3(Exception exception);
-  /**
-   * Log the given informational message.
-   * @param message an explanation of why the error occurred or what it means
-   * @param exception the exception being logged
-   */
-  void logInformation(String message);
-  /**
-   * Log the given exception as one representing an informational message.
-   * @param message an explanation of why the error occurred or what it means
-   * @param exception the exception being logged
-   */
-  void logInformation2(String message, Exception exception);
-}
-/**
- * Implementation of {@link Logger} that does nothing.
- */
-class Logger_NullLogger implements Logger {
-  void logError(String message) {
-  }
-  void logError2(String message, Exception exception) {
-  }
-  void logError3(Exception exception) {
-  }
-  void logInformation(String message) {
-  }
-  void logInformation2(String message, Exception exception) {
-  }
-}
diff --git a/pkg/analyzer-experimental/lib/src/generated/error.dart b/pkg/analyzer-experimental/lib/src/generated/error.dart
deleted file mode 100644
index d107954..0000000
--- a/pkg/analyzer-experimental/lib/src/generated/error.dart
+++ /dev/null
@@ -1,229 +0,0 @@
-// This code was auto-generated, is not intended to be edited, and is subject to
-// significant change. Please see the README file for more information.
-
-library engine.error;
-
-import 'java_core.dart';
-import 'source.dart';
-
-/**
- * Instances of the enumeration {@code ErrorType} represent the type of an {@link ErrorCode}.
- */
-class ErrorType {
-  /**
-   * Compile-time errors are errors that preclude execution. A compile time error must be reported
-   * by a Dart compiler before the erroneous code is executed.
-   */
-  static final ErrorType COMPILE_TIME_ERROR = new ErrorType('COMPILE_TIME_ERROR', 0, ErrorSeverity.ERROR);
-  /**
-   * Static warnings are those warnings reported by the static checker. They have no effect on
-   * execution. Static warnings must be provided by Dart compilers used during development.
-   */
-  static final ErrorType STATIC_WARNING = new ErrorType('STATIC_WARNING', 1, ErrorSeverity.WARNING);
-  /**
-   * Many, but not all, static warnings relate to types, in which case they are known as static type
-   * warnings.
-   */
-  static final ErrorType STATIC_TYPE_WARNING = new ErrorType('STATIC_TYPE_WARNING', 2, ErrorSeverity.WARNING);
-  /**
-   * Syntactic errors are errors produced as a result of input that does not conform to the grammar.
-   */
-  static final ErrorType SYNTACTIC_ERROR = new ErrorType('SYNTACTIC_ERROR', 3, ErrorSeverity.ERROR);
-  static final List<ErrorType> values = [COMPILE_TIME_ERROR, STATIC_WARNING, STATIC_TYPE_WARNING, SYNTACTIC_ERROR];
-  final String __name;
-  final int __ordinal;
-  /**
-   * The severity of this type of error.
-   */
-  ErrorSeverity _severity;
-  /**
-   * Initialize a newly created error type to have the given severity.
-   * @param severity the severity of this type of error
-   */
-  ErrorType(this.__name, this.__ordinal, ErrorSeverity severity) {
-    this._severity = severity;
-  }
-  /**
-   * Return the severity of this type of error.
-   * @return the severity of this type of error
-   */
-  ErrorSeverity get severity => _severity;
-  String toString() => __name;
-}
-/**
- * The interface {@code ErrorCode} defines the behavior common to objects representing error codes
- * associated with {@link AnalysisError analysis errors}.
- */
-abstract class ErrorCode {
-  /**
-   * Return the severity of this error.
-   * @return the severity of this error
-   */
-  ErrorSeverity get errorSeverity;
-  /**
-   * Return the message template used to create the message to be displayed for this error.
-   * @return the message template used to create the message to be displayed for this error
-   */
-  String get message;
-  /**
-   * Return the type of the error.
-   * @return the type of the error
-   */
-  ErrorType get type;
-  /**
-   * Return {@code true} if this error should cause recompilation of the source during the next
-   * incremental compilation.
-   * @return {@code true} if this error should cause recompilation of the source during the next
-   * incremental compilation
-   */
-  bool needsRecompilation();
-}
-/**
- * Instances of the enumeration {@code ErrorSeverity} represent the severity of an {@link ErrorCode}.
- */
-class ErrorSeverity {
-  /**
-   * The severity representing an error.
-   */
-  static final ErrorSeverity ERROR = new ErrorSeverity('ERROR', 0, "E");
-  /**
-   * The severity representing a warning. Warnings can become errors if the {@code -Werror} command
-   * line flag is specified.
-   */
-  static final ErrorSeverity WARNING = new ErrorSeverity('WARNING', 1, "W");
-  static final List<ErrorSeverity> values = [ERROR, WARNING];
-  final String __name;
-  final int __ordinal;
-  String _name;
-  ErrorSeverity(this.__name, this.__ordinal, String name) {
-    this._name = name;
-  }
-  String get name => _name;
-  String toString() => __name;
-}
-/**
- * The interface {@code AnalysisErrorListener} defines the behavior of objects that listen for{@link AnalysisError analysis errors} being produced by the analysis engine.
- */
-abstract class AnalysisErrorListener {
-  /**
-   * This method is invoked when an error has been found by the analysis engine.
-   * @param error the error that was just found (not {@code null})
-   */
-  void onError(AnalysisError error);
-}
-/**
- * Instances of the class {@code AnalysisError} represent an error discovered during the analysis of
- * some Dart code.
- * @see AnalysisErrorListener
- */
-class AnalysisError {
-  /**
-   * An empty array of errors used when no errors are expected.
-   */
-  static List<AnalysisError> NO_ERRORS = new List<AnalysisError>(0);
-  /**
-   * The error code associated with the error.
-   */
-  ErrorCode _errorCode;
-  /**
-   * The localized error message.
-   */
-  String _message;
-  /**
-   * The source in which the error occurred, or {@code null} if unknown.
-   */
-  Source _source;
-  /**
-   * The character offset from the beginning of the source (zero based) where the error occurred.
-   */
-  int _offset = 0;
-  /**
-   * The number of characters from the offset to the end of the source which encompasses the
-   * compilation error.
-   */
-  int _length = 0;
-  /**
-   * Initialize a newly created analysis error for the specified source. The error has no location
-   * information.
-   * @param source the source for which the exception occurred
-   * @param errorCode the error code to be associated with this error
-   * @param arguments the arguments used to build the error message
-   */
-  AnalysisError.con1(Source source2, ErrorCode errorCode2, List<Object> arguments) {
-    _jtd_constructor_122_impl(source2, errorCode2, arguments);
-  }
-  _jtd_constructor_122_impl(Source source2, ErrorCode errorCode2, List<Object> arguments) {
-    this._source = source2;
-    this._errorCode = errorCode2;
-    this._message = JavaString.format(errorCode2.message, arguments);
-  }
-  /**
-   * Initialize a newly created analysis error for the specified source at the given location.
-   * @param source the source for which the exception occurred
-   * @param offset the offset of the location of the error
-   * @param length the length of the location of the error
-   * @param errorCode the error code to be associated with this error
-   * @param arguments the arguments used to build the error message
-   */
-  AnalysisError.con2(Source source3, int offset2, int length11, ErrorCode errorCode3, List<Object> arguments) {
-    _jtd_constructor_123_impl(source3, offset2, length11, errorCode3, arguments);
-  }
-  _jtd_constructor_123_impl(Source source3, int offset2, int length11, ErrorCode errorCode3, List<Object> arguments) {
-    this._source = source3;
-    this._offset = offset2;
-    this._length = length11;
-    this._errorCode = errorCode3;
-    this._message = JavaString.format(errorCode3.message, arguments);
-  }
-  /**
-   * Return the error code associated with the error.
-   * @return the error code associated with the error
-   */
-  ErrorCode get errorCode => _errorCode;
-  /**
-   * Return the number of characters from the offset to the end of the source which encompasses the
-   * compilation error.
-   * @return the length of the error location
-   */
-  int get length => _length;
-  /**
-   * Return the localized error message.
-   * @return the localized error message
-   */
-  String get message => _message;
-  /**
-   * Return the character offset from the beginning of the source (zero based) where the error
-   * occurred.
-   * @return the offset to the start of the error location
-   */
-  int get offset => _offset;
-  /**
-   * Return the source in which the error occurred, or {@code null} if unknown.
-   * @return the source in which the error occurred
-   */
-  Source get source => _source;
-  int get hashCode {
-    int hashCode = _offset;
-    hashCode ^= (_message != null) ? _message.hashCode : 0;
-    hashCode ^= (_source != null) ? _source.hashCode : 0;
-    return hashCode;
-  }
-  /**
-   * Set the source in which the error occurred to the given source.
-   * @param source the source in which the error occurred
-   */
-  void set source(Source source4) {
-    this._source = source4;
-  }
-  String toString() {
-    StringBuffer builder = new StringBuffer();
-    builder.add((_source != null) ? _source.fullName : "<unknown source>");
-    builder.add("(");
-    builder.add(_offset);
-    builder.add("..");
-    builder.add(_offset + _length - 1);
-    builder.add("): ");
-    builder.add(_message);
-    return builder.toString();
-  }
-}
diff --git a/pkg/analyzer-experimental/lib/src/generated/instrumentation.dart b/pkg/analyzer-experimental/lib/src/generated/instrumentation.dart
deleted file mode 100644
index fbf9994..0000000
--- a/pkg/analyzer-experimental/lib/src/generated/instrumentation.dart
+++ /dev/null
@@ -1,189 +0,0 @@
-// This code was auto-generated, is not intended to be edited, and is subject to
-// significant change. Please see the README file for more information.
-
-library engine.instrumentation;
-
-import 'java_core.dart';
-
-/**
- * The interface {@code OperationBuilder} defines the behavior of objects used to collect data about
- * an operation that has occurred and record that data through an instrumentation logger.
- * <p>
- * For an example of using objects that implement this interface, see {@link Instrumentation}.
- */
-abstract class OperationBuilder {
-  /**
-   * Log the data that has been collected. The operation builder should not be used after this
-   * method is invoked. The behavior of any method defined on this interface that is used after this
-   * method is invoked is undefined.
-   */
-  void log();
-  /**
-   * Lazily compute and append the given data to the data being collected by this builder.
-   * @param name the name used to identify the data
-   * @param a function that will be executed in the background to return the value of the data to be
-   * collected
-   * @return this builder
-   */
-  OperationBuilder with2(String name, AsyncValue valueGenerator);
-  /**
-   * Append the given data to the data being collected by this builder.
-   * @param name the name used to identify the data
-   * @param value the value of the data to be collected
-   * @return this builder
-   */
-  OperationBuilder with3(String name, int value);
-  /**
-   * Append the given data to the data being collected by this builder.
-   * @param name the name used to identify the data
-   * @param value the value of the data to be collected
-   * @return this builder
-   */
-  OperationBuilder with4(String name, String value);
-  /**
-   * Append the given data to the data being collected by this builder.
-   * @param name the name used to identify the data
-   * @param value the value of the data to be collected
-   * @return this builder
-   */
-  OperationBuilder with5(String name, List<String> value);
-}
-/**
- * The interface {@code InstrumentationLogger} defines the behavior of objects that are used to log
- * instrumentation data.
- * <p>
- * For an example of using objects that implement this interface, see {@link Instrumentation}.
- */
-abstract class InstrumentationLogger {
-  /**
-   * Create an operation builder that can collect the data associated with an operation. The
-   * operation is identified by the given name, is declared to contain only metrics data (data that
-   * is not user identifiable and does not contain user intellectual property), and took the given
-   * amount of time to complete.
-   * @param name the name used to uniquely identify the operation
-   * @param time the number of milliseconds required to perform the operation, or {@code -1} if the
-   * time is not available or not applicable to this kind of operation
-   * @return the operation builder that was created
-   */
-  OperationBuilder createMetric(String name, int time);
-  /**
-   * Create an operation builder that can collect the data associated with an operation. The
-   * operation is identified by the given name, is declared to potentially contain data that is
-   * either user identifiable or contains user intellectual property (but is not guaranteed to
-   * contain either), and took the given amount of time to complete.
-   * @param name the name used to uniquely identify the operation
-   * @param time the number of milliseconds required to perform the operation, or {@code -1} if the
-   * time is not available or not applicable to this kind of operation
-   * @return the operation builder that was created
-   */
-  OperationBuilder createOperation(String name, int time);
-}
-abstract class AsyncValue {
-  /**
-   * Returns a String to be logged This would typically be used with an anonymous implementation
-   * closing over some variables with an expensive operation to be performed in the background
-   * @return The data to be logged
-   */
-  String compute();
-}
-/**
- * The class {@code Instrumentation} implements support for logging instrumentation information.
- * <p>
- * Instrumentation information consists of information about specific operations. Those operations
- * can range from user-facing operations, such as saving the changes to a file, to internal
- * operations, such as tokenizing source code. The information to be logged is gathered by an{@link OperationBuilder operation builder}, created by one of the static methods on this class.
- * <p>
- * Note, however, that until an instrumentation logger is installed using the method{@link #setLogger(InstrumentationLogger)}, all instrumentation data will be lost.
- * <p>
- * <b>Example</b>
- * <p>
- * To collect metrics about how long it took to save a file, you would write something like the
- * following:
- * <pre>
- * long startTime = System.currentTimeMillis();
- * // save the file
- * long endTime = System.currentTimeMillis();
- * metric("Save", endTime - startTime).with("chars", fileLength).log();
- * </pre>
- * The {@code metric} method creates an operation builder for an operation named {@code "Save"} that
- * took {@code endTime - startTime} milliseconds to run. The {@code with} method attaches additional
- * data to the operation; in this case recording that the file was {@code fileLength} characters
- * long. The {@code log} method tells the builder that all of the data has been collected and that
- * the resulting information should be logged.
- */
-class Instrumentation {
-  /**
-   * An instrumentation logger that can be used when no other instrumentation logger has been
-   * configured. This logger will silently ignore all data and logging requests.
-   */
-  static InstrumentationLogger _NULL_LOGGER = new InstrumentationLogger_5();
-  /**
-   * The current instrumentation logger.
-   */
-  static InstrumentationLogger _CURRENT_LOGGER = _NULL_LOGGER;
-  /**
-   * Create an operation builder that can collect the data associated with an operation. The
-   * operation is identified by the given name and is declared to contain only metrics data (data
-   * that is not user identifiable and does not contain user intellectual property).
-   * @param name the name used to uniquely identify the operation
-   * @return the operation builder that was created
-   */
-  static OperationBuilder metric(String name) => _CURRENT_LOGGER.createMetric(name, -1);
-  /**
-   * Create an operation builder that can collect the data associated with an operation. The
-   * operation is identified by the given name, is declared to contain only metrics data (data that
-   * is not user identifiable and does not contain user intellectual property), and took the given
-   * amount of time to complete.
-   * @param name the name used to uniquely identify the operation
-   * @param time the number of milliseconds required to perform the operation
-   * @return the operation builder that was created
-   */
-  static OperationBuilder metric2(String name, int time) => _CURRENT_LOGGER.createMetric(name, time);
-  /**
-   * Create an operation builder that can collect the data associated with an operation. The
-   * operation is identified by the given name and is declared to potentially contain data that is
-   * either user identifiable or contains user intellectual property (but is not guaranteed to
-   * contain either).
-   * @param name the name used to uniquely identify the operation
-   * @return the operation builder that was created
-   */
-  static OperationBuilder operation(String name) => _CURRENT_LOGGER.createOperation(name, -1);
-  /**
-   * Create an operation builder that can collect the data associated with an operation. The
-   * operation is identified by the given name, is declared to potentially contain data that is
-   * either user identifiable or contains user intellectual property (but is not guaranteed to
-   * contain either), and took the given amount of time to complete.
-   * @param name the name used to uniquely identify the operation
-   * @param time the number of milliseconds required to perform the operation
-   * @return the operation builder that was created
-   */
-  static OperationBuilder operation2(String name, int time) => _CURRENT_LOGGER.createOperation(name, time);
-  /**
-   * Set the logger that should receive instrumentation information to the given logger.
-   * @param logger the logger that should receive instrumentation information
-   */
-  static void set logger(InstrumentationLogger logger3) {
-    _CURRENT_LOGGER = logger3 == null ? _NULL_LOGGER : logger3;
-  }
-  /**
-   * Prevent the creation of instances of this class
-   */
-  Instrumentation() {
-  }
-}
-class InstrumentationLogger_5 implements InstrumentationLogger {
-  /**
-   * An operation builder that will silently ignore all data and logging requests.
-   */
-  OperationBuilder _NULL_BUILDER = new OperationBuilder_6();
-  OperationBuilder createMetric(String name, int time) => _NULL_BUILDER;
-  OperationBuilder createOperation(String name, int time) => _NULL_BUILDER;
-}
-class OperationBuilder_6 implements OperationBuilder {
-  void log() {
-  }
-  OperationBuilder with2(String name, AsyncValue valueGenerator) => this;
-  OperationBuilder with3(String name, int value) => this;
-  OperationBuilder with4(String name, String value) => this;
-  OperationBuilder with5(String name, List<String> value) => this;
-}
\ No newline at end of file
diff --git a/pkg/analyzer-experimental/lib/src/generated/java_engine.dart b/pkg/analyzer-experimental/lib/src/generated/java_engine.dart
deleted file mode 100644
index b1c131a4..0000000
--- a/pkg/analyzer-experimental/lib/src/generated/java_engine.dart
+++ /dev/null
@@ -1,56 +0,0 @@
-library java.engine;
-
-import "dart:io";
-import "java_core.dart";
-import "source.dart";
-import "error.dart";
-import "ast.dart";
-import "element.dart";
-
-//class AnalysisException implements Exception {
-//  String toString() => "AnalysisException";
-//}
-
-//class AnalysisEngine {
-//  static getInstance() {
-//    throw new UnsupportedOperationException();
-//  }
-//}
-
-//class AnalysisContext {
-//  Element getElement(ElementLocation location) {
-//    throw new UnsupportedOperationException();
-//  }
-//}
-
-//class AnalysisContextImpl extends AnalysisContext {
-//  getSourceFactory() {
-//    throw new UnsupportedOperationException();
-//  }
-//  LibraryElement getLibraryElementOrNull(Source source) {
-//    return null;
-//  }
-//  LibraryElement getLibraryElement(Source source) {
-//    throw new UnsupportedOperationException();
-//  }
-//  void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
-//    throw new UnsupportedOperationException();
-//  }
-//  getPublicNamespace(LibraryElement library) {
-//    throw new UnsupportedOperationException();
-//  }
-//  CompilationUnit parse(Source source, AnalysisErrorListener errorListener) {
-//    throw new UnsupportedOperationException();
-//  }
-//}
-
-class StringUtilities {
-  static List<String> EMPTY_ARRAY = new List(0);
-}
-
-File createFile(String path) => new File(path);
-
-class OSUtilities {
-  static bool isWindows() => Platform.operatingSystem == 'windows';
-  static bool isMac() => Platform.operatingSystem == 'macos';
-}
diff --git a/pkg/analyzer-experimental/lib/src/generated/source.dart b/pkg/analyzer-experimental/lib/src/generated/source.dart
deleted file mode 100644
index 811dce2..0000000
--- a/pkg/analyzer-experimental/lib/src/generated/source.dart
+++ /dev/null
@@ -1,624 +0,0 @@
-// This code was auto-generated, is not intended to be edited, and is subject to
-// significant change. Please see the README file for more information.
-
-library engine.source;
-
-import 'dart:io';
-import 'dart:uri';
-import 'java_core.dart';
-import 'package:analyzer-experimental/src/generated/sdk.dart' show DartSdk;
-
-/**
- * Instances of the class {@code FileUriResolver} resolve {@code file} URI's.
- */
-class FileUriResolver extends UriResolver {
-  /**
-   * The name of the {@code file} scheme.
-   */
-  static String _FILE_SCHEME = "file";
-  /**
-   * Return {@code true} if the given URI is a {@code file} URI.
-   * @param uri the URI being tested
-   * @return {@code true} if the given URI is a {@code file} URI
-   */
-  static bool isFileUri(Uri uri) => uri.scheme == _FILE_SCHEME;
-  /**
-   * Initialize a newly created resolver to resolve {@code file} URI's relative to the given root
-   * directory.
-   */
-  FileUriResolver() : super() {
-  }
-  Source resolveAbsolute(SourceFactory factory, Uri uri) {
-    if (!isFileUri(uri)) {
-      return null;
-    }
-    return new FileBasedSource.con1(factory, newFileFromUri(uri));
-  }
-}
-/**
- * Instances of the class {@code DartUriResolver} resolve {@code dart} URI's.
- */
-class DartUriResolver extends UriResolver {
-  /**
-   * The Dart SDK against which URI's are to be resolved.
-   */
-  DartSdk _sdk;
-  /**
-   * The name of the {@code dart} scheme.
-   */
-  static String _DART_SCHEME = "dart";
-  /**
-   * Return {@code true} if the given URI is a {@code dart:} URI.
-   * @param uri the URI being tested
-   * @return {@code true} if the given URI is a {@code dart:} URI
-   */
-  static bool isDartUri(Uri uri) => uri.scheme == _DART_SCHEME;
-  /**
-   * Initialize a newly created resolver to resolve Dart URI's against the given platform within the
-   * given Dart SDK.
-   * @param sdk the Dart SDK against which URI's are to be resolved
-   */
-  DartUriResolver(DartSdk sdk) {
-    this._sdk = sdk;
-  }
-  Source resolveAbsolute(SourceFactory factory, Uri uri) {
-    if (!isDartUri(uri)) {
-      return null;
-    }
-    File resolvedFile = _sdk.mapDartUri(uri.toString());
-    return new FileBasedSource.con2(factory, resolvedFile, true);
-  }
-}
-/**
- * Instances of the class {@code FileBasedSource} implement a source that represents a file.
- */
-class FileBasedSource implements Source {
-  /**
-   * The source factory that created this source and that should be used to resolve URI's against
-   * this source.
-   */
-  SourceFactory _factory;
-  /**
-   * The file represented by this source.
-   */
-  File _file;
-  /**
-   * A flag indicating whether this source is in one of the system libraries.
-   */
-  bool _inSystemLibrary = false;
-  /**
-   * Initialize a newly created source object. The source object is assumed to not be in a system
-   * library.
-   * @param factory the source factory that created this source
-   * @param file the file represented by this source
-   */
-  FileBasedSource.con1(SourceFactory factory, File file) {
-    _jtd_constructor_243_impl(factory, file);
-  }
-  _jtd_constructor_243_impl(SourceFactory factory, File file) {
-    _jtd_constructor_244_impl(factory, file, false);
-  }
-  /**
-   * Initialize a newly created source object.
-   * @param factory the source factory that created this source
-   * @param file the file represented by this source
-   * @param inSystemLibrary {@code true} if this source is in one of the system libraries
-   */
-  FileBasedSource.con2(SourceFactory factory2, File file3, bool inSystemLibrary2) {
-    _jtd_constructor_244_impl(factory2, file3, inSystemLibrary2);
-  }
-  _jtd_constructor_244_impl(SourceFactory factory2, File file3, bool inSystemLibrary2) {
-    this._factory = factory2;
-    this._file = file3;
-    this._inSystemLibrary = inSystemLibrary2;
-  }
-  bool operator ==(Object object) => object != null && identical(this.runtimeType, object.runtimeType) && _file == ((object as FileBasedSource))._file;
-  void getContents(Source_ContentReceiver receiver) {
-    receiver.accept2(_file.readAsStringSync());
-  }
-  String get fullName => _file.fullPathSync();
-  String get shortName => _file.name;
-  int get hashCode => _file.hashCode;
-  bool isInSystemLibrary() => _inSystemLibrary;
-  Source resolve(String uri) => _factory.resolveUri(this, uri);
-  String toString() {
-    if (_file == null) {
-      return "<unknown source>";
-    }
-    return _file.fullPathSync();
-  }
-  /**
-   * Return the file represented by this source. This is an internal method that is only intended to
-   * be used by {@link UriResolver}.
-   * @return the file represented by this source
-   */
-  File get file => _file;
-}
-/**
- * Instances of the class {@link DirectoryBasedSourceContainer} represent a source container that
- * contains all sources within a given directory.
- */
-class DirectoryBasedSourceContainer implements SourceContainer {
-  /**
-   * Append the system file separator to the given path unless the path already ends with a
-   * separator.
-   * @param path the path to which the file separator is to be added
-   * @return a path that ends with the system file separator
-   */
-  static String appendFileSeparator(String path) {
-    if (path == null || path.length <= 0 || path.codeUnitAt(path.length - 1) == System.pathSeparatorChar) {
-      return path;
-    }
-    return "${path}${System.pathSeparator}";
-  }
-  /**
-   * The container's path (not {@code null}).
-   */
-  String _path;
-  /**
-   * Construct a container representing the specified directory and containing any sources whose{@link Source#getFullName()} starts with the directory's path. This is a convenience method,
-   * fully equivalent to {@link DirectoryBasedSourceContainer#DirectoryBasedSourceContainer(String)}.
-   * @param directory the directory (not {@code null})
-   */
-  DirectoryBasedSourceContainer.con1(File directory) {
-    _jtd_constructor_241_impl(directory);
-  }
-  _jtd_constructor_241_impl(File directory) {
-    _jtd_constructor_242_impl(directory.fullPathSync());
-  }
-  /**
-   * Construct a container representing the specified path and containing any sources whose{@link Source#getFullName()} starts with the specified path.
-   * @param path the path (not {@code null} and not empty)
-   */
-  DirectoryBasedSourceContainer.con2(String path3) {
-    _jtd_constructor_242_impl(path3);
-  }
-  _jtd_constructor_242_impl(String path3) {
-    this._path = appendFileSeparator(path3);
-  }
-  bool contains(Source source) => source.fullName.startsWith(_path);
-  bool operator ==(Object obj) => (obj is DirectoryBasedSourceContainer) && ((obj as DirectoryBasedSourceContainer)).path == path;
-  /**
-   * Answer the receiver's path, used to determine if a source is contained in the receiver.
-   * @return the path (not {@code null}, not empty)
-   */
-  String get path => _path;
-  int get hashCode => _path.hashCode;
-}
-/**
- * Instances of the class {@code PackageUriResolver} resolve {@code package} URI's in the context of
- * an application.
- */
-class PackageUriResolver extends UriResolver {
-  /**
-   * The package directories that {@code package} URI's are assumed to be relative to.
-   */
-  List<File> _packagesDirectories;
-  /**
-   * The name of the {@code package} scheme.
-   */
-  static String _PACKAGE_SCHEME = "package";
-  /**
-   * Return {@code true} if the given URI is a {@code package} URI.
-   * @param uri the URI being tested
-   * @return {@code true} if the given URI is a {@code package} URI
-   */
-  static bool isPackageUri(Uri uri) => uri.scheme == _PACKAGE_SCHEME;
-  /**
-   * Initialize a newly created resolver to resolve {@code package} URI's relative to the given
-   * package directories.
-   * @param packagesDirectories the package directories that {@code package} URI's are assumed to be
-   * relative to
-   */
-  PackageUriResolver(List<File> packagesDirectories) {
-    if (packagesDirectories.length < 1) {
-      throw new IllegalArgumentException("At least one package directory must be provided");
-    }
-    this._packagesDirectories = packagesDirectories;
-  }
-  Source resolveAbsolute(SourceFactory factory, Uri uri) {
-    if (!isPackageUri(uri)) {
-      return null;
-    }
-    String path4 = uri.path;
-    if (path4 == null) {
-      path4 = uri.path;
-      if (path4 == null) {
-        return null;
-      }
-    }
-    for (File packagesDirectory in _packagesDirectories) {
-      File resolvedFile = newRelativeFile(packagesDirectory, path4);
-      if (resolvedFile.existsSync()) {
-        return new FileBasedSource.con1(factory, resolvedFile);
-      }
-    }
-    return new FileBasedSource.con1(factory, newRelativeFile(_packagesDirectories[0], path4));
-  }
-}
-/**
- * The abstract class {@code UriResolver} defines the behavior of objects that are used to resolve
- * URI's for a source factory. Subclasses of this class are expected to resolve a single scheme of
- * absolute URI.
- */
-abstract class UriResolver {
-  /**
-   * Initialize a newly created resolver.
-   */
-  UriResolver() : super() {
-  }
-  /**
-   * Working on behalf of the given source factory, resolve the (possibly relative) contained URI
-   * against the URI associated with the containing source object. Return a {@link Source source}representing the file to which it was resolved, or {@code null} if it could not be resolved.
-   * @param factory the source factory requesting the resolution of the URI
-   * @param containingSource the source containing the given URI
-   * @param containedUri the (possibly relative) URI to be resolved against the containing source
-   * @return a {@link Source source} representing the URI to which given URI was resolved
-   */
-  Source resolve(SourceFactory factory, Source containingSource, Uri containedUri) {
-    if (containedUri.isAbsolute()) {
-      return resolveAbsolute(factory, containedUri);
-    } else {
-      return resolveRelative(factory, containingSource, containedUri);
-    }
-  }
-  /**
-   * Resolve the given absolute URI. Return a {@link Source source} representing the file to which
-   * it was resolved, or {@code null} if it could not be resolved.
-   * @param uri the URI to be resolved
-   * @return a {@link Source source} representing the URI to which given URI was resolved
-   */
-  Source resolveAbsolute(SourceFactory factory, Uri uri);
-  /**
-   * Resolve the relative (contained) URI against the URI associated with the containing source
-   * object. Return a {@link Source source} representing the file to which it was resolved, or{@code null} if it could not be resolved.
-   * @param containingSource the source containing the given URI
-   * @param containedUri the (possibly relative) URI to be resolved against the containing source
-   * @return a {@link Source source} representing the URI to which given URI was resolved
-   */
-  Source resolveRelative(SourceFactory factory, Source containingSource, Uri containedUri) {
-    if (containingSource is FileBasedSource) {
-      try {
-        Uri resolvedUri = newUriFromFile(((containingSource as FileBasedSource)).file).resolveUri(containedUri);
-        return new FileBasedSource.con1(factory, newFileFromUri(resolvedUri));
-      } on JavaException catch (exception) {
-      }
-    }
-    return null;
-  }
-}
-/**
- * Instances of the class {@code SourceFactory} resolve possibly relative URI's against an existing{@link Source source}.
- */
-class SourceFactory {
-  /**
-   * The resolvers used to resolve absolute URI's.
-   */
-  List<UriResolver> _resolvers;
-  /**
-   * A cache of content used to override the default content of a source.
-   */
-  ContentCache _contentCache;
-  /**
-   * Initialize a newly created source factory.
-   * @param contentCache the cache holding content used to override the default content of a source.
-   * @param resolvers the resolvers used to resolve absolute URI's
-   */
-  SourceFactory.con1(ContentCache contentCache2, List<UriResolver> resolvers2) {
-    _jtd_constructor_247_impl(contentCache2, resolvers2);
-  }
-  _jtd_constructor_247_impl(ContentCache contentCache2, List<UriResolver> resolvers2) {
-    this._contentCache = contentCache2;
-    this._resolvers = resolvers2;
-  }
-  /**
-   * Initialize a newly created source factory.
-   * @param resolvers the resolvers used to resolve absolute URI's
-   */
-  SourceFactory.con2(List<UriResolver> resolvers) {
-    _jtd_constructor_248_impl(resolvers);
-  }
-  _jtd_constructor_248_impl(List<UriResolver> resolvers) {
-    _jtd_constructor_247_impl(new ContentCache(), [resolvers]);
-  }
-  /**
-   * Return a source container representing the given directory
-   * @param directory the directory (not {@code null})
-   * @return the source container representing the directory (not {@code null})
-   */
-  SourceContainer forDirectory(File directory) => new DirectoryBasedSourceContainer.con1(directory);
-  /**
-   * Return a source object representing the given file.
-   * @param file the file to be represented by the returned source object
-   * @return a source object representing the given file
-   */
-  Source forFile(File file) => new FileBasedSource.con1(this, file);
-  /**
-   * Return a source object representing the given absolute URI, or {@code null} if the URI is not a
-   * valid URI or if it is not an absolute URI.
-   * @param absoluteUri the absolute URI to be resolved
-   * @return a source object representing the absolute URI
-   */
-  Source forUri(String absoluteUri) {
-    try {
-      Uri uri = new Uri.fromComponents(path: absoluteUri);
-      if (uri.isAbsolute()) {
-        return resolveUri2(null, uri);
-      }
-    } on URISyntaxException catch (exception) {
-    }
-    return null;
-  }
-  /**
-   * Return a source object representing the URI that results from resolving the given (possibly
-   * relative) contained URI against the URI associated with an existing source object, or{@code null} if either the contained URI is invalid or if it cannot be resolved against the
-   * source object's URI.
-   * @param containingSource the source containing the given URI
-   * @param containedUri the (possibly relative) URI to be resolved against the containing source
-   * @return the source representing the contained URI
-   */
-  Source resolveUri(Source containingSource, String containedUri) {
-    try {
-      return resolveUri2(containingSource, new Uri.fromComponents(path: containedUri));
-    } on URISyntaxException catch (exception) {
-      return null;
-    }
-  }
-  /**
-   * Set the contents of the given source to the given contents. This has the effect of overriding
-   * the default contents of the source. If the contents are {@code null} the override is removed so
-   * that the default contents will be returned.
-   * @param source the source whose contents are being overridden
-   * @param contents the new contents of the source
-   */
-  void setContents(Source source, String contents) {
-    _contentCache.setContents(source, contents);
-  }
-  /**
-   * Return the contents of the given source, or {@code null} if this factory does not override the
-   * contents of the source.
-   * <p>
-   * <b>Note:</b> This method is not intended to be used except by{@link FileBasedSource#getContents(com.google.dart.engine.source.Source.ContentReceiver)}.
-   * @param source the source whose content is to be returned
-   * @return the contents of the given source
-   */
-  String getContents(Source source) => _contentCache.getContents(source);
-  /**
-   * Return a source object representing the URI that results from resolving the given (possibly
-   * relative) contained URI against the URI associated with an existing source object, or{@code null} if either the contained URI is invalid or if it cannot be resolved against the
-   * source object's URI.
-   * @param containingSource the source containing the given URI
-   * @param containedUri the (possibly relative) URI to be resolved against the containing source
-   * @return the source representing the contained URI
-   */
-  Source resolveUri2(Source containingSource, Uri containedUri) {
-    for (UriResolver resolver in _resolvers) {
-      Source result = resolver.resolve(this, containingSource, containedUri);
-      if (result != null) {
-        return result;
-      }
-    }
-    return null;
-  }
-}
-/**
- * The interface {@code Source} defines the behavior of objects representing source code that can be
- * compiled.
- */
-abstract class Source {
-  /**
-   * Return {@code true} if the given object is a source that represents the same source code as
-   * this source.
-   * @param object the object to be compared with this object
-   * @return {@code true} if the given object is a source that represents the same source code as
-   * this source
-   * @see Object#equals(Object)
-   */
-  bool operator ==(Object object);
-  /**
-   * Get the contents of this source and pass it to the given receiver. Exactly one of the methods
-   * defined on the receiver will be invoked unless an exception is thrown. The method that will be
-   * invoked depends on which of the possible representations of the contents is the most efficient.
-   * Whichever method is invoked, it will be invoked before this method returns.
-   * @param receiver the content receiver to which the content of this source will be passed
-   * @throws Exception if the contents of this source could not be accessed
-   */
-  void getContents(Source_ContentReceiver receiver);
-  /**
-   * Return the full (long) version of the name that can be displayed to the user to denote this
-   * source. For example, for a source representing a file this would typically be the absolute path
-   * of the file.
-   * @return a name that can be displayed to the user to denote this source
-   */
-  String get fullName;
-  /**
-   * Return a short version of the name that can be displayed to the user to denote this source. For
-   * example, for a source representing a file this would typically be the name of the file.
-   * @return a name that can be displayed to the user to denote this source
-   */
-  String get shortName;
-  /**
-   * Return a hash code for this source.
-   * @return a hash code for this source
-   * @see Object#hashCode()
-   */
-  int get hashCode;
-  /**
-   * Return {@code true} if this source is in one of the system libraries.
-   * @return {@code true} if this is in a system library
-   */
-  bool isInSystemLibrary();
-  /**
-   * Resolve the given URI relative to the location of this source.
-   * @param uri the URI to be resolved against this source
-   * @return a source representing the resolved URI
-   */
-  Source resolve(String uri);
-}
-/**
- * The interface {@code ContentReceiver} defines the behavior of objects that can receive the
- * content of a source.
- */
-abstract class Source_ContentReceiver {
-  /**
-   * Accept the contents of a source represented as a character buffer.
-   * @param contents the contents of the source
-   */
-  accept(CharBuffer contents);
-  /**
-   * Accept the contents of a source represented as a string.
-   * @param contents the contents of the source
-   */
-  void accept2(String contents);
-}
-/**
- * Instances of class {@code ContentCache} hold content used to override the default content of a{@link Source}.
- */
-class ContentCache {
-  /**
-   * A table mapping sources to the contents of those sources. This is used to override the default
-   * contents of a source.
-   */
-  Map<Source, String> _contentMap = new Map<Source, String>();
-  /**
-   * Return the contents of the given source, or {@code null} if this cache does not override the
-   * contents of the source.
-   * <p>
-   * <b>Note:</b> This method is not intended to be used except by{@link SourceFactory#getContents(com.google.dart.engine.source.Source.ContentReceiver)}.
-   * @param source the source whose content is to be returned
-   * @return the contents of the given source
-   */
-  String getContents(Source source) => _contentMap[source];
-  /**
-   * Set the contents of the given source to the given contents. This has the effect of overriding
-   * the default contents of the source. If the contents are {@code null} the override is removed so
-   * that the default contents will be returned.
-   * @param source the source whose contents are being overridden
-   * @param contents the new contents of the source
-   */
-  void setContents(Source source, String contents) {
-    if (contents == null) {
-      _contentMap.remove(source);
-    } else {
-      _contentMap[source] = contents;
-    }
-  }
-}
-/**
- * The interface {@code SourceContainer} is used by clients to define a collection of sources
- * <p>
- * Source containers are not used within analysis engine, but can be used by clients to group
- * sources for the purposes of accessing composite dependency information. For example, the Eclipse
- * client uses source containers to represent Eclipse projects, which allows it to easily compute
- * project-level dependencies.
- */
-abstract class SourceContainer {
-  /**
-   * Determine if the specified source is part of the receiver's collection of sources.
-   * @param source the source in question
-   * @return {@code true} if the receiver contains the source, else {@code false}
-   */
-  bool contains(Source source);
-}
-/**
- * Instances of the class {@code LineInfo} encapsulate information about line and column information
- * within a source file.
- */
-class LineInfo {
-  /**
-   * An array containing the offsets of the first character of each line in the source code.
-   */
-  List<int> _lineStarts;
-  /**
-   * Initialize a newly created set of line information to represent the data encoded in the given
-   * array.
-   * @param lineStarts the offsets of the first character of each line in the source code
-   */
-  LineInfo(List<int> lineStarts) {
-    if (lineStarts == null) {
-      throw new IllegalArgumentException("lineStarts must be non-null");
-    } else if (lineStarts.length < 1) {
-      throw new IllegalArgumentException("lineStarts must be non-empty");
-    }
-    this._lineStarts = lineStarts;
-  }
-  /**
-   * Return the location information for the character at the given offset.
-   * @param offset the offset of the character for which location information is to be returned
-   * @return the location information for the character at the given offset
-   */
-  LineInfo_Location getLocation(int offset) {
-    int lineCount = _lineStarts.length;
-    for (int i = 1; i < lineCount; i++) {
-      if (offset < _lineStarts[i]) {
-        return new LineInfo_Location(i, offset - _lineStarts[i - 1] + 1);
-      }
-    }
-    return new LineInfo_Location(lineCount, offset - _lineStarts[lineCount - 1] + 1);
-  }
-}
-/**
- * Instances of the class {@code Location} represent the location of a character as a line and
- * column pair.
- */
-class LineInfo_Location {
-  /**
-   * The one-based index of the line containing the character.
-   */
-  int _lineNumber = 0;
-  /**
-   * The one-based index of the column containing the character.
-   */
-  int _columnNumber = 0;
-  /**
-   * Initialize a newly created location to represent the location of the character at the given
-   * line and column position.
-   * @param lineNumber the one-based index of the line containing the character
-   * @param columnNumber the one-based index of the column containing the character
-   */
-  LineInfo_Location(int lineNumber, int columnNumber) {
-    this._lineNumber = lineNumber;
-    this._columnNumber = columnNumber;
-  }
-  /**
-   * Return the one-based index of the column containing the character.
-   * @return the one-based index of the column containing the character
-   */
-  int get columnNumber => _columnNumber;
-  /**
-   * Return the one-based index of the line containing the character.
-   * @return the one-based index of the line containing the character
-   */
-  int get lineNumber => _lineNumber;
-}
-/**
- * The enumeration {@code SourceKind} defines the different kinds of sources that are known to the
- * analysis engine.
- */
-class SourceKind {
-  /**
-   * A source containing HTML. The HTML might or might not contain Dart scripts.
-   */
-  static final SourceKind HTML = new SourceKind('HTML', 0);
-  /**
-   * A Dart compilation unit that is not a part of another library. Libraries might or might not
-   * contain any directives, including a library directive.
-   */
-  static final SourceKind LIBRARY = new SourceKind('LIBRARY', 1);
-  /**
-   * A Dart compilation unit that is part of another library. Parts contain a part-of directive.
-   */
-  static final SourceKind PART = new SourceKind('PART', 2);
-  /**
-   * An unknown kind of source. Used both when it is not possible to identify the kind of a source
-   * and also when the kind of a source is not known without performing a computation and the client
-   * does not want to spend the time to identify the kind.
-   */
-  static final SourceKind UNKNOWN = new SourceKind('UNKNOWN', 3);
-  static final List<SourceKind> values = [HTML, LIBRARY, PART, UNKNOWN];
-  final String __name;
-  final int __ordinal;
-  SourceKind(this.__name, this.__ordinal) {
-  }
-  String toString() => __name;
-}
\ No newline at end of file
diff --git a/pkg/analyzer-experimental/README.md b/pkg/analyzer_experimental/README.md
similarity index 100%
rename from pkg/analyzer-experimental/README.md
rename to pkg/analyzer_experimental/README.md
diff --git a/pkg/analyzer-experimental/bin/analyzer.dart b/pkg/analyzer_experimental/bin/analyzer.dart
similarity index 95%
rename from pkg/analyzer-experimental/bin/analyzer.dart
rename to pkg/analyzer_experimental/bin/analyzer.dart
index 2214490..cb730cd 100644
--- a/pkg/analyzer-experimental/bin/analyzer.dart
+++ b/pkg/analyzer_experimental/bin/analyzer.dart
@@ -10,7 +10,7 @@
 import 'dart:async';
 import 'dart:io';
 
-import 'package:analyzer-experimental/options.dart';
+import 'package:analyzer_experimental/options.dart';
 
 // Exit status codes.
 const OK_EXIT = 0;
diff --git a/pkg/analyzer-experimental/example/parser_driver.dart b/pkg/analyzer_experimental/example/parser_driver.dart
similarity index 79%
rename from pkg/analyzer-experimental/example/parser_driver.dart
rename to pkg/analyzer_experimental/example/parser_driver.dart
index 061a055..8501552 100644
--- a/pkg/analyzer-experimental/example/parser_driver.dart
+++ b/pkg/analyzer_experimental/example/parser_driver.dart
@@ -4,29 +4,29 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer-experimental/src/generated/ast.dart';
-import 'package:analyzer-experimental/src/generated/error.dart';
-import 'package:analyzer-experimental/src/generated/java_core.dart';
-import 'package:analyzer-experimental/src/generated/parser.dart';
-import 'package:analyzer-experimental/src/generated/scanner.dart';
+import 'package:analyzer_experimental/src/generated/ast.dart';
+import 'package:analyzer_experimental/src/generated/error.dart';
+import 'package:analyzer_experimental/src/generated/java_core.dart';
+import 'package:analyzer_experimental/src/generated/parser.dart';
+import 'package:analyzer_experimental/src/generated/scanner.dart';
 
 import 'dart:io';
 
 
 main() {
-  
+
   print('working dir ${new File('.').fullPathSync()}');
-  
+
   var args = new Options().arguments;
   if (args.length == 0) {
     print('Usage: parser_driver [files_to_parse]');
     exit(0);
   }
-  
+
   for (var arg in args) {
     _parse(new File(arg));
   }
-  
+
 }
 
 _parse(File file) {
@@ -36,10 +36,10 @@
   var token = scanner.tokenize();
   var parser = new Parser(null, errorListener);
   var unit = parser.parseCompilationUnit(token);
-  
+
   var visitor = new _ASTVisitor();
   unit.accept(visitor);
-  
+
   for (var error in errorListener.errors) {
     print(error);
   }
diff --git a/pkg/analyzer-experimental/example/scanner_driver.dart b/pkg/analyzer_experimental/example/scanner_driver.dart
similarity index 84%
rename from pkg/analyzer-experimental/example/scanner_driver.dart
rename to pkg/analyzer_experimental/example/scanner_driver.dart
index ab5a46c..0455cbe 100644
--- a/pkg/analyzer-experimental/example/scanner_driver.dart
+++ b/pkg/analyzer_experimental/example/scanner_driver.dart
@@ -4,25 +4,25 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer-experimental/src/generated/java_core.dart';
-import 'package:analyzer-experimental/src/generated/scanner.dart';
+import 'package:analyzer_experimental/src/generated/java_core.dart';
+import 'package:analyzer_experimental/src/generated/scanner.dart';
 
 import 'dart:io';
 
 main() {
-  
+
   print('working dir ${new File('.').fullPathSync()}');
-  
+
   var args = new Options().arguments;
   if (args.length == 0) {
     print('Usage: scanner_driver [files_to_scan]');
     exit(0);
   }
-  
+
   for (var arg in args) {
     _scan(new File(arg));
   }
-  
+
 }
 
 _scan(File file) {
diff --git a/pkg/analyzer-experimental/lib/analyzer.dart b/pkg/analyzer_experimental/lib/analyzer.dart
similarity index 100%
rename from pkg/analyzer-experimental/lib/analyzer.dart
rename to pkg/analyzer_experimental/lib/analyzer.dart
diff --git a/pkg/analyzer-experimental/lib/options.dart b/pkg/analyzer_experimental/lib/options.dart
similarity index 100%
rename from pkg/analyzer-experimental/lib/options.dart
rename to pkg/analyzer_experimental/lib/options.dart
diff --git a/pkg/analyzer-experimental/lib/src/generated/ast.dart b/pkg/analyzer_experimental/lib/src/generated/ast.dart
similarity index 92%
rename from pkg/analyzer-experimental/lib/src/generated/ast.dart
rename to pkg/analyzer_experimental/lib/src/generated/ast.dart
index 3c842d7..b47c576 100644
--- a/pkg/analyzer-experimental/lib/src/generated/ast.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/ast.dart
@@ -7,6 +7,7 @@
 import 'java_core.dart';
 import 'java_engine.dart';
 import 'error.dart';
+import 'source.dart' show LineInfo;
 import 'scanner.dart';
 import 'engine.dart' show AnalysisEngine;
 import 'utilities_dart.dart';
@@ -15,6 +16,7 @@
 /**
  * The abstract class {@code ASTNode} defines the behavior common to all nodes in the AST structure
  * for a Dart program.
+ * @coverage dart.engine.ast
  */
 abstract class ASTNode {
   /**
@@ -22,6 +24,11 @@
    */
   ASTNode _parent;
   /**
+   * A table mapping the names of properties to their values, or {@code null} if this node does not
+   * have any properties associated with it.
+   */
+  Map<String, Object> _propertyMap;
+  /**
    * A comparator that can be used to sort AST nodes in lexical order. In other words,{@code compare} will return a negative value if the offset of the first node is less than the
    * offset of the second node, zero (0) if the nodes have the same offset, and a positive value if
    * if the offset of the first node is greater than the offset of the second node.
@@ -43,7 +50,7 @@
       node = node.parent;
     }
     ;
-    return (node as ASTNode);
+    return node as ASTNode;
   }
   /**
    * Return the first token included in this node's source range.
@@ -97,6 +104,17 @@
    */
   ASTNode get parent => _parent;
   /**
+   * Return the value of the property with the given name, or {@code null} if this node does not
+   * have a property with the given name.
+   * @return the value of the property with the given name
+   */
+  Object getProperty(String propertyName) {
+    if (_propertyMap == null) {
+      return null;
+    }
+    return _propertyMap[propertyName];
+  }
+  /**
    * Return the node at the root of this node's AST structure. Note that this method's performance
    * is linear with respect to the depth of the node in the AST structure (O(depth)).
    * @return the node at the root of this node's AST structure
@@ -118,6 +136,26 @@
    */
   bool isSynthetic() => false;
   /**
+   * Set the value of the property with the given name to the given value. If the value is{@code null}, the property will effectively be removed.
+   * @param propertyName the name of the property whose value is to be set
+   * @param propertyValue the new value of the property
+   */
+  void setProperty(String propertyName, Object propertyValue) {
+    if (propertyValue == null) {
+      if (_propertyMap != null) {
+        _propertyMap.remove(propertyName);
+        if (_propertyMap.isEmpty) {
+          _propertyMap = null;
+        }
+      }
+    } else {
+      if (_propertyMap == null) {
+        _propertyMap = new Map<String, Object>();
+      }
+      _propertyMap[propertyName] = propertyValue;
+    }
+  }
+  /**
    * Return a textual description of this node in a form approximating valid source. The returned
    * string will not be valid source primarily in the case where the node itself is not well-formed.
    * @return the source code equivalent of this node
@@ -169,6 +207,7 @@
 /**
  * The interface {@code ASTVisitor} defines the behavior of objects that can be used to visit an AST
  * structure.
+ * @coverage dart.engine.ast
  */
 abstract class ASTVisitor<R> {
   R visitAdjacentStrings(AdjacentStrings node);
@@ -195,6 +234,7 @@
   R visitConstructorFieldInitializer(ConstructorFieldInitializer node);
   R visitConstructorName(ConstructorName node);
   R visitContinueStatement(ContinueStatement node);
+  R visitDeclaredIdentifier(DeclaredIdentifier node);
   R visitDefaultFormalParameter(DefaultFormalParameter node);
   R visitDoStatement(DoStatement node);
   R visitDoubleLiteral(DoubleLiteral node);
@@ -279,6 +319,7 @@
  * <pre>
  * adjacentStrings ::={@link StringLiteral string} {@link StringLiteral string}+
  * </pre>
+ * @coverage dart.engine.ast
  */
 class AdjacentStrings extends StringLiteral {
   /**
@@ -313,6 +354,7 @@
 /**
  * The abstract class {@code AnnotatedNode} defines the behavior of nodes that can be annotated with
  * both a comment and metadata.
+ * @coverage dart.engine.ast
  */
 abstract class AnnotatedNode extends ASTNode {
   /**
@@ -425,6 +467,7 @@
  * annotation ::=
  * '@' {@link Identifier qualified} (‘.’ {@link SimpleIdentifier identifier})? {@link ArgumentList arguments}?
  * </pre>
+ * @coverage dart.engine.ast
  */
 class Annotation extends ASTNode {
   /**
@@ -569,6 +612,7 @@
  * <pre>
  * argumentDefinitionTest ::=
  * '?' {@link SimpleIdentifier identifier}</pre>
+ * @coverage dart.engine.ast
  */
 class ArgumentDefinitionTest extends Expression {
   /**
@@ -611,8 +655,8 @@
    * Set the identifier representing the argument being tested to the given identifier.
    * @param identifier the identifier representing the argument being tested
    */
-  void set identifier(SimpleIdentifier identifier5) {
-    this._identifier = becomeParentOf(identifier5);
+  void set identifier(SimpleIdentifier identifier7) {
+    this._identifier = becomeParentOf(identifier7);
   }
   /**
    * Set the token representing the question mark to the given token.
@@ -634,6 +678,7 @@
  * arguments ::={@link NamedExpression namedArgument} (',' {@link NamedExpression namedArgument})
  * | {@link Expression expressionList} (',' {@link NamedExpression namedArgument})
  * </pre>
+ * @coverage dart.engine.ast
  */
 class ArgumentList extends ASTNode {
   /**
@@ -649,6 +694,14 @@
    */
   Token _rightParenthesis;
   /**
+   * An array containing the elements representing the parameters corresponding to each of the
+   * arguments in this list, or {@code null} if the AST has not been resolved or if the function or
+   * method being invoked could not be determined. The array must be the same length as the number
+   * of arguments, but can contain {@code null} entries if a given argument does not correspond to a
+   * formal parameter.
+   */
+  List<ParameterElement> _correspondingParameters;
+  /**
    * Initialize a newly created list of arguments.
    * @param leftParenthesis the left parenthesis
    * @param arguments the expressions producing the values of the arguments
@@ -688,6 +741,19 @@
    */
   Token get rightParenthesis => _rightParenthesis;
   /**
+   * Set the parameter elements corresponding to each of the arguments in this list to the given
+   * array of parameters. The array of parameters must be the same length as the number of
+   * arguments, but can contain {@code null} entries if a given argument does not correspond to a
+   * formal parameter.
+   * @param parameters the parameter elements corresponding to the arguments
+   */
+  void set correspondingParameters(List<ParameterElement> parameters) {
+    if (parameters.length != _arguments.length) {
+      throw new IllegalArgumentException("Expected ${_arguments.length} parameters, not ${parameters.length}");
+    }
+    _correspondingParameters = parameters;
+  }
+  /**
    * Set the left parenthesis to the given token.
    * @param parenthesis the left parenthesis
    */
@@ -704,11 +770,33 @@
   void visitChildren(ASTVisitor<Object> visitor) {
     _arguments.accept(visitor);
   }
+  /**
+   * If the given expression is a child of this list, and the AST structure has been resolved, and
+   * the function being invoked is known, and the expression corresponds to one of the parameters of
+   * the function being invoked, then return the parameter element representing the parameter to
+   * which the value of the given expression will be bound. Otherwise, return {@code null}.
+   * <p>
+   * This method is only intended to be used by {@link Expression#getParameterElement()}.
+   * @param expression the expression corresponding to the parameter to be returned
+   * @return the parameter element representing the parameter to which the value of the expression
+   * will be bound
+   */
+  ParameterElement getParameterElementFor(Expression expression) {
+    if (_correspondingParameters == null) {
+      return null;
+    }
+    int index = _arguments.indexOf(expression);
+    if (index < 0) {
+      return null;
+    }
+    return _correspondingParameters[index];
+  }
 }
 /**
  * Instances of the class {@code AsExpression} represent an 'as' expression.
  * <pre>
  * asExpression ::={@link Expression expression} 'as' {@link TypeName type}</pre>
+ * @coverage dart.engine.ast
  */
 class AsExpression extends Expression {
   /**
@@ -791,6 +879,7 @@
  * assertStatement ::=
  * 'assert' '(' {@link Expression conditionalExpression} ')' ';'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class AssertStatement extends Statement {
   /**
@@ -908,6 +997,7 @@
  * Instances of the class {@code AssignmentExpression} represent an assignment expression.
  * <pre>
  * assignmentExpression ::={@link Expression leftHandSide} {@link Token operator} {@link Expression rightHandSide}</pre>
+ * @coverage dart.engine.ast
  */
 class AssignmentExpression extends Expression {
   /**
@@ -1008,6 +1098,7 @@
  * Instances of the class {@code BinaryExpression} represent a binary (infix) expression.
  * <pre>
  * binaryExpression ::={@link Expression leftOperand} {@link Token operator} {@link Expression rightOperand}</pre>
+ * @coverage dart.engine.ast
  */
 class BinaryExpression extends Expression {
   /**
@@ -1110,6 +1201,7 @@
  * block ::=
  * '{' statement* '}'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class Block extends Statement {
   /**
@@ -1184,6 +1276,7 @@
  * block of statements.
  * <pre>
  * blockFunctionBody ::={@link Block block}</pre>
+ * @coverage dart.engine.ast
  */
 class BlockFunctionBody extends FunctionBody {
   /**
@@ -1227,6 +1320,7 @@
  * booleanLiteral ::=
  * 'false' | 'true'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class BooleanLiteral extends Literal {
   /**
@@ -1289,6 +1383,7 @@
  * breakStatement ::=
  * 'break' {@link SimpleIdentifier label}? ';'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class BreakStatement extends Statement {
   /**
@@ -1376,6 +1471,7 @@
  * '[ ' expression '] '
  * | identifier
  * </pre>
+ * @coverage dart.engine.ast
  */
 class CascadeExpression extends Expression {
   /**
@@ -1434,6 +1530,7 @@
  * catchPart {@link Block block}| 'on' type catchPart? {@link Block block}catchPart ::=
  * 'catch' '(' {@link SimpleIdentifier exceptionParameter} (',' {@link SimpleIdentifier stackTraceParameter})? ')'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class CatchClause extends ASTNode {
   /**
@@ -1644,6 +1741,7 @@
  * ({@link ExtendsClause extendsClause} {@link WithClause withClause}?)?{@link ImplementsClause implementsClause}?
  * '{' {@link ClassMember classMember}* '}'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class ClassDeclaration extends CompilationUnitMember {
   /**
@@ -1743,10 +1841,6 @@
    * @return the token representing the 'class' keyword
    */
   Token get classKeyword => _classKeyword;
-  /**
-   * @return the {@link ClassElement} associated with this identifier, or {@code null} if the AST
-   * structure has not been resolved or if this identifier could not be resolved.
-   */
   ClassElement get element => _name != null ? (_name.element as ClassElement) : null;
   Token get endToken => _rightBracket;
   /**
@@ -1874,6 +1968,7 @@
 /**
  * The abstract class {@code ClassMember} defines the behavior common to nodes that declare a name
  * within the scope of a class.
+ * @coverage dart.engine.ast
  */
 abstract class ClassMember extends Declaration {
   /**
@@ -1896,6 +1991,7 @@
  * classTypeAlias ::={@link SimpleIdentifier identifier} {@link TypeParameterList typeParameters}? '=' 'abstract'? mixinApplication
  * mixinApplication ::={@link TypeName superclass} {@link WithClause withClause} {@link ImplementsClause implementsClause}? ';'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class ClassTypeAlias extends TypeAlias {
   /**
@@ -1973,11 +2069,6 @@
    * @return the token for the 'abstract' keyword
    */
   Token get abstractKeyword => _abstractKeyword;
-  /**
-   * Return the {@link ClassElement} associated with this type alias, or {@code null} if the AST
-   * structure has not been resolved.
-   * @return the {@link ClassElement} associated with this type alias
-   */
   ClassElement get element => _name != null ? (_name.element as ClassElement) : null;
   /**
    * Return the token for the '=' separating the name from the definition.
@@ -2073,6 +2164,7 @@
  * directive.
  * <pre>
  * combinator ::={@link HideCombinator hideCombinator}| {@link ShowCombinator showCombinator}</pre>
+ * @coverage dart.engine.ast
  */
 abstract class Combinator extends ASTNode {
   /**
@@ -2124,6 +2216,7 @@
  * '/ **' (CHARACTER | {@link CommentReference commentReference})* '&#42;/'
  * | ('///' (CHARACTER - EOL)* EOL)+
  * </pre>
+ * @coverage dart.engine.ast
  */
 class Comment extends ASTNode {
   /**
@@ -2230,6 +2323,7 @@
   static final List<CommentType> values = [END_OF_LINE, BLOCK, DOCUMENTATION];
   final String __name;
   final int __ordinal;
+  int get ordinal => __ordinal;
   CommentType(this.__name, this.__ordinal) {
   }
   String toString() => __name;
@@ -2241,6 +2335,7 @@
  * commentReference ::=
  * '[' 'new'? {@link Identifier identifier} ']'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class CommentReference extends ASTNode {
   /**
@@ -2283,8 +2378,8 @@
    * Set the identifier being referenced to the given identifier.
    * @param identifier the identifier being referenced
    */
-  void set identifier(Identifier identifier18) {
-    identifier18 = becomeParentOf(identifier18);
+  void set identifier(Identifier identifier24) {
+    identifier24 = becomeParentOf(identifier24);
   }
   /**
    * Set the token representing the 'new' keyword to the given token.
@@ -2308,6 +2403,7 @@
  * compilationUnit ::=
  * directives declarations
  * directives ::={@link ScriptTag scriptTag}? {@link LibraryDirective libraryDirective}? namespaceDirective* {@link PartDirective partDirective}| {@link PartOfDirective partOfDirective}namespaceDirective ::={@link ImportDirective importDirective}| {@link ExportDirective exportDirective}declarations ::={@link CompilationUnitMember compilationUnitMember}</pre>
+ * @coverage dart.engine.ast
  */
 class CompilationUnit extends ASTNode {
   /**
@@ -2409,8 +2505,8 @@
       return resolverErrors;
     } else {
       List<AnalysisError> allErrors = new List<AnalysisError>(parserErrors.length + resolverErrors.length);
-      System.arraycopy(parserErrors, 0, allErrors, 0, parserErrors.length);
-      System.arraycopy(resolverErrors, 0, allErrors, parserErrors.length, resolverErrors.length);
+      JavaSystem.arraycopy(parserErrors, 0, allErrors, 0, parserErrors.length);
+      JavaSystem.arraycopy(resolverErrors, 0, allErrors, parserErrors.length, resolverErrors.length);
       return allErrors;
     }
   }
@@ -2419,20 +2515,14 @@
     if (endToken3 == null) {
       return 0;
     }
-    return endToken3.offset + endToken3.length - beginToken.offset;
+    return endToken3.offset + endToken3.length;
   }
   /**
    * Get the {@link LineInfo} object for this compilation unit.
    * @return the associated {@link LineInfo}
    */
   LineInfo get lineInfo => _lineInfo;
-  int get offset {
-    Token beginToken4 = beginToken;
-    if (beginToken4 == null) {
-      return 0;
-    }
-    return beginToken4.offset;
-  }
+  int get offset => 0;
   /**
    * Return an array containing all of the parsing errors associated with the receiver.
    * @return an array of errors (not {@code null}, contains no {@code null}s).
@@ -2531,6 +2621,7 @@
  * declare a name within the scope of a compilation unit.
  * <pre>
  * compilationUnitMember ::={@link ClassDeclaration classDeclaration}| {@link TypeAlias typeAlias}| {@link FunctionDeclaration functionDeclaration}| {@link MethodDeclaration getOrSetDeclaration}| {@link VariableDeclaration constantsDeclaration}| {@link VariableDeclaration variablesDeclaration}</pre>
+ * @coverage dart.engine.ast
  */
 abstract class CompilationUnitMember extends Declaration {
   /**
@@ -2551,6 +2642,7 @@
  * Instances of the class {@code ConditionalExpression} represent a conditional expression.
  * <pre>
  * conditionalExpression ::={@link Expression condition} '?' {@link Expression thenExpression} ':' {@link Expression elseExpression}</pre>
+ * @coverage dart.engine.ast
  */
 class ConditionalExpression extends Expression {
   /**
@@ -2684,6 +2776,7 @@
  * initializerList ::=
  * ':' {@link ConstructorInitializer initializer} (',' {@link ConstructorInitializer initializer})
  * </pre>
+ * @coverage dart.engine.ast
  */
 class ConstructorDeclaration extends ClassMember {
   /**
@@ -2691,11 +2784,13 @@
    */
   Token _externalKeyword;
   /**
-   * The token for the 'const' keyword.
+   * The token for the 'const' keyword, or {@code null} if the constructor is not a const
+   * constructor.
    */
   Token _constKeyword;
   /**
-   * The token for the 'factory' keyword.
+   * The token for the 'factory' keyword, or {@code null} if the constructor is not a factory
+   * constructor.
    */
   Token _factoryKeyword;
   /**
@@ -2799,11 +2894,6 @@
    * @return the token for the 'const' keyword
    */
   Token get constKeyword => _constKeyword;
-  /**
-   * Return the element associated with this constructor , or {@code null} if the AST structure has
-   * not been resolved or if this constructor could not be resolved.
-   * @return the element associated with this constructor
-   */
   ConstructorElement get element => _element;
   Token get endToken {
     if (_body != null) {
@@ -2948,6 +3038,7 @@
     safelyVisitChild(_name, visitor);
     safelyVisitChild(_parameters, visitor);
     _initializers.accept(visitor);
+    safelyVisitChild(_redirectedConstructor, visitor);
     safelyVisitChild(_body, visitor);
   }
   Token get firstTokenAfterCommentAndMetadata {
@@ -2980,6 +3071,7 @@
  * <pre>
  * fieldInitializer ::=
  * ('this' '.')? {@link SimpleIdentifier fieldName} '=' {@link Expression conditionalExpression cascadeSection*}</pre>
+ * @coverage dart.engine.ast
  */
 class ConstructorFieldInitializer extends ConstructorInitializer {
   /**
@@ -3109,6 +3201,7 @@
  * occur in the initializer list of a constructor declaration.
  * <pre>
  * constructorInitializer ::={@link SuperConstructorInvocation superInvocation}| {@link ConstructorFieldInitializer fieldInitializer}</pre>
+ * @coverage dart.engine.ast
  */
 abstract class ConstructorInitializer extends ASTNode {
 }
@@ -3118,6 +3211,7 @@
  * constructorName:
  * type ('.' identifier)?
  * </pre>
+ * @coverage dart.engine.ast
  */
 class ConstructorName extends ASTNode {
   /**
@@ -3227,6 +3321,7 @@
  * continueStatement ::=
  * 'continue' {@link SimpleIdentifier label}? ';'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class ContinueStatement extends Statement {
   /**
@@ -3305,6 +3400,7 @@
 /**
  * The abstract class {@code Declaration} defines the behavior common to nodes that represent the
  * declaration of a name. Each declared name is visible within a name scope.
+ * @coverage dart.engine.ast
  */
 abstract class Declaration extends AnnotatedNode {
   /**
@@ -3320,6 +3416,122 @@
    * @param metadata the annotations associated with this declaration
    */
   Declaration({Comment comment, List<Annotation> metadata}) : this.full(comment, metadata);
+  /**
+   * Return the element associated with this declaration, or {@code null} if either this node
+   * corresponds to a list of declarations or if the AST structure has not been resolved.
+   * @return the element associated with this declaration
+   */
+  Element get element;
+}
+/**
+ * Instances of the class {@code DeclaredIdentifier} represent the declaration of a single
+ * identifier.
+ * <pre>
+ * declaredIdentifier ::=
+ * ({@link Annotation metadata} finalConstVarOrType {@link SimpleIdentifier identifier}</pre>
+ * @coverage dart.engine.ast
+ */
+class DeclaredIdentifier extends Declaration {
+  /**
+   * The token representing either the 'final', 'const' or 'var' keyword, or {@code null} if no
+   * keyword was used.
+   */
+  Token _keyword;
+  /**
+   * The name of the declared type of the parameter, or {@code null} if the parameter does not have
+   * a declared type.
+   */
+  TypeName _type;
+  /**
+   * The name of the variable being declared.
+   */
+  SimpleIdentifier _identifier;
+  /**
+   * Initialize a newly created formal parameter.
+   * @param comment the documentation comment associated with this parameter
+   * @param metadata the annotations associated with this parameter
+   * @param keyword the token representing either the 'final', 'const' or 'var' keyword
+   * @param type the name of the declared type of the parameter
+   * @param identifier the name of the parameter being declared
+   */
+  DeclaredIdentifier.full(Comment comment, List<Annotation> metadata, Token keyword, TypeName type, SimpleIdentifier identifier) : super.full(comment, metadata) {
+    this._keyword = keyword;
+    this._type = becomeParentOf(type);
+    this._identifier = becomeParentOf(identifier);
+  }
+  /**
+   * Initialize a newly created formal parameter.
+   * @param comment the documentation comment associated with this parameter
+   * @param metadata the annotations associated with this parameter
+   * @param keyword the token representing either the 'final', 'const' or 'var' keyword
+   * @param type the name of the declared type of the parameter
+   * @param identifier the name of the parameter being declared
+   */
+  DeclaredIdentifier({Comment comment, List<Annotation> metadata, Token keyword, TypeName type, SimpleIdentifier identifier}) : this.full(comment, metadata, keyword, type, identifier);
+  accept(ASTVisitor visitor) => visitor.visitDeclaredIdentifier(this);
+  LocalVariableElement get element {
+    SimpleIdentifier identifier11 = identifier;
+    if (identifier11 == null) {
+      return null;
+    }
+    return identifier11.element as LocalVariableElement;
+  }
+  Token get endToken => _identifier.endToken;
+  /**
+   * Return the name of the variable being declared.
+   * @return the name of the variable being declared
+   */
+  SimpleIdentifier get identifier => _identifier;
+  /**
+   * Return the token representing either the 'final', 'const' or 'var' keyword.
+   * @return the token representing either the 'final', 'const' or 'var' keyword
+   */
+  Token get keyword => _keyword;
+  /**
+   * Return the name of the declared type of the parameter, or {@code null} if the parameter does
+   * not have a declared type.
+   * @return the name of the declared type of the parameter
+   */
+  TypeName get type => _type;
+  /**
+   * Return {@code true} if this variable was declared with the 'const' modifier.
+   * @return {@code true} if this variable was declared with the 'const' modifier
+   */
+  bool isConst() => (_keyword is KeywordToken) && identical(((_keyword as KeywordToken)).keyword, Keyword.CONST);
+  /**
+   * Return {@code true} if this variable was declared with the 'final' modifier. Variables that are
+   * declared with the 'const' modifier will return {@code false} even though they are implicitly
+   * final.
+   * @return {@code true} if this variable was declared with the 'final' modifier
+   */
+  bool isFinal() => (_keyword is KeywordToken) && identical(((_keyword as KeywordToken)).keyword, Keyword.FINAL);
+  /**
+   * Set the token representing either the 'final', 'const' or 'var' keyword to the given token.
+   * @param keyword the token representing either the 'final', 'const' or 'var' keyword
+   */
+  void set keyword(Token keyword8) {
+    this._keyword = keyword8;
+  }
+  /**
+   * Set the name of the declared type of the parameter to the given type name.
+   * @param typeName the name of the declared type of the parameter
+   */
+  void set type(TypeName typeName) {
+    _type = becomeParentOf(typeName);
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(_type, visitor);
+    safelyVisitChild(_identifier, visitor);
+  }
+  Token get firstTokenAfterCommentAndMetadata {
+    if (_keyword != null) {
+      return _keyword;
+    } else if (_type != null) {
+      return _type.beginToken;
+    }
+    return _identifier.beginToken;
+  }
 }
 /**
  * Instances of the class {@code DefaultFormalParameter} represent a formal parameter with a default
@@ -3329,6 +3541,7 @@
  * defaultFormalParameter ::={@link NormalFormalParameter normalFormalParameter} ('=' {@link Expression defaultValue})?
  * defaultNamedParameter ::={@link NormalFormalParameter normalFormalParameter} (':' {@link Expression defaultValue})?
  * </pre>
+ * @coverage dart.engine.ast
  */
 class DefaultFormalParameter extends FormalParameter {
   /**
@@ -3398,13 +3611,15 @@
    */
   Token get separator => _separator;
   /**
-   * Return {@code true} if this parameter is a const parameter.
-   * @return {@code true} if this parameter is a const parameter
+   * Return {@code true} if this parameter was declared with the 'const' modifier.
+   * @return {@code true} if this parameter was declared with the 'const' modifier
    */
   bool isConst() => _parameter != null && _parameter.isConst();
   /**
-   * Return {@code true} if this parameter is a final parameter.
-   * @return {@code true} if this parameter is a final parameter
+   * Return {@code true} if this parameter was declared with the 'final' modifier. Parameters that
+   * are declared with the 'const' modifier will return {@code false} even though they are
+   * implicitly final.
+   * @return {@code true} if this parameter was declared with the 'final' modifier
    */
   bool isFinal() => _parameter != null && _parameter.isFinal();
   /**
@@ -3445,6 +3660,7 @@
  * directive.
  * <pre>
  * directive ::={@link ExportDirective exportDirective}| {@link ImportDirective importDirective}| {@link LibraryDirective libraryDirective}| {@link PartDirective partDirective}| {@link PartOfDirective partOfDirective}</pre>
+ * @coverage dart.engine.ast
  */
 abstract class Directive extends AnnotatedNode {
   /**
@@ -3492,6 +3708,7 @@
  * doStatement ::=
  * 'do' {@link Statement body} 'while' '(' {@link Expression condition} ')' ';'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class DoStatement extends Statement {
   /**
@@ -3653,6 +3870,7 @@
  * exponent ::=
  * ('e' | 'E') ('+' | '-')? decimalDigit+
  * </pre>
+ * @coverage dart.engine.ast
  */
 class DoubleLiteral extends Literal {
   /**
@@ -3715,6 +3933,7 @@
  * emptyFunctionBody ::=
  * ';'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class EmptyFunctionBody extends FunctionBody {
   /**
@@ -3758,6 +3977,7 @@
  * emptyStatement ::=
  * ';'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class EmptyStatement extends Statement {
   /**
@@ -3795,10 +4015,21 @@
   }
 }
 /**
+ * Ephemeral identifiers are created as needed to mimic the presence of an empty identifier.
+ * @coverage dart.engine.ast
+ */
+class EphemeralIdentifier extends SimpleIdentifier {
+  EphemeralIdentifier.full(ASTNode parent, int location) : super.full(new Token(TokenType.IDENTIFIER, location)) {
+    parent.becomeParentOf(this);
+  }
+  EphemeralIdentifier({ASTNode parent, int location}) : this.full(parent, location);
+}
+/**
  * Instances of the class {@code ExportDirective} represent an export directive.
  * <pre>
  * exportDirective ::={@link Annotation metadata} 'export' {@link StringLiteral libraryUri} {@link Combinator combinator}* ';'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class ExportDirective extends NamespaceDirective {
   /**
@@ -3834,6 +4065,7 @@
  * <pre>
  * expression ::={@link AssignmentExpression assignmentExpression}| {@link ConditionalExpression conditionalExpression} cascadeSection
  * | {@link ThrowExpression throwExpression}</pre>
+ * @coverage dart.engine.ast
  */
 abstract class Expression extends ASTNode {
   /**
@@ -3846,6 +4078,21 @@
    */
   Type2 _propagatedType;
   /**
+   * If this expression is an argument to an invocation, and the AST structure has been resolved,
+   * and the function being invoked is known, and this expression corresponds to one of the
+   * parameters of the function being invoked, then return the parameter element representing the
+   * parameter to which the value of this expression will be bound. Otherwise, return {@code null}.
+   * @return the parameter element representing the parameter to which the value of this expression
+   * will be bound
+   */
+  ParameterElement get parameterElement {
+    ASTNode parent3 = parent;
+    if (parent3 is ArgumentList) {
+      return ((parent3 as ArgumentList)).getParameterElementFor(this);
+    }
+    return null;
+  }
+  /**
    * Return the propagated type of this expression, or {@code null} if type propagation has not been
    * performed on the AST structure.
    * @return the propagated type of this expression
@@ -3884,6 +4131,7 @@
  * expressionFunctionBody ::=
  * '=>' {@link Expression expression} ';'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class ExpressionFunctionBody extends FunctionBody {
   /**
@@ -3972,6 +4220,7 @@
  * <pre>
  * expressionStatement ::={@link Expression expression}? ';'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class ExpressionStatement extends Statement {
   /**
@@ -4041,6 +4290,7 @@
  * <pre>
  * extendsClause ::=
  * 'extends' {@link TypeName superclass}</pre>
+ * @coverage dart.engine.ast
  */
 class ExtendsClause extends ASTNode {
   /**
@@ -4083,8 +4333,8 @@
    * Set the token representing the 'extends' keyword to the given token.
    * @param keyword the token representing the 'extends' keyword
    */
-  void set keyword(Token keyword8) {
-    this._keyword = keyword8;
+  void set keyword(Token keyword9) {
+    this._keyword = keyword9;
   }
   /**
    * Set the name of the class that is being extended to the given name.
@@ -4104,6 +4354,7 @@
  * fieldDeclaration ::=
  * 'static'? {@link VariableDeclarationList fieldList} ';'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class FieldDeclaration extends ClassMember {
   /**
@@ -4141,6 +4392,7 @@
    */
   FieldDeclaration({Comment comment, List<Annotation> metadata, Token keyword, VariableDeclarationList fieldList, Token semicolon}) : this.full(comment, metadata, keyword, fieldList, semicolon);
   accept(ASTVisitor visitor) => visitor.visitFieldDeclaration(this);
+  Element get element => null;
   Token get endToken => _semicolon;
   /**
    * Return the fields being declared.
@@ -4169,8 +4421,8 @@
    * Set the token representing the 'static' keyword to the given token.
    * @param keyword the token representing the 'static' keyword
    */
-  void set keyword(Token keyword9) {
-    this._keyword = keyword9;
+  void set keyword(Token keyword10) {
+    this._keyword = keyword10;
   }
   /**
    * Set the semicolon terminating the declaration to the given token.
@@ -4195,6 +4447,7 @@
  * <pre>
  * fieldFormalParameter ::=
  * ('final' {@link TypeName type} | 'const' {@link TypeName type} | 'var' | {@link TypeName type})? 'this' '.' {@link SimpleIdentifier identifier}</pre>
+ * @coverage dart.engine.ast
  */
 class FieldFormalParameter extends NormalFormalParameter {
   /**
@@ -4279,8 +4532,8 @@
    * Set the token representing either the 'final', 'const' or 'var' keyword to the given token.
    * @param keyword the token representing either the 'final', 'const' or 'var' keyword
    */
-  void set keyword(Token keyword10) {
-    this._keyword = keyword10;
+  void set keyword(Token keyword11) {
+    this._keyword = keyword11;
   }
   /**
    * Set the token representing the period to the given token.
@@ -4314,6 +4567,7 @@
  * <pre>
  * forEachStatement ::=
  * 'for' '(' {@link SimpleFormalParameter loopParameter} 'in' {@link Expression iterator} ')' {@link Block body}</pre>
+ * @coverage dart.engine.ast
  */
 class ForEachStatement extends Statement {
   /**
@@ -4327,7 +4581,7 @@
   /**
    * The declaration of the loop variable.
    */
-  SimpleFormalParameter _loopParameter;
+  DeclaredIdentifier _loopVariable;
   /**
    * The token representing the 'in' keyword.
    */
@@ -4348,15 +4602,15 @@
    * Initialize a newly created for-each statement.
    * @param forKeyword the token representing the 'for' keyword
    * @param leftParenthesis the left parenthesis
-   * @param loopParameter the declaration of the loop variable
+   * @param loopVariable the declaration of the loop variable
    * @param iterator the expression evaluated to produce the iterator
    * @param rightParenthesis the right parenthesis
    * @param body the body of the loop
    */
-  ForEachStatement.full(Token forKeyword, Token leftParenthesis, SimpleFormalParameter loopParameter, Token inKeyword, Expression iterator, Token rightParenthesis, Statement body) {
+  ForEachStatement.full(Token forKeyword, Token leftParenthesis, DeclaredIdentifier loopVariable, Token inKeyword, Expression iterator, Token rightParenthesis, Statement body) {
     this._forKeyword = forKeyword;
     this._leftParenthesis = leftParenthesis;
-    this._loopParameter = becomeParentOf(loopParameter);
+    this._loopVariable = becomeParentOf(loopVariable);
     this._inKeyword = inKeyword;
     this._iterator = becomeParentOf(iterator);
     this._rightParenthesis = rightParenthesis;
@@ -4366,12 +4620,12 @@
    * Initialize a newly created for-each statement.
    * @param forKeyword the token representing the 'for' keyword
    * @param leftParenthesis the left parenthesis
-   * @param loopParameter the declaration of the loop variable
+   * @param loopVariable the declaration of the loop variable
    * @param iterator the expression evaluated to produce the iterator
    * @param rightParenthesis the right parenthesis
    * @param body the body of the loop
    */
-  ForEachStatement({Token forKeyword, Token leftParenthesis, SimpleFormalParameter loopParameter, Token inKeyword, Expression iterator, Token rightParenthesis, Statement body}) : this.full(forKeyword, leftParenthesis, loopParameter, inKeyword, iterator, rightParenthesis, body);
+  ForEachStatement({Token forKeyword, Token leftParenthesis, DeclaredIdentifier loopVariable, Token inKeyword, Expression iterator, Token rightParenthesis, Statement body}) : this.full(forKeyword, leftParenthesis, loopVariable, inKeyword, iterator, rightParenthesis, body);
   accept(ASTVisitor visitor) => visitor.visitForEachStatement(this);
   Token get beginToken => _forKeyword;
   /**
@@ -4404,7 +4658,7 @@
    * Return the declaration of the loop variable.
    * @return the declaration of the loop variable
    */
-  SimpleFormalParameter get loopParameter => _loopParameter;
+  DeclaredIdentifier get loopVariable => _loopVariable;
   /**
    * Return the right parenthesis.
    * @return the right parenthesis
@@ -4446,11 +4700,11 @@
     this._leftParenthesis = leftParenthesis3;
   }
   /**
-   * Set the declaration of the loop variable to the given parameter.
-   * @param parameter the declaration of the loop variable
+   * Set the declaration of the loop variable to the given variable.
+   * @param variable the declaration of the loop variable
    */
-  void set loopParameter(SimpleFormalParameter parameter) {
-    _loopParameter = becomeParentOf(parameter);
+  void set loopVariable(DeclaredIdentifier variable) {
+    _loopVariable = becomeParentOf(variable);
   }
   /**
    * Set the right parenthesis to the given token.
@@ -4460,7 +4714,7 @@
     this._rightParenthesis = rightParenthesis3;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
-    safelyVisitChild(_loopParameter, visitor);
+    safelyVisitChild(_loopVariable, visitor);
     safelyVisitChild(_iterator, visitor);
     safelyVisitChild(_body, visitor);
   }
@@ -4473,6 +4727,7 @@
  * forInitializerStatement ';' {@link Expression expression}? ';' {@link Expression expressionList}?
  * forInitializerStatement ::={@link DefaultFormalParameter initializedVariableDeclaration}| {@link Expression expression}?
  * </pre>
+ * @coverage dart.engine.ast
  */
 class ForStatement extends Statement {
   /**
@@ -4688,6 +4943,7 @@
  * parameter to a function.
  * <pre>
  * formalParameter ::={@link NormalFormalParameter normalFormalParameter}| {@link DefaultFormalParameter namedFormalParameter}| {@link DefaultFormalParameter optionalFormalParameter}</pre>
+ * @coverage dart.engine.ast
  */
 abstract class FormalParameter extends ASTNode {
   /**
@@ -4696,11 +4952,11 @@
    * @return the element representing this parameter
    */
   ParameterElement get element {
-    SimpleIdentifier identifier9 = identifier;
-    if (identifier9 == null) {
+    SimpleIdentifier identifier12 = identifier;
+    if (identifier12 == null) {
       return null;
     }
-    return (identifier9.element as ParameterElement);
+    return identifier12.element as ParameterElement;
   }
   /**
    * Return the name of the parameter being declared.
@@ -4735,6 +4991,7 @@
  * namedFormalParameters ::=
  * '{' {@link DefaultFormalParameter namedFormalParameter} (',' {@link DefaultFormalParameter namedFormalParameter})* '}'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class FormalParameterList extends ASTNode {
   /**
@@ -4866,6 +5123,7 @@
  * body of a function or method.
  * <pre>
  * functionBody ::={@link BlockFunctionBody blockFunctionBody}| {@link EmptyFunctionBody emptyFunctionBody}| {@link ExpressionFunctionBody expressionFunctionBody}</pre>
+ * @coverage dart.engine.ast
  */
 abstract class FunctionBody extends ASTNode {
 }
@@ -4876,6 +5134,7 @@
  * functionDeclaration ::=
  * 'external' functionSignature
  * | functionSignature {@link FunctionBody functionBody}functionSignature ::={@link Type returnType}? ('get' | 'set')? {@link SimpleIdentifier functionName} {@link FormalParameterList formalParameterList}</pre>
+ * @coverage dart.engine.ast
  */
 class FunctionDeclaration extends CompilationUnitMember {
   /**
@@ -4929,12 +5188,7 @@
    */
   FunctionDeclaration({Comment comment, List<Annotation> metadata, Token externalKeyword, TypeName returnType, Token propertyKeyword, SimpleIdentifier name, FunctionExpression functionExpression}) : this.full(comment, metadata, externalKeyword, returnType, propertyKeyword, name, functionExpression);
   accept(ASTVisitor visitor) => visitor.visitFunctionDeclaration(this);
-  /**
-   * Return the {@link FunctionElement} associated with this function, or {@code null} if the AST
-   * structure has not been resolved.
-   * @return the {@link FunctionElement} associated with this function
-   */
-  FunctionElement get element => _name != null ? (_name.element as FunctionElement) : null;
+  ExecutableElement get element => _name != null ? (_name.element as ExecutableElement) : null;
   Token get endToken => _functionExpression.endToken;
   /**
    * Return the token representing the 'external' keyword, or {@code null} if this is not an
@@ -5020,6 +5274,7 @@
 }
 /**
  * Instances of the class {@code FunctionDeclarationStatement} wrap a {@link FunctionDeclarationfunction declaration} as a statement.
+ * @coverage dart.engine.ast
  */
 class FunctionDeclarationStatement extends Statement {
   /**
@@ -5061,6 +5316,7 @@
  * Instances of the class {@code FunctionExpression} represent a function expression.
  * <pre>
  * functionExpression ::={@link FormalParameterList formalParameterList} {@link FunctionBody functionBody}</pre>
+ * @coverage dart.engine.ast
  */
 class FunctionExpression extends Expression {
   /**
@@ -5157,6 +5413,7 @@
  * getters and setters are represented by either {@link PrefixedIdentifier prefixed identifier} or{@link PropertyAccess property access} nodes.
  * <pre>
  * functionExpressionInvoction ::={@link Expression function} {@link ArgumentList argumentList}</pre>
+ * @coverage dart.engine.ast
  */
 class FunctionExpressionInvocation extends Expression {
   /**
@@ -5239,6 +5496,7 @@
  * functionTypeAlias ::=
  * functionPrefix {@link TypeParameterList typeParameterList}? {@link FormalParameterList formalParameterList} ';'
  * functionPrefix ::={@link TypeName returnType}? {@link SimpleIdentifier name}</pre>
+ * @coverage dart.engine.ast
  */
 class FunctionTypeAlias extends TypeAlias {
   /**
@@ -5289,12 +5547,7 @@
    */
   FunctionTypeAlias({Comment comment, List<Annotation> metadata, Token keyword, TypeName returnType, SimpleIdentifier name, TypeParameterList typeParameters, FormalParameterList parameters, Token semicolon}) : this.full(comment, metadata, keyword, returnType, name, typeParameters, parameters, semicolon);
   accept(ASTVisitor visitor) => visitor.visitFunctionTypeAlias(this);
-  /**
-   * Return the {@link TypeAliasElement} associated with this type alias, or {@code null} if the AST
-   * structure has not been resolved.
-   * @return the {@link TypeAliasElement} associated with this type alias
-   */
-  TypeAliasElement get element => _name != null ? (_name.element as TypeAliasElement) : null;
+  FunctionTypeAliasElement get element => _name != null ? (_name.element as FunctionTypeAliasElement) : null;
   /**
    * Return the name of the function type being declared.
    * @return the name of the function type being declared
@@ -5358,6 +5611,7 @@
  * parameter.
  * <pre>
  * functionSignature ::={@link TypeName returnType}? {@link SimpleIdentifier identifier} {@link FormalParameterList formalParameterList}</pre>
+ * @coverage dart.engine.ast
  */
 class FunctionTypedFormalParameter extends NormalFormalParameter {
   /**
@@ -5440,6 +5694,7 @@
  * hideCombinator ::=
  * 'hide' {@link SimpleIdentifier identifier} (',' {@link SimpleIdentifier identifier})
  * </pre>
+ * @coverage dart.engine.ast
  */
 class HideCombinator extends Combinator {
   /**
@@ -5477,6 +5732,7 @@
  * identifier.
  * <pre>
  * identifier ::={@link SimpleIdentifier simpleIdentifier}| {@link PrefixedIdentifier prefixedIdentifier}</pre>
+ * @coverage dart.engine.ast
  */
 abstract class Identifier extends Expression {
   /**
@@ -5487,30 +5743,18 @@
    */
   static bool isPrivateName(String name) => name.startsWith("_");
   /**
-   * The element associated with this identifier, or {@code null} if the AST structure has not been
-   * resolved or if this identifier could not be resolved.
-   */
-  Element _element;
-  /**
    * Return the element associated with this identifier, or {@code null} if the AST structure has
    * not been resolved or if this identifier could not be resolved. One example of the latter case
    * is an identifier that is not defined within the scope in which it appears.
    * @return the element associated with this identifier
    */
-  Element get element => _element;
+  Element get element;
   /**
    * Return the lexical representation of the identifier.
    * @return the lexical representation of the identifier
    */
   String get name;
   bool isAssignable() => true;
-  /**
-   * Set the element associated with this identifier to the given element.
-   * @param element the element associated with this identifier
-   */
-  void set element(Element element11) {
-    this._element = element11;
-  }
 }
 /**
  * Instances of the class {@code IfStatement} represent an if statement.
@@ -5518,6 +5762,7 @@
  * ifStatement ::=
  * 'if' '(' {@link Expression expression} ')' {@link Statement thenStatement} ('else' {@link Statement elseStatement})?
  * </pre>
+ * @coverage dart.engine.ast
  */
 class IfStatement extends Statement {
   /**
@@ -5687,6 +5932,7 @@
  * implementsClause ::=
  * 'implements' {@link TypeName superclass} (',' {@link TypeName superclass})
  * </pre>
+ * @coverage dart.engine.ast
  */
 class ImplementsClause extends ASTNode {
   /**
@@ -5730,8 +5976,8 @@
    * Set the token representing the 'implements' keyword to the given token.
    * @param keyword the token representing the 'implements' keyword
    */
-  void set keyword(Token keyword11) {
-    this._keyword = keyword11;
+  void set keyword(Token keyword12) {
+    this._keyword = keyword12;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     _interfaces.accept(visitor);
@@ -5742,6 +5988,7 @@
  * <pre>
  * importDirective ::={@link Annotation metadata} 'import' {@link StringLiteral libraryUri} ('as' identifier)? {@link Combinator combinator}* ';'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class ImportDirective extends NamespaceDirective {
   /**
@@ -5818,6 +6065,7 @@
  * <pre>
  * indexExpression ::={@link Expression target} '[' {@link Expression index} ']'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class IndexExpression extends Expression {
   /**
@@ -5855,7 +6103,7 @@
    * @param rightBracket the right square bracket
    */
   IndexExpression.forTarget_full(Expression target3, Token leftBracket4, Expression index2, Token rightBracket4) {
-    _jtd_constructor_56_impl(target3, leftBracket4, index2, rightBracket4);
+    _jtd_constructor_58_impl(target3, leftBracket4, index2, rightBracket4);
   }
   /**
    * Initialize a newly created index expression.
@@ -5865,7 +6113,7 @@
    * @param rightBracket the right square bracket
    */
   IndexExpression.forTarget({Expression target3, Token leftBracket4, Expression index2, Token rightBracket4}) : this.forTarget_full(target3, leftBracket4, index2, rightBracket4);
-  _jtd_constructor_56_impl(Expression target3, Token leftBracket4, Expression index2, Token rightBracket4) {
+  _jtd_constructor_58_impl(Expression target3, Token leftBracket4, Expression index2, Token rightBracket4) {
     this._target = becomeParentOf(target3);
     this._leftBracket = leftBracket4;
     this._index = becomeParentOf(index2);
@@ -5879,7 +6127,7 @@
    * @param rightBracket the right square bracket
    */
   IndexExpression.forCascade_full(Token period7, Token leftBracket5, Expression index3, Token rightBracket5) {
-    _jtd_constructor_57_impl(period7, leftBracket5, index3, rightBracket5);
+    _jtd_constructor_59_impl(period7, leftBracket5, index3, rightBracket5);
   }
   /**
    * Initialize a newly created index expression.
@@ -5889,7 +6137,7 @@
    * @param rightBracket the right square bracket
    */
   IndexExpression.forCascade({Token period7, Token leftBracket5, Expression index3, Token rightBracket5}) : this.forCascade_full(period7, leftBracket5, index3, rightBracket5);
-  _jtd_constructor_57_impl(Token period7, Token leftBracket5, Expression index3, Token rightBracket5) {
+  _jtd_constructor_59_impl(Token period7, Token leftBracket5, Expression index3, Token rightBracket5) {
     this._period = period7;
     this._leftBracket = leftBracket5;
     this._index = becomeParentOf(index3);
@@ -5967,9 +6215,9 @@
    * @return {@code true} if this expression is in a context where the operator '[]' will be invoked
    */
   bool inGetterContext() {
-    ASTNode parent3 = parent;
-    if (parent3 is AssignmentExpression) {
-      AssignmentExpression assignment = (parent3 as AssignmentExpression);
+    ASTNode parent4 = parent;
+    if (parent4 is AssignmentExpression) {
+      AssignmentExpression assignment = parent4 as AssignmentExpression;
       if (identical(assignment.leftHandSide, this) && identical(assignment.operator.type, TokenType.EQ)) {
         return false;
       }
@@ -5985,13 +6233,13 @@
    * invoked
    */
   bool inSetterContext() {
-    ASTNode parent4 = parent;
-    if (parent4 is PrefixExpression) {
-      return ((parent4 as PrefixExpression)).operator.type.isIncrementOperator();
-    } else if (parent4 is PostfixExpression) {
+    ASTNode parent5 = parent;
+    if (parent5 is PrefixExpression) {
+      return ((parent5 as PrefixExpression)).operator.type.isIncrementOperator();
+    } else if (parent5 is PostfixExpression) {
       return true;
-    } else if (parent4 is AssignmentExpression) {
-      return identical(((parent4 as AssignmentExpression)).leftHandSide, this);
+    } else if (parent5 is AssignmentExpression) {
+      return identical(((parent5 as AssignmentExpression)).leftHandSide, this);
     }
     return false;
   }
@@ -6013,8 +6261,8 @@
    * Set the element associated with the operator to the given element.
    * @param element the element associated with this operator
    */
-  void set element(MethodElement element12) {
-    this._element = element12;
+  void set element(MethodElement element11) {
+    this._element = element11;
   }
   /**
    * Set the expression used to compute the index to the given expression.
@@ -6055,6 +6303,7 @@
  * <pre>
  * newExpression ::=
  * ('new' | 'const') {@link TypeName type} ('.' {@link SimpleIdentifier identifier})? {@link ArgumentList argumentList}</pre>
+ * @coverage dart.engine.ast
  */
 class InstanceCreationExpression extends Expression {
   /**
@@ -6117,6 +6366,11 @@
    */
   Token get keyword => _keyword;
   /**
+   * Return {@code true} if this creation expression is used to invoke a constant constructor.
+   * @return {@code true} if this creation expression is used to invoke a constant constructor
+   */
+  bool isConst() => _keyword is KeywordToken && identical(((_keyword as KeywordToken)).keyword, Keyword.CONST);
+  /**
    * Set the list of arguments to the constructor to the given list.
    * @param argumentList the list of arguments to the constructor
    */
@@ -6134,15 +6388,15 @@
    * Set the element associated with the constructor to the given element.
    * @param element the element associated with the constructor
    */
-  void set element(ConstructorElement element13) {
-    this._element = element13;
+  void set element(ConstructorElement element12) {
+    this._element = element12;
   }
   /**
    * Set the keyword used to indicate how an object should be created to the given keyword.
    * @param keyword the keyword used to indicate how an object should be created
    */
-  void set keyword(Token keyword12) {
-    this._keyword = keyword12;
+  void set keyword(Token keyword13) {
+    this._keyword = keyword13;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_constructorName, visitor);
@@ -6161,6 +6415,7 @@
  * '0x' hexidecimalDigit+
  * | '0X' hexidecimalDigit+
  * </pre>
+ * @coverage dart.engine.ast
  */
 class IntegerLiteral extends Literal {
   /**
@@ -6220,6 +6475,7 @@
  * The abstract class {@code InterpolationElement} defines the behavior common to elements within a{@link StringInterpolation string interpolation}.
  * <pre>
  * interpolationElement ::={@link InterpolationExpression interpolationExpression}| {@link InterpolationString interpolationString}</pre>
+ * @coverage dart.engine.ast
  */
 abstract class InterpolationElement extends ASTNode {
 }
@@ -6230,6 +6486,7 @@
  * interpolationExpression ::=
  * '$' {@link SimpleIdentifier identifier}| '$' '{' {@link Expression expression} '}'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class InterpolationExpression extends InterpolationElement {
   /**
@@ -6319,6 +6576,7 @@
  * interpolationString ::=
  * characters
  * </pre>
+ * @coverage dart.engine.ast
  */
 class InterpolationString extends InterpolationElement {
   /**
@@ -6378,6 +6636,7 @@
  * Instances of the class {@code IsExpression} represent an is expression.
  * <pre>
  * isExpression ::={@link Expression expression} 'is' '!'? {@link TypeName type}</pre>
+ * @coverage dart.engine.ast
  */
 class IsExpression extends Expression {
   /**
@@ -6479,6 +6738,7 @@
  * <pre>
  * label ::={@link SimpleIdentifier label} ':'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class Label extends ASTNode {
   /**
@@ -6528,8 +6788,8 @@
    * Set the label being associated with the statement to the given label.
    * @param label the label being associated with the statement
    */
-  void set label(SimpleIdentifier label2) {
-    this._label = becomeParentOf(label2);
+  void set label(SimpleIdentifier label3) {
+    this._label = becomeParentOf(label3);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_label, visitor);
@@ -6540,6 +6800,7 @@
  * with them.
  * <pre>
  * labeledStatement ::={@link Label label}+ {@link Statement statement}</pre>
+ * @coverage dart.engine.ast
  */
 class LabeledStatement extends Statement {
   /**
@@ -6601,6 +6862,7 @@
  * <pre>
  * libraryDirective ::={@link Annotation metadata} 'library' {@link Identifier name} ';'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class LibraryDirective extends Directive {
   /**
@@ -6687,6 +6949,7 @@
  * <pre>
  * libraryIdentifier ::={@link SimpleIdentifier component} ('.' {@link SimpleIdentifier component})
  * </pre>
+ * @coverage dart.engine.ast
  */
 class LibraryIdentifier extends Identifier {
   /**
@@ -6713,17 +6976,18 @@
    * @return the components of the identifier
    */
   NodeList<SimpleIdentifier> get components => _components;
+  Element get element => null;
   Token get endToken => _components.endToken;
   String get name {
-    StringBuffer builder = new StringBuffer();
+    JavaStringBuilder builder = new JavaStringBuilder();
     bool needsPeriod = false;
     for (SimpleIdentifier identifier in _components) {
       if (needsPeriod) {
-        builder.add(".");
+        builder.append(".");
       } else {
         needsPeriod = true;
       }
-      builder.add(identifier.name);
+      builder.append(identifier.name);
     }
     return builder.toString();
   }
@@ -6737,6 +7001,7 @@
  * listLiteral ::=
  * 'const'? ('<' {@link TypeName type} '>')? '[' ({@link Expression expressionList} ','?)? ']'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class ListLiteral extends TypedLiteral {
   /**
@@ -6828,6 +7093,7 @@
  * expression.
  * <pre>
  * literal ::={@link BooleanLiteral booleanLiteral}| {@link DoubleLiteral doubleLiteral}| {@link IntegerLiteral integerLiteral}| {@link ListLiteral listLiteral}| {@link MapLiteral mapLiteral}| {@link NullLiteral nullLiteral}| {@link StringLiteral stringLiteral}</pre>
+ * @coverage dart.engine.ast
  */
 abstract class Literal extends Expression {
 }
@@ -6837,6 +7103,7 @@
  * mapLiteral ::=
  * 'const'? ('<' {@link TypeName type} '>')? '{' ({@link MapLiteralEntry entry} (',' {@link MapLiteralEntry entry})* ','?)? '}'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class MapLiteral extends TypedLiteral {
   /**
@@ -6928,6 +7195,7 @@
  * literal.
  * <pre>
  * mapLiteralEntry ::={@link StringLiteral key} ':' {@link Expression value}</pre>
+ * @coverage dart.engine.ast
  */
 class MapLiteralEntry extends ASTNode {
   /**
@@ -7010,8 +7278,8 @@
  * <pre>
  * methodDeclaration ::=
  * methodSignature {@link FunctionBody body}methodSignature ::=
- * 'external'? ('abstract' | 'static')? {@link Type returnType}? ('get' | 'set')? methodName{@link FormalParameterList formalParameterList}methodName ::={@link SimpleIdentifier name} ('.' {@link SimpleIdentifier name})?
- * | 'operator' {@link SimpleIdentifier operator}</pre>
+ * 'external'? ('abstract' | 'static')? {@link Type returnType}? ('get' | 'set')? methodName{@link FormalParameterList formalParameterList}methodName ::={@link SimpleIdentifier name}| 'operator' {@link SimpleIdentifier operator}</pre>
+ * @coverage dart.engine.ast
  */
 class MethodDeclaration extends ClassMember {
   /**
@@ -7040,7 +7308,7 @@
   /**
    * The name of the method.
    */
-  Identifier _name;
+  SimpleIdentifier _name;
   /**
    * The parameters associated with the method, or {@code null} if this method declares a getter.
    */
@@ -7063,7 +7331,7 @@
    * declares a getter
    * @param body the body of the method
    */
-  MethodDeclaration.full(Comment comment, List<Annotation> metadata, Token externalKeyword, Token modifierKeyword, TypeName returnType, Token propertyKeyword, Token operatorKeyword, Identifier name, FormalParameterList parameters, FunctionBody body) : super.full(comment, metadata) {
+  MethodDeclaration.full(Comment comment, List<Annotation> metadata, Token externalKeyword, Token modifierKeyword, TypeName returnType, Token propertyKeyword, Token operatorKeyword, SimpleIdentifier name, FormalParameterList parameters, FunctionBody body) : super.full(comment, metadata) {
     this._externalKeyword = externalKeyword;
     this._modifierKeyword = modifierKeyword;
     this._returnType = becomeParentOf(returnType);
@@ -7087,7 +7355,7 @@
    * declares a getter
    * @param body the body of the method
    */
-  MethodDeclaration({Comment comment, List<Annotation> metadata, Token externalKeyword, Token modifierKeyword, TypeName returnType, Token propertyKeyword, Token operatorKeyword, Identifier name, FormalParameterList parameters, FunctionBody body}) : this.full(comment, metadata, externalKeyword, modifierKeyword, returnType, propertyKeyword, operatorKeyword, name, parameters, body);
+  MethodDeclaration({Comment comment, List<Annotation> metadata, Token externalKeyword, Token modifierKeyword, TypeName returnType, Token propertyKeyword, Token operatorKeyword, SimpleIdentifier name, FormalParameterList parameters, FunctionBody body}) : this.full(comment, metadata, externalKeyword, modifierKeyword, returnType, propertyKeyword, operatorKeyword, name, parameters, body);
   accept(ASTVisitor visitor) => visitor.visitMethodDeclaration(this);
   /**
    * Return the body of the method.
@@ -7119,7 +7387,7 @@
    * Return the name of the method.
    * @return the name of the method
    */
-  Identifier get name => _name;
+  SimpleIdentifier get name => _name;
   /**
    * Return the token representing the 'operator' keyword, or {@code null} if this method does not
    * declare an operator.
@@ -7144,6 +7412,11 @@
    */
   TypeName get returnType => _returnType;
   /**
+   * Return {@code true} if this method is declared to be an abstract method.
+   * @return {@code true} if this method is declared to be an abstract method
+   */
+  bool isAbstract() => _modifierKeyword != null && identical(((_modifierKeyword as KeywordToken)).keyword, Keyword.ABSTRACT);
+  /**
    * Return {@code true} if this method declares a getter.
    * @return {@code true} if this method declares a getter
    */
@@ -7159,6 +7432,11 @@
    */
   bool isSetter() => _propertyKeyword != null && identical(((_propertyKeyword as KeywordToken)).keyword, Keyword.SET);
   /**
+   * Return {@code true} if this method is declared to be a static method.
+   * @return {@code true} if this method is declared to be a static method
+   */
+  bool isStatic() => _modifierKeyword != null && identical(((_modifierKeyword as KeywordToken)).keyword, Keyword.STATIC);
+  /**
    * Set the body of the method to the given function body.
    * @param functionBody the body of the method
    */
@@ -7183,7 +7461,7 @@
    * Set the name of the method to the given identifier.
    * @param identifier the name of the method
    */
-  void set name(Identifier identifier) {
+  void set name(SimpleIdentifier identifier) {
     _name = becomeParentOf(identifier);
   }
   /**
@@ -7241,6 +7519,7 @@
  * <pre>
  * methodInvoction ::=
  * ({@link Expression target} '.')? {@link SimpleIdentifier methodName} {@link ArgumentList argumentList}</pre>
+ * @coverage dart.engine.ast
  */
 class MethodInvocation extends Expression {
   /**
@@ -7291,6 +7570,8 @@
   Token get beginToken {
     if (_target != null) {
       return _target.beginToken;
+    } else if (_period != null) {
+      return _period;
     }
     return _methodName.beginToken;
   }
@@ -7380,6 +7661,7 @@
  * with it. They are used in method invocations when there are named parameters.
  * <pre>
  * namedExpression ::={@link Label name} {@link Expression expression}</pre>
+ * @coverage dart.engine.ast
  */
 class NamedExpression extends Expression {
   /**
@@ -7407,6 +7689,18 @@
   NamedExpression({Label name, Expression expression}) : this.full(name, expression);
   accept(ASTVisitor visitor) => visitor.visitNamedExpression(this);
   Token get beginToken => _name.beginToken;
+  /**
+   * Return the element representing the parameter being named by this expression, or {@code null}if the AST structure has not been resolved or if there is no parameter with the same name as
+   * this expression.
+   * @return the element representing the parameter being named by this expression
+   */
+  ParameterElement get element {
+    Element element20 = _name.label.element;
+    if (element20 is ParameterElement) {
+      return element20 as ParameterElement;
+    }
+    return null;
+  }
   Token get endToken => _expression.endToken;
   /**
    * Return the expression with which the name is associated.
@@ -7442,6 +7736,7 @@
  * a directive that impacts the namespace of a library.
  * <pre>
  * directive ::={@link ExportDirective exportDirective}| {@link ImportDirective importDirective}</pre>
+ * @coverage dart.engine.ast
  */
 abstract class NamespaceDirective extends UriBasedDirective {
   /**
@@ -7514,6 +7809,7 @@
  * that are required (are not optional).
  * <pre>
  * normalFormalParameter ::={@link FunctionTypedFormalParameter functionSignature}| {@link FieldFormalParameter fieldFormalParameter}| {@link SimpleFormalParameter simpleFormalParameter}</pre>
+ * @coverage dart.engine.ast
  */
 abstract class NormalFormalParameter extends FormalParameter {
   /**
@@ -7556,9 +7852,9 @@
   Comment get documentationComment => _comment;
   SimpleIdentifier get identifier => _identifier;
   ParameterKind get kind {
-    ASTNode parent5 = parent;
-    if (parent5 is DefaultFormalParameter) {
-      return ((parent5 as DefaultFormalParameter)).kind;
+    ASTNode parent6 = parent;
+    if (parent6 is DefaultFormalParameter) {
+      return ((parent6 as DefaultFormalParameter)).kind;
     }
     return ParameterKind.REQUIRED;
   }
@@ -7568,13 +7864,15 @@
    */
   NodeList<Annotation> get metadata => _metadata;
   /**
-   * Return {@code true} if this parameter is a const parameter.
-   * @return {@code true} if this parameter is a const parameter
+   * Return {@code true} if this parameter was declared with the 'const' modifier.
+   * @return {@code true} if this parameter was declared with the 'const' modifier
    */
   bool isConst();
   /**
-   * Return {@code true} if this parameter is a final parameter.
-   * @return {@code true} if this parameter is a final parameter
+   * Return {@code true} if this parameter was declared with the 'final' modifier. Parameters that
+   * are declared with the 'const' modifier will return {@code false} even though they are
+   * implicitly final.
+   * @return {@code true} if this parameter was declared with the 'final' modifier
    */
   bool isFinal();
   /**
@@ -7588,8 +7886,8 @@
    * Set the name of the parameter being declared to the given identifier.
    * @param identifier the name of the parameter being declared
    */
-  void set identifier(SimpleIdentifier identifier6) {
-    this._identifier = becomeParentOf(identifier6);
+  void set identifier(SimpleIdentifier identifier8) {
+    this._identifier = becomeParentOf(identifier8);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     if (commentIsBeforeAnnotations()) {
@@ -7633,6 +7931,7 @@
  * nullLiteral ::=
  * 'null'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class NullLiteral extends Literal {
   /**
@@ -7675,6 +7974,7 @@
  * parenthesizedExpression ::=
  * '(' {@link Expression expression} ')'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class ParenthesizedExpression extends Expression {
   /**
@@ -7755,6 +8055,7 @@
  * <pre>
  * partDirective ::={@link Annotation metadata} 'part' {@link StringLiteral partUri} ';'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class PartDirective extends UriBasedDirective {
   /**
@@ -7820,6 +8121,7 @@
  * <pre>
  * partOfDirective ::={@link Annotation metadata} 'part' 'of' {@link Identifier libraryName} ';'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class PartOfDirective extends Directive {
   /**
@@ -7924,6 +8226,7 @@
  * Instances of the class {@code PostfixExpression} represent a postfix unary expression.
  * <pre>
  * postfixExpression ::={@link Expression operand} {@link Token operator}</pre>
+ * @coverage dart.engine.ast
  */
 class PostfixExpression extends Expression {
   /**
@@ -7978,8 +8281,8 @@
    * Set the element associated with the operator to the given element.
    * @param element the element associated with the operator
    */
-  void set element(MethodElement element14) {
-    this._element = element14;
+  void set element(MethodElement element13) {
+    this._element = element13;
   }
   /**
    * Set the expression computing the operand for the operator to the given expression.
@@ -8003,6 +8306,7 @@
  * Instances of the class {@code PrefixExpression} represent a prefix unary expression.
  * <pre>
  * prefixExpression ::={@link Token operator} {@link Expression operand}</pre>
+ * @coverage dart.engine.ast
  */
 class PrefixExpression extends Expression {
   /**
@@ -8057,8 +8361,8 @@
    * Set the element associated with the operator to the given element.
    * @param element the element associated with the operator
    */
-  void set element(MethodElement element15) {
-    this._element = element15;
+  void set element(MethodElement element14) {
+    this._element = element14;
   }
   /**
    * Set the expression computing the operand for the operator to the given expression.
@@ -8084,6 +8388,7 @@
  * identifier.
  * <pre>
  * prefixedIdentifier ::={@link SimpleIdentifier prefix} '.' {@link SimpleIdentifier identifier}</pre>
+ * @coverage dart.engine.ast
  */
 class PrefixedIdentifier extends Identifier {
   /**
@@ -8118,6 +8423,12 @@
   PrefixedIdentifier({SimpleIdentifier prefix, Token period, SimpleIdentifier identifier}) : this.full(prefix, period, identifier);
   accept(ASTVisitor visitor) => visitor.visitPrefixedIdentifier(this);
   Token get beginToken => _prefix.beginToken;
+  Element get element {
+    if (_identifier == null) {
+      return null;
+    }
+    return _identifier.element;
+  }
   Token get endToken => _identifier.endToken;
   /**
    * Return the identifier being prefixed.
@@ -8139,8 +8450,8 @@
    * Set the identifier being prefixed to the given identifier.
    * @param identifier the identifier being prefixed
    */
-  void set identifier(SimpleIdentifier identifier7) {
-    this._identifier = becomeParentOf(identifier7);
+  void set identifier(SimpleIdentifier identifier9) {
+    this._identifier = becomeParentOf(identifier9);
   }
   /**
    * Set the period used to separate the prefix from the identifier to the given token.
@@ -8169,6 +8480,7 @@
  * identifier.
  * <pre>
  * propertyAccess ::={@link Expression target} '.' {@link SimpleIdentifier propertyName}</pre>
+ * @coverage dart.engine.ast
  */
 class PropertyAccess extends Expression {
   /**
@@ -8287,6 +8599,7 @@
  * redirectingConstructorInvocation ::=
  * 'this' ('.' identifier)? arguments
  * </pre>
+ * @coverage dart.engine.ast
  */
 class RedirectingConstructorInvocation extends ConstructorInitializer {
   /**
@@ -8382,15 +8695,15 @@
    * Set the element associated with the constructor to the given element.
    * @param element the element associated with the constructor
    */
-  void set element(ConstructorElement element16) {
-    this._element = element16;
+  void set element(ConstructorElement element15) {
+    this._element = element15;
   }
   /**
    * Set the token for the 'this' keyword to the given token.
    * @param keyword the token for the 'this' keyword
    */
-  void set keyword(Token keyword13) {
-    this._keyword = keyword13;
+  void set keyword(Token keyword14) {
+    this._keyword = keyword14;
   }
   /**
    * Set the token for the period before the name of the constructor that is being invoked to the
@@ -8411,6 +8724,7 @@
  * returnStatement ::=
  * 'return' {@link Expression expression}? ';'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class ReturnStatement extends Statement {
   /**
@@ -8474,8 +8788,8 @@
    * Set the token representing the 'return' keyword to the given token.
    * @param keyword the token representing the 'return' keyword
    */
-  void set keyword(Token keyword14) {
-    this._keyword = keyword14;
+  void set keyword(Token keyword15) {
+    this._keyword = keyword15;
   }
   /**
    * Set the semicolon terminating the statement to the given token.
@@ -8495,6 +8809,7 @@
  * scriptTag ::=
  * '#!' (~NEWLINE)* NEWLINE
  * </pre>
+ * @coverage dart.engine.ast
  */
 class ScriptTag extends ASTNode {
   /**
@@ -8538,6 +8853,7 @@
  * showCombinator ::=
  * 'show' {@link SimpleIdentifier identifier} (',' {@link SimpleIdentifier identifier})
  * </pre>
+ * @coverage dart.engine.ast
  */
 class ShowCombinator extends Combinator {
   /**
@@ -8575,6 +8891,7 @@
  * <pre>
  * simpleFormalParameter ::=
  * ('final' {@link TypeName type} | 'var' | {@link TypeName type})? {@link SimpleIdentifier identifier}</pre>
+ * @coverage dart.engine.ast
  */
 class SimpleFormalParameter extends NormalFormalParameter {
   /**
@@ -8635,8 +8952,8 @@
    * Set the token representing either the 'final', 'const' or 'var' keyword to the given token.
    * @param keyword the token representing either the 'final', 'const' or 'var' keyword
    */
-  void set keyword(Token keyword15) {
-    this._keyword = keyword15;
+  void set keyword(Token keyword16) {
+    this._keyword = keyword16;
   }
   /**
    * Set the name of the declared type of the parameter to the given type name.
@@ -8659,6 +8976,7 @@
  * initialCharacter ::= '_' | '$' | letter
  * internalCharacter ::= '_' | '$' | letter | digit
  * </pre>
+ * @coverage dart.engine.ast
  */
 class SimpleIdentifier extends Identifier {
   /**
@@ -8666,6 +8984,11 @@
    */
   Token _token;
   /**
+   * The element associated with this identifier, or {@code null} if the AST structure has not been
+   * resolved or if this identifier could not be resolved.
+   */
+  Element _element;
+  /**
    * Initialize a newly created identifier.
    * @param token the token representing the identifier
    */
@@ -8679,6 +9002,7 @@
   SimpleIdentifier({Token token}) : this.full(token);
   accept(ASTVisitor visitor) => visitor.visitSimpleIdentifier(this);
   Token get beginToken => _token;
+  Element get element => _element;
   Token get endToken => _token;
   String get name => _token.lexeme;
   /**
@@ -8687,6 +9011,38 @@
    */
   Token get token => _token;
   /**
+   * Return {@code true} if this identifier is the name being declared in a declaration.
+   * @return {@code true} if this identifier is the name being declared in a declaration
+   */
+  bool inDeclarationContext() {
+    ASTNode parent7 = parent;
+    if (parent7 is CatchClause) {
+      CatchClause clause = parent7 as CatchClause;
+      return identical(this, clause.exceptionParameter) || identical(this, clause.stackTraceParameter);
+    } else if (parent7 is ClassDeclaration) {
+      return identical(this, ((parent7 as ClassDeclaration)).name);
+    } else if (parent7 is ClassTypeAlias) {
+      return identical(this, ((parent7 as ClassTypeAlias)).name);
+    } else if (parent7 is ConstructorDeclaration) {
+      return identical(this, ((parent7 as ConstructorDeclaration)).name);
+    } else if (parent7 is FunctionDeclaration) {
+      return identical(this, ((parent7 as FunctionDeclaration)).name);
+    } else if (parent7 is FunctionTypeAlias) {
+      return identical(this, ((parent7 as FunctionTypeAlias)).name);
+    } else if (parent7 is Label) {
+      return identical(this, ((parent7 as Label)).label) && (parent7.parent is LabeledStatement);
+    } else if (parent7 is MethodDeclaration) {
+      return identical(this, ((parent7 as MethodDeclaration)).name);
+    } else if (parent7 is NormalFormalParameter) {
+      return identical(this, ((parent7 as NormalFormalParameter)).identifier);
+    } else if (parent7 is TypeParameter) {
+      return identical(this, ((parent7 as TypeParameter)).name);
+    } else if (parent7 is VariableDeclaration) {
+      return identical(this, ((parent7 as VariableDeclaration)).name);
+    }
+    return false;
+  }
+  /**
    * Return {@code true} if this expression is computing a right-hand value.
    * <p>
    * Note that {@link #inGetterContext()} and {@link #inSetterContext()} are not opposites, nor are
@@ -8694,18 +9050,25 @@
    * @return {@code true} if this expression is in a context where a getter will be invoked
    */
   bool inGetterContext() {
-    ASTNode parent6 = parent;
+    ASTNode parent8 = parent;
     ASTNode target = this;
-    if (parent6 is PrefixedIdentifier) {
-      PrefixedIdentifier prefixed = (parent6 as PrefixedIdentifier);
+    if (parent8 is PrefixedIdentifier) {
+      PrefixedIdentifier prefixed = parent8 as PrefixedIdentifier;
       if (identical(prefixed.prefix, this)) {
         return true;
       }
-      parent6 = prefixed.parent;
+      parent8 = prefixed.parent;
       target = prefixed;
+    } else if (parent8 is PropertyAccess) {
+      PropertyAccess access = parent8 as PropertyAccess;
+      if (identical(access.target, this)) {
+        return true;
+      }
+      parent8 = access.parent;
+      target = access;
     }
-    if (parent6 is AssignmentExpression) {
-      AssignmentExpression expr = (parent6 as AssignmentExpression);
+    if (parent8 is AssignmentExpression) {
+      AssignmentExpression expr = parent8 as AssignmentExpression;
       if (identical(expr.leftHandSide, target) && identical(expr.operator.type, TokenType.EQ)) {
         return false;
       }
@@ -8720,27 +9083,41 @@
    * @return {@code true} if this expression is in a context where a setter will be invoked
    */
   bool inSetterContext() {
-    ASTNode parent7 = parent;
+    ASTNode parent9 = parent;
     ASTNode target = this;
-    if (parent7 is PrefixedIdentifier) {
-      PrefixedIdentifier prefixed = (parent7 as PrefixedIdentifier);
+    if (parent9 is PrefixedIdentifier) {
+      PrefixedIdentifier prefixed = parent9 as PrefixedIdentifier;
       if (identical(prefixed.prefix, this)) {
         return false;
       }
-      parent7 = prefixed.parent;
+      parent9 = prefixed.parent;
       target = prefixed;
+    } else if (parent9 is PropertyAccess) {
+      PropertyAccess access = parent9 as PropertyAccess;
+      if (identical(access.target, this)) {
+        return false;
+      }
+      parent9 = access.parent;
+      target = access;
     }
-    if (parent7 is PrefixExpression) {
-      return ((parent7 as PrefixExpression)).operator.type.isIncrementOperator();
-    } else if (parent7 is PostfixExpression) {
+    if (parent9 is PrefixExpression) {
+      return ((parent9 as PrefixExpression)).operator.type.isIncrementOperator();
+    } else if (parent9 is PostfixExpression) {
       return true;
-    } else if (parent7 is AssignmentExpression) {
-      return identical(((parent7 as AssignmentExpression)).leftHandSide, target);
+    } else if (parent9 is AssignmentExpression) {
+      return identical(((parent9 as AssignmentExpression)).leftHandSide, target);
     }
     return false;
   }
   bool isSynthetic() => _token.isSynthetic();
   /**
+   * Set the element associated with this identifier to the given element.
+   * @param element the element associated with this identifier
+   */
+  void set element(Element element16) {
+    this._element = element16;
+  }
+  /**
    * Set the token representing the identifier to the given token.
    * @param token the token representing the literal
    */
@@ -8769,6 +9146,7 @@
  * "'" characters "'"
  * '"' characters '"'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class SimpleStringLiteral extends StringLiteral {
   /**
@@ -8845,6 +9223,7 @@
  * statement.
  * <pre>
  * statement ::={@link Block block}| {@link VariableDeclarationStatement initializedVariableDeclaration ';'}| {@link ForStatement forStatement}| {@link ForEachStatement forEachStatement}| {@link WhileStatement whileStatement}| {@link DoStatement doStatement}| {@link SwitchStatement switchStatement}| {@link IfStatement ifStatement}| {@link TryStatement tryStatement}| {@link BreakStatement breakStatement}| {@link ContinueStatement continueStatement}| {@link ReturnStatement returnStatement}| {@link ExpressionStatement expressionStatement}| {@link FunctionDeclarationStatement functionSignature functionBody}</pre>
+ * @coverage dart.engine.ast
  */
 abstract class Statement extends ASTNode {
 }
@@ -8855,6 +9234,7 @@
  * ''' {@link InterpolationElement interpolationElement}* '''
  * | '"' {@link InterpolationElement interpolationElement}* '"'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class StringInterpolation extends StringLiteral {
   /**
@@ -8890,6 +9270,7 @@
  * Instances of the class {@code StringLiteral} represent a string literal expression.
  * <pre>
  * stringLiteral ::={@link SimpleStringLiteral simpleStringLiteral}| {@link AdjacentStrings adjacentStrings}| {@link StringInterpolation stringInterpolation}</pre>
+ * @coverage dart.engine.ast
  */
 abstract class StringLiteral extends Literal {
 }
@@ -8899,6 +9280,7 @@
  * <pre>
  * superInvocation ::=
  * 'super' ('.' {@link SimpleIdentifier name})? {@link ArgumentList argumentList}</pre>
+ * @coverage dart.engine.ast
  */
 class SuperConstructorInvocation extends ConstructorInitializer {
   /**
@@ -9001,8 +9383,8 @@
    * Set the token for the 'super' keyword to the given token.
    * @param keyword the token for the 'super' keyword
    */
-  void set keyword(Token keyword16) {
-    this._keyword = keyword16;
+  void set keyword(Token keyword17) {
+    this._keyword = keyword17;
   }
   /**
    * Set the token for the period before the name of the constructor that is being invoked to the
@@ -9023,6 +9405,7 @@
  * superExpression ::=
  * 'super'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class SuperExpression extends Expression {
   /**
@@ -9053,8 +9436,8 @@
    * Set the token representing the keyword to the given token.
    * @param keyword the token representing the keyword
    */
-  void set keyword(Token keyword17) {
-    this._keyword = keyword17;
+  void set keyword(Token keyword18) {
+    this._keyword = keyword18;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
   }
@@ -9063,6 +9446,7 @@
  * Instances of the class {@code SwitchCase} represent the case in a switch statement.
  * <pre>
  * switchCase ::={@link SimpleIdentifier label}* 'case' {@link Expression expression} ':' {@link Statement statement}</pre>
+ * @coverage dart.engine.ast
  */
 class SwitchCase extends SwitchMember {
   /**
@@ -9112,6 +9496,7 @@
  * Instances of the class {@code SwitchDefault} represent the default case in a switch statement.
  * <pre>
  * switchDefault ::={@link SimpleIdentifier label}* 'default' ':' {@link Statement statement}</pre>
+ * @coverage dart.engine.ast
  */
 class SwitchDefault extends SwitchMember {
   /**
@@ -9145,6 +9530,7 @@
  * switchCase
  * | switchDefault
  * </pre>
+ * @coverage dart.engine.ast
  */
 abstract class SwitchMember extends ASTNode {
   /**
@@ -9229,8 +9615,8 @@
    * Set the token representing the 'case' or 'default' keyword to the given token.
    * @param keyword the token representing the 'case' or 'default' keyword
    */
-  void set keyword(Token keyword18) {
-    this._keyword = keyword18;
+  void set keyword(Token keyword19) {
+    this._keyword = keyword19;
   }
 }
 /**
@@ -9239,6 +9625,7 @@
  * switchStatement ::=
  * 'switch' '(' {@link Expression expression} ')' '{' {@link SwitchCase switchCase}* {@link SwitchDefault defaultCase}? '}'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class SwitchStatement extends Statement {
   /**
@@ -9350,8 +9737,8 @@
    * Set the token representing the 'switch' keyword to the given token.
    * @param keyword the token representing the 'switch' keyword
    */
-  void set keyword(Token keyword19) {
-    this._keyword = keyword19;
+  void set keyword(Token keyword20) {
+    this._keyword = keyword20;
   }
   /**
    * Set the left curly bracket to the given token.
@@ -9392,6 +9779,7 @@
  * thisExpression ::=
  * 'this'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class ThisExpression extends Expression {
   /**
@@ -9422,8 +9810,8 @@
    * Set the token representing the keyword to the given token.
    * @param keyword the token representing the keyword
    */
-  void set keyword(Token keyword20) {
-    this._keyword = keyword20;
+  void set keyword(Token keyword21) {
+    this._keyword = keyword21;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
   }
@@ -9434,6 +9822,7 @@
  * throwExpression ::=
  * 'throw' {@link Expression expression}? ';'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class ThrowExpression extends Expression {
   /**
@@ -9492,8 +9881,8 @@
    * Set the token representing the 'throw' keyword to the given token.
    * @param keyword the token representing the 'throw' keyword
    */
-  void set keyword(Token keyword21) {
-    this._keyword = keyword21;
+  void set keyword(Token keyword22) {
+    this._keyword = keyword22;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_expression, visitor);
@@ -9507,6 +9896,7 @@
  * ('final' | 'const') type? staticFinalDeclarationList ';'
  * | variableDeclaration ';'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class TopLevelVariableDeclaration extends CompilationUnitMember {
   /**
@@ -9537,6 +9927,7 @@
    */
   TopLevelVariableDeclaration({Comment comment, List<Annotation> metadata, VariableDeclarationList variableList, Token semicolon}) : this.full(comment, metadata, variableList, semicolon);
   accept(ASTVisitor visitor) => visitor.visitTopLevelVariableDeclaration(this);
+  Element get element => null;
   Token get endToken => _semicolon;
   /**
    * Return the semicolon terminating the declaration.
@@ -9575,6 +9966,7 @@
  * 'try' {@link Block block} ({@link CatchClause catchClause}+ finallyClause? | finallyClause)
  * finallyClause ::=
  * 'finally' {@link Block block}</pre>
+ * @coverage dart.engine.ast
  */
 class TryStatement extends Statement {
   /**
@@ -9706,6 +10098,7 @@
  * classTypeAlias
  * | functionTypeAlias
  * </pre>
+ * @coverage dart.engine.ast
  */
 abstract class TypeAlias extends CompilationUnitMember {
   /**
@@ -9750,8 +10143,8 @@
    * Set the token representing the 'typedef' keyword to the given token.
    * @param keyword the token representing the 'typedef' keyword
    */
-  void set keyword(Token keyword22) {
-    this._keyword = keyword22;
+  void set keyword(Token keyword23) {
+    this._keyword = keyword23;
   }
   /**
    * Set the semicolon terminating the declaration to the given token.
@@ -9768,6 +10161,7 @@
  * typeArguments ::=
  * '<' typeName (',' typeName)* '>'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class TypeArgumentList extends ASTNode {
   /**
@@ -9843,6 +10237,7 @@
  * <pre>
  * typeName ::={@link Identifier identifier} typeArguments?
  * </pre>
+ * @coverage dart.engine.ast
  */
 class TypeName extends ASTNode {
   /**
@@ -9930,6 +10325,7 @@
  * <pre>
  * typeParameter ::={@link SimpleIdentifier name} ('extends' {@link TypeName bound})?
  * </pre>
+ * @coverage dart.engine.ast
  */
 class TypeParameter extends Declaration {
   /**
@@ -9975,6 +10371,7 @@
    * @return the name of the upper bound for legal arguments
    */
   TypeName get bound => _bound;
+  TypeVariableElement get element => _name != null ? (_name.element as TypeVariableElement) : null;
   Token get endToken {
     if (_bound == null) {
       return _name.endToken;
@@ -10002,8 +10399,8 @@
    * Set the token representing the 'assert' keyword to the given token.
    * @param keyword the token representing the 'assert' keyword
    */
-  void set keyword(Token keyword23) {
-    this._keyword = keyword23;
+  void set keyword(Token keyword24) {
+    this._keyword = keyword24;
   }
   /**
    * Set the name of the type parameter to the given identifier.
@@ -10025,6 +10422,7 @@
  * typeParameterList ::=
  * '<' {@link TypeParameter typeParameter} (',' {@link TypeParameter typeParameter})* '>'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class TypeParameterList extends ASTNode {
   /**
@@ -10085,6 +10483,7 @@
  * associated with them.
  * <pre>
  * listLiteral ::={@link ListLiteral listLiteral}| {@link MapLiteral mapLiteral}</pre>
+ * @coverage dart.engine.ast
  */
 abstract class TypedLiteral extends Literal {
   /**
@@ -10148,6 +10547,7 @@
  * a directive that references a URI.
  * <pre>
  * uriBasedDirective ::={@link ExportDirective exportDirective}| {@link ImportDirective importDirective}| {@link PartDirective partDirective}</pre>
+ * @coverage dart.engine.ast
  */
 abstract class UriBasedDirective extends Directive {
   /**
@@ -10193,6 +10593,7 @@
  * <pre>
  * variableDeclaration ::={@link SimpleIdentifier identifier} ('=' {@link Expression initialValue})?
  * </pre>
+ * @coverage dart.engine.ast
  */
 class VariableDeclaration extends Declaration {
   /**
@@ -10232,11 +10633,6 @@
    */
   VariableDeclaration({Comment comment, List<Annotation> metadata, SimpleIdentifier name, Token equals, Expression initializer}) : this.full(comment, metadata, name, equals, initializer);
   accept(ASTVisitor visitor) => visitor.visitVariableDeclaration(this);
-  /**
-   * Return the {@link VariableElement} associated with this variable, or {@code null} if the AST
-   * structure has not been resolved.
-   * @return the {@link VariableElement} associated with this variable
-   */
   VariableElement get element => _name != null ? (_name.element as VariableElement) : null;
   Token get endToken {
     if (_initializer != null) {
@@ -10262,6 +10658,24 @@
    */
   SimpleIdentifier get name => _name;
   /**
+   * Return {@code true} if this variable was declared with the 'const' modifier.
+   * @return {@code true} if this variable was declared with the 'const' modifier
+   */
+  bool isConst() {
+    ASTNode parent10 = parent;
+    return parent10 is VariableDeclarationList && ((parent10 as VariableDeclarationList)).isConst();
+  }
+  /**
+   * Return {@code true} if this variable was declared with the 'final' modifier. Variables that are
+   * declared with the 'const' modifier will return {@code false} even though they are implicitly
+   * final.
+   * @return {@code true} if this variable was declared with the 'final' modifier
+   */
+  bool isFinal() {
+    ASTNode parent11 = parent;
+    return parent11 is VariableDeclarationList && ((parent11 as VariableDeclarationList)).isFinal();
+  }
+  /**
    * Set the equal sign separating the variable name from the initial value to the given token.
    * @param equals the equal sign separating the variable name from the initial value
    */
@@ -10300,6 +10714,7 @@
  * | 'const' {@link TypeName type}?
  * | 'var'
  * | {@link TypeName type}</pre>
+ * @coverage dart.engine.ast
  */
 class VariableDeclarationList extends ASTNode {
   /**
@@ -10361,11 +10776,23 @@
    */
   NodeList<VariableDeclaration> get variables => _variables;
   /**
+   * Return {@code true} if the variables in this list were declared with the 'const' modifier.
+   * @return {@code true} if the variables in this list were declared with the 'const' modifier
+   */
+  bool isConst() => _keyword is KeywordToken && identical(((_keyword as KeywordToken)).keyword, Keyword.CONST);
+  /**
+   * Return {@code true} if the variables in this list were declared with the 'final' modifier.
+   * Variables that are declared with the 'const' modifier will return {@code false} even though
+   * they are implicitly final.
+   * @return {@code true} if the variables in this list were declared with the 'final' modifier
+   */
+  bool isFinal() => _keyword is KeywordToken && identical(((_keyword as KeywordToken)).keyword, Keyword.FINAL);
+  /**
    * Set the token representing the 'final', 'const' or 'var' keyword to the given token.
    * @param keyword the token representing the 'final', 'const' or 'var' keyword
    */
-  void set keyword(Token keyword24) {
-    this._keyword = keyword24;
+  void set keyword(Token keyword25) {
+    this._keyword = keyword25;
   }
   /**
    * Set the type of the variables being declared to the given type name.
@@ -10385,6 +10812,7 @@
  * <pre>
  * variableDeclarationStatement ::={@link VariableDeclarationList variableList} ';'
  * </pre>
+ * @coverage dart.engine.ast
  */
 class VariableDeclarationStatement extends Statement {
   /**
@@ -10446,6 +10874,7 @@
  * <pre>
  * whileStatement ::=
  * 'while' '(' {@link Expression condition} ')' {@link Statement body}</pre>
+ * @coverage dart.engine.ast
  */
 class WhileStatement extends Statement {
   /**
@@ -10539,8 +10968,8 @@
    * Set the token representing the 'while' keyword to the given token.
    * @param keyword the token representing the 'while' keyword
    */
-  void set keyword(Token keyword25) {
-    this._keyword = keyword25;
+  void set keyword(Token keyword26) {
+    this._keyword = keyword26;
   }
   /**
    * Set the left parenthesis to the given token.
@@ -10567,6 +10996,7 @@
  * withClause ::=
  * 'with' {@link TypeName mixin} (',' {@link TypeName mixin})
  * </pre>
+ * @coverage dart.engine.ast
  */
 class WithClause extends ASTNode {
   /**
@@ -10647,6 +11077,7 @@
  * In addition, this class defines several values that can be returned to indicate various
  * conditions encountered during evaluation. These are documented with the static field that define
  * those values.
+ * @coverage dart.engine.ast
  */
 class ConstantEvaluator extends GeneralizingASTVisitor<Object> {
   /**
@@ -10654,14 +11085,25 @@
    * expressions.
    */
   static Object NOT_A_CONSTANT = new Object();
+  /**
+   * The error reporter by which errors will be reported.
+   */
+  ErrorReporter _errorReporter;
+  /**
+   * Initialize a newly created constant evaluator.
+   * @param errorReporter the error reporter by which errors will be reported
+   */
+  ConstantEvaluator(ErrorReporter errorReporter) {
+    this._errorReporter = errorReporter;
+  }
   Object visitAdjacentStrings(AdjacentStrings node) {
-    StringBuffer builder = new StringBuffer();
+    JavaStringBuilder builder = new JavaStringBuilder();
     for (StringLiteral string in node.strings) {
       Object value = string.accept(this);
       if (identical(value, NOT_A_CONSTANT)) {
         return value;
       }
-      builder.add(value);
+      builder.append(value);
     }
     return builder.toString();
   }
@@ -10674,114 +11116,137 @@
     if (identical(rightOperand2, NOT_A_CONSTANT)) {
       return rightOperand2;
     }
-    if (node.operator.type == TokenType.AMPERSAND) {
-      if (leftOperand2 is int && rightOperand2 is int) {
-        return ((leftOperand2 as int)) & (rightOperand2 as int);
+    while (true) {
+      if (node.operator.type == TokenType.AMPERSAND) {
+        if (leftOperand2 is int && rightOperand2 is int) {
+          return ((leftOperand2 as int)) & (rightOperand2 as int);
+        }
+      } else if (node.operator.type == TokenType.AMPERSAND_AMPERSAND) {
+        if (leftOperand2 is bool && rightOperand2 is bool) {
+          return ((leftOperand2 as bool)) && ((rightOperand2 as bool));
+        }
+      } else if (node.operator.type == TokenType.BANG_EQ) {
+        if (leftOperand2 is bool && rightOperand2 is bool) {
+          return ((leftOperand2 as bool)) != ((rightOperand2 as bool));
+        } else if (leftOperand2 is int && rightOperand2 is int) {
+          return ((leftOperand2 as int)) != rightOperand2;
+        } else if (leftOperand2 is double && rightOperand2 is double) {
+          return ((leftOperand2 as double)) != rightOperand2;
+        } else if (leftOperand2 is String && rightOperand2 is String) {
+          return ((leftOperand2 as String)) != rightOperand2;
+        }
+      } else if (node.operator.type == TokenType.BAR) {
+        if (leftOperand2 is int && rightOperand2 is int) {
+          return ((leftOperand2 as int)) | (rightOperand2 as int);
+        }
+      } else if (node.operator.type == TokenType.BAR_BAR) {
+        if (leftOperand2 is bool && rightOperand2 is bool) {
+          return ((leftOperand2 as bool)) || ((rightOperand2 as bool));
+        }
+      } else if (node.operator.type == TokenType.CARET) {
+        if (leftOperand2 is int && rightOperand2 is int) {
+          return ((leftOperand2 as int)) ^ (rightOperand2 as int);
+        }
+      } else if (node.operator.type == TokenType.EQ_EQ) {
+        if (leftOperand2 is bool && rightOperand2 is bool) {
+          return identical(((leftOperand2 as bool)), ((rightOperand2 as bool)));
+        } else if (leftOperand2 is int && rightOperand2 is int) {
+          return ((leftOperand2 as int)) == rightOperand2;
+        } else if (leftOperand2 is double && rightOperand2 is double) {
+          return ((leftOperand2 as double)) == rightOperand2;
+        } else if (leftOperand2 is String && rightOperand2 is String) {
+          return ((leftOperand2 as String)) == rightOperand2;
+        }
+      } else if (node.operator.type == TokenType.GT) {
+        if (leftOperand2 is int && rightOperand2 is int) {
+          return ((leftOperand2 as int)).compareTo((rightOperand2 as int)) > 0;
+        } else if (leftOperand2 is double && rightOperand2 is double) {
+          return ((leftOperand2 as double)).compareTo((rightOperand2 as double)) > 0;
+        }
+      } else if (node.operator.type == TokenType.GT_EQ) {
+        if (leftOperand2 is int && rightOperand2 is int) {
+          return ((leftOperand2 as int)).compareTo((rightOperand2 as int)) >= 0;
+        } else if (leftOperand2 is double && rightOperand2 is double) {
+          return ((leftOperand2 as double)).compareTo((rightOperand2 as double)) >= 0;
+        }
+      } else if (node.operator.type == TokenType.GT_GT) {
+        if (leftOperand2 is int && rightOperand2 is int) {
+          return ((leftOperand2 as int)) >> ((rightOperand2 as int));
+        }
+      } else if (node.operator.type == TokenType.LT) {
+        if (leftOperand2 is int && rightOperand2 is int) {
+          return ((leftOperand2 as int)).compareTo((rightOperand2 as int)) < 0;
+        } else if (leftOperand2 is double && rightOperand2 is double) {
+          return ((leftOperand2 as double)).compareTo((rightOperand2 as double)) < 0;
+        }
+      } else if (node.operator.type == TokenType.LT_EQ) {
+        if (leftOperand2 is int && rightOperand2 is int) {
+          return ((leftOperand2 as int)).compareTo((rightOperand2 as int)) <= 0;
+        } else if (leftOperand2 is double && rightOperand2 is double) {
+          return ((leftOperand2 as double)).compareTo((rightOperand2 as double)) <= 0;
+        }
+      } else if (node.operator.type == TokenType.LT_LT) {
+        if (leftOperand2 is int && rightOperand2 is int) {
+          return ((leftOperand2 as int)) << ((rightOperand2 as int));
+        }
+      } else if (node.operator.type == TokenType.MINUS) {
+        if (leftOperand2 is int && rightOperand2 is int) {
+          return ((leftOperand2 as int)) - (rightOperand2 as int);
+        } else if (leftOperand2 is double && rightOperand2 is double) {
+          return ((leftOperand2 as double)) - ((rightOperand2 as double));
+        }
+      } else if (node.operator.type == TokenType.PERCENT) {
+        if (leftOperand2 is int && rightOperand2 is int) {
+          return ((leftOperand2 as int)).remainder((rightOperand2 as int));
+        } else if (leftOperand2 is double && rightOperand2 is double) {
+          return ((leftOperand2 as double)) % ((rightOperand2 as double));
+        }
+      } else if (node.operator.type == TokenType.PLUS) {
+        if (leftOperand2 is int && rightOperand2 is int) {
+          return ((leftOperand2 as int)) + (rightOperand2 as int);
+        } else if (leftOperand2 is double && rightOperand2 is double) {
+          return ((leftOperand2 as double)) + ((rightOperand2 as double));
+        }
+      } else if (node.operator.type == TokenType.STAR) {
+        if (leftOperand2 is int && rightOperand2 is int) {
+          return ((leftOperand2 as int)) * (rightOperand2 as int);
+        } else if (leftOperand2 is double && rightOperand2 is double) {
+          return ((leftOperand2 as double)) * ((rightOperand2 as double));
+        }
+      } else if (node.operator.type == TokenType.SLASH) {
+        if (leftOperand2 is int && rightOperand2 is int) {
+          if (rightOperand2 != 0) {
+            return ((leftOperand2 as int)) ~/ (rightOperand2 as int);
+          } else {
+            reportDivideByZeroError(node);
+            return 0;
+          }
+        } else if (leftOperand2 is double && rightOperand2 is double) {
+          if (rightOperand2 != 0) {
+            return ((leftOperand2 as double)) / ((rightOperand2 as double));
+          } else {
+            reportDivideByZeroError(node);
+            return 0;
+          }
+        }
+      } else if (node.operator.type == TokenType.TILDE_SLASH) {
+        if (leftOperand2 is int && rightOperand2 is int) {
+          if (rightOperand2 != 0) {
+            return ((leftOperand2 as int)) ~/ (rightOperand2 as int);
+          } else {
+            reportDivideByZeroError(node);
+            return 0;
+          }
+        } else if (leftOperand2 is double && rightOperand2 is double) {
+          if (rightOperand2 != 0) {
+            return ((leftOperand2 as double)) ~/ ((rightOperand2 as double));
+          } else {
+            reportDivideByZeroError(node);
+            return 0;
+          }
+        }
       }
-    } else if (node.operator.type == TokenType.AMPERSAND_AMPERSAND) {
-      if (leftOperand2 is bool && rightOperand2 is bool) {
-        return ((leftOperand2 as bool)) && ((rightOperand2 as bool));
-      }
-    } else if (node.operator.type == TokenType.BANG_EQ) {
-      if (leftOperand2 is bool && rightOperand2 is bool) {
-        return ((leftOperand2 as bool)) != ((rightOperand2 as bool));
-      } else if (leftOperand2 is int && rightOperand2 is int) {
-        return ((leftOperand2 as int)) != rightOperand2;
-      } else if (leftOperand2 is double && rightOperand2 is double) {
-        return ((leftOperand2 as double)) != rightOperand2;
-      } else if (leftOperand2 is String && rightOperand2 is String) {
-        return ((leftOperand2 as String)) != rightOperand2;
-      }
-    } else if (node.operator.type == TokenType.BAR) {
-      if (leftOperand2 is int && rightOperand2 is int) {
-        return ((leftOperand2 as int)) | (rightOperand2 as int);
-      }
-    } else if (node.operator.type == TokenType.BAR_BAR) {
-      if (leftOperand2 is bool && rightOperand2 is bool) {
-        return ((leftOperand2 as bool)) || ((rightOperand2 as bool));
-      }
-    } else if (node.operator.type == TokenType.CARET) {
-      if (leftOperand2 is int && rightOperand2 is int) {
-        return ((leftOperand2 as int)) ^ (rightOperand2 as int);
-      }
-    } else if (node.operator.type == TokenType.EQ_EQ) {
-      if (leftOperand2 is bool && rightOperand2 is bool) {
-        return identical(((leftOperand2 as bool)), ((rightOperand2 as bool)));
-      } else if (leftOperand2 is int && rightOperand2 is int) {
-        return ((leftOperand2 as int)) == rightOperand2;
-      } else if (leftOperand2 is double && rightOperand2 is double) {
-        return ((leftOperand2 as double)) == rightOperand2;
-      } else if (leftOperand2 is String && rightOperand2 is String) {
-        return ((leftOperand2 as String)) == rightOperand2;
-      }
-    } else if (node.operator.type == TokenType.GT) {
-      if (leftOperand2 is int && rightOperand2 is int) {
-        return ((leftOperand2 as int)).compareTo((rightOperand2 as int)) > 0;
-      } else if (leftOperand2 is double && rightOperand2 is double) {
-        return ((leftOperand2 as double)).compareTo((rightOperand2 as double)) > 0;
-      }
-    } else if (node.operator.type == TokenType.GT_EQ) {
-      if (leftOperand2 is int && rightOperand2 is int) {
-        return ((leftOperand2 as int)).compareTo((rightOperand2 as int)) >= 0;
-      } else if (leftOperand2 is double && rightOperand2 is double) {
-        return ((leftOperand2 as double)).compareTo((rightOperand2 as double)) >= 0;
-      }
-    } else if (node.operator.type == TokenType.GT_GT) {
-      if (leftOperand2 is int && rightOperand2 is int) {
-        return ((leftOperand2 as int)) >> ((rightOperand2 as int));
-      }
-    } else if (node.operator.type == TokenType.LT) {
-      if (leftOperand2 is int && rightOperand2 is int) {
-        return ((leftOperand2 as int)).compareTo((rightOperand2 as int)) < 0;
-      } else if (leftOperand2 is double && rightOperand2 is double) {
-        return ((leftOperand2 as double)).compareTo((rightOperand2 as double)) < 0;
-      }
-    } else if (node.operator.type == TokenType.LT_EQ) {
-      if (leftOperand2 is int && rightOperand2 is int) {
-        return ((leftOperand2 as int)).compareTo((rightOperand2 as int)) <= 0;
-      } else if (leftOperand2 is double && rightOperand2 is double) {
-        return ((leftOperand2 as double)).compareTo((rightOperand2 as double)) <= 0;
-      }
-    } else if (node.operator.type == TokenType.LT_LT) {
-      if (leftOperand2 is int && rightOperand2 is int) {
-        return ((leftOperand2 as int)) << ((rightOperand2 as int));
-      }
-    } else if (node.operator.type == TokenType.MINUS) {
-      if (leftOperand2 is int && rightOperand2 is int) {
-        return ((leftOperand2 as int)) - (rightOperand2 as int);
-      } else if (leftOperand2 is double && rightOperand2 is double) {
-        return ((leftOperand2 as double)) - ((rightOperand2 as double));
-      }
-    } else if (node.operator.type == TokenType.PERCENT) {
-      if (leftOperand2 is int && rightOperand2 is int) {
-        return ((leftOperand2 as int)).remainder((rightOperand2 as int));
-      } else if (leftOperand2 is double && rightOperand2 is double) {
-        return ((leftOperand2 as double)) % ((rightOperand2 as double));
-      }
-    } else if (node.operator.type == TokenType.PLUS) {
-      if (leftOperand2 is int && rightOperand2 is int) {
-        return ((leftOperand2 as int)) + (rightOperand2 as int);
-      } else if (leftOperand2 is double && rightOperand2 is double) {
-        return ((leftOperand2 as double)) + ((rightOperand2 as double));
-      }
-    } else if (node.operator.type == TokenType.STAR) {
-      if (leftOperand2 is int && rightOperand2 is int) {
-        return ((leftOperand2 as int)) * (rightOperand2 as int);
-      } else if (leftOperand2 is double && rightOperand2 is double) {
-        return ((leftOperand2 as double)) * ((rightOperand2 as double));
-      }
-    } else if (node.operator.type == TokenType.SLASH) {
-      if (leftOperand2 is int && rightOperand2 is int) {
-        return ((leftOperand2 as int)) ~/ (rightOperand2 as int);
-      } else if (leftOperand2 is double && rightOperand2 is double) {
-        return ((leftOperand2 as double)) / ((rightOperand2 as double));
-      }
-    } else if (node.operator.type == TokenType.TILDE_SLASH) {
-      if (leftOperand2 is int && rightOperand2 is int) {
-        return ((leftOperand2 as int)) ~/ (rightOperand2 as int);
-      } else if (leftOperand2 is double && rightOperand2 is double) {
-        return ((leftOperand2 as double)) ~/ ((rightOperand2 as double));
-      }
+      break;
     }
     return visitExpression(node);
   }
@@ -10811,11 +11276,11 @@
     Map<String, Object> map = new Map<String, Object>();
     for (MapLiteralEntry entry in node.entries) {
       Object key2 = entry.key.accept(this);
-      Object value7 = entry.value.accept(this);
-      if (key2 is! String || identical(value7, NOT_A_CONSTANT)) {
+      Object value8 = entry.value.accept(this);
+      if (key2 is! String || identical(value8, NOT_A_CONSTANT)) {
         return NOT_A_CONSTANT;
       }
-      map[(key2 as String)] = value7;
+      map[(key2 as String)] = value8;
     }
     return map;
   }
@@ -10829,24 +11294,27 @@
     if (identical(operand2, NOT_A_CONSTANT)) {
       return operand2;
     }
-    if (node.operator.type == TokenType.BANG) {
-      if (identical(operand2, true)) {
-        return false;
-      } else if (identical(operand2, false)) {
-        return true;
+    while (true) {
+      if (node.operator.type == TokenType.BANG) {
+        if (identical(operand2, true)) {
+          return false;
+        } else if (identical(operand2, false)) {
+          return true;
+        }
+      } else if (node.operator.type == TokenType.TILDE) {
+        if (operand2 is int) {
+          return ~((operand2 as int));
+        }
+      } else if (node.operator.type == TokenType.MINUS) {
+        if (operand2 == null) {
+          return null;
+        } else if (operand2 is int) {
+          return -((operand2 as int));
+        } else if (operand2 is double) {
+          return -((operand2 as double));
+        }
       }
-    } else if (node.operator.type == TokenType.TILDE) {
-      if (operand2 is int) {
-        return ~((operand2 as int));
-      }
-    } else if (node.operator.type == TokenType.MINUS) {
-      if (operand2 == null) {
-        return null;
-      } else if (operand2 is int) {
-        return -((operand2 as int));
-      } else if (operand2 is double) {
-        return -((operand2 as double));
-      }
+      break;
     }
     return NOT_A_CONSTANT;
   }
@@ -10854,13 +11322,13 @@
   Object visitSimpleIdentifier(SimpleIdentifier node) => getConstantValue(null);
   Object visitSimpleStringLiteral(SimpleStringLiteral node) => node.value;
   Object visitStringInterpolation(StringInterpolation node) {
-    StringBuffer builder = new StringBuffer();
+    JavaStringBuilder builder = new JavaStringBuilder();
     for (InterpolationElement element in node.elements) {
       Object value = element.accept(this);
       if (identical(value, NOT_A_CONSTANT)) {
         return value;
       }
-      builder.add(value);
+      builder.append(value);
     }
     return builder.toString();
   }
@@ -10871,12 +11339,56 @@
    */
   Object getConstantValue(Element element) {
     if (element is FieldElement) {
-      FieldElement field = (element as FieldElement);
+      FieldElement field = element as FieldElement;
       if (field.isStatic() && field.isConst()) {
       }
     }
     return NOT_A_CONSTANT;
   }
+  void reportDivideByZeroError(BinaryExpression node) {
+    _errorReporter.reportError(CompileTimeErrorCode.COMPILE_TIME_CONSTANT_RAISES_EXCEPTION_DIVIDE_BY_ZERO, node, []);
+  }
+}
+/**
+ * Instances of the class {@code ElementLocator} locate the {@link Element Dart model element}associated with a given {@link ASTNode AST node}.
+ * @coverage dart.engine.ast
+ */
+class ElementLocator {
+  /**
+   * Locate the {@link Element Dart model element} associated with the given {@link ASTNode AST
+   * node}.
+   * @param node the node (not {@code null})
+   * @return the associated element, or {@code null} if none is found
+   */
+  static Element locate(ASTNode node) {
+    ElementLocator_ElementMapper mapper = new ElementLocator_ElementMapper();
+    return node.accept(mapper);
+  }
+  /**
+   * Clients should use {@link #locate(ASTNode)}.
+   */
+  ElementLocator() {
+  }
+}
+/**
+ * Visitor that maps nodes to elements.
+ */
+class ElementLocator_ElementMapper extends GeneralizingASTVisitor<Element> {
+  Element visitBinaryExpression(BinaryExpression node) => node.element;
+  Element visitIdentifier(Identifier node) => node.element;
+  Element visitImportDirective(ImportDirective node) => node.element;
+  Element visitIndexExpression(IndexExpression node) => node.element;
+  Element visitLibraryDirective(LibraryDirective node) => node.element;
+  Element visitPostfixExpression(PostfixExpression node) => node.element;
+  Element visitPrefixedIdentifier(PrefixedIdentifier node) => node.element;
+  Element visitPrefixExpression(PrefixExpression node) => node.element;
+  Element visitStringLiteral(StringLiteral node) {
+    ASTNode parent12 = node.parent;
+    if (parent12 is UriBasedDirective) {
+      return ((parent12 as UriBasedDirective)).element;
+    }
+    return null;
+  }
 }
 /**
  * Instances of the class {@code GeneralizingASTVisitor} implement an AST visitor that will
@@ -10892,6 +11404,7 @@
  * explicitly invoke the more general visit method. Failure to do so will cause the visit methods
  * for superclasses of the node to not be invoked and will cause the children of the visited node to
  * not be visited.
+ * @coverage dart.engine.ast
  */
 class GeneralizingASTVisitor<R> implements ASTVisitor<R> {
   R visitAdjacentStrings(AdjacentStrings node) => visitStringLiteral(node);
@@ -10924,6 +11437,7 @@
   R visitConstructorName(ConstructorName node) => visitNode(node);
   R visitContinueStatement(ContinueStatement node) => visitStatement(node);
   R visitDeclaration(Declaration node) => visitAnnotatedNode(node);
+  R visitDeclaredIdentifier(DeclaredIdentifier node) => visitDeclaration(node);
   R visitDefaultFormalParameter(DefaultFormalParameter node) => visitFormalParameter(node);
   R visitDirective(Directive node) => visitAnnotatedNode(node);
   R visitDoStatement(DoStatement node) => visitStatement(node);
@@ -10969,7 +11483,7 @@
   R visitMapLiteral(MapLiteral node) => visitTypedLiteral(node);
   R visitMapLiteralEntry(MapLiteralEntry node) => visitNode(node);
   R visitMethodDeclaration(MethodDeclaration node) => visitClassMember(node);
-  R visitMethodInvocation(MethodInvocation node) => visitNode(node);
+  R visitMethodInvocation(MethodInvocation node) => visitExpression(node);
   R visitNamedExpression(NamedExpression node) => visitExpression(node);
   R visitNamespaceDirective(NamespaceDirective node) => visitUriBasedDirective(node);
   R visitNode(ASTNode node) {
@@ -11023,6 +11537,7 @@
  * source range, given the AST structure built from the source. More specifically, they will return
  * the {@link ASTNode AST node} with the shortest length whose source range completely encompasses
  * the specified range.
+ * @coverage dart.engine.ast
  */
 class NodeLocator extends GeneralizingASTVisitor<Object> {
   /**
@@ -11044,10 +11559,10 @@
    * @param offset the offset used to identify the node
    */
   NodeLocator.con1(int offset) {
-    _jtd_constructor_114_impl(offset);
+    _jtd_constructor_118_impl(offset);
   }
-  _jtd_constructor_114_impl(int offset) {
-    _jtd_constructor_115_impl(offset, offset);
+  _jtd_constructor_118_impl(int offset) {
+    _jtd_constructor_119_impl(offset, offset);
   }
   /**
    * Initialize a newly created locator to locate one or more {@link ASTNode AST nodes} by locating
@@ -11057,9 +11572,9 @@
    * @param end the end offset of the range used to identify the node
    */
   NodeLocator.con2(int start, int end) {
-    _jtd_constructor_115_impl(start, end);
+    _jtd_constructor_119_impl(start, end);
   }
-  _jtd_constructor_115_impl(int start, int end) {
+  _jtd_constructor_119_impl(int start, int end) {
     this._startOffset = start;
     this._endOffset = end;
   }
@@ -11118,6 +11633,7 @@
  * Subclasses that override a visit method must either invoke the overridden visit method or must
  * explicitly ask the visited node to visit its children. Failure to do so will cause the children
  * of the visited node to not be visited.
+ * @coverage dart.engine.ast
  */
 class RecursiveASTVisitor<R> implements ASTVisitor<R> {
   R visitAdjacentStrings(AdjacentStrings node) {
@@ -11216,6 +11732,10 @@
     node.visitChildren(this);
     return null;
   }
+  R visitDeclaredIdentifier(DeclaredIdentifier node) {
+    node.visitChildren(this);
+    return null;
+  }
   R visitDefaultFormalParameter(DefaultFormalParameter node) {
     node.visitChildren(this);
     return null;
@@ -11518,6 +12038,7 @@
  * when visiting an AST node. It is intended to be a superclass for classes that use the visitor
  * pattern primarily as a dispatch mechanism (and hence don't need to recursively visit a whole
  * structure) and that only need to visit a small number of node types.
+ * @coverage dart.engine.ast
  */
 class SimpleASTVisitor<R> implements ASTVisitor<R> {
   R visitAdjacentStrings(AdjacentStrings node) => null;
@@ -11544,6 +12065,7 @@
   R visitConstructorFieldInitializer(ConstructorFieldInitializer node) => null;
   R visitConstructorName(ConstructorName node) => null;
   R visitContinueStatement(ContinueStatement node) => null;
+  R visitDeclaredIdentifier(DeclaredIdentifier node) => null;
   R visitDefaultFormalParameter(DefaultFormalParameter node) => null;
   R visitDoStatement(DoStatement node) => null;
   R visitDoubleLiteral(DoubleLiteral node) => null;
@@ -11622,6 +12144,7 @@
 /**
  * Instances of the class {@code ToSourceVisitor} write a source representation of a visited AST
  * node (and all of it's children) to a writer.
+ * @coverage dart.engine.ast
  */
 class ToSourceVisitor implements ASTVisitor<Object> {
   /**
@@ -11804,6 +12327,12 @@
     _writer.print(";");
     return null;
   }
+  Object visitDeclaredIdentifier(DeclaredIdentifier node) {
+    visit5(node.keyword, " ");
+    visit2(node.type, " ");
+    visit(node.identifier);
+    return null;
+  }
   Object visitDefaultFormalParameter(DefaultFormalParameter node) {
     visit(node.parameter);
     if (node.separator != null) {
@@ -11873,7 +12402,7 @@
   }
   Object visitForEachStatement(ForEachStatement node) {
     _writer.print("for (");
-    visit(node.loopParameter);
+    visit(node.loopVariable);
     _writer.print(" in ");
     visit(node.iterator);
     _writer.print(") ");
@@ -12453,7 +12982,9 @@
   }
   bool addAll(Collection<E> nodes) {
     if (nodes != null) {
-      super.addAll(nodes);
+      for (E node in nodes) {
+        add(node);
+      }
       return true;
     }
     return false;
diff --git a/pkg/analyzer_experimental/lib/src/generated/constant.dart b/pkg/analyzer_experimental/lib/src/generated/constant.dart
new file mode 100644
index 0000000..93ddccb
--- /dev/null
+++ b/pkg/analyzer_experimental/lib/src/generated/constant.dart
@@ -0,0 +1,1115 @@
+// This code was auto-generated, is not intended to be edited, and is subject to
+// significant change. Please see the README file for more information.
+
+library engine.constant;
+
+import 'java_core.dart';
+import 'source.dart' show Source;
+import 'error.dart' show AnalysisError, ErrorCode, CompileTimeErrorCode;
+import 'scanner.dart' show TokenType;
+import 'ast.dart';
+import 'element.dart';
+
+/**
+ * Instances of the class {@code ConstantEvaluator} evaluate constant expressions to produce their
+ * compile-time value. According to the Dart Language Specification: <blockquote> A constant
+ * expression is one of the following:
+ * <ul>
+ * <li>A literal number.</li>
+ * <li>A literal boolean.</li>
+ * <li>A literal string where any interpolated expression is a compile-time constant that evaluates
+ * to a numeric, string or boolean value or to {@code null}.</li>
+ * <li>{@code null}.</li>
+ * <li>A reference to a static constant variable.</li>
+ * <li>An identifier expression that denotes a constant variable, a class or a type variable.</li>
+ * <li>A constant constructor invocation.</li>
+ * <li>A constant list literal.</li>
+ * <li>A constant map literal.</li>
+ * <li>A simple or qualified identifier denoting a top-level function or a static method.</li>
+ * <li>A parenthesized expression {@code (e)} where {@code e} is a constant expression.</li>
+ * <li>An expression of one of the forms {@code identical(e1, e2)}, {@code e1 == e2},{@code e1 != e2} where {@code e1} and {@code e2} are constant expressions that evaluate to a
+ * numeric, string or boolean value or to {@code null}.</li>
+ * <li>An expression of one of the forms {@code !e}, {@code e1 && e2} or {@code e1 || e2}, where{@code e}, {@code e1} and {@code e2} are constant expressions that evaluate to a boolean value or
+ * to {@code null}.</li>
+ * <li>An expression of one of the forms {@code ~e}, {@code e1 ^ e2}, {@code e1 & e2},{@code e1 | e2}, {@code e1 >> e2} or {@code e1 << e2}, where {@code e}, {@code e1} and {@code e2}are constant expressions that evaluate to an integer value or to {@code null}.</li>
+ * <li>An expression of one of the forms {@code -e}, {@code e1 + e2}, {@code e1 - e2},{@code e1 * e2}, {@code e1 / e2}, {@code e1 ~/ e2}, {@code e1 > e2}, {@code e1 < e2},{@code e1 >= e2}, {@code e1 <= e2} or {@code e1 % e2}, where {@code e}, {@code e1} and {@code e2}are constant expressions that evaluate to a numeric value or to {@code null}.</li>
+ * </ul>
+ * </blockquote> The values returned by instances of this class are therefore {@code null} and
+ * instances of the classes {@code Boolean}, {@code BigInteger}, {@code Double}, {@code String}, and{@code DartObject}.
+ * <p>
+ * In addition, this class defines several values that can be returned to indicate various
+ * conditions encountered during evaluation. These are documented with the static field that define
+ * those values.
+ */
+class ConstantEvaluator {
+  /**
+   * The source containing the expression(s) that will be evaluated.
+   */
+  Source _source;
+  /**
+   * Initialize a newly created evaluator to evaluate expressions in the given source.
+   * @param source the source containing the expression(s) that will be evaluated
+   */
+  ConstantEvaluator(Source source) {
+    this._source = source;
+  }
+  EvaluationResult evaluate(Expression expression) {
+    EvaluationResultImpl result = expression.accept(new ConstantVisitor());
+    if (result is ValidResult) {
+      return EvaluationResult.forValue(((result as ValidResult)).value);
+    }
+    List<AnalysisError> errors = new List<AnalysisError>();
+    for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) {
+      ASTNode node2 = data.node;
+      errors.add(new AnalysisError.con2(_source, node2.offset, node2.length, data.errorCode, []));
+    }
+    return EvaluationResult.forErrors(new List.from(errors));
+  }
+}
+/**
+ * Instances of the class {@code EvaluationResult} represent the result of attempting to evaluate an
+ * expression.
+ */
+class EvaluationResult {
+  /**
+   * Return an evaluation result representing the result of evaluating an expression that is not a
+   * compile-time constant because of the given errors.
+   * @param errors the errors that should be reported for the expression(s) that were evaluated
+   * @return the result of evaluating an expression that is not a compile-time constant
+   */
+  static EvaluationResult forErrors(List<AnalysisError> errors) => new EvaluationResult(null, errors);
+  /**
+   * Return an evaluation result representing the result of evaluating an expression that is a
+   * compile-time constant that evaluates to the given value.
+   * @param value the value of the expression
+   * @return the result of evaluating an expression that is a compile-time constant
+   */
+  static EvaluationResult forValue(Object value) => new EvaluationResult(value, null);
+  /**
+   * The value of the expression.
+   */
+  Object _value;
+  /**
+   * The errors that should be reported for the expression(s) that were evaluated.
+   */
+  List<AnalysisError> _errors;
+  /**
+   * Initialize a newly created result object with the given state. Clients should use one of the
+   * factory methods: {@link #forErrors(AnalysisError[])} and {@link #forValue(Object)}.
+   * @param value the value of the expression
+   * @param errors the errors that should be reported for the expression(s) that were evaluated
+   */
+  EvaluationResult(Object value, List<AnalysisError> errors) {
+    this._value = value;
+    this._errors = errors;
+  }
+  /**
+   * Return an array containing the errors that should be reported for the expression(s) that were
+   * evaluated. If there are no such errors, the array will be empty. The array can be empty even if
+   * the expression is not a valid compile time constant if the errors would have been reported by
+   * other parts of the analysis engine.
+   */
+  List<AnalysisError> get errors => _errors == null ? AnalysisError.NO_ERRORS : _errors;
+  /**
+   * Return the value of the expression, or {@code null} if the expression evaluated to {@code null}or if the expression could not be evaluated, either because it was not a compile-time constant
+   * expression or because it would throw an exception when evaluated.
+   * @return the value of the expression
+   */
+  Object get value => _value;
+  /**
+   * Return {@code true} if the expression is a compile-time constant expression that would not
+   * throw an exception when evaluated.
+   * @return {@code true} if the expression is a valid compile-time constant expression
+   */
+  bool isValid() => _errors == null;
+}
+/**
+ * Instances of the class {@code ConstantVisitor} evaluate constant expressions to produce their
+ * compile-time value. According to the Dart Language Specification: <blockquote> A constant
+ * expression is one of the following:
+ * <ul>
+ * <li>A literal number.</li>
+ * <li>A literal boolean.</li>
+ * <li>A literal string where any interpolated expression is a compile-time constant that evaluates
+ * to a numeric, string or boolean value or to {@code null}.</li>
+ * <li>{@code null}.</li>
+ * <li>A reference to a static constant variable.</li>
+ * <li>An identifier expression that denotes a constant variable, a class or a type variable.</li>
+ * <li>A constant constructor invocation.</li>
+ * <li>A constant list literal.</li>
+ * <li>A constant map literal.</li>
+ * <li>A simple or qualified identifier denoting a top-level function or a static method.</li>
+ * <li>A parenthesized expression {@code (e)} where {@code e} is a constant expression.</li>
+ * <li>An expression of one of the forms {@code identical(e1, e2)}, {@code e1 == e2},{@code e1 != e2} where {@code e1} and {@code e2} are constant expressions that evaluate to a
+ * numeric, string or boolean value or to {@code null}.</li>
+ * <li>An expression of one of the forms {@code !e}, {@code e1 && e2} or {@code e1 || e2}, where{@code e}, {@code e1} and {@code e2} are constant expressions that evaluate to a boolean value or
+ * to {@code null}.</li>
+ * <li>An expression of one of the forms {@code ~e}, {@code e1 ^ e2}, {@code e1 & e2},{@code e1 | e2}, {@code e1 >> e2} or {@code e1 << e2}, where {@code e}, {@code e1} and {@code e2}are constant expressions that evaluate to an integer value or to {@code null}.</li>
+ * <li>An expression of one of the forms {@code -e}, {@code e1 + e2}, {@code e1 - e2},{@code e1 * e2}, {@code e1 / e2}, {@code e1 ~/ e2}, {@code e1 > e2}, {@code e1 < e2},{@code e1 >= e2}, {@code e1 <= e2} or {@code e1 % e2}, where {@code e}, {@code e1} and {@code e2}are constant expressions that evaluate to a numeric value or to {@code null}.</li>
+ * </ul>
+ * </blockquote>
+ */
+class ConstantVisitor extends GeneralizingASTVisitor<EvaluationResultImpl> {
+  /**
+   * Initialize a newly created constant visitor.
+   */
+  ConstantVisitor() : super() {
+  }
+  EvaluationResultImpl visitAdjacentStrings(AdjacentStrings node) {
+    EvaluationResultImpl result = null;
+    for (StringLiteral string in node.strings) {
+      if (result == null) {
+        result = string.accept(this);
+      } else {
+        result = result.concatenate(node, string.accept(this));
+      }
+    }
+    return result;
+  }
+  EvaluationResultImpl visitBinaryExpression(BinaryExpression node) {
+    EvaluationResultImpl leftResult = node.leftOperand.accept(this);
+    EvaluationResultImpl rightResult = node.rightOperand.accept(this);
+    while (true) {
+      if (node.operator.type == TokenType.AMPERSAND) {
+        return leftResult.bitAnd(node, rightResult);
+      } else if (node.operator.type == TokenType.AMPERSAND_AMPERSAND) {
+        return leftResult.logicalAnd(node, rightResult);
+      } else if (node.operator.type == TokenType.BANG_EQ) {
+        return leftResult.notEqual(node, rightResult);
+      } else if (node.operator.type == TokenType.BAR) {
+        return leftResult.bitOr(node, rightResult);
+      } else if (node.operator.type == TokenType.BAR_BAR) {
+        return leftResult.logicalOr(node, rightResult);
+      } else if (node.operator.type == TokenType.CARET) {
+        return leftResult.bitXor(node, rightResult);
+      } else if (node.operator.type == TokenType.EQ_EQ) {
+        return leftResult.equalEqual(node, rightResult);
+      } else if (node.operator.type == TokenType.GT) {
+        return leftResult.greaterThan(node, rightResult);
+      } else if (node.operator.type == TokenType.GT_EQ) {
+        return leftResult.greaterThanOrEqual(node, rightResult);
+      } else if (node.operator.type == TokenType.GT_GT) {
+        return leftResult.shiftRight(node, rightResult);
+      } else if (node.operator.type == TokenType.LT) {
+        return leftResult.lessThan(node, rightResult);
+      } else if (node.operator.type == TokenType.LT_EQ) {
+        return leftResult.lessThanOrEqual(node, rightResult);
+      } else if (node.operator.type == TokenType.LT_LT) {
+        return leftResult.shiftLeft(node, rightResult);
+      } else if (node.operator.type == TokenType.MINUS) {
+        return leftResult.minus(node, rightResult);
+      } else if (node.operator.type == TokenType.PERCENT) {
+        return leftResult.remainder(node, rightResult);
+      } else if (node.operator.type == TokenType.PLUS) {
+        return leftResult.add(node, rightResult);
+      } else if (node.operator.type == TokenType.STAR) {
+        return leftResult.times(node, rightResult);
+      } else if (node.operator.type == TokenType.SLASH) {
+        return leftResult.divide(node, rightResult);
+      } else if (node.operator.type == TokenType.TILDE_SLASH) {
+        return leftResult.integerDivide(node, rightResult);
+      }
+      break;
+    }
+    return error(node, null);
+  }
+  EvaluationResultImpl visitBooleanLiteral(BooleanLiteral node) => node.value ? ValidResult.RESULT_TRUE : ValidResult.RESULT_FALSE;
+  EvaluationResultImpl visitDoubleLiteral(DoubleLiteral node) => new ValidResult(node.value);
+  EvaluationResultImpl visitInstanceCreationExpression(InstanceCreationExpression node) {
+    ConstructorElement constructor = node.element;
+    if (constructor != null && constructor.isConst()) {
+      node.argumentList.accept(this);
+      return ValidResult.RESULT_OBJECT;
+    }
+    return error(node, null);
+  }
+  EvaluationResultImpl visitIntegerLiteral(IntegerLiteral node) => new ValidResult(node.value);
+  EvaluationResultImpl visitInterpolationExpression(InterpolationExpression node) {
+    EvaluationResultImpl result = node.expression.accept(this);
+    return result.performToString(node);
+  }
+  EvaluationResultImpl visitInterpolationString(InterpolationString node) => new ValidResult(node.value);
+  EvaluationResultImpl visitListLiteral(ListLiteral node) {
+    ErrorResult result = null;
+    for (Expression element in node.elements) {
+      result = union(result, element.accept(this));
+    }
+    if (result != null) {
+      return result;
+    }
+    return ValidResult.RESULT_OBJECT;
+  }
+  EvaluationResultImpl visitMapLiteral(MapLiteral node) {
+    ErrorResult result = null;
+    for (MapLiteralEntry entry in node.entries) {
+      result = union(result, entry.key.accept(this));
+      result = union(result, entry.value.accept(this));
+    }
+    if (result != null) {
+      return result;
+    }
+    return ValidResult.RESULT_OBJECT;
+  }
+  EvaluationResultImpl visitMethodInvocation(MethodInvocation node) {
+    Element element21 = node.methodName.element;
+    if (element21 is FunctionElement) {
+      FunctionElement function = element21 as FunctionElement;
+      if (function.name == "identical") {
+        NodeList<Expression> arguments3 = node.argumentList.arguments;
+        if (arguments3.length == 2) {
+          Element enclosingElement2 = function.enclosingElement;
+          if (enclosingElement2 is CompilationUnitElement) {
+            LibraryElement library20 = ((enclosingElement2 as CompilationUnitElement)).library;
+            if (library20.isDartCore()) {
+              EvaluationResultImpl leftArgument = arguments3[0].accept(this);
+              EvaluationResultImpl rightArgument = arguments3[1].accept(this);
+              return leftArgument.equalEqual(node, rightArgument);
+            }
+          }
+        }
+      }
+    }
+    return error(node, null);
+  }
+  EvaluationResultImpl visitNode(ASTNode node) => error(node, null);
+  EvaluationResultImpl visitNullLiteral(NullLiteral node) => new ValidResult(null);
+  EvaluationResultImpl visitParenthesizedExpression(ParenthesizedExpression node) => node.expression.accept(this);
+  EvaluationResultImpl visitPrefixedIdentifier(PrefixedIdentifier node) => getConstantValue(node, node.element);
+  EvaluationResultImpl visitPrefixExpression(PrefixExpression node) {
+    EvaluationResultImpl operand3 = node.operand.accept(this);
+    while (true) {
+      if (node.operator.type == TokenType.BANG) {
+        return operand3.logicalNot(node);
+      } else if (node.operator.type == TokenType.TILDE) {
+        return operand3.bitNot(node);
+      } else if (node.operator.type == TokenType.MINUS) {
+        return operand3.negated(node);
+      }
+      break;
+    }
+    return error(node, null);
+  }
+  EvaluationResultImpl visitPropertyAccess(PropertyAccess node) => getConstantValue(node, node.propertyName.element);
+  EvaluationResultImpl visitSimpleIdentifier(SimpleIdentifier node) => getConstantValue(node, node.element);
+  EvaluationResultImpl visitSimpleStringLiteral(SimpleStringLiteral node) => new ValidResult(node.value);
+  EvaluationResultImpl visitStringInterpolation(StringInterpolation node) {
+    EvaluationResultImpl result = null;
+    for (InterpolationElement element in node.elements) {
+      if (result == null) {
+        result = element.accept(this);
+      } else {
+        result = result.concatenate(node, element.accept(this));
+      }
+    }
+    return result;
+  }
+  /**
+   * Return a result object representing an error associated with the given node.
+   * @param node the AST node associated with the error
+   * @param code the error code indicating the nature of the error
+   * @return a result object representing an error associated with the given node
+   */
+  ErrorResult error(ASTNode node, ErrorCode code) => new ErrorResult.con1(node, code == null ? CompileTimeErrorCode.INVALID_CONSTANT : code);
+  /**
+   * Return the constant value of the static constant represented by the given element.
+   * @param node the node to be used if an error needs to be reported
+   * @param element the element whose value is to be returned
+   * @return the constant value of the static constant
+   */
+  EvaluationResultImpl getConstantValue(ASTNode node, Element element) {
+    if (element is PropertyAccessorElementImpl) {
+      element = ((element as PropertyAccessorElementImpl)).variable;
+    }
+    if (element is VariableElementImpl) {
+      EvaluationResultImpl value = ((element as VariableElementImpl)).evaluationResult;
+      if (value != null) {
+        return value;
+      }
+    }
+    return error(node, null);
+  }
+  /**
+   * Return the union of the errors encoded in the given results.
+   * @param leftResult the first set of errors, or {@code null} if there was no previous collection
+   * of errors
+   * @param rightResult the errors to be added to the collection, or a valid result if there are no
+   * errors to be added
+   * @return the union of the errors encoded in the given results
+   */
+  ErrorResult union(ErrorResult leftResult, EvaluationResultImpl rightResult) {
+    if (rightResult is ErrorResult) {
+      if (leftResult != null) {
+        return new ErrorResult.con2(leftResult, (rightResult as ErrorResult));
+      } else {
+        return rightResult as ErrorResult;
+      }
+    }
+    return leftResult;
+  }
+}
+/**
+ * Instances of the class {@code ErrorResult} represent the result of evaluating an expression that
+ * is not a valid compile time constant.
+ */
+class ErrorResult extends EvaluationResultImpl {
+  /**
+   * The errors that prevent the expression from being a valid compile time constant.
+   */
+  List<ErrorResult_ErrorData> _errors = new List<ErrorResult_ErrorData>();
+  /**
+   * Initialize a newly created result representing the error with the given code reported against
+   * the given node.
+   * @param node the node against which the error should be reported
+   * @param errorCode the error code for the error to be generated
+   */
+  ErrorResult.con1(ASTNode node, ErrorCode errorCode) {
+    _jtd_constructor_156_impl(node, errorCode);
+  }
+  _jtd_constructor_156_impl(ASTNode node, ErrorCode errorCode) {
+    _errors.add(new ErrorResult_ErrorData(node, errorCode));
+  }
+  /**
+   * Initialize a newly created result to represent the union of the errors in the given result
+   * objects.
+   * @param firstResult the first set of results being merged
+   * @param secondResult the second set of results being merged
+   */
+  ErrorResult.con2(ErrorResult firstResult, ErrorResult secondResult) {
+    _jtd_constructor_157_impl(firstResult, secondResult);
+  }
+  _jtd_constructor_157_impl(ErrorResult firstResult, ErrorResult secondResult) {
+    _errors.addAll(firstResult._errors);
+    _errors.addAll(secondResult._errors);
+  }
+  EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.addToError(node, this);
+  EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitAndError(node, this);
+  EvaluationResultImpl bitNot(Expression node) => this;
+  EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitOrError(node, this);
+  EvaluationResultImpl bitXor(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitXorError(node, this);
+  EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOperand) => rightOperand.concatenateError(node, this);
+  EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.divideError(node, this);
+  EvaluationResultImpl equalEqual(Expression node, EvaluationResultImpl rightOperand) => rightOperand.equalEqualError(node, this);
+  List<ErrorResult_ErrorData> get errorData => _errors;
+  List<AnalysisError> get errors => new List.from(_errors);
+  EvaluationResultImpl greaterThan(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanError(node, this);
+  EvaluationResultImpl greaterThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanOrEqualError(node, this);
+  EvaluationResultImpl integerDivide(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.integerDivideError(node, this);
+  EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl lessThan(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanError(node, this);
+  EvaluationResultImpl lessThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanOrEqualError(node, this);
+  EvaluationResultImpl logicalAnd(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalAndError(node, this);
+  EvaluationResultImpl logicalNot(Expression node) => this;
+  EvaluationResultImpl logicalOr(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalOrError(node, this);
+  EvaluationResultImpl minus(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.minusError(node, this);
+  EvaluationResultImpl negated(Expression node) => this;
+  EvaluationResultImpl notEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.notEqualError(node, this);
+  EvaluationResultImpl performToString(ASTNode node) => this;
+  EvaluationResultImpl remainder(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.remainderError(node, this);
+  EvaluationResultImpl shiftLeft(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftLeftError(node, this);
+  EvaluationResultImpl shiftRight(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftRightError(node, this);
+  EvaluationResultImpl times(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.timesError(node, this);
+  EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
+  EvaluationResultImpl addToValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
+  EvaluationResultImpl bitAndValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
+  EvaluationResultImpl bitOrValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
+  EvaluationResultImpl bitXorValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
+  EvaluationResultImpl concatenateValid(Expression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
+  EvaluationResultImpl divideValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
+  EvaluationResultImpl equalEqualValid(Expression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
+  EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
+  EvaluationResultImpl greaterThanOrEqualValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl greaterThanValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
+  EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
+  EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
+  EvaluationResultImpl lessThanOrEqualValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl lessThanValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
+  EvaluationResultImpl logicalAndValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
+  EvaluationResultImpl logicalOrValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
+  EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
+  EvaluationResultImpl notEqualValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
+  EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
+  EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
+  EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
+  EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand) => this;
+}
+class ErrorResult_ErrorData {
+  /**
+   * The node against which the error should be reported.
+   */
+  ASTNode _node;
+  /**
+   * The error code for the error to be generated.
+   */
+  ErrorCode _errorCode;
+  /**
+   * Initialize a newly created data holder to represent the error with the given code reported
+   * against the given node.
+   * @param node the node against which the error should be reported
+   * @param errorCode the error code for the error to be generated
+   */
+  ErrorResult_ErrorData(ASTNode node, ErrorCode errorCode) {
+    this._node = node;
+    this._errorCode = errorCode;
+  }
+  /**
+   * Return the error code for the error to be generated.
+   * @return the error code for the error to be generated
+   */
+  ErrorCode get errorCode => _errorCode;
+  /**
+   * Return the node against which the error should be reported.
+   * @return the node against which the error should be reported
+   */
+  ASTNode get node => _node;
+}
+/**
+ * Instances of the class {@code InternalResult} represent the result of attempting to evaluate a
+ * expression.
+ */
+abstract class EvaluationResultImpl {
+  EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl bitNot(Expression node);
+  EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl bitXor(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl equalEqual(Expression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl greaterThan(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl greaterThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl integerDivide(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl lessThan(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl lessThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl logicalAnd(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl logicalNot(Expression node);
+  EvaluationResultImpl logicalOr(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl minus(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl negated(Expression node);
+  EvaluationResultImpl notEqual(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl performToString(ASTNode node);
+  EvaluationResultImpl remainder(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl shiftLeft(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl shiftRight(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl times(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand);
+  EvaluationResultImpl addToValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperand);
+  EvaluationResultImpl bitAndValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand);
+  EvaluationResultImpl bitOrValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperand);
+  EvaluationResultImpl bitXorValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand);
+  EvaluationResultImpl concatenateValid(Expression node, ValidResult leftOperand);
+  EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperand);
+  EvaluationResultImpl divideValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand);
+  EvaluationResultImpl equalEqualValid(Expression node, ValidResult leftOperand);
+  EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftOperand);
+  EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResult leftOperand);
+  EvaluationResultImpl greaterThanOrEqualValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl greaterThanValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult leftOperand);
+  EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOperand);
+  EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult leftOperand);
+  EvaluationResultImpl lessThanOrEqualValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl lessThanValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOperand);
+  EvaluationResultImpl logicalAndValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOperand);
+  EvaluationResultImpl logicalOrValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand);
+  EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOperand);
+  EvaluationResultImpl notEqualValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOperand);
+  EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOperand);
+  EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOperand);
+  EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand);
+  EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand);
+}
+/**
+ * Instances of the class {@code ValidResult} represent the result of attempting to evaluate a valid
+ * compile time constant expression.
+ */
+class ValidResult extends EvaluationResultImpl {
+  /**
+   * A result object representing the value 'false'.
+   */
+  static ValidResult RESULT_FALSE = new ValidResult(false);
+  /**
+   * A result object representing the an arbitrary object on which no further operations can be
+   * performed.
+   */
+  static ValidResult RESULT_OBJECT = new ValidResult(new Object());
+  /**
+   * A result object representing the value 'true'.
+   */
+  static ValidResult RESULT_TRUE = new ValidResult(true);
+  /**
+   * The value of the expression.
+   */
+  Object _value;
+  /**
+   * Initialize a newly created result to represent the given value.
+   * @param value the value of the expression
+   */
+  ValidResult(Object value) {
+    this._value = value;
+  }
+  EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.addToValid(node, this);
+  EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitAndValid(node, this);
+  EvaluationResultImpl bitNot(Expression node) {
+    if (_value == null) {
+      return error(node);
+    } else if (_value is int) {
+      return valueOf(~((_value as int)));
+    }
+    return error(node);
+  }
+  EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitOrValid(node, this);
+  EvaluationResultImpl bitXor(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitXorValid(node, this);
+  EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOperand) => rightOperand.concatenateValid(node, this);
+  EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.divideValid(node, this);
+  EvaluationResultImpl equalEqual(Expression node, EvaluationResultImpl rightOperand) => rightOperand.equalEqualValid(node, this);
+  Object get value => _value;
+  EvaluationResultImpl greaterThan(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanValid(node, this);
+  EvaluationResultImpl greaterThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanOrEqualValid(node, this);
+  EvaluationResultImpl integerDivide(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.integerDivideValid(node, this);
+  EvaluationResultImpl lessThan(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanValid(node, this);
+  EvaluationResultImpl lessThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanOrEqualValid(node, this);
+  EvaluationResultImpl logicalAnd(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalAndValid(node, this);
+  EvaluationResultImpl logicalNot(Expression node) {
+    if (_value == null) {
+      return RESULT_TRUE;
+    } else if (_value is bool) {
+      return ((_value as bool)) ? RESULT_FALSE : RESULT_TRUE;
+    }
+    return error(node);
+  }
+  EvaluationResultImpl logicalOr(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalOrValid(node, this);
+  EvaluationResultImpl minus(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.minusValid(node, this);
+  EvaluationResultImpl negated(Expression node) {
+    if (_value == null) {
+      return error(node);
+    } else if (_value is int) {
+      return valueOf(-((_value as int)));
+    } else if (_value is double) {
+      return valueOf3(-((_value as double)));
+    }
+    return error(node);
+  }
+  EvaluationResultImpl notEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.notEqualValid(node, this);
+  EvaluationResultImpl performToString(ASTNode node) {
+    if (_value == null) {
+      return valueOf4("null");
+    } else if (_value is bool) {
+      return valueOf4(((_value as bool)).toString());
+    } else if (_value is int) {
+      return valueOf4(((_value as int)).toString());
+    } else if (_value is double) {
+      return valueOf4(((_value as double)).toString());
+    } else if (_value is String) {
+      return this;
+    }
+    return error(node);
+  }
+  EvaluationResultImpl remainder(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.remainderValid(node, this);
+  EvaluationResultImpl shiftLeft(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftLeftValid(node, this);
+  EvaluationResultImpl shiftRight(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftRightValid(node, this);
+  EvaluationResultImpl times(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.timesValid(node, this);
+  String toString() {
+    if (_value == null) {
+      return "null";
+    }
+    return _value.toString();
+  }
+  EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
+  EvaluationResultImpl addToValid(BinaryExpression node, ValidResult leftOperand3) {
+    Object leftValue = leftOperand3.value;
+    if (leftValue == null) {
+      return error(node.leftOperand);
+    } else if (_value == null) {
+      return error(node.rightOperand);
+    } else if (leftValue is int) {
+      if (_value is int) {
+        return valueOf(((leftValue as int)) + (_value as int));
+      } else if (_value is double) {
+        return valueOf3(((leftValue as int)).toDouble() + ((_value as double)));
+      }
+    } else if (leftValue is double) {
+      if (_value is int) {
+        return valueOf3(((leftValue as double)) + ((_value as int)).toDouble());
+      } else if (_value is double) {
+        return valueOf3(((leftValue as double)) + ((_value as double)));
+      }
+    } else if (leftValue is String) {
+      if (_value is String) {
+        return valueOf4("${((leftValue as String))}${((_value as String))}");
+      }
+    }
+    return error(node);
+  }
+  EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
+  EvaluationResultImpl bitAndValid(BinaryExpression node, ValidResult leftOperand4) {
+    Object leftValue = leftOperand4.value;
+    if (leftValue == null) {
+      return error(node.leftOperand);
+    } else if (_value == null) {
+      return error(node.rightOperand);
+    } else if (leftValue is int) {
+      if (_value is int) {
+        return valueOf(((leftValue as int)) & (_value as int));
+      }
+      return error(node.leftOperand);
+    }
+    if (_value is int) {
+      return error(node.rightOperand);
+    }
+    return union(error(node.leftOperand), error(node.rightOperand));
+  }
+  EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
+  EvaluationResultImpl bitOrValid(BinaryExpression node, ValidResult leftOperand5) {
+    Object leftValue = leftOperand5.value;
+    if (leftValue == null) {
+      return error(node.leftOperand);
+    } else if (_value == null) {
+      return error(node.rightOperand);
+    } else if (leftValue is int) {
+      if (_value is int) {
+        return valueOf(((leftValue as int)) | (_value as int));
+      }
+      return error(node.leftOperand);
+    }
+    if (_value is int) {
+      return error(node.rightOperand);
+    }
+    return union(error(node.leftOperand), error(node.rightOperand));
+  }
+  EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
+  EvaluationResultImpl bitXorValid(BinaryExpression node, ValidResult leftOperand6) {
+    Object leftValue = leftOperand6.value;
+    if (leftValue == null) {
+      return error(node.leftOperand);
+    } else if (_value == null) {
+      return error(node.rightOperand);
+    } else if (leftValue is int) {
+      if (_value is int) {
+        return valueOf(((leftValue as int)) ^ (_value as int));
+      }
+      return error(node.leftOperand);
+    }
+    if (_value is int) {
+      return error(node.rightOperand);
+    }
+    return union(error(node.leftOperand), error(node.rightOperand));
+  }
+  EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand) => leftOperand;
+  EvaluationResultImpl concatenateValid(Expression node, ValidResult leftOperand) {
+    Object leftValue = leftOperand.value;
+    if (leftValue is String && _value is String) {
+      return valueOf4("${((leftValue as String))}${((_value as String))}");
+    }
+    return error(node);
+  }
+  EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
+  EvaluationResultImpl divideValid(BinaryExpression node, ValidResult leftOperand7) {
+    Object leftValue = leftOperand7.value;
+    if (leftValue == null) {
+      return error(node.leftOperand);
+    } else if (_value == null) {
+      return error(node.rightOperand);
+    } else if (leftValue is int) {
+      if (_value is int) {
+        if (((_value as int)) == 0) {
+          return error2(node.rightOperand, CompileTimeErrorCode.COMPILE_TIME_CONSTANT_RAISES_EXCEPTION_DIVIDE_BY_ZERO);
+        }
+        return valueOf(((leftValue as int)) ~/ (_value as int));
+      } else if (_value is double) {
+        return valueOf3(((leftValue as int)).toDouble() / ((_value as double)));
+      }
+    } else if (leftValue is double) {
+      if (_value is int) {
+        return valueOf3(((leftValue as double)) / ((_value as int)).toDouble());
+      } else if (_value is double) {
+        return valueOf3(((leftValue as double)) / ((_value as double)));
+      }
+    }
+    return error(node);
+  }
+  EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand) => leftOperand;
+  EvaluationResultImpl equalEqualValid(Expression node, ValidResult leftOperand) {
+    Object leftValue = leftOperand.value;
+    if (leftValue == null) {
+      return valueOf2(_value == null);
+    } else if (leftValue is bool) {
+      if (_value is bool) {
+        return valueOf2(identical(((leftValue as bool)), ((_value as bool))));
+      }
+      return RESULT_FALSE;
+    } else if (leftValue is int) {
+      if (_value is int) {
+        return valueOf2(((leftValue as int)) == _value);
+      } else if (_value is double) {
+        return valueOf2(toDouble((leftValue as int)) == _value);
+      }
+      return RESULT_FALSE;
+    } else if (leftValue is double) {
+      if (_value is int) {
+        return valueOf2(((leftValue as double)) == toDouble((_value as int)));
+      } else if (_value is double) {
+        return valueOf2(((leftValue as double)) == _value);
+      }
+      return RESULT_FALSE;
+    } else if (leftValue is String) {
+      if (_value is String) {
+        return valueOf2(((leftValue as String)) == _value);
+      }
+      return RESULT_FALSE;
+    }
+    return RESULT_FALSE;
+  }
+  EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
+  EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
+  EvaluationResultImpl greaterThanOrEqualValid(BinaryExpression node, ValidResult leftOperand8) {
+    Object leftValue = leftOperand8.value;
+    if (leftValue == null) {
+      return error(node.leftOperand);
+    } else if (_value == null) {
+      return error(node.rightOperand);
+    } else if (leftValue is int) {
+      if (_value is int) {
+        return valueOf2(((leftValue as int)).compareTo((_value as int)) >= 0);
+      } else if (_value is double) {
+        return valueOf2(((leftValue as int)).toDouble() >= ((_value as double)));
+      }
+    } else if (leftValue is double) {
+      if (_value is int) {
+        return valueOf2(((leftValue as double)) >= ((_value as int)).toDouble());
+      } else if (_value is double) {
+        return valueOf2(((leftValue as double)) >= ((_value as double)));
+      }
+    }
+    return error(node);
+  }
+  EvaluationResultImpl greaterThanValid(BinaryExpression node, ValidResult leftOperand9) {
+    Object leftValue = leftOperand9.value;
+    if (leftValue == null) {
+      return error(node.leftOperand);
+    } else if (_value == null) {
+      return error(node.rightOperand);
+    } else if (leftValue is int) {
+      if (_value is int) {
+        return valueOf2(((leftValue as int)).compareTo((_value as int)) > 0);
+      } else if (_value is double) {
+        return valueOf2(((leftValue as int)).toDouble() > ((_value as double)));
+      }
+    } else if (leftValue is double) {
+      if (_value is int) {
+        return valueOf2(((leftValue as double)) > ((_value as int)).toDouble());
+      } else if (_value is double) {
+        return valueOf2(((leftValue as double)) > ((_value as double)));
+      }
+    }
+    return error(node);
+  }
+  EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
+  EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult leftOperand10) {
+    Object leftValue = leftOperand10.value;
+    if (leftValue == null) {
+      return error(node.leftOperand);
+    } else if (_value == null) {
+      return error(node.rightOperand);
+    } else if (leftValue is int) {
+      if (_value is int) {
+        if (((_value as int)) == 0) {
+          return error2(node.rightOperand, CompileTimeErrorCode.COMPILE_TIME_CONSTANT_RAISES_EXCEPTION_DIVIDE_BY_ZERO);
+        }
+        return valueOf(((leftValue as int)) ~/ (_value as int));
+      } else if (_value is double) {
+        double result = ((leftValue as int)).toDouble() / ((_value as double));
+        return valueOf((result as int));
+      }
+    } else if (leftValue is double) {
+      if (_value is int) {
+        double result = ((leftValue as double)) / ((_value as int)).toDouble();
+        return valueOf((result as int));
+      } else if (_value is double) {
+        double result = ((leftValue as double)) / ((_value as double));
+        return valueOf((result as int));
+      }
+    }
+    return error(node);
+  }
+  EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
+  EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
+  EvaluationResultImpl lessThanOrEqualValid(BinaryExpression node, ValidResult leftOperand11) {
+    Object leftValue = leftOperand11.value;
+    if (leftValue == null) {
+      return error(node.leftOperand);
+    } else if (_value == null) {
+      return error(node.rightOperand);
+    } else if (leftValue is int) {
+      if (_value is int) {
+        return valueOf2(((leftValue as int)).compareTo((_value as int)) <= 0);
+      } else if (_value is double) {
+        return valueOf2(((leftValue as int)).toDouble() <= ((_value as double)));
+      }
+    } else if (leftValue is double) {
+      if (_value is int) {
+        return valueOf2(((leftValue as double)) <= ((_value as int)).toDouble());
+      } else if (_value is double) {
+        return valueOf2(((leftValue as double)) <= ((_value as double)));
+      }
+    }
+    return error(node);
+  }
+  EvaluationResultImpl lessThanValid(BinaryExpression node, ValidResult leftOperand12) {
+    Object leftValue = leftOperand12.value;
+    if (leftValue == null) {
+      return error(node.leftOperand);
+    } else if (_value == null) {
+      return error(node.rightOperand);
+    } else if (leftValue is int) {
+      if (_value is int) {
+        return valueOf2(((leftValue as int)).compareTo((_value as int)) < 0);
+      } else if (_value is double) {
+        return valueOf2(((leftValue as int)).toDouble() < ((_value as double)));
+      }
+    } else if (leftValue is double) {
+      if (_value is int) {
+        return valueOf2(((leftValue as double)) < ((_value as int)).toDouble());
+      } else if (_value is double) {
+        return valueOf2(((leftValue as double)) < ((_value as double)));
+      }
+    }
+    return error(node);
+  }
+  EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
+  EvaluationResultImpl logicalAndValid(BinaryExpression node, ValidResult leftOperand) {
+    Object leftValue = leftOperand.value;
+    if (leftValue is bool && ((leftValue as bool))) {
+      return booleanConversion(node.rightOperand, _value);
+    }
+    return RESULT_FALSE;
+  }
+  EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
+  EvaluationResultImpl logicalOrValid(BinaryExpression node, ValidResult leftOperand) {
+    Object leftValue = leftOperand.value;
+    if (leftValue is bool && ((leftValue as bool))) {
+      return RESULT_TRUE;
+    }
+    return booleanConversion(node.rightOperand, _value);
+  }
+  EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
+  EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand13) {
+    Object leftValue = leftOperand13.value;
+    if (leftValue == null) {
+      return error(node.leftOperand);
+    } else if (_value == null) {
+      return error(node.rightOperand);
+    } else if (leftValue is int) {
+      if (_value is int) {
+        return valueOf(((leftValue as int)) - (_value as int));
+      } else if (_value is double) {
+        return valueOf3(((leftValue as int)).toDouble() - ((_value as double)));
+      }
+    } else if (leftValue is double) {
+      if (_value is int) {
+        return valueOf3(((leftValue as double)) - ((_value as int)).toDouble());
+      } else if (_value is double) {
+        return valueOf3(((leftValue as double)) - ((_value as double)));
+      }
+    }
+    return error(node);
+  }
+  EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
+  EvaluationResultImpl notEqualValid(BinaryExpression node, ValidResult leftOperand) {
+    Object leftValue = leftOperand.value;
+    if (leftValue == null) {
+      return valueOf2(_value != null);
+    } else if (leftValue is bool) {
+      if (_value is bool) {
+        return valueOf2(((leftValue as bool)) != ((_value as bool)));
+      }
+      return RESULT_TRUE;
+    } else if (leftValue is int) {
+      if (_value is int) {
+        return valueOf2(((leftValue as int)) != _value);
+      } else if (_value is double) {
+        return valueOf2(toDouble((leftValue as int)) != _value);
+      }
+      return RESULT_TRUE;
+    } else if (leftValue is double) {
+      if (_value is int) {
+        return valueOf2(((leftValue as double)) != toDouble((_value as int)));
+      } else if (_value is double) {
+        return valueOf2(((leftValue as double)) != _value);
+      }
+      return RESULT_TRUE;
+    } else if (leftValue is String) {
+      if (_value is String) {
+        return valueOf2(((leftValue as String)) != _value);
+      }
+      return RESULT_TRUE;
+    }
+    return RESULT_TRUE;
+  }
+  EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
+  EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOperand14) {
+    Object leftValue = leftOperand14.value;
+    if (leftValue == null) {
+      return error(node.leftOperand);
+    } else if (_value == null) {
+      return error(node.rightOperand);
+    } else if (leftValue is int) {
+      if (((_value as int)) == 0) {
+        return error2(node.rightOperand, CompileTimeErrorCode.COMPILE_TIME_CONSTANT_RAISES_EXCEPTION_DIVIDE_BY_ZERO);
+      }
+      if (_value is int) {
+        return valueOf(((leftValue as int)).remainder((_value as int)));
+      } else if (_value is double) {
+        return valueOf3(((leftValue as int)).toDouble() % ((_value as double)));
+      }
+    } else if (leftValue is double) {
+      if (_value is int) {
+        return valueOf3(((leftValue as double)) % ((_value as int)).toDouble());
+      } else if (_value is double) {
+        return valueOf3(((leftValue as double)) % ((_value as double)));
+      }
+    }
+    return error(node);
+  }
+  EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
+  EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOperand15) {
+    Object leftValue = leftOperand15.value;
+    if (leftValue == null) {
+      return error(node.leftOperand);
+    } else if (_value == null) {
+      return error(node.rightOperand);
+    } else if (leftValue is int) {
+      if (_value is int) {
+        return valueOf(((leftValue as int)) << ((_value as int)));
+      }
+      return error(node.rightOperand);
+    }
+    if (_value is int) {
+      return error(node.leftOperand);
+    }
+    return union(error(node.leftOperand), error(node.rightOperand));
+  }
+  EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
+  EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOperand16) {
+    Object leftValue = leftOperand16.value;
+    if (leftValue == null) {
+      return error(node.leftOperand);
+    } else if (_value == null) {
+      return error(node.rightOperand);
+    } else if (leftValue is int) {
+      if (_value is int) {
+        return valueOf(((leftValue as int)) >> ((_value as int)));
+      }
+      return error(node.rightOperand);
+    }
+    if (_value is int) {
+      return error(node.leftOperand);
+    }
+    return union(error(node.leftOperand), error(node.rightOperand));
+  }
+  EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
+  EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand17) {
+    Object leftValue = leftOperand17.value;
+    if (leftValue == null) {
+      return error(node.leftOperand);
+    } else if (_value == null) {
+      return error(node.rightOperand);
+    } else if (leftValue is int) {
+      if (_value is int) {
+        return valueOf(((leftValue as int)) * (_value as int));
+      } else if (_value is double) {
+        return valueOf3(((leftValue as int)).toDouble() * ((_value as double)));
+      }
+    } else if (leftValue is double) {
+      if (_value is int) {
+        return valueOf3(((leftValue as double)) * ((_value as int)).toDouble());
+      } else if (_value is double) {
+        return valueOf3(((leftValue as double)) * ((_value as double)));
+      }
+    }
+    return error(node);
+  }
+  /**
+   * Return the result of applying boolean conversion to the given value.
+   * @param node the node against which errors should be reported
+   * @param value the value to be converted to a boolean
+   * @return the result of applying boolean conversion to the given value
+   */
+  EvaluationResultImpl booleanConversion(ASTNode node, Object value) {
+    if (value == null) {
+      return error(node);
+    } else if (value is bool && ((value as bool))) {
+      return RESULT_TRUE;
+    }
+    return RESULT_FALSE;
+  }
+  ErrorResult error(ASTNode node) => error2(node, CompileTimeErrorCode.INVALID_CONSTANT);
+  /**
+   * Return a result object representing an error associated with the given node.
+   * @param node the AST node associated with the error
+   * @param code the error code indicating the nature of the error
+   * @return a result object representing an error associated with the given node
+   */
+  ErrorResult error2(ASTNode node, ErrorCode code) => new ErrorResult.con1(node, code);
+  double toDouble(int value) => value.toDouble();
+  /**
+   * Return an error result that is the union of the two given error results.
+   * @param firstError the first error to be combined
+   * @param secondError the second error to be combined
+   * @return an error result that is the union of the two given error results
+   */
+  ErrorResult union(ErrorResult firstError, ErrorResult secondError) => new ErrorResult.con2(firstError, secondError);
+  /**
+   * Return a result object representing the given value.
+   * @param value the value to be represented as a result object
+   * @return a result object representing the given value
+   */
+  ValidResult valueOf(int value) => new ValidResult(value);
+  /**
+   * Return a result object representing the given value.
+   * @param value the value to be represented as a result object
+   * @return a result object representing the given value
+   */
+  ValidResult valueOf2(bool value) => value ? RESULT_TRUE : RESULT_FALSE;
+  /**
+   * Return a result object representing the given value.
+   * @param value the value to be represented as a result object
+   * @return a result object representing the given value
+   */
+  ValidResult valueOf3(double value) => new ValidResult(value);
+  /**
+   * Return a result object representing the given value.
+   * @param value the value to be represented as a result object
+   * @return a result object representing the given value
+   */
+  ValidResult valueOf4(String value) => new ValidResult(value);
+}
\ No newline at end of file
diff --git a/pkg/analyzer-experimental/lib/src/generated/element.dart b/pkg/analyzer_experimental/lib/src/generated/element.dart
similarity index 69%
rename from pkg/analyzer-experimental/lib/src/generated/element.dart
rename to pkg/analyzer_experimental/lib/src/generated/element.dart
index 9be35da..601a3e1 100644
--- a/pkg/analyzer-experimental/lib/src/generated/element.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/element.dart
@@ -8,13 +8,16 @@
 import 'java_engine.dart';
 import 'source.dart';
 import 'scanner.dart' show Keyword;
-import 'ast.dart';
+import 'ast.dart' show Identifier, LibraryIdentifier;
+import 'html.dart' show XmlTagNode;
 import 'engine.dart' show AnalysisContext;
+import 'constant.dart' show EvaluationResultImpl;
 import 'utilities_dart.dart';
 
 /**
  * The interface {@code Annotation} defines the behavior of objects representing a single annotation
  * associated with an element.
+ * @coverage dart.engine.element
  */
 abstract class Annotation {
   /**
@@ -26,6 +29,7 @@
 }
 /**
  * The interface {@code ClassElement} defines the behavior of elements that represent a class.
+ * @coverage dart.engine.element
  */
 abstract class ClassElement implements Element {
   /**
@@ -103,10 +107,25 @@
    */
   bool isAbstract();
   /**
+   * Return {@code true} if this class is defined by a typedef construct.
+   * @return {@code true} if this class is defined by a typedef construct
+   */
+  bool isTypedef();
+  /**
+   * Return {@code true} if this class can validly be used as a mixin when defining another class.
+   * The behavior of this method is defined by the Dart Language Specification in section 9:
+   * <blockquote>It is a compile-time error if a declared or derived mixin refers to super. It is a
+   * compile-time error if a declared or derived mixin explicitly declares a constructor. It is a
+   * compile-time error if a mixin is derived from a class whose superclass is not
+   * Object.</blockquote>
+   * @return {@code true} if this class can validly be used as a mixin
+   */
+  bool isValidMixin();
+  /**
    * Return the element representing the getter that results from looking up the given getter in
    * this class with respect to the given library, or {@code null} if the look up fails. The
    * behavior of this method is defined by the Dart Language Specification in section 12.15.1:
-   * <blockquote> The result of looking up getter (respectively setter) <i>m</i> in class <i>C</i>
+   * <blockquote>The result of looking up getter (respectively setter) <i>m</i> in class <i>C</i>
    * with respect to library <i>L</i> is:
    * <ul>
    * <li>If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is
@@ -165,6 +184,7 @@
 /**
  * The interface {@code CompilationUnitElement} defines the behavior of elements representing a
  * compilation unit.
+ * @coverage dart.engine.element
  */
 abstract class CompilationUnitElement implements Element {
   /**
@@ -184,24 +204,25 @@
    */
   List<FunctionElement> get functions;
   /**
-   * Return an array containing all of the type aliases contained in this compilation unit.
-   * @return the type aliases contained in this compilation unit
+   * Return an array containing all of the top-level variables contained in this compilation unit.
+   * @return the top-level variables contained in this compilation unit
    */
-  List<TypeAliasElement> get typeAliases;
+  List<TopLevelVariableElement> get topLevelVariables;
+  /**
+   * Return an array containing all of the function type aliases contained in this compilation unit.
+   * @return the function type aliases contained in this compilation unit
+   */
+  List<FunctionTypeAliasElement> get functionTypeAliases;
   /**
    * Return an array containing all of the classes contained in this compilation unit.
    * @return the classes contained in this compilation unit
    */
   List<ClassElement> get types;
-  /**
-   * Return an array containing all of the variables contained in this compilation unit.
-   * @return the variables contained in this compilation unit
-   */
-  List<VariableElement> get variables;
 }
 /**
  * The interface {@code ConstructorElement} defines the behavior of elements representing a
  * constructor or a factory method defined within a type.
+ * @coverage dart.engine.element
  */
 abstract class ConstructorElement implements ExecutableElement {
   /**
@@ -239,9 +260,21 @@
  * Second, there are elements in the element model that do not have a name. These correspond to
  * unnamed functions and exist in order to more accurately represent the semantic structure of the
  * program.
+ * @coverage dart.engine.element
  */
 abstract class Element {
   /**
+   * A comparator that can be used to sort elements by their name offset. Elements with a smaller
+   * offset will be sorted to be before elements with a larger name offset.
+   */
+  static Comparator<Element> SORT_BY_OFFSET = (Element firstElement, Element secondElement) => firstElement.nameOffset - secondElement.nameOffset;
+  /**
+   * Use the given visitor to visit this element.
+   * @param visitor the visitor that will visit this element
+   * @return the value returned by the visitor as a result of visiting this element
+   */
+  accept(ElementVisitor visitor);
+  /**
    * Return the element of the given class that most immediately encloses this element, or{@code null} if there is no enclosing element of the given class.
    * @param elementClass the class of the element to be returned
    * @return the element that encloses this element
@@ -314,43 +347,61 @@
    * @return {@code true} if this element is synthetic
    */
   bool isSynthetic();
+  /**
+   * Use the given visitor to visit all of the children of this element. There is no guarantee of
+   * the order in which the children will be visited.
+   * @param visitor the visitor that will be used to visit the children of this element
+   */
+  void visitChildren(ElementVisitor<Object> visitor);
 }
 /**
  * The enumeration {@code ElementKind} defines the various kinds of elements in the element model.
+ * @coverage dart.engine.element
  */
 class ElementKind {
-  static final ElementKind CLASS = new ElementKind('CLASS', 0);
-  static final ElementKind COMPILATION_UNIT = new ElementKind('COMPILATION_UNIT', 1);
-  static final ElementKind CONSTRUCTOR = new ElementKind('CONSTRUCTOR', 2);
-  static final ElementKind DYNAMIC = new ElementKind('DYNAMIC', 3);
-  static final ElementKind ERROR = new ElementKind('ERROR', 4);
-  static final ElementKind EXPORT = new ElementKind('EXPORT', 5);
-  static final ElementKind FIELD = new ElementKind('FIELD', 6);
-  static final ElementKind FUNCTION = new ElementKind('FUNCTION', 7);
-  static final ElementKind GETTER = new ElementKind('GETTER', 8);
-  static final ElementKind HTML = new ElementKind('HTML', 9);
-  static final ElementKind IMPORT = new ElementKind('IMPORT', 10);
-  static final ElementKind LABEL = new ElementKind('LABEL', 11);
-  static final ElementKind LIBRARY = new ElementKind('LIBRARY', 12);
-  static final ElementKind METHOD = new ElementKind('METHOD', 13);
-  static final ElementKind NAME = new ElementKind('NAME', 14);
-  static final ElementKind PARAMETER = new ElementKind('PARAMETER', 15);
-  static final ElementKind PREFIX = new ElementKind('PREFIX', 16);
-  static final ElementKind SETTER = new ElementKind('SETTER', 17);
-  static final ElementKind TYPE_ALIAS = new ElementKind('TYPE_ALIAS', 18);
-  static final ElementKind TYPE_VARIABLE = new ElementKind('TYPE_VARIABLE', 19);
-  static final ElementKind UNIVERSE = new ElementKind('UNIVERSE', 20);
-  static final ElementKind VARIABLE = new ElementKind('VARIABLE', 21);
-  static final List<ElementKind> values = [CLASS, COMPILATION_UNIT, CONSTRUCTOR, DYNAMIC, ERROR, EXPORT, FIELD, FUNCTION, GETTER, HTML, IMPORT, LABEL, LIBRARY, METHOD, NAME, PARAMETER, PREFIX, SETTER, TYPE_ALIAS, TYPE_VARIABLE, UNIVERSE, VARIABLE];
+  static final ElementKind CLASS = new ElementKind('CLASS', 0, "class");
+  static final ElementKind COMPILATION_UNIT = new ElementKind('COMPILATION_UNIT', 1, "compilation unit");
+  static final ElementKind CONSTRUCTOR = new ElementKind('CONSTRUCTOR', 2, "constructor");
+  static final ElementKind DYNAMIC = new ElementKind('DYNAMIC', 3, "<dynamic>");
+  static final ElementKind EMBEDDED_HTML_SCRIPT = new ElementKind('EMBEDDED_HTML_SCRIPT', 4, "embedded html script");
+  static final ElementKind ERROR = new ElementKind('ERROR', 5, "<error>");
+  static final ElementKind EXPORT = new ElementKind('EXPORT', 6, "export directive");
+  static final ElementKind EXTERNAL_HTML_SCRIPT = new ElementKind('EXTERNAL_HTML_SCRIPT', 7, "external html script");
+  static final ElementKind FIELD = new ElementKind('FIELD', 8, "field");
+  static final ElementKind FUNCTION = new ElementKind('FUNCTION', 9, "function");
+  static final ElementKind GETTER = new ElementKind('GETTER', 10, "getter");
+  static final ElementKind HTML = new ElementKind('HTML', 11, "html");
+  static final ElementKind IMPORT = new ElementKind('IMPORT', 12, "import directive");
+  static final ElementKind LABEL = new ElementKind('LABEL', 13, "label");
+  static final ElementKind LIBRARY = new ElementKind('LIBRARY', 14, "library");
+  static final ElementKind LOCAL_VARIABLE = new ElementKind('LOCAL_VARIABLE', 15, "local variable");
+  static final ElementKind METHOD = new ElementKind('METHOD', 16, "method");
+  static final ElementKind NAME = new ElementKind('NAME', 17, "<name>");
+  static final ElementKind PARAMETER = new ElementKind('PARAMETER', 18, "parameter");
+  static final ElementKind PREFIX = new ElementKind('PREFIX', 19, "import prefix");
+  static final ElementKind SETTER = new ElementKind('SETTER', 20, "setter");
+  static final ElementKind TOP_LEVEL_VARIABLE = new ElementKind('TOP_LEVEL_VARIABLE', 21, "top level variable");
+  static final ElementKind FUNCTION_TYPE_ALIAS = new ElementKind('FUNCTION_TYPE_ALIAS', 22, "function type alias");
+  static final ElementKind TYPE_VARIABLE = new ElementKind('TYPE_VARIABLE', 23, "type variable");
+  static final ElementKind UNIVERSE = new ElementKind('UNIVERSE', 24, "<universe>");
+  static final List<ElementKind> values = [CLASS, COMPILATION_UNIT, CONSTRUCTOR, DYNAMIC, EMBEDDED_HTML_SCRIPT, ERROR, EXPORT, EXTERNAL_HTML_SCRIPT, FIELD, FUNCTION, GETTER, HTML, IMPORT, LABEL, LIBRARY, LOCAL_VARIABLE, METHOD, NAME, PARAMETER, PREFIX, SETTER, TOP_LEVEL_VARIABLE, FUNCTION_TYPE_ALIAS, TYPE_VARIABLE, UNIVERSE];
   final String __name;
   final int __ordinal;
-  ElementKind(this.__name, this.__ordinal) {
+  int get ordinal => __ordinal;
+  String _displayName;
+  ElementKind(this.__name, this.__ordinal, String displayName) {
+    this._displayName = displayName;
   }
+  /**
+   * @return the name of this {@link ElementKind} to display in UI.
+   */
+  String get displayName => _displayName;
   String toString() => __name;
 }
 /**
  * The interface {@code ElementLocation} defines the behavior of objects that represent the location
  * of an element within the element model.
+ * @coverage dart.engine.element
  */
 abstract class ElementLocation {
   /**
@@ -361,15 +412,56 @@
   String get encoding;
 }
 /**
+ * The interface {@code ElementVisitor} defines the behavior of objects that can be used to visit an
+ * element structure.
+ * @coverage dart.engine.element
+ */
+abstract class ElementVisitor<R> {
+  R visitClassElement(ClassElement element);
+  R visitCompilationUnitElement(CompilationUnitElement element);
+  R visitConstructorElement(ConstructorElement element);
+  R visitEmbeddedHtmlScriptElement(EmbeddedHtmlScriptElement element);
+  R visitExportElement(ExportElement element);
+  R visitExternalHtmlScriptElement(ExternalHtmlScriptElement element);
+  R visitFieldElement(FieldElement element);
+  R visitFunctionElement(FunctionElement element);
+  R visitHtmlElement(HtmlElement element);
+  R visitImportElement(ImportElement element);
+  R visitLabelElement(LabelElement element);
+  R visitLibraryElement(LibraryElement element);
+  R visitLocalVariableElement(LocalVariableElement element);
+  R visitMethodElement(MethodElement element);
+  R visitMultiplyDefinedElement(MultiplyDefinedElement element);
+  R visitParameterElement(ParameterElement element);
+  R visitPrefixElement(PrefixElement element);
+  R visitPropertyAccessorElement(PropertyAccessorElement element);
+  R visitTopLevelVariableElement(TopLevelVariableElement element);
+  R visitFunctionTypeAliasElement(FunctionTypeAliasElement element);
+  R visitTypeVariableElement(TypeVariableElement element);
+}
+/**
+ * The interface {@code EmbeddedHtmlScriptElement} defines the behavior of elements representing a
+ * script tag in an HTML file having content that defines a Dart library.
+ * @coverage dart.engine.element
+ */
+abstract class EmbeddedHtmlScriptElement implements HtmlScriptElement {
+  /**
+   * Return the library element defined by the content of the script tag.
+   * @return the library element (not {@code null})
+   */
+  LibraryElement get scriptLibrary;
+}
+/**
  * The interface {@code ExecutableElement} defines the behavior of elements representing an
  * executable object, including functions, methods, constructors, getters, and setters.
+ * @coverage dart.engine.element
  */
 abstract class ExecutableElement implements Element {
   /**
    * Return an array containing all of the functions defined within this executable element.
    * @return the functions defined within this executable element
    */
-  List<ExecutableElement> get functions;
+  List<FunctionElement> get functions;
   /**
    * Return an array containing all of the labels defined within this executable element.
    * @return the labels defined within this executable element
@@ -379,7 +471,7 @@
    * Return an array containing all of the local variables defined within this executable element.
    * @return the local variables defined within this executable element
    */
-  List<VariableElement> get localVariables;
+  List<LocalVariableElement> get localVariables;
   /**
    * Return an array containing all of the parameters defined by this executable element.
    * @return the parameters defined by this executable element
@@ -390,10 +482,17 @@
    * @return the type of function defined by this executable element
    */
   FunctionType get type;
+  /**
+   * Return {@code true} if this element is a static element. A static element is an element that is
+   * not associated with a particular instance, but rather with an entire library or class.
+   * @return {@code true} if this executable element is a static element
+   */
+  bool isStatic();
 }
 /**
  * The interface {@code ExportElement} defines the behavior of objects representing information
  * about a single export directive within a library.
+ * @coverage dart.engine.element
  */
 abstract class ExportElement implements Element {
   /**
@@ -413,62 +512,68 @@
   LibraryElement get exportedLibrary;
 }
 /**
- * The interface {@code FieldElement} defines the behavior of elements representing a field defined
- * within a type. Note that explicitly defined fields implicitly define a synthetic getter and that
- * non-{@code final} explicitly defined fields implicitly define a synthetic setter. Symmetrically,
- * synthetic fields are implicitly created for explicitly defined getters and setters. The following
- * rules apply:
- * <ul>
- * <li>Every explicit field is represented by a non-synthetic {@link FieldElement}.
- * <li>Every explicit field induces a getter and possibly a setter, both of which are represented by
- * synthetic {@link PropertyAccessorElement}s.
- * <li>Every explicit getter or setter is represented by a non-synthetic{@link PropertyAccessorElement}.
- * <li>Every explicit getter or setter (or pair thereof if they have the same name) induces a field
- * that is represented by a synthetic {@link FieldElement}.
- * </ul>
+ * The interface {@code ExternalHtmlScriptElement} defines the behavior of elements representing a
+ * script tag in an HTML file having a {@code source} attribute that references a Dart library
+ * source file.
+ * @coverage dart.engine.element
  */
-abstract class FieldElement implements VariableElement {
+abstract class ExternalHtmlScriptElement implements HtmlScriptElement {
   /**
-   * Return the getter associated with this field. If this field was explicitly defined (is not
-   * synthetic) then the getter associated with it will be synthetic.
-   * @return the getter associated with this field
+   * Return the source referenced by this element, or {@code null} if this element does not
+   * reference a Dart library source file.
+   * @return the source for the external Dart library
    */
-  PropertyAccessorElement get getter;
+  Source get scriptSource;
+}
+/**
+ * The interface {@code FieldElement} defines the behavior of elements representing a field defined
+ * within a type.
+ * @coverage dart.engine.element
+ */
+abstract class FieldElement implements PropertyInducingElement {
   /**
-   * Return the setter associated with this field, or {@code null} if the field is effectively{@code final} and therefore does not have a setter associated with it. (This can happen either
-   * because the field is explicitly defined as being {@code final} or because the field is induced
-   * by an explicit getter that does not have a corresponding setter.) If this field was explicitly
-   * defined (is not synthetic) then the setter associated with it will be synthetic.
-   * @return the setter associated with this field
+   * Return the type in which this field is defined.
+   * @return the type in which this field is defined
    */
-  PropertyAccessorElement get setter;
-  /**
-   * Return {@code true} if this field is a static field.
-   * @return {@code true} if this field is a static field
-   */
-  bool isStatic();
+  ClassElement get enclosingElement;
 }
 /**
  * The interface {@code FunctionElement} defines the behavior of elements representing a function.
+ * @coverage dart.engine.element
  */
-abstract class FunctionElement implements ExecutableElement {
+abstract class FunctionElement implements ExecutableElement, LocalElement {
+}
+/**
+ * The interface {@code FunctionTypeAliasElement} defines the behavior of elements representing a
+ * function type alias ({@code typedef}).
+ * @coverage dart.engine.element
+ */
+abstract class FunctionTypeAliasElement implements Element {
   /**
-   * Return a source range that covers the approximate portion of the source in which the name of
-   * this function is visible, or {@code null} if there is no single range of characters within
-   * which the variable's name is visible.
-   * <ul>
-   * <li>For a local function, this includes everything from the beginning of the function's body to
-   * the end of the block that encloses the function declaration.</li>
-   * <li>For top-level functions, {@code null} will be returned because they are potentially visible
-   * in multiple sources.</li>
-   * </ul>
-   * @return the range of characters in which the name of this function is visible
+   * Return the compilation unit in which this type alias is defined.
+   * @return the compilation unit in which this type alias is defined
    */
-  SourceRange get visibleRange;
+  CompilationUnitElement get enclosingElement;
+  /**
+   * Return an array containing all of the parameters defined by this type alias.
+   * @return the parameters defined by this type alias
+   */
+  List<ParameterElement> get parameters;
+  /**
+   * Return the type of function defined by this type alias.
+   * @return the type of function defined by this type alias
+   */
+  FunctionType get type;
+  /**
+   * Return an array containing all of the type variables defined for this type.
+   * @return the type variables defined for this type
+   */
+  List<TypeVariableElement> get typeVariables;
 }
 /**
  * The interface {@code HideCombinator} defines the behavior of combinators that cause some of the
  * names in a namespace to be hidden when being imported.
+ * @coverage dart.engine.element
  */
 abstract class HideCombinator implements NamespaceCombinator {
   /**
@@ -480,19 +585,30 @@
 }
 /**
  * The interface {@code HtmlElement} defines the behavior of elements representing an HTML file.
+ * @coverage dart.engine.element
  */
 abstract class HtmlElement implements Element {
   /**
-   * Return an array containing all of the libraries contained in or referenced from script tags in
-   * the HTML file. This includes libraries that are defined by the content of a script file as well
-   * as libraries that are referenced in the {@core src} attribute of a script tag.
-   * @return the libraries referenced from script tags in the HTML file
+   * 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.
+   * @return the script elements in the HTML file (not {@code null}, contains no {@code null}s)
    */
-  List<LibraryElement> get libraries;
+  List<HtmlScriptElement> get scripts;
+}
+/**
+ * The interface {@code HtmlScriptElement} defines the behavior of elements representing a script
+ * tag in an HTML file.
+ * @see EmbeddedHtmlScriptElement
+ * @see ExternalHtmlScriptElement
+ * @coverage dart.engine.element
+ */
+abstract class HtmlScriptElement implements Element {
 }
 /**
  * The interface {@code ImportElement} defines the behavior of objects representing information
  * about a single import directive within a library.
+ * @coverage dart.engine.element
  */
 abstract class ImportElement implements Element {
   /**
@@ -520,6 +636,7 @@
 /**
  * The interface {@code LabelElement} defines the behavior of elements representing a label
  * associated with a statement.
+ * @coverage dart.engine.element
  */
 abstract class LabelElement implements Element {
   /**
@@ -530,6 +647,7 @@
 }
 /**
  * The interface {@code LibraryElement} defines the behavior of elements representing a library.
+ * @coverage dart.engine.element
  */
 abstract class LibraryElement implements Element {
   /**
@@ -582,10 +700,54 @@
    * @return {@code true} if this library is an application that can be run in the browser
    */
   bool isBrowserApplication();
+  /**
+   * Return {@code true} if this library is the dart:core library.
+   * @return {@code true} if this library is the dart:core library
+   */
+  bool isDartCore();
+  /**
+   * Return {@code true} if this library is up to date with respect to the given time stamp. If any
+   * transitively referenced Source is newer than the time stamp, this method returns false.
+   * @param timeStamp the time stamp to compare against
+   * @return {@code true} if this library is up to date with respect to the given time stamp
+   */
+  bool isUpToDate2(int timeStamp);
+}
+/**
+ * The interface {@code LocalElement} defines the behavior of elements that can be (but are not
+ * required to be) defined within a method or function (an {@link ExecutableElement}).
+ * @coverage dart.engine.element
+ */
+abstract class LocalElement implements Element {
+  /**
+   * Return a source range that covers the approximate portion of the source in which the name of
+   * this element is visible, or {@code null} if there is no single range of characters within which
+   * the element name is visible.
+   * <ul>
+   * <li>For a local variable, this includes everything from the end of the variable's initializer
+   * to the end of the block that encloses the variable declaration.</li>
+   * <li>For a parameter, this includes the body of the method or function that declares the
+   * parameter.</li>
+   * <li>For a local function, this includes everything from the beginning of the function's body to
+   * the end of the block that encloses the function declaration.</li>
+   * <li>For top-level functions, {@code null} will be returned because they are potentially visible
+   * in multiple sources.</li>
+   * </ul>
+   * @return the range of characters in which the name of this element is visible
+   */
+  SourceRange get visibleRange;
+}
+/**
+ * The interface {@code LocalVariableElement} defines the behavior common to elements that represent
+ * a local variable.
+ * @coverage dart.engine.element
+ */
+abstract class LocalVariableElement implements LocalElement, VariableElement {
 }
 /**
  * The interface {@code MethodElement} defines the behavior of elements that represent a method
  * defined within a type.
+ * @coverage dart.engine.element
  */
 abstract class MethodElement implements ExecutableElement {
   /**
@@ -599,12 +761,6 @@
    * @return {@code true} if this method is abstract
    */
   bool isAbstract();
-  /**
-   * Return {@code true} if this method is static. Methods are static if they have been marked as
-   * being static using the {@code static} modifier.
-   * @return {@code true} if this method is static
-   */
-  bool isStatic();
 }
 /**
  * The interface {@code MultiplyDefinedElement} defines the behavior of pseudo-elements that
@@ -612,6 +768,7 @@
  * is not allowed by the language, so objects implementing this interface always represent an error.
  * As a result, most of the normal operations on elements do not make sense and will return useless
  * results.
+ * @coverage dart.engine.element
  */
 abstract class MultiplyDefinedElement implements Element {
   /**
@@ -624,6 +781,7 @@
 /**
  * The interface {@code NamespaceCombinator} defines the behavior common to objects that control how
  * namespaces are combined.
+ * @coverage dart.engine.element
  */
 abstract class NamespaceCombinator {
   /**
@@ -634,8 +792,9 @@
 /**
  * The interface {@code ParameterElement} defines the behavior of elements representing a parameter
  * defined within an executable element.
+ * @coverage dart.engine.element
  */
-abstract class ParameterElement implements VariableElement {
+abstract class ParameterElement implements LocalElement, VariableElement {
   /**
    * Return the kind of this parameter.
    * @return the kind of this parameter
@@ -650,6 +809,7 @@
 /**
  * The interface {@code PrefixElement} defines the behavior common to elements that represent a
  * prefix used to import one or more libraries into another library.
+ * @coverage dart.engine.element
  */
 abstract class PrefixElement implements Element {
   /**
@@ -676,14 +836,15 @@
  * <li>Every explicit getter or setter (or pair thereof if they have the same name) induces a field
  * that is represented by a synthetic {@link FieldElement}.
  * </ul>
+ * @coverage dart.engine.element
  */
 abstract class PropertyAccessorElement implements ExecutableElement {
   /**
-   * Return the field associated with this accessor. If this accessor was explicitly defined (is not
-   * synthetic) then the field associated with it will be synthetic.
-   * @return the field associated with this accessor
+   * Return the field or top-level variable associated with this accessor. If this accessor was
+   * explicitly defined (is not synthetic) then the variable associated with it will be synthetic.
+   * @return the variable associated with this accessor
    */
-  FieldElement get field;
+  PropertyInducingElement get variable;
   /**
    * Return {@code true} if this accessor represents a getter.
    * @return {@code true} if this accessor represents a getter
@@ -696,8 +857,47 @@
   bool isSetter();
 }
 /**
+ * The interface {@code PropertyInducingElement} defines the behavior of elements representing a
+ * variable that has an associated getter and possibly a setter. Note that explicitly defined
+ * variables implicitly define a synthetic getter and that non-{@code final} explicitly defined
+ * variables implicitly define a synthetic setter. Symmetrically, synthetic fields are implicitly
+ * created for explicitly defined getters and setters. The following rules apply:
+ * <ul>
+ * <li>Every explicit variable is represented by a non-synthetic {@link PropertyInducingElement}.
+ * <li>Every explicit variable induces a getter and possibly a setter, both of which are represented
+ * by synthetic {@link PropertyAccessorElement}s.
+ * <li>Every explicit getter or setter is represented by a non-synthetic{@link PropertyAccessorElement}.
+ * <li>Every explicit getter or setter (or pair thereof if they have the same name) induces a
+ * variable that is represented by a synthetic {@link PropertyInducingElement}.
+ * </ul>
+ * @coverage dart.engine.element
+ */
+abstract class PropertyInducingElement implements VariableElement {
+  /**
+   * Return the getter associated with this variable. If this variable was explicitly defined (is
+   * not synthetic) then the getter associated with it will be synthetic.
+   * @return the getter associated with this variable
+   */
+  PropertyAccessorElement get getter;
+  /**
+   * Return the setter associated with this variable, or {@code null} if the variable is effectively{@code final} and therefore does not have a setter associated with it. (This can happen either
+   * because the variable is explicitly defined as being {@code final} or because the variable is
+   * induced by an explicit getter that does not have a corresponding setter.) If this variable was
+   * explicitly defined (is not synthetic) then the setter associated with it will be synthetic.
+   * @return the setter associated with this variable
+   */
+  PropertyAccessorElement get setter;
+  /**
+   * Return {@code true} if this element is a static element. A static element is an element that is
+   * not associated with a particular instance, but rather with an entire library or class.
+   * @return {@code true} if this executable element is a static element
+   */
+  bool isStatic();
+}
+/**
  * The interface {@code ShowCombinator} defines the behavior of combinators that cause some of the
  * names in a namespace to be visible (and the rest hidden) when being imported.
+ * @coverage dart.engine.element
  */
 abstract class ShowCombinator implements NamespaceCombinator {
   /**
@@ -708,34 +908,16 @@
   List<String> get shownNames;
 }
 /**
- * The interface {@code TypeAliasElement} defines the behavior of elements representing a type alias
- * ({@code typedef}).
+ * The interface {@code TopLevelVariableElement} defines the behavior of elements representing a
+ * top-level variable.
+ * @coverage dart.engine.element
  */
-abstract class TypeAliasElement implements Element {
-  /**
-   * Return the compilation unit in which this type alias is defined.
-   * @return the compilation unit in which this type alias is defined
-   */
-  CompilationUnitElement get enclosingElement;
-  /**
-   * Return an array containing all of the parameters defined by this type alias.
-   * @return the parameters defined by this type alias
-   */
-  List<ParameterElement> get parameters;
-  /**
-   * Return the type of function defined by this type alias.
-   * @return the type of function defined by this type alias
-   */
-  FunctionType get type;
-  /**
-   * Return an array containing all of the type variables defined for this type.
-   * @return the type variables defined for this type
-   */
-  List<TypeVariableElement> get typeVariables;
+abstract class TopLevelVariableElement implements PropertyInducingElement {
 }
 /**
  * The interface {@code TypeVariableElement} defines the behavior of elements representing a type
  * variable.
+ * @coverage dart.engine.element
  */
 abstract class TypeVariableElement implements Element {
   /**
@@ -755,12 +937,14 @@
  * names that are undefined. This situation is not allowed by the language, so objects implementing
  * this interface always represent an error. As a result, most of the normal operations on elements
  * do not make sense and will return useless results.
+ * @coverage dart.engine.element
  */
 abstract class UndefinedElement implements Element {
 }
 /**
  * The interface {@code VariableElement} defines the behavior common to elements that represent a
  * variable.
+ * @coverage dart.engine.element
  */
 abstract class VariableElement implements Element {
   /**
@@ -777,35 +961,239 @@
    */
   Type2 get type;
   /**
-   * Return a source range that covers the approximate portion of the source in which the name of
-   * this variable is visible, or {@code null} if there is no single range of characters within
-   * which the variable's name is visible.
-   * <ul>
-   * <li>For a local variable, this includes everything from the end of the variable's initializer
-   * to the end of the block that encloses the variable declaration.</li>
-   * <li>For a parameter, this includes the body of the method or function that declares the
-   * parameter.</li>
-   * <li>For fields and top-level variables, {@code null} will be returned because they are
-   * potentially visible in multiple sources.</li>
-   * </ul>
-   * @return the range of characters in which the name of this variable is visible
-   */
-  SourceRange get visibleRange;
-  /**
-   * Return {@code true} if this variable is a const variable. Variables are const if they have been
-   * marked as being const using the {@code const} modifier.
-   * @return {@code true} if this variable is a const variable
+   * Return {@code true} if this variable was declared with the 'const' modifier.
+   * @return {@code true} if this variable was declared with the 'const' modifier
    */
   bool isConst();
   /**
-   * Return {@code true} if this variable is a final variable. Variables are final if they have been
-   * marked as being final using either the {@code final} or {@code const} modifiers.
-   * @return {@code true} if this variable is a final variable
+   * Return {@code true} if this variable was declared with the 'final' modifier. Variables that are
+   * declared with the 'const' modifier will return {@code false} even though they are implicitly
+   * final.
+   * @return {@code true} if this variable was declared with the 'final' modifier
    */
   bool isFinal();
 }
 /**
+ * Instances of the class {@code GeneralizingElementVisitor} implement an element visitor that will
+ * recursively visit all of the elements in an element model (like instances of the class{@link RecursiveElementVisitor}). In addition, when an element of a specific type is visited not
+ * only will the visit method for that specific type of element be invoked, but additional methods
+ * for the supertypes of that element will also be invoked. For example, using an instance of this
+ * class to visit a {@link MethodElement} will cause the method{@link #visitMethodElement(MethodElement)} to be invoked but will also cause the methods{@link #visitExecutableElement(ExecutableElement)} and {@link #visitElement(Element)} to be
+ * subsequently invoked. This allows visitors to be written that visit all executable elements
+ * without needing to override the visit method for each of the specific subclasses of{@link ExecutableElement}.
+ * <p>
+ * Note, however, that unlike many visitors, element visitors visit objects based on the interfaces
+ * implemented by those elements. Because interfaces form a graph structure rather than a tree
+ * structure the way classes do, and because it is generally undesirable for an object to be visited
+ * more than once, this class flattens the interface graph into a pseudo-tree. In particular, this
+ * class treats elements as if the element types were structured in the following way:
+ * <p>
+ * <pre>
+ * Element
+ * ClassElement
+ * CompilationUnitElement
+ * ExecutableElement
+ * ConstructorElement
+ * LocalElement
+ * FunctionElement
+ * MethodElement
+ * PropertyAccessorElement
+ * ExportElement
+ * HtmlElement
+ * ImportElement
+ * LabelElement
+ * LibraryElement
+ * MultiplyDefinedElement
+ * PrefixElement
+ * TypeAliasElement
+ * TypeVariableElement
+ * UndefinedElement
+ * VariableElement
+ * PropertyInducingElement
+ * FieldElement
+ * TopLevelVariableElement
+ * LocalElement
+ * LocalVariableElement
+ * ParameterElement
+ * </pre>
+ * <p>
+ * Subclasses that override a visit method must either invoke the overridden visit method or
+ * explicitly invoke the more general visit method. Failure to do so will cause the visit methods
+ * for superclasses of the element to not be invoked and will cause the children of the visited node
+ * to not be visited.
+ * @coverage dart.engine.element
+ */
+class GeneralizingElementVisitor<R> implements ElementVisitor<R> {
+  R visitClassElement(ClassElement element) => visitElement(element);
+  R visitCompilationUnitElement(CompilationUnitElement element) => visitElement(element);
+  R visitConstructorElement(ConstructorElement element) => visitExecutableElement(element);
+  R visitElement(Element element) {
+    element.visitChildren(this);
+    return null;
+  }
+  R visitEmbeddedHtmlScriptElement(EmbeddedHtmlScriptElement element) => visitHtmlScriptElement(element);
+  R visitExecutableElement(ExecutableElement element) => visitElement(element);
+  R visitExportElement(ExportElement element) => visitElement(element);
+  R visitExternalHtmlScriptElement(ExternalHtmlScriptElement element) => visitHtmlScriptElement(element);
+  R visitFieldElement(FieldElement element) => visitPropertyInducingElement(element);
+  R visitFunctionElement(FunctionElement element) => visitLocalElement(element);
+  R visitHtmlElement(HtmlElement element) => visitElement(element);
+  R visitHtmlScriptElement(HtmlScriptElement element) => visitElement(element);
+  R visitImportElement(ImportElement element) => visitElement(element);
+  R visitLabelElement(LabelElement element) => visitElement(element);
+  R visitLibraryElement(LibraryElement element) => visitElement(element);
+  R visitLocalElement(LocalElement element) {
+    if (element is LocalVariableElement) {
+      return visitVariableElement((element as LocalVariableElement));
+    } else if (element is ParameterElement) {
+      return visitVariableElement((element as ParameterElement));
+    } else if (element is FunctionElement) {
+      return visitExecutableElement((element as FunctionElement));
+    }
+    return null;
+  }
+  R visitLocalVariableElement(LocalVariableElement element) => visitLocalElement(element);
+  R visitMethodElement(MethodElement element) => visitExecutableElement(element);
+  R visitMultiplyDefinedElement(MultiplyDefinedElement element) => visitElement(element);
+  R visitParameterElement(ParameterElement element) => visitLocalElement(element);
+  R visitPrefixElement(PrefixElement element) => visitElement(element);
+  R visitPropertyAccessorElement(PropertyAccessorElement element) => visitExecutableElement(element);
+  R visitPropertyInducingElement(PropertyInducingElement element) => visitVariableElement(element);
+  R visitTopLevelVariableElement(TopLevelVariableElement element) => visitPropertyInducingElement(element);
+  R visitFunctionTypeAliasElement(FunctionTypeAliasElement element) => visitElement(element);
+  R visitTypeVariableElement(TypeVariableElement element) => visitElement(element);
+  R visitVariableElement(VariableElement element) => visitElement(element);
+}
+/**
+ * Instances of the class {@code RecursiveElementVisitor} implement an element visitor that will
+ * recursively visit all of the element in an element model. For example, using an instance of this
+ * class to visit a {@link CompilationUnitElement} will also cause all of the types in the
+ * compilation unit to be visited.
+ * <p>
+ * Subclasses that override a visit method must either invoke the overridden visit method or must
+ * explicitly ask the visited element to visit its children. Failure to do so will cause the
+ * children of the visited element to not be visited.
+ * @coverage dart.engine.element
+ */
+class RecursiveElementVisitor<R> implements ElementVisitor<R> {
+  R visitClassElement(ClassElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+  R visitCompilationUnitElement(CompilationUnitElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+  R visitConstructorElement(ConstructorElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+  R visitEmbeddedHtmlScriptElement(EmbeddedHtmlScriptElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+  R visitExportElement(ExportElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+  R visitExternalHtmlScriptElement(ExternalHtmlScriptElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+  R visitFieldElement(FieldElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+  R visitFunctionElement(FunctionElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+  R visitHtmlElement(HtmlElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+  R visitImportElement(ImportElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+  R visitLabelElement(LabelElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+  R visitLibraryElement(LibraryElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+  R visitLocalVariableElement(LocalVariableElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+  R visitMethodElement(MethodElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+  R visitMultiplyDefinedElement(MultiplyDefinedElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+  R visitParameterElement(ParameterElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+  R visitPrefixElement(PrefixElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+  R visitPropertyAccessorElement(PropertyAccessorElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+  R visitTopLevelVariableElement(TopLevelVariableElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+  R visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+  R visitTypeVariableElement(TypeVariableElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+}
+/**
+ * Instances of the class {@code SimpleElementVisitor} implement an element visitor that will do
+ * nothing when visiting an element. It is intended to be a superclass for classes that use the
+ * visitor pattern primarily as a dispatch mechanism (and hence don't need to recursively visit a
+ * whole structure) and that only need to visit a small number of element types.
+ * @coverage dart.engine.element
+ */
+class SimpleElementVisitor<R> implements ElementVisitor<R> {
+  R visitClassElement(ClassElement element) => null;
+  R visitCompilationUnitElement(CompilationUnitElement element) => null;
+  R visitConstructorElement(ConstructorElement element) => null;
+  R visitEmbeddedHtmlScriptElement(EmbeddedHtmlScriptElement element) => null;
+  R visitExportElement(ExportElement element) => null;
+  R visitExternalHtmlScriptElement(ExternalHtmlScriptElement element) => null;
+  R visitFieldElement(FieldElement element) => null;
+  R visitFunctionElement(FunctionElement element) => null;
+  R visitHtmlElement(HtmlElement element) => null;
+  R visitImportElement(ImportElement element) => null;
+  R visitLabelElement(LabelElement element) => null;
+  R visitLibraryElement(LibraryElement element) => null;
+  R visitLocalVariableElement(LocalVariableElement element) => null;
+  R visitMethodElement(MethodElement element) => null;
+  R visitMultiplyDefinedElement(MultiplyDefinedElement element) => null;
+  R visitParameterElement(ParameterElement element) => null;
+  R visitPrefixElement(PrefixElement element) => null;
+  R visitPropertyAccessorElement(PropertyAccessorElement element) => null;
+  R visitTopLevelVariableElement(TopLevelVariableElement element) => null;
+  R visitFunctionTypeAliasElement(FunctionTypeAliasElement element) => null;
+  R visitTypeVariableElement(TypeVariableElement element) => null;
+}
+/**
  * Instances of the class {@code AnnotationImpl} implement an {@link Annotation}.
+ * @coverage dart.engine.element
  */
 class AnnotationImpl implements Annotation {
   /**
@@ -829,6 +1217,7 @@
 }
 /**
  * Instances of the class {@code ClassElementImpl} implement a {@code ClassElement}.
+ * @coverage dart.engine.element
  */
 class ClassElementImpl extends ElementImpl implements ClassElement {
   /**
@@ -878,36 +1267,37 @@
    */
   ClassElementImpl(Identifier name) : super.con1(name) {
   }
+  accept(ElementVisitor visitor) => visitor.visitClassElement(this);
   List<PropertyAccessorElement> get accessors => _accessors;
   List<InterfaceType> get allSupertypes {
     Collection<InterfaceType> list = new Set<InterfaceType>();
     collectAllSupertypes(list);
     return new List.from(list);
   }
-  ElementImpl getChild(String identifier19) {
+  ElementImpl getChild(String identifier25) {
     for (PropertyAccessorElement accessor in _accessors) {
-      if (((accessor as PropertyAccessorElementImpl)).identifier == identifier19) {
-        return (accessor as PropertyAccessorElementImpl);
+      if (((accessor as PropertyAccessorElementImpl)).identifier == identifier25) {
+        return accessor as PropertyAccessorElementImpl;
       }
     }
     for (ConstructorElement constructor in _constructors) {
-      if (((constructor as ConstructorElementImpl)).identifier == identifier19) {
-        return (constructor as ConstructorElementImpl);
+      if (((constructor as ConstructorElementImpl)).identifier == identifier25) {
+        return constructor as ConstructorElementImpl;
       }
     }
     for (FieldElement field in _fields) {
-      if (((field as FieldElementImpl)).identifier == identifier19) {
-        return (field as FieldElementImpl);
+      if (((field as FieldElementImpl)).identifier == identifier25) {
+        return field as FieldElementImpl;
       }
     }
     for (MethodElement method in _methods) {
-      if (((method as MethodElementImpl)).identifier == identifier19) {
-        return (method as MethodElementImpl);
+      if (((method as MethodElementImpl)).identifier == identifier25) {
+        return method as MethodElementImpl;
       }
     }
     for (TypeVariableElement typeVariable in _typeVariables) {
-      if (((typeVariable as TypeVariableElementImpl)).identifier == identifier19) {
-        return (typeVariable as TypeVariableElementImpl);
+      if (((typeVariable as TypeVariableElementImpl)).identifier == identifier25) {
+        return typeVariable as TypeVariableElementImpl;
       }
     }
     return null;
@@ -918,10 +1308,10 @@
   ElementKind get kind => ElementKind.CLASS;
   List<MethodElement> get methods => _methods;
   List<InterfaceType> get mixins => _mixins;
-  ConstructorElement getNamedConstructor(String name21) {
+  ConstructorElement getNamedConstructor(String name23) {
     for (ConstructorElement element in constructors) {
       String elementName = element.name;
-      if (elementName != null && elementName == name21) {
+      if (elementName != null && elementName == name23) {
         return element;
       }
     }
@@ -940,6 +1330,8 @@
     return null;
   }
   bool isAbstract() => hasModifier(Modifier.ABSTRACT);
+  bool isTypedef() => hasModifier(Modifier.TYPEDEF);
+  bool isValidMixin() => hasModifier(Modifier.MIXIN);
   PropertyAccessorElement lookUpGetter(String getterName, LibraryElement library) {
     PropertyAccessorElement element = getGetter(getterName);
     if (element != null && element.isAccessibleIn(library)) {
@@ -1088,8 +1480,15 @@
    * Set the type defined by the class to the given type.
    * @param type the type defined by the class
    */
-  void set type(InterfaceType type4) {
-    this._type = type4;
+  void set type(InterfaceType type5) {
+    this._type = type5;
+  }
+  /**
+   * Set whether this class is defined by a typedef construct to correspond to the given value.
+   * @param isTypedef {@code true} if the class is defined by a typedef construct
+   */
+  void set typedef(bool isTypedef) {
+    setModifier(Modifier.TYPEDEF, isTypedef);
   }
   /**
    * Set the type variables defined for this class to the given type variables.
@@ -1101,23 +1500,38 @@
     }
     this._typeVariables = typeVariables2;
   }
-  void appendTo(StringBuffer builder) {
+  /**
+   * Set whether this class is a valid mixin to correspond to the given value.
+   * @param isValidMixin {@code true} if this class can be used as a mixin
+   */
+  void set validMixin(bool isValidMixin) {
+    setModifier(Modifier.MIXIN, isValidMixin);
+  }
+  void visitChildren(ElementVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChildren(_accessors, visitor);
+    safelyVisitChildren(_constructors, visitor);
+    safelyVisitChildren(_fields, visitor);
+    safelyVisitChildren(_methods, visitor);
+    safelyVisitChildren(_typeVariables, visitor);
+  }
+  void appendTo(JavaStringBuilder builder) {
     String name11 = name;
     if (name11 == null) {
-      builder.add("{unnamed class}");
+      builder.append("{unnamed class}");
     } else {
-      builder.add(name11);
+      builder.append(name11);
     }
     int variableCount = _typeVariables.length;
     if (variableCount > 0) {
-      builder.add("<");
+      builder.append("<");
       for (int i = 0; i < variableCount; i++) {
         if (i > 0) {
-          builder.add(", ");
+          builder.append(", ");
         }
         ((_typeVariables[i] as TypeVariableElementImpl)).appendTo(builder);
       }
-      builder.add(">");
+      builder.append(">");
     }
   }
   void collectAllSupertypes(Collection<InterfaceType> list) {
@@ -1183,6 +1597,7 @@
 }
 /**
  * Instances of the class {@code CompilationUnitElementImpl} implement a{@link CompilationUnitElement}.
+ * @coverage dart.engine.element
  */
 class CompilationUnitElementImpl extends ElementImpl implements CompilationUnitElement {
   /**
@@ -1197,15 +1612,15 @@
   /**
    * An array containing all of the variables contained in this compilation unit.
    */
-  List<VariableElement> _variables = VariableElementImpl.EMPTY_ARRAY;
+  List<TopLevelVariableElement> _variables = TopLevelVariableElementImpl.EMPTY_ARRAY;
   /**
    * The source that corresponds to this compilation unit.
    */
   Source _source;
   /**
-   * An array containing all of the type aliases contained in this compilation unit.
+   * An array containing all of the function type aliases contained in this compilation unit.
    */
-  List<TypeAliasElement> _typeAliases = TypeAliasElementImpl.EMPTY_ARRAY;
+  List<FunctionTypeAliasElement> _typeAliases = FunctionTypeAliasElementImpl.EMPTY_ARRAY;
   /**
    * An array containing all of the types contained in this compilation unit.
    */
@@ -1220,44 +1635,45 @@
    */
   CompilationUnitElementImpl(String name) : super.con2(name, -1) {
   }
-  bool operator ==(Object object) => identical(this.runtimeType, object.runtimeType) && _source == ((object as CompilationUnitElementImpl)).source;
+  accept(ElementVisitor visitor) => visitor.visitCompilationUnitElement(this);
+  bool operator ==(Object object) => object != null && identical(runtimeType, object.runtimeType) && _source == ((object as CompilationUnitElementImpl)).source;
   List<PropertyAccessorElement> get accessors => _accessors;
-  ElementImpl getChild(String identifier20) {
+  ElementImpl getChild(String identifier26) {
     for (PropertyAccessorElement accessor in _accessors) {
-      if (((accessor as PropertyAccessorElementImpl)).identifier == identifier20) {
-        return (accessor as PropertyAccessorElementImpl);
+      if (((accessor as PropertyAccessorElementImpl)).identifier == identifier26) {
+        return accessor as PropertyAccessorElementImpl;
       }
     }
     for (VariableElement variable in _variables) {
-      if (((variable as VariableElementImpl)).identifier == identifier20) {
-        return (variable as VariableElementImpl);
+      if (((variable as VariableElementImpl)).identifier == identifier26) {
+        return variable as VariableElementImpl;
       }
     }
     for (ExecutableElement function in _functions) {
-      if (((function as ExecutableElementImpl)).identifier == identifier20) {
-        return (function as ExecutableElementImpl);
+      if (((function as ExecutableElementImpl)).identifier == identifier26) {
+        return function as ExecutableElementImpl;
       }
     }
-    for (TypeAliasElement typeAlias in _typeAliases) {
-      if (((typeAlias as TypeAliasElementImpl)).identifier == identifier20) {
-        return (typeAlias as TypeAliasElementImpl);
+    for (FunctionTypeAliasElement typeAlias in _typeAliases) {
+      if (((typeAlias as FunctionTypeAliasElementImpl)).identifier == identifier26) {
+        return typeAlias as FunctionTypeAliasElementImpl;
       }
     }
     for (ClassElement type in _types) {
-      if (((type as ClassElementImpl)).identifier == identifier20) {
-        return (type as ClassElementImpl);
+      if (((type as ClassElementImpl)).identifier == identifier26) {
+        return type as ClassElementImpl;
       }
     }
     return null;
   }
-  LibraryElement get enclosingElement => (super.enclosingElement as LibraryElement);
+  LibraryElement get enclosingElement => super.enclosingElement as LibraryElement;
   List<FunctionElement> get functions => _functions;
+  List<FunctionTypeAliasElement> get functionTypeAliases => _typeAliases;
   String get identifier => source.fullName;
   ElementKind get kind => ElementKind.COMPILATION_UNIT;
   Source get source => _source;
-  List<TypeAliasElement> get typeAliases => _typeAliases;
+  List<TopLevelVariableElement> get topLevelVariables => _variables;
   List<ClassElement> get types => _types;
-  List<VariableElement> get variables => _variables;
   int get hashCode => _source.hashCode;
   /**
    * Set the top-level accessors (getters and setters) contained in this compilation unit to the
@@ -1288,12 +1704,22 @@
     this._source = source5;
   }
   /**
-   * Set the type aliases contained in this compilation unit to the given type aliases.
-   * @param typeAliases the type aliases contained in this compilation unit
+   * Set the top-level variables contained in this compilation unit to the given variables.
+   * @param variables the top-level variables contained in this compilation unit
    */
-  void set typeAliases(List<TypeAliasElement> typeAliases2) {
-    for (TypeAliasElement typeAlias in typeAliases2) {
-      ((typeAlias as TypeAliasElementImpl)).enclosingElement = this;
+  void set topLevelVariables(List<TopLevelVariableElement> variables2) {
+    for (TopLevelVariableElement field in variables2) {
+      ((field as TopLevelVariableElementImpl)).enclosingElement = this;
+    }
+    this._variables = variables2;
+  }
+  /**
+   * Set the function type aliases contained in this compilation unit to the given type aliases.
+   * @param typeAliases the function type aliases contained in this compilation unit
+   */
+  void set typeAliases(List<FunctionTypeAliasElement> typeAliases2) {
+    for (FunctionTypeAliasElement typeAlias in typeAliases2) {
+      ((typeAlias as FunctionTypeAliasElementImpl)).enclosingElement = this;
     }
     this._typeAliases = typeAliases2;
   }
@@ -1307,26 +1733,105 @@
     }
     this._types = types2;
   }
-  /**
-   * Set the variables contained in this compilation unit to the given variables.
-   * @param variables the variables contained in this compilation unit
-   */
-  void set variables(List<VariableElement> variables2) {
-    for (VariableElement field in variables2) {
-      ((field as VariableElementImpl)).enclosingElement = this;
-    }
-    this._variables = variables2;
+  void visitChildren(ElementVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChildren(_accessors, visitor);
+    safelyVisitChildren(_functions, visitor);
+    safelyVisitChildren(_typeAliases, visitor);
+    safelyVisitChildren(_types, visitor);
+    safelyVisitChildren(_variables, visitor);
   }
-  void appendTo(StringBuffer builder) {
+  void appendTo(JavaStringBuilder builder) {
     if (_source == null) {
-      builder.add("{compilation unit}");
+      builder.append("{compilation unit}");
     } else {
-      builder.add(_source.fullName);
+      builder.append(_source.fullName);
     }
   }
 }
 /**
+ * Instances of the class {@code ConstFieldElementImpl} implement a {@code FieldElement} for a
+ * 'const' field that has an initializer.
+ */
+class ConstFieldElementImpl extends FieldElementImpl {
+  /**
+   * The result of evaluating this variable's initializer.
+   */
+  EvaluationResultImpl _result;
+  /**
+   * Initialize a newly created field element to have the given name.
+   * @param name the name of this element
+   */
+  ConstFieldElementImpl(Identifier name) : super.con1(name) {
+  }
+  EvaluationResultImpl get evaluationResult => _result;
+  void set evaluationResult(EvaluationResultImpl result2) {
+    this._result = result2;
+  }
+}
+/**
+ * Instances of the class {@code ConstLocalVariableElementImpl} implement a{@code LocalVariableElement} for a local 'const' variable that has an initializer.
+ * @coverage dart.engine.element
+ */
+class ConstLocalVariableElementImpl extends LocalVariableElementImpl {
+  /**
+   * The result of evaluating this variable's initializer.
+   */
+  EvaluationResultImpl _result;
+  /**
+   * Initialize a newly created local variable element to have the given name.
+   * @param name the name of this element
+   */
+  ConstLocalVariableElementImpl(Identifier name) : super(name) {
+  }
+  EvaluationResultImpl get evaluationResult => _result;
+  void set evaluationResult(EvaluationResultImpl result3) {
+    this._result = result3;
+  }
+}
+/**
+ * Instances of the class {@code ConstParameterElementImpl} implement a {@code ParameterElement} for
+ * a 'const' parameter that has an initializer.
+ * @coverage dart.engine.element
+ */
+class ConstParameterElementImpl extends ParameterElementImpl {
+  /**
+   * The result of evaluating this variable's initializer.
+   */
+  EvaluationResultImpl _result;
+  /**
+   * Initialize a newly created parameter element to have the given name.
+   * @param name the name of this element
+   */
+  ConstParameterElementImpl(Identifier name) : super(name) {
+  }
+  EvaluationResultImpl get evaluationResult => _result;
+  void set evaluationResult(EvaluationResultImpl result4) {
+    this._result = result4;
+  }
+}
+/**
+ * Instances of the class {@code ConstTopLevelVariableElementImpl} implement a{@code TopLevelVariableElement} for a top-level 'const' variable that has an initializer.
+ */
+class ConstTopLevelVariableElementImpl extends TopLevelVariableElementImpl {
+  /**
+   * The result of evaluating this variable's initializer.
+   */
+  EvaluationResultImpl _result;
+  /**
+   * Initialize a newly created top-level variable element to have the given name.
+   * @param name the name of this element
+   */
+  ConstTopLevelVariableElementImpl(Identifier name) : super.con1(name) {
+  }
+  EvaluationResultImpl get evaluationResult => _result;
+  void set evaluationResult(EvaluationResultImpl result5) {
+    this._result = result5;
+  }
+}
+/**
  * Instances of the class {@code ConstructorElementImpl} implement a {@code ConstructorElement}.
+ * @coverage dart.engine.element
  */
 class ConstructorElementImpl extends ExecutableElementImpl implements ConstructorElement {
   /**
@@ -1339,10 +1844,19 @@
    */
   ConstructorElementImpl(Identifier name) : super.con1(name) {
   }
-  ClassElement get enclosingElement => (super.enclosingElement as ClassElement);
+  accept(ElementVisitor visitor) => visitor.visitConstructorElement(this);
+  ClassElement get enclosingElement => super.enclosingElement as ClassElement;
   ElementKind get kind => ElementKind.CONSTRUCTOR;
   bool isConst() => hasModifier(Modifier.CONST);
   bool isFactory() => hasModifier(Modifier.FACTORY);
+  bool isStatic() => false;
+  /**
+   * Set whether this constructor represents a 'const' constructor to the given value.
+   * @param isConst {@code true} if this constructor represents a 'const' constructor
+   */
+  void set const2(bool isConst) {
+    setModifier(Modifier.CONST, isConst);
+  }
   /**
    * Set whether this constructor represents a factory method to the given value.
    * @param isFactory {@code true} if this constructor represents a factory method
@@ -1350,12 +1864,12 @@
   void set factory(bool isFactory) {
     setModifier(Modifier.FACTORY, isFactory);
   }
-  void appendTo(StringBuffer builder) {
-    builder.add(enclosingElement.name);
+  void appendTo(JavaStringBuilder builder) {
+    builder.append(enclosingElement.name);
     String name12 = name;
     if (name12 != null && !name12.isEmpty) {
-      builder.add(".");
-      builder.add(name12);
+      builder.append(".");
+      builder.append(name12);
     }
     super.appendTo(builder);
   }
@@ -1363,13 +1877,14 @@
 /**
  * Instances of the class {@code DynamicElementImpl} represent the synthetic element representing
  * the declaration of the type {@code dynamic}.
+ * @coverage dart.engine.element
  */
 class DynamicElementImpl extends ElementImpl {
   /**
    * Return the unique instance of this class.
    * @return the unique instance of this class
    */
-  static DynamicElementImpl get instance => (DynamicTypeImpl.instance.element as DynamicElementImpl);
+  static DynamicElementImpl get instance => DynamicTypeImpl.instance.element as DynamicElementImpl;
   /**
    * The type defined by this element.
    */
@@ -1382,6 +1897,7 @@
   DynamicElementImpl() : super.con2(Keyword.DYNAMIC.syntax, -1) {
     setModifier(Modifier.SYNTHETIC, true);
   }
+  accept(ElementVisitor visitor) => null;
   ElementKind get kind => ElementKind.DYNAMIC;
   /**
    * Return the type defined by this element.
@@ -1392,13 +1908,14 @@
    * Set the type defined by this element to the given type.
    * @param type the type defined by this element
    */
-  void set type(DynamicTypeImpl type5) {
-    this._type = type5;
+  void set type(DynamicTypeImpl type6) {
+    this._type = type6;
   }
 }
 /**
  * The abstract class {@code ElementImpl} implements the behavior common to objects that implement
  * an {@link Element}.
+ * @coverage dart.engine.element
  */
 abstract class ElementImpl implements Element {
   /**
@@ -1427,11 +1944,11 @@
    * Initialize a newly created element to have the given name.
    * @param name the name of this element
    */
-  ElementImpl.con1(Identifier name22) {
-    _jtd_constructor_135_impl(name22);
+  ElementImpl.con1(Identifier name24) {
+    _jtd_constructor_172_impl(name24);
   }
-  _jtd_constructor_135_impl(Identifier name22) {
-    _jtd_constructor_136_impl(name22 == null ? "" : name22.name, name22 == null ? -1 : name22.offset);
+  _jtd_constructor_172_impl(Identifier name24) {
+    _jtd_constructor_173_impl(name24 == null ? "" : name24.name, name24 == null ? -1 : name24.offset);
   }
   /**
    * Initialize a newly created element to have the given name.
@@ -1440,20 +1957,20 @@
    * declaration of this element
    */
   ElementImpl.con2(String name8, int nameOffset2) {
-    _jtd_constructor_136_impl(name8, nameOffset2);
+    _jtd_constructor_173_impl(name8, nameOffset2);
   }
-  _jtd_constructor_136_impl(String name8, int nameOffset2) {
+  _jtd_constructor_173_impl(String name8, int nameOffset2) {
     this._name = name8;
     this._nameOffset = nameOffset2;
     this._modifiers = new Set();
   }
-  bool operator ==(Object object) => object is Element && ((object as Element)).location == location;
+  bool operator ==(Object object) => object != null && identical(object.runtimeType, runtimeType) && ((object as Element)).location == location;
   Element getAncestor(Type elementClass) {
     Element ancestor = _enclosingElement;
     while (ancestor != null && !isInstanceOf(ancestor, elementClass)) {
       ancestor = ancestor.enclosingElement;
     }
-    return (ancestor as Element);
+    return ancestor as Element;
   }
   /**
    * Return the child of this element that is uniquely identified by the given identifier, or{@code null} if there is no such child.
@@ -1480,9 +1997,9 @@
     return _enclosingElement.source;
   }
   int get hashCode => location.hashCode;
-  bool isAccessibleIn(LibraryElement library18) {
+  bool isAccessibleIn(LibraryElement library21) {
     if (Identifier.isPrivateName(_name)) {
-      return library18 == library;
+      return library21 == library;
     }
     return true;
   }
@@ -1502,21 +2019,23 @@
     setModifier(Modifier.SYNTHETIC, isSynthetic);
   }
   String toString() {
-    StringBuffer builder = new StringBuffer();
+    JavaStringBuilder builder = new JavaStringBuilder();
     appendTo(builder);
     return builder.toString();
   }
+  void visitChildren(ElementVisitor<Object> visitor) {
+  }
   /**
    * Append a textual representation of this type to the given builder.
    * @param builder the builder to which the text is to be appended
    */
-  void appendTo(StringBuffer builder) {
+  void appendTo(JavaStringBuilder builder) {
     if (_name == null) {
-      builder.add("<unnamed ");
-      builder.add(runtimeType.toString());
-      builder.add(">");
+      builder.append("<unnamed ");
+      builder.append(runtimeType.toString());
+      builder.append(">");
     } else {
-      builder.add(_name);
+      builder.append(_name);
     }
   }
   /**
@@ -1532,6 +2051,28 @@
    */
   bool hasModifier(Modifier modifier) => _modifiers.contains(modifier);
   /**
+   * If the given child is not {@code null}, use the given visitor to visit it.
+   * @param child the child to be visited
+   * @param visitor the visitor to be used to visit the child
+   */
+  void safelyVisitChild(Element child, ElementVisitor<Object> visitor) {
+    if (child != null) {
+      child.accept(visitor);
+    }
+  }
+  /**
+   * Use the given visitor to visit all of the children in the given array.
+   * @param children the children to be visited
+   * @param visitor the visitor being used to visit the children
+   */
+  void safelyVisitChildren(List<Element> children, ElementVisitor<Object> visitor) {
+    if (children != null) {
+      for (Element child in children) {
+        child.accept(visitor);
+      }
+    }
+  }
+  /**
    * Set the enclosing element of this element to the given element.
    * @param element the enclosing element of this element
    */
@@ -1554,6 +2095,7 @@
 }
 /**
  * Instances of the class {@code ElementLocationImpl} implement an {@link ElementLocation}.
+ * @coverage dart.engine.element
  */
 class ElementLocationImpl implements ElementLocation {
   /**
@@ -1569,9 +2111,9 @@
    * @param element the element whose location is being represented
    */
   ElementLocationImpl.con1(Element element) {
-    _jtd_constructor_137_impl(element);
+    _jtd_constructor_174_impl(element);
   }
-  _jtd_constructor_137_impl(Element element) {
+  _jtd_constructor_174_impl(Element element) {
     List<String> components = new List<String>();
     Element ancestor = element;
     while (ancestor != null) {
@@ -1585,16 +2127,16 @@
    * @param encoding the encoded form of a location
    */
   ElementLocationImpl.con2(String encoding) {
-    _jtd_constructor_138_impl(encoding);
+    _jtd_constructor_175_impl(encoding);
   }
-  _jtd_constructor_138_impl(String encoding) {
+  _jtd_constructor_175_impl(String encoding) {
     this._components = decode(encoding);
   }
   bool operator ==(Object object) {
     if (object is! ElementLocationImpl) {
       return false;
     }
-    ElementLocationImpl location = (object as ElementLocationImpl);
+    ElementLocationImpl location = object as ElementLocationImpl;
     return JavaArrays.equals(_components, location._components);
   }
   /**
@@ -1603,11 +2145,11 @@
    */
   List<String> get components => _components;
   String get encoding {
-    StringBuffer builder = new StringBuffer();
+    JavaStringBuilder builder = new JavaStringBuilder();
     int length2 = _components.length;
     for (int i = 0; i < length2; i++) {
       if (i > 0) {
-        builder.addCharCode(_SEPARATOR_CHAR);
+        builder.appendChar(_SEPARATOR_CHAR);
       }
       encode(builder, _components[i]);
     }
@@ -1622,22 +2164,22 @@
    */
   List<String> decode(String encoding) {
     List<String> components = new List<String>();
-    StringBuffer builder = new StringBuffer();
+    JavaStringBuilder builder = new JavaStringBuilder();
     int index = 0;
     int length3 = encoding.length;
     while (index < length3) {
       int currentChar = encoding.codeUnitAt(index);
       if (currentChar == _SEPARATOR_CHAR) {
         if (index + 1 < length3 && encoding.codeUnitAt(index + 1) == _SEPARATOR_CHAR) {
-          builder.addCharCode(_SEPARATOR_CHAR);
+          builder.appendChar(_SEPARATOR_CHAR);
           index += 2;
         } else {
           components.add(builder.toString());
-          builder.clear();
+          builder.length = 0;
           index++;
         }
       } else {
-        builder.addCharCode(currentChar);
+        builder.appendChar(currentChar);
         index++;
       }
     }
@@ -1651,25 +2193,56 @@
    * @param builder the builder to which the encoded component is to be appended
    * @param component the component to be appended to the builder
    */
-  void encode(StringBuffer builder, String component) {
+  void encode(JavaStringBuilder builder, String component) {
     int length4 = component.length;
     for (int i = 0; i < length4; i++) {
       int currentChar = component.codeUnitAt(i);
       if (currentChar == _SEPARATOR_CHAR) {
-        builder.addCharCode(_SEPARATOR_CHAR);
+        builder.appendChar(_SEPARATOR_CHAR);
       }
-      builder.addCharCode(currentChar);
+      builder.appendChar(currentChar);
     }
   }
 }
 /**
+ * Instances of the class {@code EmbeddedHtmlScriptElementImpl} implement an{@link EmbeddedHtmlScriptElement}.
+ * @coverage dart.engine.element
+ */
+class EmbeddedHtmlScriptElementImpl extends HtmlScriptElementImpl implements EmbeddedHtmlScriptElement {
+  /**
+   * The library defined by the script tag's content.
+   */
+  LibraryElement _scriptLibrary;
+  /**
+   * Initialize a newly created script element to have the specified tag name and offset.
+   * @param node the XML node from which this element is derived (not {@code null})
+   */
+  EmbeddedHtmlScriptElementImpl(XmlTagNode node) : super(node) {
+  }
+  accept(ElementVisitor visitor) => visitor.visitEmbeddedHtmlScriptElement(this);
+  ElementKind get kind => ElementKind.EMBEDDED_HTML_SCRIPT;
+  LibraryElement get scriptLibrary => _scriptLibrary;
+  /**
+   * Set the script library defined by the script tag's content.
+   * @param scriptLibrary the library or {@code null} if none
+   */
+  void set scriptLibrary(LibraryElementImpl scriptLibrary2) {
+    scriptLibrary2.enclosingElement = this;
+    this._scriptLibrary = scriptLibrary2;
+  }
+  void visitChildren(ElementVisitor<Object> visitor) {
+    safelyVisitChild(_scriptLibrary, visitor);
+  }
+}
+/**
  * The abstract class {@code ExecutableElementImpl} implements the behavior common to{@code ExecutableElement}s.
+ * @coverage dart.engine.element
  */
 abstract class ExecutableElementImpl extends ElementImpl implements ExecutableElement {
   /**
    * An array containing all of the functions defined within this executable element.
    */
-  List<ExecutableElement> _functions = EMPTY_ARRAY;
+  List<FunctionElement> _functions = FunctionElementImpl.EMPTY_ARRAY;
   /**
    * An array containing all of the labels defined within this executable element.
    */
@@ -1677,7 +2250,7 @@
   /**
    * An array containing all of the local variables defined within this executable element.
    */
-  List<VariableElement> _localVariables = VariableElementImpl.EMPTY_ARRAY;
+  List<LocalVariableElement> _localVariables = LocalVariableElementImpl.EMPTY_ARRAY;
   /**
    * An array containing all of the parameters defined by this executable element.
    */
@@ -1695,9 +2268,9 @@
    * @param name the name of this element
    */
   ExecutableElementImpl.con1(Identifier name) : super.con1(name) {
-    _jtd_constructor_139_impl(name);
+    _jtd_constructor_177_impl(name);
   }
-  _jtd_constructor_139_impl(Identifier name) {
+  _jtd_constructor_177_impl(Identifier name) {
   }
   /**
    * Initialize a newly created executable element to have the given name.
@@ -1706,45 +2279,45 @@
    * declaration of this element
    */
   ExecutableElementImpl.con2(String name, int nameOffset) : super.con2(name, nameOffset) {
-    _jtd_constructor_140_impl(name, nameOffset);
+    _jtd_constructor_178_impl(name, nameOffset);
   }
-  _jtd_constructor_140_impl(String name, int nameOffset) {
+  _jtd_constructor_178_impl(String name, int nameOffset) {
   }
-  ElementImpl getChild(String identifier21) {
+  ElementImpl getChild(String identifier27) {
     for (ExecutableElement function in _functions) {
-      if (((function as ExecutableElementImpl)).identifier == identifier21) {
-        return (function as ExecutableElementImpl);
+      if (((function as ExecutableElementImpl)).identifier == identifier27) {
+        return function as ExecutableElementImpl;
       }
     }
     for (LabelElement label in _labels) {
-      if (((label as LabelElementImpl)).identifier == identifier21) {
-        return (label as LabelElementImpl);
+      if (((label as LabelElementImpl)).identifier == identifier27) {
+        return label as LabelElementImpl;
       }
     }
     for (VariableElement variable in _localVariables) {
-      if (((variable as VariableElementImpl)).identifier == identifier21) {
-        return (variable as VariableElementImpl);
+      if (((variable as VariableElementImpl)).identifier == identifier27) {
+        return variable as VariableElementImpl;
       }
     }
     for (ParameterElement parameter in _parameters) {
-      if (((parameter as ParameterElementImpl)).identifier == identifier21) {
-        return (parameter as ParameterElementImpl);
+      if (((parameter as ParameterElementImpl)).identifier == identifier27) {
+        return parameter as ParameterElementImpl;
       }
     }
     return null;
   }
-  List<ExecutableElement> get functions => _functions;
+  List<FunctionElement> get functions => _functions;
   List<LabelElement> get labels => _labels;
-  List<VariableElement> get localVariables => _localVariables;
+  List<LocalVariableElement> get localVariables => _localVariables;
   List<ParameterElement> get parameters => _parameters;
   FunctionType get type => _type;
   /**
    * Set the functions defined within this executable element to the given functions.
    * @param functions the functions defined within this executable element
    */
-  void set functions(List<ExecutableElement> functions3) {
-    for (ExecutableElement function in functions3) {
-      ((function as ExecutableElementImpl)).enclosingElement = this;
+  void set functions(List<FunctionElement> functions3) {
+    for (FunctionElement function in functions3) {
+      ((function as FunctionElementImpl)).enclosingElement = this;
     }
     this._functions = functions3;
   }
@@ -1762,9 +2335,9 @@
    * Set the local variables defined within this executable element to the given variables.
    * @param localVariables the local variables defined within this executable element
    */
-  void set localVariables(List<VariableElement> localVariables2) {
-    for (VariableElement variable in localVariables2) {
-      ((variable as VariableElementImpl)).enclosingElement = this;
+  void set localVariables(List<LocalVariableElement> localVariables2) {
+    for (LocalVariableElement variable in localVariables2) {
+      ((variable as LocalVariableElementImpl)).enclosingElement = this;
     }
     this._localVariables = localVariables2;
   }
@@ -1782,27 +2355,35 @@
    * Set the type of function defined by this executable element to the given type.
    * @param type the type of function defined by this executable element
    */
-  void set type(FunctionType type6) {
-    this._type = type6;
+  void set type(FunctionType type7) {
+    this._type = type7;
   }
-  void appendTo(StringBuffer builder) {
-    builder.add("(");
+  void visitChildren(ElementVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChildren(_functions, visitor);
+    safelyVisitChildren(_labels, visitor);
+    safelyVisitChildren(_localVariables, visitor);
+    safelyVisitChildren(_parameters, visitor);
+  }
+  void appendTo(JavaStringBuilder builder) {
+    builder.append("(");
     int parameterCount = _parameters.length;
     for (int i = 0; i < parameterCount; i++) {
       if (i > 0) {
-        builder.add(", ");
+        builder.append(", ");
       }
       ((_parameters[i] as ParameterElementImpl)).appendTo(builder);
     }
-    builder.add(")");
+    builder.append(")");
     if (_type != null) {
-      builder.add(" -> ");
-      builder.add(_type.returnType);
+      builder.append(" -> ");
+      builder.append(_type.returnType);
     }
   }
 }
 /**
  * Instances of the class {@code ExportElementImpl} implement an {@link ExportElement}.
+ * @coverage dart.engine.element
  */
 class ExportElementImpl extends ElementImpl implements ExportElement {
   /**
@@ -1819,6 +2400,7 @@
    */
   ExportElementImpl() : super.con1(null) {
   }
+  accept(ElementVisitor visitor) => visitor.visitExportElement(this);
   List<NamespaceCombinator> get combinators => _combinators;
   LibraryElement get exportedLibrary => _exportedLibrary;
   ElementKind get kind => ElementKind.EXPORT;
@@ -1838,23 +2420,42 @@
   void set exportedLibrary(LibraryElement exportedLibrary2) {
     this._exportedLibrary = exportedLibrary2;
   }
-  void appendTo(StringBuffer builder) {
-    builder.add("export ");
+  void appendTo(JavaStringBuilder builder) {
+    builder.append("export ");
     ((_exportedLibrary as LibraryElementImpl)).appendTo(builder);
   }
 }
 /**
- * Instances of the class {@code FieldElementImpl} implement a {@code FieldElement}.
+ * Instances of the class {@code ExternalHtmlScriptElementImpl} implement an{@link ExternalHtmlScriptElement}.
+ * @coverage dart.engine.element
  */
-class FieldElementImpl extends VariableElementImpl implements FieldElement {
+class ExternalHtmlScriptElementImpl extends HtmlScriptElementImpl implements ExternalHtmlScriptElement {
   /**
-   * The getter associated with this field.
+   * The source specified in the {@code source} attribute or {@code null} if unspecified.
    */
-  PropertyAccessorElement _getter;
+  Source _scriptSource;
   /**
-   * The setter associated with this field, or {@code null} if the field is effectively{@code final} and therefore does not have a setter associated with it.
+   * Initialize a newly created script element to have the specified tag name and offset.
+   * @param node the XML node from which this element is derived (not {@code null})
    */
-  PropertyAccessorElement _setter;
+  ExternalHtmlScriptElementImpl(XmlTagNode node) : super(node) {
+  }
+  accept(ElementVisitor visitor) => visitor.visitExternalHtmlScriptElement(this);
+  ElementKind get kind => ElementKind.EXTERNAL_HTML_SCRIPT;
+  Source get scriptSource => _scriptSource;
+  /**
+   * Set the source specified in the {@code source} attribute.
+   * @param scriptSource the script source or {@code null} if unspecified
+   */
+  void set scriptSource(Source scriptSource2) {
+    this._scriptSource = scriptSource2;
+  }
+}
+/**
+ * Instances of the class {@code FieldElementImpl} implement a {@code FieldElement}.
+ * @coverage dart.engine.element
+ */
+class FieldElementImpl extends PropertyInducingElementImpl implements FieldElement {
   /**
    * An empty array of field elements.
    */
@@ -1864,39 +2465,24 @@
    * @param name the name of this element
    */
   FieldElementImpl.con1(Identifier name) : super.con1(name) {
-    _jtd_constructor_142_impl(name);
+    _jtd_constructor_181_impl(name);
   }
-  _jtd_constructor_142_impl(Identifier name) {
+  _jtd_constructor_181_impl(Identifier name) {
   }
   /**
    * Initialize a newly created synthetic field element to have the given name.
    * @param name the name of this element
    */
-  FieldElementImpl.con2(String name) : super.con2(name, -1) {
-    _jtd_constructor_143_impl(name);
+  FieldElementImpl.con2(String name) : super.con2(name) {
+    _jtd_constructor_182_impl(name);
   }
-  _jtd_constructor_143_impl(String name) {
-    synthetic = true;
+  _jtd_constructor_182_impl(String name) {
   }
-  PropertyAccessorElement get getter => _getter;
+  accept(ElementVisitor visitor) => visitor.visitFieldElement(this);
+  ClassElement get enclosingElement => super.enclosingElement as ClassElement;
   ElementKind get kind => ElementKind.FIELD;
-  PropertyAccessorElement get setter => _setter;
   bool isStatic() => hasModifier(Modifier.STATIC);
   /**
-   * Set the getter associated with this field to the given accessor.
-   * @param getter the getter associated with this field
-   */
-  void set getter(PropertyAccessorElement getter2) {
-    this._getter = getter2;
-  }
-  /**
-   * Set the setter associated with this field to the given accessor.
-   * @param setter the setter associated with this field
-   */
-  void set setter(PropertyAccessorElement setter2) {
-    this._setter = setter2;
-  }
-  /**
    * Set whether this field is static to correspond to the given value.
    * @param isStatic {@code true} if the field is static
    */
@@ -1906,6 +2492,7 @@
 }
 /**
  * Instances of the class {@code FunctionElementImpl} implement a {@code FunctionElement}.
+ * @coverage dart.engine.element
  */
 class FunctionElementImpl extends ExecutableElementImpl implements FunctionElement {
   /**
@@ -1925,9 +2512,9 @@
    * Initialize a newly created synthetic function element.
    */
   FunctionElementImpl() : super.con2("", -1) {
-    _jtd_constructor_144_impl();
+    _jtd_constructor_183_impl();
   }
-  _jtd_constructor_144_impl() {
+  _jtd_constructor_183_impl() {
     synthetic = true;
   }
   /**
@@ -1935,10 +2522,11 @@
    * @param name the name of this element
    */
   FunctionElementImpl.con1(Identifier name) : super.con1(name) {
-    _jtd_constructor_145_impl(name);
+    _jtd_constructor_184_impl(name);
   }
-  _jtd_constructor_145_impl(Identifier name) {
+  _jtd_constructor_184_impl(Identifier name) {
   }
+  accept(ElementVisitor visitor) => visitor.visitFunctionElement(this);
   String get identifier => name;
   ElementKind get kind => ElementKind.FUNCTION;
   SourceRange get visibleRange {
@@ -1947,6 +2535,7 @@
     }
     return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
   }
+  bool isStatic() => enclosingElement is CompilationUnitElement;
   /**
    * Set the visible range for this element to the range starting at the given offset with the given
    * length.
@@ -1958,16 +2547,126 @@
     _visibleRangeOffset = offset;
     _visibleRangeLength = length;
   }
-  void appendTo(StringBuffer builder) {
+  void appendTo(JavaStringBuilder builder) {
     String name13 = name;
     if (name13 != null) {
-      builder.add(name13);
+      builder.append(name13);
     }
     super.appendTo(builder);
   }
 }
 /**
+ * Instances of the class {@code FunctionTypeAliasElementImpl} implement a{@code FunctionTypeAliasElement}.
+ * @coverage dart.engine.element
+ */
+class FunctionTypeAliasElementImpl extends ElementImpl implements FunctionTypeAliasElement {
+  /**
+   * An array containing all of the parameters defined by this type alias.
+   */
+  List<ParameterElement> _parameters = ParameterElementImpl.EMPTY_ARRAY;
+  /**
+   * The type of function defined by this type alias.
+   */
+  FunctionType _type;
+  /**
+   * An array containing all of the type variables defined for this type.
+   */
+  List<TypeVariableElement> _typeVariables = TypeVariableElementImpl.EMPTY_ARRAY;
+  /**
+   * An empty array of type alias elements.
+   */
+  static List<FunctionTypeAliasElement> EMPTY_ARRAY = new List<FunctionTypeAliasElement>(0);
+  /**
+   * Initialize a newly created type alias element to have the given name.
+   * @param name the name of this element
+   */
+  FunctionTypeAliasElementImpl(Identifier name) : super.con1(name) {
+  }
+  accept(ElementVisitor visitor) => visitor.visitFunctionTypeAliasElement(this);
+  ElementImpl getChild(String identifier28) {
+    for (VariableElement parameter in _parameters) {
+      if (((parameter as VariableElementImpl)).identifier == identifier28) {
+        return parameter as VariableElementImpl;
+      }
+    }
+    for (TypeVariableElement typeVariable in _typeVariables) {
+      if (((typeVariable as TypeVariableElementImpl)).identifier == identifier28) {
+        return typeVariable as TypeVariableElementImpl;
+      }
+    }
+    return null;
+  }
+  CompilationUnitElement get enclosingElement => super.enclosingElement as CompilationUnitElement;
+  ElementKind get kind => ElementKind.FUNCTION_TYPE_ALIAS;
+  List<ParameterElement> get parameters => _parameters;
+  FunctionType get type => _type;
+  List<TypeVariableElement> get typeVariables => _typeVariables;
+  /**
+   * Set the parameters defined by this type alias to the given parameters.
+   * @param parameters the parameters defined by this type alias
+   */
+  void set parameters(List<ParameterElement> parameters8) {
+    if (parameters8 != null) {
+      for (ParameterElement parameter in parameters8) {
+        ((parameter as ParameterElementImpl)).enclosingElement = this;
+      }
+    }
+    this._parameters = parameters8;
+  }
+  /**
+   * Set the type of function defined by this type alias to the given type.
+   * @param type the type of function defined by this type alias
+   */
+  void set type(FunctionType type8) {
+    this._type = type8;
+  }
+  /**
+   * Set the type variables defined for this type to the given variables.
+   * @param typeVariables the type variables defined for this type
+   */
+  void set typeVariables(List<TypeVariableElement> typeVariables3) {
+    for (TypeVariableElement variable in typeVariables3) {
+      ((variable as TypeVariableElementImpl)).enclosingElement = this;
+    }
+    this._typeVariables = typeVariables3;
+  }
+  void visitChildren(ElementVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChildren(_parameters, visitor);
+    safelyVisitChildren(_typeVariables, visitor);
+  }
+  void appendTo(JavaStringBuilder builder) {
+    builder.append("typedef ");
+    builder.append(name);
+    int variableCount = _typeVariables.length;
+    if (variableCount > 0) {
+      builder.append("<");
+      for (int i = 0; i < variableCount; i++) {
+        if (i > 0) {
+          builder.append(", ");
+        }
+        ((_typeVariables[i] as TypeVariableElementImpl)).appendTo(builder);
+      }
+      builder.append(">");
+    }
+    builder.append("(");
+    int parameterCount = _parameters.length;
+    for (int i = 0; i < parameterCount; i++) {
+      if (i > 0) {
+        builder.append(", ");
+      }
+      ((_parameters[i] as ParameterElementImpl)).appendTo(builder);
+    }
+    builder.append(")");
+    if (_type != null) {
+      builder.append(" -> ");
+      builder.append(_type.returnType);
+    }
+  }
+}
+/**
  * Instances of the class {@code ShowCombinatorImpl} implement a {@link ShowCombinator}.
+ * @coverage dart.engine.element
  */
 class HideCombinatorImpl implements HideCombinator {
   /**
@@ -1990,20 +2689,21 @@
     this._hiddenNames = hiddenNames2;
   }
   String toString() {
-    StringBuffer builder = new StringBuffer();
-    builder.add("show ");
+    JavaStringBuilder builder = new JavaStringBuilder();
+    builder.append("show ");
     int count = _hiddenNames.length;
     for (int i = 0; i < count; i++) {
       if (i > 0) {
-        builder.add(", ");
+        builder.append(", ");
       }
-      builder.add(_hiddenNames[i]);
+      builder.append(_hiddenNames[i]);
     }
     return builder.toString();
   }
 }
 /**
  * Instances of the class {@code HtmlElementImpl} implement an {@link HtmlElement}.
+ * @coverage dart.engine.element
  */
 class HtmlElementImpl extends ElementImpl implements HtmlElement {
   /**
@@ -2015,9 +2715,9 @@
    */
   AnalysisContext _context;
   /**
-   * The libraries contained in or referenced from script tags in the HTML file.
+   * The scripts contained in or referenced from script tags in the HTML file.
    */
-  List<LibraryElement> _libraries = LibraryElementImpl.EMPTY_ARRAY;
+  List<HtmlScriptElement> _scripts = HtmlScriptElementImpl.EMPTY_ARRAY;
   /**
    * The source that corresponds to this HTML file.
    */
@@ -2030,19 +2730,22 @@
   HtmlElementImpl(AnalysisContext context, String name) : super.con2(name, -1) {
     this._context = context;
   }
-  bool operator ==(Object object) => identical(this.runtimeType, object.runtimeType) && _source == ((object as CompilationUnitElementImpl)).source;
+  accept(ElementVisitor visitor) => visitor.visitHtmlElement(this);
+  bool operator ==(Object object) => identical(runtimeType, object.runtimeType) && _source == ((object as CompilationUnitElementImpl)).source;
   AnalysisContext get context => _context;
   ElementKind get kind => ElementKind.HTML;
-  List<LibraryElement> get libraries => _libraries;
+  List<HtmlScriptElement> get scripts => _scripts;
   Source get source => _source;
   int get hashCode => _source.hashCode;
   /**
-   * Set the libraries contained in or referenced from script tags in the HTML file to the given
-   * libraries.
-   * @param libraries the libraries contained in or referenced from script tags in the HTML file
+   * Set the scripts contained in the HTML file to the given scripts.
+   * @param scripts the scripts
    */
-  void set libraries(List<LibraryElement> libraries2) {
-    this._libraries = libraries2;
+  void set scripts(List<HtmlScriptElement> scripts2) {
+    for (HtmlScriptElement script in scripts2) {
+      ((script as HtmlScriptElementImpl)).enclosingElement = this;
+    }
+    this._scripts = scripts2;
   }
   /**
    * Set the source that corresponds to this HTML file to the given source.
@@ -2051,16 +2754,37 @@
   void set source(Source source6) {
     this._source = source6;
   }
-  void appendTo(StringBuffer builder) {
+  void visitChildren(ElementVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChildren(_scripts, visitor);
+  }
+  void appendTo(JavaStringBuilder builder) {
     if (_source == null) {
-      builder.add("{HTML file}");
+      builder.append("{HTML file}");
     } else {
-      builder.add(_source.fullName);
+      builder.append(_source.fullName);
     }
   }
 }
 /**
+ * Instances of the class {@code HtmlScriptElementImpl} implement an {@link HtmlScriptElement}.
+ * @coverage dart.engine.element
+ */
+abstract class HtmlScriptElementImpl extends ElementImpl implements HtmlScriptElement {
+  /**
+   * An empty array of HTML script elements.
+   */
+  static List<HtmlScriptElement> EMPTY_ARRAY = new List<HtmlScriptElement>(0);
+  /**
+   * Initialize a newly created script element to have the specified tag name and offset.
+   * @param node the XML node from which this element is derived (not {@code null})
+   */
+  HtmlScriptElementImpl(XmlTagNode node) : super.con2(node.tag.lexeme, node.tag.offset) {
+  }
+}
+/**
  * Instances of the class {@code ImportElementImpl} implement an {@link ImportElement}.
+ * @coverage dart.engine.element
  */
 class ImportElementImpl extends ElementImpl implements ImportElement {
   /**
@@ -2082,6 +2806,7 @@
    */
   ImportElementImpl() : super.con1(null) {
   }
+  accept(ElementVisitor visitor) => visitor.visitImportElement(this);
   List<NamespaceCombinator> get combinators => _combinators;
   LibraryElement get importedLibrary => _importedLibrary;
   ElementKind get kind => ElementKind.IMPORT;
@@ -2109,13 +2834,18 @@
   void set prefix(PrefixElement prefix3) {
     this._prefix = prefix3;
   }
-  void appendTo(StringBuffer builder) {
-    builder.add("import ");
+  void visitChildren(ElementVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(_prefix, visitor);
+  }
+  void appendTo(JavaStringBuilder builder) {
+    builder.append("import ");
     ((_importedLibrary as LibraryElementImpl)).appendTo(builder);
   }
 }
 /**
  * Instances of the class {@code LabelElementImpl} implement a {@code LabelElement}.
+ * @coverage dart.engine.element
  */
 class LabelElementImpl extends ElementImpl implements LabelElement {
   /**
@@ -2140,7 +2870,8 @@
     this._onSwitchStatement = onSwitchStatement;
     this._onSwitchMember = onSwitchMember;
   }
-  ExecutableElement get enclosingElement => (super.enclosingElement as ExecutableElement);
+  accept(ElementVisitor visitor) => visitor.visitLabelElement(this);
+  ExecutableElement get enclosingElement => super.enclosingElement as ExecutableElement;
   ElementKind get kind => ElementKind.LABEL;
   /**
    * Return {@code true} if this label is associated with a {@code switch} member ({@code case} or{@code default}).
@@ -2155,6 +2886,7 @@
 }
 /**
  * Instances of the class {@code LibraryElementImpl} implement a {@code LibraryElement}.
+ * @coverage dart.engine.element
  */
 class LibraryElementImpl extends ElementImpl implements LibraryElement {
   /**
@@ -2162,6 +2894,36 @@
    */
   static List<LibraryElement> EMPTY_ARRAY = new List<LibraryElement>(0);
   /**
+   * Determine if the given library is up to date with respect to the given time stamp.
+   * @param library the library to process
+   * @param timeStamp the time stamp to check against
+   * @param visitedLibraries the set of visited libraries
+   */
+  static bool isUpToDate(LibraryElement library, int timeStamp, Set<LibraryElement> visitedLibraries) {
+    if (!visitedLibraries.contains(library)) {
+      javaSetAdd(visitedLibraries, library);
+      if (timeStamp < library.definingCompilationUnit.source.modificationStamp) {
+        return false;
+      }
+      for (CompilationUnitElement element in library.parts) {
+        if (timeStamp < element.source.modificationStamp) {
+          return false;
+        }
+      }
+      for (LibraryElement importedLibrary in library.importedLibraries) {
+        if (!isUpToDate(importedLibrary, timeStamp, visitedLibraries)) {
+          return false;
+        }
+      }
+      for (LibraryElement exportedLibrary in library.exportedLibraries) {
+        if (!isUpToDate(exportedLibrary, timeStamp, visitedLibraries)) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+  /**
    * The analysis context in which this library is defined.
    */
   AnalysisContext _context;
@@ -2193,14 +2955,15 @@
   LibraryElementImpl(AnalysisContext context, LibraryIdentifier name) : super.con1(name) {
     this._context = context;
   }
-  bool operator ==(Object object) => identical(this.runtimeType, object.runtimeType) && _definingCompilationUnit == ((object as LibraryElementImpl)).definingCompilationUnit;
-  ElementImpl getChild(String identifier22) {
-    if (((_definingCompilationUnit as CompilationUnitElementImpl)).identifier == identifier22) {
-      return (_definingCompilationUnit as CompilationUnitElementImpl);
+  accept(ElementVisitor visitor) => visitor.visitLibraryElement(this);
+  bool operator ==(Object object) => object != null && identical(runtimeType, object.runtimeType) && _definingCompilationUnit == ((object as LibraryElementImpl)).definingCompilationUnit;
+  ElementImpl getChild(String identifier29) {
+    if (((_definingCompilationUnit as CompilationUnitElementImpl)).identifier == identifier29) {
+      return _definingCompilationUnit as CompilationUnitElementImpl;
     }
     for (CompilationUnitElement part in _parts) {
-      if (((part as CompilationUnitElementImpl)).identifier == identifier22) {
-        return (part as CompilationUnitElementImpl);
+      if (((part as CompilationUnitElementImpl)).identifier == identifier29) {
+        return part as CompilationUnitElementImpl;
       }
     }
     return null;
@@ -2241,6 +3004,11 @@
   }
   int get hashCode => _definingCompilationUnit.hashCode;
   bool isBrowserApplication() => _entryPoint != null && isOrImportsBrowserLibrary();
+  bool isDartCore() => name == "dart.core";
+  bool isUpToDate2(int timeStamp) {
+    Set<LibraryElement> visitedLibraries = new Set();
+    return isUpToDate(this, timeStamp, visitedLibraries);
+  }
   /**
    * Set the compilation unit that defines this library to the given compilation unit.
    * @param definingCompilationUnit the compilation unit that defines this library
@@ -2254,7 +3022,6 @@
    * @param entryPoint the entry point for this library
    */
   void set entryPoint(FunctionElement entryPoint2) {
-    ((entryPoint2 as FunctionElementImpl)).enclosingElement = this;
     this._entryPoint = entryPoint2;
   }
   /**
@@ -2262,6 +3029,9 @@
    * @param exports the specifications of all of the exports defined in this library
    */
   void set exports(List<ExportElement> exports2) {
+    for (ExportElement exportElement in exports2) {
+      ((exportElement as ExportElementImpl)).enclosingElement = this;
+    }
     this._exports = exports2;
   }
   /**
@@ -2269,6 +3039,13 @@
    * @param imports the specifications of all of the imports defined in this library
    */
   void set imports(List<ImportElement> imports2) {
+    for (ImportElement importElement in imports2) {
+      ((importElement as ImportElementImpl)).enclosingElement = this;
+      PrefixElementImpl prefix5 = importElement.prefix as PrefixElementImpl;
+      if (prefix5 != null) {
+        prefix5.enclosingElement = this;
+      }
+    }
     this._imports = imports2;
   }
   /**
@@ -2281,18 +3058,25 @@
     }
     this._parts = parts2;
   }
+  void visitChildren(ElementVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(_definingCompilationUnit, visitor);
+    safelyVisitChildren(_exports, visitor);
+    safelyVisitChildren(_imports, visitor);
+    safelyVisitChildren(_parts, visitor);
+  }
   /**
    * Answer {@code true} if the receiver directly or indirectly imports the dart:html libraries.
    * @return {@code true} if the receiver directly or indirectly imports the dart:html libraries
    */
   bool isOrImportsBrowserLibrary() {
-    List<LibraryElement> visited = new List<LibraryElement>(10);
-    Source htmlLibSource = definingCompilationUnit.source.resolve(DartSdk.DART_HTML);
+    List<LibraryElement> visited = new List<LibraryElement>();
+    Source htmlLibSource = definingCompilationUnit.source.resolve("dart:html");
     visited.add(this);
     for (int index = 0; index < visited.length; index++) {
       LibraryElement library = visited[index];
-      Source source8 = library.definingCompilationUnit.source;
-      if (source8 == htmlLibSource) {
+      Source source10 = library.definingCompilationUnit.source;
+      if (source10 == htmlLibSource) {
         return true;
       }
       for (LibraryElement importedLibrary in library.importedLibraries) {
@@ -2310,7 +3094,57 @@
   }
 }
 /**
+ * Instances of the class {@code LocalVariableElementImpl} implement a {@code LocalVariableElement}.
+ * @coverage dart.engine.element
+ */
+class LocalVariableElementImpl extends VariableElementImpl implements LocalVariableElement {
+  /**
+   * The offset to the beginning of the visible range for this element.
+   */
+  int _visibleRangeOffset = 0;
+  /**
+   * The length of the visible range for this element, or {@code -1} if this element does not have a
+   * visible range.
+   */
+  int _visibleRangeLength = -1;
+  /**
+   * An empty array of field elements.
+   */
+  static List<LocalVariableElement> EMPTY_ARRAY = new List<LocalVariableElement>(0);
+  /**
+   * Initialize a newly created local variable element to have the given name.
+   * @param name the name of this element
+   */
+  LocalVariableElementImpl(Identifier name) : super.con1(name) {
+  }
+  accept(ElementVisitor visitor) => visitor.visitLocalVariableElement(this);
+  ElementKind get kind => ElementKind.LOCAL_VARIABLE;
+  SourceRange get visibleRange {
+    if (_visibleRangeLength < 0) {
+      return null;
+    }
+    return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
+  }
+  /**
+   * Set the visible range for this element to the range starting at the given offset with the given
+   * length.
+   * @param offset the offset to the beginning of the visible range for this element
+   * @param length the length of the visible range for this element, or {@code -1} if this element
+   * does not have a visible range
+   */
+  void setVisibleRange(int offset, int length) {
+    _visibleRangeOffset = offset;
+    _visibleRangeLength = length;
+  }
+  void appendTo(JavaStringBuilder builder) {
+    builder.append(type);
+    builder.append(" ");
+    builder.append(name);
+  }
+}
+/**
  * Instances of the class {@code MethodElementImpl} implement a {@code MethodElement}.
+ * @coverage dart.engine.element
  */
 class MethodElementImpl extends ExecutableElementImpl implements MethodElement {
   /**
@@ -2322,9 +3156,9 @@
    * @param name the name of this element
    */
   MethodElementImpl.con1(Identifier name) : super.con1(name) {
-    _jtd_constructor_151_impl(name);
+    _jtd_constructor_193_impl(name);
   }
-  _jtd_constructor_151_impl(Identifier name) {
+  _jtd_constructor_193_impl(Identifier name) {
   }
   /**
    * Initialize a newly created method element to have the given name.
@@ -2333,11 +3167,12 @@
    * declaration of this element
    */
   MethodElementImpl.con2(String name, int nameOffset) : super.con2(name, nameOffset) {
-    _jtd_constructor_152_impl(name, nameOffset);
+    _jtd_constructor_194_impl(name, nameOffset);
   }
-  _jtd_constructor_152_impl(String name, int nameOffset) {
+  _jtd_constructor_194_impl(String name, int nameOffset) {
   }
-  ClassElement get enclosingElement => (super.enclosingElement as ClassElement);
+  accept(ElementVisitor visitor) => visitor.visitMethodElement(this);
+  ClassElement get enclosingElement => super.enclosingElement as ClassElement;
   ElementKind get kind => ElementKind.METHOD;
   bool isAbstract() => hasModifier(Modifier.ABSTRACT);
   bool isStatic() => hasModifier(Modifier.STATIC);
@@ -2355,16 +3190,17 @@
   void set static(bool isStatic) {
     setModifier(Modifier.STATIC, isStatic);
   }
-  void appendTo(StringBuffer builder) {
-    builder.add(enclosingElement.name);
-    builder.add(".");
-    builder.add(name);
+  void appendTo(JavaStringBuilder builder) {
+    builder.append(enclosingElement.name);
+    builder.append(".");
+    builder.append(name);
     super.appendTo(builder);
   }
 }
 /**
  * The enumeration {@code Modifier} defines constants for all of the modifiers defined by the Dart
  * language and for a few additional flags that are useful.
+ * @coverage dart.engine.element
  */
 class Modifier {
   static final Modifier ABSTRACT = new Modifier('ABSTRACT', 0);
@@ -2373,12 +3209,15 @@
   static final Modifier FINAL = new Modifier('FINAL', 3);
   static final Modifier GETTER = new Modifier('GETTER', 4);
   static final Modifier INITIALIZING_FORMAL = new Modifier('INITIALIZING_FORMAL', 5);
-  static final Modifier SETTER = new Modifier('SETTER', 6);
-  static final Modifier STATIC = new Modifier('STATIC', 7);
-  static final Modifier SYNTHETIC = new Modifier('SYNTHETIC', 8);
-  static final List<Modifier> values = [ABSTRACT, CONST, FACTORY, FINAL, GETTER, INITIALIZING_FORMAL, SETTER, STATIC, SYNTHETIC];
+  static final Modifier MIXIN = new Modifier('MIXIN', 6);
+  static final Modifier SETTER = new Modifier('SETTER', 7);
+  static final Modifier STATIC = new Modifier('STATIC', 8);
+  static final Modifier SYNTHETIC = new Modifier('SYNTHETIC', 9);
+  static final Modifier TYPEDEF = new Modifier('TYPEDEF', 10);
+  static final List<Modifier> values = [ABSTRACT, CONST, FACTORY, FINAL, GETTER, INITIALIZING_FORMAL, MIXIN, SETTER, STATIC, SYNTHETIC, TYPEDEF];
   final String __name;
   final int __ordinal;
+  int get ordinal => __ordinal;
   Modifier(this.__name, this.__ordinal) {
   }
   String toString() => __name;
@@ -2386,6 +3225,7 @@
 /**
  * Instances of the class {@code MultiplyDefinedElementImpl} represent a collection of elements that
  * have the same name within the same scope.
+ * @coverage dart.engine.element
  */
 class MultiplyDefinedElementImpl implements MultiplyDefinedElement {
   /**
@@ -2410,6 +3250,7 @@
     _name = firstElement.name;
     _conflictingElements = computeConflictingElements(firstElement, secondElement);
   }
+  accept(ElementVisitor visitor) => visitor.visitMultiplyDefinedElement(this);
   Element getAncestor(Type elementClass) => null;
   List<Element> get conflictingElements => _conflictingElements;
   AnalysisContext get context => _context;
@@ -2431,18 +3272,20 @@
   }
   bool isSynthetic() => true;
   String toString() {
-    StringBuffer builder = new StringBuffer();
-    builder.add("[");
+    JavaStringBuilder builder = new JavaStringBuilder();
+    builder.append("[");
     int count = _conflictingElements.length;
     for (int i = 0; i < count; i++) {
       if (i > 0) {
-        builder.add(", ");
+        builder.append(", ");
       }
       ((_conflictingElements[i] as ElementImpl)).appendTo(builder);
     }
-    builder.add("]");
+    builder.append("]");
     return builder.toString();
   }
+  void visitChildren(ElementVisitor<Object> visitor) {
+  }
   /**
    * Add the given element to the list of elements. If the element is a multiply-defined element,
    * add all of the conflicting elements that it represents.
@@ -2475,6 +3318,7 @@
 }
 /**
  * Instances of the class {@code ParameterElementImpl} implement a {@code ParameterElement}.
+ * @coverage dart.engine.element
  */
 class ParameterElementImpl extends VariableElementImpl implements ParameterElement {
   /**
@@ -2482,6 +3326,15 @@
    */
   ParameterKind _parameterKind;
   /**
+   * The offset to the beginning of the visible range for this element.
+   */
+  int _visibleRangeOffset = 0;
+  /**
+   * The length of the visible range for this element, or {@code -1} if this element does not have a
+   * visible range.
+   */
+  int _visibleRangeLength = -1;
+  /**
    * An empty array of field elements.
    */
   static List<ParameterElement> EMPTY_ARRAY = new List<ParameterElement>(0);
@@ -2491,8 +3344,15 @@
    */
   ParameterElementImpl(Identifier name) : super.con1(name) {
   }
+  accept(ElementVisitor visitor) => visitor.visitParameterElement(this);
   ElementKind get kind => ElementKind.PARAMETER;
   ParameterKind get parameterKind => _parameterKind;
+  SourceRange get visibleRange {
+    if (_visibleRangeLength < 0) {
+      return null;
+    }
+    return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
+  }
   bool isInitializingFormal() => hasModifier(Modifier.INITIALIZING_FORMAL);
   /**
    * Set whether this parameter is an initializing formal parameter to match the given value.
@@ -2508,17 +3368,29 @@
   void set parameterKind(ParameterKind parameterKind2) {
     this._parameterKind = parameterKind2;
   }
-  void appendTo(StringBuffer builder) {
-    builder.add(type);
-    builder.add(" ");
-    builder.add(name);
-    builder.add(" (");
-    builder.add(kind);
-    builder.add(")");
+  /**
+   * Set the visible range for this element to the range starting at the given offset with the given
+   * length.
+   * @param offset the offset to the beginning of the visible range for this element
+   * @param length the length of the visible range for this element, or {@code -1} if this element
+   * does not have a visible range
+   */
+  void setVisibleRange(int offset, int length) {
+    _visibleRangeOffset = offset;
+    _visibleRangeLength = length;
+  }
+  void appendTo(JavaStringBuilder builder) {
+    builder.append(type);
+    builder.append(" ");
+    builder.append(name);
+    builder.append(" (");
+    builder.append(kind);
+    builder.append(")");
   }
 }
 /**
  * Instances of the class {@code PrefixElementImpl} implement a {@code PrefixElement}.
+ * @coverage dart.engine.element
  */
 class PrefixElementImpl extends ElementImpl implements PrefixElement {
   /**
@@ -2535,7 +3407,8 @@
    */
   PrefixElementImpl(Identifier name) : super.con1(name) {
   }
-  LibraryElement get enclosingElement => (super.enclosingElement as LibraryElement);
+  accept(ElementVisitor visitor) => visitor.visitPrefixElement(this);
+  LibraryElement get enclosingElement => super.enclosingElement as LibraryElement;
   List<LibraryElement> get importedLibraries => _importedLibraries;
   ElementKind get kind => ElementKind.PREFIX;
   /**
@@ -2548,60 +3421,57 @@
     }
     this._importedLibraries = importedLibraries2;
   }
-  void appendTo(StringBuffer builder) {
-    builder.add("as ");
+  void appendTo(JavaStringBuilder builder) {
+    builder.append("as ");
     super.appendTo(builder);
   }
 }
 /**
  * Instances of the class {@code PropertyAccessorElementImpl} implement a{@code PropertyAccessorElement}.
+ * @coverage dart.engine.element
  */
 class PropertyAccessorElementImpl extends ExecutableElementImpl implements PropertyAccessorElement {
   /**
-   * The field associated with this accessor.
+   * The variable associated with this accessor.
    */
-  FieldElement _field;
+  PropertyInducingElement _variable;
   /**
    * An empty array of property accessor elements.
    */
   static List<PropertyAccessorElement> EMPTY_ARRAY = new List<PropertyAccessorElement>(0);
   /**
-   * Initialize a newly created synthetic property accessor element to be associated with the given
-   * field.
-   * @param name the name of this element
-   */
-  PropertyAccessorElementImpl.con1(FieldElementImpl field2) : super.con2(field2.name, -1) {
-    _jtd_constructor_157_impl(field2);
-  }
-  _jtd_constructor_157_impl(FieldElementImpl field2) {
-    this._field = field2;
-    synthetic = true;
-  }
-  /**
    * Initialize a newly created property accessor element to have the given name.
    * @param name the name of this element
    */
-  PropertyAccessorElementImpl.con2(Identifier name) : super.con1(name) {
-    _jtd_constructor_158_impl(name);
+  PropertyAccessorElementImpl.con1(Identifier name) : super.con1(name) {
+    _jtd_constructor_199_impl(name);
   }
-  _jtd_constructor_158_impl(Identifier name) {
+  _jtd_constructor_199_impl(Identifier name) {
   }
-  FieldElement get field => _field;
+  /**
+   * Initialize a newly created synthetic property accessor element to be associated with the given
+   * variable.
+   * @param variable the variable with which this access is associated
+   */
+  PropertyAccessorElementImpl.con2(PropertyInducingElementImpl variable2) : super.con2(variable2.name, -1) {
+    _jtd_constructor_200_impl(variable2);
+  }
+  _jtd_constructor_200_impl(PropertyInducingElementImpl variable2) {
+    this._variable = variable2;
+    synthetic = true;
+  }
+  accept(ElementVisitor visitor) => visitor.visitPropertyAccessorElement(this);
+  bool operator ==(Object object) => super == object && identical(isGetter(), ((object as PropertyAccessorElement)).isGetter());
   ElementKind get kind {
     if (isGetter()) {
       return ElementKind.GETTER;
     }
     return ElementKind.SETTER;
   }
+  PropertyInducingElement get variable => _variable;
   bool isGetter() => hasModifier(Modifier.GETTER);
   bool isSetter() => hasModifier(Modifier.SETTER);
-  /**
-   * Set the field associated with this accessor to the given field.
-   * @param field the field associated with this accessor
-   */
-  void set field(FieldElement field3) {
-    this._field = field3;
-  }
+  bool isStatic() => variable.isStatic();
   /**
    * Set whether this accessor is a getter to correspond to the given value.
    * @param isGetter {@code true} if the accessor is a getter
@@ -2616,14 +3486,75 @@
   void set setter(bool isSetter) {
     setModifier(Modifier.SETTER, isSetter);
   }
-  void appendTo(StringBuffer builder) {
-    builder.add(isGetter() ? "get " : "set ");
-    builder.add(field.name);
+  /**
+   * Set the variable associated with this accessor to the given variable.
+   * @param variable the variable associated with this accessor
+   */
+  void set variable(PropertyInducingElement variable3) {
+    this._variable = variable3;
+  }
+  void appendTo(JavaStringBuilder builder) {
+    builder.append(isGetter() ? "get " : "set ");
+    builder.append(variable.name);
     super.appendTo(builder);
   }
 }
 /**
+ * Instances of the class {@code PropertyInducingElementImpl} implement a{@code PropertyInducingElement}.
+ * @coverage dart.engine.element
+ */
+abstract class PropertyInducingElementImpl extends VariableElementImpl implements PropertyInducingElement {
+  /**
+   * The getter associated with this element.
+   */
+  PropertyAccessorElement _getter;
+  /**
+   * The setter associated with this element, or {@code null} if the element is effectively{@code final} and therefore does not have a setter associated with it.
+   */
+  PropertyAccessorElement _setter;
+  /**
+   * An empty array of elements.
+   */
+  static List<PropertyInducingElement> EMPTY_ARRAY = new List<PropertyInducingElement>(0);
+  /**
+   * Initialize a newly created element to have the given name.
+   * @param name the name of this element
+   */
+  PropertyInducingElementImpl.con1(Identifier name) : super.con1(name) {
+    _jtd_constructor_201_impl(name);
+  }
+  _jtd_constructor_201_impl(Identifier name) {
+  }
+  /**
+   * Initialize a newly created synthetic element to have the given name.
+   * @param name the name of this element
+   */
+  PropertyInducingElementImpl.con2(String name) : super.con2(name, -1) {
+    _jtd_constructor_202_impl(name);
+  }
+  _jtd_constructor_202_impl(String name) {
+    synthetic = true;
+  }
+  PropertyAccessorElement get getter => _getter;
+  PropertyAccessorElement get setter => _setter;
+  /**
+   * Set the getter associated with this element to the given accessor.
+   * @param getter the getter associated with this element
+   */
+  void set getter(PropertyAccessorElement getter2) {
+    this._getter = getter2;
+  }
+  /**
+   * Set the setter associated with this element to the given accessor.
+   * @param setter the setter associated with this element
+   */
+  void set setter(PropertyAccessorElement setter2) {
+    this._setter = setter2;
+  }
+}
+/**
  * Instances of the class {@code ShowCombinatorImpl} implement a {@link ShowCombinator}.
+ * @coverage dart.engine.element
  */
 class ShowCombinatorImpl implements ShowCombinator {
   /**
@@ -2646,122 +3577,52 @@
     this._shownNames = shownNames2;
   }
   String toString() {
-    StringBuffer builder = new StringBuffer();
-    builder.add("show ");
+    JavaStringBuilder builder = new JavaStringBuilder();
+    builder.append("show ");
     int count = _shownNames.length;
     for (int i = 0; i < count; i++) {
       if (i > 0) {
-        builder.add(", ");
+        builder.append(", ");
       }
-      builder.add(_shownNames[i]);
+      builder.append(_shownNames[i]);
     }
     return builder.toString();
   }
 }
 /**
- * Instances of the class {@code TypeAliasElementImpl} implement a {@code TypeAliasElement}.
+ * Instances of the class {@code TopLevelVariableElementImpl} implement a{@code TopLevelVariableElement}.
+ * @coverage dart.engine.element
  */
-class TypeAliasElementImpl extends ElementImpl implements TypeAliasElement {
+class TopLevelVariableElementImpl extends PropertyInducingElementImpl implements TopLevelVariableElement {
   /**
-   * An array containing all of the parameters defined by this type alias.
+   * An empty array of top-level variable elements.
    */
-  List<ParameterElement> _parameters = ParameterElementImpl.EMPTY_ARRAY;
+  static List<TopLevelVariableElement> EMPTY_ARRAY = new List<TopLevelVariableElement>(0);
   /**
-   * The type of function defined by this type alias.
-   */
-  FunctionType _type;
-  /**
-   * An array containing all of the type variables defined for this type.
-   */
-  List<TypeVariableElement> _typeVariables = TypeVariableElementImpl.EMPTY_ARRAY;
-  /**
-   * An empty array of type alias elements.
-   */
-  static List<TypeAliasElement> EMPTY_ARRAY = new List<TypeAliasElement>(0);
-  /**
-   * Initialize a newly created type alias element to have the given name.
+   * Initialize a newly created top-level variable element to have the given name.
    * @param name the name of this element
    */
-  TypeAliasElementImpl(Identifier name) : super.con1(name) {
+  TopLevelVariableElementImpl.con1(Identifier name) : super.con1(name) {
+    _jtd_constructor_204_impl(name);
   }
-  ElementImpl getChild(String identifier23) {
-    for (VariableElement parameter in _parameters) {
-      if (((parameter as VariableElementImpl)).identifier == identifier23) {
-        return (parameter as VariableElementImpl);
-      }
-    }
-    for (TypeVariableElement typeVariable in _typeVariables) {
-      if (((typeVariable as TypeVariableElementImpl)).identifier == identifier23) {
-        return (typeVariable as TypeVariableElementImpl);
-      }
-    }
-    return null;
-  }
-  CompilationUnitElement get enclosingElement => (super.enclosingElement as CompilationUnitElement);
-  ElementKind get kind => ElementKind.TYPE_ALIAS;
-  List<ParameterElement> get parameters => _parameters;
-  FunctionType get type => _type;
-  List<TypeVariableElement> get typeVariables => _typeVariables;
-  /**
-   * Set the parameters defined by this type alias to the given parameters.
-   * @param parameters the parameters defined by this type alias
-   */
-  void set parameters(List<ParameterElement> parameters8) {
-    if (parameters8 != null) {
-      for (ParameterElement parameter in parameters8) {
-        ((parameter as ParameterElementImpl)).enclosingElement = this;
-      }
-    }
-    this._parameters = parameters8;
+  _jtd_constructor_204_impl(Identifier name) {
   }
   /**
-   * Set the type of function defined by this type alias to the given type.
-   * @param type the type of function defined by this type alias
+   * Initialize a newly created synthetic top-level variable element to have the given name.
+   * @param name the name of this element
    */
-  void set type(FunctionType type7) {
-    this._type = type7;
+  TopLevelVariableElementImpl.con2(String name) : super.con2(name) {
+    _jtd_constructor_205_impl(name);
   }
-  /**
-   * Set the type variables defined for this type to the given variables.
-   * @param typeVariables the type variables defined for this type
-   */
-  void set typeVariables(List<TypeVariableElement> typeVariables3) {
-    for (TypeVariableElement variable in typeVariables3) {
-      ((variable as TypeVariableElementImpl)).enclosingElement = this;
-    }
-    this._typeVariables = typeVariables3;
+  _jtd_constructor_205_impl(String name) {
   }
-  void appendTo(StringBuffer builder) {
-    builder.add("typedef ");
-    builder.add(name);
-    int variableCount = _typeVariables.length;
-    if (variableCount > 0) {
-      builder.add("<");
-      for (int i = 0; i < variableCount; i++) {
-        if (i > 0) {
-          builder.add(", ");
-        }
-        ((_typeVariables[i] as TypeVariableElementImpl)).appendTo(builder);
-      }
-      builder.add(">");
-    }
-    builder.add("(");
-    int parameterCount = _parameters.length;
-    for (int i = 0; i < parameterCount; i++) {
-      if (i > 0) {
-        builder.add(", ");
-      }
-      ((_parameters[i] as ParameterElementImpl)).appendTo(builder);
-    }
-    builder.add(")");
-    if (_type != null) {
-      builder.add(" -> ");
-      builder.add(_type.returnType);
-    }
-  }
+  accept(ElementVisitor visitor) => visitor.visitTopLevelVariableElement(this);
+  ElementKind get kind => ElementKind.TOP_LEVEL_VARIABLE;
+  bool isStatic() => true;
 }
 /**
  * Instances of the class {@code TypeVariableElementImpl} implement a {@code TypeVariableElement}.
+ * @coverage dart.engine.element
  */
 class TypeVariableElementImpl extends ElementImpl implements TypeVariableElement {
   /**
@@ -2783,6 +3644,7 @@
    */
   TypeVariableElementImpl(Identifier name) : super.con1(name) {
   }
+  accept(ElementVisitor visitor) => visitor.visitTypeVariableElement(this);
   Type2 get bound => _bound;
   ElementKind get kind => ElementKind.TYPE_VARIABLE;
   TypeVariableType get type => _type;
@@ -2797,21 +3659,22 @@
    * Set the type defined by this type variable to the given type
    * @param type the type defined by this type variable
    */
-  void set type(TypeVariableType type8) {
-    this._type = type8;
+  void set type(TypeVariableType type9) {
+    this._type = type9;
   }
-  void appendTo(StringBuffer builder) {
-    builder.add(name);
+  void appendTo(JavaStringBuilder builder) {
+    builder.append(name);
     if (_bound != null) {
-      builder.add(" extends ");
-      builder.add(_bound);
+      builder.append(" extends ");
+      builder.append(_bound);
     }
   }
 }
 /**
  * Instances of the class {@code VariableElementImpl} implement a {@code VariableElement}.
+ * @coverage dart.engine.element
  */
-class VariableElementImpl extends ElementImpl implements VariableElement {
+abstract class VariableElementImpl extends ElementImpl implements VariableElement {
   /**
    * The declared type of this variable.
    */
@@ -2822,15 +3685,6 @@
    */
   FunctionElement _initializer;
   /**
-   * The offset to the beginning of the visible range for this element.
-   */
-  int _visibleRangeOffset = 0;
-  /**
-   * The length of the visible range for this element, or {@code -1} if this element does not have a
-   * visible range.
-   */
-  int _visibleRangeLength = -1;
-  /**
    * An empty array of variable elements.
    */
   static List<VariableElement> EMPTY_ARRAY = new List<VariableElement>(0);
@@ -2839,9 +3693,9 @@
    * @param name the name of this element
    */
   VariableElementImpl.con1(Identifier name) : super.con1(name) {
-    _jtd_constructor_162_impl(name);
+    _jtd_constructor_207_impl(name);
   }
-  _jtd_constructor_162_impl(Identifier name) {
+  _jtd_constructor_207_impl(Identifier name) {
   }
   /**
    * Initialize a newly created variable element to have the given name.
@@ -2850,29 +3704,37 @@
    * declaration of this element
    */
   VariableElementImpl.con2(String name, int nameOffset) : super.con2(name, nameOffset) {
-    _jtd_constructor_163_impl(name, nameOffset);
+    _jtd_constructor_208_impl(name, nameOffset);
   }
-  _jtd_constructor_163_impl(String name, int nameOffset) {
+  _jtd_constructor_208_impl(String name, int nameOffset) {
   }
+  /**
+   * Return the result of evaluating this variable's initializer as a compile-time constant
+   * expression, or {@code null} if this variable is not a 'const' variable or does not have an
+   * initializer.
+   * @return the result of evaluating this variable's initializer
+   */
+  EvaluationResultImpl get evaluationResult => null;
   FunctionElement get initializer => _initializer;
-  ElementKind get kind => ElementKind.VARIABLE;
   Type2 get type => _type;
-  SourceRange get visibleRange {
-    if (_visibleRangeLength < 0) {
-      return null;
-    }
-    return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
-  }
   bool isConst() => hasModifier(Modifier.CONST);
   bool isFinal() => hasModifier(Modifier.FINAL);
   /**
    * Set whether this variable is const to correspond to the given value.
    * @param isConst {@code true} if the variable is const
    */
-  void set const2(bool isConst) {
+  void set const3(bool isConst) {
     setModifier(Modifier.CONST, isConst);
   }
   /**
+   * Set the result of evaluating this variable's initializer as a compile-time constant expression
+   * to the given result.
+   * @param result the result of evaluating this variable's initializer
+   */
+  void set evaluationResult(EvaluationResultImpl result) {
+    throw new IllegalStateException("Invalid attempt to set a compile-time constant result");
+  }
+  /**
    * Set whether this variable is final to correspond to the given value.
    * @param isFinal {@code true} if the variable is final
    */
@@ -2893,28 +3755,22 @@
    * Set the declared type of this variable to the given type.
    * @param type the declared type of this variable
    */
-  void set type(Type2 type9) {
-    this._type = type9;
+  void set type(Type2 type10) {
+    this._type = type10;
   }
-  /**
-   * Set the visible range for this element to the range starting at the given offset with the given
-   * length.
-   * @param offset the offset to the beginning of the visible range for this element
-   * @param length the length of the visible range for this element, or {@code -1} if this element
-   * does not have a visible range
-   */
-  void setVisibleRange(int offset, int length) {
-    _visibleRangeOffset = offset;
-    _visibleRangeLength = length;
+  void visitChildren(ElementVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(_initializer, visitor);
   }
-  void appendTo(StringBuffer builder) {
-    builder.add(type);
-    builder.add(" ");
-    builder.add(name);
+  void appendTo(JavaStringBuilder builder) {
+    builder.append(type);
+    builder.append(" ");
+    builder.append(name);
   }
 }
 /**
  * The unique instance of the class {@code BottomTypeImpl} implements the type {@code bottom}.
+ * @coverage dart.engine.type
  */
 class BottomTypeImpl extends TypeImpl {
   /**
@@ -2939,6 +3795,7 @@
 }
 /**
  * The unique instance of the class {@code DynamicTypeImpl} implements the type {@code dynamic}.
+ * @coverage dart.engine.type
  */
 class DynamicTypeImpl extends TypeImpl {
   /**
@@ -2957,25 +3814,28 @@
     ((element as DynamicElementImpl)).type = this;
   }
   bool operator ==(Object object) => object is DynamicTypeImpl;
+  bool isDynamic() => true;
   bool isMoreSpecificThan(Type2 type) => false;
-  bool isSubtypeOf(Type2 type) => false;
+  bool isSubtypeOf(Type2 type) => identical(this, type);
   bool isSupertypeOf(Type2 type) => true;
   DynamicTypeImpl substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) => this;
 }
 /**
  * Instances of the class {@code FunctionTypeImpl} defines the behavior common to objects
  * representing the type of a function, method, constructor, getter, or setter.
+ * @coverage dart.engine.type
  */
 class FunctionTypeImpl extends TypeImpl implements FunctionType {
   /**
-   * Return {@code true} if all of the types in the first array are equal to the corresponding types
-   * in the second array.
-   * @param firstTypes the first array of types being compared
-   * @param secondTypes the second array of types being compared
-   * @return {@code true} if all of the types in the first array are equal to the corresponding
-   * types in the second array
+   * Return {@code true} if all of the name/type pairs in the first map are equal to the
+   * corresponding name/type pairs in the second map. The maps are expected to iterate over their
+   * entries in the same order in which those entries were added to the map.
+   * @param firstTypes the first map of name/type pairs being compared
+   * @param secondTypes the second map of name/type pairs being compared
+   * @return {@code true} if all of the name/type pairs in the first map are equal to the
+   * corresponding name/type pairs in the second map
    */
-  static bool equals2(LinkedHashMap<String, Type2> firstTypes, LinkedHashMap<String, Type2> secondTypes) {
+  static bool equals2(Map<String, Type2> firstTypes, Map<String, Type2> secondTypes) {
     if (secondTypes.length != firstTypes.length) {
       return false;
     }
@@ -2999,7 +3859,10 @@
    * @param parameterTypes the parameter types for the substitution
    * @return the result of performing the substitution on each of the types
    */
-  static LinkedHashMap<String, Type2> substitute3(LinkedHashMap<String, Type2> types, List<Type2> argumentTypes, List<Type2> parameterTypes) {
+  static Map<String, Type2> substitute3(Map<String, Type2> types, List<Type2> argumentTypes, List<Type2> parameterTypes) {
+    if (types.isEmpty) {
+      return types;
+    }
     LinkedHashMap<String, Type2> newTypes = new LinkedHashMap<String, Type2>();
     for (MapEntry<String, Type2> entry in getMapEntrySet(types)) {
       newTypes[entry.getKey()] = entry.getValue().substitute2(argumentTypes, parameterTypes);
@@ -3025,7 +3888,7 @@
    * A table mapping the names of named parameters to the types of the named parameters of this type
    * of function.
    */
-  LinkedHashMap<String, Type2> _namedParameterTypes = new LinkedHashMap<String, Type2>();
+  Map<String, Type2> _namedParameterTypes = new Map();
   /**
    * The type of object returned by this type of function.
    */
@@ -3036,25 +3899,25 @@
    * @param element the element representing the declaration of the function type
    */
   FunctionTypeImpl.con1(ExecutableElement element) : super(element, element == null ? null : element.name) {
-    _jtd_constructor_209_impl(element);
+    _jtd_constructor_259_impl(element);
   }
-  _jtd_constructor_209_impl(ExecutableElement element) {
+  _jtd_constructor_259_impl(ExecutableElement element) {
   }
   /**
    * Initialize a newly created function type to be declared by the given element and to have the
    * given name.
    * @param element the element representing the declaration of the function type
    */
-  FunctionTypeImpl.con2(TypeAliasElement element) : super(element, element == null ? null : element.name) {
-    _jtd_constructor_210_impl(element);
+  FunctionTypeImpl.con2(FunctionTypeAliasElement element) : super(element, element == null ? null : element.name) {
+    _jtd_constructor_260_impl(element);
   }
-  _jtd_constructor_210_impl(TypeAliasElement element) {
+  _jtd_constructor_260_impl(FunctionTypeAliasElement element) {
   }
   bool operator ==(Object object) {
     if (object is! FunctionTypeImpl) {
       return false;
     }
-    FunctionTypeImpl otherType = (object as FunctionTypeImpl);
+    FunctionTypeImpl otherType = object as FunctionTypeImpl;
     return element == otherType.element && JavaArrays.equals(_normalParameterTypes, otherType._normalParameterTypes) && JavaArrays.equals(_optionalParameterTypes, otherType._optionalParameterTypes) && equals2(_namedParameterTypes, otherType._namedParameterTypes);
   }
   Map<String, Type2> get namedParameterTypes => _namedParameterTypes;
@@ -3063,20 +3926,24 @@
   Type2 get returnType => _returnType;
   List<Type2> get typeArguments => _typeArguments;
   int get hashCode {
-    Element element34 = element;
-    if (element34 == null) {
+    Element element40 = element;
+    if (element40 == null) {
       return 0;
     }
-    return element34.hashCode;
+    return element40.hashCode;
   }
   bool isSubtypeOf(Type2 type) {
-    if (type == null || type is! FunctionType) {
+    if (type == null) {
       return false;
-    } else if (identical(this, type) || this == type) {
+    } else if (identical(this, type) || type.isDynamic() || type.isDartCoreFunction()) {
+      return true;
+    } else if (type is! FunctionType) {
+      return false;
+    } else if (this == type) {
       return true;
     }
     FunctionType t = this;
-    FunctionType s = (type as FunctionType);
+    FunctionType s = type as FunctionType;
     if (t.normalParameterTypes.length != s.normalParameterTypes.length) {
       return false;
     } else if (t.normalParameterTypes.length > 0) {
@@ -3174,21 +4041,21 @@
     if (argumentTypes.length == 0) {
       return this;
     }
-    Element element35 = element;
-    FunctionTypeImpl newType = (element35 is ExecutableElement) ? new FunctionTypeImpl.con1((element35 as ExecutableElement)) : new FunctionTypeImpl.con2((element35 as TypeAliasElement));
+    Element element41 = element;
+    FunctionTypeImpl newType = (element41 is ExecutableElement) ? new FunctionTypeImpl.con1((element41 as ExecutableElement)) : new FunctionTypeImpl.con2((element41 as FunctionTypeAliasElement));
     newType.returnType = _returnType.substitute2(argumentTypes, parameterTypes);
     newType.normalParameterTypes = TypeImpl.substitute(_normalParameterTypes, argumentTypes, parameterTypes);
     newType.optionalParameterTypes = TypeImpl.substitute(_optionalParameterTypes, argumentTypes, parameterTypes);
-    newType.namedParameterTypes = substitute3(_namedParameterTypes, argumentTypes, parameterTypes);
+    newType._namedParameterTypes = substitute3(_namedParameterTypes, argumentTypes, parameterTypes);
     return newType;
   }
-  void appendTo(StringBuffer builder) {
-    builder.add("(");
+  void appendTo(JavaStringBuilder builder) {
+    builder.append("(");
     bool needsComma = false;
     if (_normalParameterTypes.length > 0) {
       for (Type2 type in _normalParameterTypes) {
         if (needsComma) {
-          builder.add(", ");
+          builder.append(", ");
         } else {
           needsComma = true;
         }
@@ -3197,48 +4064,53 @@
     }
     if (_optionalParameterTypes.length > 0) {
       if (needsComma) {
-        builder.add(", ");
+        builder.append(", ");
         needsComma = false;
       }
-      builder.add("[");
+      builder.append("[");
       for (Type2 type in _optionalParameterTypes) {
         if (needsComma) {
-          builder.add(", ");
+          builder.append(", ");
         } else {
           needsComma = true;
         }
         ((type as TypeImpl)).appendTo(builder);
       }
-      builder.add("]");
+      builder.append("]");
       needsComma = true;
     }
     if (_namedParameterTypes.length > 0) {
       if (needsComma) {
-        builder.add(", ");
+        builder.append(", ");
         needsComma = false;
       }
-      builder.add("{");
+      builder.append("{");
       for (MapEntry<String, Type2> entry in getMapEntrySet(_namedParameterTypes)) {
         if (needsComma) {
-          builder.add(", ");
+          builder.append(", ");
         } else {
           needsComma = true;
         }
-        builder.add(entry.getKey());
-        builder.add(": ");
+        builder.append(entry.getKey());
+        builder.append(": ");
         ((entry.getValue() as TypeImpl)).appendTo(builder);
       }
-      builder.add("}");
+      builder.append("}");
       needsComma = true;
     }
-    builder.add(") -> ");
-    ((_returnType as TypeImpl)).appendTo(builder);
+    builder.append(") -> ");
+    if (_returnType == null) {
+      builder.append("null");
+    } else {
+      ((_returnType as TypeImpl)).appendTo(builder);
+    }
   }
 }
 /**
  * Instances of the class {@code InterfaceTypeImpl} defines the behavior common to objects
  * representing the type introduced by either a class or an interface, or a reference to such a
  * type.
+ * @coverage dart.engine.type
  */
 class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
   /**
@@ -3303,9 +4175,9 @@
    * @see #getLeastUpperBound(Type)
    */
   static Set<InterfaceType> computeSuperinterfaceSet2(InterfaceType type, Set<InterfaceType> set) {
-    Element element36 = type.element;
-    if (element36 != null && element36 is ClassElement) {
-      ClassElement classElement = (element36 as ClassElement);
+    Element element42 = type.element;
+    if (element42 != null && element42 is ClassElement) {
+      ClassElement classElement = element42 as ClassElement;
       List<InterfaceType> superinterfaces = classElement.interfaces;
       for (InterfaceType superinterface in superinterfaces) {
         javaSetAdd(set, superinterface);
@@ -3328,9 +4200,9 @@
    * @param element the element representing the declaration of the type
    */
   InterfaceTypeImpl.con1(ClassElement element) : super(element, element.name) {
-    _jtd_constructor_211_impl(element);
+    _jtd_constructor_261_impl(element);
   }
-  _jtd_constructor_211_impl(ClassElement element) {
+  _jtd_constructor_261_impl(ClassElement element) {
   }
   /**
    * Initialize a newly created type to have the given name. This constructor should only be used in
@@ -3338,18 +4210,18 @@
    * @param name the name of the type
    */
   InterfaceTypeImpl.con2(String name) : super(null, name) {
-    _jtd_constructor_212_impl(name);
+    _jtd_constructor_262_impl(name);
   }
-  _jtd_constructor_212_impl(String name) {
+  _jtd_constructor_262_impl(String name) {
   }
   bool operator ==(Object object) {
     if (object is! InterfaceTypeImpl) {
       return false;
     }
-    InterfaceTypeImpl otherType = (object as InterfaceTypeImpl);
+    InterfaceTypeImpl otherType = object as InterfaceTypeImpl;
     return element == otherType.element && JavaArrays.equals(_typeArguments, otherType._typeArguments);
   }
-  ClassElement get element => (super.element as ClassElement);
+  ClassElement get element => super.element as ClassElement;
   Type2 getLeastUpperBound(Type2 type) {
     Type2 dynamicType = DynamicTypeImpl.instance;
     if (identical(this, dynamicType) || identical(type, dynamicType)) {
@@ -3359,7 +4231,7 @@
       return null;
     }
     InterfaceType i = this;
-    InterfaceType j = (type as InterfaceType);
+    InterfaceType j = type as InterfaceType;
     Set<InterfaceType> si = computeSuperinterfaceSet(i);
     Set<InterfaceType> sj = computeSuperinterfaceSet(j);
     javaSetAdd(si, i);
@@ -3367,7 +4239,7 @@
     si.retainAll(sj);
     Set<InterfaceType> s = si;
     List<InterfaceType> sn = new List.from(s);
-    List<int> depths = new List<int>(sn.length);
+    List<int> depths = new List<int>.filled(sn.length, 0);
     int maxDepth = 0;
     for (int n = 0; n < sn.length; n++) {
       depths[n] = computeLongestInheritancePathToObject(sn[n]);
@@ -3396,11 +4268,18 @@
   }
   List<Type2> get typeArguments => _typeArguments;
   int get hashCode {
-    ClassElement element37 = element;
-    if (element37 == null) {
+    ClassElement element43 = element;
+    if (element43 == null) {
       return 0;
     }
-    return element37.hashCode;
+    return element43.hashCode;
+  }
+  bool isDartCoreFunction() {
+    ClassElement element44 = element;
+    if (element44 == null) {
+      return false;
+    }
+    return element44.name == "Function" && element44.library.isDartCore();
   }
   bool isDirectSupertypeOf(InterfaceType type) {
     ClassElement i = element;
@@ -3431,7 +4310,7 @@
     } else if (type is! InterfaceType) {
       return false;
     }
-    InterfaceType s = (type as InterfaceType);
+    InterfaceType s = type as InterfaceType;
     if (this == s) {
       return true;
     }
@@ -3469,7 +4348,7 @@
       return true;
     }
     InterfaceType typeT = this;
-    InterfaceType typeS = (type as InterfaceType);
+    InterfaceType typeS = type as InterfaceType;
     ClassElement elementT = element;
     if (elementT == null) {
       return false;
@@ -3527,24 +4406,25 @@
     newType.typeArguments = TypeImpl.substitute(_typeArguments, argumentTypes, parameterTypes);
     return newType;
   }
-  void appendTo(StringBuffer builder) {
-    builder.add(name);
+  void appendTo(JavaStringBuilder builder) {
+    builder.append(name);
     int argumentCount = _typeArguments.length;
     if (argumentCount > 0) {
-      builder.add("<");
+      builder.append("<");
       for (int i = 0; i < argumentCount; i++) {
         if (i > 0) {
-          builder.add(", ");
+          builder.append(", ");
         }
         ((_typeArguments[i] as TypeImpl)).appendTo(builder);
       }
-      builder.add(">");
+      builder.append(">");
     }
   }
 }
 /**
  * The abstract class {@code TypeImpl} implements the behavior common to objects representing the
  * declared type of elements in the element model.
+ * @coverage dart.engine.type
  */
 abstract class TypeImpl implements Type2 {
   /**
@@ -3557,6 +4437,9 @@
    */
   static List<Type2> substitute(List<Type2> types, List<Type2> argumentTypes, List<Type2> parameterTypes) {
     int length6 = types.length;
+    if (length6 == 0) {
+      return types;
+    }
     List<Type2> newTypes = new List<Type2>(length6);
     for (int i = 0; i < length6; i++) {
       newTypes[i] = types[i].substitute2(argumentTypes, parameterTypes);
@@ -3589,10 +4472,13 @@
   Type2 getLeastUpperBound(Type2 type) => null;
   String get name => _name;
   bool isAssignableTo(Type2 type) => this.isSubtypeOf(type) || type.isSubtypeOf(this);
+  bool isDartCoreFunction() => false;
+  bool isDynamic() => false;
   bool isMoreSpecificThan(Type2 type) => false;
   bool isSupertypeOf(Type2 type) => type.isSubtypeOf(this);
+  bool isVoid() => false;
   String toString() {
-    StringBuffer builder = new StringBuffer();
+    JavaStringBuilder builder = new JavaStringBuilder();
     appendTo(builder);
     return builder.toString();
   }
@@ -3600,17 +4486,18 @@
    * Append a textual representation of this type to the given builder.
    * @param builder the builder to which the text is to be appended
    */
-  void appendTo(StringBuffer builder) {
+  void appendTo(JavaStringBuilder builder) {
     if (_name == null) {
-      builder.add("<unnamed type>");
+      builder.append("<unnamed type>");
     } else {
-      builder.add(_name);
+      builder.append(_name);
     }
   }
 }
 /**
  * Instances of the class {@code TypeVariableTypeImpl} defines the behavior of objects representing
  * the type introduced by a type variable.
+ * @coverage dart.engine.type
  */
 class TypeVariableTypeImpl extends TypeImpl implements TypeVariableType {
   /**
@@ -3635,7 +4522,7 @@
   TypeVariableTypeImpl(TypeVariableElement element) : super(element, element.name) {
   }
   bool operator ==(Object object) => object is TypeVariableTypeImpl && element == ((object as TypeVariableTypeImpl)).element;
-  TypeVariableElement get element => (super.element as TypeVariableElement);
+  TypeVariableElement get element => super.element as TypeVariableElement;
   int get hashCode => element.hashCode;
   bool isMoreSpecificThan(Type2 type) {
     Type2 upperBound = element.bound;
@@ -3654,6 +4541,7 @@
 }
 /**
  * The unique instance of the class {@code VoidTypeImpl} implements the type {@code void}.
+ * @coverage dart.engine.type
  */
 class VoidTypeImpl extends TypeImpl implements VoidType {
   /**
@@ -3672,6 +4560,7 @@
   }
   bool operator ==(Object object) => identical(object, this);
   bool isSubtypeOf(Type2 type) => identical(type, this) || identical(type, DynamicTypeImpl.instance);
+  bool isVoid() => true;
   VoidTypeImpl substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) => this;
 }
 /**
@@ -3687,6 +4576,7 @@
  * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {T<sub>x1</sub> x1, &hellip;, T<sub>xk</sub> xk})
  * &rarr; T</i>.</li>
  * </ol>
+ * @coverage dart.engine.type
  */
 abstract class FunctionType implements Type2 {
   /**
@@ -3801,6 +4691,7 @@
 /**
  * The interface {@code InterfaceType} defines the behavior common to objects representing the type
  * introduced by either a class or an interface, or a reference to such a type.
+ * @coverage dart.engine.type
  */
 abstract class InterfaceType implements Type2 {
   ClassElement get element;
@@ -3892,6 +4783,7 @@
 /**
  * The interface {@code Type} defines the behavior of objects representing the declared type of
  * elements in the element model.
+ * @coverage dart.engine.type
  */
 abstract class Type2 {
   /**
@@ -3923,6 +4815,18 @@
    */
   bool isAssignableTo(Type2 type);
   /**
+   * Return {@code true} if this type represents the type 'Function' defined in the dart:core
+   * library.
+   * @return {@code true} if this type represents the type 'Function' defined in the dart:core
+   * library
+   */
+  bool isDartCoreFunction();
+  /**
+   * Return {@code true} if this type represents the type 'dynamic'.
+   * @return {@code true} if this type represents the type 'dynamic'
+   */
+  bool isDynamic();
+  /**
    * Return {@code true} if this type is more specific than the given type.
    * @param type the type being compared with this type
    * @return {@code true} if this type is more specific than the given type
@@ -3942,6 +4846,11 @@
    */
   bool isSupertypeOf(Type2 type);
   /**
+   * Return {@code true} if this type represents the type 'void'.
+   * @return {@code true} if this type represents the type 'void'
+   */
+  bool isVoid();
+  /**
    * Return the type resulting from substituting the given arguments for the given parameters in
    * this type. The specification defines this operation in section 2: <blockquote> The notation
    * <i>[x<sub>1</sub>, ..., x<sub>n</sub>/y<sub>1</sub>, ..., y<sub>n</sub>]E</i> denotes a copy of
@@ -3958,13 +4867,15 @@
 /**
  * The interface {@code TypeVariableType} defines the behavior of objects representing the type
  * introduced by a type variable.
+ * @coverage dart.engine.type
  */
 abstract class TypeVariableType implements Type2 {
   TypeVariableElement get element;
 }
 /**
  * The interface {@code VoidType} defines the behavior of the unique object representing the type{@code void}.
+ * @coverage dart.engine.type
  */
 abstract class VoidType implements Type2 {
   VoidType substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes);
-}
+}
\ No newline at end of file
diff --git a/pkg/analyzer_experimental/lib/src/generated/engine.dart b/pkg/analyzer_experimental/lib/src/generated/engine.dart
new file mode 100644
index 0000000..f782870
--- /dev/null
+++ b/pkg/analyzer_experimental/lib/src/generated/engine.dart
@@ -0,0 +1,1051 @@
+// This code was auto-generated, is not intended to be edited, and is subject to
+// significant change. Please see the README file for more information.
+
+library engine;
+
+import 'java_core.dart';
+import 'java_engine.dart';
+import 'dart:collection' show HasNextIterator;
+import 'error.dart';
+import 'source.dart';
+import 'scanner.dart' show Token, CharBufferScanner, StringScanner;
+import 'ast.dart' show CompilationUnit, Directive, PartOfDirective;
+import 'parser.dart' show Parser;
+import 'element.dart';
+import 'resolver.dart' show Namespace, NamespaceBuilder, LibraryResolver;
+import 'html.dart' show HtmlScanner, HtmlScanResult, HtmlParser, HtmlParseResult;
+
+/**
+ * The unique instance of the class {@code AnalysisEngine} serves as the entry point for the
+ * functionality provided by the analysis engine.
+ * @coverage dart.engine
+ */
+class AnalysisEngine {
+  /**
+   * The suffix used for Dart source files.
+   */
+  static String SUFFIX_DART = "dart";
+  /**
+   * The short suffix used for HTML files.
+   */
+  static String SUFFIX_HTM = "htm";
+  /**
+   * The long suffix used for HTML files.
+   */
+  static String SUFFIX_HTML = "html";
+  /**
+   * The unique instance of this class.
+   */
+  static AnalysisEngine _UniqueInstance = new AnalysisEngine();
+  /**
+   * Return the unique instance of this class.
+   * @return the unique instance of this class
+   */
+  static AnalysisEngine get instance => _UniqueInstance;
+  /**
+   * Return {@code true} if the given file name is assumed to contain Dart source code.
+   * @param fileName the name of the file being tested
+   * @return {@code true} if the given file name is assumed to contain Dart source code
+   */
+  static bool isDartFileName(String fileName) {
+    if (fileName == null) {
+      return false;
+    }
+    return javaStringEqualsIgnoreCase(FileNameUtilities.getExtension(fileName), SUFFIX_DART);
+  }
+  /**
+   * Return {@code true} if the given file name is assumed to contain HTML.
+   * @param fileName the name of the file being tested
+   * @return {@code true} if the given file name is assumed to contain HTML
+   */
+  static bool isHtmlFileName(String fileName) {
+    if (fileName == null) {
+      return false;
+    }
+    String extension = FileNameUtilities.getExtension(fileName);
+    return javaStringEqualsIgnoreCase(extension, SUFFIX_HTML) || javaStringEqualsIgnoreCase(extension, SUFFIX_HTM);
+  }
+  /**
+   * The logger that should receive information about errors within the analysis engine.
+   */
+  Logger _logger = Logger.NULL;
+  /**
+   * Prevent the creation of instances of this class.
+   */
+  AnalysisEngine() : super() {
+  }
+  /**
+   * Create a new context in which analysis can be performed.
+   * @return the analysis context that was created
+   */
+  AnalysisContext createAnalysisContext() => new AnalysisContextImpl();
+  /**
+   * Return the logger that should receive information about errors within the analysis engine.
+   * @return the logger that should receive information about errors within the analysis engine
+   */
+  Logger get logger => _logger;
+  /**
+   * Set the logger that should receive information about errors within the analysis engine to the
+   * given logger.
+   * @param logger the logger that should receive information about errors within the analysis
+   * engine
+   */
+  void set logger(Logger logger2) {
+    this._logger = logger2 == null ? Logger.NULL : logger2;
+  }
+}
+/**
+ * The interface {@code AnalysisContext} defines the behavior of objects that represent a context in
+ * which analysis can be performed. The context includes such information as the version of the SDK
+ * being analyzed against as well as the package-root used to resolve 'package:' URI's. (The latter
+ * is included indirectly through the {@link SourceFactory source factory}.)
+ * <p>
+ * Analysis engine allows for having more than one context. This can be used, for example, to
+ * perform one analysis based on the state of files on disk and a separate analysis based on the
+ * state of those files in open editors. It can also be used to perform an analysis based on a
+ * proposed future state, such as the state after a refactoring.
+ */
+abstract class AnalysisContext {
+  /**
+   * Respond to the given set of changes by removing any cached information that might now be
+   * out-of-date. The result indicates what operations need to be performed as a result of this
+   * change without actually performing those operations.
+   * @param changeSet a description of the changes that have occurred
+   * @return a result (not {@code null}) indicating operations to be performed
+   */
+  ChangeResult changed(ChangeSet changeSet);
+  /**
+   * Clear any cached information that is dependent on resolution. This method should be invoked if
+   * the assumptions used by resolution have changed but the contents of the file have not changed.
+   * Use {@link #sourceChanged(Source)} and {@link #sourcesDeleted(SourceContainer)} to indicate
+   * when the contents of a file or files have changed.
+   */
+  void clearResolution();
+  /**
+   * Call this method when this context is no longer going to be used. At this point, the receiver
+   * may choose to push some of its information back into the global cache for consumption by
+   * another context for performance.
+   */
+  void discard();
+  /**
+   * Create a new context in which analysis can be performed. Any sources in the specified directory
+   * in the receiver will be removed from the receiver and added to the newly created context.
+   * @param directory the directory (not {@code null}) containing sources that should be removed
+   * from the receiver and added to the returned context
+   * @return the analysis context that was created (not {@code null})
+   */
+  AnalysisContext extractAnalysisContext(SourceContainer container);
+  /**
+   * Return the element referenced by the given location.
+   * @param location the reference describing the element to be returned
+   * @return the element referenced by the given location
+   */
+  Element getElement(ElementLocation location);
+  /**
+   * Return an array containing all of the errors associated with the given source.
+   * @param source the source whose errors are to be returned
+   * @return all of the errors associated with the given source
+   * @throws AnalysisException if the errors could not be determined because the analysis could not
+   * be performed
+   */
+  List<AnalysisError> getErrors(Source source);
+  /**
+   * Parse and build an element model for the HTML file defined by the given source.
+   * @param source the source defining the HTML file whose element model is to be returned
+   * @return the element model corresponding to the HTML file defined by the given source
+   */
+  HtmlElement getHtmlElement(Source source);
+  /**
+   * Return the kind of the given source if it is already known, or {@code null} if the kind is not
+   * already known.
+   * @param source the source whose kind is to be returned
+   * @return the kind of the given source
+   * @see #getOrComputeKindOf(Source)
+   */
+  SourceKind getKnownKindOf(Source source);
+  /**
+   * Return the sources for the defining compilation units of any libraries of which the given
+   * source is a part. The array will normally contain a single library because most Dart sources
+   * are only included in a single library, but it is possible to have a part that is contained in
+   * multiple identically named libraries. If the source represents the defining compilation unit of
+   * a library, then the returned array will contain the given source as its only element. If the
+   * source does not represent a Dart source or is not known to this context, the returned array
+   * will be empty.
+   * @param source the source contained in the returned libraries
+   * @return the sources for the libraries containing the given source
+   */
+  List<Source> getLibrariesContaining(Source source);
+  /**
+   * Return the element model corresponding to the library defined by the given source. If the
+   * element model does not yet exist it will be created. The process of creating an element model
+   * for a library can long-running, depending on the size of the library and the number of
+   * libraries that are imported into it that also need to have a model built for them.
+   * @param source the source defining the library whose element model is to be returned
+   * @return the element model corresponding to the library defined by the given source or{@code null} if the element model could not be determined because the analysis could
+   * not be performed
+   */
+  LibraryElement getLibraryElement(Source source);
+  /**
+   * Return the element model corresponding to the library defined by the given source, or{@code null} if the element model does not yet exist.
+   * @param source the source defining the library whose element model is to be returned
+   * @return the element model corresponding to the library defined by the given source
+   */
+  LibraryElement getLibraryElementOrNull(Source source);
+  /**
+   * Return the kind of the given source, computing it's kind if it is not already known.
+   * @param source the source whose kind is to be returned
+   * @return the kind of the given source
+   * @see #getKnownKindOf(Source)
+   */
+  SourceKind getOrComputeKindOf(Source source);
+  /**
+   * Return an array containing all of the parsing errors associated with the given source.
+   * @param source the source whose errors are to be returned
+   * @return all of the parsing errors associated with the given source
+   * @throws AnalysisException if the errors could not be determined because the analysis could not
+   * be performed
+   */
+  List<AnalysisError> getParsingErrors(Source source);
+  /**
+   * Return an array containing all of the resolution errors associated with the given source.
+   * @param source the source whose errors are to be returned
+   * @return all of the resolution errors associated with the given source
+   * @throws AnalysisException if the errors could not be determined because the analysis could not
+   * be performed
+   */
+  List<AnalysisError> getResolutionErrors(Source source);
+  /**
+   * Return the source factory used to create the sources that can be analyzed in this context.
+   * @return the source factory used to create the sources that can be analyzed in this context
+   */
+  SourceFactory get sourceFactory;
+  /**
+   * Add the sources contained in the specified context to the receiver's collection of sources.
+   * This method is called when an existing context's pubspec has been removed, and the contained
+   * sources should be reanalyzed as part of the receiver.
+   * @param context the context being merged (not {@code null})
+   */
+  void mergeAnalysisContext(AnalysisContext context);
+  /**
+   * Parse a single source to produce an AST structure. The resulting AST structure may or may not
+   * be resolved, and may have a slightly different structure depending upon whether it is resolved.
+   * @param source the source to be parsed
+   * @return the AST structure representing the content of the source
+   * @throws AnalysisException if the analysis could not be performed
+   */
+  CompilationUnit parse(Source source);
+  /**
+   * Parse a single HTML source to produce an AST structure. The resulting HTML AST structure may or
+   * may not be resolved, and may have a slightly different structure depending upon whether it is
+   * resolved.
+   * @param source the HTML source to be parsed
+   * @return the parse result (not {@code null})
+   * @throws AnalysisException if the analysis could not be performed
+   */
+  HtmlParseResult parseHtml(Source source);
+  /**
+   * Parse and resolve a single source within the given context to produce a fully resolved AST.
+   * @param source the source to be parsed and resolved
+   * @param library the library defining the context in which the source file is to be resolved
+   * @return the result of resolving the AST structure representing the content of the source
+   * @throws AnalysisException if the analysis could not be performed
+   */
+  CompilationUnit resolve(Source source, LibraryElement library);
+  /**
+   * Scan a single source to produce a token stream.
+   * @param source the source to be scanned
+   * @param errorListener the listener to which errors should be reported
+   * @return the head of the token stream representing the content of the source
+   * @throws AnalysisException if the analysis could not be performed
+   */
+  Token scan(Source source, AnalysisErrorListener errorListener);
+  /**
+   * Scan a single source to produce an HTML token stream.
+   * @param source the source to be scanned
+   * @return the scan result (not {@code null})
+   * @throws AnalysisException if the analysis could not be performed
+   */
+  HtmlScanResult scanHtml(Source source);
+  /**
+   * Set the source factory used to create the sources that can be analyzed in this context to the
+   * given source factory.
+   * @param sourceFactory the source factory used to create the sources that can be analyzed in this
+   * context
+   */
+  void set sourceFactory(SourceFactory sourceFactory4);
+  /**
+   * Given a collection of sources with content that has changed, return an {@link Iterable}identifying the sources that need to be resolved.
+   * @param changedSources an array of sources (not {@code null}, contains no {@code null}s)
+   * @return An iterable returning the sources to be resolved
+   */
+  Iterable<Source> sourcesToResolve(List<Source> changedSources);
+}
+/**
+ * Instances of the class {@code AnalysisException} represent an exception that occurred during the
+ * analysis of one or more sources.
+ * @coverage dart.engine
+ */
+class AnalysisException extends JavaException {
+  /**
+   * Initialize a newly created exception.
+   */
+  AnalysisException() : super() {
+    _jtd_constructor_123_impl();
+  }
+  _jtd_constructor_123_impl() {
+  }
+  /**
+   * Initialize a newly created exception to have the given message.
+   * @param message the message associated with the exception
+   */
+  AnalysisException.con1(String message) : super(message) {
+    _jtd_constructor_124_impl(message);
+  }
+  _jtd_constructor_124_impl(String message) {
+  }
+  /**
+   * Initialize a newly created exception to have the given message and cause.
+   * @param message the message associated with the exception
+   * @param cause the underlying exception that caused this exception
+   */
+  AnalysisException.con2(String message, Exception cause) : super(message, cause) {
+    _jtd_constructor_125_impl(message, cause);
+  }
+  _jtd_constructor_125_impl(String message, Exception cause) {
+  }
+  /**
+   * Initialize a newly created exception to have the given cause.
+   * @param cause the underlying exception that caused this exception
+   */
+  AnalysisException.con3(Exception cause) : super.withCause(cause) {
+    _jtd_constructor_126_impl(cause);
+  }
+  _jtd_constructor_126_impl(Exception cause) {
+  }
+}
+/**
+ * Instances of {@code ChangeResult} are returned by {@link AnalysisContext#changed(ChangeSet)} to
+ * indicate what operations need to be performed as a result of the change.
+ * @coverage dart.engine
+ */
+class ChangeResult {
+}
+/**
+ * Instances of the class {@code ChangeSet} indicate what sources have been added, changed, or
+ * removed.
+ * @coverage dart.engine
+ */
+class ChangeSet {
+  /**
+   * A table mapping the sources that have been added to their contents.
+   */
+  Map<Source, String> _added3 = new Map<Source, String>();
+  /**
+   * A table mapping the sources that have been changed to their contents.
+   */
+  Map<Source, String> _changed3 = new Map<Source, String>();
+  /**
+   * A list containing the sources that have been removed..
+   */
+  List<Source> _removed2 = new List<Source>();
+  /**
+   * A list containing the source containers specifying additional sources that have been removed.
+   */
+  List<SourceContainer> _removedContainers = new List<SourceContainer>();
+  /**
+   * Initialize a newly created change set to be empty.
+   */
+  ChangeSet() : super() {
+  }
+  /**
+   * Record that the specified source has been added and that it's content is the default contents
+   * of the source.
+   * @param source the source that was added
+   */
+  void added(Source source) {
+    added2(source, null);
+  }
+  /**
+   * Record that the specified source has been added and that it has the given content. If the
+   * content is non-{@code null}, this has the effect of overriding the default contents of the
+   * source. If the contents are {@code null}, any previous the override is removed so that the
+   * default contents will be used.
+   * @param source the source that was added
+   * @param content the content of the new source
+   */
+  void added2(Source source, String content) {
+    if (source != null) {
+      _added3[source] = content;
+    }
+  }
+  /**
+   * Record that the specified source has been changed and that it's content is the default contents
+   * of the source.
+   * @param source the source that was changed
+   */
+  void changed(Source source) {
+    changed2(source, null);
+  }
+  /**
+   * Record that the specified source has been changed and that it now has the given content. If the
+   * content is non-{@code null}, this has the effect of overriding the default contents of the
+   * source. If the contents are {@code null}, any previous the override is removed so that the
+   * default contents will be used.
+   * @param source the source that was changed
+   * @param content the new content of the source
+   */
+  void changed2(Source source, String content) {
+    if (source != null) {
+      _changed3[source] = content;
+    }
+  }
+  /**
+   * Return a table mapping the sources that have been added to their contents.
+   * @return a table mapping the sources that have been added to their contents
+   */
+  Map<Source, String> get addedWithContent => _added3;
+  /**
+   * Return a table mapping the sources that have been changed to their contents.
+   * @return a table mapping the sources that have been changed to their contents
+   */
+  Map<Source, String> get changedWithContent => _changed3;
+  /**
+   * Return a list containing the sources that were removed.
+   * @return a list containing the sources that were removed
+   */
+  List<Source> get removed => _removed2;
+  /**
+   * Return a list containing the source containers that were removed.
+   * @return a list containing the source containers that were removed
+   */
+  List<SourceContainer> get removedContainers => _removedContainers;
+  /**
+   * Return {@code true} if this change set does not contain any changes.
+   * @return {@code true} if this change set does not contain any changes
+   */
+  bool isEmpty() => _added3.isEmpty && _changed3.isEmpty && _removed2.isEmpty && _removedContainers.isEmpty;
+  /**
+   * Record that the specified source has been removed.
+   * @param source the source that was removed
+   */
+  void removed3(Source source) {
+    if (source != null) {
+      _removed2.add(source);
+    }
+  }
+  /**
+   * Record that the specified source container has been removed.
+   * @param container the source container that was removed
+   */
+  void removedContainer(SourceContainer container) {
+    if (container != null) {
+      _removedContainers.add(container);
+    }
+  }
+}
+/**
+ * Instances of the class {@code AnalysisContextImpl} implement an {@link AnalysisContext analysis
+ * context}.
+ * @coverage dart.engine
+ */
+class AnalysisContextImpl implements AnalysisContext {
+  /**
+   * The source factory used to create the sources that can be analyzed in this context.
+   */
+  SourceFactory _sourceFactory;
+  /**
+   * A table mapping sources known to the context to the information known about the source.
+   */
+  Map<Source, SourceInfo> _sourceMap = new Map<Source, SourceInfo>();
+  /**
+   * A cache mapping sources to the compilation units that were produced for the contents of the
+   * source.
+   */
+  Map<Source, CompilationUnit> _parseCache = new Map<Source, CompilationUnit>();
+  /**
+   * A cache mapping sources to the html parse results that were produced for the contents of the
+   * source.
+   */
+  Map<Source, HtmlParseResult> _htmlParseCache = new Map<Source, HtmlParseResult>();
+  /**
+   * A cache mapping sources (of the defining compilation units of libraries) to the library
+   * elements for those libraries.
+   */
+  Map<Source, LibraryElement> _libraryElementCache = new Map<Source, LibraryElement>();
+  /**
+   * A cache mapping sources (of the defining compilation units of libraries) to the public
+   * namespace for that library.
+   */
+  Map<Source, Namespace> _publicNamespaceCache = new Map<Source, Namespace>();
+  /**
+   * The object used to synchronize access to all of the caches.
+   */
+  Object _cacheLock = new Object();
+  /**
+   * The suffix used by sources that contain Dart.
+   */
+  static String _DART_SUFFIX = ".dart";
+  /**
+   * The suffix used by sources that contain HTML.
+   */
+  static String _HTML_SUFFIX = ".html";
+  /**
+   * Initialize a newly created analysis context.
+   */
+  AnalysisContextImpl() : super() {
+  }
+  ChangeResult changed(ChangeSet changeSet) {
+    if (changeSet.isEmpty()) {
+      return new ChangeResult();
+    }
+    {
+      for (MapEntry<Source, String> entry in getMapEntrySet(changeSet.addedWithContent)) {
+        _sourceFactory.setContents(entry.getKey(), entry.getValue());
+      }
+      for (MapEntry<Source, String> entry in getMapEntrySet(changeSet.changedWithContent)) {
+        _sourceFactory.setContents(entry.getKey(), entry.getValue());
+      }
+      for (Source source in changeSet.addedWithContent.keys.toSet()) {
+        sourceAvailable(source);
+      }
+      for (Source source in changeSet.changedWithContent.keys.toSet()) {
+        sourceChanged(source);
+      }
+      for (Source source in changeSet.removed) {
+        sourceDeleted(source);
+      }
+      for (SourceContainer container in changeSet.removedContainers) {
+        sourcesDeleted(container);
+      }
+    }
+    return new ChangeResult();
+  }
+  void clearResolution() {
+    {
+      _parseCache.clear();
+      _htmlParseCache.clear();
+      _libraryElementCache.clear();
+      _publicNamespaceCache.clear();
+    }
+  }
+  void discard() {
+    {
+      _sourceMap.clear();
+      _parseCache.clear();
+      _htmlParseCache.clear();
+      _libraryElementCache.clear();
+      _publicNamespaceCache.clear();
+    }
+  }
+  AnalysisContext extractAnalysisContext(SourceContainer container) {
+    AnalysisContextImpl newContext = AnalysisEngine.instance.createAnalysisContext() as AnalysisContextImpl;
+    List<Source> sourcesToRemove = new List<Source>();
+    {
+      for (MapEntry<Source, SourceInfo> entry in getMapEntrySet(_sourceMap)) {
+        Source source = entry.getKey();
+        if (container.contains(source)) {
+          sourcesToRemove.add(source);
+          newContext._sourceMap[source] = new SourceInfo.con2(entry.getValue());
+        }
+      }
+    }
+    return newContext;
+  }
+  Element getElement(ElementLocation location) {
+    throw new UnsupportedOperationException();
+  }
+  List<AnalysisError> getErrors(Source source) {
+    throw new UnsupportedOperationException();
+  }
+  HtmlElement getHtmlElement(Source source) {
+    throw new UnsupportedOperationException();
+  }
+  SourceKind getKnownKindOf(Source source) {
+    if (source.fullName.endsWith(_HTML_SUFFIX)) {
+      return SourceKind.HTML;
+    }
+    if (!source.fullName.endsWith(_DART_SUFFIX)) {
+      return SourceKind.UNKNOWN;
+    }
+    {
+      if (_libraryElementCache.containsKey(source)) {
+        return SourceKind.LIBRARY;
+      }
+      CompilationUnit unit = _parseCache[source];
+      if (unit != null && hasPartOfDirective(unit)) {
+        return SourceKind.PART;
+      }
+    }
+    return null;
+  }
+  List<Source> getLibrariesContaining(Source source) {
+    {
+      SourceInfo info = _sourceMap[source];
+      if (info == null) {
+        return Source.EMPTY_ARRAY;
+      }
+      return info.librarySources;
+    }
+  }
+  LibraryElement getLibraryElement(Source source) {
+    {
+      LibraryElement element = _libraryElementCache[source];
+      if (element == null) {
+        if (getOrComputeKindOf(source) != SourceKind.LIBRARY) {
+          return null;
+        }
+        LibraryResolver resolver = new LibraryResolver.con1(this);
+        try {
+          element = resolver.resolveLibrary(source, true);
+          if (element != null) {
+            _libraryElementCache[source] = element;
+          }
+        } on AnalysisException catch (exception) {
+          AnalysisEngine.instance.logger.logError2("Could not resolve the library ${source.fullName}", exception);
+        }
+      }
+      return element;
+    }
+  }
+  /**
+   * Return the element model corresponding to the library defined by the given source, or{@code null} if the element model does not yet exist.
+   * @param source the source defining the library whose element model is to be returned
+   * @return the element model corresponding to the library defined by the given source
+   */
+  LibraryElement getLibraryElementOrNull(Source source) {
+    {
+      return _libraryElementCache[source];
+    }
+  }
+  SourceKind getOrComputeKindOf(Source source) {
+    SourceKind kind = getKnownKindOf(source);
+    if (kind != null) {
+      return kind;
+    }
+    try {
+      if (hasPartOfDirective(parse(source))) {
+        return SourceKind.PART;
+      }
+    } on AnalysisException catch (exception) {
+      return SourceKind.UNKNOWN;
+    }
+    return SourceKind.LIBRARY;
+  }
+  List<AnalysisError> getParsingErrors(Source source) {
+    throw new UnsupportedOperationException();
+  }
+  /**
+   * Return a namespace containing mappings for all of the public names defined by the given
+   * library.
+   * @param library the library whose public namespace is to be returned
+   * @return the public namespace of the given library
+   */
+  Namespace getPublicNamespace(LibraryElement library) {
+    Source source8 = library.definingCompilationUnit.source;
+    {
+      Namespace namespace = _publicNamespaceCache[source8];
+      if (namespace == null) {
+        NamespaceBuilder builder = new NamespaceBuilder();
+        namespace = builder.createPublicNamespace(library);
+        _publicNamespaceCache[source8] = namespace;
+      }
+      return namespace;
+    }
+  }
+  /**
+   * Return a namespace containing mappings for all of the public names defined by the library
+   * defined by the given source.
+   * @param source the source defining the library whose public namespace is to be returned
+   * @return the public namespace corresponding to the library defined by the given source
+   */
+  Namespace getPublicNamespace2(Source source) {
+    {
+      Namespace namespace = _publicNamespaceCache[source];
+      if (namespace == null) {
+        LibraryElement library = getLibraryElement(source);
+        if (library == null) {
+          return null;
+        }
+        NamespaceBuilder builder = new NamespaceBuilder();
+        namespace = builder.createPublicNamespace(library);
+        _publicNamespaceCache[source] = namespace;
+      }
+      return namespace;
+    }
+  }
+  List<AnalysisError> getResolutionErrors(Source source) {
+    throw new UnsupportedOperationException();
+  }
+  SourceFactory get sourceFactory => _sourceFactory;
+  void mergeAnalysisContext(AnalysisContext context) {
+    {
+      for (MapEntry<Source, SourceInfo> entry in getMapEntrySet(((context as AnalysisContextImpl))._sourceMap)) {
+        Source newSource = entry.getKey();
+        SourceInfo existingInfo = _sourceMap[newSource];
+        if (existingInfo == null) {
+          _sourceMap[newSource] = new SourceInfo.con2(entry.getValue());
+        } else {
+        }
+      }
+    }
+  }
+  CompilationUnit parse(Source source) {
+    {
+      CompilationUnit unit = _parseCache[source];
+      if (unit == null) {
+        RecordingErrorListener errorListener = new RecordingErrorListener();
+        AnalysisContextImpl_ScanResult scanResult = internalScan(source, errorListener);
+        Parser parser = new Parser(source, errorListener);
+        unit = parser.parseCompilationUnit(scanResult._token);
+        unit.parsingErrors = errorListener.getErrors2(source);
+        unit.lineInfo = new LineInfo(scanResult._lineStarts);
+        _parseCache[source] = unit;
+      }
+      return unit;
+    }
+  }
+  CompilationUnit parse3(Source source, AnalysisErrorListener errorListener) {
+    {
+      CompilationUnit unit = _parseCache[source];
+      if (unit == null) {
+        AnalysisContextImpl_ScanResult scanResult = internalScan(source, errorListener);
+        Parser parser = new Parser(source, errorListener);
+        unit = parser.parseCompilationUnit(scanResult._token);
+        unit.lineInfo = new LineInfo(scanResult._lineStarts);
+        _parseCache[source] = unit;
+      }
+      return unit;
+    }
+  }
+  HtmlParseResult parseHtml(Source source) {
+    {
+      HtmlParseResult result = _htmlParseCache[source];
+      if (result == null) {
+        result = new HtmlParser(source).parse(scanHtml(source));
+        _htmlParseCache[source] = result;
+      }
+      return result;
+    }
+  }
+  /**
+   * Given a table mapping the source for the libraries represented by the corresponding elements to
+   * the elements representing the libraries, record those mappings.
+   * @param elementMap a table mapping the source for the libraries represented by the elements to
+   * the elements representing the libraries
+   */
+  void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
+    {
+      javaMapPutAll(_libraryElementCache, elementMap);
+    }
+  }
+  CompilationUnit resolve(Source source, LibraryElement library) => parse(source);
+  Token scan(Source source, AnalysisErrorListener errorListener) {
+    AnalysisContextImpl_ScanResult result = internalScan(source, errorListener);
+    return result._token;
+  }
+  HtmlScanResult scanHtml(Source source) {
+    HtmlScanner scanner = new HtmlScanner(source);
+    try {
+      source.getContents(scanner);
+    } on JavaException catch (exception) {
+      throw new AnalysisException.con3(exception);
+    }
+    return scanner.result;
+  }
+  void set sourceFactory(SourceFactory sourceFactory2) {
+    this._sourceFactory = sourceFactory2;
+  }
+  Iterable<Source> sourcesToResolve(List<Source> changedSources) {
+    List<Source> librarySources = new List<Source>();
+    for (Source source in changedSources) {
+      if (identical(getOrComputeKindOf(source), SourceKind.LIBRARY)) {
+        librarySources.add(source);
+      }
+    }
+    return librarySources;
+  }
+  /**
+   * Return {@code true} if the given compilation unit has a part-of directive.
+   * @param unit the compilation unit being tested
+   * @return {@code true} if the compilation unit has a part-of directive
+   */
+  bool hasPartOfDirective(CompilationUnit unit) {
+    for (Directive directive in unit.directives) {
+      if (directive is PartOfDirective) {
+        return true;
+      }
+    }
+    return false;
+  }
+  AnalysisContextImpl_ScanResult internalScan(Source source, AnalysisErrorListener errorListener) {
+    AnalysisContextImpl_ScanResult result = new AnalysisContextImpl_ScanResult();
+    Source_ContentReceiver receiver = new Source_ContentReceiver_3(source, errorListener, result);
+    try {
+      source.getContents(receiver);
+    } on JavaException catch (exception) {
+      throw new AnalysisException.con3(exception);
+    }
+    return result;
+  }
+  /**
+   * Note: This method must only be invoked while we are synchronized on {@link #cacheLock}.
+   * @param source the source that has been added
+   */
+  void sourceAvailable(Source source) {
+    SourceInfo existingInfo = _sourceMap[source];
+    if (existingInfo == null) {
+      _sourceMap[source] = new SourceInfo.con1(source, getOrComputeKindOf(source));
+    }
+  }
+  /**
+   * Note: This method must only be invoked while we are synchronized on {@link #cacheLock}.
+   * @param source the source that has been changed
+   */
+  void sourceChanged(Source source) {
+    SourceInfo info = _sourceMap[source];
+    if (info == null) {
+      return;
+    }
+    _parseCache.remove(source);
+    _htmlParseCache.remove(source);
+    _libraryElementCache.remove(source);
+    _publicNamespaceCache.remove(source);
+    for (Source librarySource in info.librarySources) {
+      _libraryElementCache.remove(librarySource);
+      _publicNamespaceCache.remove(librarySource);
+    }
+  }
+  /**
+   * Note: This method must only be invoked while we are synchronized on {@link #cacheLock}.
+   * @param source the source that has been deleted
+   */
+  void sourceDeleted(Source source) {
+    _sourceMap.remove(source);
+    sourceChanged(source);
+  }
+  /**
+   * Note: This method must only be invoked while we are synchronized on {@link #cacheLock}.
+   * @param container the source container specifying the sources that have been deleted
+   */
+  void sourcesDeleted(SourceContainer container) {
+    List<Source> sourcesToRemove = new List<Source>();
+    for (Source source in _sourceMap.keys.toSet()) {
+      if (container.contains(source)) {
+        sourcesToRemove.add(source);
+      }
+    }
+  }
+}
+/**
+ * Instances of the class {@code ScanResult} represent the results of scanning a source.
+ */
+class AnalysisContextImpl_ScanResult {
+  /**
+   * The first token in the token stream.
+   */
+  Token _token;
+  /**
+   * The line start information that was produced.
+   */
+  List<int> _lineStarts;
+  /**
+   * Initialize a newly created result object to be empty.
+   */
+  AnalysisContextImpl_ScanResult() : super() {
+  }
+}
+class Source_ContentReceiver_3 implements Source_ContentReceiver {
+  Source source;
+  AnalysisErrorListener errorListener;
+  AnalysisContextImpl_ScanResult result;
+  Source_ContentReceiver_3(this.source, this.errorListener, this.result);
+  accept(CharBuffer contents) {
+    CharBufferScanner scanner = new CharBufferScanner(source, contents, errorListener);
+    result._token = scanner.tokenize();
+    result._lineStarts = scanner.lineStarts;
+  }
+  void accept2(String contents) {
+    StringScanner scanner = new StringScanner(source, contents, errorListener);
+    result._token = scanner.tokenize();
+    result._lineStarts = scanner.lineStarts;
+  }
+}
+/**
+ * Instances of the class {@code RecordingErrorListener} implement an error listener that will
+ * record the errors that are reported to it in a way that is appropriate for caching those errors
+ * within an analysis context.
+ * @coverage dart.engine
+ */
+class RecordingErrorListener implements AnalysisErrorListener {
+  /**
+   * A HashMap of lists containing the errors that were collected, keyed by each {@link Source}.
+   */
+  Map<Source, List<AnalysisError>> _errors = new Map<Source, List<AnalysisError>>();
+  /**
+   * Answer the errors collected by the listener.
+   * @return an array of errors (not {@code null}, contains no {@code null}s)
+   */
+  List<AnalysisError> get errors {
+    Set<MapEntry<Source, List<AnalysisError>>> entrySet2 = getMapEntrySet(_errors);
+    if (entrySet2.length == 0) {
+      return AnalysisError.NO_ERRORS;
+    }
+    List<AnalysisError> resultList = new List<AnalysisError>();
+    for (MapEntry<Source, List<AnalysisError>> entry in entrySet2) {
+      resultList.addAll(entry.getValue());
+    }
+    return new List.from(resultList);
+  }
+  /**
+   * Answer the errors collected by the listener for some passed {@link Source}.
+   * @param source some {@link Source} for which the caller wants the set of {@link AnalysisError}s
+   * collected by this listener
+   * @return the errors collected by the listener for the passed {@link Source}
+   */
+  List<AnalysisError> getErrors2(Source source) {
+    List<AnalysisError> errorsForSource = _errors[source];
+    if (errorsForSource == null) {
+      return AnalysisError.NO_ERRORS;
+    } else {
+      return new List.from(errorsForSource);
+    }
+  }
+  void onError(AnalysisError event) {
+    Source source9 = event.source;
+    List<AnalysisError> errorsForSource = _errors[source9];
+    if (_errors[source9] == null) {
+      errorsForSource = new List<AnalysisError>();
+      _errors[source9] = errorsForSource;
+    }
+    errorsForSource.add(event);
+  }
+}
+/**
+ * Instances of the class {@code SourceInfo} maintain the information known by an analysis context
+ * about an individual source.
+ * @coverage dart.engine
+ */
+class SourceInfo {
+  /**
+   * The kind of the source.
+   */
+  SourceKind _kind;
+  /**
+   * The sources for the defining compilation units for the libraries containing the source, or{@code null} if the libraries containing the source are not yet known.
+   */
+  List<Source> _librarySources = null;
+  SourceInfo.con1(Source source, SourceKind kind3) {
+    _jtd_constructor_161_impl(source, kind3);
+  }
+  _jtd_constructor_161_impl(Source source, SourceKind kind3) {
+    this._kind = kind3;
+  }
+  /**
+   * Initialize a newly created information holder to hold the same information as the given holder.
+   * @param info the information holder used to initialize this holder
+   */
+  SourceInfo.con2(SourceInfo info) {
+    _jtd_constructor_162_impl(info);
+  }
+  _jtd_constructor_162_impl(SourceInfo info) {
+    _kind = info._kind;
+    _librarySources = new List<Source>.from(info._librarySources);
+  }
+  /**
+   * Add the given source to the list of sources for the defining compilation units for the
+   * libraries containing this source.
+   * @param source the source to be added to the list
+   */
+  void addLibrarySource(Source source) {
+    if (_librarySources == null) {
+      _librarySources = new List<Source>();
+    }
+    _librarySources.add(source);
+  }
+  /**
+   * Return the kind of the source.
+   * @return the kind of the source
+   */
+  SourceKind get kind => _kind;
+  /**
+   * Return the sources for the defining compilation units for the libraries containing this source.
+   * @return the sources for the defining compilation units for the libraries containing this source
+   */
+  List<Source> get librarySources {
+    if (_librarySources == null) {
+      return Source.EMPTY_ARRAY;
+    }
+    return new List.from(_librarySources);
+  }
+  /**
+   * Remove the given source from the list of sources for the defining compilation units for the
+   * libraries containing this source.
+   * @param source the source to be removed to the list
+   */
+  void removeLibrarySource(Source source) {
+    _librarySources.remove(source);
+    if (_librarySources.isEmpty) {
+      _librarySources = null;
+    }
+  }
+  /**
+   * Set the kind of the source to the given kind.
+   * @param kind the kind of the source
+   */
+  void set kind(SourceKind kind4) {
+    this._kind = kind4;
+  }
+}
+/**
+ * The interface {@code Logger} defines the behavior of objects that can be used to receive
+ * information about errors within the analysis engine. Implementations usually write this
+ * information to a file, but can also record the information for later use (such as during testing)
+ * or even ignore the information.
+ * @coverage dart.engine.utilities
+ */
+abstract class Logger {
+  static Logger NULL = new Logger_NullLogger();
+  /**
+   * Log the given message as an error.
+   * @param message an explanation of why the error occurred or what it means
+   */
+  void logError(String message);
+  /**
+   * Log the given exception as one representing an error.
+   * @param message an explanation of why the error occurred or what it means
+   * @param exception the exception being logged
+   */
+  void logError2(String message, Exception exception);
+  /**
+   * Log the given exception as one representing an error.
+   * @param exception the exception being logged
+   */
+  void logError3(Exception exception);
+  /**
+   * Log the given informational message.
+   * @param message an explanation of why the error occurred or what it means
+   * @param exception the exception being logged
+   */
+  void logInformation(String message);
+  /**
+   * Log the given exception as one representing an informational message.
+   * @param message an explanation of why the error occurred or what it means
+   * @param exception the exception being logged
+   */
+  void logInformation2(String message, Exception exception);
+}
+/**
+ * Implementation of {@link Logger} that does nothing.
+ */
+class Logger_NullLogger implements Logger {
+  void logError(String message) {
+  }
+  void logError2(String message, Exception exception) {
+  }
+  void logError3(Exception exception) {
+  }
+  void logInformation(String message) {
+  }
+  void logInformation2(String message, Exception exception) {
+  }
+}
\ No newline at end of file
diff --git a/pkg/analyzer_experimental/lib/src/generated/error.dart b/pkg/analyzer_experimental/lib/src/generated/error.dart
new file mode 100644
index 0000000..2693822
--- /dev/null
+++ b/pkg/analyzer_experimental/lib/src/generated/error.dart
@@ -0,0 +1,1461 @@
+// This code was auto-generated, is not intended to be edited, and is subject to
+// significant change. Please see the README file for more information.
+
+library engine.error;
+
+import 'java_core.dart';
+import 'source.dart';
+import 'ast.dart' show ASTNode;
+import 'scanner.dart' show Token;
+
+/**
+ * Instances of the enumeration {@code ErrorSeverity} represent the severity of an {@link ErrorCode}.
+ * @coverage dart.engine.error
+ */
+class ErrorSeverity {
+  /**
+   * The severity representing a non-error. This is never used for any error code, but is useful for
+   * clients.
+   */
+  static final ErrorSeverity NONE = new ErrorSeverity('NONE', 0, " ", "none");
+  /**
+   * The severity representing a warning. Warnings can become errors if the {@code -Werror} command
+   * line flag is specified.
+   */
+  static final ErrorSeverity WARNING = new ErrorSeverity('WARNING', 1, "W", "warning");
+  /**
+   * The severity representing an error.
+   */
+  static final ErrorSeverity ERROR = new ErrorSeverity('ERROR', 2, "E", "error");
+  static final List<ErrorSeverity> values = [NONE, WARNING, ERROR];
+  final String __name;
+  final int __ordinal;
+  int get ordinal => __ordinal;
+  /**
+   * The name of the severity used when producing machine output.
+   */
+  String _machineCode;
+  /**
+   * The name of the severity used when producing readable output.
+   */
+  String _displayName;
+  /**
+   * Initialize a newly created severity with the given names.
+   * @param machineCode the name of the severity used when producing machine output
+   * @param displayName the name of the severity used when producing readable output
+   */
+  ErrorSeverity(this.__name, this.__ordinal, String machineCode, String displayName) {
+    this._machineCode = machineCode;
+    this._displayName = displayName;
+  }
+  /**
+   * Return the name of the severity used when producing readable output.
+   * @return the name of the severity used when producing readable output
+   */
+  String get displayName => _displayName;
+  /**
+   * Return the name of the severity used when producing machine output.
+   * @return the name of the severity used when producing machine output
+   */
+  String get machineCode => _machineCode;
+  /**
+   * Return the severity constant that represents the greatest severity.
+   * @param severity the severity being compared against
+   * @return the most sever of this or the given severity
+   */
+  ErrorSeverity max(ErrorSeverity severity) => this.ordinal >= severity.ordinal ? this : severity;
+  String toString() => __name;
+}
+/**
+ * Instances of the class {@code ErrorReporter} wrap an error listener with utility methods used to
+ * create the errors being reported.
+ * @coverage dart.engine.error
+ */
+class ErrorReporter {
+  /**
+   * The error listener to which errors will be reported.
+   */
+  AnalysisErrorListener _errorListener;
+  /**
+   * The default source to be used when reporting errors.
+   */
+  Source _defaultSource;
+  /**
+   * The source to be used when reporting errors.
+   */
+  Source _source;
+  /**
+   * Initialize a newly created error reporter that will report errors to the given listener.
+   * @param errorListener the error listener to which errors will be reported
+   * @param defaultSource the default source to be used when reporting errors
+   */
+  ErrorReporter(AnalysisErrorListener errorListener, Source defaultSource) {
+    if (errorListener == null) {
+      throw new IllegalArgumentException("An error listener must be provided");
+    } else if (defaultSource == null) {
+      throw new IllegalArgumentException("A default source must be provided");
+    }
+    this._errorListener = errorListener;
+    this._defaultSource = defaultSource;
+    this._source = defaultSource;
+  }
+  /**
+   * Report an error with the given error code and arguments.
+   * @param errorCode the error code of the error to be reported
+   * @param node the node specifying the location of the error
+   * @param arguments the arguments to the error, used to compose the error message
+   */
+  void reportError(ErrorCode errorCode, ASTNode node, List<Object> arguments) {
+    _errorListener.onError(new AnalysisError.con2(_source, node.offset, node.length, errorCode, [arguments]));
+  }
+  /**
+   * Report an error with the given error code and arguments.
+   * @param errorCode the error code of the error to be reported
+   * @param token the token specifying the location of the error
+   * @param arguments the arguments to the error, used to compose the error message
+   */
+  void reportError2(ErrorCode errorCode, Token token, List<Object> arguments) {
+    _errorListener.onError(new AnalysisError.con2(_source, token.offset, token.length, errorCode, [arguments]));
+  }
+  /**
+   * Set the source to be used when reporting errors. Setting the source to {@code null} will cause
+   * the default source to be used.
+   * @param source the source to be used when reporting errors
+   */
+  void set source(Source source7) {
+    this._source = source7 == null ? _defaultSource : source7;
+  }
+}
+/**
+ * Instances of the class {@code AnalysisError} represent an error discovered during the analysis of
+ * some Dart code.
+ * @see AnalysisErrorListener
+ * @coverage dart.engine.error
+ */
+class AnalysisError {
+  /**
+   * An empty array of errors used when no errors are expected.
+   */
+  static List<AnalysisError> NO_ERRORS = new List<AnalysisError>(0);
+  /**
+   * The error code associated with the error.
+   */
+  ErrorCode _errorCode;
+  /**
+   * The localized error message.
+   */
+  String _message;
+  /**
+   * The source in which the error occurred, or {@code null} if unknown.
+   */
+  Source _source;
+  /**
+   * The character offset from the beginning of the source (zero based) where the error occurred.
+   */
+  int _offset = 0;
+  /**
+   * The number of characters from the offset to the end of the source which encompasses the
+   * compilation error.
+   */
+  int _length = 0;
+  /**
+   * Initialize a newly created analysis error for the specified source. The error has no location
+   * information.
+   * @param source the source for which the exception occurred
+   * @param errorCode the error code to be associated with this error
+   * @param arguments the arguments used to build the error message
+   */
+  AnalysisError.con1(Source source2, ErrorCode errorCode2, List<Object> arguments) {
+    _jtd_constructor_129_impl(source2, errorCode2, arguments);
+  }
+  _jtd_constructor_129_impl(Source source2, ErrorCode errorCode2, List<Object> arguments) {
+    this._source = source2;
+    this._errorCode = errorCode2;
+    this._message = JavaString.format(errorCode2.message, arguments);
+  }
+  /**
+   * Initialize a newly created analysis error for the specified source at the given location.
+   * @param source the source for which the exception occurred
+   * @param offset the offset of the location of the error
+   * @param length the length of the location of the error
+   * @param errorCode the error code to be associated with this error
+   * @param arguments the arguments used to build the error message
+   */
+  AnalysisError.con2(Source source3, int offset2, int length11, ErrorCode errorCode3, List<Object> arguments) {
+    _jtd_constructor_130_impl(source3, offset2, length11, errorCode3, arguments);
+  }
+  _jtd_constructor_130_impl(Source source3, int offset2, int length11, ErrorCode errorCode3, List<Object> arguments) {
+    this._source = source3;
+    this._offset = offset2;
+    this._length = length11;
+    this._errorCode = errorCode3;
+    this._message = JavaString.format(errorCode3.message, arguments);
+  }
+  /**
+   * Return the error code associated with the error.
+   * @return the error code associated with the error
+   */
+  ErrorCode get errorCode => _errorCode;
+  /**
+   * Return the number of characters from the offset to the end of the source which encompasses the
+   * compilation error.
+   * @return the length of the error location
+   */
+  int get length => _length;
+  /**
+   * Return the localized error message.
+   * @return the localized error message
+   */
+  String get message => _message;
+  /**
+   * Return the character offset from the beginning of the source (zero based) where the error
+   * occurred.
+   * @return the offset to the start of the error location
+   */
+  int get offset => _offset;
+  /**
+   * Return the source in which the error occurred, or {@code null} if unknown.
+   * @return the source in which the error occurred
+   */
+  Source get source => _source;
+  int get hashCode {
+    int hashCode = _offset;
+    hashCode ^= (_message != null) ? _message.hashCode : 0;
+    hashCode ^= (_source != null) ? _source.hashCode : 0;
+    return hashCode;
+  }
+  /**
+   * Set the source in which the error occurred to the given source.
+   * @param source the source in which the error occurred
+   */
+  void set source(Source source4) {
+    this._source = source4;
+  }
+  String toString() {
+    JavaStringBuilder builder = new JavaStringBuilder();
+    builder.append((_source != null) ? _source.fullName : "<unknown source>");
+    builder.append("(");
+    builder.append(_offset);
+    builder.append("..");
+    builder.append(_offset + _length - 1);
+    builder.append("): ");
+    builder.append(_message);
+    return builder.toString();
+  }
+}
+/**
+ * The interface {@code ErrorCode} defines the behavior common to objects representing error codes
+ * associated with {@link AnalysisError analysis errors}.
+ * @coverage dart.engine.error
+ */
+abstract class ErrorCode {
+  /**
+   * Return the severity of this error.
+   * @return the severity of this error
+   */
+  ErrorSeverity get errorSeverity;
+  /**
+   * Return the message template used to create the message to be displayed for this error.
+   * @return the message template used to create the message to be displayed for this error
+   */
+  String get message;
+  /**
+   * Return the type of the error.
+   * @return the type of the error
+   */
+  ErrorType get type;
+  /**
+   * Return {@code true} if this error should cause recompilation of the source during the next
+   * incremental compilation.
+   * @return {@code true} if this error should cause recompilation of the source during the next
+   * incremental compilation
+   */
+  bool needsRecompilation();
+}
+/**
+ * Instances of the enumeration {@code ErrorType} represent the type of an {@link ErrorCode}.
+ * @coverage dart.engine.error
+ */
+class ErrorType {
+  /**
+   * Compile-time errors are errors that preclude execution. A compile time error must be reported
+   * by a Dart compiler before the erroneous code is executed.
+   */
+  static final ErrorType COMPILE_TIME_ERROR = new ErrorType('COMPILE_TIME_ERROR', 0, ErrorSeverity.ERROR);
+  /**
+   * Static warnings are those warnings reported by the static checker. They have no effect on
+   * execution. Static warnings must be provided by Dart compilers used during development.
+   */
+  static final ErrorType STATIC_WARNING = new ErrorType('STATIC_WARNING', 1, ErrorSeverity.WARNING);
+  /**
+   * Many, but not all, static warnings relate to types, in which case they are known as static type
+   * warnings.
+   */
+  static final ErrorType STATIC_TYPE_WARNING = new ErrorType('STATIC_TYPE_WARNING', 2, ErrorSeverity.WARNING);
+  /**
+   * Syntactic errors are errors produced as a result of input that does not conform to the grammar.
+   */
+  static final ErrorType SYNTACTIC_ERROR = new ErrorType('SYNTACTIC_ERROR', 3, ErrorSeverity.ERROR);
+  static final List<ErrorType> values = [COMPILE_TIME_ERROR, STATIC_WARNING, STATIC_TYPE_WARNING, SYNTACTIC_ERROR];
+  final String __name;
+  final int __ordinal;
+  int get ordinal => __ordinal;
+  /**
+   * The severity of this type of error.
+   */
+  ErrorSeverity _severity;
+  /**
+   * Initialize a newly created error type to have the given severity.
+   * @param severity the severity of this type of error
+   */
+  ErrorType(this.__name, this.__ordinal, ErrorSeverity severity) {
+    this._severity = severity;
+  }
+  /**
+   * Return the severity of this type of error.
+   * @return the severity of this type of error
+   */
+  ErrorSeverity get severity => _severity;
+  String toString() => __name;
+}
+/**
+ * The enumeration {@code CompileTimeErrorCode} defines the error codes used for compile time
+ * errors. The convention for this class is for the name of the error code to indicate the problem
+ * that caused the error to be generated and for the error message to explain what is wrong and,
+ * when appropriate, how the problem can be corrected.
+ * @coverage dart.engine.error
+ */
+class CompileTimeErrorCode implements ErrorCode {
+  /**
+   * 14.2 Exports: It is a compile-time error if a name <i>N</i> is re-exported by a library
+   * <i>L</i> and <i>N</i> is introduced into the export namespace of <i>L</i> by more than one
+   * export.
+   */
+  static final CompileTimeErrorCode AMBIGUOUS_EXPORT = new CompileTimeErrorCode('AMBIGUOUS_EXPORT', 0, "");
+  /**
+   * 14.1 Imports: If a name <i>N</i> is referenced by a library <i>L</i> and <i>N</i> is introduced
+   * into the top level scope <i>L</i> by more than one import then:
+   * <ol>
+   * <li>It is a static warning if <i>N</i> is used as a type annotation.
+   * <li>In checked mode, it is a dynamic error if <i>N</i> is used as a type annotation and
+   * referenced during a subtype test.
+   * <li>Otherwise, it is a compile-time error.
+   * </ol>
+   */
+  static final CompileTimeErrorCode AMBIGUOUS_IMPORT = new CompileTimeErrorCode('AMBIGUOUS_IMPORT', 1, "");
+  /**
+   * 12.33 Argument Definition Test: It is a compile time error if <i>v</i> does not denote a formal
+   * parameter.
+   * @param the name of the identifier in the argument definition test that is not a parameter
+   */
+  static final CompileTimeErrorCode ARGUMENT_DEFINITION_TEST_NON_PARAMETER = new CompileTimeErrorCode('ARGUMENT_DEFINITION_TEST_NON_PARAMETER', 2, "'%s' is not a parameter");
+  /**
+   * 12.30 Identifier Reference: It is a compile-time error to use a built-in identifier other than
+   * dynamic as a type annotation.
+   */
+  static final CompileTimeErrorCode BUILT_IN_IDENTIFIER_AS_TYPE = new CompileTimeErrorCode('BUILT_IN_IDENTIFIER_AS_TYPE', 3, "The built-in identifier '%s' cannot be as a type");
+  /**
+   * 12.30 Identifier Reference: It is a compile-time error if a built-in identifier is used as the
+   * declared name of a class, type parameter or type alias.
+   */
+  static final CompileTimeErrorCode BUILT_IN_IDENTIFIER_AS_TYPE_NAME = new CompileTimeErrorCode('BUILT_IN_IDENTIFIER_AS_TYPE_NAME', 4, "The built-in identifier '%s' cannot be used as a type name");
+  /**
+   * 12.30 Identifier Reference: It is a compile-time error if a built-in identifier is used as the
+   * declared name of a class, type parameter or type alias.
+   */
+  static final CompileTimeErrorCode BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME = new CompileTimeErrorCode('BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME', 5, "The built-in identifier '%s' cannot be used as a type alias name");
+  /**
+   * 12.30 Identifier Reference: It is a compile-time error if a built-in identifier is used as the
+   * declared name of a class, type parameter or type alias.
+   */
+  static final CompileTimeErrorCode BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME = new CompileTimeErrorCode('BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME', 6, "The built-in identifier '%s' cannot be used as a type variable name");
+  /**
+   * 13.9 Switch: It is a compile-time error if the class <i>C</i> implements the operator
+   * <i>==</i>.
+   */
+  static final CompileTimeErrorCode CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS = new CompileTimeErrorCode('CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS', 7, "The switch case expression type '%s' cannot override the == operator");
+  /**
+   * 12.1 Constants: It is a compile-time error if evaluation of a compile-time constant would raise
+   * an exception.
+   */
+  static final CompileTimeErrorCode COMPILE_TIME_CONSTANT_RAISES_EXCEPTION = new CompileTimeErrorCode('COMPILE_TIME_CONSTANT_RAISES_EXCEPTION', 8, "");
+  /**
+   * 12.1 Constants: It is a compile-time error if evaluation of a compile-time constant would raise
+   * an exception.
+   */
+  static final CompileTimeErrorCode COMPILE_TIME_CONSTANT_RAISES_EXCEPTION_DIVIDE_BY_ZERO = new CompileTimeErrorCode('COMPILE_TIME_CONSTANT_RAISES_EXCEPTION_DIVIDE_BY_ZERO', 9, "Cannot divide by zero");
+  /**
+   * 7.6 Constructors: A constructor name always begins with the name of its immediately enclosing
+   * class, and may optionally be followed by a dot and an identifier <i>id</i>. It is a
+   * compile-time error if <i>id</i> is the name of a member declared in the immediately enclosing
+   * class.
+   */
+  static final CompileTimeErrorCode CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD = new CompileTimeErrorCode('CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD', 10, "'%s' cannot be used to name a constructor and a method in this class");
+  /**
+   * 7.6 Constructors: A constructor name always begins with the name of its immediately enclosing
+   * class, and may optionally be followed by a dot and an identifier <i>id</i>. It is a
+   * compile-time error if <i>id</i> is the name of a member declared in the immediately enclosing
+   * class.
+   */
+  static final CompileTimeErrorCode CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD = new CompileTimeErrorCode('CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD', 11, "'%s' cannot be used to name a constructor and a field in this class");
+  /**
+   * 7.6.3 Constant Constructors: It is a compile-time error if a constant constructor is declared
+   * by a class that has a non-final instance variable.
+   */
+  static final CompileTimeErrorCode CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD = new CompileTimeErrorCode('CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD', 12, "Classes with non-final fields cannot define 'const' constructors");
+  /**
+   * 6.2 Formal Parameters: It is a compile-time error if a formal parameter is declared as a
+   * constant variable.
+   */
+  static final CompileTimeErrorCode CONST_FORMAL_PARAMETER = new CompileTimeErrorCode('CONST_FORMAL_PARAMETER', 13, "Parameters cannot be 'const'");
+  /**
+   * 5 Variables: A constant variable must be initialized to a compile-time constant or a
+   * compile-time error occurs.
+   */
+  static final CompileTimeErrorCode CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE = new CompileTimeErrorCode('CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE', 14, "'const' variables must be constant value");
+  /**
+   * 12.11.2 Const: It is a compile-time error if evaluation of a constant object results in an
+   * uncaught exception being thrown.
+   */
+  static final CompileTimeErrorCode CONST_EVAL_THROWS_EXCEPTION = new CompileTimeErrorCode('CONST_EVAL_THROWS_EXCEPTION', 15, "");
+  /**
+   * 12.11.2 Const: If <i>T</i> is a parameterized type <i>S&lt;U<sub>1</sub>, &hellip;,
+   * U<sub>m</sub>&gt;</i>, let <i>R = S</i>; It is a compile time error if <i>S</i> is not a
+   * generic type with <i>m</i> type parameters.
+   * @param typeName the name of the type being referenced (<i>S</i>)
+   * @param argumentCount the number of type arguments provided
+   * @param parameterCount the number of type parameters that were declared
+   */
+  static final CompileTimeErrorCode CONST_WITH_INVALID_TYPE_PARAMETERS = new CompileTimeErrorCode('CONST_WITH_INVALID_TYPE_PARAMETERS', 16, "The type '%s' is declared with %d type parameters, but %d type arguments were given");
+  /**
+   * 12.11.2 Const: If <i>e</i> is of the form <i>const T(a<sub>1</sub>, &hellip;, a<sub>n</sub>,
+   * x<sub>n+1</sub>: a<sub>n+1</sub>, &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i> it is a
+   * compile-time error if the type <i>T</i> does not declare a constant constructor with the same
+   * name as the declaration of <i>T</i>.
+   */
+  static final CompileTimeErrorCode CONST_WITH_NON_CONST = new CompileTimeErrorCode('CONST_WITH_NON_CONST', 17, "The constructor being called is not a 'const' constructor");
+  /**
+   * 12.11.2 Const: In all of the above cases, it is a compile-time error if <i>a<sub>i</sub>, 1
+   * &lt;= i &lt;= n + k</i>, is not a compile-time constant expression.
+   */
+  static final CompileTimeErrorCode CONST_WITH_NON_CONSTANT_ARGUMENT = new CompileTimeErrorCode('CONST_WITH_NON_CONSTANT_ARGUMENT', 18, "");
+  /**
+   * 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.
+   * <p>
+   * 12.11.2 Const: If <i>e</i> is of the form <i>const T.id(a<sub>1</sub>, &hellip;, a<sub>n</sub>,
+   * x<sub>n+1</sub>: a<sub>n+1</sub>, &hellip; x<sub>n+k</sub>: a<sub>n+k</sub>)</i> 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 final CompileTimeErrorCode CONST_WITH_NON_TYPE = new CompileTimeErrorCode('CONST_WITH_NON_TYPE', 19, "");
+  /**
+   * 12.11.2 Const: It is a compile-time error if <i>T</i> includes any type parameters.
+   */
+  static final CompileTimeErrorCode CONST_WITH_TYPE_PARAMETERS = new CompileTimeErrorCode('CONST_WITH_TYPE_PARAMETERS', 20, "");
+  /**
+   * 12.11.2 Const: It is a compile-time error if <i>T.id</i> is not the name of a constant
+   * constructor declared by the type <i>T</i>.
+   */
+  static final CompileTimeErrorCode CONST_WITH_UNDEFINED_CONSTRUCTOR = new CompileTimeErrorCode('CONST_WITH_UNDEFINED_CONSTRUCTOR', 21, "");
+  /**
+   * 15.3.1 Typedef: It is a compile-time error if any default values are specified in the signature
+   * of a function type alias.
+   */
+  static final CompileTimeErrorCode DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS = new CompileTimeErrorCode('DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS', 22, "");
+  /**
+   * 3.1 Scoping: It is a compile-time error if there is more than one entity with the same name
+   * declared in the same scope.
+   * @param duplicateName the name of the duplicate entity
+   */
+  static final CompileTimeErrorCode DUPLICATE_DEFINITION = new CompileTimeErrorCode('DUPLICATE_DEFINITION', 23, "The name '%s' is already defined");
+  /**
+   * 7 Classes: It is a compile-time error if a class declares two members of the same name.
+   */
+  static final CompileTimeErrorCode DUPLICATE_MEMBER_NAME = new CompileTimeErrorCode('DUPLICATE_MEMBER_NAME', 24, "");
+  /**
+   * 7 Classes: It is a compile-time error if a class has an instance member and a static member
+   * with the same name.
+   */
+  static final CompileTimeErrorCode DUPLICATE_MEMBER_NAME_INSTANCE_STATIC = new CompileTimeErrorCode('DUPLICATE_MEMBER_NAME_INSTANCE_STATIC', 25, "");
+  /**
+   * 12.14.2 Binding Actuals to Formals: It is a compile-time error if <i>q<sub>i</sub> =
+   * q<sub>j</sub></i> for any <i>i != j</i> [where <i>q<sub>i</sub></i> is the label for a named
+   * argument].
+   */
+  static final CompileTimeErrorCode DUPLICATE_NAMED_ARGUMENT = new CompileTimeErrorCode('DUPLICATE_NAMED_ARGUMENT', 26, "");
+  /**
+   * 14.2 Exports: It is a compile-time error if the compilation unit found at the specified URI is
+   * not a library declaration.
+   */
+  static final CompileTimeErrorCode EXPORT_OF_NON_LIBRARY = new CompileTimeErrorCode('EXPORT_OF_NON_LIBRARY', 27, "");
+  /**
+   * 7.9 Superclasses: It is a compile-time error if the extends clause of a class <i>C</i> includes
+   * a type expression that does not denote a class available in the lexical scope of <i>C</i>.
+   * @param typeName the name of the superclass that was not found
+   */
+  static final CompileTimeErrorCode EXTENDS_NON_CLASS = new CompileTimeErrorCode('EXTENDS_NON_CLASS', 28, "Classes can only extend other classes");
+  /**
+   * 12.2 Null: It is a compile-time error for a class to attempt to extend or implement Null.
+   * <p>
+   * 12.3 Numbers: It is a compile-time error for a class to attempt to extend or implement int.
+   * <p>
+   * 12.3 Numbers: It is a compile-time error for a class to attempt to extend or implement double.
+   * <p>
+   * 12.3 Numbers: It is a compile-time error for any type other than the types int and double to
+   * attempt to extend or implement num.
+   * <p>
+   * 12.4 Booleans: It is a compile-time error for a class to attempt to extend or implement bool.
+   * <p>
+   * 12.5 Strings: It is a compile-time error for a class to attempt to extend or implement String.
+   */
+  static final CompileTimeErrorCode EXTENDS_OR_IMPLEMENTS_DISALLOWED_CLASS = new CompileTimeErrorCode('EXTENDS_OR_IMPLEMENTS_DISALLOWED_CLASS', 29, "");
+  /**
+   * 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It is a compile time
+   * error if more than one initializer corresponding to a given instance variable appears in
+   * <i>k</i>’s list.
+   */
+  static final CompileTimeErrorCode FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS = new CompileTimeErrorCode('FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS', 30, "");
+  /**
+   * 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It is a compile time
+   * error if <i>k</i>’s initializer list contains an initializer for a final variable <i>f</i>
+   * whose declaration includes an initialization expression.
+   */
+  static final CompileTimeErrorCode FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION = new CompileTimeErrorCode('FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION', 31, "");
+  /**
+   * 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It is a compile time
+   * error if <i>k</i>’s initializer list contains an initializer for a variable that is initialized
+   * by means of an initializing formal of <i>k</i>.
+   */
+  static final CompileTimeErrorCode FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER = new CompileTimeErrorCode('FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER', 32, "");
+  /**
+   * 7.6.1 Generative Constructors: It is a compile-time error if an initializing formal is used by
+   * a function other than a non-redirecting generative constructor.
+   */
+  static final CompileTimeErrorCode FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR = new CompileTimeErrorCode('FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR', 33, "");
+  /**
+   * 5 Variables: It is a compile-time error if a final instance variable that has been initialized
+   * at its point of declaration is also initialized in a constructor.
+   */
+  static final CompileTimeErrorCode FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR = new CompileTimeErrorCode('FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR', 34, "");
+  /**
+   * 5 Variables: It is a compile-time error if a final instance variable that has is initialized by
+   * means of an initializing formal of a constructor is also initialized elsewhere in the same
+   * constructor.
+   */
+  static final CompileTimeErrorCode FINAL_INITIALIZED_MULTIPLE_TIMES = new CompileTimeErrorCode('FINAL_INITIALIZED_MULTIPLE_TIMES', 35, "");
+  /**
+   * 5 Variables: It is a compile-time error if a library, static or local variable <i>v</i> is
+   * final and <i>v</i> is not initialized at its point of declaration.
+   */
+  static final CompileTimeErrorCode FINAL_NOT_INITIALIZED = new CompileTimeErrorCode('FINAL_NOT_INITIALIZED', 36, "");
+  /**
+   * 7.2 Getters: It is a compile-time error if a class has both a getter and a method with the same
+   * name.
+   */
+  static final CompileTimeErrorCode GETTER_AND_METHOD_WITH_SAME_NAME = new CompileTimeErrorCode('GETTER_AND_METHOD_WITH_SAME_NAME', 37, "");
+  /**
+   * 7.10 Superinterfaces: It is a compile-time error if the implements clause of a class includes
+   * type dynamic.
+   */
+  static final CompileTimeErrorCode IMPLEMENTS_DYNAMIC = new CompileTimeErrorCode('IMPLEMENTS_DYNAMIC', 38, "");
+  /**
+   * 7.10 Superinterfaces: It is a compile-time error if the implements clause of a class <i>C</i>
+   * includes a type expression that does not denote a class available in the lexical scope of
+   * <i>C</i>.
+   * @param typeName the name of the interface that was not found
+   */
+  static final CompileTimeErrorCode IMPLEMENTS_NON_CLASS = new CompileTimeErrorCode('IMPLEMENTS_NON_CLASS', 39, "Classes can only implement other classes");
+  /**
+   * 7.10 Superinterfaces: It is a compile-time error if a type <i>T</i> appears more than once in
+   * the implements clause of a class.
+   */
+  static final CompileTimeErrorCode IMPLEMENTS_REPEATED = new CompileTimeErrorCode('IMPLEMENTS_REPEATED', 40, "");
+  /**
+   * 7.10 Superinterfaces: It is a compile-time error if the interface of a class <i>C</i> is a
+   * superinterface of itself.
+   */
+  static final CompileTimeErrorCode IMPLEMENTS_SELF = new CompileTimeErrorCode('IMPLEMENTS_SELF', 41, "");
+  /**
+   * 14.1 Imports: It is a compile-time error to import two different libraries with the same name.
+   */
+  static final CompileTimeErrorCode IMPORT_DUPLICATED_LIBRARY_NAME = new CompileTimeErrorCode('IMPORT_DUPLICATED_LIBRARY_NAME', 42, "");
+  /**
+   * 14.1 Imports: It is a compile-time error if the compilation unit found at the specified URI is
+   * not a library declaration.
+   */
+  static final CompileTimeErrorCode IMPORT_OF_NON_LIBRARY = new CompileTimeErrorCode('IMPORT_OF_NON_LIBRARY', 43, "");
+  /**
+   * 13.9 Switch: It is a compile-time error if values of the expressions <i>e<sub>k</sub></i> are
+   * not instances of the same class <i>C</i>, for all <i>1 &lt;= k &lt;= n</i>.
+   */
+  static final CompileTimeErrorCode INCONSITENT_CASE_EXPRESSION_TYPES = new CompileTimeErrorCode('INCONSITENT_CASE_EXPRESSION_TYPES', 44, "");
+  /**
+   * 7.6.1 Generative Constructors: An initializing formal has the form <i>this.id</i>. It is a
+   * compile-time error if <i>id</i> is not the name of an instance variable of the immediately
+   * enclosing class.
+   */
+  static final CompileTimeErrorCode INITIALIZER_FOR_NON_EXISTANT_FIELD = new CompileTimeErrorCode('INITIALIZER_FOR_NON_EXISTANT_FIELD', 45, "");
+  /**
+   * TODO(brianwilkerson) Remove this when we have decided on how to report errors in compile-time
+   * constants. Until then, this acts as a placeholder for more informative errors.
+   */
+  static final CompileTimeErrorCode INVALID_CONSTANT = new CompileTimeErrorCode('INVALID_CONSTANT', 46, "");
+  /**
+   * 7.6 Constructors: It is a compile-time error if the name of a constructor is not a constructor
+   * name.
+   */
+  static final CompileTimeErrorCode INVALID_CONSTRUCTOR_NAME = new CompileTimeErrorCode('INVALID_CONSTRUCTOR_NAME', 47, "");
+  /**
+   * 7.6.2 Factories: It is a compile-time error if <i>M</i> is not the name of the immediately
+   * enclosing class.
+   */
+  static final CompileTimeErrorCode INVALID_FACTORY_NAME_NOT_A_CLASS = new CompileTimeErrorCode('INVALID_FACTORY_NAME_NOT_A_CLASS', 48, "");
+  /**
+   * 7.1 Instance Methods: It is a static warning if an instance method <i>m1</i> overrides an
+   * instance member <i>m2</i>, the signature of <i>m2</i> explicitly specifies a default value for
+   * a formal parameter <i>p</i> and the signature of <i>m1</i> specifies a different default value
+   * for <i>p</i>.
+   */
+  static final CompileTimeErrorCode INVALID_OVERRIDE_DEFAULT_VALUE = new CompileTimeErrorCode('INVALID_OVERRIDE_DEFAULT_VALUE', 49, "");
+  /**
+   * 7.1: It is a compile-time error if an instance method <i>m1</i> overrides an instance member
+   * <i>m2</i> and <i>m1</i> does not declare all the named parameters declared by <i>m2</i>.
+   */
+  static final CompileTimeErrorCode INVALID_OVERRIDE_NAMED = new CompileTimeErrorCode('INVALID_OVERRIDE_NAMED', 50, "");
+  /**
+   * 7.1 Instance Methods: It is a compile-time error if an instance method m1 overrides an instance
+   * member <i>m2</i> and <i>m1</i> has fewer optional positional parameters than <i>m2</i>.
+   */
+  static final CompileTimeErrorCode INVALID_OVERRIDE_POSITIONAL = new CompileTimeErrorCode('INVALID_OVERRIDE_POSITIONAL', 51, "");
+  /**
+   * 7.1 Instance Methods: It is a compile-time error if an instance method <i>m1</i> overrides an
+   * instance member <i>m2</i> and <i>m1</i> has a different number of required parameters than
+   * <i>m2</i>.
+   */
+  static final CompileTimeErrorCode INVALID_OVERRIDE_REQUIRED = new CompileTimeErrorCode('INVALID_OVERRIDE_REQUIRED', 52, "");
+  /**
+   * 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 final CompileTimeErrorCode INVALID_REFERENCE_TO_THIS = new CompileTimeErrorCode('INVALID_REFERENCE_TO_THIS', 53, "");
+  /**
+   * 12.7 Maps: It is a compile-time error if the first type argument to a map literal is not
+   * String.
+   */
+  static final CompileTimeErrorCode INVALID_TYPE_ARGUMENT_FOR_KEY = new CompileTimeErrorCode('INVALID_TYPE_ARGUMENT_FOR_KEY', 54, "");
+  /**
+   * 12.6 Lists: It is a compile time error if the type argument of a constant list literal includes
+   * a type parameter.
+   */
+  static final CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_LIST = new CompileTimeErrorCode('INVALID_TYPE_ARGUMENT_IN_CONST_LIST', 55, "");
+  /**
+   * 12.7 Maps: It is a compile time error if the type arguments of a constant map literal include a
+   * type parameter.
+   */
+  static final CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_MAP = new CompileTimeErrorCode('INVALID_TYPE_ARGUMENT_IN_CONST_MAP', 56, "");
+  /**
+   * 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It is a compile-time
+   * error if <i>k</i>'s initializer list contains an initializer for a variable that is not an
+   * instance variable declared in the immediately surrounding class.
+   */
+  static final CompileTimeErrorCode INVALID_VARIABLE_IN_INITIALIZER = new CompileTimeErrorCode('INVALID_VARIABLE_IN_INITIALIZER', 57, "");
+  /**
+   * 13.13 Break: It is a compile-time error if no such statement <i>s<sub>E</sub></i> exists within
+   * the innermost function in which <i>s<sub>b</sub></i> occurs.
+   * <p>
+   * 13.14 Continue: It is a compile-time error if no such statement or case clause
+   * <i>s<sub>E</sub></i> exists within the innermost function in which <i>s<sub>c</sub></i> occurs.
+   * @param labelName the name of the unresolvable label
+   */
+  static final CompileTimeErrorCode LABEL_IN_OUTER_SCOPE = new CompileTimeErrorCode('LABEL_IN_OUTER_SCOPE', 58, "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
+   * the innermost function in which <i>s<sub>b</sub></i> occurs.
+   * <p>
+   * 13.14 Continue: It is a compile-time error if no such statement or case clause
+   * <i>s<sub>E</sub></i> exists within the innermost function in which <i>s<sub>c</sub></i> occurs.
+   * @param labelName the name of the unresolvable label
+   */
+  static final CompileTimeErrorCode LABEL_UNDEFINED = new CompileTimeErrorCode('LABEL_UNDEFINED', 59, "Cannot reference undefined label '%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 final CompileTimeErrorCode MEMBER_WITH_CLASS_NAME = new CompileTimeErrorCode('MEMBER_WITH_CLASS_NAME', 60, "");
+  /**
+   * 9 Mixins: It is a compile-time error if a declared or derived mixin explicitly declares a
+   * constructor.
+   */
+  static final CompileTimeErrorCode MIXIN_DECLARES_CONSTRUCTOR = new CompileTimeErrorCode('MIXIN_DECLARES_CONSTRUCTOR', 61, "");
+  /**
+   * 9 Mixins: It is a compile-time error if a mixin is derived from a class whose superclass is not
+   * Object.
+   */
+  static final CompileTimeErrorCode MIXIN_INHERITS_FROM_NOT_OBJECT = new CompileTimeErrorCode('MIXIN_INHERITS_FROM_NOT_OBJECT', 62, "");
+  /**
+   * 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.
+   * @param typeName the name of the mixin that was not found
+   */
+  static final CompileTimeErrorCode MIXIN_OF_NON_CLASS = new CompileTimeErrorCode('MIXIN_OF_NON_CLASS', 63, "Classes can only mixin other classes");
+  /**
+   * 9.1 Mixin Application: If <i>M</i> is a class, it is a compile time error if a well formed
+   * mixin cannot be derived from <i>M</i>.
+   */
+  static final CompileTimeErrorCode MIXIN_OF_NON_MIXIN = new CompileTimeErrorCode('MIXIN_OF_NON_MIXIN', 64, "");
+  /**
+   * 9 Mixins: It is a compile-time error if a declared or derived mixin refers to super.
+   */
+  static final CompileTimeErrorCode MIXIN_REFERENCES_SUPER = new CompileTimeErrorCode('MIXIN_REFERENCES_SUPER', 65, "");
+  /**
+   * 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 final CompileTimeErrorCode MIXIN_WITH_NON_CLASS_SUPERCLASS = new CompileTimeErrorCode('MIXIN_WITH_NON_CLASS_SUPERCLASS', 66, "");
+  /**
+   * 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 final CompileTimeErrorCode MULTIPLE_SUPER_INITIALIZERS = new CompileTimeErrorCode('MULTIPLE_SUPER_INITIALIZERS', 67, "");
+  /**
+   * 12.11.1 New: It is a compile time error if <i>S</i> is not a generic type with <i>m</i> type
+   * parameters.
+   * @param typeName the name of the type being referenced (<i>S</i>)
+   * @param argumentCount the number of type arguments provided
+   * @param parameterCount the number of type parameters that were declared
+   */
+  static final CompileTimeErrorCode NEW_WITH_INVALID_TYPE_PARAMETERS = new CompileTimeErrorCode('NEW_WITH_INVALID_TYPE_PARAMETERS', 68, "The type '%s' is declared with %d type parameters, but %d type arguments were given");
+  /**
+   * 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 final CompileTimeErrorCode NON_CONST_MAP_AS_EXPRESSION_STATEMENT = new CompileTimeErrorCode('NON_CONST_MAP_AS_EXPRESSION_STATEMENT', 69, "");
+  /**
+   * 13.9 Switch: Given a switch statement of the form <i>switch (e) { label<sub>11</sub> &hellip;
+   * label<sub>1j1</sub> case e<sub>1</sub>: s<sub>1</sub> &hellip; label<sub>n1</sub> &hellip;
+   * label<sub>njn</sub> case e<sub>n</sub>: s<sub>n</sub> default: s<sub>n+1</sub>}</i> or the form
+   * <i>switch (e) { label<sub>11</sub> &hellip; label<sub>1j1</sub> case e<sub>1</sub>:
+   * s<sub>1</sub> &hellip; label<sub>n1</sub> &hellip; label<sub>njn</sub> case e<sub>n</sub>:
+   * 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 final CompileTimeErrorCode NON_CONSTANT_CASE_EXPRESSION = new CompileTimeErrorCode('NON_CONSTANT_CASE_EXPRESSION', 70, "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 final CompileTimeErrorCode NON_CONSTANT_DEFAULT_VALUE = new CompileTimeErrorCode('NON_CONSTANT_DEFAULT_VALUE', 71, "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 final CompileTimeErrorCode NON_CONSTANT_LIST_ELEMENT = new CompileTimeErrorCode('NON_CONSTANT_LIST_ELEMENT', 72, "'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 final CompileTimeErrorCode NON_CONSTANT_MAP_KEY = new CompileTimeErrorCode('NON_CONSTANT_MAP_KEY', 73, "The keys in a 'const' 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 final CompileTimeErrorCode NON_CONSTANT_MAP_VALUE = new CompileTimeErrorCode('NON_CONSTANT_MAP_VALUE', 74, "The values in a 'const' map must be constant");
+  /**
+   * 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 final CompileTimeErrorCode NON_CONSTANT_VALUE_IN_INITIALIZER = new CompileTimeErrorCode('NON_CONSTANT_VALUE_IN_INITIALIZER', 75, "");
+  /**
+   * 7.9 Superclasses: It is a compile-time error to specify an extends clause for class Object.
+   */
+  static final CompileTimeErrorCode OBJECT_CANNOT_EXTEND_ANOTHER_CLASS = new CompileTimeErrorCode('OBJECT_CANNOT_EXTEND_ANOTHER_CLASS', 76, "");
+  /**
+   * 7.1.1 Operators: It is a compile-time error to declare an optional parameter in an operator.
+   */
+  static final CompileTimeErrorCode OPTIONAL_PARAMETER_IN_OPERATOR = new CompileTimeErrorCode('OPTIONAL_PARAMETER_IN_OPERATOR', 77, "");
+  /**
+   * 8 Interfaces: It is a compile-time error if an interface member <i>m1</i> overrides an
+   * interface member <i>m2</i> and <i>m1</i> does not declare all the named parameters declared by
+   * <i>m2</i> in the same order.
+   */
+  static final CompileTimeErrorCode OVERRIDE_MISSING_NAMED_PARAMETERS = new CompileTimeErrorCode('OVERRIDE_MISSING_NAMED_PARAMETERS', 78, "");
+  /**
+   * 8 Interfaces: It is a compile-time error if an interface member <i>m1</i> overrides an
+   * interface member <i>m2</i> and <i>m1</i> has a different number of required parameters than
+   * <i>m2</i>.
+   */
+  static final CompileTimeErrorCode OVERRIDE_MISSING_REQUIRED_PARAMETERS = new CompileTimeErrorCode('OVERRIDE_MISSING_REQUIRED_PARAMETERS', 79, "");
+  /**
+   * 14.3 Parts: It is a compile time error if the contents of the URI are not a valid part
+   * declaration.
+   */
+  static final CompileTimeErrorCode PART_OF_NON_PART = new CompileTimeErrorCode('PART_OF_NON_PART', 80, "");
+  /**
+   * 14.1 Imports: It is a compile-time error if the current library declares a top-level member
+   * named <i>p</i>.
+   */
+  static final CompileTimeErrorCode PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER = new CompileTimeErrorCode('PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER', 81, "");
+  /**
+   * 6.2.2 Optional Formals: It is a compile-time error if the name of a named optional parameter
+   * begins with an ‘_’ character.
+   */
+  static final CompileTimeErrorCode PRIVATE_OPTIONAL_PARAMETER = new CompileTimeErrorCode('PRIVATE_OPTIONAL_PARAMETER', 82, "");
+  /**
+   * 12.1 Constants: It is a compile-time error if the value of a compile-time constant expression
+   * depends on itself.
+   */
+  static final CompileTimeErrorCode RECURSIVE_COMPILE_TIME_CONSTANT = new CompileTimeErrorCode('RECURSIVE_COMPILE_TIME_CONSTANT', 83, "");
+  /**
+   * 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 final CompileTimeErrorCode RECURSIVE_FACTORY_REDIRECT = new CompileTimeErrorCode('RECURSIVE_FACTORY_REDIRECT', 84, "");
+  /**
+   * 15.3.1 Typedef: It is a compile-time error if a typedef refers to itself via a chain of
+   * references that does not include a class type.
+   */
+  static final CompileTimeErrorCode RECURSIVE_FUNCTION_TYPE_ALIAS = new CompileTimeErrorCode('RECURSIVE_FUNCTION_TYPE_ALIAS', 85, "");
+  /**
+   * 8.1 Superinterfaces: It is a compile-time error if an interface is a superinterface of itself.
+   */
+  static final CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE = new CompileTimeErrorCode('RECURSIVE_INTERFACE_INHERITANCE', 86, "");
+  /**
+   * 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 final CompileTimeErrorCode REDIRECT_TO_NON_CONST_CONSTRUCTOR = new CompileTimeErrorCode('REDIRECT_TO_NON_CONST_CONSTRUCTOR', 87, "");
+  /**
+   * 13.3 Local Variable Declaration: It is a compile-time error if <i>e</i> refers to the name
+   * <i>v</i> or the name <i>v=</i>.
+   */
+  static final CompileTimeErrorCode REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER = new CompileTimeErrorCode('REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER', 88, "");
+  /**
+   * 16.1.1 Reserved Words: A reserved word may not be used as an identifier; it is a compile-time
+   * error if a reserved word is used where an identifier is expected.
+   */
+  static final CompileTimeErrorCode RESERVED_WORD_AS_IDENTIFIER = new CompileTimeErrorCode('RESERVED_WORD_AS_IDENTIFIER', 89, "");
+  /**
+   * 13.11 Return: It is a compile-time error if a return statement of the form <i>return e;</i>
+   * appears in a generative constructor.
+   */
+  static final CompileTimeErrorCode RETURN_IN_GENERATIVE_CONSTRUCTOR = new CompileTimeErrorCode('RETURN_IN_GENERATIVE_CONSTRUCTOR', 90, "");
+  /**
+   * 6.1 Function Declarations: It is a compile-time error to preface a function declaration with
+   * the built-in identifier static.
+   */
+  static final CompileTimeErrorCode STATIC_TOP_LEVEL_FUNCTION = new CompileTimeErrorCode('STATIC_TOP_LEVEL_FUNCTION', 91, "");
+  /**
+   * 5 Variables: It is a compile-time error to preface a top level variable declaration with the
+   * built-in identifier static.
+   */
+  static final CompileTimeErrorCode STATIC_TOP_LEVEL_VARIABLE = new CompileTimeErrorCode('STATIC_TOP_LEVEL_VARIABLE', 92, "");
+  /**
+   * 12.15.4 Super Invocation: A super method invocation <i>i</i> has the form
+   * <i>super.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>, &hellip;
+   * x<sub>n+k</sub>: a<sub>n+k</sub>)</i>. It is a compile-time error if a super method invocation
+   * occurs in a top-level function or variable initializer, in an instance variable initializer or
+   * initializer list, in class Object, in a factory constructor, or in a static method or variable
+   * initializer.
+   */
+  static final CompileTimeErrorCode SUPER_IN_INVALID_CONTEXT = new CompileTimeErrorCode('SUPER_IN_INVALID_CONTEXT', 93, "");
+  /**
+   * 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 final CompileTimeErrorCode SUPER_INITIALIZER_IN_OBJECT = new CompileTimeErrorCode('SUPER_INITIALIZER_IN_OBJECT', 94, "");
+  /**
+   * 12.8 Throw: It is a compile-time error if an expression of the form throw; is not enclosed
+   * within a on-catch clause.
+   */
+  static final CompileTimeErrorCode THROW_WITHOUT_VALUE_OUTSIDE_ON = new CompileTimeErrorCode('THROW_WITHOUT_VALUE_OUTSIDE_ON', 95, "");
+  /**
+   * 12.11 Instance Creation: It is a compile-time error if a constructor of a non-generic type
+   * invoked by a new expression or a constant object expression is passed any type arguments.
+   * <p>
+   * 12.32 Type Cast: It is a compile-time error if <i>T</i> is a parameterized type of the form
+   * <i>G&lt;T<sub>1</sub>, &hellip;, T<sub>n</sub>&gt;</i> and <i>G</i> is not a generic type with
+   * <i>n</i> type parameters.
+   */
+  static final CompileTimeErrorCode TYPE_ARGUMENTS_FOR_NON_GENERIC_CLASS = new CompileTimeErrorCode('TYPE_ARGUMENTS_FOR_NON_GENERIC_CLASS', 96, "");
+  /**
+   * 7.6.1 Generative Constructors: Let <i>C</i> be the class in which the superinitializer appears
+   * and let <i>S</i> be the superclass of <i>C</i>. Let <i>k</i> be a generative constructor. 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 final CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER = new CompileTimeErrorCode('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER', 97, "");
+  /**
+   * 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. Each final instance
+   * variable <i>f</i> declared in the immediately enclosing class must have an initializer in
+   * <i>k</i>'s initializer list unless it has already been initialized by one of the following
+   * means:
+   * <ol>
+   * <li>Initialization at the declaration of <i>f</i>.
+   * <li>Initialization by means of an initializing formal of <i>k</i>.
+   * </ol>
+   * or a compile-time error occurs.
+   */
+  static final CompileTimeErrorCode UNINITIALIZED_FINAL_FIELD = new CompileTimeErrorCode('UNINITIALIZED_FINAL_FIELD', 98, "");
+  /**
+   * 14.1 Imports: It is a compile-time error if <i>x</i> is not a compile-time constant, or if
+   * <i>x</i> involves string interpolation.
+   * <p>
+   * 14.3 Parts: It is a compile-time error if <i>s</i> is not a compile-time constant, or if
+   * <i>s</i> involves string interpolation.
+   * <p>
+   * 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 final CompileTimeErrorCode URI_WITH_INTERPOLATION = new CompileTimeErrorCode('URI_WITH_INTERPOLATION', 99, "URIs cannot use string interpolation");
+  /**
+   * 7.1.1 Operators: It is a compile-time error if the arity of the user-declared operator []= is
+   * not 2. It is a compile time error if the arity of a user-declared operator with one of the
+   * names: &lt;, &gt;, &lt;=, &gt;=, ==, +, /, ~/, *, %, |, ^, &, &lt;&lt;, &gt;&gt;, [] is not 1.
+   * It is a compile time error if the arity of the user-declared operator - is not 0 or 1. It is a
+   * compile time error if the arity of the user-declared operator ~ is not 0.
+   */
+  static final CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR = new CompileTimeErrorCode('WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR', 100, "");
+  /**
+   * 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 final CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER = new CompileTimeErrorCode('WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER', 101, "");
+  /**
+   * 12.11 Instance Creation: It is a compile-time error if a constructor of a generic type with
+   * <i>n</i> type parameters invoked by a new expression or a constant object expression is passed
+   * <i>m</i> type arguments where <i>m != n</i>.
+   * <p>
+   * 12.31 Type Test: It is a compile-time error if <i>T</i> is a parameterized type of the form
+   * <i>G&lt;T<sub>1</sub>, &hellip;, T<sub>n</sub>&gt;</i> and <i>G</i> is not a generic type with
+   * <i>n</i> type parameters.
+   */
+  static final CompileTimeErrorCode WRONG_NUMBER_OF_TYPE_ARGUMENTS = new CompileTimeErrorCode('WRONG_NUMBER_OF_TYPE_ARGUMENTS', 102, "");
+  static final List<CompileTimeErrorCode> values = [AMBIGUOUS_EXPORT, AMBIGUOUS_IMPORT, ARGUMENT_DEFINITION_TEST_NON_PARAMETER, BUILT_IN_IDENTIFIER_AS_TYPE, BUILT_IN_IDENTIFIER_AS_TYPE_NAME, BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS, COMPILE_TIME_CONSTANT_RAISES_EXCEPTION, COMPILE_TIME_CONSTANT_RAISES_EXCEPTION_DIVIDE_BY_ZERO, CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD, CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD, CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD, CONST_FORMAL_PARAMETER, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, CONST_EVAL_THROWS_EXCEPTION, CONST_WITH_INVALID_TYPE_PARAMETERS, CONST_WITH_NON_CONST, CONST_WITH_NON_CONSTANT_ARGUMENT, CONST_WITH_NON_TYPE, CONST_WITH_TYPE_PARAMETERS, CONST_WITH_UNDEFINED_CONSTRUCTOR, DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS, DUPLICATE_DEFINITION, DUPLICATE_MEMBER_NAME, DUPLICATE_MEMBER_NAME_INSTANCE_STATIC, DUPLICATE_NAMED_ARGUMENT, EXPORT_OF_NON_LIBRARY, EXTENDS_NON_CLASS, EXTENDS_OR_IMPLEMENTS_DISALLOWED_CLASS, FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS, FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION, FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER, FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR, FINAL_INITIALIZED_MULTIPLE_TIMES, FINAL_NOT_INITIALIZED, GETTER_AND_METHOD_WITH_SAME_NAME, IMPLEMENTS_DYNAMIC, IMPLEMENTS_NON_CLASS, IMPLEMENTS_REPEATED, IMPLEMENTS_SELF, IMPORT_DUPLICATED_LIBRARY_NAME, IMPORT_OF_NON_LIBRARY, INCONSITENT_CASE_EXPRESSION_TYPES, INITIALIZER_FOR_NON_EXISTANT_FIELD, INVALID_CONSTANT, INVALID_CONSTRUCTOR_NAME, INVALID_FACTORY_NAME_NOT_A_CLASS, INVALID_OVERRIDE_DEFAULT_VALUE, INVALID_OVERRIDE_NAMED, INVALID_OVERRIDE_POSITIONAL, INVALID_OVERRIDE_REQUIRED, INVALID_REFERENCE_TO_THIS, INVALID_TYPE_ARGUMENT_FOR_KEY, INVALID_TYPE_ARGUMENT_IN_CONST_LIST, INVALID_TYPE_ARGUMENT_IN_CONST_MAP, INVALID_VARIABLE_IN_INITIALIZER, LABEL_IN_OUTER_SCOPE, LABEL_UNDEFINED, MEMBER_WITH_CLASS_NAME, MIXIN_DECLARES_CONSTRUCTOR, MIXIN_INHERITS_FROM_NOT_OBJECT, MIXIN_OF_NON_CLASS, MIXIN_OF_NON_MIXIN, MIXIN_REFERENCES_SUPER, MIXIN_WITH_NON_CLASS_SUPERCLASS, MULTIPLE_SUPER_INITIALIZERS, NEW_WITH_INVALID_TYPE_PARAMETERS, NON_CONST_MAP_AS_EXPRESSION_STATEMENT, NON_CONSTANT_CASE_EXPRESSION, NON_CONSTANT_DEFAULT_VALUE, NON_CONSTANT_LIST_ELEMENT, NON_CONSTANT_MAP_KEY, NON_CONSTANT_MAP_VALUE, NON_CONSTANT_VALUE_IN_INITIALIZER, OBJECT_CANNOT_EXTEND_ANOTHER_CLASS, OPTIONAL_PARAMETER_IN_OPERATOR, OVERRIDE_MISSING_NAMED_PARAMETERS, OVERRIDE_MISSING_REQUIRED_PARAMETERS, PART_OF_NON_PART, PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER, PRIVATE_OPTIONAL_PARAMETER, RECURSIVE_COMPILE_TIME_CONSTANT, RECURSIVE_FACTORY_REDIRECT, RECURSIVE_FUNCTION_TYPE_ALIAS, RECURSIVE_INTERFACE_INHERITANCE, REDIRECT_TO_NON_CONST_CONSTRUCTOR, REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER, RESERVED_WORD_AS_IDENTIFIER, RETURN_IN_GENERATIVE_CONSTRUCTOR, STATIC_TOP_LEVEL_FUNCTION, STATIC_TOP_LEVEL_VARIABLE, SUPER_IN_INVALID_CONTEXT, SUPER_INITIALIZER_IN_OBJECT, THROW_WITHOUT_VALUE_OUTSIDE_ON, TYPE_ARGUMENTS_FOR_NON_GENERIC_CLASS, UNDEFINED_CONSTRUCTOR_IN_INITIALIZER, UNINITIALIZED_FINAL_FIELD, URI_WITH_INTERPOLATION, WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR, WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER, WRONG_NUMBER_OF_TYPE_ARGUMENTS];
+  final String __name;
+  final int __ordinal;
+  int get ordinal => __ordinal;
+  /**
+   * The message template used to create the message to be displayed for this error.
+   */
+  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
+   */
+  CompileTimeErrorCode(this.__name, this.__ordinal, String message) {
+    this._message = message;
+  }
+  ErrorSeverity get errorSeverity => ErrorType.COMPILE_TIME_ERROR.severity;
+  String get message => _message;
+  ErrorType get type => ErrorType.COMPILE_TIME_ERROR;
+  bool needsRecompilation() => true;
+  String toString() => __name;
+}
+/**
+ * The enumeration {@code StaticWarningCode} defines the error codes used for static warnings. The
+ * convention for this class is for the name of the error code to indicate the problem that caused
+ * the error to be generated and for the error message to explain what is wrong and, when
+ * appropriate, how the problem can be corrected.
+ * @coverage dart.engine.error
+ */
+class StaticWarningCode implements ErrorCode {
+  /**
+   * 12.11.1 New: It is a static warning if the static type of <i>a<sub>i</sub>, 1 &lt;= i &lt;= n+
+   * k</i> may not be assigned to the type of the corresponding formal parameter of the constructor
+   * <i>T.id</i> (respectively <i>T</i>).
+   * <p>
+   * 12.11.2 Const: It is a static warning if the static type of <i>a<sub>i</sub>, 1 &lt;= i &lt;=
+   * n+ k</i> may not be assigned to the type of the corresponding formal parameter of the
+   * constructor <i>T.id</i> (respectively <i>T</i>).
+   * <p>
+   * 12.14.2 Binding Actuals to Formals: Let <i>T<sub>i</sub></i> be the static type of
+   * <i>a<sub>i</sub></i>, let <i>S<sub>i</sub></i> be the type of <i>p<sub>i</sub>, 1 &lt;= i &lt;=
+   * n+k</i> and let <i>S<sub>q</sub></i> be the type of the named parameter <i>q</i> of <i>f</i>.
+   * 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>.
+   * <p>
+   * 12.14.2 Binding Actuals to Formals: Furthermore, each <i>q<sub>i</sub>, 1 &lt;= i &lt;= l</i>,
+   * must have a corresponding named parameter in the set <i>{p<sub>n+1</sub>, &hellip;
+   * p<sub>n+k</sub>}</i> or a static warning occurs. It is a static warning if
+   * <i>T<sub>m+j</sub></i> may not be assigned to <i>S<sub>r</sub></i>, where <i>r = q<sub>j</sub>,
+   * 1 &lt;= j &lt;= l</i>.
+   */
+  static final StaticWarningCode ARGUMENT_TYPE_NOT_ASSIGNABLE = new StaticWarningCode('ARGUMENT_TYPE_NOT_ASSIGNABLE', 0, "");
+  /**
+   * 5 Variables: Attempting to assign to a final variable elsewhere will cause a NoSuchMethodError
+   * to be thrown, because no setter is defined for it. The assignment will also give rise to a
+   * static warning for the same reason.
+   */
+  static final StaticWarningCode ASSIGNMENT_TO_FINAL = new StaticWarningCode('ASSIGNMENT_TO_FINAL', 1, "");
+  /**
+   * 13.9 Switch: It is a static warning if the last statement of the statement sequence
+   * <i>s<sub>k</sub></i> is not a break, continue, return or throw statement.
+   */
+  static final StaticWarningCode CASE_BLOCK_NOT_TERMINATED = new StaticWarningCode('CASE_BLOCK_NOT_TERMINATED', 2, "");
+  /**
+   * 12.32 Type Cast: It is a static warning if <i>T</i> does not denote a type available in the
+   * current lexical scope.
+   */
+  static final StaticWarningCode CAST_TO_NON_TYPE = new StaticWarningCode('CAST_TO_NON_TYPE', 3, "");
+  /**
+   * 16.1.2 Comments: A token of the form <i>[new c](uri)</i> will be replaced by a link in the
+   * formatted output. The link will point at the constructor named <i>c</i> in <i>L</i>. The title
+   * of the link will be <i>c</i>. It is a static warning if uri is not the URI of a dart library
+   * <i>L</i>, or if <i>c</i> is not the name of a constructor of a class declared in the exported
+   * namespace of <i>L</i>.
+   */
+  static final StaticWarningCode COMMENT_REFERENCE_CONSTRUCTOR_NOT_VISIBLE = new StaticWarningCode('COMMENT_REFERENCE_CONSTRUCTOR_NOT_VISIBLE', 4, "");
+  /**
+   * 16.1.2 Comments: A token of the form <i>[id](uri)</i> will be replaced by a link in the
+   * formatted output. The link will point at the declaration named <i>id</i> in <i>L</i>. The title
+   * of the link will be <i>id</i>. It is a static warning if uri is not the URI of a dart library
+   * <i>L</i>, or if <i>id</i> is not a name declared in the exported namespace of <i>L</i>.
+   */
+  static final StaticWarningCode COMMENT_REFERENCE_IDENTIFIER_NOT_VISIBLE = new StaticWarningCode('COMMENT_REFERENCE_IDENTIFIER_NOT_VISIBLE', 5, "");
+  /**
+   * 16.1.2 Comments: It is a static warning if <i>c</i> does not denote a constructor that
+   * available in the scope of the documentation comment.
+   */
+  static final StaticWarningCode COMMENT_REFERENCE_UNDECLARED_CONSTRUCTOR = new StaticWarningCode('COMMENT_REFERENCE_UNDECLARED_CONSTRUCTOR', 6, "");
+  /**
+   * 16.1.2 Comments: It is a static warning if <i>id</i> does not denote a declaration that
+   * available in the scope of the documentation comment.
+   */
+  static final StaticWarningCode COMMENT_REFERENCE_UNDECLARED_IDENTIFIER = new StaticWarningCode('COMMENT_REFERENCE_UNDECLARED_IDENTIFIER', 7, "");
+  /**
+   * 16.1.2 Comments: A token of the form <i>[id](uri)</i> will be replaced by a link in the
+   * formatted output. The link will point at the declaration named <i>id</i> in <i>L</i>. The title
+   * of the link will be <i>id</i>. It is a static warning if uri is not the URI of a dart library
+   * <i>L</i>, or if <i>id</i> is not a name declared in the exported namespace of <i>L</i>.
+   */
+  static final StaticWarningCode COMMENT_REFERENCE_URI_NOT_LIBRARY = new StaticWarningCode('COMMENT_REFERENCE_URI_NOT_LIBRARY', 8, "");
+  /**
+   * 7.4 Abstract Instance Members: It is a static warning if an abstract member is declared or
+   * inherited in a concrete class.
+   */
+  static final StaticWarningCode CONCRETE_CLASS_WITH_ABSTRACT_MEMBER = new StaticWarningCode('CONCRETE_CLASS_WITH_ABSTRACT_MEMBER', 9, "");
+  /**
+   * 7.2 Getters: It is a static warning if a class <i>C</i> declares an instance getter named
+   * <i>v</i> and an accessible static member named <i>v</i> or <i>v=</i> is declared in a
+   * superclass of <i>C</i>.
+   */
+  static final StaticWarningCode CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER = new StaticWarningCode('CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER', 10, "");
+  /**
+   * 7.3 Setters: It is a static warning if a class <i>C</i> declares an instance setter named
+   * <i>v=</i> and an accessible static member named <i>v=</i> or <i>v</i> is declared in a
+   * superclass of <i>C</i>.
+   */
+  static final StaticWarningCode CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER = new StaticWarningCode('CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER', 11, "");
+  /**
+   * 7.2 Getters: It is a static warning if a class declares a static getter named <i>v</i> and also
+   * has a non-static setter named <i>v=</i>.
+   */
+  static final StaticWarningCode CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER = new StaticWarningCode('CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER', 12, "");
+  /**
+   * 7.3 Setters: It is a static warning if a class declares a static setter named <i>v=</i> and
+   * also has a non-static member named <i>v</i>.
+   */
+  static final StaticWarningCode CONFLICTING_STATIC_SETTER_AND_INSTANCE_GETTER = new StaticWarningCode('CONFLICTING_STATIC_SETTER_AND_INSTANCE_GETTER', 13, "");
+  /**
+   * 12.11.2 Const: Given an instance creation expression of the form <i>const q(a<sub>1</sub>,
+   * &hellip; a<sub>n</sub>)</i> it is a static warning if <i>q</i> is the constructor of an
+   * abstract class but <i>q</i> is not a factory constructor.
+   */
+  static final StaticWarningCode CONST_WITH_ABSTRACT_CLASS = new StaticWarningCode('CONST_WITH_ABSTRACT_CLASS', 14, "Abstract classes cannot be created with a 'const' expression");
+  /**
+   * 12.7 Maps: It is a static warning if the values of any two keys in a map literal are equal.
+   */
+  static final StaticWarningCode EQUAL_KEYS_IN_MAP = new StaticWarningCode('EQUAL_KEYS_IN_MAP', 15, "Keys in a map cannot be equal");
+  /**
+   * 7.6.1 Generative Constructors: An initializing formal has the form <i>this.id</i>. It is a
+   * static warning if the static type of <i>id</i> is not assignable to <i>T<sub>id</sub></i>.
+   */
+  static final StaticWarningCode FIELD_INITIALIZER_WITH_INVALID_TYPE = new StaticWarningCode('FIELD_INITIALIZER_WITH_INVALID_TYPE', 16, "");
+  /**
+   * 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m &lt; h</i> or if <i>m &gt;
+   * n</i>.
+   */
+  static final StaticWarningCode INCORRECT_NUMBER_OF_ARGUMENTS = new StaticWarningCode('INCORRECT_NUMBER_OF_ARGUMENTS', 17, "");
+  /**
+   * 7.1 Instance Methods: It is a static warning if a class <i>C</i> declares an instance method
+   * named <i>n</i> and an accessible static member named <i>n</i> is declared in a superclass of
+   * <i>C</i>.
+   */
+  static final StaticWarningCode INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC = new StaticWarningCode('INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC', 18, "");
+  /**
+   * 7.6.2 Factories: It is a static warning if <i>M.id</i> is not a constructor name.
+   */
+  static final StaticWarningCode INVALID_FACTORY_NAME = new StaticWarningCode('INVALID_FACTORY_NAME', 19, "");
+  /**
+   * 7.2 Getters: It is a static warning if a getter <i>m1</i> overrides a getter <i>m2</i> and the
+   * type of <i>m1</i> is not a subtype of the type of <i>m2</i>.
+   */
+  static final StaticWarningCode INVALID_OVERRIDE_GETTER_TYPE = new StaticWarningCode('INVALID_OVERRIDE_GETTER_TYPE', 20, "");
+  /**
+   * 7.1 Instance Methods: It is a static warning if an instance method <i>m1</i> overrides an
+   * instance method <i>m2</i> and the type of <i>m1</i> is not a subtype of the type of <i>m2</i>.
+   */
+  static final StaticWarningCode INVALID_OVERRIDE_RETURN_TYPE = new StaticWarningCode('INVALID_OVERRIDE_RETURN_TYPE', 21, "");
+  /**
+   * 7.3 Setters: It is a static warning if a setter <i>m1</i> overrides a setter <i>m2</i> and the
+   * type of <i>m1</i> is not a subtype of the type of <i>m2</i>.
+   */
+  static final StaticWarningCode INVALID_OVERRIDE_SETTER_RETURN_TYPE = new StaticWarningCode('INVALID_OVERRIDE_SETTER_RETURN_TYPE', 22, "");
+  /**
+   * 12.15.4 Super Invocation: A super method invocation <i>i</i> has the form
+   * <i>super.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>, &hellip;
+   * x<sub>n+k</sub>: a<sub>n+k</sub>)</i>. If <i>S.m</i> exists, it is a static warning if the type
+   * <i>F</i> of <i>S.m</i> may not be assigned to a function type.
+   */
+  static final StaticWarningCode INVOCATION_OF_NON_FUNCTION = new StaticWarningCode('INVOCATION_OF_NON_FUNCTION', 23, "");
+  /**
+   * 7.3 Setters: It is a static warning if a class has a setter named <i>v=</i> with argument type
+   * <i>T</i> and a getter named <i>v</i> with return type <i>S</i>, and <i>T</i> may not be
+   * assigned to <i>S</i>.
+   */
+  static final StaticWarningCode MISMATCHED_GETTER_AND_SETTER_TYPES = new StaticWarningCode('MISMATCHED_GETTER_AND_SETTER_TYPES', 24, "");
+  /**
+   * 12.11.1 New: It is a static warning if <i>q</i> is a constructor of an abstract class and
+   * <i>q</i> is not a factory constructor.
+   */
+  static final StaticWarningCode NEW_WITH_ABSTRACT_CLASS = new StaticWarningCode('NEW_WITH_ABSTRACT_CLASS', 25, "Abstract classes cannot be created with a 'new' expression");
+  /**
+   * 12.11.1 New: It is a static warning if <i>T</i> is not a class accessible in the current scope,
+   * optionally followed by type arguments.
+   */
+  static final StaticWarningCode NEW_WITH_NON_TYPE = new StaticWarningCode('NEW_WITH_NON_TYPE', 26, "");
+  /**
+   * 12.11.1 New: If <i>T</i> is a class or parameterized type accessible in the current scope then:
+   * 1. If <i>e</i> is of the form <i>new T.id(a<sub>1</sub>, &hellip;, a<sub>n</sub>,
+   * x<sub>n+1</sub>: a<sub>n+1</sub>, &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i> it is a
+   * static warning if <i>T.id</i> is not the name of a constructor declared by the type <i>T</i>.
+   * If <i>e</i> of the form <i>new T(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>:
+   * a<sub>n+1</sub>, &hellip; x<sub>n+k</sub>: a<sub>n+kM/sub>)</i> it is a static warning if the
+   * type <i>T</i> does not declare a constructor with the same name as the declaration of <i>T</i>.
+   */
+  static final StaticWarningCode NEW_WITH_UNDEFINED_CONSTRUCTOR = new StaticWarningCode('NEW_WITH_UNDEFINED_CONSTRUCTOR', 27, "");
+  /**
+   * 7.10 Superinterfaces: It is a static warning if the implicit interface of a non-abstract class
+   * <i>C</i> includes an instance member <i>m</i> and <i>C</i> does not declare or inherit a
+   * corresponding instance member <i>m</i>.
+   */
+  static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER = new StaticWarningCode('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER', 28, "");
+  /**
+   * 7.9.1 Inheritance and Overriding: It is a static warning if a non-abstract class inherits an
+   * abstract method.
+   */
+  static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_METHOD = new StaticWarningCode('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_METHOD', 29, "");
+  /**
+   * 12.31 Type Test: It is a static warning if <i>T</i> does not denote a type available in the
+   * current lexical scope.
+   */
+  static final StaticWarningCode NON_TYPE = new StaticWarningCode('NON_TYPE', 30, "");
+  /**
+   * 13.10 Try: An on-catch clause of the form <i>on T catch (p<sub>1</sub>, p<sub>2</sub>) s</i> or
+   * <i>on T s</i> matches an object <i>o</i> if the type of <i>o</i> is a subtype of <i>T</i>. It
+   * is a static warning if <i>T</i> does not denote a type available in the lexical scope of the
+   * catch clause.
+   */
+  static final StaticWarningCode NON_TYPE_IN_CATCH_CLAUSE = new StaticWarningCode('NON_TYPE_IN_CATCH_CLAUSE', 31, "");
+  /**
+   * 7.1.1 Operators: It is a static warning if the return type of the user-declared operator []= is
+   * explicitly declared and not void.
+   */
+  static final StaticWarningCode NON_VOID_RETURN_FOR_OPERATOR = new StaticWarningCode('NON_VOID_RETURN_FOR_OPERATOR', 32, "");
+  /**
+   * 7.3 Setters: It is a static warning if a setter declares a return type other than void.
+   */
+  static final StaticWarningCode NON_VOID_RETURN_FOR_SETTER = new StaticWarningCode('NON_VOID_RETURN_FOR_SETTER', 33, "");
+  /**
+   * 8 Interfaces: It is a static warning if an interface member <i>m1</i> overrides an interface
+   * member <i>m2</i> and the type of <i>m1</i> is not a subtype of the type of <i>m2</i>.
+   */
+  static final StaticWarningCode OVERRIDE_NOT_SUBTYPE = new StaticWarningCode('OVERRIDE_NOT_SUBTYPE', 34, "");
+  /**
+   * 8 Interfaces: It is a static warning if an interface method <i>m1</i> overrides an interface
+   * method <i>m2</i>, the signature of <i>m2</i> explicitly specifies a default value for a formal
+   * parameter <i>p</i> and the signature of <i>m1</i> specifies a different default value for
+   * <i>p</i>.
+   */
+  static final StaticWarningCode OVERRIDE_WITH_DIFFERENT_DEFAULT = new StaticWarningCode('OVERRIDE_WITH_DIFFERENT_DEFAULT', 35, "");
+  /**
+   * 14.3 Parts: It is a static warning if the referenced part declaration <i>p</i> names a library
+   * other than the current library as the library to which <i>p</i> belongs.
+   * @param expectedLibraryName the name of expected library name
+   * @param actualLibraryName the non-matching actual library name from the "part of" declaration
+   */
+  static final StaticWarningCode PART_OF_DIFFERENT_LIBRARY = new StaticWarningCode('PART_OF_DIFFERENT_LIBRARY', 36, "Expected this library to be part of '%s', not '%s'");
+  /**
+   * 7.6.2 Factories: It is a static warning if the function type of <i>k’</i> is not a subtype of
+   * the type of <i>k</i>.
+   */
+  static final StaticWarningCode REDIRECT_TO_INVALID_RETURN_TYPE = new StaticWarningCode('REDIRECT_TO_INVALID_RETURN_TYPE', 37, "");
+  /**
+   * 7.6.2 Factories: It is a static warning if type does not denote a class accessible in the
+   * current scope; if type does denote such a class <i>C</i> it is a static warning if the
+   * referenced constructor (be it <i>type</i> or <i>type.id</i>) is not a constructor of <i>C</i>.
+   */
+  static final StaticWarningCode REDIRECT_TO_MISSING_CONSTRUCTOR = new StaticWarningCode('REDIRECT_TO_MISSING_CONSTRUCTOR', 38, "");
+  /**
+   * 7.6.2 Factories: It is a static warning if type does not denote a class accessible in the
+   * current scope; if type does denote such a class <i>C</i> it is a static warning if the
+   * referenced constructor (be it <i>type</i> or <i>type.id</i>) is not a constructor of <i>C</i>.
+   */
+  static final StaticWarningCode REDIRECT_TO_NON_CLASS = new StaticWarningCode('REDIRECT_TO_NON_CLASS', 39, "");
+  /**
+   * 13.11 Return: Let <i>f</i> be the function immediately enclosing a return statement of the form
+   * <i>return;</i> It is a static warning if both of the following conditions hold:
+   * <ol>
+   * <li><i>f</i> is not a generative constructor.
+   * <li>The return type of <i>f</i> may not be assigned to void.
+   * </ol>
+   */
+  static final StaticWarningCode RETURN_WITHOUT_VALUE = new StaticWarningCode('RETURN_WITHOUT_VALUE', 40, "");
+  /**
+   * 13.9 Switch: It is a static warning if the type of <i>e</i> may not be assigned to the type of
+   * <i>e<sub>k</sub></i>.
+   */
+  static final StaticWarningCode SWITCH_EXPRESSION_NOT_ASSIGNABLE = new StaticWarningCode('SWITCH_EXPRESSION_NOT_ASSIGNABLE', 41, "");
+  /**
+   * 12.15.3 Static Invocation: A static method invocation <i>i</i> has the form
+   * <i>C.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>, &hellip;
+   * x<sub>n+k</sub>: a<sub>n+k</sub>)</i>. It is a static warning if <i>C</i> does not denote a
+   * class in the current scope.
+   */
+  static final StaticWarningCode UNDEFINED_CLASS = new StaticWarningCode('UNDEFINED_CLASS', 42, "");
+  /**
+   * 12.17 Getter Invocation: It is a static warning if there is no class <i>C</i> in the enclosing
+   * lexical scope of <i>i</i>, or if <i>C</i> does not declare, implicitly or explicitly, a getter
+   * named <i>m</i>.
+   */
+  static final StaticWarningCode UNDEFINED_GETTER = new StaticWarningCode('UNDEFINED_GETTER', 43, "");
+  /**
+   * 12.30 Identifier Reference: It is as static warning if an identifier expression of the form
+   * <i>id</i> occurs inside a top level or static function (be it function, method, getter, or
+   * setter) or variable initializer and there is no declaration <i>d</i> with name <i>id</i> in the
+   * lexical scope enclosing the expression.
+   */
+  static final StaticWarningCode UNDEFINED_IDENTIFIER = new StaticWarningCode('UNDEFINED_IDENTIFIER', 44, "");
+  /**
+   * 12.18 Assignment: It is as static warning if an assignment of the form <i>v = e</i> occurs
+   * inside a top level or static function (be it function, method, getter, or setter) or variable
+   * initializer and there is no declaration <i>d</i> with name <i>v=</i> in the lexical scope
+   * enclosing the assignment.
+   * <p>
+   * 12.18 Assignment: It is a static warning if there is no class <i>C</i> in the enclosing lexical
+   * scope of the assignment, or if <i>C</i> does not declare, implicitly or explicitly, a setter
+   * <i>v=</i>.
+   */
+  static final StaticWarningCode UNDEFINED_SETTER = new StaticWarningCode('UNDEFINED_SETTER', 45, "");
+  /**
+   * 12.15.3 Static Invocation: It is a static warning if <i>C</i> does not declare a static method
+   * or getter <i>m</i>.
+   */
+  static final StaticWarningCode UNDEFINED_STATIC_METHOD_OR_GETTER = new StaticWarningCode('UNDEFINED_STATIC_METHOD_OR_GETTER', 46, "");
+  static final List<StaticWarningCode> values = [ARGUMENT_TYPE_NOT_ASSIGNABLE, ASSIGNMENT_TO_FINAL, CASE_BLOCK_NOT_TERMINATED, CAST_TO_NON_TYPE, COMMENT_REFERENCE_CONSTRUCTOR_NOT_VISIBLE, COMMENT_REFERENCE_IDENTIFIER_NOT_VISIBLE, COMMENT_REFERENCE_UNDECLARED_CONSTRUCTOR, COMMENT_REFERENCE_UNDECLARED_IDENTIFIER, COMMENT_REFERENCE_URI_NOT_LIBRARY, CONCRETE_CLASS_WITH_ABSTRACT_MEMBER, CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER, CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER, CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER, CONFLICTING_STATIC_SETTER_AND_INSTANCE_GETTER, CONST_WITH_ABSTRACT_CLASS, EQUAL_KEYS_IN_MAP, FIELD_INITIALIZER_WITH_INVALID_TYPE, INCORRECT_NUMBER_OF_ARGUMENTS, INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC, INVALID_FACTORY_NAME, INVALID_OVERRIDE_GETTER_TYPE, INVALID_OVERRIDE_RETURN_TYPE, INVALID_OVERRIDE_SETTER_RETURN_TYPE, INVOCATION_OF_NON_FUNCTION, MISMATCHED_GETTER_AND_SETTER_TYPES, NEW_WITH_ABSTRACT_CLASS, NEW_WITH_NON_TYPE, NEW_WITH_UNDEFINED_CONSTRUCTOR, NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER, NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_METHOD, NON_TYPE, NON_TYPE_IN_CATCH_CLAUSE, NON_VOID_RETURN_FOR_OPERATOR, NON_VOID_RETURN_FOR_SETTER, OVERRIDE_NOT_SUBTYPE, OVERRIDE_WITH_DIFFERENT_DEFAULT, PART_OF_DIFFERENT_LIBRARY, REDIRECT_TO_INVALID_RETURN_TYPE, REDIRECT_TO_MISSING_CONSTRUCTOR, REDIRECT_TO_NON_CLASS, RETURN_WITHOUT_VALUE, SWITCH_EXPRESSION_NOT_ASSIGNABLE, UNDEFINED_CLASS, UNDEFINED_GETTER, UNDEFINED_IDENTIFIER, UNDEFINED_SETTER, UNDEFINED_STATIC_METHOD_OR_GETTER];
+  final String __name;
+  final int __ordinal;
+  int get ordinal => __ordinal;
+  /**
+   * The message template used to create the message to be displayed for this error.
+   */
+  String _message;
+  /**
+   * Initialize a newly created error code to have the given type and message.
+   * @param message the message template used to create the message to be displayed for the error
+   */
+  StaticWarningCode(this.__name, this.__ordinal, String message) {
+    this._message = message;
+  }
+  ErrorSeverity get errorSeverity => ErrorType.STATIC_WARNING.severity;
+  String get message => _message;
+  ErrorType get type => ErrorType.STATIC_WARNING;
+  bool needsRecompilation() => true;
+  String toString() => __name;
+}
+/**
+ * The interface {@code AnalysisErrorListener} defines the behavior of objects that listen for{@link AnalysisError analysis errors} being produced by the analysis engine.
+ * @coverage dart.engine.error
+ */
+abstract class AnalysisErrorListener {
+  /**
+   * This method is invoked when an error has been found by the analysis engine.
+   * @param error the error that was just found (not {@code null})
+   */
+  void onError(AnalysisError error);
+}
+/**
+ * The enumeration {@code StaticTypeWarningCode} defines the error codes used for static type
+ * warnings. The convention for this class is for the name of the error code to indicate the problem
+ * that caused the error to be generated and for the error message to explain what is wrong and,
+ * when appropriate, how the problem can be corrected.
+ * @coverage dart.engine.error
+ */
+class StaticTypeWarningCode implements ErrorCode {
+  /**
+   * 12.18 Assignment: Let <i>T</i> be the static type of <i>e<sub>1</sub></i>. It is a static type
+   * warning if <i>T</i> does not have an accessible instance setter named <i>v=</i>.
+   * @see #UNDEFINED_SETTER
+   */
+  static final StaticTypeWarningCode INACCESSIBLE_SETTER = new StaticTypeWarningCode('INACCESSIBLE_SETTER', 0, "");
+  /**
+   * 8.1.1 Inheritance and Overriding: However, if there are multiple members <i>m<sub>1</sub>,
+   * &hellip; m<sub>k</sub></i> with the same name <i>n</i> that would be inherited (because
+   * identically named members existed in several superinterfaces) then at most one member is
+   * inherited. If the static types <i>T<sub>1</sub>, &hellip;, T<sub>k</sub></i> of the members
+   * <i>m<sub>1</sub>, &hellip;, m<sub>k</sub></i> are not identical, then there must be a member
+   * <i>m<sub>x</sub></i> such that <i>T<sub>x</sub> &lt; T<sub>i</sub>, 1 &lt;= x &lt;= k</i> for
+   * all <i>i, 1 &lt;= i &lt; k</i>, or a static type warning occurs. The member that is inherited
+   * is <i>m<sub>x</sub></i>, if it exists; otherwise:
+   * <ol>
+   * <li>If all of <i>m<sub>1</sub>, &hellip; m<sub>k</sub></i> have the same number <i>r</i> of
+   * required parameters and the same set of named parameters <i>s</i>, then let <i>h = max(
+   * numberOfOptionalPositionals( m<sub>i</sub> ) ), 1 &lt;= i &lt;= k</i>. <i>I</i> has a method
+   * named <i>n</i>, with <i>r</i> required parameters of type dynamic, <i>h</i> optional positional
+   * parameters of type dynamic, named parameters <i>s</i> of type dynamic and return type dynamic.
+   * <li>Otherwise none of the members <i>m<sub>1</sub>, &hellip;, m<sub>k</sub></i> is inherited.
+   * </ol>
+   */
+  static final StaticTypeWarningCode INCONSISTENT_METHOD_INHERITANCE = new StaticTypeWarningCode('INCONSISTENT_METHOD_INHERITANCE', 1, "");
+  /**
+   * 12.18 Assignment: It is a static type warning if the static type of <i>e</i> may not be
+   * assigned to the static type of <i>v</i>. The static type of the expression <i>v = e</i> is the
+   * static type of <i>e</i>.
+   * <p>
+   * 12.18 Assignment: It is a static type warning if the static type of <i>e</i> may not be
+   * assigned to the static type of <i>C.v</i>. The static type of the expression <i>C.v = e</i> is
+   * the static type of <i>e</i>.
+   * <p>
+   * 12.18 Assignment: Let <i>T</i> be the static type of <i>e<sub>1</sub></i>. It is a static type
+   * warning if the static type of <i>e<sub>2</sub></i> may not be assigned to <i>T</i>.
+   * @param lhsTypeName the name of the left hand side type
+   * @param rhsTypeName the name of the right hand side type
+   */
+  static final StaticTypeWarningCode INVALID_ASSIGNMENT = new StaticTypeWarningCode('INVALID_ASSIGNMENT', 2, "The type '%s' can't be assigned a '%s'");
+  /**
+   * 12.14.4 Function Expression Invocation: A function expression invocation <i>i</i> has the form
+   * <i>e<sub>f</sub>(a<sub>1</sub>, &hellip; a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>,
+   * &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>, where <i>e<sub>f</sub></i> is an expression.
+   * <p>
+   * It is a static type warning if the static type <i>F</i> of <i>e<sub>f</sub></i> may not be
+   * assigned to a function type.
+   * <p>
+   * 12.15.1 Ordinary Invocation: An ordinary method invocation <i>i</i> has the form
+   * <i>o.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>, &hellip;
+   * x<sub>n+k</sub>: a<sub>n+k</sub>)</i>.
+   * <p>
+   * Let <i>T</i> be the static type of <i>o</i>. It is a static type warning if <i>T</i> does not
+   * have an accessible instance member named <i>m</i>. If <i>T.m</i> exists, it is a static warning
+   * if the type <i>F</i> of <i>T.m</i> may not be assigned to a function type. If <i>T.m</i> does
+   * not exist, or if <i>F</i> is not a function type, the static type of <i>i</i> is dynamic.
+   * <p>
+   * 12.15.3 Static Invocation: It is a static type warning if the type <i>F</i> of <i>C.m</i> may
+   * not be assigned to a function type.
+   * @param nonFunctionIdentifier the name of the identifier that is not a function type
+   */
+  static final StaticTypeWarningCode INVOCATION_OF_NON_FUNCTION = new StaticTypeWarningCode('INVOCATION_OF_NON_FUNCTION', 3, "'%s' is not a method");
+  /**
+   * 12.19 Conditional: It is a static type warning if the type of <i>e<sub>1</sub></i> may not be
+   * assigned to bool.
+   * <p>
+   * 13.5 If: It is a static type warning if the type of the expression <i>b</i> may not be assigned
+   * to bool.
+   * <p>
+   * 13.7 While: It is a static type warning if the type of <i>e</i> may not be assigned to bool.
+   * <p>
+   * 13.8 Do: It is a static type warning if the type of <i>e</i> cannot be assigned to bool.
+   */
+  static final StaticTypeWarningCode NON_BOOL_CONDITION = new StaticTypeWarningCode('NON_BOOL_CONDITION', 4, "Conditions must have a static type of 'bool'");
+  /**
+   * 13.15 Assert: It is a static type warning if the type of <i>e</i> may not be assigned to either
+   * bool or () &rarr; bool
+   */
+  static final StaticTypeWarningCode NON_BOOL_EXPRESSION = new StaticTypeWarningCode('NON_BOOL_EXPRESSION', 5, "Assertions must be on either a 'bool' or '() -> bool'");
+  /**
+   * 15.8 Parameterized Types: It is a static type warning if <i>A<sub>i</sub>, 1 &lt;= i &lt;=
+   * n</i> does not denote a type in the enclosing lexical scope.
+   */
+  static final StaticTypeWarningCode NON_TYPE_AS_TYPE_ARGUMENT = new StaticTypeWarningCode('NON_TYPE_AS_TYPE_ARGUMENT', 6, "");
+  /**
+   * 7.6.2 Factories: It is a static type warning if any of the type arguments to <i>k’</i> are not
+   * subtypes of the bounds of the corresponding formal type parameters of type.
+   */
+  static final StaticTypeWarningCode REDIRECT_WITH_INVALID_TYPE_PARAMETERS = new StaticTypeWarningCode('REDIRECT_WITH_INVALID_TYPE_PARAMETERS', 7, "");
+  /**
+   * 13.11 Return: It is a static type warning if the type of <i>e</i> may not be assigned to the
+   * declared return type of the immediately enclosing function.
+   */
+  static final StaticTypeWarningCode RETURN_OF_INVALID_TYPE = new StaticTypeWarningCode('RETURN_OF_INVALID_TYPE', 8, "The return type '%s' is not a '%s', as defined by the method");
+  /**
+   * 12.11 Instance Creation: It is a static type warning if any of the type arguments to a
+   * constructor of a generic type <i>G</i> invoked by a new expression or a constant object
+   * expression are not subtypes of the bounds of the corresponding formal type parameters of
+   * <i>G</i>.
+   * @param boundedTypeName the name of the type used in the instance creation that should be
+   * limited by the bound as specified in the class declaration
+   * @param boundingTypeName the name of the bounding type
+   */
+  static final StaticTypeWarningCode TYPE_ARGUMENT_NOT_MATCHING_BOUNDS = new StaticTypeWarningCode('TYPE_ARGUMENT_NOT_MATCHING_BOUNDS', 9, "'%s' does not extend '%s'");
+  /**
+   * 10 Generics: It is a static type warning if a type parameter is a supertype of its upper bound.
+   * <p>
+   * 15.8 Parameterized Types: If <i>S</i> is the static type of a member <i>m</i> of <i>G</i>, then
+   * the static type of the member <i>m</i> of <i>G&lt;A<sub>1</sub>, &hellip; A<sub>n</sub>&gt;</i>
+   * is <i>[A<sub>1</sub>, &hellip;, A<sub>n</sub>/T<sub>1</sub>, &hellip;, T<sub>n</sub>]S</i>
+   * where <i>T<sub>1</sub>, &hellip; T<sub>n</sub></i> are the formal type parameters of <i>G</i>.
+   * Let <i>B<sub>i</sub></i> be the bounds of <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>. It is a
+   * static type warning if <i>A<sub>i</sub></i> is not a subtype of <i>[A<sub>1</sub>, &hellip;,
+   * A<sub>n</sub>/T<sub>1</sub>, &hellip;, T<sub>n</sub>]B<sub>i</sub>, 1 &lt;= i &lt;= n</i>.
+   */
+  static final StaticTypeWarningCode TYPE_ARGUMENT_VIOLATES_BOUNDS = new StaticTypeWarningCode('TYPE_ARGUMENT_VIOLATES_BOUNDS', 10, "");
+  /**
+   * 12.17 Getter Invocation: Let <i>T</i> be the static type of <i>e</i>. It is a static type
+   * warning if <i>T</i> does not have a getter named <i>m</i>.
+   */
+  static final StaticTypeWarningCode UNDEFINED_GETTER = new StaticTypeWarningCode('UNDEFINED_GETTER', 11, "There is no such getter '%s' in '%s'");
+  /**
+   * 12.18 Assignment: Let <i>T</i> be the static type of <i>e<sub>1</sub></i>. It is a static type
+   * warning if <i>T</i> does not have an accessible instance setter named <i>v=</i>.
+   * @see #INACCESSIBLE_SETTER
+   */
+  static final StaticTypeWarningCode UNDEFINED_SETTER = new StaticTypeWarningCode('UNDEFINED_SETTER', 12, "There is no such setter '%s' in '%s'");
+  /**
+   * 12.15.4 Super Invocation: A super method invocation <i>i</i> has the form
+   * <i>super.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>, &hellip;
+   * x<sub>n+k</sub>: a<sub>n+k</sub>)</i>. It is a static type warning if <i>S</i> does not have an
+   * accessible instance member named <i>m</i>.
+   * @param methodName the name of the method that is undefined
+   * @param typeName the resolved type name that the method lookup is happening on
+   */
+  static final StaticTypeWarningCode UNDEFINED_SUPER_METHOD = new StaticTypeWarningCode('UNDEFINED_SUPER_METHOD', 13, "There is no such method '%s' in '%s'");
+  /**
+   * 15.8 Parameterized Types: It is a static type warning if <i>G</i> is not an accessible generic
+   * type declaration with <i>n</i> type parameters.
+   * @param typeName the name of the type being referenced (<i>G</i>)
+   * @param argumentCount the number of type arguments provided
+   * @param parameterCount the number of type parameters that were declared
+   */
+  static final StaticTypeWarningCode WRONG_NUMBER_OF_TYPE_ARGUMENTS = new StaticTypeWarningCode('WRONG_NUMBER_OF_TYPE_ARGUMENTS', 14, "The type '%s' is declared with %d type parameters, but %d type arguments were given");
+  static final List<StaticTypeWarningCode> values = [INACCESSIBLE_SETTER, INCONSISTENT_METHOD_INHERITANCE, INVALID_ASSIGNMENT, INVOCATION_OF_NON_FUNCTION, NON_BOOL_CONDITION, NON_BOOL_EXPRESSION, NON_TYPE_AS_TYPE_ARGUMENT, REDIRECT_WITH_INVALID_TYPE_PARAMETERS, RETURN_OF_INVALID_TYPE, TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, TYPE_ARGUMENT_VIOLATES_BOUNDS, UNDEFINED_GETTER, UNDEFINED_SETTER, UNDEFINED_SUPER_METHOD, WRONG_NUMBER_OF_TYPE_ARGUMENTS];
+  final String __name;
+  final int __ordinal;
+  int get ordinal => __ordinal;
+  /**
+   * The message template used to create the message to be displayed for this error.
+   */
+  String _message;
+  /**
+   * Initialize a newly created error code to have the given type and message.
+   * @param message the message template used to create the message to be displayed for the error
+   */
+  StaticTypeWarningCode(this.__name, this.__ordinal, String message) {
+    this._message = message;
+  }
+  ErrorSeverity get errorSeverity => ErrorType.STATIC_TYPE_WARNING.severity;
+  String get message => _message;
+  ErrorType get type => ErrorType.STATIC_TYPE_WARNING;
+  bool needsRecompilation() => true;
+  String toString() => __name;
+}
\ No newline at end of file
diff --git a/pkg/analyzer_experimental/lib/src/generated/html.dart b/pkg/analyzer_experimental/lib/src/generated/html.dart
new file mode 100644
index 0000000..1114485
--- /dev/null
+++ b/pkg/analyzer_experimental/lib/src/generated/html.dart
@@ -0,0 +1,1333 @@
+// This code was auto-generated, is not intended to be edited, and is subject to
+// significant change. Please see the README file for more information.
+
+library engine.html;
+
+import 'dart:collection';
+import 'java_core.dart';
+import 'source.dart';
+import 'error.dart';
+import 'instrumentation.dart';
+import 'element.dart' show HtmlElementImpl;
+
+/**
+ * Instances of the class {@code Token} represent a token that was scanned from the input. Each
+ * token knows which token follows it, acting as the head of a linked list of tokens.
+ * @coverage dart.engine.html
+ */
+class Token {
+  /**
+   * The offset from the beginning of the file to the first character in the token.
+   */
+  int _offset = 0;
+  /**
+   * The previous token in the token stream.
+   */
+  Token _previous;
+  /**
+   * The next token in the token stream.
+   */
+  Token _next;
+  /**
+   * The type of the token.
+   */
+  TokenType _type;
+  /**
+   * The lexeme represented by this token.
+   */
+  String _value;
+  /**
+   * Initialize a newly created token.
+   * @param type the token type (not {@code null})
+   * @param offset the offset from the beginning of the file to the first character in the token
+   */
+  Token.con1(TokenType type, int offset) {
+    _jtd_constructor_147_impl(type, offset);
+  }
+  _jtd_constructor_147_impl(TokenType type, int offset) {
+    _jtd_constructor_148_impl(type, offset, type.lexeme);
+  }
+  /**
+   * Initialize a newly created token.
+   * @param type the token type (not {@code null})
+   * @param offset the offset from the beginning of the file to the first character in the token
+   * @param value the lexeme represented by this token (not {@code null})
+   */
+  Token.con2(TokenType type4, int offset3, String value7) {
+    _jtd_constructor_148_impl(type4, offset3, value7);
+  }
+  _jtd_constructor_148_impl(TokenType type4, int offset3, String value7) {
+    this._type = type4;
+    this._value = value7;
+    this._offset = offset3;
+  }
+  /**
+   * Return the offset from the beginning of the file to the character after last character of the
+   * token.
+   * @return the offset from the beginning of the file to the first character after last character
+   * of the token
+   */
+  int get end => _offset + length;
+  /**
+   * Return the number of characters in the node's source range.
+   * @return the number of characters in the node's source range
+   */
+  int get length => lexeme.length;
+  /**
+   * Return the lexeme that represents this token.
+   * @return the lexeme (not {@code null})
+   */
+  String get lexeme => _value;
+  /**
+   * Return the next token in the token stream.
+   * @return the next token in the token stream
+   */
+  Token get next => _next;
+  /**
+   * Return the offset from the beginning of the file to the first character in the token.
+   * @return the offset from the beginning of the file to the first character in the token
+   */
+  int get offset => _offset;
+  /**
+   * Return the previous token in the token stream.
+   * @return the previous token in the token stream
+   */
+  Token get previous => _previous;
+  /**
+   * Answer the token type for the receiver.
+   * @return the token type (not {@code null})
+   */
+  TokenType get type => _type;
+  /**
+   * Return {@code true} if this token is a synthetic token. A synthetic token is a token that was
+   * introduced by the parser in order to recover from an error in the code. Synthetic tokens always
+   * have a length of zero ({@code 0}).
+   * @return {@code true} if this token is a synthetic token
+   */
+  bool isSynthetic() => length == 0;
+  /**
+   * Set the next token in the token stream to the given token. This has the side-effect of setting
+   * this token to be the previous token for the given token.
+   * @param token the next token in the token stream
+   * @return the token that was passed in
+   */
+  Token setNext(Token token) {
+    _next = token;
+    token.previous = this;
+    return token;
+  }
+  String toString() => lexeme;
+  /**
+   * Set the previous token in the token stream to the given token.
+   * @param previous the previous token in the token stream
+   */
+  void set previous(Token previous2) {
+    this._previous = previous2;
+  }
+}
+/**
+ * Instances of {@code HtmlParseResult} hold the result of parsing an HTML file.
+ * @coverage dart.engine.html
+ */
+class HtmlParseResult extends HtmlScanResult {
+  /**
+   * The unit containing the parsed information (not {@code null}).
+   */
+  HtmlUnit _unit;
+  HtmlParseResult(Token token, List<int> lineStarts, HtmlUnit unit) : super(token, lineStarts) {
+    this._unit = unit;
+  }
+  /**
+   * Answer the unit generated by parsing the source
+   * @return the unit (not {@code null})
+   */
+  HtmlUnit get htmlUnit => _unit;
+}
+/**
+ * Instances of the class {@code RecursiveXmlVisitor} implement an XML visitor that will recursively
+ * visit all of the nodes in an XML structure. For example, using an instance of this class to visit
+ * a {@link XmlTagNode} will also cause all of the contained {@link XmlAttributeNode}s and{@link XmlTagNode}s to be visited.
+ * <p>
+ * Subclasses that override a visit method must either invoke the overridden visit method or must
+ * explicitly ask the visited node to visit its children. Failure to do so will cause the children
+ * of the visited node to not be visited.
+ * @coverage dart.engine.html
+ */
+class RecursiveXmlVisitor<R> implements XmlVisitor<R> {
+  R visitHtmlUnit(HtmlUnit node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitXmlAttributeNode(XmlAttributeNode node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitXmlTagNode(XmlTagNode node) {
+    node.visitChildren(this);
+    return null;
+  }
+}
+/**
+ * The abstract class {@code XmlNode} defines behavior common to all XML/HTML nodes.
+ * @coverage dart.engine.html
+ */
+abstract class XmlNode {
+  /**
+   * The parent of the node, or {@code null} if the node is the root of an AST structure.
+   */
+  XmlNode _parent;
+  /**
+   * Use the given visitor to visit this node.
+   * @param visitor the visitor that will visit this node
+   * @return the value returned by the visitor as a result of visiting this node
+   */
+  accept(XmlVisitor visitor);
+  /**
+   * Return the first token included in this node's source range.
+   * @return the first token or {@code null} if none
+   */
+  Token get beginToken;
+  /**
+   * Return the offset of the character immediately following the last character of this node's
+   * source range. This is equivalent to {@code node.getOffset() + node.getLength()}. For an html
+   * unit this will be equal to the length of the unit's source.
+   * @return the offset of the character just past the node's source range
+   */
+  int get end => offset + length;
+  /**
+   * Return the last token included in this node's source range.
+   * @return the last token or {@code null} if none
+   */
+  Token get endToken;
+  /**
+   * Return the number of characters in the node's source range.
+   * @return the number of characters in the node's source range
+   */
+  int get length {
+    Token beginToken4 = beginToken;
+    Token endToken4 = endToken;
+    if (beginToken4 == null || endToken4 == null) {
+      return -1;
+    }
+    return endToken4.offset + endToken4.length - beginToken4.offset;
+  }
+  /**
+   * Return the offset from the beginning of the file to the first character in the node's source
+   * range.
+   * @return the offset from the beginning of the file to the first character in the node's source
+   * range
+   */
+  int get offset {
+    Token beginToken5 = beginToken;
+    if (beginToken5 == null) {
+      return -1;
+    }
+    return beginToken.offset;
+  }
+  /**
+   * Return this node's parent node, or {@code null} if this node is the root of an AST structure.
+   * <p>
+   * Note that the relationship between an AST node and its parent node may change over the lifetime
+   * of a node.
+   * @return the parent of this node, or {@code null} if none
+   */
+  XmlNode get parent => _parent;
+  /**
+   * Use the given visitor to visit all of the children of this node. The children will be visited
+   * in source order.
+   * @param visitor the visitor that will be used to visit the children of this node
+   */
+  void visitChildren(XmlVisitor<Object> visitor);
+  /**
+   * Make this node the parent of the given child nodes.
+   * @param children the nodes that will become the children of this node
+   * @return the nodes that were made children of this node
+   */
+  List<XmlNode> becomeParentOf(List<XmlNode> children) {
+    if (children != null) {
+      for (JavaIterator<XmlNode> iter = new JavaIterator(children); iter.hasNext;) {
+        XmlNode node = iter.next();
+        node.parent = this;
+      }
+    }
+    return children;
+  }
+  /**
+   * Make this node the parent of the given child node.
+   * @param child the node that will become a child of this node
+   * @return the node that was made a child of this node
+   */
+  XmlNode becomeParentOf2(XmlNode child) {
+    if (child != null) {
+      XmlNode node = child;
+      node.parent = this;
+    }
+    return child;
+  }
+  /**
+   * Set the parent of this node to the given node.
+   * @param newParent the node that is to be made the parent of this node
+   */
+  void set parent(XmlNode newParent) {
+    _parent = newParent;
+  }
+}
+/**
+ * Instances of the class {@code SimpleXmlVisitor} implement an AST visitor that will do nothing
+ * when visiting an AST node. It is intended to be a superclass for classes that use the visitor
+ * pattern primarily as a dispatch mechanism (and hence don't need to recursively visit a whole
+ * structure) and that only need to visit a small number of node types.
+ */
+class SimpleXmlVisitor<R> implements XmlVisitor<R> {
+  R visitHtmlUnit(HtmlUnit htmlUnit) => null;
+  R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode) => null;
+  R visitXmlTagNode(XmlTagNode xmlTagNode) => null;
+}
+/**
+ * The abstract class {@code AbstractScanner} implements a scanner for HTML code. Subclasses are
+ * required to implement the interface used to access the characters being scanned.
+ * @coverage dart.engine.html
+ */
+abstract class AbstractScanner {
+  static List<String> _NO_PASS_THROUGH_ELEMENTS = <String> [];
+  /**
+   * The source being scanned.
+   */
+  Source _source;
+  /**
+   * The token pointing to the head of the linked list of tokens.
+   */
+  Token _tokens;
+  /**
+   * The last token that was scanned.
+   */
+  Token _tail;
+  /**
+   * A list containing the offsets of the first character of each line in the source code.
+   */
+  List<int> _lineStarts = new List<int>();
+  /**
+   * An array of element tags for which the content between tags should be consider a single token.
+   */
+  List<String> _passThroughElements = _NO_PASS_THROUGH_ELEMENTS;
+  /**
+   * Initialize a newly created scanner.
+   * @param source the source being scanned
+   */
+  AbstractScanner(Source source) {
+    this._source = source;
+    _tokens = new Token.con1(TokenType.EOF, -1);
+    _tokens.setNext(_tokens);
+    _tail = _tokens;
+    recordStartOfLine();
+  }
+  /**
+   * Return an array containing the offsets of the first character of each line in the source code.
+   * @return an array containing the offsets of the first character of each line in the source code
+   */
+  List<int> get lineStarts => _lineStarts;
+  /**
+   * Return the current offset relative to the beginning of the file. Return the initial offset if
+   * the scanner has not yet scanned the source code, and one (1) past the end of the source code if
+   * the source code has been scanned.
+   * @return the current offset of the scanner in the source
+   */
+  int get offset;
+  /**
+   * Answer the source being scanned.
+   * @return the source or {@code null} if undefined
+   */
+  Source get source => _source;
+  /**
+   * Set array of element tags for which the content between tags should be consider a single token.
+   */
+  void set passThroughElements(List<String> passThroughElements2) {
+    this._passThroughElements = passThroughElements2 != null ? passThroughElements2 : _NO_PASS_THROUGH_ELEMENTS;
+  }
+  /**
+   * Scan the source code to produce a list of tokens representing the source.
+   * @return the first token in the list of tokens that were produced
+   */
+  Token tokenize() {
+    scan();
+    appendEofToken();
+    return firstToken();
+  }
+  /**
+   * Advance the current position and return the character at the new current position.
+   * @return the character at the new current position
+   */
+  int advance();
+  /**
+   * Return the substring of the source code between the start offset and the modified current
+   * position. The current position is modified by adding the end delta.
+   * @param start the offset to the beginning of the string, relative to the start of the file
+   * @param endDelta the number of character after the current location to be included in the
+   * string, or the number of characters before the current location to be excluded if the
+   * offset is negative
+   * @return the specified substring of the source code
+   */
+  String getString(int start, int endDelta);
+  /**
+   * Return the character at the current position without changing the current position.
+   * @return the character at the current position
+   */
+  int peek();
+  /**
+   * Record the fact that we are at the beginning of a new line in the source.
+   */
+  void recordStartOfLine() {
+    _lineStarts.add(offset);
+  }
+  void appendEofToken() {
+    Token eofToken = new Token.con1(TokenType.EOF, offset);
+    eofToken.setNext(eofToken);
+    _tail = _tail.setNext(eofToken);
+  }
+  Token emit(Token token) {
+    _tail.setNext(token);
+    _tail = token;
+    return token;
+  }
+  Token emit2(TokenType type, int start) => emit(new Token.con1(type, start));
+  Token emit3(TokenType type, int start, int count) => emit(new Token.con2(type, start, getString(start, count)));
+  Token firstToken() => _tokens.next;
+  int recordStartOfLineAndAdvance(int c) {
+    if (c == 0xD) {
+      c = advance();
+      if (c == 0xA) {
+        c = advance();
+      }
+      recordStartOfLine();
+    } else if (c == 0xA) {
+      c = advance();
+      recordStartOfLine();
+    } else {
+      c = advance();
+    }
+    return c;
+  }
+  void scan() {
+    bool inBrackets = false;
+    bool passThrough = false;
+    int c = advance();
+    while (c >= 0) {
+      int start = offset;
+      if (c == 0x3C) {
+        c = advance();
+        if (c == 0x21) {
+          c = advance();
+          if (c == 0x2D && peek() == 0x2D) {
+            c = advance();
+            int dashCount = 1;
+            while (c >= 0) {
+              if (c == 0x2D) {
+                dashCount++;
+              } else if (c == 0x3E && dashCount >= 2) {
+                c = advance();
+                break;
+              } else {
+                dashCount = 0;
+              }
+              c = recordStartOfLineAndAdvance(c);
+            }
+            emit3(TokenType.COMMENT, start, -1);
+            if (_tail.length < 7) {
+            }
+          } else {
+            while (c >= 0) {
+              if (c == 0x3E) {
+                c = advance();
+                break;
+              }
+              c = recordStartOfLineAndAdvance(c);
+            }
+            emit3(TokenType.DECLARATION, start, -1);
+            if (!_tail.lexeme.endsWith(">")) {
+            }
+          }
+        } else if (c == 0x3F) {
+          while (c >= 0) {
+            if (c == 0x3F) {
+              c = advance();
+              if (c == 0x3E) {
+                c = advance();
+                break;
+              }
+            } else {
+              c = recordStartOfLineAndAdvance(c);
+            }
+          }
+          emit3(TokenType.DIRECTIVE, start, -1);
+          if (_tail.length < 4) {
+          }
+        } else if (c == 0x2F) {
+          emit2(TokenType.LT_SLASH, start);
+          inBrackets = true;
+          c = advance();
+        } else {
+          inBrackets = true;
+          emit2(TokenType.LT, start);
+          while (Character.isWhitespace(c)) {
+            c = recordStartOfLineAndAdvance(c);
+          }
+          if (Character.isLetterOrDigit(c)) {
+            int tagStart = offset;
+            c = advance();
+            while (Character.isLetterOrDigit(c) || c == 0x2D || c == 0x5F) {
+              c = advance();
+            }
+            emit3(TokenType.TAG, tagStart, -1);
+            String tag = _tail.lexeme;
+            for (String str in _passThroughElements) {
+              if (str == tag) {
+                passThrough = true;
+                break;
+              }
+            }
+          }
+        }
+      } else if (c == 0x3E) {
+        emit2(TokenType.GT, start);
+        inBrackets = false;
+        c = advance();
+        if (passThrough) {
+          while (c >= 0 && (c != 0x3C || peek() != 0x2F)) {
+            c = recordStartOfLineAndAdvance(c);
+          }
+          if (start + 1 < offset) {
+            emit3(TokenType.TEXT, start + 1, -1);
+          }
+          passThrough = false;
+        }
+      } else if (c == 0x2F && peek() == 0x3E) {
+        advance();
+        emit2(TokenType.SLASH_GT, start);
+        inBrackets = false;
+        c = advance();
+      } else if (!inBrackets) {
+        c = recordStartOfLineAndAdvance(c);
+        while (c != 0x3C && c >= 0) {
+          c = recordStartOfLineAndAdvance(c);
+        }
+        emit3(TokenType.TEXT, start, -1);
+      } else if (c == 0x22 || c == 0x27) {
+        int endQuote = c;
+        c = advance();
+        while (c >= 0) {
+          if (c == endQuote) {
+            c = advance();
+            break;
+          }
+          c = recordStartOfLineAndAdvance(c);
+        }
+        emit3(TokenType.STRING, start, -1);
+      } else if (c == 0x3D) {
+        emit2(TokenType.EQ, start);
+        c = advance();
+      } else if (Character.isWhitespace(c)) {
+        do {
+          c = recordStartOfLineAndAdvance(c);
+        } while (Character.isWhitespace(c));
+      } else if (Character.isLetterOrDigit(c)) {
+        c = advance();
+        while (Character.isLetterOrDigit(c) || c == 0x2D || c == 0x5F) {
+          c = advance();
+        }
+        emit3(TokenType.TAG, start, -1);
+      } else {
+        emit3(TokenType.TEXT, start, 0);
+        c = advance();
+      }
+    }
+  }
+}
+/**
+ * Instances of {@code HtmlScanResult} hold the result of scanning an HTML file.
+ * @coverage dart.engine.html
+ */
+class HtmlScanResult {
+  /**
+   * The first token in the token stream (not {@code null}).
+   */
+  Token _token;
+  /**
+   * The line start information that was produced.
+   */
+  List<int> _lineStarts;
+  HtmlScanResult(Token token, List<int> lineStarts) {
+    this._token = token;
+    this._lineStarts = lineStarts;
+  }
+  /**
+   * Answer the line start information that was produced.
+   * @return an array of line starts (not {@code null})
+   */
+  List<int> get lineStarts => _lineStarts;
+  /**
+   * Answer the first token in the token stream.
+   * @return the token (not {@code null})
+   */
+  Token get token => _token;
+}
+/**
+ * Instances of the class {@code StringScanner} implement a scanner that reads from a string. The
+ * scanning logic is in the superclass.
+ * @coverage dart.engine.html
+ */
+class StringScanner extends AbstractScanner {
+  /**
+   * The string from which characters will be read.
+   */
+  String _string;
+  /**
+   * The number of characters in the string.
+   */
+  int _stringLength = 0;
+  /**
+   * The index, relative to the string, of the last character that was read.
+   */
+  int _charOffset = 0;
+  /**
+   * Initialize a newly created scanner to scan the characters in the given string.
+   * @param source the source being scanned
+   * @param string the string from which characters will be read
+   */
+  StringScanner(Source source, String string) : super(source) {
+    this._string = string;
+    this._stringLength = string.length;
+    this._charOffset = -1;
+  }
+  int get offset => _charOffset;
+  void set offset(int offset12) {
+    _charOffset = offset12;
+  }
+  int advance() {
+    if (++_charOffset < _stringLength) {
+      return _string.codeUnitAt(_charOffset);
+    }
+    _charOffset = _stringLength;
+    return -1;
+  }
+  String getString(int start, int endDelta) => _string.substring(start, _charOffset + 1 + endDelta);
+  int peek() {
+    if (_charOffset + 1 < _stringLength) {
+      return _string.codeUnitAt(_charOffset + 1);
+    }
+    return -1;
+  }
+}
+/**
+ * Instances of the class {@code CharBufferScanner} implement a scanner that reads from a character
+ * buffer. The scanning logic is in the superclass.
+ * @coverage dart.engine.html
+ */
+class CharBufferScanner extends AbstractScanner {
+  /**
+   * The buffer from which characters will be read.
+   */
+  CharBuffer _buffer;
+  /**
+   * The number of characters in the buffer.
+   */
+  int _bufferLength = 0;
+  /**
+   * The index of the last character that was read.
+   */
+  int _charOffset = 0;
+  /**
+   * Initialize a newly created scanner to scan the characters in the given character buffer.
+   * @param source the source being scanned
+   * @param buffer the buffer from which characters will be read
+   */
+  CharBufferScanner(Source source, CharBuffer buffer) : super(source) {
+    this._buffer = buffer;
+    this._bufferLength = buffer.length();
+    this._charOffset = -1;
+  }
+  int get offset => _charOffset;
+  int advance() {
+    if (++_charOffset < _bufferLength) {
+      return _buffer.charAt(_charOffset);
+    }
+    _charOffset = _bufferLength;
+    return -1;
+  }
+  String getString(int start, int endDelta) => _buffer.subSequence(start, _charOffset + 1 + endDelta).toString();
+  int peek() {
+    if (_charOffset + 1 < _bufferLength) {
+      return _buffer.charAt(_charOffset + 1);
+    }
+    return -1;
+  }
+}
+/**
+ * The enumeration {@code TokenType} defines the types of tokens that can be returned by the
+ * scanner.
+ * @coverage dart.engine.html
+ */
+class TokenType {
+  /**
+   * The type of the token that marks the end of the input.
+   */
+  static final TokenType EOF = new TokenType_EOF('EOF', 0, "");
+  static final TokenType EQ = new TokenType('EQ', 1, "=");
+  static final TokenType GT = new TokenType('GT', 2, ">");
+  static final TokenType LT_SLASH = new TokenType('LT_SLASH', 3, "</");
+  static final TokenType LT = new TokenType('LT', 4, "<");
+  static final TokenType SLASH_GT = new TokenType('SLASH_GT', 5, "/>");
+  static final TokenType COMMENT = new TokenType('COMMENT', 6, null);
+  static final TokenType DECLARATION = new TokenType('DECLARATION', 7, null);
+  static final TokenType DIRECTIVE = new TokenType('DIRECTIVE', 8, null);
+  static final TokenType STRING = new TokenType('STRING', 9, null);
+  static final TokenType TAG = new TokenType('TAG', 10, null);
+  static final TokenType TEXT = new TokenType('TEXT', 11, null);
+  static final List<TokenType> values = [EOF, EQ, GT, LT_SLASH, LT, SLASH_GT, COMMENT, DECLARATION, DIRECTIVE, STRING, TAG, TEXT];
+  final String __name;
+  final int __ordinal;
+  int get ordinal => __ordinal;
+  /**
+   * The lexeme that defines this type of token, or {@code null} if there is more than one possible
+   * lexeme for this type of token.
+   */
+  String _lexeme;
+  TokenType(this.__name, this.__ordinal, String lexeme) {
+    this._lexeme = lexeme;
+  }
+  /**
+   * Return the lexeme that defines this type of token, or {@code null} if there is more than one
+   * possible lexeme for this type of token.
+   * @return the lexeme that defines this type of token
+   */
+  String get lexeme => _lexeme;
+  String toString() => __name;
+}
+class TokenType_EOF extends TokenType {
+  TokenType_EOF(String ___name, int ___ordinal, String arg0) : super(___name, ___ordinal, arg0);
+  String toString() => "-eof-";
+}
+/**
+ * Instances of {@code XmlAttributeNode} represent name/value pairs owned by an {@link XmlTagNode}.
+ * @coverage dart.engine.html
+ */
+class XmlAttributeNode extends XmlNode {
+  Token _name;
+  Token _equals;
+  Token _value;
+  /**
+   * Construct a new instance representing an XML attribute.
+   * @param name the name token (not {@code null}). This may be a zero length token if the attribute
+   * is badly formed.
+   * @param equals the equals sign or {@code null} if none
+   * @param value the value token (not {@code null})
+   */
+  XmlAttributeNode(Token name, Token equals, Token value) {
+    this._name = name;
+    this._equals = equals;
+    this._value = value;
+  }
+  accept(XmlVisitor visitor) => visitor.visitXmlAttributeNode(this);
+  Token get beginToken => _name;
+  Token get endToken => _value;
+  /**
+   * Answer the equals sign token that appears between the name and value tokens. This may be{@code null} if the attribute is badly formed.
+   * @return the token or {@code null} if there is no equals sign between the name and value
+   */
+  Token get equals => _equals;
+  /**
+   * Answer the attribute name. This may be a zero length token if the attribute is badly formed.
+   * @return the name (not {@code null})
+   */
+  Token get name => _name;
+  /**
+   * Answer the lexeme for the value token without the leading and trailing quotes.
+   * @return the text or {@code null} if the value is not specified
+   */
+  String get text {
+    if (_value == null) {
+      return null;
+    }
+    String text = _value.lexeme;
+    int len = text.length;
+    if (len > 0) {
+      if (text.codeUnitAt(0) == 0x22) {
+        if (len > 1 && text.codeUnitAt(len - 1) == 0x22) {
+          return text.substring(1, len - 1);
+        } else {
+          return text.substring(1);
+        }
+      } else if (text.codeUnitAt(0) == 0x27) {
+        if (len > 1 && text.codeUnitAt(len - 1) == 0x27) {
+          return text.substring(1, len - 1);
+        } else {
+          return text.substring(1);
+        }
+      }
+    }
+    return text;
+  }
+  /**
+   * Answer the attribute value. A properly formed value will start and end with matching quote
+   * characters, but the value returned may not be properly formed.
+   * @return the value or {@code null} if this represents a badly formed attribute
+   */
+  Token get value => _value;
+  void visitChildren(XmlVisitor<Object> visitor) {
+  }
+}
+/**
+ * The interface {@code XmlVisitor} defines the behavior of objects that can be used to visit an{@link XmlNode} structure.
+ * @coverage dart.engine.html
+ */
+abstract class XmlVisitor<R> {
+  R visitHtmlUnit(HtmlUnit htmlUnit);
+  R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode);
+  R visitXmlTagNode(XmlTagNode xmlTagNode);
+}
+/**
+ * Instances of {@code HtmlScanner} receive and scan HTML content from a {@link Source}.<br/>
+ * For example, the following code scans HTML source and returns the result:
+ * <pre>
+ * HtmlScanner scanner = new HtmlScanner(source);
+ * source.getContents(scanner);
+ * return scanner.getResult();
+ * </pre>
+ * @coverage dart.engine.html
+ */
+class HtmlScanner implements Source_ContentReceiver {
+  List<String> _SCRIPT_TAG = <String> ["script"];
+  /**
+   * The source being scanned (not {@code null})
+   */
+  Source _source;
+  /**
+   * The scanner used to scan the source
+   */
+  AbstractScanner _scanner;
+  /**
+   * The first token in the token stream.
+   */
+  Token _token;
+  /**
+   * Construct a new instance to scan the specified source.
+   * @param source the source to be scanned (not {@code null})
+   */
+  HtmlScanner(Source source) {
+    this._source = source;
+  }
+  accept(CharBuffer contents) {
+    _scanner = new CharBufferScanner(_source, contents);
+    _scanner.passThroughElements = _SCRIPT_TAG;
+    _token = _scanner.tokenize();
+  }
+  void accept2(String contents) {
+    _scanner = new StringScanner(_source, contents);
+    _scanner.passThroughElements = _SCRIPT_TAG;
+    _token = _scanner.tokenize();
+  }
+  /**
+   * Answer the result of scanning the source
+   * @return the result (not {@code null})
+   */
+  HtmlScanResult get result => new HtmlScanResult(_token, _scanner.lineStarts);
+}
+/**
+ * Instances of the class {@code XmlParser} are used to parse tokens into a AST structure comprised
+ * of {@link XmlNode}s.
+ * @coverage dart.engine.html
+ */
+class XmlParser {
+  /**
+   * The source being parsed.
+   */
+  Source _source;
+  /**
+   * The next token to be parsed.
+   */
+  Token _currentToken;
+  /**
+   * Construct a parser for the specified source.
+   * @param source the source being parsed
+   */
+  XmlParser(Source source) {
+    this._source = source;
+  }
+  /**
+   * Answer the source being parsed.
+   * @return the source
+   */
+  Source get source => _source;
+  /**
+   * Answer {@code true} if the specified tag is self closing and thus should never have content or
+   * child tag nodes.
+   * @param tag the tag (not {@code null})
+   * @return {@code true} if self closing
+   */
+  bool isSelfClosing(Token tag) => false;
+  /**
+   * Parse the entire token stream and in the process, advance the current token to the end of the
+   * token stream.
+   * @return the list of tag nodes found (not {@code null}, contains no {@code null})
+   */
+  List<XmlTagNode> parseTopTagNodes(Token firstToken) {
+    _currentToken = firstToken;
+    List<XmlTagNode> tagNodes = new List<XmlTagNode>();
+    while (true) {
+      while (true) {
+        if (_currentToken.type == TokenType.LT) {
+          tagNodes.add(parseTagNode());
+        } else if (_currentToken.type == TokenType.DECLARATION || _currentToken.type == TokenType.DIRECTIVE || _currentToken.type == TokenType.COMMENT) {
+          _currentToken = _currentToken.next;
+        } else if (_currentToken.type == TokenType.EOF) {
+          return tagNodes;
+        } else {
+          reportUnexpectedToken();
+          _currentToken = _currentToken.next;
+        }
+        break;
+      }
+    }
+  }
+  /**
+   * Answer the current token.
+   * @return the current token
+   */
+  Token get currentToken => _currentToken;
+  /**
+   * Insert a synthetic token of the specified type before the current token
+   * @param type the type of token to be inserted (not {@code null})
+   * @return the synthetic token that was inserted (not {@code null})
+   */
+  Token insertSyntheticToken(TokenType type) {
+    Token token = new Token.con2(type, _currentToken.offset, "");
+    _currentToken.previous.setNext(token);
+    token.setNext(_currentToken);
+    return token;
+  }
+  /**
+   * Parse the token stream for an attribute. This method advances the current token over the
+   * attribute, but should not be called if the {@link #currentToken} is not {@link TokenType#TAG}.
+   * @return the attribute (not {@code null})
+   */
+  XmlAttributeNode parseAttribute() {
+    Token name = _currentToken;
+    _currentToken = _currentToken.next;
+    Token equals;
+    if (identical(_currentToken.type, TokenType.EQ)) {
+      equals = _currentToken;
+      _currentToken = _currentToken.next;
+    } else {
+      reportUnexpectedToken();
+      equals = insertSyntheticToken(TokenType.EQ);
+    }
+    Token value;
+    if (identical(_currentToken.type, TokenType.STRING)) {
+      value = _currentToken;
+      _currentToken = _currentToken.next;
+    } else {
+      reportUnexpectedToken();
+      value = insertSyntheticToken(TokenType.STRING);
+    }
+    return new XmlAttributeNode(name, equals, value);
+  }
+  /**
+   * Parse the stream for a sequence of attributes. This method advances the current token to the
+   * next {@link TokenType#GT}, {@link TokenType#SLASH_GT}, or {@link TokenType#EOF}.
+   * @return a collection of zero or more attributes (not {@code null}, contains no {@code null}s)
+   */
+  List<XmlAttributeNode> parseAttributes() {
+    TokenType type11 = _currentToken.type;
+    if (identical(type11, TokenType.GT) || identical(type11, TokenType.SLASH_GT) || identical(type11, TokenType.EOF)) {
+      return XmlTagNode.NO_ATTRIBUTES;
+    }
+    List<XmlAttributeNode> attributes = new List<XmlAttributeNode>();
+    while (true) {
+      while (true) {
+        if (_currentToken.type == TokenType.GT || _currentToken.type == TokenType.SLASH_GT || _currentToken.type == TokenType.EOF) {
+          return attributes;
+        } else if (_currentToken.type == TokenType.TAG) {
+          attributes.add(parseAttribute());
+        } else {
+          reportUnexpectedToken();
+          _currentToken = _currentToken.next;
+        }
+        break;
+      }
+    }
+  }
+  /**
+   * Parse the stream for a sequence of tag nodes existing within a parent tag node. This method
+   * advances the current token to the next {@link TokenType#LT_SLASH} or {@link TokenType#EOF}.
+   * @return a list of nodes (not {@code null}, contains no {@code null}s)
+   */
+  List<XmlTagNode> parseChildTagNodes() {
+    TokenType type12 = _currentToken.type;
+    if (identical(type12, TokenType.LT_SLASH) || identical(type12, TokenType.EOF)) {
+      return XmlTagNode.NO_TAG_NODES;
+    }
+    List<XmlTagNode> nodes = new List<XmlTagNode>();
+    while (true) {
+      while (true) {
+        if (_currentToken.type == TokenType.LT) {
+          nodes.add(parseTagNode());
+        } else if (_currentToken.type == TokenType.LT_SLASH || _currentToken.type == TokenType.EOF) {
+          return nodes;
+        } else if (_currentToken.type == TokenType.COMMENT) {
+          _currentToken = _currentToken.next;
+        } else {
+          reportUnexpectedToken();
+          _currentToken = _currentToken.next;
+        }
+        break;
+      }
+    }
+  }
+  /**
+   * Parse the token stream for the next tag node. This method advances current token over the
+   * parsed tag node, but should only be called if the current token is {@link TokenType#LT}
+   * @return the tag node or {@code null} if none found
+   */
+  XmlTagNode parseTagNode() {
+    Token nodeStart = _currentToken;
+    _currentToken = _currentToken.next;
+    Token tag;
+    if (identical(_currentToken.type, TokenType.TAG)) {
+      tag = _currentToken;
+      _currentToken = _currentToken.next;
+    } else {
+      reportUnexpectedToken();
+      tag = insertSyntheticToken(TokenType.TAG);
+    }
+    List<XmlAttributeNode> attributes = parseAttributes();
+    Token attributeEnd;
+    if (identical(_currentToken.type, TokenType.GT) || identical(_currentToken.type, TokenType.SLASH_GT)) {
+      attributeEnd = _currentToken;
+      _currentToken = _currentToken.next;
+    } else {
+      reportUnexpectedToken();
+      attributeEnd = insertSyntheticToken(TokenType.SLASH_GT);
+    }
+    if (identical(attributeEnd.type, TokenType.SLASH_GT) || isSelfClosing(tag)) {
+      return new XmlTagNode(nodeStart, tag, attributes, attributeEnd, XmlTagNode.NO_TAG_NODES, _currentToken, null, attributeEnd);
+    }
+    List<XmlTagNode> tagNodes = parseChildTagNodes();
+    Token contentEnd;
+    if (identical(_currentToken.type, TokenType.LT_SLASH)) {
+      contentEnd = _currentToken;
+      _currentToken = _currentToken.next;
+    } else {
+      reportUnexpectedToken();
+      contentEnd = insertSyntheticToken(TokenType.LT_SLASH);
+    }
+    Token closingTag;
+    if (identical(_currentToken.type, TokenType.TAG)) {
+      closingTag = _currentToken;
+      _currentToken = _currentToken.next;
+    } else {
+      reportUnexpectedToken();
+      closingTag = insertSyntheticToken(TokenType.TAG);
+    }
+    Token nodeEnd;
+    if (identical(_currentToken.type, TokenType.GT)) {
+      nodeEnd = _currentToken;
+      _currentToken = _currentToken.next;
+    } else {
+      reportUnexpectedToken();
+      nodeEnd = insertSyntheticToken(TokenType.GT);
+    }
+    return new XmlTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes, contentEnd, closingTag, nodeEnd);
+  }
+  /**
+   * Report the current token as unexpected
+   */
+  void reportUnexpectedToken() {
+  }
+}
+/**
+ * Instances of {@code XmlTagNode} represent XML or HTML elements such as {@code <p>} and{@code <body foo="bar"> ... </body>}.
+ * @coverage dart.engine.html
+ */
+class XmlTagNode extends XmlNode {
+  /**
+   * Constant representing empty list of attributes.
+   */
+  static List<XmlAttributeNode> NO_ATTRIBUTES = new UnmodifiableListView(new List<XmlAttributeNode>());
+  /**
+   * Constant representing empty list of tag nodes.
+   */
+  static List<XmlTagNode> NO_TAG_NODES = new UnmodifiableListView(new List<XmlTagNode>());
+  /**
+   * The starting {@link TokenType#LT} token (not {@code null}).
+   */
+  Token _nodeStart;
+  /**
+   * The {@link TokenType#TAG} token after the starting '&lt;' (not {@code null}).
+   */
+  Token _tag;
+  /**
+   * The attributes contained by the receiver (not {@code null}, contains no {@code null}s).
+   */
+  List<XmlAttributeNode> _attributes;
+  /**
+   * The {@link TokenType#GT} or {@link TokenType#SLASH_GT} token after the attributes (not{@code null}). The token may be the same token as {@link #nodeEnd} if there are no child{@link #tagNodes}.
+   */
+  Token _attributeEnd;
+  /**
+   * The tag nodes contained in the receiver (not {@code null}, contains no {@code null}s).
+   */
+  List<XmlTagNode> _tagNodes;
+  /**
+   * The token (not {@code null}) after the content, which may be
+   * <ul>
+   * <li>(1) {@link TokenType#LT_SLASH} for nodes with open and close tags, or</li>
+   * <li>(2) the {@link TokenType#LT} nodeStart of the next sibling node if this node is self
+   * closing or the attributeEnd is {@link TokenType#SLASH_GT}, or</li>
+   * <li>(3) {@link TokenType#EOF} if the node does not have a closing tag and is the last node in
+   * the stream {@link TokenType#LT_SLASH} token after the content, or {@code null} if there is no
+   * content and the attributes ended with {@link TokenType#SLASH_GT}.</li>
+   * </ul>
+   */
+  Token _contentEnd;
+  /**
+   * The closing {@link TokenType#TAG} after the child elements or {@code null} if there is no
+   * content and the attributes ended with {@link TokenType#SLASH_GT}
+   */
+  Token _closingTag;
+  /**
+   * The ending {@link TokenType#GT} or {@link TokenType#SLASH_GT} token (not {@code null}).
+   */
+  Token _nodeEnd;
+  /**
+   * Construct a new instance representing an XML or HTML element
+   * @param nodeStart the starting {@link TokenType#LT} token (not {@code null})
+   * @param tag the {@link TokenType#TAG} token after the starting '&lt;' (not {@code null}).
+   * @param attributes the attributes associated with this element or {@link #NO_ATTRIBUTES} (not{@code null}, contains no {@code null}s)
+   * @param attributeEnd The {@link TokenType#GT} or {@link TokenType#SLASH_GT} token after the
+   * attributes (not {@code null}). The token may be the same token as {@link #nodeEnd} if
+   * there are no child {@link #tagNodes}.
+   * @param tagNodes child tag nodes of the receiver or {@link #NO_TAG_NODES} (not {@code null},
+   * contains no {@code null}s)
+   * @param contentEnd the token (not {@code null}) after the content, which may be
+   * <ul>
+   * <li>(1) {@link TokenType#LT_SLASH} for nodes with open and close tags, or</li>
+   * <li>(2) the {@link TokenType#LT} nodeStart of the next sibling node if this node is
+   * self closing or the attributeEnd is {@link TokenType#SLASH_GT}, or</li>
+   * <li>(3) {@link TokenType#EOF} if the node does not have a closing tag and is the last
+   * node in the stream {@link TokenType#LT_SLASH} token after the content, or {@code null}if there is no content and the attributes ended with {@link TokenType#SLASH_GT}.</li>
+   * </ul>
+   * @param closingTag the closing {@link TokenType#TAG} after the child elements or {@code null} if
+   * there is no content and the attributes ended with {@link TokenType#SLASH_GT}
+   * @param nodeEnd the ending {@link TokenType#GT} or {@link TokenType#SLASH_GT} token (not{@code null})
+   */
+  XmlTagNode(Token nodeStart, Token tag, List<XmlAttributeNode> attributes, Token attributeEnd, List<XmlTagNode> tagNodes, Token contentEnd, Token closingTag, Token nodeEnd) {
+    this._nodeStart = nodeStart;
+    this._tag = tag;
+    this._attributes = becomeParentOf(attributes);
+    this._attributeEnd = attributeEnd;
+    this._tagNodes = becomeParentOf(tagNodes);
+    this._contentEnd = contentEnd;
+    this._closingTag = closingTag;
+    this._nodeEnd = nodeEnd;
+  }
+  accept(XmlVisitor visitor) => visitor.visitXmlTagNode(this);
+  /**
+   * The {@link TokenType#GT} or {@link TokenType#SLASH_GT} token after the attributes (not{@code null}). The token may be the same token as {@link #nodeEnd} if there are no child{@link #tagNodes}.
+   * @return the token (not {@code null})
+   */
+  Token get attributeEnd => _attributeEnd;
+  /**
+   * Answer the receiver's attributes. Callers should not manipulate the returned list to edit the
+   * AST structure.
+   * @return the attributes (not {@code null}, contains no {@code null}s)
+   */
+  List<XmlAttributeNode> get attributes => _attributes;
+  Token get beginToken => _nodeStart;
+  /**
+   * The the closing {@link TokenType#TAG} after the child elements or {@code null} if there is no
+   * content and the attributes ended with {@link TokenType#SLASH_GT}
+   * @return the closing tag or {@code null}
+   */
+  Token get closingTag => _closingTag;
+  /**
+   * Answer a string representing the content contained in the receiver. This includes the textual
+   * representation of any child tag nodes ({@link #getTagNodes()}). Whitespace between '&lt;',
+   * '&lt;/', and '>', '/>' is discarded, but all other whitespace is preserved.
+   * @return the content (not {@code null})
+   */
+  String get content {
+    Token token = _attributeEnd.next;
+    if (identical(token, _contentEnd)) {
+      return "";
+    }
+    String content = token.lexeme;
+    token = token.next;
+    if (identical(token, _contentEnd)) {
+      return content;
+    }
+    JavaStringBuilder buffer = new JavaStringBuilder();
+    while (token != _contentEnd) {
+      buffer.append(token.lexeme);
+      token = token.next;
+    }
+    return buffer.toString();
+  }
+  /**
+   * Answer the token (not {@code null}) after the content, which may be
+   * <ul>
+   * <li>(1) {@link TokenType#LT_SLASH} for nodes with open and close tags, or</li>
+   * <li>(2) the {@link TokenType#LT} nodeStart of the next sibling node if this node is self
+   * closing or the attributeEnd is {@link TokenType#SLASH_GT}, or</li>
+   * <li>(3) {@link TokenType#EOF} if the node does not have a closing tag and is the last node in
+   * the stream {@link TokenType#LT_SLASH} token after the content, or {@code null} if there is no
+   * content and the attributes ended with {@link TokenType#SLASH_GT}.</li>
+   * </ul>
+   * @return the token (not {@code null})
+   */
+  Token get contentEnd => _contentEnd;
+  Token get endToken {
+    if (_nodeEnd != null) {
+      return _nodeEnd;
+    }
+    if (_closingTag != null) {
+      return _closingTag;
+    }
+    if (_contentEnd != null) {
+      return _contentEnd;
+    }
+    if (!_tagNodes.isEmpty) {
+      return _tagNodes[_tagNodes.length - 1].endToken;
+    }
+    if (_attributeEnd != null) {
+      return _attributeEnd;
+    }
+    if (!_attributes.isEmpty) {
+      return _attributes[_attributes.length - 1].endToken;
+    }
+    return _tag;
+  }
+  /**
+   * Answer the ending {@link TokenType#GT} or {@link TokenType#SLASH_GT} token.
+   * @return the token (not {@code null})
+   */
+  Token get nodeEnd => _nodeEnd;
+  /**
+   * Answer the starting {@link TokenType#LT} token.
+   * @return the token (not {@code null})
+   */
+  Token get nodeStart => _nodeStart;
+  /**
+   * Answer the {@link TokenType#TAG} token after the starting '&lt;'.
+   * @return the token (not {@code null})
+   */
+  Token get tag => _tag;
+  /**
+   * Answer the tag nodes contained in the receiver. Callers should not manipulate the returned list
+   * to edit the AST structure.
+   * @return the children (not {@code null}, contains no {@code null}s)
+   */
+  List<XmlTagNode> get tagNodes => _tagNodes;
+  void visitChildren(XmlVisitor<Object> visitor) {
+    for (XmlAttributeNode node in _attributes) {
+      node.accept(visitor);
+    }
+    for (XmlTagNode node in _tagNodes) {
+      node.accept(visitor);
+    }
+  }
+}
+/**
+ * Instances of the class {@code HtmlParser} are used to parse tokens into a AST structure comprised
+ * of {@link XmlNode}s.
+ * @coverage dart.engine.html
+ */
+class HtmlParser extends XmlParser {
+  static Set<String> SELF_CLOSING = new Set<String>();
+  /**
+   * Construct a parser for the specified source.
+   * @param source the source being parsed
+   */
+  HtmlParser(Source source) : super(source) {
+  }
+  /**
+   * Parse the tokens specified by the given scan result.
+   * @param scanResult the result of scanning an HTML source (not {@code null})
+   * @return the parse result (not {@code null})
+   */
+  HtmlParseResult parse(HtmlScanResult scanResult) {
+    Token firstToken = scanResult.token;
+    List<XmlTagNode> tagNodes = parseTopTagNodes(firstToken);
+    HtmlUnit unit = new HtmlUnit(firstToken, tagNodes, currentToken);
+    return new HtmlParseResult(firstToken, scanResult.lineStarts, unit);
+  }
+  /**
+   * Scan then parse the specified source.
+   * @param source the source to be scanned and parsed (not {@code null})
+   * @return the parse result (not {@code null})
+   */
+  HtmlParseResult parse2(Source source) {
+    HtmlScanner scanner = new HtmlScanner(source);
+    source.getContents(scanner);
+    return parse(scanner.result);
+  }
+  bool isSelfClosing(Token tag) => SELF_CLOSING.contains(tag.lexeme);
+}
+/**
+ * Instances of the class {@code HtmlUnit} represent the contents of an HTML file.
+ * @coverage dart.engine.html
+ */
+class HtmlUnit extends XmlNode {
+  /**
+   * The first token in the token stream that was parsed to form this HTML unit.
+   */
+  Token _beginToken;
+  /**
+   * The last token in the token stream that was parsed to form this compilation unit. This token
+   * should always have a type of {@link TokenType.EOF}.
+   */
+  Token _endToken;
+  /**
+   * The tag nodes contained in the receiver (not {@code null}, contains no {@code null}s).
+   */
+  List<XmlTagNode> _tagNodes;
+  /**
+   * The element associated with this HTML unit or {@code null} if the receiver is not resolved.
+   */
+  HtmlElementImpl _element;
+  /**
+   * Construct a new instance representing the content of an HTML file.
+   * @param beginToken the first token in the file (not {@code null})
+   * @param tagNodes child tag nodes of the receiver (not {@code null}, contains no {@code null}s)
+   * @param endToken the last token in the token stream which should be of type{@link TokenType.EOF}
+   */
+  HtmlUnit(Token beginToken, List<XmlTagNode> tagNodes, Token endToken) {
+    this._beginToken = beginToken;
+    this._tagNodes = becomeParentOf(tagNodes);
+    this._endToken = endToken;
+  }
+  accept(XmlVisitor visitor) => visitor.visitHtmlUnit(this);
+  Token get beginToken => _beginToken;
+  /**
+   * Return the element associated with this HTML unit.
+   * @return the element or {@code null} if the receiver is not resolved
+   */
+  HtmlElementImpl get element => _element;
+  Token get endToken => _endToken;
+  /**
+   * Answer the tag nodes contained in the receiver. Callers should not manipulate the returned list
+   * to edit the AST structure.
+   * @return the children (not {@code null}, contains no {@code null}s)
+   */
+  List<XmlTagNode> get tagNodes => _tagNodes;
+  /**
+   * Set the element associated with this HTML unit.
+   * @param element the element
+   */
+  void set element(HtmlElementImpl element18) {
+    this._element = element18;
+  }
+  void visitChildren(XmlVisitor<Object> visitor) {
+    for (XmlTagNode node in _tagNodes) {
+      node.accept(visitor);
+    }
+  }
+}
\ No newline at end of file
diff --git a/pkg/analyzer_experimental/lib/src/generated/instrumentation.dart b/pkg/analyzer_experimental/lib/src/generated/instrumentation.dart
new file mode 100644
index 0000000..f4c632b
--- /dev/null
+++ b/pkg/analyzer_experimental/lib/src/generated/instrumentation.dart
@@ -0,0 +1,219 @@
+// This code was auto-generated, is not intended to be edited, and is subject to
+// significant change. Please see the README file for more information.
+
+library engine.instrumentation;
+
+import 'java_core.dart';
+
+/**
+ * The class {@code Instrumentation} implements support for logging instrumentation information.
+ * <p>
+ * Instrumentation information consists of information about specific operations. Those operations
+ * can range from user-facing operations, such as saving the changes to a file, to internal
+ * operations, such as tokenizing source code. The information to be logged is gathered by{@link InstrumentationBuilder instrumentation builder}, created by one of the static methods on
+ * this class such as {@link #builder(Class)} or {@link #builder(String)}.
+ * <p>
+ * Note, however, that until an instrumentation logger is installed using the method{@link #setLogger(InstrumentationLogger)}, all instrumentation data will be lost.
+ * <p>
+ * <b>Example</b>
+ * <p>
+ * To collect metrics about how long it took to save a file, you would write something like the
+ * following:
+ * <pre>
+ * InstrumentationBuilder instrumentation = Instrumentation.builder(this.getClass());
+ * // save the file
+ * instrumentation.metric("chars", fileLength).log();
+ * </pre>
+ * The {@code Instrumentation.builder} method creates a new {@link InstrumentationBuilderinstrumentation builder} and records the time at which it was created. The{@link InstrumentationBuilder#metric(String,long)} appends the information specified by the
+ * arguments and records the time at which the method is called so that the time to complete the
+ * save operation can be calculated. The {@code log} method tells the builder that all of the data
+ * has been collected and that the resulting information should be logged.
+ * @coverage dart.engine.utilities
+ */
+class Instrumentation {
+  /**
+   * A builder that will silently ignore all data and logging requests.
+   */
+  static InstrumentationBuilder _NULL_INSTRUMENTATION_BUILDER = new InstrumentationBuilder_8();
+  /**
+   * An instrumentation logger that can be used when no other instrumentation logger has been
+   * configured. This logger will silently ignore all data and logging requests.
+   */
+  static InstrumentationLogger _NULL_LOGGER = new InstrumentationLogger_9();
+  /**
+   * The current instrumentation logger.
+   */
+  static InstrumentationLogger _CURRENT_LOGGER = _NULL_LOGGER;
+  /**
+   * Create a builder that can collect the data associated with an operation.
+   * @param clazz the class performing the operation (not {@code null})
+   * @return the builder that was created (not {@code null})
+   */
+  static InstrumentationBuilder builder(Type clazz) => _CURRENT_LOGGER.createBuilder(clazz.toString());
+  /**
+   * Create a builder that can collect the data associated with an operation.
+   * @param name the name used to uniquely identify the operation (not {@code null})
+   * @return the builder that was created (not {@code null})
+   */
+  static InstrumentationBuilder builder2(String name) => _CURRENT_LOGGER.createBuilder(name);
+  /**
+   * Return a builder that will silently ignore all data and logging requests.
+   * @return the builder (not {@code null})
+   */
+  static InstrumentationBuilder get nullBuilder => _NULL_INSTRUMENTATION_BUILDER;
+  /**
+   * Set the logger that should receive instrumentation information to the given logger.
+   * @param logger the logger that should receive instrumentation information
+   */
+  static void set logger(InstrumentationLogger logger3) {
+    _CURRENT_LOGGER = logger3 == null ? _NULL_LOGGER : logger3;
+  }
+  /**
+   * Prevent the creation of instances of this class
+   */
+  Instrumentation() {
+  }
+}
+class InstrumentationBuilder_8 implements InstrumentationBuilder {
+  InstrumentationBuilder data(String name, int value) => this;
+  InstrumentationBuilder data2(String name, String value) => this;
+  InstrumentationBuilder data3(String name, List<String> value) => this;
+  InstrumentationLevel get instrumentationLevel => InstrumentationLevel.OFF;
+  void log() {
+  }
+  InstrumentationBuilder metric(String name, int value) => this;
+  InstrumentationBuilder metric2(String name, String value) => this;
+  InstrumentationBuilder metric3(String name, List<String> value) => this;
+}
+class InstrumentationLogger_9 implements InstrumentationLogger {
+  InstrumentationBuilder createBuilder(String name) => Instrumentation._NULL_INSTRUMENTATION_BUILDER;
+}
+/**
+ * The interface {@code InstrumentationBuilder} defines the behavior of objects used to collect data
+ * about an operation that has occurred and record that data through an instrumentation logger.
+ * <p>
+ * For an example of using objects that implement this interface, see {@link Instrumentation}.
+ * @coverage dart.engine.utilities
+ */
+abstract class InstrumentationBuilder {
+  /**
+   * Append the given data to the data being collected by this builder. The information is declared
+   * to potentially contain data that is either user identifiable or contains user intellectual
+   * property (but is not guaranteed to contain either).
+   * @param name the name used to identify the data
+   * @param value the value of the data to be collected
+   * @return this builder
+   */
+  InstrumentationBuilder data(String name, int value);
+  /**
+   * Append the given data to the data being collected by this builder. The information is declared
+   * to potentially contain data that is either user identifiable or contains user intellectual
+   * property (but is not guaranteed to contain either).
+   * @param name the name used to identify the data
+   * @param value the value of the data to be collected
+   * @return this builder
+   */
+  InstrumentationBuilder data2(String name, String value);
+  /**
+   * Append the given data to the data being collected by this builder. The information is declared
+   * to potentially contain data that is either user identifiable or contains user intellectual
+   * property (but is not guaranteed to contain either).
+   * @param name the name used to identify the data
+   * @param value the value of the data to be collected
+   * @return this builder
+   */
+  InstrumentationBuilder data3(String name, List<String> value);
+  /**
+   * Answer the {@link InstrumentationLevel} of this {@code InstrumentationBuilder}.
+   * @return one of {@link InstrumentationLevel#EVERYTHING}, {@link InstrumentationLevel#METRICS},{@link InstrumentationLevel#OFF}
+   */
+  InstrumentationLevel get instrumentationLevel;
+  /**
+   * Log the data that has been collected. The instrumentation builder should not be used after this
+   * method is invoked. The behavior of any method defined on this interface that is used after this
+   * method is invoked is undefined.
+   */
+  void log();
+  /**
+   * Append the given metric to the data being collected by this builder. The information is
+   * declared to contain only metrics data (data that is not user identifiable and does not contain
+   * user intellectual property).
+   * @param name the name used to identify the data
+   * @param value the value of the data to be collected
+   * @return this builder
+   */
+  InstrumentationBuilder metric(String name, int value);
+  /**
+   * Append the given metric to the data being collected by this builder. The information is
+   * declared to contain only metrics data (data that is not user identifiable and does not contain
+   * user intellectual property).
+   * @param name the name used to identify the data
+   * @param value the value of the data to be collected
+   * @return this builder
+   */
+  InstrumentationBuilder metric2(String name, String value);
+  /**
+   * Append the given metric to the data being collected by this builder. The information is
+   * declared to contain only metrics data (data that is not user identifiable and does not contain
+   * user intellectual property).
+   * @param name the name used to identify the data
+   * @param value the value of the data to be collected
+   * @return this builder
+   */
+  InstrumentationBuilder metric3(String name, List<String> value);
+}
+/**
+ * The instrumentation recording level representing (1) recording {@link #EVERYTHING} recording of
+ * all instrumentation data, (2) recording only {@link #METRICS} information, or (3) recording
+ * turned {@link #OFF} in which case nothing is recorded.
+ * @coverage dart.engine.utilities
+ */
+class InstrumentationLevel {
+  /**
+   * Recording all instrumented information
+   */
+  static final InstrumentationLevel EVERYTHING = new InstrumentationLevel('EVERYTHING', 0);
+  /**
+   * Recording only metrics
+   */
+  static final InstrumentationLevel METRICS = new InstrumentationLevel('METRICS', 1);
+  /**
+   * Nothing recorded
+   */
+  static final InstrumentationLevel OFF = new InstrumentationLevel('OFF', 2);
+  static final List<InstrumentationLevel> values = [EVERYTHING, METRICS, OFF];
+  final String __name;
+  final int __ordinal;
+  int get ordinal => __ordinal;
+  static InstrumentationLevel fromString(String str) {
+    if (str == "EVERYTHING") {
+      return InstrumentationLevel.EVERYTHING;
+    }
+    if (str == "METRICS") {
+      return InstrumentationLevel.METRICS;
+    }
+    if (str == "OFF") {
+      return InstrumentationLevel.OFF;
+    }
+    throw new IllegalArgumentException("Unrecognised InstrumentationLevel");
+  }
+  InstrumentationLevel(this.__name, this.__ordinal) {
+  }
+  String toString() => __name;
+}
+/**
+ * The interface {@code InstrumentationLogger} defines the behavior of objects that are used to log
+ * instrumentation data.
+ * <p>
+ * For an example of using objects that implement this interface, see {@link Instrumentation}.
+ * @coverage dart.engine.utilities
+ */
+abstract class InstrumentationLogger {
+  /**
+   * Create a builder that can collect the data associated with an operation identified by the given
+   * name.
+   * @param name the name used to uniquely identify the operation
+   * @return the builder that was created
+   */
+  InstrumentationBuilder createBuilder(String name);
+}
\ No newline at end of file
diff --git a/pkg/analyzer-experimental/lib/src/generated/java_core.dart b/pkg/analyzer_experimental/lib/src/generated/java_core.dart
similarity index 78%
rename from pkg/analyzer-experimental/lib/src/generated/java_core.dart
rename to pkg/analyzer_experimental/lib/src/generated/java_core.dart
index 7b148cb..1170ca1 100644
--- a/pkg/analyzer-experimental/lib/src/generated/java_core.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/java_core.dart
@@ -1,30 +1,18 @@
 library java.core;
 
 import "dart:math" as math;
-import "dart:io";
 import "dart:uri";
 
-class System {
-  static final String pathSeparator = Platform.pathSeparator;
-  static final int pathSeparatorChar = Platform.pathSeparator.codeUnitAt(0);
-
+class JavaSystem {
   static int currentTimeMillis() {
     return (new DateTime.now()).millisecondsSinceEpoch;
   }
-  static String getProperty(String name) {
-    if (name == 'os.name') {
-      return Platform.operatingSystem;
-    }
-    if (name == 'line.separator') {
-      if (Platform.operatingSystem == 'windows') {
-        return '\r\n';
-      }
-      return '\n';
-    }
-    return null;
-  }
-  static String getenv(String name) => Platform.environment[name];
 
+  static void arraycopy(List src, int srcPos, List dest, int destPos, int length) {
+    for (int i = 0; i < length; i++) {
+      dest[destPos + i] = src[srcPos + i];
+    }
+  }
 }
 
 /**
@@ -43,15 +31,22 @@
   if (oTypeName == tTypeName) {
     return true;
   }
-  if (oTypeName == "${tTypeName}Impl") {
-    return true;
-  }
-  if (oTypeName.startsWith("_HashMap") && tTypeName == "Map") {
+  if (oTypeName.startsWith("HashMap") && tTypeName == "Map") {
     return true;
   }
   if (oTypeName.startsWith("List") && tTypeName == "List") {
     return true;
   }
+  // Dart Analysis Engine specific
+  if (oTypeName == "${tTypeName}Impl") {
+    return true;
+  }
+  if (tTypeName == "ExecutableElement") {
+    if (oTypeName == "MethodElementImpl" || oTypeName == "FunctionElementImpl") {
+      return true;
+    }
+  }
+  // no
   return false;
 }
 
@@ -90,6 +85,9 @@
   static bool isLetterOrDigit(int c) {
     return isLetter(c) || c >= 0x30 && c <= 0x39;
   }
+  static bool isWhitespace(int c) {
+    return c == 0x09 || c == 0x20 || c == 0x0A || c == 0x0D;
+  }
   static int digit(int codePoint, int radix) {
     if (radix != 16) {
       throw new ArgumentError("only radix == 16 is supported");
@@ -100,6 +98,10 @@
     if (0x41 <= codePoint && codePoint <= 0x46) {
       return 0xA + (codePoint - 0x41);
     }
+    if (0x61 <= codePoint && codePoint <= 0x66) {
+      return 0xA + (codePoint - 0x61);
+    }
+    return -1;
   }
   static String toChars(int codePoint) {
     throw new UnsupportedOperationException();
@@ -132,7 +134,7 @@
     int c = fmt.codeUnitAt(i);
     if (c == 0x25) {
       if (markFound) {
-        sb.addCharCode(c);
+        sb.writeCharCode(c);
         markFound = false;
       } else {
         markFound = true;
@@ -143,18 +145,18 @@
       markFound = false;
       // %d
       if (c == 0x64) {
-        sb.add(args[argIndex++]);
+        sb.writeCharCode(args[argIndex++]);
         continue;
       }
       // %s
       if (c == 0x73) {
-        sb.add(args[argIndex++]);
+        sb.writeCharCode(args[argIndex++]);
         continue;
       }
       // unknown
       throw new IllegalArgumentException('[$fmt][$i] = 0x${c.toRadixString(16)}');
     } else {
-      sb.addCharCode(c);
+      sb.writeCharCode(c);
     }
   }
   return sb.toString();
@@ -181,7 +183,7 @@
   final StringBuffer _sb = new StringBuffer();
 
   void print(x) {
-    _sb.add(x);
+    _sb.write(x);
   }
 
   String toString() => _sb.toString();
@@ -193,7 +195,7 @@
   static String repeat(String s, int n) {
     StringBuffer sb = new StringBuffer();
     for (int i = 0; i < n; i++) {
-      sb.add(s);
+      sb.write(s);
     }
     return sb.toString();
   }
@@ -222,6 +224,12 @@
   String toString() => "IllegalStateException: $message";
 }
 
+class StringIndexOutOfBoundsException implements Exception {
+  final int index;
+  const StringIndexOutOfBoundsException(this.index);
+  String toString() => "StringIndexOutOfBoundsException: $index";
+}
+
 class IllegalStateException implements Exception {
   final String message;
   const IllegalStateException([this.message = ""]);
@@ -268,7 +276,7 @@
   }
 
   void addLast(E value) {
-    elements.addLast(value);
+    elements.add(value);
   }
 
   void addAll(Iterable<E> iterable) {
@@ -283,6 +291,10 @@
     return elements.indexOf(element, start);
   }
 
+  void insert(int index, E element) {
+    elements.insert(index, element);
+  }
+
   int lastIndexOf(E element, [int start]) {
     return elements.lastIndexOf(element, start);
   }
@@ -305,9 +317,9 @@
 
   Iterable<E> get reversed => elements.reversed;
 
-  List<E> getRange(int start, int length) {
-    return elements.getRange(start, length);
-  }
+  List<E> sublist(int start, [int end]) => elements.sublist(start, end);
+
+  List<E> getRange(int start, int length) => sublist(start, start + length);
 
   void setRange(int start, int length, List<E> from, [int startFrom]) {
     elements.setRange(start, length, from, startFrom);
@@ -320,6 +332,10 @@
   void insertRange(int start, int length, [E fill]) {
     elements.insertRange(start, length, fill);
   }
+
+  Map<int, E> asMap() {
+    return elements.asMap();
+  }
 }
 
 class JavaIterator<E> {
@@ -388,20 +404,34 @@
   });
 }
 
-File newRelativeFile(File base, String child) {
-  var childPath = new Path(base.fullPathSync()).join(new Path(child));
-  return new File.fromPath(childPath);
+bool javaStringEqualsIgnoreCase(String a, String b) {
+  return a.toLowerCase() == b.toLowerCase();
 }
 
-File newFileFromUri(Uri uri) {
-  return new File(uri.path);
-}
-
-File getAbsoluteFile(File file) {
-  var path = file.fullPathSync();
-  return new File(path);
-}
-
-Uri newUriFromFile(File file) {
-  return new Uri.fromComponents(path: file.fullPathSync());
+class JavaStringBuilder {
+  StringBuffer sb = new StringBuffer();
+  String toString() => sb.toString();
+  void append(x) {
+    sb.write(x);
+  }
+  void appendChar(int c) {
+    sb.writeCharCode(c);
+  }
+  int get length => sb.length;
+  void set length(int newLength) {
+    if (newLength < 0) {
+      throw new StringIndexOutOfBoundsException(newLength);
+    }
+    if (sb.length < newLength) {
+      while (sb.length < newLength) {
+        sb.writeCharCode(0);
+      }
+    } else if (sb.length > newLength) {
+      var s = sb.toString().substring(0, newLength);
+      sb = new StringBuffer(s);
+    }
+  }
+  void clear() {
+    sb = new StringBuffer();
+  }
 }
diff --git a/pkg/analyzer_experimental/lib/src/generated/java_engine.dart b/pkg/analyzer_experimental/lib/src/generated/java_engine.dart
new file mode 100644
index 0000000..770acf5
--- /dev/null
+++ b/pkg/analyzer_experimental/lib/src/generated/java_engine.dart
@@ -0,0 +1,18 @@
+library java.engine;
+
+class StringUtilities {
+  static List<String> EMPTY_ARRAY = new List(0);
+}
+
+class FileNameUtilities {
+  static String getExtension(String fileName) {
+    if (fileName == null) {
+      return "";
+    }
+    int index = fileName.lastIndexOf('.');
+    if (index >= 0) {
+      return fileName.substring(index + 1);
+    }
+    return "";
+  }
+}
diff --git a/pkg/analyzer_experimental/lib/src/generated/java_engine_io.dart b/pkg/analyzer_experimental/lib/src/generated/java_engine_io.dart
new file mode 100644
index 0000000..32923b6
--- /dev/null
+++ b/pkg/analyzer_experimental/lib/src/generated/java_engine_io.dart
@@ -0,0 +1,14 @@
+library java.engine.io;
+
+import "dart:io";
+import "java_io.dart";
+
+
+class OSUtilities {
+  static bool isWindows() => Platform.operatingSystem == 'windows';
+  static bool isMac() => Platform.operatingSystem == 'macos';
+}
+
+class FileUtilities2 {
+  static JavaFile createFile(String path) => new JavaFile(path);
+}
diff --git a/pkg/analyzer_experimental/lib/src/generated/java_io.dart b/pkg/analyzer_experimental/lib/src/generated/java_io.dart
new file mode 100644
index 0000000..53c2546
--- /dev/null
+++ b/pkg/analyzer_experimental/lib/src/generated/java_io.dart
@@ -0,0 +1,89 @@
+library java.io;
+
+import "dart:io";
+import "dart:uri";
+
+class JavaSystemIO {
+  static Map<String, String> _properties = new Map();
+  static String getProperty(String name) {
+    {
+      String value = _properties[name];
+      if (value != null) {
+        return value;
+      }
+    }
+    if (name == 'os.name') {
+      return Platform.operatingSystem;
+    }
+    if (name == 'line.separator') {
+      if (Platform.operatingSystem == 'windows') {
+        return '\r\n';
+      }
+      return '\n';
+    }
+    if (name == 'com.google.dart.sdk') {
+      String exec = new Options().executable;
+      if (exec.length != 0) {
+        String sdkPath;
+        // may be "xcodebuild/ReleaseIA32/dart" with "dart-sdk" sibling
+        {
+          sdkPath = new Path(exec).directoryPath.append("dart-sdk").toNativePath();
+          if (new Directory(sdkPath).existsSync()) {
+            _properties[name] = sdkPath;
+            return sdkPath;
+          }
+        }
+        // probably be "dart-sdk/bin/dart"
+        sdkPath = new Path(exec).directoryPath.directoryPath.toString();
+        _properties[name] = sdkPath;
+        return sdkPath;
+      }
+    }
+    return null;
+  }
+  static String setProperty(String name, String value) {
+    String oldValue = _properties[name];
+    _properties[name] = value;
+    return oldValue;
+  }
+  static String getenv(String name) => Platform.environment[name];
+}
+
+class JavaFile {
+  static final String separator = Platform.pathSeparator;
+  static final int separatorChar = Platform.pathSeparator.codeUnitAt(0);
+  Path _path;
+  JavaFile(String path) {
+    this._path = new Path(path);
+  }
+  JavaFile.relative(JavaFile base, String child) {
+    this._path = base._path.join(new Path(child));
+  }
+  JavaFile.fromUri(Uri uri) : this(uri.path);
+  int get hashCode => _path.hashCode;
+  bool operator ==(other) {
+    return other is JavaFile && other._path.toNativePath() == _path.toNativePath();
+  }
+  String getPath() => _path.toNativePath();
+  String getName() => _path.filename;
+  String getParent() => _path.directoryPath.toNativePath();
+  JavaFile getParentFile() => new JavaFile(getParent());
+  String getAbsolutePath() => _path.canonicalize().toNativePath();
+  String getCanonicalPath() => _path.canonicalize().toNativePath();
+  JavaFile getAbsoluteFile() => new JavaFile(getAbsolutePath());
+  JavaFile getCanonicalFile() => new JavaFile(getCanonicalPath());
+  bool exists() {
+    if (_newFile().existsSync()) {
+      return true;
+    }
+    if (_newDirectory().existsSync()) {
+      return true;
+    }
+    return false;
+  }
+  Uri toURI() => new Uri.fromComponents(path: _path.toString());
+  String readAsStringSync() => _newFile().readAsStringSync();
+  int lastModified() => _newFile().lastModifiedSync().millisecondsSinceEpoch;
+  File _newFile() => new File.fromPath(_path);
+  Directory _newDirectory() => new Directory.fromPath(_path);
+}
diff --git a/pkg/analyzer-experimental/lib/src/generated/java_junit.dart b/pkg/analyzer_experimental/lib/src/generated/java_junit.dart
similarity index 100%
rename from pkg/analyzer-experimental/lib/src/generated/java_junit.dart
rename to pkg/analyzer_experimental/lib/src/generated/java_junit.dart
diff --git a/pkg/analyzer-experimental/lib/src/generated/parser.dart b/pkg/analyzer_experimental/lib/src/generated/parser.dart
similarity index 88%
rename from pkg/analyzer-experimental/lib/src/generated/parser.dart
rename to pkg/analyzer_experimental/lib/src/generated/parser.dart
index 1c3f211..b23627d 100644
--- a/pkg/analyzer-experimental/lib/src/generated/parser.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/parser.dart
@@ -10,11 +10,12 @@
 import 'source.dart';
 import 'scanner.dart';
 import 'ast.dart';
-import 'package:analyzer-experimental/src/generated/utilities_dart.dart';
+import 'package:analyzer_experimental/src/generated/utilities_dart.dart';
 
 /**
  * Instances of the class {@code CommentAndMetadata} implement a simple data-holder for a method
  * that needs to return multiple values.
+ * @coverage dart.engine.parser
  */
 class CommentAndMetadata {
   /**
@@ -48,6 +49,7 @@
 /**
  * Instances of the class {@code FinalConstVarOrType} implement a simple data-holder for a method
  * that needs to return multiple values.
+ * @coverage dart.engine.parser
  */
 class FinalConstVarOrType {
   /**
@@ -81,6 +83,7 @@
 /**
  * Instances of the class {@code Modifiers} implement a simple data-holder for a method that needs
  * to return multiple values.
+ * @coverage dart.engine.parser
  */
 class Modifiers {
   /**
@@ -207,7 +210,7 @@
     this._varKeyword = varKeyword2;
   }
   String toString() {
-    StringBuffer builder = new StringBuffer();
+    JavaStringBuilder builder = new JavaStringBuilder();
     bool needsSpace = appendKeyword(builder, false, _abstractKeyword);
     needsSpace = appendKeyword(builder, needsSpace, _constKeyword);
     needsSpace = appendKeyword(builder, needsSpace, _externalKeyword);
@@ -225,12 +228,12 @@
    * @param keyword the keyword to be appended
    * @return {@code true} if subsequent keywords need to be prefixed with a space
    */
-  bool appendKeyword(StringBuffer builder, bool needsSpace, Token keyword) {
+  bool appendKeyword(JavaStringBuilder builder, bool needsSpace, Token keyword) {
     if (keyword != null) {
       if (needsSpace) {
-        builder.addCharCode(0x20);
+        builder.appendChar(0x20);
       }
-      builder.add(keyword.lexeme);
+      builder.append(keyword.lexeme);
       return true;
     }
     return needsSpace;
@@ -238,6 +241,7 @@
 }
 /**
  * Instances of the class {@code Parser} are used to parse tokens into an AST structure.
+ * @coverage dart.engine.parser
  */
 class Parser {
   /**
@@ -332,15 +336,15 @@
    * @param startIndex the index of the first character representing the scalar value
    * @param endIndex the index of the last character representing the scalar value
    */
-  void appendScalarValue(StringBuffer builder, String escapeSequence, int scalarValue, int startIndex, int endIndex) {
+  void appendScalarValue(JavaStringBuilder builder, String escapeSequence, int scalarValue, int startIndex, int endIndex) {
     if (scalarValue < 0 || scalarValue > Character.MAX_CODE_POINT || (scalarValue >= 0xD800 && scalarValue <= 0xDFFF)) {
-      reportError3(ParserErrorCode.INVALID_CODE_POINT, [escapeSequence]);
+      reportError4(ParserErrorCode.INVALID_CODE_POINT, [escapeSequence]);
       return;
     }
     if (scalarValue < Character.MAX_VALUE) {
-      builder.addCharCode((scalarValue as int));
+      builder.appendChar((scalarValue as int));
     } else {
-      builder.add(Character.toChars(scalarValue));
+      builder.append(Character.toChars(scalarValue));
     }
   }
   /**
@@ -370,7 +374,7 @@
     } else if (end > 1 && (lexeme.endsWith("\"") || lexeme.endsWith("'"))) {
       end -= 1;
     }
-    StringBuffer builder = new StringBuffer();
+    JavaStringBuilder builder = new JavaStringBuilder();
     int index = start;
     while (index < end) {
       index = translateCharacter(builder, lexeme, index);
@@ -407,7 +411,7 @@
    */
   void ensureAssignable(Expression expression) {
     if (expression != null && !expression.isAssignable()) {
-      reportError3(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, []);
+      reportError4(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, []);
     }
   }
   /**
@@ -420,7 +424,7 @@
     if (matches(keyword)) {
       return andAdvance;
     }
-    reportError3(ParserErrorCode.EXPECTED_TOKEN, [keyword.syntax]);
+    reportError4(ParserErrorCode.EXPECTED_TOKEN, [keyword.syntax]);
     return _currentToken;
   }
   /**
@@ -434,9 +438,9 @@
       return andAdvance;
     }
     if (identical(type, TokenType.SEMICOLON)) {
-      reportError4(ParserErrorCode.EXPECTED_TOKEN, _currentToken.previous, [type.lexeme]);
+      reportError5(ParserErrorCode.EXPECTED_TOKEN, _currentToken.previous, [type.lexeme]);
     } else {
-      reportError3(ParserErrorCode.EXPECTED_TOKEN, [type.lexeme]);
+      reportError4(ParserErrorCode.EXPECTED_TOKEN, [type.lexeme]);
     }
     return _currentToken;
   }
@@ -537,8 +541,8 @@
     if (token == null) {
       return false;
     }
-    TokenType type15 = token.type;
-    return identical(type15, TokenType.EQ) || identical(type15, TokenType.COMMA) || identical(type15, TokenType.SEMICOLON) || matches3(token, Keyword.IN);
+    TokenType type21 = token.type;
+    return identical(type21, TokenType.EQ) || identical(type21, TokenType.COMMA) || identical(type21, TokenType.SEMICOLON) || matches3(token, Keyword.IN);
   }
   /**
    * Return {@code true} if the current token appears to be the beginning of a switch member.
@@ -550,8 +554,8 @@
       token = token.next.next;
     }
     if (identical(token.type, TokenType.KEYWORD)) {
-      Keyword keyword27 = ((token as KeywordToken)).keyword;
-      return identical(keyword27, Keyword.CASE) || identical(keyword27, Keyword.DEFAULT);
+      Keyword keyword29 = ((token as KeywordToken)).keyword;
+      return identical(keyword29, Keyword.CASE) || identical(keyword29, Keyword.DEFAULT);
     }
     return false;
   }
@@ -568,8 +572,8 @@
     int firstOffset = 2147483647;
     for (Token token in tokens) {
       if (token != null) {
-        int offset4 = token.offset;
-        if (offset4 < firstOffset) {
+        int offset5 = token.offset;
+        if (offset5 < firstOffset) {
           first = token;
         }
       }
@@ -594,14 +598,14 @@
    * @param keyword the keyword that is being tested for
    * @return {@code true} if the given token matches the given keyword
    */
-  bool matches3(Token token, Keyword keyword35) => identical(token.type, TokenType.KEYWORD) && identical(((token as KeywordToken)).keyword, keyword35);
+  bool matches3(Token token, Keyword keyword37) => identical(token.type, TokenType.KEYWORD) && identical(((token as KeywordToken)).keyword, keyword37);
   /**
    * Return {@code true} if the given token has the given type.
    * @param token the token being tested
    * @param type the type of token that is being tested for
    * @return {@code true} if the given token has the given type
    */
-  bool matches4(Token token, TokenType type24) => identical(token.type, type24);
+  bool matches4(Token token, TokenType type31) => identical(token.type, type31);
   /**
    * Return {@code true} if the current token has the given type. Note that this method, unlike
    * other variants, will modify the token stream if possible to match a wider range of tokens. In
@@ -610,33 +614,33 @@
    * @param type the type of token that can optionally appear in the current location
    * @return {@code true} if the current token has the given type
    */
-  bool matches5(TokenType type25) {
+  bool matches5(TokenType type32) {
     TokenType currentType = _currentToken.type;
-    if (currentType != type25) {
-      if (identical(type25, TokenType.GT)) {
+    if (currentType != type32) {
+      if (identical(type32, TokenType.GT)) {
         if (identical(currentType, TokenType.GT_GT)) {
-          int offset5 = _currentToken.offset;
-          Token first = new Token(TokenType.GT, offset5);
-          Token second = new Token(TokenType.GT, offset5 + 1);
+          int offset6 = _currentToken.offset;
+          Token first = new Token(TokenType.GT, offset6);
+          Token second = new Token(TokenType.GT, offset6 + 1);
           second.setNext(_currentToken.next);
           first.setNext(second);
           _currentToken.previous.setNext(first);
           _currentToken = first;
           return true;
         } else if (identical(currentType, TokenType.GT_EQ)) {
-          int offset6 = _currentToken.offset;
-          Token first = new Token(TokenType.GT, offset6);
-          Token second = new Token(TokenType.EQ, offset6 + 1);
+          int offset7 = _currentToken.offset;
+          Token first = new Token(TokenType.GT, offset7);
+          Token second = new Token(TokenType.EQ, offset7 + 1);
           second.setNext(_currentToken.next);
           first.setNext(second);
           _currentToken.previous.setNext(first);
           _currentToken = first;
           return true;
         } else if (identical(currentType, TokenType.GT_GT_EQ)) {
-          int offset7 = _currentToken.offset;
-          Token first = new Token(TokenType.GT, offset7);
-          Token second = new Token(TokenType.GT, offset7 + 1);
-          Token third = new Token(TokenType.EQ, offset7 + 2);
+          int offset8 = _currentToken.offset;
+          Token first = new Token(TokenType.GT, offset8);
+          Token second = new Token(TokenType.GT, offset8 + 1);
+          Token third = new Token(TokenType.EQ, offset8 + 2);
           third.setNext(_currentToken.next);
           second.setNext(third);
           first.setNext(second);
@@ -792,7 +796,7 @@
       arguments.add(argument);
       if (foundNamedArgument) {
         if (!generatedError && argument is! NamedExpression) {
-          reportError3(ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT, []);
+          reportError4(ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT, []);
           generatedError = true;
         }
       } else if (argument is NamedExpression) {
@@ -842,10 +846,10 @@
         if (expression is SimpleIdentifier) {
           expression = new MethodInvocation.full(null, null, (expression as SimpleIdentifier), argumentList);
         } else if (expression is PrefixedIdentifier) {
-          PrefixedIdentifier identifier = (expression as PrefixedIdentifier);
+          PrefixedIdentifier identifier = expression as PrefixedIdentifier;
           expression = new MethodInvocation.full(identifier.prefix, identifier.period, identifier.identifier, argumentList);
         } else if (expression is PropertyAccess) {
-          PropertyAccess access = (expression as PropertyAccess);
+          PropertyAccess access = expression as PropertyAccess;
           expression = new MethodInvocation.full(access.target, access.operator, access.propertyName, argumentList);
         } else {
           expression = new FunctionExpressionInvocation.full(expression, argumentList);
@@ -857,7 +861,7 @@
       Expression selectorExpression = parseAssignableSelector(expression, isOptional || (expression is PrefixedIdentifier));
       if (identical(selectorExpression, expression)) {
         if (!isOptional && (expression is PrefixedIdentifier)) {
-          PrefixedIdentifier identifier = (expression as PrefixedIdentifier);
+          PrefixedIdentifier identifier = expression as PrefixedIdentifier;
           expression = new PropertyAccess.full(identifier.prefix, identifier.period, identifier.identifier);
         }
         return expression;
@@ -888,7 +892,7 @@
       return new PropertyAccess.full(prefix, period, parseSimpleIdentifier());
     } else {
       if (!optional) {
-        reportError3(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, []);
+        reportError4(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, []);
       }
       return prefix;
     }
@@ -977,7 +981,7 @@
         statements.add(statement);
       }
       if (identical(_currentToken, statementStart)) {
-        reportError4(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
+        reportError5(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
         advance();
       }
       statementStart = _currentToken;
@@ -1000,7 +1004,7 @@
       label = parseSimpleIdentifier();
     }
     if (!_inLoop && !_inSwitch && label == null) {
-      reportError4(ParserErrorCode.BREAK_OUTSIDE_OF_LOOP, breakKeyword, []);
+      reportError5(ParserErrorCode.BREAK_OUTSIDE_OF_LOOP, breakKeyword, []);
     }
     Token semicolon = expect2(TokenType.SEMICOLON);
     return new BreakStatement.full(breakKeyword, label, semicolon);
@@ -1009,7 +1013,7 @@
    * Parse a cascade section.
    * <pre>
    * cascadeSection ::=
-   * '..' cascadeSelector arguments* (assignableSelector arguments*)* cascadeAssignment?
+   * '..' (cascadeSelector arguments*) (assignableSelector arguments*)* cascadeAssignment?
    * cascadeSelector ::=
    * '[' expression ']'
    * | identifier
@@ -1031,7 +1035,7 @@
       expression = new IndexExpression.forCascade_full(period, leftBracket, index, rightBracket);
       period = null;
     } else {
-      reportError4(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
+      reportError5(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
       return expression;
     }
     if (identical(_currentToken.type, TokenType.OPEN_PAREN)) {
@@ -1065,7 +1069,7 @@
     if (_currentToken.type.isAssignmentOperator()) {
       Token operator = andAdvance;
       ensureAssignable(expression);
-      expression = new AssignmentExpression.full(expression, operator, parseExpression2());
+      expression = new AssignmentExpression.full(expression, operator, parseExpressionWithoutCascade());
     }
     return expression;
   }
@@ -1082,7 +1086,7 @@
    */
   ClassDeclaration parseClassDeclaration(CommentAndMetadata commentAndMetadata, Token abstractKeyword) {
     Token keyword = expect(Keyword.CLASS);
-    SimpleIdentifier name = parseSimpleIdentifier2(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
+    SimpleIdentifier name = parseSimpleIdentifier();
     String className = name.name;
     TypeParameterList typeParameters = null;
     if (matches5(TokenType.LT)) {
@@ -1097,29 +1101,29 @@
         if (extendsClause == null) {
           extendsClause = parseExtendsClause();
           if (withClause != null) {
-            reportError4(ParserErrorCode.WITH_BEFORE_EXTENDS, withClause.withKeyword, []);
+            reportError5(ParserErrorCode.WITH_BEFORE_EXTENDS, withClause.withKeyword, []);
           } else if (implementsClause != null) {
-            reportError4(ParserErrorCode.IMPLEMENTS_BEFORE_EXTENDS, implementsClause.keyword, []);
+            reportError5(ParserErrorCode.IMPLEMENTS_BEFORE_EXTENDS, implementsClause.keyword, []);
           }
         } else {
-          reportError4(ParserErrorCode.MULTIPLE_EXTENDS_CLAUSES, extendsClause.keyword, []);
+          reportError5(ParserErrorCode.MULTIPLE_EXTENDS_CLAUSES, extendsClause.keyword, []);
           parseExtendsClause();
         }
       } else if (matches(Keyword.WITH)) {
         if (withClause == null) {
           withClause = parseWithClause();
           if (implementsClause != null) {
-            reportError4(ParserErrorCode.IMPLEMENTS_BEFORE_WITH, implementsClause.keyword, []);
+            reportError5(ParserErrorCode.IMPLEMENTS_BEFORE_WITH, implementsClause.keyword, []);
           }
         } else {
-          reportError4(ParserErrorCode.MULTIPLE_WITH_CLAUSES, withClause.withKeyword, []);
+          reportError5(ParserErrorCode.MULTIPLE_WITH_CLAUSES, withClause.withKeyword, []);
           parseWithClause();
         }
       } else if (matches(Keyword.IMPLEMENTS)) {
         if (implementsClause == null) {
           implementsClause = parseImplementsClause();
         } else {
-          reportError4(ParserErrorCode.MULTIPLE_IMPLEMENTS_CLAUSES, implementsClause.keyword, []);
+          reportError5(ParserErrorCode.MULTIPLE_IMPLEMENTS_CLAUSES, implementsClause.keyword, []);
           parseImplementsClause();
         }
       } else {
@@ -1127,19 +1131,19 @@
       }
     }
     if (withClause != null && extendsClause == null) {
-      reportError4(ParserErrorCode.WITH_WITHOUT_EXTENDS, withClause.withKeyword, []);
+      reportError5(ParserErrorCode.WITH_WITHOUT_EXTENDS, withClause.withKeyword, []);
     }
     Token leftBracket = null;
     List<ClassMember> members = null;
     Token rightBracket = null;
     if (matches5(TokenType.OPEN_CURLY_BRACKET)) {
       leftBracket = expect2(TokenType.OPEN_CURLY_BRACKET);
-      members = parseClassMembers(className);
+      members = parseClassMembers(className, ((leftBracket as BeginToken)).endToken != null);
       rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET);
     } else {
       leftBracket = createSyntheticToken(TokenType.OPEN_CURLY_BRACKET);
       rightBracket = createSyntheticToken(TokenType.CLOSE_CURLY_BRACKET);
-      reportError3(ParserErrorCode.MISSING_CLASS_BODY, []);
+      reportError4(ParserErrorCode.MISSING_CLASS_BODY, []);
     }
     return new ClassDeclaration.full(commentAndMetadata.comment, commentAndMetadata.metadata, abstractKeyword, keyword, name, typeParameters, extendsClause, withClause, implementsClause, leftBracket, members, rightBracket);
   }
@@ -1185,7 +1189,7 @@
     } else if (matches(Keyword.SET) && matchesIdentifier2(peek())) {
       validateModifiersForGetterOrSetterOrMethod(modifiers);
       return parseSetter(commentAndMetadata, modifiers.externalKeyword, modifiers.staticKeyword, null);
-    } else if (matches(Keyword.OPERATOR) && peek().isOperator()) {
+    } else if (matches(Keyword.OPERATOR) && peek().isOperator() && matches4(peek2(2), TokenType.OPEN_PAREN)) {
       validateModifiersForOperator(modifiers);
       return parseOperator(commentAndMetadata, modifiers.externalKeyword, null);
     } else if (!matchesIdentifier()) {
@@ -1211,7 +1215,7 @@
     } else if (matches(Keyword.SET) && matchesIdentifier2(peek())) {
       validateModifiersForGetterOrSetterOrMethod(modifiers);
       return parseSetter(commentAndMetadata, modifiers.externalKeyword, modifiers.staticKeyword, type);
-    } else if (matches(Keyword.OPERATOR) && peek().isOperator()) {
+    } else if (matches(Keyword.OPERATOR) && peek().isOperator() && matches4(peek2(2), TokenType.OPEN_PAREN)) {
       validateModifiersForOperator(modifiers);
       return parseOperator(commentAndMetadata, modifiers.externalKeyword, type);
     } else if (!matchesIdentifier()) {
@@ -1227,14 +1231,17 @@
    * classMembers ::=
    * (metadata memberDefinition)
    * </pre>
+   * @param className the name of the class whose members are being parsed
+   * @param balancedBrackets {@code true} if the opening and closing brackets for the class are
+   * balanced
    * @return the list of class members that were parsed
    */
-  List<ClassMember> parseClassMembers(String className) {
+  List<ClassMember> parseClassMembers(String className, bool balancedBrackets) {
     List<ClassMember> members = new List<ClassMember>();
     Token memberStart = _currentToken;
-    while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET) && !matches(Keyword.CLASS) && !matches(Keyword.TYPEDEF)) {
+    while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET) && (balancedBrackets || (!matches(Keyword.CLASS) && !matches(Keyword.TYPEDEF)))) {
       if (matches5(TokenType.SEMICOLON)) {
-        reportError4(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
+        reportError5(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
         advance();
       } else {
         ClassMember member = parseClassMember(className);
@@ -1243,7 +1250,7 @@
         }
       }
       if (identical(_currentToken, memberStart)) {
-        reportError4(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
+        reportError5(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
         advance();
       }
       memberStart = _currentToken;
@@ -1344,7 +1351,7 @@
     }
     try {
       List<bool> errorFound = [false];
-      AnalysisErrorListener listener = new AnalysisErrorListener_4(errorFound);
+      AnalysisErrorListener listener = new AnalysisErrorListener_7(errorFound);
       StringScanner scanner = new StringScanner(null, referenceSource, listener);
       scanner.setSourceStart(1, 1, sourceOffset);
       Token firstToken = scanner.tokenize();
@@ -1432,10 +1439,7 @@
    * @return the compilation unit that was parsed
    */
   CompilationUnit parseCompilationUnit2() {
-    Token firstToken = _currentToken.precedingComments;
-    if (firstToken == null) {
-      firstToken = _currentToken;
-    }
+    Token firstToken = _currentToken;
     ScriptTag scriptTag = null;
     if (matches5(TokenType.SCRIPT_TAG)) {
       scriptTag = new ScriptTag.full(andAdvance);
@@ -1449,18 +1453,18 @@
     Token memberStart = _currentToken;
     while (!matches5(TokenType.EOF)) {
       CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
-      if (matches(Keyword.IMPORT) || matches(Keyword.EXPORT) || matches(Keyword.LIBRARY) || matches(Keyword.PART)) {
+      if ((matches(Keyword.IMPORT) || matches(Keyword.EXPORT) || matches(Keyword.LIBRARY) || matches(Keyword.PART)) && !matches4(peek(), TokenType.PERIOD) && !matches4(peek(), TokenType.LT)) {
         Directive directive = parseDirective(commentAndMetadata);
         if (declarations.length > 0 && !directiveFoundAfterDeclaration) {
-          reportError3(ParserErrorCode.DIRECTIVE_AFTER_DECLARATION, []);
+          reportError4(ParserErrorCode.DIRECTIVE_AFTER_DECLARATION, []);
           directiveFoundAfterDeclaration = true;
         }
         if (directive is LibraryDirective) {
           if (libraryDirectiveFound) {
-            reportError3(ParserErrorCode.MULTIPLE_LIBRARY_DIRECTIVES, []);
+            reportError4(ParserErrorCode.MULTIPLE_LIBRARY_DIRECTIVES, []);
           } else {
             if (directives.length > 0) {
-              reportError3(ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST, []);
+              reportError4(ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST, []);
             }
             libraryDirectiveFound = true;
           }
@@ -1468,28 +1472,28 @@
           partDirectiveFound = true;
         } else if (partDirectiveFound) {
           if (directive is ExportDirective) {
-            reportError3(ParserErrorCode.EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE, []);
+            reportError4(ParserErrorCode.EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE, []);
           } else if (directive is ImportDirective) {
-            reportError3(ParserErrorCode.IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE, []);
+            reportError4(ParserErrorCode.IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE, []);
           }
         }
         if (directive is PartOfDirective) {
           if (partOfDirectiveFound) {
-            reportError3(ParserErrorCode.MULTIPLE_PART_OF_DIRECTIVES, []);
+            reportError4(ParserErrorCode.MULTIPLE_PART_OF_DIRECTIVES, []);
           } else {
             for (Directive preceedingDirective in directives) {
-              reportError4(ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART, preceedingDirective.keyword, []);
+              reportError5(ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART, preceedingDirective.keyword, []);
             }
             partOfDirectiveFound = true;
           }
         } else {
           if (partOfDirectiveFound) {
-            reportError4(ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART, directive.keyword, []);
+            reportError5(ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART, directive.keyword, []);
           }
         }
         directives.add(directive);
       } else if (matches5(TokenType.SEMICOLON)) {
-        reportError4(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
+        reportError5(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
         advance();
       } else {
         CompilationUnitMember member = parseCompilationUnitMember(commentAndMetadata);
@@ -1498,7 +1502,7 @@
         }
       }
       if (identical(_currentToken, memberStart)) {
-        reportError4(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
+        reportError5(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
         advance();
       }
       memberStart = _currentToken;
@@ -1526,7 +1530,7 @@
     Modifiers modifiers = parseModifiers();
     if (matches(Keyword.CLASS)) {
       return parseClassDeclaration(commentAndMetadata, validateModifiersForClass(modifiers));
-    } else if (matches(Keyword.TYPEDEF)) {
+    } else if (matches(Keyword.TYPEDEF) && !matches4(peek(), TokenType.PERIOD) && !matches4(peek(), TokenType.LT)) {
       validateModifiersForTypedef(modifiers);
       return parseTypeAlias(commentAndMetadata);
     }
@@ -1534,12 +1538,12 @@
       TypeName returnType = parseReturnType();
       if ((matches(Keyword.GET) || matches(Keyword.SET)) && matchesIdentifier2(peek())) {
         validateModifiersForTopLevelFunction(modifiers);
-        return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, null, false);
+        return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, null);
       } else if (matches(Keyword.OPERATOR) && peek().isOperator()) {
         return null;
       } else if (matchesIdentifier() && matchesAny(peek(), [TokenType.OPEN_PAREN, TokenType.OPEN_CURLY_BRACKET, TokenType.FUNCTION])) {
         validateModifiersForTopLevelFunction(modifiers);
-        return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, null, false);
+        return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, null);
       } else {
         if (matchesIdentifier()) {
           if (matchesAny(peek(), [TokenType.EQ, TokenType.COMMA, TokenType.SEMICOLON])) {
@@ -1551,27 +1555,27 @@
       }
     } else if ((matches(Keyword.GET) || matches(Keyword.SET)) && matchesIdentifier2(peek())) {
       validateModifiersForTopLevelFunction(modifiers);
-      return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, null, false);
-    } else if (matches(Keyword.OPERATOR) && peek().isOperator()) {
+      return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, null);
+    } else if (matches(Keyword.OPERATOR) && peek().isOperator() && matches4(peek2(2), TokenType.OPEN_PAREN)) {
       return null;
     } else if (!matchesIdentifier()) {
       return null;
     } else if (matches4(peek(), TokenType.OPEN_PAREN)) {
       validateModifiersForTopLevelFunction(modifiers);
-      return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, null, false);
+      return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, null);
     } else if (matchesAny(peek(), [TokenType.EQ, TokenType.COMMA, TokenType.SEMICOLON])) {
       return new TopLevelVariableDeclaration.full(commentAndMetadata.comment, commentAndMetadata.metadata, parseVariableDeclarationList2(validateModifiersForTopLevelVariable(modifiers), null), expect2(TokenType.SEMICOLON));
     }
     TypeName returnType = parseReturnType();
     if (matches(Keyword.GET) || matches(Keyword.SET)) {
       validateModifiersForTopLevelFunction(modifiers);
-      return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, returnType, false);
+      return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, returnType);
     } else if (!matchesIdentifier()) {
       return null;
     }
     if (matchesAny(peek(), [TokenType.OPEN_PAREN, TokenType.FUNCTION, TokenType.OPEN_CURLY_BRACKET])) {
       validateModifiersForTopLevelFunction(modifiers);
-      return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, returnType, false);
+      return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, returnType);
     }
     return new TopLevelVariableDeclaration.full(commentAndMetadata.comment, commentAndMetadata.metadata, parseVariableDeclarationList2(validateModifiersForTopLevelVariable(modifiers), returnType), expect2(TokenType.SEMICOLON));
   }
@@ -1649,7 +1653,7 @@
     } else {
       body = parseFunctionBody(true, false);
       if (!bodyAllowed && body is! EmptyFunctionBody) {
-        reportError3(ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY, []);
+        reportError4(ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY, []);
       }
     }
     return new ConstructorDeclaration.full(commentAndMetadata.comment, commentAndMetadata.metadata, externalKeyword, constKeyword, factoryKeyword, returnType, period, name, parameters, separator, initializers, redirectedConstructor, body);
@@ -1715,14 +1719,14 @@
   Statement parseContinueStatement() {
     Token continueKeyword = expect(Keyword.CONTINUE);
     if (!_inLoop && !_inSwitch) {
-      reportError4(ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, continueKeyword, []);
+      reportError5(ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, continueKeyword, []);
     }
     SimpleIdentifier label = null;
     if (matchesIdentifier()) {
       label = parseSimpleIdentifier();
     }
     if (_inSwitch && !_inLoop && label == null) {
-      reportError4(ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE, continueKeyword, []);
+      reportError5(ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE, continueKeyword, []);
     }
     Token semicolon = expect2(TokenType.SEMICOLON);
     return new ContinueStatement.full(continueKeyword, label, semicolon);
@@ -1968,7 +1972,7 @@
       if (matchesIdentifier2(peek()) || matches4(peek(), TokenType.LT) || matches3(peek(), Keyword.THIS) || (matches4(peek(), TokenType.PERIOD) && matchesIdentifier2(peek2(2)) && (matchesIdentifier2(peek2(3)) || matches4(peek2(3), TokenType.LT) || matches3(peek2(3), Keyword.THIS)))) {
         type = parseReturnType();
       } else if (!optional) {
-        reportError3(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, []);
+        reportError4(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, []);
       }
     }
     return new FinalConstVarOrType(keyword, type);
@@ -1991,7 +1995,7 @@
       Token seperator = andAdvance;
       Expression defaultValue = parseExpression2();
       if (identical(kind, ParameterKind.NAMED)) {
-        reportError4(ParserErrorCode.WRONG_SEPARATOR_FOR_NAMED_PARAMETER, seperator, []);
+        reportError5(ParserErrorCode.WRONG_SEPARATOR_FOR_NAMED_PARAMETER, seperator, []);
       } else if (identical(kind, ParameterKind.REQUIRED)) {
         reportError(ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP, parameter, []);
       }
@@ -2000,7 +2004,7 @@
       Token seperator = andAdvance;
       Expression defaultValue = parseExpression2();
       if (identical(kind, ParameterKind.POSITIONAL)) {
-        reportError4(ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER, seperator, []);
+        reportError5(ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER, seperator, []);
       } else if (identical(kind, ParameterKind.REQUIRED)) {
         reportError(ParserErrorCode.NAMED_PARAMETER_OUTSIDE_GROUP, parameter, []);
       }
@@ -2030,6 +2034,12 @@
    * @return the formal parameters that were parsed
    */
   FormalParameterList parseFormalParameterList() {
+    if (matches5(TokenType.EQ) && matches4(peek(), TokenType.OPEN_PAREN)) {
+      Token previous4 = _currentToken.previous;
+      if ((matches4(previous4, TokenType.EQ_EQ) || matches4(previous4, TokenType.BANG_EQ)) && _currentToken.offset == previous4.offset + 2) {
+        advance();
+      }
+    }
     Token leftParenthesis = expect2(TokenType.OPEN_PAREN);
     if (matches5(TokenType.CLOSE_PAREN)) {
       return new FormalParameterList.full(leftParenthesis, null, null, null, andAdvance);
@@ -2054,7 +2064,7 @@
         firstParameter = false;
       } else if (!optional(TokenType.COMMA)) {
         if (((leftParenthesis as BeginToken)).endToken != null) {
-          reportError3(ParserErrorCode.EXPECTED_TOKEN, [TokenType.COMMA.lexeme]);
+          reportError4(ParserErrorCode.EXPECTED_TOKEN, [TokenType.COMMA.lexeme]);
         } else {
           break;
         }
@@ -2062,11 +2072,11 @@
       initialToken = _currentToken;
       if (matches5(TokenType.OPEN_SQUARE_BRACKET)) {
         if (leftSquareBracket != null && !reportedMuliplePositionalGroups) {
-          reportError3(ParserErrorCode.MULTIPLE_POSITIONAL_PARAMETER_GROUPS, []);
+          reportError4(ParserErrorCode.MULTIPLE_POSITIONAL_PARAMETER_GROUPS, []);
           reportedMuliplePositionalGroups = true;
         }
         if (leftCurlyBracket != null && !reportedMixedGroups) {
-          reportError3(ParserErrorCode.MIXED_PARAMETER_GROUPS, []);
+          reportError4(ParserErrorCode.MIXED_PARAMETER_GROUPS, []);
           reportedMixedGroups = true;
         }
         leftSquareBracket = andAdvance;
@@ -2074,11 +2084,11 @@
         kind = ParameterKind.POSITIONAL;
       } else if (matches5(TokenType.OPEN_CURLY_BRACKET)) {
         if (leftCurlyBracket != null && !reportedMulipleNamedGroups) {
-          reportError3(ParserErrorCode.MULTIPLE_NAMED_PARAMETER_GROUPS, []);
+          reportError4(ParserErrorCode.MULTIPLE_NAMED_PARAMETER_GROUPS, []);
           reportedMulipleNamedGroups = true;
         }
         if (leftSquareBracket != null && !reportedMixedGroups) {
-          reportError3(ParserErrorCode.MIXED_PARAMETER_GROUPS, []);
+          reportError4(ParserErrorCode.MIXED_PARAMETER_GROUPS, []);
           reportedMixedGroups = true;
         }
         leftCurlyBracket = andAdvance;
@@ -2092,20 +2102,36 @@
         rightSquareBracket = andAdvance;
         currentParameters = normalParameters;
         if (leftSquareBracket == null) {
+          if (leftCurlyBracket != null) {
+            reportError4(ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP, ["}"]);
+            rightCurlyBracket = rightSquareBracket;
+            rightSquareBracket = null;
+          } else {
+            reportError4(ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP, ["["]);
+          }
         }
         kind = ParameterKind.REQUIRED;
       } else if (matches5(TokenType.CLOSE_CURLY_BRACKET)) {
         rightCurlyBracket = andAdvance;
         currentParameters = normalParameters;
         if (leftCurlyBracket == null) {
+          if (leftSquareBracket != null) {
+            reportError4(ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP, ["]"]);
+            rightSquareBracket = rightCurlyBracket;
+            rightCurlyBracket = null;
+          } else {
+            reportError4(ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP, ["{"]);
+          }
         }
         kind = ParameterKind.REQUIRED;
       }
     } while (!matches5(TokenType.CLOSE_PAREN) && initialToken != _currentToken);
     Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
     if (leftSquareBracket != null && rightSquareBracket == null) {
+      reportError4(ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP, ["]"]);
     }
     if (leftCurlyBracket != null && rightCurlyBracket == null) {
+      reportError4(ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP, ["}"]);
     }
     if (leftSquareBracket == null) {
       leftSquareBracket = leftCurlyBracket;
@@ -2150,25 +2176,25 @@
           initialization = parseExpression2();
         }
         if (matches(Keyword.IN)) {
-          SimpleFormalParameter loopParameter = null;
+          DeclaredIdentifier loopVariable = null;
           if (variableList == null) {
-            reportError3(ParserErrorCode.MISSING_VARIABLE_IN_FOR_EACH, []);
+            reportError4(ParserErrorCode.MISSING_VARIABLE_IN_FOR_EACH, []);
           } else {
             NodeList<VariableDeclaration> variables3 = variableList.variables;
             if (variables3.length > 1) {
-              reportError3(ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH, [variables3.length.toString()]);
+              reportError4(ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH, [variables3.length.toString()]);
             }
             VariableDeclaration variable = variables3[0];
             if (variable.initializer != null) {
-              reportError3(ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH, []);
+              reportError4(ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH, []);
             }
-            loopParameter = new SimpleFormalParameter.full(null, null, variableList.keyword, variableList.type, variable.name);
+            loopVariable = new DeclaredIdentifier.full(null, null, variableList.keyword, variableList.type, variable.name);
           }
           Token inKeyword = expect(Keyword.IN);
           Expression iterator = parseExpression2();
           Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
           Statement body = parseStatement2();
-          return new ForEachStatement.full(forKeyword, leftParenthesis, loopParameter, inKeyword, iterator, rightParenthesis, body);
+          return new ForEachStatement.full(forKeyword, leftParenthesis, loopVariable, inKeyword, iterator, rightParenthesis, body);
         }
       }
       Token leftSeparator = expect2(TokenType.SEMICOLON);
@@ -2211,7 +2237,7 @@
     try {
       if (matches5(TokenType.SEMICOLON)) {
         if (!mayBeEmpty) {
-          reportError3(ParserErrorCode.MISSING_FUNCTION_BODY, []);
+          reportError4(ParserErrorCode.MISSING_FUNCTION_BODY, []);
         }
         return new EmptyFunctionBody.full(andAdvance);
       } else if (matches5(TokenType.FUNCTION)) {
@@ -2229,7 +2255,7 @@
         parseStringLiteral();
         return new EmptyFunctionBody.full(andAdvance);
       } else {
-        reportError3(ParserErrorCode.MISSING_FUNCTION_BODY, []);
+        reportError4(ParserErrorCode.MISSING_FUNCTION_BODY, []);
         return new EmptyFunctionBody.full(createSyntheticToken(TokenType.SEMICOLON));
       }
     } finally {
@@ -2251,7 +2277,7 @@
    * @param isStatement {@code true} if the function declaration is being parsed as a statement
    * @return the function declaration that was parsed
    */
-  FunctionDeclaration parseFunctionDeclaration(CommentAndMetadata commentAndMetadata, Token externalKeyword, TypeName returnType, bool isStatement) {
+  FunctionDeclaration parseFunctionDeclaration(CommentAndMetadata commentAndMetadata, Token externalKeyword, TypeName returnType) {
     Token keyword = null;
     bool isGetter = false;
     if (matches(Keyword.GET) && !matches4(peek(), TokenType.OPEN_PAREN)) {
@@ -2267,19 +2293,17 @@
         parameters = parseFormalParameterList();
         validateFormalParameterList(parameters);
       } else {
-        reportError3(ParserErrorCode.MISSING_FUNCTION_PARAMETERS, []);
+        reportError4(ParserErrorCode.MISSING_FUNCTION_PARAMETERS, []);
       }
     } else if (matches5(TokenType.OPEN_PAREN)) {
-      reportError3(ParserErrorCode.GETTER_WITH_PARAMETERS, []);
+      reportError4(ParserErrorCode.GETTER_WITH_PARAMETERS, []);
       parseFormalParameterList();
     }
-    FunctionBody body = null;
+    FunctionBody body;
     if (externalKeyword == null) {
       body = parseFunctionBody(false, false);
-    }
-    if (!isStatement && matches5(TokenType.SEMICOLON)) {
-      reportError3(ParserErrorCode.UNEXPECTED_TOKEN, [_currentToken.lexeme]);
-      advance();
+    } else {
+      body = new EmptyFunctionBody.full(expect2(TokenType.SEMICOLON));
     }
     return new FunctionDeclaration.full(commentAndMetadata.comment, commentAndMetadata.metadata, externalKeyword, returnType, keyword, name, new FunctionExpression.full(parameters, body));
   }
@@ -2303,7 +2327,7 @@
    * @param returnType the return type, or {@code null} if there is no return type
    * @return the function declaration statement that was parsed
    */
-  Statement parseFunctionDeclarationStatement2(CommentAndMetadata commentAndMetadata, TypeName returnType) => new FunctionDeclarationStatement.full(parseFunctionDeclaration(commentAndMetadata, null, returnType, true));
+  Statement parseFunctionDeclarationStatement2(CommentAndMetadata commentAndMetadata, TypeName returnType) => new FunctionDeclarationStatement.full(parseFunctionDeclaration(commentAndMetadata, null, returnType));
   /**
    * Parse a function expression.
    * <pre>
@@ -2335,13 +2359,13 @@
     if (hasReturnTypeInTypeAlias()) {
       returnType = parseReturnType();
     }
-    SimpleIdentifier name = parseSimpleIdentifier2(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
+    SimpleIdentifier name = parseSimpleIdentifier();
     TypeParameterList typeParameters = null;
     if (matches5(TokenType.LT)) {
       typeParameters = parseTypeParameterList();
     }
-    if (matches5(TokenType.SEMICOLON)) {
-      reportError3(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS, []);
+    if (matches5(TokenType.SEMICOLON) || matches5(TokenType.EOF)) {
+      reportError4(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS, []);
       FormalParameterList parameters = new FormalParameterList.full(createSyntheticToken(TokenType.OPEN_PAREN), null, null, null, createSyntheticToken(TokenType.CLOSE_PAREN));
       Token semicolon = expect2(TokenType.SEMICOLON);
       return new FunctionTypeAlias.full(commentAndMetadata.comment, commentAndMetadata.metadata, keyword, returnType, name, typeParameters, parameters, semicolon);
@@ -2373,13 +2397,13 @@
     Token propertyKeyword = expect(Keyword.GET);
     SimpleIdentifier name = parseSimpleIdentifier();
     if (matches5(TokenType.OPEN_PAREN) && matches4(peek(), TokenType.CLOSE_PAREN)) {
-      reportError3(ParserErrorCode.GETTER_WITH_PARAMETERS, []);
+      reportError4(ParserErrorCode.GETTER_WITH_PARAMETERS, []);
       advance();
       advance();
     }
     FunctionBody body = parseFunctionBody(true, false);
     if (externalKeyword != null && body is! EmptyFunctionBody) {
-      reportError3(ParserErrorCode.EXTERNAL_GETTER_WITH_BODY, []);
+      reportError4(ParserErrorCode.EXTERNAL_GETTER_WITH_BODY, []);
     }
     return new MethodDeclaration.full(commentAndMetadata.comment, commentAndMetadata.metadata, externalKeyword, staticKeyword, returnType, propertyKeyword, null, name, null, body);
   }
@@ -2548,7 +2572,7 @@
       StringLiteral string = parseStringLiteral();
       reportError(ParserErrorCode.NON_IDENTIFIER_LIBRARY_NAME, string, []);
     } else {
-      reportError4(missingNameError, missingNameToken, []);
+      reportError5(missingNameError, missingNameToken, []);
     }
     List<SimpleIdentifier> components = new List<SimpleIdentifier>();
     components.add(createSyntheticIdentifier());
@@ -2613,7 +2637,7 @@
     } else if (matches5(TokenType.OPEN_SQUARE_BRACKET) || matches5(TokenType.INDEX)) {
       return parseListLiteral(modifier, typeArguments);
     }
-    reportError3(ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL, []);
+    reportError4(ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL, []);
     return new ListLiteral.full(modifier, typeArguments, createSyntheticToken(TokenType.OPEN_SQUARE_BRACKET), null, createSyntheticToken(TokenType.CLOSE_SQUARE_BRACKET));
   }
   /**
@@ -2754,51 +2778,51 @@
     Modifiers modifiers = new Modifiers();
     bool progress = true;
     while (progress) {
-      if (matches(Keyword.ABSTRACT)) {
+      if (matches(Keyword.ABSTRACT) && !matches4(peek(), TokenType.PERIOD) && !matches4(peek(), TokenType.LT)) {
         if (modifiers.abstractKeyword != null) {
-          reportError3(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
+          reportError4(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
           advance();
         } else {
           modifiers.abstractKeyword = andAdvance;
         }
       } else if (matches(Keyword.CONST)) {
         if (modifiers.constKeyword != null) {
-          reportError3(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
+          reportError4(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
           advance();
         } else {
           modifiers.constKeyword = andAdvance;
         }
-      } else if (matches(Keyword.EXTERNAL)) {
+      } else if (matches(Keyword.EXTERNAL) && !matches4(peek(), TokenType.PERIOD) && !matches4(peek(), TokenType.LT)) {
         if (modifiers.externalKeyword != null) {
-          reportError3(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
+          reportError4(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
           advance();
         } else {
           modifiers.externalKeyword = andAdvance;
         }
-      } else if (matches(Keyword.FACTORY)) {
+      } else if (matches(Keyword.FACTORY) && !matches4(peek(), TokenType.PERIOD) && !matches4(peek(), TokenType.LT)) {
         if (modifiers.factoryKeyword != null) {
-          reportError3(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
+          reportError4(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
           advance();
         } else {
           modifiers.factoryKeyword = andAdvance;
         }
       } else if (matches(Keyword.FINAL)) {
         if (modifiers.finalKeyword != null) {
-          reportError3(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
+          reportError4(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
           advance();
         } else {
           modifiers.finalKeyword = andAdvance;
         }
-      } else if (matches(Keyword.STATIC)) {
+      } else if (matches(Keyword.STATIC) && !matches4(peek(), TokenType.PERIOD) && !matches4(peek(), TokenType.LT)) {
         if (modifiers.staticKeyword != null) {
-          reportError3(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
+          reportError4(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
           advance();
         } else {
           modifiers.staticKeyword = andAdvance;
         }
       } else if (matches(Keyword.VAR)) {
         if (modifiers.varKeyword != null) {
-          reportError3(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
+          reportError4(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
           advance();
         } else {
           modifiers.varKeyword = andAdvance;
@@ -2872,32 +2896,32 @@
       }
       return parseBlock();
     } else if (matches5(TokenType.KEYWORD) && !((_currentToken as KeywordToken)).keyword.isPseudoKeyword()) {
-      Keyword keyword28 = ((_currentToken as KeywordToken)).keyword;
-      if (identical(keyword28, Keyword.ASSERT)) {
+      Keyword keyword30 = ((_currentToken as KeywordToken)).keyword;
+      if (identical(keyword30, Keyword.ASSERT)) {
         return parseAssertStatement();
-      } else if (identical(keyword28, Keyword.BREAK)) {
+      } else if (identical(keyword30, Keyword.BREAK)) {
         return parseBreakStatement();
-      } else if (identical(keyword28, Keyword.CONTINUE)) {
+      } else if (identical(keyword30, Keyword.CONTINUE)) {
         return parseContinueStatement();
-      } else if (identical(keyword28, Keyword.DO)) {
+      } else if (identical(keyword30, Keyword.DO)) {
         return parseDoStatement();
-      } else if (identical(keyword28, Keyword.FOR)) {
+      } else if (identical(keyword30, Keyword.FOR)) {
         return parseForStatement();
-      } else if (identical(keyword28, Keyword.IF)) {
+      } else if (identical(keyword30, Keyword.IF)) {
         return parseIfStatement();
-      } else if (identical(keyword28, Keyword.RETURN)) {
+      } else if (identical(keyword30, Keyword.RETURN)) {
         return parseReturnStatement();
-      } else if (identical(keyword28, Keyword.SWITCH)) {
+      } else if (identical(keyword30, Keyword.SWITCH)) {
         return parseSwitchStatement();
-      } else if (identical(keyword28, Keyword.THROW)) {
+      } else if (identical(keyword30, Keyword.THROW)) {
         return new ExpressionStatement.full(parseThrowExpression(), expect2(TokenType.SEMICOLON));
-      } else if (identical(keyword28, Keyword.TRY)) {
+      } else if (identical(keyword30, Keyword.TRY)) {
         return parseTryStatement();
-      } else if (identical(keyword28, Keyword.WHILE)) {
+      } else if (identical(keyword30, Keyword.WHILE)) {
         return parseWhileStatement();
-      } else if (identical(keyword28, Keyword.VAR) || identical(keyword28, Keyword.FINAL)) {
+      } else if (identical(keyword30, Keyword.VAR) || identical(keyword30, Keyword.FINAL)) {
         return parseVariableDeclarationStatement();
-      } else if (identical(keyword28, Keyword.VOID)) {
+      } else if (identical(keyword30, Keyword.VOID)) {
         TypeName returnType = parseReturnType();
         if (matchesIdentifier() && matchesAny(peek(), [TokenType.OPEN_PAREN, TokenType.OPEN_CURLY_BRACKET, TokenType.FUNCTION])) {
           return parseFunctionDeclarationStatement2(commentAndMetadata, returnType);
@@ -2910,7 +2934,7 @@
           }
           return null;
         }
-      } else if (identical(keyword28, Keyword.CONST)) {
+      } else if (identical(keyword30, Keyword.CONST)) {
         if (matchesAny(peek(), [TokenType.LT, TokenType.OPEN_CURLY_BRACKET, TokenType.OPEN_SQUARE_BRACKET, TokenType.INDEX])) {
           return new ExpressionStatement.full(parseExpression2(), expect2(TokenType.SEMICOLON));
         } else if (matches4(peek(), TokenType.IDENTIFIER)) {
@@ -2922,7 +2946,7 @@
           }
         }
         return parseVariableDeclarationStatement();
-      } else if (identical(keyword28, Keyword.NEW) || identical(keyword28, Keyword.TRUE) || identical(keyword28, Keyword.FALSE) || identical(keyword28, Keyword.NULL) || identical(keyword28, Keyword.SUPER) || identical(keyword28, Keyword.THIS)) {
+      } else if (identical(keyword30, Keyword.NEW) || identical(keyword30, Keyword.TRUE) || identical(keyword30, Keyword.FALSE) || identical(keyword30, Keyword.NULL) || identical(keyword30, Keyword.SUPER) || identical(keyword30, Keyword.THIS)) {
         return new ExpressionStatement.full(parseExpression2(), expect2(TokenType.SEMICOLON));
       } else {
         return null;
@@ -2933,6 +2957,9 @@
       return parseVariableDeclarationStatement();
     } else if (isFunctionDeclaration()) {
       return parseFunctionDeclarationStatement();
+    } else if (matches5(TokenType.CLOSE_CURLY_BRACKET)) {
+      reportError4(ParserErrorCode.MISSING_STATEMENT, []);
+      return new EmptyStatement.full(createSyntheticToken(TokenType.SEMICOLON));
     } else {
       return new ExpressionStatement.full(parseExpression2(), expect2(TokenType.SEMICOLON));
     }
@@ -2970,9 +2997,9 @@
       FormalParameterList parameters = parseFormalParameterList();
       return new FunctionTypedFormalParameter.full(commentAndMetadata.comment, commentAndMetadata.metadata, holder.type, identifier, parameters);
     }
-    TypeName type16 = holder.type;
-    if (type16 != null && matches3(type16.name.beginToken, Keyword.VOID)) {
-      reportError4(ParserErrorCode.VOID_PARAMETER, type16.name.beginToken, []);
+    TypeName type22 = holder.type;
+    if (type22 != null && matches3(type22.name.beginToken, Keyword.VOID)) {
+      reportError5(ParserErrorCode.VOID_PARAMETER, type22.name.beginToken, []);
     }
     if (thisKeyword != null) {
       return new FieldFormalParameter.full(commentAndMetadata.comment, commentAndMetadata.metadata, holder.keyword, holder.type, thisKeyword, period, identifier);
@@ -2997,14 +3024,14 @@
   MethodDeclaration parseOperator(CommentAndMetadata commentAndMetadata, Token externalKeyword, TypeName returnType) {
     Token operatorKeyword = expect(Keyword.OPERATOR);
     if (!_currentToken.isUserDefinableOperator()) {
-      reportError3(ParserErrorCode.NON_USER_DEFINABLE_OPERATOR, [_currentToken.lexeme]);
+      reportError4(ParserErrorCode.NON_USER_DEFINABLE_OPERATOR, [_currentToken.lexeme]);
     }
     SimpleIdentifier name = new SimpleIdentifier.full(andAdvance);
     FormalParameterList parameters = parseFormalParameterList();
     validateFormalParameterList(parameters);
     FunctionBody body = parseFunctionBody(true, false);
     if (externalKeyword != null && body is! EmptyFunctionBody) {
-      reportError3(ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY, []);
+      reportError4(ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY, []);
     }
     return new MethodDeclaration.full(commentAndMetadata.comment, commentAndMetadata.metadata, externalKeyword, null, returnType, null, operatorKeyword, name, parameters, body);
   }
@@ -3064,7 +3091,7 @@
         if (matches5(TokenType.OPEN_PAREN)) {
           ArgumentList argumentList = parseArgumentList();
           if (operand is PropertyAccess) {
-            PropertyAccess access = (operand as PropertyAccess);
+            PropertyAccess access = operand as PropertyAccess;
             operand = new MethodInvocation.full(access.target, access.operator, access.propertyName, argumentList);
           } else {
             operand = new FunctionExpressionInvocation.full(operand, argumentList);
@@ -3079,7 +3106,7 @@
       return operand;
     }
     if (operand is FunctionExpressionInvocation) {
-      reportError3(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, []);
+      reportError4(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, []);
     }
     Token operator = andAdvance;
     return new PostfixExpression.full(operand, operator);
@@ -3184,7 +3211,7 @@
     } else if (matches5(TokenType.QUESTION)) {
       return parseArgumentDefinitionTest();
     } else if (matches(Keyword.VOID)) {
-      reportError3(ParserErrorCode.UNEXPECTED_TOKEN, [_currentToken.lexeme]);
+      reportError4(ParserErrorCode.UNEXPECTED_TOKEN, [_currentToken.lexeme]);
       advance();
       return parsePrimaryExpression();
     } else {
@@ -3214,7 +3241,7 @@
    * Parse a relational expression.
    * <pre>
    * relationalExpression ::=
-   * shiftExpression ('is' type | 'as' type | relationalOperator shiftExpression)?
+   * shiftExpression ('is' '!'? type | 'as' type | relationalOperator shiftExpression)?
    * | 'super' relationalOperator shiftExpression
    * </pre>
    * @return the relational expression that was parsed
@@ -3228,8 +3255,8 @@
     }
     Expression expression = parseShiftExpression();
     if (matches(Keyword.AS)) {
-      Token isOperator = andAdvance;
-      expression = new AsExpression.full(expression, isOperator, parseTypeName());
+      Token asOperator = andAdvance;
+      expression = new AsExpression.full(expression, asOperator, parseTypeName());
     } else if (matches(Keyword.IS)) {
       Token isOperator = andAdvance;
       Token notOperator = null;
@@ -3299,7 +3326,7 @@
     validateFormalParameterList(parameters);
     FunctionBody body = parseFunctionBody(true, false);
     if (externalKeyword != null && body is! EmptyFunctionBody) {
-      reportError3(ParserErrorCode.EXTERNAL_SETTER_WITH_BODY, []);
+      reportError4(ParserErrorCode.EXTERNAL_SETTER_WITH_BODY, []);
     }
     return new MethodDeclaration.full(commentAndMetadata.comment, commentAndMetadata.metadata, externalKeyword, staticKeyword, returnType, propertyKeyword, null, name, parameters, body);
   }
@@ -3337,27 +3364,7 @@
     if (matchesIdentifier()) {
       return new SimpleIdentifier.full(andAdvance);
     }
-    reportError3(ParserErrorCode.MISSING_IDENTIFIER, []);
-    return createSyntheticIdentifier();
-  }
-  /**
-   * Parse a simple identifier and validate that it is not a built-in identifier.
-   * <pre>
-   * identifier ::=
-   * IDENTIFIER
-   * </pre>
-   * @param errorCode the error code to be used to report a built-in identifier if one is found
-   * @return the simple identifier that was parsed
-   */
-  SimpleIdentifier parseSimpleIdentifier2(ParserErrorCode errorCode) {
-    if (matchesIdentifier()) {
-      Token token = andAdvance;
-      if (identical(token.type, TokenType.KEYWORD)) {
-        reportError4(errorCode, token, [token.lexeme]);
-      }
-      return new SimpleIdentifier.full(token);
-    }
-    reportError3(ParserErrorCode.MISSING_IDENTIFIER, []);
+    reportError4(ParserErrorCode.MISSING_IDENTIFIER, []);
     return createSyntheticIdentifier();
   }
   /**
@@ -3395,7 +3402,7 @@
     while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET) && !isSwitchMember()) {
       statements.add(parseStatement2());
       if (identical(_currentToken, statementStart)) {
-        reportError4(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
+        reportError5(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
         advance();
       }
       statementStart = _currentToken;
@@ -3452,7 +3459,7 @@
       }
     }
     if (strings.length < 1) {
-      reportError3(ParserErrorCode.EXPECTED_STRING_LITERAL, []);
+      reportError4(ParserErrorCode.EXPECTED_STRING_LITERAL, []);
       return createSyntheticStringLiteral();
     } else if (strings.length == 1) {
       return strings[0];
@@ -3508,7 +3515,7 @@
           SimpleIdentifier identifier = parseSimpleIdentifier();
           String label = identifier.token.lexeme;
           if (definedLabels.contains(label)) {
-            reportError4(ParserErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT, identifier.token, [label]);
+            reportError5(ParserErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT, identifier.token, [label]);
           } else {
             javaSetAdd(definedLabels, label);
           }
@@ -3525,7 +3532,7 @@
           Token colon = expect2(TokenType.COLON);
           members.add(new SwitchDefault.full(labels, defaultKeyword, colon, parseStatements2()));
         } else {
-          reportError3(ParserErrorCode.EXPECTED_CASE_OR_DEFAULT, []);
+          reportError4(ParserErrorCode.EXPECTED_CASE_OR_DEFAULT, []);
           while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET) && !matches(Keyword.CASE) && !matches(Keyword.DEFAULT)) {
             advance();
           }
@@ -3621,7 +3628,7 @@
       finallyClause = parseBlock();
     } else {
       if (catchClauses.isEmpty) {
-        reportError3(ParserErrorCode.MISSING_CATCH_OR_FINALLY, []);
+        reportError4(ParserErrorCode.MISSING_CATCH_OR_FINALLY, []);
       }
     }
     return new TryStatement.full(tryKeyword, body, catchClauses, finallyKeyword, finallyClause);
@@ -3707,7 +3714,7 @@
    */
   TypeParameter parseTypeParameter() {
     CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
-    SimpleIdentifier name = parseSimpleIdentifier2(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME);
+    SimpleIdentifier name = parseSimpleIdentifier();
     if (matches(Keyword.EXTENDS)) {
       Token keyword = andAdvance;
       TypeName bound = parseTypeName();
@@ -3759,21 +3766,21 @@
       Token operator = andAdvance;
       if (matches(Keyword.SUPER)) {
         if (identical(operator.type, TokenType.MINUS_MINUS)) {
-          int offset8 = operator.offset;
-          Token firstOperator = new Token(TokenType.MINUS, offset8);
-          Token secondOperator = new Token(TokenType.MINUS, offset8 + 1);
+          int offset9 = operator.offset;
+          Token firstOperator = new Token(TokenType.MINUS, offset9);
+          Token secondOperator = new Token(TokenType.MINUS, offset9 + 1);
           secondOperator.setNext(_currentToken);
           firstOperator.setNext(secondOperator);
           operator.previous.setNext(firstOperator);
           return new PrefixExpression.full(firstOperator, new PrefixExpression.full(secondOperator, new SuperExpression.full(andAdvance)));
         } else {
-          reportError3(ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, [operator.lexeme]);
+          reportError4(ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, [operator.lexeme]);
           return new PrefixExpression.full(operator, new SuperExpression.full(andAdvance));
         }
       }
       return new PrefixExpression.full(operator, parseAssignableExpression(false));
     } else if (matches5(TokenType.PLUS)) {
-      reportError3(ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR, []);
+      reportError4(ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR, []);
     }
     return parsePostfixExpression();
   }
@@ -3872,13 +3879,13 @@
    * @return the with clause that was parsed
    */
   WithClause parseWithClause() {
-    Token with6 = expect(Keyword.WITH);
+    Token with2 = expect(Keyword.WITH);
     List<TypeName> types = new List<TypeName>();
     types.add(parseTypeName());
     while (optional(TokenType.COMMA)) {
       types.add(parseTypeName());
     }
-    return new WithClause.full(with6, types);
+    return new WithClause.full(with2, types);
   }
   /**
    * Return the token that is immediately after the current token. This is equivalent to{@link #peek(int) peek(1)}.
@@ -3911,8 +3918,8 @@
    * @param errorCode the error code of the error to be reported
    * @param arguments the arguments to the error, used to compose the error message
    */
-  void reportError3(ParserErrorCode errorCode, List<Object> arguments) {
-    reportError4(errorCode, _currentToken, arguments);
+  void reportError4(ParserErrorCode errorCode, List<Object> arguments) {
+    reportError5(errorCode, _currentToken, arguments);
   }
   /**
    * Report an error with the given error code and arguments.
@@ -3920,7 +3927,7 @@
    * @param token the token specifying the location of the error
    * @param arguments the arguments to the error, used to compose the error message
    */
-  void reportError4(ParserErrorCode errorCode, Token token, List<Object> arguments) {
+  void reportError5(ParserErrorCode errorCode, Token token, List<Object> arguments) {
     _errorListener.onError(new AnalysisError.con2(_source, token.offset, token.length, errorCode, [arguments]));
   }
   /**
@@ -4102,20 +4109,20 @@
    */
   Token skipStringInterpolation(Token startToken) {
     Token token = startToken;
-    TokenType type17 = token.type;
-    while (identical(type17, TokenType.STRING_INTERPOLATION_EXPRESSION) || identical(type17, TokenType.STRING_INTERPOLATION_IDENTIFIER)) {
-      if (identical(type17, TokenType.STRING_INTERPOLATION_EXPRESSION)) {
+    TokenType type23 = token.type;
+    while (identical(type23, TokenType.STRING_INTERPOLATION_EXPRESSION) || identical(type23, TokenType.STRING_INTERPOLATION_IDENTIFIER)) {
+      if (identical(type23, TokenType.STRING_INTERPOLATION_EXPRESSION)) {
         token = token.next;
-        type17 = token.type;
+        type23 = token.type;
         int bracketNestingLevel = 1;
         while (bracketNestingLevel > 0) {
-          if (identical(type17, TokenType.EOF)) {
+          if (identical(type23, TokenType.EOF)) {
             return null;
-          } else if (identical(type17, TokenType.OPEN_CURLY_BRACKET)) {
+          } else if (identical(type23, TokenType.OPEN_CURLY_BRACKET)) {
             bracketNestingLevel++;
-          } else if (identical(type17, TokenType.CLOSE_CURLY_BRACKET)) {
+          } else if (identical(type23, TokenType.CLOSE_CURLY_BRACKET)) {
             bracketNestingLevel--;
-          } else if (identical(type17, TokenType.STRING)) {
+          } else if (identical(type23, TokenType.STRING)) {
             token = skipStringLiteral(token);
             if (token == null) {
               return null;
@@ -4123,10 +4130,10 @@
           } else {
             token = token.next;
           }
-          type17 = token.type;
+          type23 = token.type;
         }
         token = token.next;
-        type17 = token.type;
+        type23 = token.type;
       } else {
         token = token.next;
         if (token.type != TokenType.IDENTIFIER) {
@@ -4134,10 +4141,10 @@
         }
         token = token.next;
       }
-      type17 = token.type;
-      if (identical(type17, TokenType.STRING)) {
+      type23 = token.type;
+      if (identical(type23, TokenType.STRING)) {
         token = token.next;
-        type17 = token.type;
+        type23 = token.type;
       }
     }
     return token;
@@ -4160,8 +4167,8 @@
     Token token = startToken;
     while (token != null && matches4(token, TokenType.STRING)) {
       token = token.next;
-      TokenType type18 = token.type;
-      if (identical(type18, TokenType.STRING_INTERPOLATION_EXPRESSION) || identical(type18, TokenType.STRING_INTERPOLATION_IDENTIFIER)) {
+      TokenType type24 = token.type;
+      if (identical(type24, TokenType.STRING_INTERPOLATION_EXPRESSION) || identical(type24, TokenType.STRING_INTERPOLATION_IDENTIFIER)) {
         token = skipStringInterpolation(token);
       }
     }
@@ -4289,10 +4296,10 @@
    * @param index the index of the character to be translated
    * @return the index of the next character to be translated
    */
-  int translateCharacter(StringBuffer builder, String lexeme, int index) {
+  int translateCharacter(JavaStringBuilder builder, String lexeme, int index) {
     int currentChar = lexeme.codeUnitAt(index);
     if (currentChar != 0x5C) {
-      builder.addCharCode(currentChar);
+      builder.appendChar(currentChar);
       return index + 1;
     }
     int length8 = lexeme.length;
@@ -4302,41 +4309,41 @@
     }
     currentChar = lexeme.codeUnitAt(currentIndex);
     if (currentChar == 0x6E) {
-      builder.addCharCode(0xA);
+      builder.appendChar(0xA);
     } else if (currentChar == 0x72) {
-      builder.addCharCode(0xD);
+      builder.appendChar(0xD);
     } else if (currentChar == 0x66) {
-      builder.addCharCode(0xC);
+      builder.appendChar(0xC);
     } else if (currentChar == 0x62) {
-      builder.addCharCode(0x8);
+      builder.appendChar(0x8);
     } else if (currentChar == 0x74) {
-      builder.addCharCode(0x9);
+      builder.appendChar(0x9);
     } else if (currentChar == 0x76) {
-      builder.addCharCode(0xB);
+      builder.appendChar(0xB);
     } else if (currentChar == 0x78) {
       if (currentIndex + 2 >= length8) {
-        reportError3(ParserErrorCode.INVALID_HEX_ESCAPE, []);
+        reportError4(ParserErrorCode.INVALID_HEX_ESCAPE, []);
         return length8;
       }
       int firstDigit = lexeme.codeUnitAt(currentIndex + 1);
       int secondDigit = lexeme.codeUnitAt(currentIndex + 2);
       if (!isHexDigit(firstDigit) || !isHexDigit(secondDigit)) {
-        reportError3(ParserErrorCode.INVALID_HEX_ESCAPE, []);
+        reportError4(ParserErrorCode.INVALID_HEX_ESCAPE, []);
       } else {
-        builder.addCharCode((((Character.digit(firstDigit, 16) << 4) + Character.digit(secondDigit, 16)) as int));
+        builder.appendChar((((Character.digit(firstDigit, 16) << 4) + Character.digit(secondDigit, 16)) as int));
       }
       return currentIndex + 3;
     } else if (currentChar == 0x75) {
       currentIndex++;
       if (currentIndex >= length8) {
-        reportError3(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
+        reportError4(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
         return length8;
       }
       currentChar = lexeme.codeUnitAt(currentIndex);
       if (currentChar == 0x7B) {
         currentIndex++;
         if (currentIndex >= length8) {
-          reportError3(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
+          reportError4(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
           return length8;
         }
         currentChar = lexeme.codeUnitAt(currentIndex);
@@ -4344,7 +4351,7 @@
         int value = 0;
         while (currentChar != 0x7D) {
           if (!isHexDigit(currentChar)) {
-            reportError3(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
+            reportError4(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
             currentIndex++;
             while (currentIndex < length8 && lexeme.codeUnitAt(currentIndex) != 0x7D) {
               currentIndex++;
@@ -4355,19 +4362,19 @@
           value = (value << 4) + Character.digit(currentChar, 16);
           currentIndex++;
           if (currentIndex >= length8) {
-            reportError3(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
+            reportError4(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
             return length8;
           }
           currentChar = lexeme.codeUnitAt(currentIndex);
         }
         if (digitCount < 1 || digitCount > 6) {
-          reportError3(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
+          reportError4(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
         }
         appendScalarValue(builder, lexeme.substring(index, currentIndex + 1), value, index, currentIndex);
         return currentIndex + 1;
       } else {
         if (currentIndex + 3 >= length8) {
-          reportError3(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
+          reportError4(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
           return length8;
         }
         int firstDigit = currentChar;
@@ -4375,14 +4382,14 @@
         int thirdDigit = lexeme.codeUnitAt(currentIndex + 2);
         int fourthDigit = lexeme.codeUnitAt(currentIndex + 3);
         if (!isHexDigit(firstDigit) || !isHexDigit(secondDigit) || !isHexDigit(thirdDigit) || !isHexDigit(fourthDigit)) {
-          reportError3(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
+          reportError4(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
         } else {
           appendScalarValue(builder, lexeme.substring(index, currentIndex + 1), ((((((Character.digit(firstDigit, 16) << 4) + Character.digit(secondDigit, 16)) << 4) + Character.digit(thirdDigit, 16)) << 4) + Character.digit(fourthDigit, 16)), index, currentIndex + 3);
         }
         return currentIndex + 4;
       }
     } else {
-      builder.addCharCode(currentChar);
+      builder.appendChar(currentChar);
     }
     return currentIndex + 1;
   }
@@ -4405,16 +4412,16 @@
   Token validateModifiersForClass(Modifiers modifiers) {
     validateModifiersForTopLevelDeclaration(modifiers);
     if (modifiers.constKeyword != null) {
-      reportError4(ParserErrorCode.CONST_CLASS, modifiers.constKeyword, []);
+      reportError5(ParserErrorCode.CONST_CLASS, modifiers.constKeyword, []);
     }
     if (modifiers.externalKeyword != null) {
-      reportError4(ParserErrorCode.EXTERNAL_CLASS, modifiers.externalKeyword, []);
+      reportError5(ParserErrorCode.EXTERNAL_CLASS, modifiers.externalKeyword, []);
     }
     if (modifiers.finalKeyword != null) {
-      reportError4(ParserErrorCode.FINAL_CLASS, modifiers.finalKeyword, []);
+      reportError5(ParserErrorCode.FINAL_CLASS, modifiers.finalKeyword, []);
     }
     if (modifiers.varKeyword != null) {
-      reportError4(ParserErrorCode.VAR_CLASS, modifiers.varKeyword, []);
+      reportError5(ParserErrorCode.VAR_CLASS, modifiers.varKeyword, []);
     }
     return modifiers.abstractKeyword;
   }
@@ -4426,25 +4433,25 @@
    */
   Token validateModifiersForConstructor(Modifiers modifiers) {
     if (modifiers.abstractKeyword != null) {
-      reportError3(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
+      reportError4(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
     }
     if (modifiers.finalKeyword != null) {
-      reportError4(ParserErrorCode.FINAL_CONSTRUCTOR, modifiers.finalKeyword, []);
+      reportError5(ParserErrorCode.FINAL_CONSTRUCTOR, modifiers.finalKeyword, []);
     }
     if (modifiers.staticKeyword != null) {
-      reportError4(ParserErrorCode.STATIC_CONSTRUCTOR, modifiers.staticKeyword, []);
+      reportError5(ParserErrorCode.STATIC_CONSTRUCTOR, modifiers.staticKeyword, []);
     }
     if (modifiers.varKeyword != null) {
-      reportError4(ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE, modifiers.varKeyword, []);
+      reportError5(ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE, modifiers.varKeyword, []);
     }
     Token externalKeyword6 = modifiers.externalKeyword;
     Token constKeyword4 = modifiers.constKeyword;
     Token factoryKeyword4 = modifiers.factoryKeyword;
     if (externalKeyword6 != null && constKeyword4 != null && constKeyword4.offset < externalKeyword6.offset) {
-      reportError4(ParserErrorCode.EXTERNAL_AFTER_CONST, externalKeyword6, []);
+      reportError5(ParserErrorCode.EXTERNAL_AFTER_CONST, externalKeyword6, []);
     }
     if (externalKeyword6 != null && factoryKeyword4 != null && factoryKeyword4.offset < externalKeyword6.offset) {
-      reportError4(ParserErrorCode.EXTERNAL_AFTER_FACTORY, externalKeyword6, []);
+      reportError5(ParserErrorCode.EXTERNAL_AFTER_FACTORY, externalKeyword6, []);
     }
     return constKeyword4;
   }
@@ -4456,13 +4463,13 @@
    */
   Token validateModifiersForField(Modifiers modifiers) {
     if (modifiers.abstractKeyword != null) {
-      reportError3(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
+      reportError4(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
     }
     if (modifiers.externalKeyword != null) {
-      reportError4(ParserErrorCode.EXTERNAL_FIELD, modifiers.externalKeyword, []);
+      reportError5(ParserErrorCode.EXTERNAL_FIELD, modifiers.externalKeyword, []);
     }
     if (modifiers.factoryKeyword != null) {
-      reportError4(ParserErrorCode.NON_CONSTRUCTOR_FACTORY, modifiers.factoryKeyword, []);
+      reportError5(ParserErrorCode.NON_CONSTRUCTOR_FACTORY, modifiers.factoryKeyword, []);
     }
     Token staticKeyword3 = modifiers.staticKeyword;
     Token constKeyword5 = modifiers.constKeyword;
@@ -4470,23 +4477,23 @@
     Token varKeyword3 = modifiers.varKeyword;
     if (constKeyword5 != null) {
       if (finalKeyword3 != null) {
-        reportError4(ParserErrorCode.CONST_AND_FINAL, finalKeyword3, []);
+        reportError5(ParserErrorCode.CONST_AND_FINAL, finalKeyword3, []);
       }
       if (varKeyword3 != null) {
-        reportError4(ParserErrorCode.CONST_AND_VAR, varKeyword3, []);
+        reportError5(ParserErrorCode.CONST_AND_VAR, varKeyword3, []);
       }
       if (staticKeyword3 != null && constKeyword5.offset < staticKeyword3.offset) {
-        reportError4(ParserErrorCode.STATIC_AFTER_CONST, staticKeyword3, []);
+        reportError5(ParserErrorCode.STATIC_AFTER_CONST, staticKeyword3, []);
       }
     } else if (finalKeyword3 != null) {
       if (varKeyword3 != null) {
-        reportError4(ParserErrorCode.FINAL_AND_VAR, varKeyword3, []);
+        reportError5(ParserErrorCode.FINAL_AND_VAR, varKeyword3, []);
       }
       if (staticKeyword3 != null && finalKeyword3.offset < staticKeyword3.offset) {
-        reportError4(ParserErrorCode.STATIC_AFTER_FINAL, staticKeyword3, []);
+        reportError5(ParserErrorCode.STATIC_AFTER_FINAL, staticKeyword3, []);
       }
     } else if (varKeyword3 != null && staticKeyword3 != null && varKeyword3.offset < staticKeyword3.offset) {
-      reportError4(ParserErrorCode.STATIC_AFTER_VAR, staticKeyword3, []);
+      reportError5(ParserErrorCode.STATIC_AFTER_VAR, staticKeyword3, []);
     }
     return lexicallyFirst([constKeyword5, finalKeyword3, varKeyword3]);
   }
@@ -4496,24 +4503,24 @@
    */
   void validateModifiersForGetterOrSetterOrMethod(Modifiers modifiers) {
     if (modifiers.abstractKeyword != null) {
-      reportError3(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
+      reportError4(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
     }
     if (modifiers.constKeyword != null) {
-      reportError4(ParserErrorCode.CONST_METHOD, modifiers.constKeyword, []);
+      reportError5(ParserErrorCode.CONST_METHOD, modifiers.constKeyword, []);
     }
     if (modifiers.factoryKeyword != null) {
-      reportError4(ParserErrorCode.NON_CONSTRUCTOR_FACTORY, modifiers.factoryKeyword, []);
+      reportError5(ParserErrorCode.NON_CONSTRUCTOR_FACTORY, modifiers.factoryKeyword, []);
     }
     if (modifiers.finalKeyword != null) {
-      reportError4(ParserErrorCode.FINAL_METHOD, modifiers.finalKeyword, []);
+      reportError5(ParserErrorCode.FINAL_METHOD, modifiers.finalKeyword, []);
     }
     if (modifiers.varKeyword != null) {
-      reportError4(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []);
+      reportError5(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []);
     }
     Token externalKeyword7 = modifiers.externalKeyword;
     Token staticKeyword4 = modifiers.staticKeyword;
     if (externalKeyword7 != null && staticKeyword4 != null && staticKeyword4.offset < externalKeyword7.offset) {
-      reportError4(ParserErrorCode.EXTERNAL_AFTER_STATIC, externalKeyword7, []);
+      reportError5(ParserErrorCode.EXTERNAL_AFTER_STATIC, externalKeyword7, []);
     }
   }
   /**
@@ -4522,22 +4529,22 @@
    */
   void validateModifiersForOperator(Modifiers modifiers) {
     if (modifiers.abstractKeyword != null) {
-      reportError3(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
+      reportError4(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
     }
     if (modifiers.constKeyword != null) {
-      reportError4(ParserErrorCode.CONST_METHOD, modifiers.constKeyword, []);
+      reportError5(ParserErrorCode.CONST_METHOD, modifiers.constKeyword, []);
     }
     if (modifiers.factoryKeyword != null) {
-      reportError4(ParserErrorCode.NON_CONSTRUCTOR_FACTORY, modifiers.factoryKeyword, []);
+      reportError5(ParserErrorCode.NON_CONSTRUCTOR_FACTORY, modifiers.factoryKeyword, []);
     }
     if (modifiers.finalKeyword != null) {
-      reportError4(ParserErrorCode.FINAL_METHOD, modifiers.finalKeyword, []);
+      reportError5(ParserErrorCode.FINAL_METHOD, modifiers.finalKeyword, []);
     }
     if (modifiers.staticKeyword != null) {
-      reportError4(ParserErrorCode.STATIC_OPERATOR, modifiers.staticKeyword, []);
+      reportError5(ParserErrorCode.STATIC_OPERATOR, modifiers.staticKeyword, []);
     }
     if (modifiers.varKeyword != null) {
-      reportError4(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []);
+      reportError5(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []);
     }
   }
   /**
@@ -4546,10 +4553,10 @@
    */
   void validateModifiersForTopLevelDeclaration(Modifiers modifiers) {
     if (modifiers.factoryKeyword != null) {
-      reportError4(ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION, modifiers.factoryKeyword, []);
+      reportError5(ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION, modifiers.factoryKeyword, []);
     }
     if (modifiers.staticKeyword != null) {
-      reportError4(ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION, modifiers.staticKeyword, []);
+      reportError5(ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION, modifiers.staticKeyword, []);
     }
   }
   /**
@@ -4559,16 +4566,16 @@
   void validateModifiersForTopLevelFunction(Modifiers modifiers) {
     validateModifiersForTopLevelDeclaration(modifiers);
     if (modifiers.abstractKeyword != null) {
-      reportError3(ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION, []);
+      reportError4(ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION, []);
     }
     if (modifiers.constKeyword != null) {
-      reportError4(ParserErrorCode.CONST_CLASS, modifiers.constKeyword, []);
+      reportError5(ParserErrorCode.CONST_CLASS, modifiers.constKeyword, []);
     }
     if (modifiers.finalKeyword != null) {
-      reportError4(ParserErrorCode.FINAL_CLASS, modifiers.finalKeyword, []);
+      reportError5(ParserErrorCode.FINAL_CLASS, modifiers.finalKeyword, []);
     }
     if (modifiers.varKeyword != null) {
-      reportError4(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []);
+      reportError5(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []);
     }
   }
   /**
@@ -4580,24 +4587,24 @@
   Token validateModifiersForTopLevelVariable(Modifiers modifiers) {
     validateModifiersForTopLevelDeclaration(modifiers);
     if (modifiers.abstractKeyword != null) {
-      reportError3(ParserErrorCode.ABSTRACT_TOP_LEVEL_VARIABLE, []);
+      reportError4(ParserErrorCode.ABSTRACT_TOP_LEVEL_VARIABLE, []);
     }
     if (modifiers.externalKeyword != null) {
-      reportError4(ParserErrorCode.EXTERNAL_FIELD, modifiers.externalKeyword, []);
+      reportError5(ParserErrorCode.EXTERNAL_FIELD, modifiers.externalKeyword, []);
     }
     Token constKeyword6 = modifiers.constKeyword;
     Token finalKeyword4 = modifiers.finalKeyword;
     Token varKeyword4 = modifiers.varKeyword;
     if (constKeyword6 != null) {
       if (finalKeyword4 != null) {
-        reportError4(ParserErrorCode.CONST_AND_FINAL, finalKeyword4, []);
+        reportError5(ParserErrorCode.CONST_AND_FINAL, finalKeyword4, []);
       }
       if (varKeyword4 != null) {
-        reportError4(ParserErrorCode.CONST_AND_VAR, varKeyword4, []);
+        reportError5(ParserErrorCode.CONST_AND_VAR, varKeyword4, []);
       }
     } else if (finalKeyword4 != null) {
       if (varKeyword4 != null) {
-        reportError4(ParserErrorCode.FINAL_AND_VAR, varKeyword4, []);
+        reportError5(ParserErrorCode.FINAL_AND_VAR, varKeyword4, []);
       }
     }
     return lexicallyFirst([constKeyword6, finalKeyword4, varKeyword4]);
@@ -4610,25 +4617,25 @@
   void validateModifiersForTypedef(Modifiers modifiers) {
     validateModifiersForTopLevelDeclaration(modifiers);
     if (modifiers.abstractKeyword != null) {
-      reportError4(ParserErrorCode.ABSTRACT_TYPEDEF, modifiers.abstractKeyword, []);
+      reportError5(ParserErrorCode.ABSTRACT_TYPEDEF, modifiers.abstractKeyword, []);
     }
     if (modifiers.constKeyword != null) {
-      reportError4(ParserErrorCode.CONST_TYPEDEF, modifiers.constKeyword, []);
+      reportError5(ParserErrorCode.CONST_TYPEDEF, modifiers.constKeyword, []);
     }
     if (modifiers.externalKeyword != null) {
-      reportError4(ParserErrorCode.EXTERNAL_TYPEDEF, modifiers.externalKeyword, []);
+      reportError5(ParserErrorCode.EXTERNAL_TYPEDEF, modifiers.externalKeyword, []);
     }
     if (modifiers.finalKeyword != null) {
-      reportError4(ParserErrorCode.FINAL_TYPEDEF, modifiers.finalKeyword, []);
+      reportError5(ParserErrorCode.FINAL_TYPEDEF, modifiers.finalKeyword, []);
     }
     if (modifiers.varKeyword != null) {
-      reportError4(ParserErrorCode.VAR_TYPEDEF, modifiers.varKeyword, []);
+      reportError5(ParserErrorCode.VAR_TYPEDEF, modifiers.varKeyword, []);
     }
   }
 }
-class AnalysisErrorListener_4 implements AnalysisErrorListener {
+class AnalysisErrorListener_7 implements AnalysisErrorListener {
   List<bool> errorFound;
-  AnalysisErrorListener_4(this.errorFound);
+  AnalysisErrorListener_7(this.errorFound);
   void onError(AnalysisError error) {
     errorFound[0] = true;
   }
@@ -4638,6 +4645,7 @@
  * parser. The convention for this class is for the name of the error code to indicate the problem
  * that caused the error to be generated and for the error message to explain what is wrong and,
  * when appropriate, how the problem can be corrected.
+ * @coverage dart.engine.parser
  */
 class ParserErrorCode implements ErrorCode {
   static final ParserErrorCode ABSTRACT_CLASS_MEMBER = new ParserErrorCode.con2('ABSTRACT_CLASS_MEMBER', 0, "Members of classes cannot be declared to be 'abstract'");
@@ -4646,102 +4654,104 @@
   static final ParserErrorCode ABSTRACT_TOP_LEVEL_VARIABLE = new ParserErrorCode.con2('ABSTRACT_TOP_LEVEL_VARIABLE', 3, "Top-level variables cannot be declared to be 'abstract'");
   static final ParserErrorCode ABSTRACT_TYPEDEF = new ParserErrorCode.con2('ABSTRACT_TYPEDEF', 4, "Type aliases cannot be declared to be 'abstract'");
   static final ParserErrorCode BREAK_OUTSIDE_OF_LOOP = new ParserErrorCode.con2('BREAK_OUTSIDE_OF_LOOP', 5, "A break statement cannot be used outside of a loop or switch statement");
-  static final ParserErrorCode BUILT_IN_IDENTIFIER_AS_TYPE_NAME = new ParserErrorCode.con2('BUILT_IN_IDENTIFIER_AS_TYPE_NAME', 6, "The built-in identifier '%s' cannot be used as a type name");
-  static final ParserErrorCode BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME = new ParserErrorCode.con2('BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME', 7, "The built-in identifier '%s' cannot be used as a type alias name");
-  static final ParserErrorCode BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME = new ParserErrorCode.con2('BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME', 8, "The built-in identifier '%s' cannot be used as a type variable name");
-  static final ParserErrorCode CONST_AND_FINAL = new ParserErrorCode.con2('CONST_AND_FINAL', 9, "Members cannot be declared to be both 'const' and 'final'");
-  static final ParserErrorCode CONST_AND_VAR = new ParserErrorCode.con2('CONST_AND_VAR', 10, "Members cannot be declared to be both 'const' and 'var'");
-  static final ParserErrorCode CONST_CLASS = new ParserErrorCode.con2('CONST_CLASS', 11, "Classes cannot be declared to be 'const'");
-  static final ParserErrorCode CONST_METHOD = new ParserErrorCode.con2('CONST_METHOD', 12, "Getters, setters and methods cannot be declared to be 'const'");
-  static final ParserErrorCode CONST_TYPEDEF = new ParserErrorCode.con2('CONST_TYPEDEF', 13, "Type aliases cannot be declared to be 'const'");
-  static final ParserErrorCode CONSTRUCTOR_WITH_RETURN_TYPE = new ParserErrorCode.con2('CONSTRUCTOR_WITH_RETURN_TYPE', 14, "Constructors cannot have a return type");
-  static final ParserErrorCode CONTINUE_OUTSIDE_OF_LOOP = new ParserErrorCode.con2('CONTINUE_OUTSIDE_OF_LOOP', 15, "A continue statement cannot be used outside of a loop or switch statement");
-  static final ParserErrorCode CONTINUE_WITHOUT_LABEL_IN_CASE = new ParserErrorCode.con2('CONTINUE_WITHOUT_LABEL_IN_CASE', 16, "A continue statement in a switch statement must have a label as a target");
-  static final ParserErrorCode DIRECTIVE_AFTER_DECLARATION = new ParserErrorCode.con2('DIRECTIVE_AFTER_DECLARATION', 17, "Directives must appear before any declarations");
-  static final ParserErrorCode DUPLICATE_LABEL_IN_SWITCH_STATEMENT = new ParserErrorCode.con2('DUPLICATE_LABEL_IN_SWITCH_STATEMENT', 18, "The label %s was already used in this switch statement");
-  static final ParserErrorCode DUPLICATED_MODIFIER = new ParserErrorCode.con2('DUPLICATED_MODIFIER', 19, "The modifier '%s' was already specified.");
-  static final ParserErrorCode EXPECTED_CASE_OR_DEFAULT = new ParserErrorCode.con2('EXPECTED_CASE_OR_DEFAULT', 20, "Expected 'case' or 'default'");
-  static final ParserErrorCode EXPECTED_LIST_OR_MAP_LITERAL = new ParserErrorCode.con2('EXPECTED_LIST_OR_MAP_LITERAL', 21, "Expected a list or map literal");
-  static final ParserErrorCode EXPECTED_STRING_LITERAL = new ParserErrorCode.con2('EXPECTED_STRING_LITERAL', 22, "Expected a string literal");
-  static final ParserErrorCode EXPECTED_TOKEN = new ParserErrorCode.con2('EXPECTED_TOKEN', 23, "Expected to find: %s");
-  static final ParserErrorCode EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE = new ParserErrorCode.con2('EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE', 24, "Export directives must preceed part directives");
-  static final ParserErrorCode EXTERNAL_AFTER_CONST = new ParserErrorCode.con2('EXTERNAL_AFTER_CONST', 25, "The modifier 'external' should be before the modifier 'const'");
-  static final ParserErrorCode EXTERNAL_AFTER_FACTORY = new ParserErrorCode.con2('EXTERNAL_AFTER_FACTORY', 26, "The modifier 'external' should be before the modifier 'factory'");
-  static final ParserErrorCode EXTERNAL_AFTER_STATIC = new ParserErrorCode.con2('EXTERNAL_AFTER_STATIC', 27, "The modifier 'external' should be before the modifier 'static'");
-  static final ParserErrorCode EXTERNAL_CLASS = new ParserErrorCode.con2('EXTERNAL_CLASS', 28, "Classes cannot be declared to be 'external'");
-  static final ParserErrorCode EXTERNAL_CONSTRUCTOR_WITH_BODY = new ParserErrorCode.con2('EXTERNAL_CONSTRUCTOR_WITH_BODY', 29, "External constructors cannot have a body");
-  static final ParserErrorCode EXTERNAL_FIELD = new ParserErrorCode.con2('EXTERNAL_FIELD', 30, "Fields cannot be declared to be 'external'");
-  static final ParserErrorCode EXTERNAL_GETTER_WITH_BODY = new ParserErrorCode.con2('EXTERNAL_GETTER_WITH_BODY', 31, "External getters cannot have a body");
-  static final ParserErrorCode EXTERNAL_METHOD_WITH_BODY = new ParserErrorCode.con2('EXTERNAL_METHOD_WITH_BODY', 32, "External methods cannot have a body");
-  static final ParserErrorCode EXTERNAL_OPERATOR_WITH_BODY = new ParserErrorCode.con2('EXTERNAL_OPERATOR_WITH_BODY', 33, "External operators cannot have a body");
-  static final ParserErrorCode EXTERNAL_SETTER_WITH_BODY = new ParserErrorCode.con2('EXTERNAL_SETTER_WITH_BODY', 34, "External setters cannot have a body");
-  static final ParserErrorCode EXTERNAL_TYPEDEF = new ParserErrorCode.con2('EXTERNAL_TYPEDEF', 35, "Type aliases cannot be declared to be 'external'");
-  static final ParserErrorCode FACTORY_TOP_LEVEL_DECLARATION = new ParserErrorCode.con2('FACTORY_TOP_LEVEL_DECLARATION', 36, "Top-level declarations cannot be declared to be 'factory'");
-  static final ParserErrorCode FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR = new ParserErrorCode.con2('FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR', 37, "Field initializers can only be used in a constructor");
-  static final ParserErrorCode FINAL_AND_VAR = new ParserErrorCode.con2('FINAL_AND_VAR', 38, "Members cannot be declared to be both 'final' and 'var'");
-  static final ParserErrorCode FINAL_CLASS = new ParserErrorCode.con2('FINAL_CLASS', 39, "Classes cannot be declared to be 'final'");
-  static final ParserErrorCode FINAL_CONSTRUCTOR = new ParserErrorCode.con2('FINAL_CONSTRUCTOR', 40, "A constructor cannot be declared to be 'final'");
-  static final ParserErrorCode FINAL_METHOD = new ParserErrorCode.con2('FINAL_METHOD', 41, "Getters, setters and methods cannot be declared to be 'final'");
-  static final ParserErrorCode FINAL_TYPEDEF = new ParserErrorCode.con2('FINAL_TYPEDEF', 42, "Type aliases cannot be declared to be 'final'");
-  static final ParserErrorCode GETTER_WITH_PARAMETERS = new ParserErrorCode.con2('GETTER_WITH_PARAMETERS', 43, "Getter should be declared without a parameter list");
-  static final ParserErrorCode ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE = new ParserErrorCode.con2('ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE', 44, "Illegal assignment to non-assignable expression");
-  static final ParserErrorCode IMPLEMENTS_BEFORE_EXTENDS = new ParserErrorCode.con2('IMPLEMENTS_BEFORE_EXTENDS', 45, "The extends clause must be before the implements clause");
-  static final ParserErrorCode IMPLEMENTS_BEFORE_WITH = new ParserErrorCode.con2('IMPLEMENTS_BEFORE_WITH', 46, "The with clause must be before the implements clause");
-  static final ParserErrorCode IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE = new ParserErrorCode.con2('IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE', 47, "Import directives must preceed part directives");
-  static final ParserErrorCode INITIALIZED_VARIABLE_IN_FOR_EACH = new ParserErrorCode.con2('INITIALIZED_VARIABLE_IN_FOR_EACH', 48, "The loop variable in a for-each loop cannot be initialized");
-  static final ParserErrorCode INVALID_CODE_POINT = new ParserErrorCode.con2('INVALID_CODE_POINT', 49, "The escape sequence '%s' is not a valid code point");
-  static final ParserErrorCode INVALID_COMMENT_REFERENCE = new ParserErrorCode.con2('INVALID_COMMENT_REFERENCE', 50, "Comment references should contain a possibly prefixed identifier and can start with 'new', but should not contain anything else");
-  static final ParserErrorCode INVALID_HEX_ESCAPE = new ParserErrorCode.con2('INVALID_HEX_ESCAPE', 51, "An escape sequence starting with '\\x' must be followed by 2 hexidecimal digits");
-  static final ParserErrorCode INVALID_OPERATOR_FOR_SUPER = new ParserErrorCode.con2('INVALID_OPERATOR_FOR_SUPER', 52, "The operator '%s' cannot be used with 'super'");
-  static final ParserErrorCode INVALID_UNICODE_ESCAPE = new ParserErrorCode.con2('INVALID_UNICODE_ESCAPE', 53, "An escape sequence starting with '\\u' must be followed by 4 hexidecimal digits or from 1 to 6 digits between '{' and '}'");
-  static final ParserErrorCode LIBRARY_DIRECTIVE_NOT_FIRST = new ParserErrorCode.con2('LIBRARY_DIRECTIVE_NOT_FIRST', 54, "The library directive must appear before all other directives");
-  static final ParserErrorCode MISSING_ASSIGNABLE_SELECTOR = new ParserErrorCode.con2('MISSING_ASSIGNABLE_SELECTOR', 55, "Missing selector such as \".<identifier>\" or \"[0]\"");
-  static final ParserErrorCode MISSING_CATCH_OR_FINALLY = new ParserErrorCode.con2('MISSING_CATCH_OR_FINALLY', 56, "A try statement must have either a catch or finally clause");
-  static final ParserErrorCode MISSING_CLASS_BODY = new ParserErrorCode.con2('MISSING_CLASS_BODY', 57, "A class definition must have a body, even if it is empty");
-  static final ParserErrorCode MISSING_CONST_FINAL_VAR_OR_TYPE = new ParserErrorCode.con2('MISSING_CONST_FINAL_VAR_OR_TYPE', 58, "Variables must be declared using the keywords 'const', 'final', 'var' or a type name");
-  static final ParserErrorCode MISSING_FUNCTION_BODY = new ParserErrorCode.con2('MISSING_FUNCTION_BODY', 59, "A function body must be provided");
-  static final ParserErrorCode MISSING_FUNCTION_PARAMETERS = new ParserErrorCode.con2('MISSING_FUNCTION_PARAMETERS', 60, "Functions must have an explicit list of parameters");
-  static final ParserErrorCode MISSING_IDENTIFIER = new ParserErrorCode.con2('MISSING_IDENTIFIER', 61, "Expected an identifier");
-  static final ParserErrorCode MISSING_NAME_IN_LIBRARY_DIRECTIVE = new ParserErrorCode.con2('MISSING_NAME_IN_LIBRARY_DIRECTIVE', 62, "Library directives must include a library name");
-  static final ParserErrorCode MISSING_NAME_IN_PART_OF_DIRECTIVE = new ParserErrorCode.con2('MISSING_NAME_IN_PART_OF_DIRECTIVE', 63, "Library directives must include a library name");
-  static final ParserErrorCode MISSING_TYPEDEF_PARAMETERS = new ParserErrorCode.con2('MISSING_TYPEDEF_PARAMETERS', 64, "Type aliases for functions must have an explicit list of parameters");
-  static final ParserErrorCode MISSING_VARIABLE_IN_FOR_EACH = new ParserErrorCode.con2('MISSING_VARIABLE_IN_FOR_EACH', 65, "A loop variable must be declared in a for-each loop before the 'in', but none were found");
-  static final ParserErrorCode MIXED_PARAMETER_GROUPS = new ParserErrorCode.con2('MIXED_PARAMETER_GROUPS', 66, "Cannot have both positional and named parameters in a single parameter list");
-  static final ParserErrorCode MULTIPLE_EXTENDS_CLAUSES = new ParserErrorCode.con2('MULTIPLE_EXTENDS_CLAUSES', 67, "Each class definition can have at most one extends clause");
-  static final ParserErrorCode MULTIPLE_IMPLEMENTS_CLAUSES = new ParserErrorCode.con2('MULTIPLE_IMPLEMENTS_CLAUSES', 68, "Each class definition can have at most one implements clause");
-  static final ParserErrorCode MULTIPLE_LIBRARY_DIRECTIVES = new ParserErrorCode.con2('MULTIPLE_LIBRARY_DIRECTIVES', 69, "Only one library directive may be declared in a file");
-  static final ParserErrorCode MULTIPLE_NAMED_PARAMETER_GROUPS = new ParserErrorCode.con2('MULTIPLE_NAMED_PARAMETER_GROUPS', 70, "Cannot have multiple groups of named parameters in a single parameter list");
-  static final ParserErrorCode MULTIPLE_PART_OF_DIRECTIVES = new ParserErrorCode.con2('MULTIPLE_PART_OF_DIRECTIVES', 71, "Only one part-of directive may be declared in a file");
-  static final ParserErrorCode MULTIPLE_POSITIONAL_PARAMETER_GROUPS = new ParserErrorCode.con2('MULTIPLE_POSITIONAL_PARAMETER_GROUPS', 72, "Cannot have multiple groups of positional parameters in a single parameter list");
-  static final ParserErrorCode MULTIPLE_VARIABLES_IN_FOR_EACH = new ParserErrorCode.con2('MULTIPLE_VARIABLES_IN_FOR_EACH', 73, "A single loop variable must be declared in a for-each loop before the 'in', but %s were found");
-  static final ParserErrorCode MULTIPLE_WITH_CLAUSES = new ParserErrorCode.con2('MULTIPLE_WITH_CLAUSES', 74, "Each class definition can have at most one with clause");
-  static final ParserErrorCode NAMED_PARAMETER_OUTSIDE_GROUP = new ParserErrorCode.con2('NAMED_PARAMETER_OUTSIDE_GROUP', 75, "Named parameters must be enclosed in curly braces ('{' and '}')");
-  static final ParserErrorCode NON_CONSTRUCTOR_FACTORY = new ParserErrorCode.con2('NON_CONSTRUCTOR_FACTORY', 76, "Only constructors can be declared to be a 'factory'");
-  static final ParserErrorCode NON_IDENTIFIER_LIBRARY_NAME = new ParserErrorCode.con2('NON_IDENTIFIER_LIBRARY_NAME', 77, "The name of a library must be an identifier");
-  static final ParserErrorCode NON_PART_OF_DIRECTIVE_IN_PART = new ParserErrorCode.con2('NON_PART_OF_DIRECTIVE_IN_PART', 78, "The part-of directive must be the only directive in a part");
-  static final ParserErrorCode NON_USER_DEFINABLE_OPERATOR = new ParserErrorCode.con2('NON_USER_DEFINABLE_OPERATOR', 79, "The operator '%s' is not user definable");
-  static final ParserErrorCode POSITIONAL_AFTER_NAMED_ARGUMENT = new ParserErrorCode.con2('POSITIONAL_AFTER_NAMED_ARGUMENT', 80, "Positional arguments must occur before named arguments");
-  static final ParserErrorCode POSITIONAL_PARAMETER_OUTSIDE_GROUP = new ParserErrorCode.con2('POSITIONAL_PARAMETER_OUTSIDE_GROUP', 81, "Positional parameters must be enclosed in square brackets ('[' and ']')");
-  static final ParserErrorCode STATIC_AFTER_CONST = new ParserErrorCode.con2('STATIC_AFTER_CONST', 82, "The modifier 'static' should be before the modifier 'const'");
-  static final ParserErrorCode STATIC_AFTER_FINAL = new ParserErrorCode.con2('STATIC_AFTER_FINAL', 83, "The modifier 'static' should be before the modifier 'final'");
-  static final ParserErrorCode STATIC_AFTER_VAR = new ParserErrorCode.con2('STATIC_AFTER_VAR', 84, "The modifier 'static' should be before the modifier 'var'");
-  static final ParserErrorCode STATIC_CONSTRUCTOR = new ParserErrorCode.con2('STATIC_CONSTRUCTOR', 85, "Constructors cannot be static");
-  static final ParserErrorCode STATIC_OPERATOR = new ParserErrorCode.con2('STATIC_OPERATOR', 86, "Operators cannot be static");
-  static final ParserErrorCode STATIC_TOP_LEVEL_DECLARATION = new ParserErrorCode.con2('STATIC_TOP_LEVEL_DECLARATION', 87, "Top-level declarations cannot be declared to be 'static'");
+  static final ParserErrorCode CONST_AND_FINAL = new ParserErrorCode.con2('CONST_AND_FINAL', 6, "Members cannot be declared to be both 'const' and 'final'");
+  static final ParserErrorCode CONST_AND_VAR = new ParserErrorCode.con2('CONST_AND_VAR', 7, "Members cannot be declared to be both 'const' and 'var'");
+  static final ParserErrorCode CONST_CLASS = new ParserErrorCode.con2('CONST_CLASS', 8, "Classes cannot be declared to be 'const'");
+  static final ParserErrorCode CONST_METHOD = new ParserErrorCode.con2('CONST_METHOD', 9, "Getters, setters and methods cannot be declared to be 'const'");
+  static final ParserErrorCode CONST_TYPEDEF = new ParserErrorCode.con2('CONST_TYPEDEF', 10, "Type aliases cannot be declared to be 'const'");
+  static final ParserErrorCode CONSTRUCTOR_WITH_RETURN_TYPE = new ParserErrorCode.con2('CONSTRUCTOR_WITH_RETURN_TYPE', 11, "Constructors cannot have a return type");
+  static final ParserErrorCode CONTINUE_OUTSIDE_OF_LOOP = new ParserErrorCode.con2('CONTINUE_OUTSIDE_OF_LOOP', 12, "A continue statement cannot be used outside of a loop or switch statement");
+  static final ParserErrorCode CONTINUE_WITHOUT_LABEL_IN_CASE = new ParserErrorCode.con2('CONTINUE_WITHOUT_LABEL_IN_CASE', 13, "A continue statement in a switch statement must have a label as a target");
+  static final ParserErrorCode DIRECTIVE_AFTER_DECLARATION = new ParserErrorCode.con2('DIRECTIVE_AFTER_DECLARATION', 14, "Directives must appear before any declarations");
+  static final ParserErrorCode DUPLICATE_LABEL_IN_SWITCH_STATEMENT = new ParserErrorCode.con2('DUPLICATE_LABEL_IN_SWITCH_STATEMENT', 15, "The label %s was already used in this switch statement");
+  static final ParserErrorCode DUPLICATED_MODIFIER = new ParserErrorCode.con2('DUPLICATED_MODIFIER', 16, "The modifier '%s' was already specified.");
+  static final ParserErrorCode EXPECTED_CASE_OR_DEFAULT = new ParserErrorCode.con2('EXPECTED_CASE_OR_DEFAULT', 17, "Expected 'case' or 'default'");
+  static final ParserErrorCode EXPECTED_LIST_OR_MAP_LITERAL = new ParserErrorCode.con2('EXPECTED_LIST_OR_MAP_LITERAL', 18, "Expected a list or map literal");
+  static final ParserErrorCode EXPECTED_STRING_LITERAL = new ParserErrorCode.con2('EXPECTED_STRING_LITERAL', 19, "Expected a string literal");
+  static final ParserErrorCode EXPECTED_TOKEN = new ParserErrorCode.con2('EXPECTED_TOKEN', 20, "Expected to find '%s'");
+  static final ParserErrorCode EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE = new ParserErrorCode.con2('EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE', 21, "Export directives must preceed part directives");
+  static final ParserErrorCode EXTERNAL_AFTER_CONST = new ParserErrorCode.con2('EXTERNAL_AFTER_CONST', 22, "The modifier 'external' should be before the modifier 'const'");
+  static final ParserErrorCode EXTERNAL_AFTER_FACTORY = new ParserErrorCode.con2('EXTERNAL_AFTER_FACTORY', 23, "The modifier 'external' should be before the modifier 'factory'");
+  static final ParserErrorCode EXTERNAL_AFTER_STATIC = new ParserErrorCode.con2('EXTERNAL_AFTER_STATIC', 24, "The modifier 'external' should be before the modifier 'static'");
+  static final ParserErrorCode EXTERNAL_CLASS = new ParserErrorCode.con2('EXTERNAL_CLASS', 25, "Classes cannot be declared to be 'external'");
+  static final ParserErrorCode EXTERNAL_CONSTRUCTOR_WITH_BODY = new ParserErrorCode.con2('EXTERNAL_CONSTRUCTOR_WITH_BODY', 26, "External constructors cannot have a body");
+  static final ParserErrorCode EXTERNAL_FIELD = new ParserErrorCode.con2('EXTERNAL_FIELD', 27, "Fields cannot be declared to be 'external'");
+  static final ParserErrorCode EXTERNAL_GETTER_WITH_BODY = new ParserErrorCode.con2('EXTERNAL_GETTER_WITH_BODY', 28, "External getters cannot have a body");
+  static final ParserErrorCode EXTERNAL_METHOD_WITH_BODY = new ParserErrorCode.con2('EXTERNAL_METHOD_WITH_BODY', 29, "External methods cannot have a body");
+  static final ParserErrorCode EXTERNAL_OPERATOR_WITH_BODY = new ParserErrorCode.con2('EXTERNAL_OPERATOR_WITH_BODY', 30, "External operators cannot have a body");
+  static final ParserErrorCode EXTERNAL_SETTER_WITH_BODY = new ParserErrorCode.con2('EXTERNAL_SETTER_WITH_BODY', 31, "External setters cannot have a body");
+  static final ParserErrorCode EXTERNAL_TYPEDEF = new ParserErrorCode.con2('EXTERNAL_TYPEDEF', 32, "Type aliases cannot be declared to be 'external'");
+  static final ParserErrorCode FACTORY_TOP_LEVEL_DECLARATION = new ParserErrorCode.con2('FACTORY_TOP_LEVEL_DECLARATION', 33, "Top-level declarations cannot be declared to be 'factory'");
+  static final ParserErrorCode FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR = new ParserErrorCode.con2('FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR', 34, "Field initializers can only be used in a constructor");
+  static final ParserErrorCode FINAL_AND_VAR = new ParserErrorCode.con2('FINAL_AND_VAR', 35, "Members cannot be declared to be both 'final' and 'var'");
+  static final ParserErrorCode FINAL_CLASS = new ParserErrorCode.con2('FINAL_CLASS', 36, "Classes cannot be declared to be 'final'");
+  static final ParserErrorCode FINAL_CONSTRUCTOR = new ParserErrorCode.con2('FINAL_CONSTRUCTOR', 37, "A constructor cannot be declared to be 'final'");
+  static final ParserErrorCode FINAL_METHOD = new ParserErrorCode.con2('FINAL_METHOD', 38, "Getters, setters and methods cannot be declared to be 'final'");
+  static final ParserErrorCode FINAL_TYPEDEF = new ParserErrorCode.con2('FINAL_TYPEDEF', 39, "Type aliases cannot be declared to be 'final'");
+  static final ParserErrorCode GETTER_WITH_PARAMETERS = new ParserErrorCode.con2('GETTER_WITH_PARAMETERS', 40, "Getter should be declared without a parameter list");
+  static final ParserErrorCode ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE = new ParserErrorCode.con2('ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE', 41, "Illegal assignment to non-assignable expression");
+  static final ParserErrorCode IMPLEMENTS_BEFORE_EXTENDS = new ParserErrorCode.con2('IMPLEMENTS_BEFORE_EXTENDS', 42, "The extends clause must be before the implements clause");
+  static final ParserErrorCode IMPLEMENTS_BEFORE_WITH = new ParserErrorCode.con2('IMPLEMENTS_BEFORE_WITH', 43, "The with clause must be before the implements clause");
+  static final ParserErrorCode IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE = new ParserErrorCode.con2('IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE', 44, "Import directives must preceed part directives");
+  static final ParserErrorCode INITIALIZED_VARIABLE_IN_FOR_EACH = new ParserErrorCode.con2('INITIALIZED_VARIABLE_IN_FOR_EACH', 45, "The loop variable in a for-each loop cannot be initialized");
+  static final ParserErrorCode INVALID_CODE_POINT = new ParserErrorCode.con2('INVALID_CODE_POINT', 46, "The escape sequence '%s' is not a valid code point");
+  static final ParserErrorCode INVALID_COMMENT_REFERENCE = new ParserErrorCode.con2('INVALID_COMMENT_REFERENCE', 47, "Comment references should contain a possibly prefixed identifier and can start with 'new', but should not contain anything else");
+  static final ParserErrorCode INVALID_HEX_ESCAPE = new ParserErrorCode.con2('INVALID_HEX_ESCAPE', 48, "An escape sequence starting with '\\x' must be followed by 2 hexidecimal digits");
+  static final ParserErrorCode INVALID_OPERATOR_FOR_SUPER = new ParserErrorCode.con2('INVALID_OPERATOR_FOR_SUPER', 49, "The operator '%s' cannot be used with 'super'");
+  static final ParserErrorCode INVALID_UNICODE_ESCAPE = new ParserErrorCode.con2('INVALID_UNICODE_ESCAPE', 50, "An escape sequence starting with '\\u' must be followed by 4 hexidecimal digits or from 1 to 6 digits between '{' and '}'");
+  static final ParserErrorCode LIBRARY_DIRECTIVE_NOT_FIRST = new ParserErrorCode.con2('LIBRARY_DIRECTIVE_NOT_FIRST', 51, "The library directive must appear before all other directives");
+  static final ParserErrorCode MISSING_ASSIGNABLE_SELECTOR = new ParserErrorCode.con2('MISSING_ASSIGNABLE_SELECTOR', 52, "Missing selector such as \".<identifier>\" or \"[0]\"");
+  static final ParserErrorCode MISSING_CATCH_OR_FINALLY = new ParserErrorCode.con2('MISSING_CATCH_OR_FINALLY', 53, "A try statement must have either a catch or finally clause");
+  static final ParserErrorCode MISSING_CLASS_BODY = new ParserErrorCode.con2('MISSING_CLASS_BODY', 54, "A class definition must have a body, even if it is empty");
+  static final ParserErrorCode MISSING_CONST_FINAL_VAR_OR_TYPE = new ParserErrorCode.con2('MISSING_CONST_FINAL_VAR_OR_TYPE', 55, "Variables must be declared using the keywords 'const', 'final', 'var' or a type name");
+  static final ParserErrorCode MISSING_FUNCTION_BODY = new ParserErrorCode.con2('MISSING_FUNCTION_BODY', 56, "A function body must be provided");
+  static final ParserErrorCode MISSING_FUNCTION_PARAMETERS = new ParserErrorCode.con2('MISSING_FUNCTION_PARAMETERS', 57, "Functions must have an explicit list of parameters");
+  static final ParserErrorCode MISSING_IDENTIFIER = new ParserErrorCode.con2('MISSING_IDENTIFIER', 58, "Expected an identifier");
+  static final ParserErrorCode MISSING_NAME_IN_LIBRARY_DIRECTIVE = new ParserErrorCode.con2('MISSING_NAME_IN_LIBRARY_DIRECTIVE', 59, "Library directives must include a library name");
+  static final ParserErrorCode MISSING_NAME_IN_PART_OF_DIRECTIVE = new ParserErrorCode.con2('MISSING_NAME_IN_PART_OF_DIRECTIVE', 60, "Library directives must include a library name");
+  static final ParserErrorCode MISSING_STATEMENT = new ParserErrorCode.con2('MISSING_STATEMENT', 61, "Expected a statement");
+  static final ParserErrorCode MISSING_TERMINATOR_FOR_PARAMETER_GROUP = new ParserErrorCode.con2('MISSING_TERMINATOR_FOR_PARAMETER_GROUP', 62, "There is no '%s' to close the parameter group");
+  static final ParserErrorCode MISSING_TYPEDEF_PARAMETERS = new ParserErrorCode.con2('MISSING_TYPEDEF_PARAMETERS', 63, "Type aliases for functions must have an explicit list of parameters");
+  static final ParserErrorCode MISSING_VARIABLE_IN_FOR_EACH = new ParserErrorCode.con2('MISSING_VARIABLE_IN_FOR_EACH', 64, "A loop variable must be declared in a for-each loop before the 'in', but none were found");
+  static final ParserErrorCode MIXED_PARAMETER_GROUPS = new ParserErrorCode.con2('MIXED_PARAMETER_GROUPS', 65, "Cannot have both positional and named parameters in a single parameter list");
+  static final ParserErrorCode MULTIPLE_EXTENDS_CLAUSES = new ParserErrorCode.con2('MULTIPLE_EXTENDS_CLAUSES', 66, "Each class definition can have at most one extends clause");
+  static final ParserErrorCode MULTIPLE_IMPLEMENTS_CLAUSES = new ParserErrorCode.con2('MULTIPLE_IMPLEMENTS_CLAUSES', 67, "Each class definition can have at most one implements clause");
+  static final ParserErrorCode MULTIPLE_LIBRARY_DIRECTIVES = new ParserErrorCode.con2('MULTIPLE_LIBRARY_DIRECTIVES', 68, "Only one library directive may be declared in a file");
+  static final ParserErrorCode MULTIPLE_NAMED_PARAMETER_GROUPS = new ParserErrorCode.con2('MULTIPLE_NAMED_PARAMETER_GROUPS', 69, "Cannot have multiple groups of named parameters in a single parameter list");
+  static final ParserErrorCode MULTIPLE_PART_OF_DIRECTIVES = new ParserErrorCode.con2('MULTIPLE_PART_OF_DIRECTIVES', 70, "Only one part-of directive may be declared in a file");
+  static final ParserErrorCode MULTIPLE_POSITIONAL_PARAMETER_GROUPS = new ParserErrorCode.con2('MULTIPLE_POSITIONAL_PARAMETER_GROUPS', 71, "Cannot have multiple groups of positional parameters in a single parameter list");
+  static final ParserErrorCode MULTIPLE_VARIABLES_IN_FOR_EACH = new ParserErrorCode.con2('MULTIPLE_VARIABLES_IN_FOR_EACH', 72, "A single loop variable must be declared in a for-each loop before the 'in', but %s were found");
+  static final ParserErrorCode MULTIPLE_WITH_CLAUSES = new ParserErrorCode.con2('MULTIPLE_WITH_CLAUSES', 73, "Each class definition can have at most one with clause");
+  static final ParserErrorCode NAMED_PARAMETER_OUTSIDE_GROUP = new ParserErrorCode.con2('NAMED_PARAMETER_OUTSIDE_GROUP', 74, "Named parameters must be enclosed in curly braces ('{' and '}')");
+  static final ParserErrorCode NON_CONSTRUCTOR_FACTORY = new ParserErrorCode.con2('NON_CONSTRUCTOR_FACTORY', 75, "Only constructors can be declared to be a 'factory'");
+  static final ParserErrorCode NON_IDENTIFIER_LIBRARY_NAME = new ParserErrorCode.con2('NON_IDENTIFIER_LIBRARY_NAME', 76, "The name of a library must be an identifier");
+  static final ParserErrorCode NON_PART_OF_DIRECTIVE_IN_PART = new ParserErrorCode.con2('NON_PART_OF_DIRECTIVE_IN_PART', 77, "The part-of directive must be the only directive in a part");
+  static final ParserErrorCode NON_USER_DEFINABLE_OPERATOR = new ParserErrorCode.con2('NON_USER_DEFINABLE_OPERATOR', 78, "The operator '%s' is not user definable");
+  static final ParserErrorCode POSITIONAL_AFTER_NAMED_ARGUMENT = new ParserErrorCode.con2('POSITIONAL_AFTER_NAMED_ARGUMENT', 79, "Positional arguments must occur before named arguments");
+  static final ParserErrorCode POSITIONAL_PARAMETER_OUTSIDE_GROUP = new ParserErrorCode.con2('POSITIONAL_PARAMETER_OUTSIDE_GROUP', 80, "Positional parameters must be enclosed in square brackets ('[' and ']')");
+  static final ParserErrorCode STATIC_AFTER_CONST = new ParserErrorCode.con2('STATIC_AFTER_CONST', 81, "The modifier 'static' should be before the modifier 'const'");
+  static final ParserErrorCode STATIC_AFTER_FINAL = new ParserErrorCode.con2('STATIC_AFTER_FINAL', 82, "The modifier 'static' should be before the modifier 'final'");
+  static final ParserErrorCode STATIC_AFTER_VAR = new ParserErrorCode.con2('STATIC_AFTER_VAR', 83, "The modifier 'static' should be before the modifier 'var'");
+  static final ParserErrorCode STATIC_CONSTRUCTOR = new ParserErrorCode.con2('STATIC_CONSTRUCTOR', 84, "Constructors cannot be static");
+  static final ParserErrorCode STATIC_OPERATOR = new ParserErrorCode.con2('STATIC_OPERATOR', 85, "Operators cannot be static");
+  static final ParserErrorCode STATIC_TOP_LEVEL_DECLARATION = new ParserErrorCode.con2('STATIC_TOP_LEVEL_DECLARATION', 86, "Top-level declarations cannot be declared to be 'static'");
+  static final ParserErrorCode UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP = new ParserErrorCode.con2('UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP', 87, "There is no '%s' to open a parameter group");
   static final ParserErrorCode UNEXPECTED_TOKEN = new ParserErrorCode.con2('UNEXPECTED_TOKEN', 88, "Unexpected token '%s'");
   static final ParserErrorCode USE_OF_UNARY_PLUS_OPERATOR = new ParserErrorCode.con2('USE_OF_UNARY_PLUS_OPERATOR', 89, "There is no unary plus operator in Dart");
   static final ParserErrorCode WITH_BEFORE_EXTENDS = new ParserErrorCode.con2('WITH_BEFORE_EXTENDS', 90, "The extends clause must be before the with clause");
   static final ParserErrorCode WITH_WITHOUT_EXTENDS = new ParserErrorCode.con2('WITH_WITHOUT_EXTENDS', 91, "The with clause cannot be used without an extends clause");
   static final ParserErrorCode WRONG_SEPARATOR_FOR_NAMED_PARAMETER = new ParserErrorCode.con2('WRONG_SEPARATOR_FOR_NAMED_PARAMETER', 92, "The default value of a named parameter should be preceeded by ':'");
   static final ParserErrorCode WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER = new ParserErrorCode.con2('WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER', 93, "The default value of a positional parameter should be preceeded by '='");
-  static final ParserErrorCode VAR_CLASS = new ParserErrorCode.con2('VAR_CLASS', 94, "Classes cannot be declared to be 'var'");
-  static final ParserErrorCode VAR_RETURN_TYPE = new ParserErrorCode.con2('VAR_RETURN_TYPE', 95, "The return type cannot be 'var'");
-  static final ParserErrorCode VAR_TYPEDEF = new ParserErrorCode.con2('VAR_TYPEDEF', 96, "Type aliases cannot be declared to be 'var'");
-  static final ParserErrorCode VOID_PARAMETER = new ParserErrorCode.con2('VOID_PARAMETER', 97, "Parameters cannot have a type of 'void'");
-  static final ParserErrorCode VOID_VARIABLE = new ParserErrorCode.con2('VOID_VARIABLE', 98, "Variables cannot have a type of 'void'");
-  static final List<ParserErrorCode> values = [ABSTRACT_CLASS_MEMBER, ABSTRACT_STATIC_METHOD, ABSTRACT_TOP_LEVEL_FUNCTION, ABSTRACT_TOP_LEVEL_VARIABLE, ABSTRACT_TYPEDEF, BREAK_OUTSIDE_OF_LOOP, BUILT_IN_IDENTIFIER_AS_TYPE_NAME, BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, CONST_AND_FINAL, CONST_AND_VAR, CONST_CLASS, CONST_METHOD, CONST_TYPEDEF, CONSTRUCTOR_WITH_RETURN_TYPE, CONTINUE_OUTSIDE_OF_LOOP, CONTINUE_WITHOUT_LABEL_IN_CASE, DIRECTIVE_AFTER_DECLARATION, DUPLICATE_LABEL_IN_SWITCH_STATEMENT, DUPLICATED_MODIFIER, EXPECTED_CASE_OR_DEFAULT, EXPECTED_LIST_OR_MAP_LITERAL, EXPECTED_STRING_LITERAL, EXPECTED_TOKEN, EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE, EXTERNAL_AFTER_CONST, EXTERNAL_AFTER_FACTORY, EXTERNAL_AFTER_STATIC, EXTERNAL_CLASS, EXTERNAL_CONSTRUCTOR_WITH_BODY, EXTERNAL_FIELD, EXTERNAL_GETTER_WITH_BODY, EXTERNAL_METHOD_WITH_BODY, EXTERNAL_OPERATOR_WITH_BODY, EXTERNAL_SETTER_WITH_BODY, EXTERNAL_TYPEDEF, FACTORY_TOP_LEVEL_DECLARATION, FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, FINAL_AND_VAR, FINAL_CLASS, FINAL_CONSTRUCTOR, FINAL_METHOD, FINAL_TYPEDEF, GETTER_WITH_PARAMETERS, ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, IMPLEMENTS_BEFORE_EXTENDS, IMPLEMENTS_BEFORE_WITH, IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE, INITIALIZED_VARIABLE_IN_FOR_EACH, INVALID_CODE_POINT, INVALID_COMMENT_REFERENCE, INVALID_HEX_ESCAPE, INVALID_OPERATOR_FOR_SUPER, INVALID_UNICODE_ESCAPE, LIBRARY_DIRECTIVE_NOT_FIRST, MISSING_ASSIGNABLE_SELECTOR, MISSING_CATCH_OR_FINALLY, MISSING_CLASS_BODY, MISSING_CONST_FINAL_VAR_OR_TYPE, MISSING_FUNCTION_BODY, MISSING_FUNCTION_PARAMETERS, MISSING_IDENTIFIER, MISSING_NAME_IN_LIBRARY_DIRECTIVE, MISSING_NAME_IN_PART_OF_DIRECTIVE, MISSING_TYPEDEF_PARAMETERS, MISSING_VARIABLE_IN_FOR_EACH, MIXED_PARAMETER_GROUPS, MULTIPLE_EXTENDS_CLAUSES, MULTIPLE_IMPLEMENTS_CLAUSES, MULTIPLE_LIBRARY_DIRECTIVES, MULTIPLE_NAMED_PARAMETER_GROUPS, MULTIPLE_PART_OF_DIRECTIVES, MULTIPLE_POSITIONAL_PARAMETER_GROUPS, MULTIPLE_VARIABLES_IN_FOR_EACH, MULTIPLE_WITH_CLAUSES, NAMED_PARAMETER_OUTSIDE_GROUP, NON_CONSTRUCTOR_FACTORY, NON_IDENTIFIER_LIBRARY_NAME, NON_PART_OF_DIRECTIVE_IN_PART, NON_USER_DEFINABLE_OPERATOR, POSITIONAL_AFTER_NAMED_ARGUMENT, POSITIONAL_PARAMETER_OUTSIDE_GROUP, STATIC_AFTER_CONST, STATIC_AFTER_FINAL, STATIC_AFTER_VAR, STATIC_CONSTRUCTOR, STATIC_OPERATOR, STATIC_TOP_LEVEL_DECLARATION, UNEXPECTED_TOKEN, USE_OF_UNARY_PLUS_OPERATOR, WITH_BEFORE_EXTENDS, WITH_WITHOUT_EXTENDS, WRONG_SEPARATOR_FOR_NAMED_PARAMETER, WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER, VAR_CLASS, VAR_RETURN_TYPE, VAR_TYPEDEF, VOID_PARAMETER, VOID_VARIABLE];
+  static final ParserErrorCode WRONG_TERMINATOR_FOR_PARAMETER_GROUP = new ParserErrorCode.con2('WRONG_TERMINATOR_FOR_PARAMETER_GROUP', 94, "Expected '%s' to close parameter group");
+  static final ParserErrorCode VAR_CLASS = new ParserErrorCode.con2('VAR_CLASS', 95, "Classes cannot be declared to be 'var'");
+  static final ParserErrorCode VAR_RETURN_TYPE = new ParserErrorCode.con2('VAR_RETURN_TYPE', 96, "The return type cannot be 'var'");
+  static final ParserErrorCode VAR_TYPEDEF = new ParserErrorCode.con2('VAR_TYPEDEF', 97, "Type aliases cannot be declared to be 'var'");
+  static final ParserErrorCode VOID_PARAMETER = new ParserErrorCode.con2('VOID_PARAMETER', 98, "Parameters cannot have a type of 'void'");
+  static final ParserErrorCode VOID_VARIABLE = new ParserErrorCode.con2('VOID_VARIABLE', 99, "Variables cannot have a type of 'void'");
+  static final List<ParserErrorCode> values = [ABSTRACT_CLASS_MEMBER, ABSTRACT_STATIC_METHOD, ABSTRACT_TOP_LEVEL_FUNCTION, ABSTRACT_TOP_LEVEL_VARIABLE, ABSTRACT_TYPEDEF, BREAK_OUTSIDE_OF_LOOP, CONST_AND_FINAL, CONST_AND_VAR, CONST_CLASS, CONST_METHOD, CONST_TYPEDEF, CONSTRUCTOR_WITH_RETURN_TYPE, CONTINUE_OUTSIDE_OF_LOOP, CONTINUE_WITHOUT_LABEL_IN_CASE, DIRECTIVE_AFTER_DECLARATION, DUPLICATE_LABEL_IN_SWITCH_STATEMENT, DUPLICATED_MODIFIER, EXPECTED_CASE_OR_DEFAULT, EXPECTED_LIST_OR_MAP_LITERAL, EXPECTED_STRING_LITERAL, EXPECTED_TOKEN, EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE, EXTERNAL_AFTER_CONST, EXTERNAL_AFTER_FACTORY, EXTERNAL_AFTER_STATIC, EXTERNAL_CLASS, EXTERNAL_CONSTRUCTOR_WITH_BODY, EXTERNAL_FIELD, EXTERNAL_GETTER_WITH_BODY, EXTERNAL_METHOD_WITH_BODY, EXTERNAL_OPERATOR_WITH_BODY, EXTERNAL_SETTER_WITH_BODY, EXTERNAL_TYPEDEF, FACTORY_TOP_LEVEL_DECLARATION, FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, FINAL_AND_VAR, FINAL_CLASS, FINAL_CONSTRUCTOR, FINAL_METHOD, FINAL_TYPEDEF, GETTER_WITH_PARAMETERS, ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, IMPLEMENTS_BEFORE_EXTENDS, IMPLEMENTS_BEFORE_WITH, IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE, INITIALIZED_VARIABLE_IN_FOR_EACH, INVALID_CODE_POINT, INVALID_COMMENT_REFERENCE, INVALID_HEX_ESCAPE, INVALID_OPERATOR_FOR_SUPER, INVALID_UNICODE_ESCAPE, LIBRARY_DIRECTIVE_NOT_FIRST, MISSING_ASSIGNABLE_SELECTOR, MISSING_CATCH_OR_FINALLY, MISSING_CLASS_BODY, MISSING_CONST_FINAL_VAR_OR_TYPE, MISSING_FUNCTION_BODY, MISSING_FUNCTION_PARAMETERS, MISSING_IDENTIFIER, MISSING_NAME_IN_LIBRARY_DIRECTIVE, MISSING_NAME_IN_PART_OF_DIRECTIVE, MISSING_STATEMENT, MISSING_TERMINATOR_FOR_PARAMETER_GROUP, MISSING_TYPEDEF_PARAMETERS, MISSING_VARIABLE_IN_FOR_EACH, MIXED_PARAMETER_GROUPS, MULTIPLE_EXTENDS_CLAUSES, MULTIPLE_IMPLEMENTS_CLAUSES, MULTIPLE_LIBRARY_DIRECTIVES, MULTIPLE_NAMED_PARAMETER_GROUPS, MULTIPLE_PART_OF_DIRECTIVES, MULTIPLE_POSITIONAL_PARAMETER_GROUPS, MULTIPLE_VARIABLES_IN_FOR_EACH, MULTIPLE_WITH_CLAUSES, NAMED_PARAMETER_OUTSIDE_GROUP, NON_CONSTRUCTOR_FACTORY, NON_IDENTIFIER_LIBRARY_NAME, NON_PART_OF_DIRECTIVE_IN_PART, NON_USER_DEFINABLE_OPERATOR, POSITIONAL_AFTER_NAMED_ARGUMENT, POSITIONAL_PARAMETER_OUTSIDE_GROUP, STATIC_AFTER_CONST, STATIC_AFTER_FINAL, STATIC_AFTER_VAR, STATIC_CONSTRUCTOR, STATIC_OPERATOR, STATIC_TOP_LEVEL_DECLARATION, UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP, UNEXPECTED_TOKEN, USE_OF_UNARY_PLUS_OPERATOR, WITH_BEFORE_EXTENDS, WITH_WITHOUT_EXTENDS, WRONG_SEPARATOR_FOR_NAMED_PARAMETER, WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER, WRONG_TERMINATOR_FOR_PARAMETER_GROUP, VAR_CLASS, VAR_RETURN_TYPE, VAR_TYPEDEF, VOID_PARAMETER, VOID_VARIABLE];
   String __name;
   int __ordinal = 0;
+  int get ordinal => __ordinal;
   /**
    * The severity of this error.
    */
@@ -4756,9 +4766,9 @@
    * @param message the message template used to create the message to be displayed for the error
    */
   ParserErrorCode.con1(String ___name, int ___ordinal, ErrorSeverity severity2, String message2) {
-    _jtd_constructor_217_impl(___name, ___ordinal, severity2, message2);
+    _jtd_constructor_269_impl(___name, ___ordinal, severity2, message2);
   }
-  _jtd_constructor_217_impl(String ___name, int ___ordinal, ErrorSeverity severity2, String message2) {
+  _jtd_constructor_269_impl(String ___name, int ___ordinal, ErrorSeverity severity2, String message2) {
     __name = ___name;
     __ordinal = ___ordinal;
     this._severity = severity2;
@@ -4769,10 +4779,10 @@
    * @param message the message template used to create the message to be displayed for the error
    */
   ParserErrorCode.con2(String ___name, int ___ordinal, String message) {
-    _jtd_constructor_218_impl(___name, ___ordinal, message);
+    _jtd_constructor_270_impl(___name, ___ordinal, message);
   }
-  _jtd_constructor_218_impl(String ___name, int ___ordinal, String message) {
-    _jtd_constructor_217_impl(___name, ___ordinal, ErrorSeverity.ERROR, message);
+  _jtd_constructor_270_impl(String ___name, int ___ordinal, String message) {
+    _jtd_constructor_269_impl(___name, ___ordinal, ErrorSeverity.ERROR, message);
   }
   ErrorSeverity get errorSeverity => _severity;
   String get message => _message;
@@ -5001,6 +5011,12 @@
     _writer.print(";");
     return null;
   }
+  Object visitDeclaredIdentifier(DeclaredIdentifier node) {
+    visit8(node.keyword, " ");
+    visit6(node.type, " ");
+    visit(node.identifier);
+    return null;
+  }
   Object visitDefaultFormalParameter(DefaultFormalParameter node) {
     visit(node.parameter);
     if (node.separator != null) {
@@ -5071,7 +5087,7 @@
   }
   Object visitForEachStatement(ForEachStatement node) {
     _writer.print("for (");
-    visit(node.loopParameter);
+    visit(node.loopVariable);
     _writer.print(" in ");
     visit(node.iterator);
     _writer.print(") ");
@@ -5081,10 +5097,10 @@
   Object visitFormalParameterList(FormalParameterList node) {
     String groupEnd = null;
     _writer.print('(');
-    NodeList<FormalParameter> parameters11 = node.parameters;
-    int size7 = parameters11.length;
+    NodeList<FormalParameter> parameters13 = node.parameters;
+    int size7 = parameters13.length;
     for (int i = 0; i < size7; i++) {
-      FormalParameter parameter = parameters11[i];
+      FormalParameter parameter = parameters13[i];
       if (i > 0) {
         _writer.print(", ");
       }
@@ -5366,12 +5382,12 @@
     return null;
   }
   Object visitReturnStatement(ReturnStatement node) {
-    Expression expression16 = node.expression;
-    if (expression16 == null) {
+    Expression expression17 = node.expression;
+    if (expression17 == null) {
       _writer.print("return;");
     } else {
       _writer.print("return ");
-      expression16.accept(this);
+      expression17.accept(this);
       _writer.print(";");
     }
     return null;
diff --git a/pkg/analyzer-experimental/lib/src/generated/resolver.dart b/pkg/analyzer_experimental/lib/src/generated/resolver.dart
similarity index 64%
rename from pkg/analyzer-experimental/lib/src/generated/resolver.dart
rename to pkg/analyzer_experimental/lib/src/generated/resolver.dart
index 2e576fc..aba27db 100644
--- a/pkg/analyzer-experimental/lib/src/generated/resolver.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/resolver.dart
@@ -8,16 +8,20 @@
 import 'java_engine.dart';
 import 'source.dart';
 import 'error.dart';
-import 'scanner.dart' show Keyword, TokenType, Token, KeywordToken, StringToken;
+import 'scanner.dart' as sc;
 import 'utilities_dart.dart';
 import 'ast.dart';
+import 'parser.dart' show Parser;
 import 'element.dart' hide HideCombinator, ShowCombinator;
+import 'html.dart' as ht;
 import 'engine.dart';
+import 'constant.dart';
 import 'element.dart' as __imp_combi show HideCombinator, ShowCombinator;
 
 /**
  * Instances of the class {@code CompilationUnitBuilder} build an element model for a single
  * compilation unit.
+ * @coverage dart.engine.resolver
  */
 class CompilationUnitBuilder {
   /**
@@ -43,7 +47,7 @@
    * @return the compilation unit element that was built
    * @throws AnalysisException if the analysis could not be performed
    */
-  CompilationUnitElementImpl buildCompilationUnit(Source source) => buildCompilationUnit2(source, _analysisContext.parse2(source, _errorListener));
+  CompilationUnitElementImpl buildCompilationUnit(Source source) => buildCompilationUnit2(source, _analysisContext.parse3(source, _errorListener));
   /**
    * Build the compilation unit element for the given source.
    * @param source the source describing the compilation unit
@@ -51,17 +55,17 @@
    * @return the compilation unit element that was built
    * @throws AnalysisException if the analysis could not be performed
    */
-  CompilationUnitElementImpl buildCompilationUnit2(Source source11, CompilationUnit unit) {
+  CompilationUnitElementImpl buildCompilationUnit2(Source source13, CompilationUnit unit) {
     ElementHolder holder = new ElementHolder();
     ElementBuilder builder = new ElementBuilder(holder);
     unit.accept(builder);
-    CompilationUnitElementImpl element = new CompilationUnitElementImpl(source11.shortName);
+    CompilationUnitElementImpl element = new CompilationUnitElementImpl(source13.shortName);
     element.accessors = holder.accessors;
     element.functions = holder.functions;
-    element.source = source11;
+    element.source = source13;
     element.typeAliases = holder.typeAliases;
     element.types = holder.types;
-    element.variables = holder.variables;
+    element.topLevelVariables = holder.topLevelVariables;
     unit.element = element;
     return element;
   }
@@ -69,6 +73,7 @@
 /**
  * Instances of the class {@code ElementBuilder} traverse an AST structure and build the element
  * model representing the AST structure.
+ * @coverage dart.engine.resolver
  */
 class ElementBuilder extends RecursiveASTVisitor<Object> {
   /**
@@ -80,6 +85,14 @@
    */
   bool _inFieldContext = false;
   /**
+   * A flag indicating whether a variable declaration is within the body of a method or function.
+   */
+  bool _inFunction = false;
+  /**
+   * A flag indicating whether the class currently being visited can be used as a mixin.
+   */
+  bool _isValidMixin = false;
+  /**
    * Initialize a newly created element builder to build the elements for a compilation unit.
    * @param initialHolder the element holder associated with the compilation unit being built
    */
@@ -89,30 +102,34 @@
   Object visitCatchClause(CatchClause node) {
     SimpleIdentifier exceptionParameter2 = node.exceptionParameter;
     if (exceptionParameter2 != null) {
-      VariableElementImpl exception = new VariableElementImpl.con1(exceptionParameter2);
-      _currentHolder.addVariable(exception);
+      LocalVariableElementImpl exception = new LocalVariableElementImpl(exceptionParameter2);
+      _currentHolder.addLocalVariable(exception);
       exceptionParameter2.element = exception;
       SimpleIdentifier stackTraceParameter2 = node.stackTraceParameter;
       if (stackTraceParameter2 != null) {
-        VariableElementImpl stackTrace = new VariableElementImpl.con1(stackTraceParameter2);
-        _currentHolder.addVariable(stackTrace);
+        LocalVariableElementImpl stackTrace = new LocalVariableElementImpl(stackTraceParameter2);
+        _currentHolder.addLocalVariable(stackTrace);
         stackTraceParameter2.element = stackTrace;
       }
     }
-    node.visitChildren(this);
-    return null;
+    return super.visitCatchClause(node);
   }
   Object visitClassDeclaration(ClassDeclaration node) {
     ElementHolder holder = new ElementHolder();
+    _isValidMixin = true;
     visitChildren(holder, node);
     SimpleIdentifier className = node.name;
     ClassElementImpl element = new ClassElementImpl(className);
+    List<TypeVariableElement> typeVariables4 = holder.typeVariables;
+    InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element);
+    interfaceType.typeArguments = createTypeVariableTypes(typeVariables4);
+    element.type = interfaceType;
     List<ConstructorElement> constructors3 = holder.constructors;
     if (constructors3.length == 0) {
       ConstructorElementImpl constructor = new ConstructorElementImpl(null);
       constructor.synthetic = true;
       FunctionTypeImpl type = new FunctionTypeImpl.con1(constructor);
-      type.returnType = element.type;
+      type.returnType = interfaceType;
       constructor.type = type;
       constructors3 = <ConstructorElement> [constructor];
     }
@@ -121,19 +138,8 @@
     element.constructors = constructors3;
     element.fields = holder.fields;
     element.methods = holder.methods;
-    List<TypeVariableElement> typeVariables4 = holder.typeVariables;
     element.typeVariables = typeVariables4;
-    InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element);
-    int typeVariableCount = typeVariables4.length;
-    List<Type2> typeArguments = new List<Type2>(typeVariableCount);
-    for (int i = 0; i < typeVariableCount; i++) {
-      TypeVariableElementImpl typeVariable = (typeVariables4[i] as TypeVariableElementImpl);
-      TypeVariableTypeImpl typeArgument = new TypeVariableTypeImpl(typeVariable);
-      typeVariable.type = typeArgument;
-      typeArguments[i] = typeArgument;
-    }
-    interfaceType.typeArguments = typeArguments;
-    element.type = interfaceType;
+    element.validMixin = _isValidMixin;
     _currentHolder.addType(element);
     className.element = element;
     return null;
@@ -144,24 +150,18 @@
     SimpleIdentifier className = node.name;
     ClassElementImpl element = new ClassElementImpl(className);
     element.abstract = node.abstractKeyword != null;
+    element.typedef = true;
     List<TypeVariableElement> typeVariables5 = holder.typeVariables;
     element.typeVariables = typeVariables5;
     InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element);
-    int typeVariableCount = typeVariables5.length;
-    List<Type2> typeArguments = new List<Type2>(typeVariableCount);
-    for (int i = 0; i < typeVariableCount; i++) {
-      TypeVariableElementImpl typeVariable = (typeVariables5[i] as TypeVariableElementImpl);
-      TypeVariableTypeImpl typeArgument = new TypeVariableTypeImpl(typeVariable);
-      typeVariable.type = typeArgument;
-      typeArguments[i] = typeArgument;
-    }
-    interfaceType.typeArguments = typeArguments;
+    interfaceType.typeArguments = createTypeVariableTypes(typeVariables5);
     element.type = interfaceType;
     _currentHolder.addType(element);
     className.element = element;
     return null;
   }
   Object visitConstructorDeclaration(ConstructorDeclaration node) {
+    _isValidMixin = false;
     ElementHolder holder = new ElementHolder();
     visitChildren(holder, node);
     SimpleIdentifier constructorName = node.name;
@@ -171,8 +171,9 @@
     }
     element.functions = holder.functions;
     element.labels = holder.labels;
-    element.localVariables = holder.variables;
+    element.localVariables = holder.localVariables;
     element.parameters = holder.parameters;
+    element.const2 = node.constKeyword != null;
     _currentHolder.addConstructor(element);
     node.element = element;
     if (constructorName != null) {
@@ -180,20 +181,43 @@
     }
     return null;
   }
+  Object visitDeclaredIdentifier(DeclaredIdentifier node) {
+    SimpleIdentifier variableName = node.identifier;
+    sc.Token keyword27 = node.keyword;
+    LocalVariableElementImpl element = new LocalVariableElementImpl(variableName);
+    ForEachStatement statement = node.parent as ForEachStatement;
+    int declarationEnd = node.offset + node.length;
+    int statementEnd = statement.offset + statement.length;
+    element.setVisibleRange(declarationEnd, statementEnd - declarationEnd - 1);
+    element.const3 = matches(keyword27, sc.Keyword.CONST);
+    element.final2 = matches(keyword27, sc.Keyword.FINAL);
+    _currentHolder.addLocalVariable(element);
+    variableName.element = element;
+    return super.visitDeclaredIdentifier(node);
+  }
   Object visitDefaultFormalParameter(DefaultFormalParameter node) {
     ElementHolder holder = new ElementHolder();
-    visitChildren(holder, node.defaultValue);
+    visit(holder, node.defaultValue);
     FunctionElementImpl initializer = new FunctionElementImpl();
     initializer.functions = holder.functions;
     initializer.labels = holder.labels;
-    initializer.localVariables = holder.variables;
+    initializer.localVariables = holder.localVariables;
     initializer.parameters = holder.parameters;
     SimpleIdentifier parameterName = node.parameter.identifier;
-    ParameterElementImpl parameter = new ParameterElementImpl(parameterName);
-    parameter.const2 = node.isConst();
+    ParameterElementImpl parameter;
+    if (node.isConst()) {
+      parameter = new ConstParameterElementImpl(parameterName);
+      parameter.const3 = true;
+    } else {
+      parameter = new ParameterElementImpl(parameterName);
+    }
     parameter.final2 = node.isFinal();
     parameter.initializer = initializer;
     parameter.parameterKind = node.kind;
+    FunctionBody body = getFunctionBody(node);
+    if (body != null) {
+      parameter.setVisibleRange(body.offset, body.length);
+    }
     _currentHolder.addParameter(parameter);
     parameterName.element = parameter;
     node.parameter.accept(this);
@@ -213,38 +237,101 @@
     if (node.parent is! DefaultFormalParameter) {
       SimpleIdentifier parameterName = node.identifier;
       ParameterElementImpl parameter = new ParameterElementImpl(parameterName);
-      parameter.const2 = node.isConst();
+      parameter.const3 = node.isConst();
       parameter.initializingFormal = true;
       parameter.final2 = node.isFinal();
       parameter.parameterKind = node.kind;
       _currentHolder.addParameter(parameter);
       parameterName.element = parameter;
     }
-    node.visitChildren(this);
-    return null;
+    return super.visitFieldFormalParameter(node);
   }
   Object visitFunctionDeclaration(FunctionDeclaration node) {
-    ElementHolder holder = new ElementHolder();
-    visitChildren(holder, node);
-    SimpleIdentifier functionName = node.name;
-    FunctionElementImpl element = new FunctionElementImpl.con1(functionName);
-    element.functions = holder.functions;
-    element.labels = holder.labels;
-    element.localVariables = holder.variables;
-    element.parameters = holder.parameters;
-    _currentHolder.addFunction(element);
-    functionName.element = element;
+    FunctionExpression expression = node.functionExpression;
+    if (expression != null) {
+      ElementHolder holder = new ElementHolder();
+      bool wasInFunction = _inFunction;
+      _inFunction = true;
+      try {
+        visitChildren(holder, expression);
+      } finally {
+        _inFunction = wasInFunction;
+      }
+      sc.Token property = node.propertyKeyword;
+      if (property == null) {
+        SimpleIdentifier functionName = node.name;
+        FunctionElementImpl element = new FunctionElementImpl.con1(functionName);
+        element.functions = holder.functions;
+        element.labels = holder.labels;
+        element.localVariables = holder.localVariables;
+        element.parameters = holder.parameters;
+        FunctionTypeImpl type = new FunctionTypeImpl.con1(element);
+        element.type = type;
+        _currentHolder.addFunction(element);
+        expression.element = element;
+        functionName.element = element;
+      } else {
+        SimpleIdentifier propertyNameNode = node.name;
+        if (propertyNameNode == null) {
+          return null;
+        }
+        String propertyName = propertyNameNode.name;
+        FieldElementImpl field = _currentHolder.getField(propertyName) as FieldElementImpl;
+        if (field == null) {
+          field = new FieldElementImpl.con2(node.name.name);
+          field.final2 = true;
+          _currentHolder.addField(field);
+        }
+        if (matches(property, sc.Keyword.GET)) {
+          PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con1(propertyNameNode);
+          getter.functions = holder.functions;
+          getter.labels = holder.labels;
+          getter.localVariables = holder.localVariables;
+          getter.variable = field;
+          getter.getter = true;
+          field.getter = getter;
+          _currentHolder.addAccessor(getter);
+          propertyNameNode.element = getter;
+        } else {
+          PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con1(propertyNameNode);
+          setter.functions = holder.functions;
+          setter.labels = holder.labels;
+          setter.localVariables = holder.localVariables;
+          setter.parameters = holder.parameters;
+          setter.variable = field;
+          setter.setter = true;
+          field.setter = setter;
+          field.final2 = false;
+          _currentHolder.addAccessor(setter);
+          propertyNameNode.element = setter;
+        }
+      }
+    }
     return null;
   }
   Object visitFunctionExpression(FunctionExpression node) {
     ElementHolder holder = new ElementHolder();
-    visitChildren(holder, node);
+    bool wasInFunction = _inFunction;
+    _inFunction = true;
+    try {
+      visitChildren(holder, node);
+    } finally {
+      _inFunction = wasInFunction;
+    }
     SimpleIdentifier functionName = null;
     FunctionElementImpl element = new FunctionElementImpl.con1(functionName);
     element.functions = holder.functions;
     element.labels = holder.labels;
-    element.localVariables = holder.variables;
+    element.localVariables = holder.localVariables;
     element.parameters = holder.parameters;
+    if (_inFunction) {
+      Block enclosingBlock = node.getAncestor(Block);
+      if (enclosingBlock != null) {
+        int functionEnd = node.offset + node.length;
+        int blockEnd = enclosingBlock.offset + enclosingBlock.length;
+        element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1);
+      }
+    }
     FunctionTypeImpl type = new FunctionTypeImpl.con1(element);
     element.type = type;
     _currentHolder.addFunction(element);
@@ -256,10 +343,12 @@
     visitChildren(holder, node);
     SimpleIdentifier aliasName = node.name;
     List<ParameterElement> parameters10 = holder.parameters;
-    TypeAliasElementImpl element = new TypeAliasElementImpl(aliasName);
+    List<TypeVariableElement> typeVariables6 = holder.typeVariables;
+    FunctionTypeAliasElementImpl element = new FunctionTypeAliasElementImpl(aliasName);
     element.parameters = parameters10;
-    element.typeVariables = holder.typeVariables;
+    element.typeVariables = typeVariables6;
     FunctionTypeImpl type = new FunctionTypeImpl.con2(element);
+    type.typeArguments = createTypeVariableTypes(typeVariables6);
     element.type = type;
     _currentHolder.addTypeAlias(element);
     aliasName.element = element;
@@ -284,56 +373,61 @@
       _currentHolder.addLabel(element);
       labelName.element = element;
     }
-    node.visitChildren(this);
-    return null;
+    return super.visitLabeledStatement(node);
   }
   Object visitMethodDeclaration(MethodDeclaration node) {
     ElementHolder holder = new ElementHolder();
-    visitChildren(holder, node);
-    Token property = node.propertyKeyword;
+    bool wasInFunction = _inFunction;
+    _inFunction = true;
+    try {
+      visitChildren(holder, node);
+    } finally {
+      _inFunction = wasInFunction;
+    }
+    sc.Token property = node.propertyKeyword;
     if (property == null) {
-      Identifier methodName = node.name;
+      SimpleIdentifier methodName = node.name;
       String nameOfMethod = methodName.name;
-      if (nameOfMethod == TokenType.MINUS.lexeme && node.parameters.parameters.length == 0) {
+      if (nameOfMethod == sc.TokenType.MINUS.lexeme && node.parameters.parameters.length == 0) {
         nameOfMethod = "unary-";
       }
       MethodElementImpl element = new MethodElementImpl.con2(nameOfMethod, methodName.offset);
-      Token keyword = node.modifierKeyword;
-      element.abstract = matches(keyword, Keyword.ABSTRACT);
+      sc.Token keyword = node.modifierKeyword;
+      element.abstract = matches(keyword, sc.Keyword.ABSTRACT);
       element.functions = holder.functions;
       element.labels = holder.labels;
-      element.localVariables = holder.variables;
+      element.localVariables = holder.localVariables;
       element.parameters = holder.parameters;
-      element.static = matches(keyword, Keyword.STATIC);
+      element.static = matches(keyword, sc.Keyword.STATIC);
       _currentHolder.addMethod(element);
       methodName.element = element;
     } else {
-      Identifier propertyNameNode = node.name;
+      SimpleIdentifier propertyNameNode = node.name;
       String propertyName = propertyNameNode.name;
-      FieldElementImpl field = (_currentHolder.getField(propertyName) as FieldElementImpl);
+      FieldElementImpl field = _currentHolder.getField(propertyName) as FieldElementImpl;
       if (field == null) {
         field = new FieldElementImpl.con2(node.name.name);
         field.final2 = true;
-        field.static = matches(node.modifierKeyword, Keyword.STATIC);
+        field.static = matches(node.modifierKeyword, sc.Keyword.STATIC);
         _currentHolder.addField(field);
       }
-      if (matches(property, Keyword.GET)) {
-        PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con2(propertyNameNode);
+      if (matches(property, sc.Keyword.GET)) {
+        PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con1(propertyNameNode);
         getter.functions = holder.functions;
         getter.labels = holder.labels;
-        getter.localVariables = holder.variables;
-        getter.field = field;
+        getter.localVariables = holder.localVariables;
+        getter.variable = field;
         getter.getter = true;
         field.getter = getter;
         _currentHolder.addAccessor(getter);
         propertyNameNode.element = getter;
       } else {
-        PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con2(propertyNameNode);
+        PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con1(propertyNameNode);
         setter.functions = holder.functions;
         setter.labels = holder.labels;
-        setter.localVariables = holder.variables;
+        setter.localVariables = holder.localVariables;
         setter.parameters = holder.parameters;
-        setter.field = field;
+        setter.variable = field;
         setter.setter = true;
         field.setter = setter;
         field.final2 = false;
@@ -347,14 +441,17 @@
     if (node.parent is! DefaultFormalParameter) {
       SimpleIdentifier parameterName = node.identifier;
       ParameterElementImpl parameter = new ParameterElementImpl(parameterName);
-      parameter.const2 = node.isConst();
+      parameter.const3 = node.isConst();
       parameter.final2 = node.isFinal();
       parameter.parameterKind = node.kind;
       _currentHolder.addParameter(parameter);
       parameterName.element = parameter;
     }
-    node.visitChildren(this);
-    return null;
+    return super.visitSimpleFormalParameter(node);
+  }
+  Object visitSuperExpression(SuperExpression node) {
+    _isValidMixin = false;
+    return super.visitSuperExpression(node);
   }
   Object visitSwitchCase(SwitchCase node) {
     for (Label label in node.labels) {
@@ -363,8 +460,7 @@
       _currentHolder.addLabel(element);
       labelName.element = element;
     }
-    node.visitChildren(this);
-    return null;
+    return super.visitSwitchCase(node);
   }
   Object visitSwitchDefault(SwitchDefault node) {
     for (Label label in node.labels) {
@@ -373,8 +469,7 @@
       _currentHolder.addLabel(element);
       labelName.element = element;
     }
-    node.visitChildren(this);
-    return null;
+    return super.visitSwitchDefault(node);
   }
   Object visitTypeParameter(TypeParameter node) {
     SimpleIdentifier parameterName = node.name;
@@ -383,58 +478,115 @@
     element.type = type;
     _currentHolder.addTypeVariable(element);
     parameterName.element = element;
-    node.visitChildren(this);
-    return null;
+    return super.visitTypeParameter(node);
   }
   Object visitVariableDeclaration(VariableDeclaration node) {
+    sc.Token keyword28 = ((node.parent as VariableDeclarationList)).keyword;
+    bool isConst = matches(keyword28, sc.Keyword.CONST);
+    bool isFinal = matches(keyword28, sc.Keyword.FINAL);
+    bool hasInitializer = node.initializer != null;
     VariableElementImpl element;
     if (_inFieldContext) {
       SimpleIdentifier fieldName = node.name;
-      FieldElementImpl field = new FieldElementImpl.con1(fieldName);
+      FieldElementImpl field;
+      if (isConst && hasInitializer) {
+        field = new ConstFieldElementImpl(fieldName);
+      } else {
+        field = new FieldElementImpl.con1(fieldName);
+      }
       element = field;
       _currentHolder.addField(field);
       fieldName.element = field;
+    } else if (_inFunction) {
+      SimpleIdentifier variableName = node.name;
+      LocalVariableElementImpl variable;
+      if (isConst && hasInitializer) {
+        variable = new ConstLocalVariableElementImpl(variableName);
+      } else {
+        variable = new LocalVariableElementImpl(variableName);
+      }
+      element = variable;
+      Block enclosingBlock = node.getAncestor(Block);
+      int functionEnd = node.offset + node.length;
+      int blockEnd = enclosingBlock.offset + enclosingBlock.length;
+      variable.setVisibleRange(functionEnd, blockEnd - functionEnd - 1);
+      _currentHolder.addLocalVariable(variable);
+      variableName.element = element;
     } else {
       SimpleIdentifier variableName = node.name;
-      element = new VariableElementImpl.con1(variableName);
-      _currentHolder.addVariable(element);
+      TopLevelVariableElementImpl variable;
+      if (isConst && hasInitializer) {
+        variable = new ConstTopLevelVariableElementImpl(variableName);
+      } else {
+        variable = new TopLevelVariableElementImpl.con1(variableName);
+      }
+      element = variable;
+      _currentHolder.addTopLevelVariable(variable);
       variableName.element = element;
     }
-    Token keyword26 = ((node.parent as VariableDeclarationList)).keyword;
-    bool isFinal = matches(keyword26, Keyword.FINAL);
-    element.const2 = matches(keyword26, Keyword.CONST);
+    element.const3 = isConst;
     element.final2 = isFinal;
-    if (node.initializer != null) {
+    if (hasInitializer) {
       ElementHolder holder = new ElementHolder();
       bool wasInFieldContext = _inFieldContext;
       _inFieldContext = false;
       try {
-        visitChildren(holder, node.initializer);
+        visit(holder, node.initializer);
       } finally {
         _inFieldContext = wasInFieldContext;
       }
       FunctionElementImpl initializer = new FunctionElementImpl();
       initializer.functions = holder.functions;
       initializer.labels = holder.labels;
-      initializer.localVariables = holder.variables;
+      initializer.localVariables = holder.localVariables;
       initializer.synthetic = true;
       element.initializer = initializer;
     }
-    if (_inFieldContext) {
-      FieldElementImpl field = (element as FieldElementImpl);
-      PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con1(field);
+    if (element is PropertyInducingElementImpl) {
+      PropertyInducingElementImpl variable = element as PropertyInducingElementImpl;
+      PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con2(variable);
       getter.getter = true;
       _currentHolder.addAccessor(getter);
-      field.getter = getter;
+      variable.getter = getter;
       if (!isFinal) {
-        PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con1(field);
+        PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con2(variable);
         setter.setter = true;
         _currentHolder.addAccessor(setter);
-        field.setter = setter;
+        variable.setter = setter;
       }
-      field.static = matches(((node.parent.parent as FieldDeclaration)).keyword, Keyword.STATIC);
+      if (_inFieldContext) {
+        ((variable as FieldElementImpl)).static = matches(((node.parent.parent as FieldDeclaration)).keyword, sc.Keyword.STATIC);
+      }
     }
-    node.visitChildren(this);
+    return super.visitVariableDeclaration(node);
+  }
+  List<Type2> createTypeVariableTypes(List<TypeVariableElement> typeVariables) {
+    int typeVariableCount = typeVariables.length;
+    List<Type2> typeArguments = new List<Type2>(typeVariableCount);
+    for (int i = 0; i < typeVariableCount; i++) {
+      TypeVariableElementImpl typeVariable = typeVariables[i] as TypeVariableElementImpl;
+      TypeVariableTypeImpl typeArgument = new TypeVariableTypeImpl(typeVariable);
+      typeVariable.type = typeArgument;
+      typeArguments[i] = typeArgument;
+    }
+    return typeArguments;
+  }
+  /**
+   * Return the body of the function that contains the given parameter, or {@code null} if no
+   * function body could be found.
+   * @param node the parameter contained in the function whose body is to be returned
+   * @return the body of the function that contains the given parameter
+   */
+  FunctionBody getFunctionBody(FormalParameter node) {
+    ASTNode parent13 = node.parent;
+    while (parent13 != null) {
+      if (parent13 is FunctionExpression) {
+        return ((parent13 as FunctionExpression)).body;
+      } else if (parent13 is MethodDeclaration) {
+        return ((parent13 as MethodDeclaration)).body;
+      }
+      parent13 = parent13.parent;
+    }
     return null;
   }
   /**
@@ -443,7 +595,23 @@
    * @param keyword the keyword being tested for
    * @return {@code true} if the given token is a token for the given keyword
    */
-  bool matches(Token token, Keyword keyword34) => token != null && identical(token.type, TokenType.KEYWORD) && identical(((token as KeywordToken)).keyword, keyword34);
+  bool matches(sc.Token token, sc.Keyword keyword36) => token != null && identical(token.type, sc.TokenType.KEYWORD) && identical(((token as sc.KeywordToken)).keyword, keyword36);
+  /**
+   * Make the given holder be the current holder while visiting the given node.
+   * @param holder the holder that will gather elements that are built while visiting the children
+   * @param node the node to be visited
+   */
+  void visit(ElementHolder holder, ASTNode node) {
+    if (node != null) {
+      ElementHolder previousHolder = _currentHolder;
+      _currentHolder = holder;
+      try {
+        node.accept(this);
+      } finally {
+        _currentHolder = previousHolder;
+      }
+    }
+  }
   /**
    * Make the given holder be the current holder while visiting the children of the given node.
    * @param holder the holder that will gather elements that are built while visiting the children
@@ -464,6 +632,7 @@
 /**
  * Instances of the class {@code ElementHolder} hold on to elements created while traversing an AST
  * structure so that they can be accessed when creating their enclosing element.
+ * @coverage dart.engine.resolver
  */
 class ElementHolder {
   List<PropertyAccessorElement> _accessors = new List<PropertyAccessorElement>();
@@ -471,12 +640,13 @@
   List<FieldElement> _fields = new List<FieldElement>();
   List<FunctionElement> _functions = new List<FunctionElement>();
   List<LabelElement> _labels = new List<LabelElement>();
+  List<VariableElement> _localVariables = new List<VariableElement>();
   List<MethodElement> _methods = new List<MethodElement>();
-  List<TypeAliasElement> _typeAliases = new List<TypeAliasElement>();
+  List<FunctionTypeAliasElement> _typeAliases = new List<FunctionTypeAliasElement>();
   List<ParameterElement> _parameters = new List<ParameterElement>();
+  List<VariableElement> _topLevelVariables = new List<VariableElement>();
   List<ClassElement> _types = new List<ClassElement>();
   List<TypeVariableElement> _typeVariables = new List<TypeVariableElement>();
-  List<VariableElement> _variables = new List<VariableElement>();
   /**
    * Initialize a newly created element holder.
    */
@@ -497,24 +667,27 @@
   void addLabel(LabelElement element) {
     _labels.add(element);
   }
+  void addLocalVariable(LocalVariableElement element) {
+    _localVariables.add(element);
+  }
   void addMethod(MethodElement element) {
     _methods.add(element);
   }
   void addParameter(ParameterElement element) {
     _parameters.add(element);
   }
+  void addTopLevelVariable(TopLevelVariableElement element) {
+    _topLevelVariables.add(element);
+  }
   void addType(ClassElement element) {
     _types.add(element);
   }
-  void addTypeAlias(TypeAliasElement element) {
+  void addTypeAlias(FunctionTypeAliasElement element) {
     _typeAliases.add(element);
   }
   void addTypeVariable(TypeVariableElement element) {
     _typeVariables.add(element);
   }
-  void addVariable(VariableElement element) {
-    _variables.add(element);
-  }
   List<PropertyAccessorElement> get accessors => new List.from(_accessors);
   List<ConstructorElement> get constructors => new List.from(_constructors);
   FieldElement getField(String fieldName) {
@@ -528,12 +701,147 @@
   List<FieldElement> get fields => new List.from(_fields);
   List<FunctionElement> get functions => new List.from(_functions);
   List<LabelElement> get labels => new List.from(_labels);
+  List<LocalVariableElement> get localVariables => new List.from(_localVariables);
   List<MethodElement> get methods => new List.from(_methods);
   List<ParameterElement> get parameters => new List.from(_parameters);
-  List<TypeAliasElement> get typeAliases => new List.from(_typeAliases);
+  List<TopLevelVariableElement> get topLevelVariables => new List.from(_topLevelVariables);
+  List<FunctionTypeAliasElement> get typeAliases => new List.from(_typeAliases);
   List<ClassElement> get types => new List.from(_types);
   List<TypeVariableElement> get typeVariables => new List.from(_typeVariables);
-  List<VariableElement> get variables => new List.from(_variables);
+}
+/**
+ * Instances of the class {@code HtmlUnitBuilder} build an element model for a single HTML unit.
+ */
+class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
+  static String _APPLICATION_DART_IN_DOUBLE_QUOTES = "\"application/dart\"";
+  static String _APPLICATION_DART_IN_SINGLE_QUOTES = "'application/dart'";
+  static String _SCRIPT = "script";
+  static String _SRC = "src";
+  static String _TYPE = "type";
+  /**
+   * The analysis context in which the element model will be built.
+   */
+  AnalysisContextImpl _context;
+  /**
+   * The HTML element being built.
+   */
+  HtmlElementImpl _htmlElement;
+  /**
+   * The script elements being built.
+   */
+  List<HtmlScriptElement> _scripts;
+  /**
+   * Initialize a newly created HTML unit builder.
+   * @param context the analysis context in which the element model will be built
+   */
+  HtmlUnitBuilder(AnalysisContextImpl context) {
+    this._context = context;
+  }
+  /**
+   * Build the HTML element for the given source.
+   * @param source the source describing the compilation unit
+   * @return the HTML element that was built
+   * @throws AnalysisException if the analysis could not be performed
+   */
+  HtmlElementImpl buildHtmlElement(Source source) => buildHtmlElement2(source, _context.parseHtml(source).htmlUnit);
+  /**
+   * Build the HTML element for the given source.
+   * @param source the source describing the compilation unit
+   * @param unit the AST structure representing the HTML
+   * @throws AnalysisException if the analysis could not be performed
+   */
+  HtmlElementImpl buildHtmlElement2(Source source14, ht.HtmlUnit unit) {
+    HtmlElementImpl result = new HtmlElementImpl(_context, source14.shortName);
+    result.source = source14;
+    _htmlElement = result;
+    unit.accept(this);
+    _htmlElement = null;
+    unit.element = result;
+    return result;
+  }
+  Object visitHtmlUnit(ht.HtmlUnit node) {
+    _scripts = new List<HtmlScriptElement>();
+    node.visitChildren(this);
+    _htmlElement.scripts = new List.from(_scripts);
+    _scripts = null;
+    return null;
+  }
+  Object visitXmlAttributeNode(ht.XmlAttributeNode node) => null;
+  Object visitXmlTagNode(ht.XmlTagNode node) {
+    if (isScriptNode(node)) {
+      Source htmlSource = _htmlElement.source;
+      String scriptSourcePath = getScriptSourcePath(node);
+      if (identical(node.attributeEnd.type, ht.TokenType.GT) && scriptSourcePath == null) {
+        EmbeddedHtmlScriptElementImpl script = new EmbeddedHtmlScriptElementImpl(node);
+        String contents = node.content;
+        AnalysisErrorListener errorListener = new AnalysisErrorListener_2();
+        sc.StringScanner scanner = new sc.StringScanner(null, contents, errorListener);
+        sc.Token firstToken = scanner.tokenize();
+        List<int> lineStarts2 = scanner.lineStarts;
+        Parser parser = new Parser(null, errorListener);
+        CompilationUnit unit = parser.parseCompilationUnit(firstToken);
+        try {
+          CompilationUnitBuilder builder = new CompilationUnitBuilder(_context, errorListener);
+          CompilationUnitElementImpl elem = builder.buildCompilationUnit2(htmlSource, unit);
+          LibraryElementImpl library = new LibraryElementImpl(_context, null);
+          library.definingCompilationUnit = elem;
+          script.scriptLibrary = library;
+        } on AnalysisException catch (e) {
+          print(e);
+        }
+        _scripts.add(script);
+      } else {
+        ExternalHtmlScriptElementImpl script = new ExternalHtmlScriptElementImpl(node);
+        if (scriptSourcePath != null) {
+          script.scriptSource = htmlSource.resolve(scriptSourcePath);
+        }
+        _scripts.add(script);
+      }
+    } else {
+      node.visitChildren(this);
+    }
+    return null;
+  }
+  /**
+   * Return the value of the source attribute if it exists.
+   * @param node the node containing attributes
+   * @return the source path or {@code null} if not defined
+   */
+  String getScriptSourcePath(ht.XmlTagNode node) {
+    for (ht.XmlAttributeNode attribute in node.attributes) {
+      if (attribute.name.lexeme == _SRC) {
+        String text2 = attribute.text;
+        return text2 != null && text2.length > 0 ? text2 : null;
+      }
+    }
+    return null;
+  }
+  /**
+   * Determine if the specified node is a Dart script.
+   * @param node the node to be tested (not {@code null})
+   * @return {@code true} if the node is a Dart script
+   */
+  bool isScriptNode(ht.XmlTagNode node) {
+    if (node.tagNodes.length != 0 || node.tag.lexeme != _SCRIPT) {
+      return false;
+    }
+    for (ht.XmlAttributeNode attribute in node.attributes) {
+      if (attribute.name.lexeme == _TYPE) {
+        ht.Token valueToken = attribute.value;
+        if (valueToken != null) {
+          String value = valueToken.lexeme;
+          if (value == _APPLICATION_DART_IN_DOUBLE_QUOTES || value == _APPLICATION_DART_IN_SINGLE_QUOTES) {
+            return true;
+          }
+        }
+      }
+    }
+    return false;
+  }
+}
+class AnalysisErrorListener_2 implements AnalysisErrorListener {
+  void onError(AnalysisError error) {
+  }
 }
 /**
  * Instances of the class {@code ElementResolver} are used by instances of {@link ResolverVisitor}to resolve references within the AST structure to the elements being referenced. The requirements
@@ -567,7 +875,7 @@
  * the case of a part-of directive, the specified library does not exist.</li>
  * <li>Every {@link ImportDirective} and {@link ExportDirective} should resolve to the element
  * representing the library being specified by the directive unless the specified library does not
- * exist (a {@link LibraryElement}).</li>
+ * exist (an {@link ImportElement} or {@link ExportElement}).</li>
  * <li>The identifier representing the prefix in an {@link ImportDirective} should resolve to the
  * element representing the prefix (a {@link PrefixElement}).</li>
  * <li>The identifiers in the hide and show combinators in {@link ImportDirective}s and{@link ExportDirective}s should resolve to the elements that are being hidden or shown,
@@ -580,6 +888,7 @@
  * anything. This includes such things as references to undeclared variables (which is an error) and
  * names in hide and show combinators that are not defined in the imported library (which is not an
  * error).
+ * @coverage dart.engine.resolver
  */
 class ElementResolver extends SimpleASTVisitor<Object> {
   /**
@@ -594,16 +903,16 @@
     this._resolver = resolver;
   }
   Object visitAssignmentExpression(AssignmentExpression node) {
-    TokenType operator7 = node.operator.type;
-    if (operator7 != TokenType.EQ) {
+    sc.TokenType operator7 = node.operator.type;
+    if (operator7 != sc.TokenType.EQ) {
       operator7 = operatorFromCompoundAssignment(operator7);
       Expression leftNode = node.leftHandSide;
       if (leftNode != null) {
-        Type2 leftType = leftNode.staticType;
+        Type2 leftType = getType(leftNode);
         if (leftType != null) {
           Element leftElement = leftType.element;
           if (leftElement != null) {
-            MethodElement method = lookUpMethod(leftElement, operator7.lexeme, 1, []);
+            MethodElement method = lookUpMethod(leftElement, operator7.lexeme);
             if (method != null) {
               node.element = method;
             } else {
@@ -615,11 +924,11 @@
     return null;
   }
   Object visitBinaryExpression(BinaryExpression node) {
-    Token operator8 = node.operator;
+    sc.Token operator8 = node.operator;
     if (operator8.isUserDefinableOperator()) {
       Type2 leftType = getType(node.leftOperand);
       Element leftTypeElement;
-      if (leftType == null) {
+      if (leftType == null || leftType.isDynamic()) {
         return null;
       } else if (leftType is FunctionType) {
         leftTypeElement = _resolver.typeProvider.functionType.element;
@@ -627,9 +936,9 @@
         leftTypeElement = leftType.element;
       }
       String methodName = operator8.lexeme;
-      MethodElement member = lookUpMethod(leftTypeElement, methodName, 1, []);
+      MethodElement member = lookUpMethod(leftTypeElement, methodName);
       if (member == null) {
-        _resolver.reportError2(ResolverErrorCode.CANNOT_BE_RESOLVED, operator8, [methodName]);
+        _resolver.reportError3(ResolverErrorCode.CANNOT_BE_RESOLVED, operator8, [methodName]);
       } else {
         node.element = member;
       }
@@ -645,11 +954,20 @@
     return null;
   }
   Object visitConstructorName(ConstructorName node) {
-    Type2 type10 = node.type.type;
-    if (type10 is! InterfaceType) {
+    Type2 type13 = node.type.type;
+    if (type13 is DynamicTypeImpl) {
+      return null;
+    } else if (type13 is! InterfaceType) {
+      ASTNode parent14 = node.parent;
+      if (parent14 is InstanceCreationExpression) {
+        if (((parent14 as InstanceCreationExpression)).isConst()) {
+        } else {
+        }
+      } else {
+      }
       return null;
     }
-    ClassElement classElement = ((type10 as InterfaceType)).element;
+    ClassElement classElement = ((type13 as InterfaceType)).element;
     ConstructorElement constructor;
     SimpleIdentifier name14 = node.name;
     if (name14 == null) {
@@ -669,6 +987,13 @@
     }
     return null;
   }
+  Object visitExportDirective(ExportDirective node) {
+    Element element22 = node.element;
+    if (element22 is ExportElement) {
+      resolveCombinators(((element22 as ExportElement)).exportedLibrary, node.combinators);
+    }
+    return null;
+  }
   Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) => null;
   Object visitImportDirective(ImportDirective node) {
     SimpleIdentifier prefixNode = node.prefix;
@@ -677,25 +1002,29 @@
       for (PrefixElement prefixElement in _resolver.definingLibrary.prefixes) {
         if (prefixElement.name == prefixName) {
           recordResolution(prefixNode, prefixElement);
+          break;
         }
-        return null;
       }
     }
+    Element element23 = node.element;
+    if (element23 is ImportElement) {
+      resolveCombinators(((element23 as ImportElement)).importedLibrary, node.combinators);
+    }
     return null;
   }
   Object visitIndexExpression(IndexExpression node) {
-    Type2 arrayType = getType(node.array);
-    if (arrayType == null) {
+    Type2 arrayType = getType(node.realTarget);
+    if (arrayType == null || arrayType.isDynamic()) {
       return null;
     }
     Element arrayTypeElement = arrayType.element;
     String operator;
     if (node.inSetterContext()) {
-      operator = TokenType.INDEX_EQ.lexeme;
+      operator = sc.TokenType.INDEX_EQ.lexeme;
     } else {
-      operator = TokenType.INDEX.lexeme;
+      operator = sc.TokenType.INDEX.lexeme;
     }
-    MethodElement member = lookUpMethod(arrayTypeElement, operator, 1, []);
+    MethodElement member = lookUpMethod(arrayTypeElement, operator);
     if (member == null) {
       _resolver.reportError(ResolverErrorCode.CANNOT_BE_RESOLVED, node, [operator]);
     } else {
@@ -704,38 +1033,59 @@
     return null;
   }
   Object visitInstanceCreationExpression(InstanceCreationExpression node) {
-    node.element = node.constructorName.element;
+    ConstructorElement invokedConstructor = node.constructorName.element;
+    node.element = invokedConstructor;
+    resolveNamedArguments(node.argumentList, invokedConstructor);
     return null;
   }
-  Object visitLibraryIdentifier(LibraryIdentifier node) => null;
   Object visitMethodInvocation(MethodInvocation node) {
     SimpleIdentifier methodName2 = node.methodName;
-    Expression target4 = node.target;
+    Expression target = node.realTarget;
     Element element;
-    if (target4 == null) {
+    if (target == null) {
       element = _resolver.nameScope.lookup(methodName2, _resolver.definingLibrary);
       if (element == null) {
-        element = lookUpMethod(_resolver.enclosingClass, methodName2.name, -1, []);
-      }
-    } else {
-      Type2 targetType = getType(target4);
-      if (targetType is InterfaceType) {
-        int parameterCount = 0;
-        List<String> parameterNames = new List<String>();
-        ArgumentList argumentList10 = node.argumentList;
-        for (Expression argument in argumentList10.arguments) {
-          if (argument is NamedExpression) {
-            parameterNames.add(((argument as NamedExpression)).name.label.name);
-          } else {
-            parameterCount++;
+        element = lookUpMethod(_resolver.enclosingClass, methodName2.name);
+        if (element == null) {
+          PropertyAccessorElement getter = lookUpGetter(_resolver.enclosingClass, methodName2.name);
+          if (getter != null) {
+            FunctionType getterType = getter.type;
+            if (getterType != null) {
+              Type2 returnType4 = getterType.returnType;
+              if (!isExecutableType(returnType4)) {
+                _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName2, [methodName2.name]);
+              }
+            }
+            recordResolution(methodName2, getter);
+            return null;
           }
         }
-        element = lookUpMethod(targetType.element, methodName2.name, parameterCount, new List.from(parameterNames));
-      } else if (target4 is SimpleIdentifier) {
-        Element targetElement = ((target4 as SimpleIdentifier)).element;
+      }
+    } else {
+      Type2 targetType = getType(target);
+      if (targetType is InterfaceType) {
+        element = lookUpMethod(targetType.element, methodName2.name);
+        if (element == null) {
+          ClassElement targetClass = targetType.element as ClassElement;
+          PropertyAccessorElement accessor = lookUpGetterInType(targetClass, methodName2.name);
+          if (accessor != null) {
+            Type2 returnType5 = accessor.type.returnType.substitute2(((targetType as InterfaceType)).typeArguments, TypeVariableTypeImpl.getTypes(targetClass.typeVariables));
+            if (!isExecutableType(returnType5)) {
+              _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName2, [methodName2.name]);
+              return null;
+            }
+            element = accessor;
+          }
+        }
+        if (element == null && target is SuperExpression) {
+          _resolver.reportError(StaticTypeWarningCode.UNDEFINED_SUPER_METHOD, methodName2, [methodName2.name, targetType.element.name]);
+          return null;
+        }
+      } else if (target is SimpleIdentifier) {
+        Element targetElement = ((target as SimpleIdentifier)).element;
         if (targetElement is PrefixElement) {
-          String name9 = "${((target4 as SimpleIdentifier)).name}.${methodName2}";
-          Identifier functionName = new Identifier_2(name9);
+          String name9 = "${((target as SimpleIdentifier)).name}.${methodName2}";
+          Identifier functionName = new Identifier_4(name9);
           element = _resolver.nameScope.lookup(functionName, _resolver.definingLibrary);
         } else {
           return null;
@@ -746,133 +1096,158 @@
     }
     ExecutableElement invokedMethod = null;
     if (element is ExecutableElement) {
-      invokedMethod = (element as ExecutableElement);
-    } else if (element is FieldElement) {
+      invokedMethod = element as ExecutableElement;
     } else {
-      return null;
-    }
-    if (invokedMethod == null) {
-      return null;
+      if (element is PropertyInducingElement) {
+        PropertyAccessorElement getter3 = ((element as PropertyInducingElement)).getter;
+        FunctionType getterType = getter3.type;
+        if (getterType != null) {
+          Type2 returnType6 = getterType.returnType;
+          if (!isExecutableType(returnType6)) {
+            _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName2, [methodName2.name]);
+          }
+        }
+        recordResolution(methodName2, element);
+        return null;
+      } else if (element is VariableElement) {
+        Type2 variableType = ((element as VariableElement)).type;
+        if (!isExecutableType(variableType)) {
+          _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName2, [methodName2.name]);
+        }
+        recordResolution(methodName2, element);
+        return null;
+      } else {
+        _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName2, [methodName2.name]);
+        return null;
+      }
     }
     recordResolution(methodName2, invokedMethod);
+    resolveNamedArguments(node.argumentList, invokedMethod);
     return null;
   }
   Object visitPostfixExpression(PostfixExpression node) {
-    Token operator9 = node.operator;
-    if (operator9.isUserDefinableOperator()) {
-      Type2 operandType = getType(node.operand);
-      if (operandType == null) {
-        return null;
-      }
-      Element operandTypeElement = operandType.element;
-      String methodName;
-      if (identical(operator9.type, TokenType.PLUS_PLUS)) {
-        methodName = TokenType.PLUS.lexeme;
-      } else {
-        methodName = TokenType.MINUS.lexeme;
-      }
-      MethodElement member = lookUpMethod(operandTypeElement, methodName, 1, []);
-      if (member == null) {
-        _resolver.reportError2(ResolverErrorCode.CANNOT_BE_RESOLVED, operator9, [methodName]);
-      } else {
-        node.element = member;
-      }
+    sc.Token operator9 = node.operator;
+    Type2 operandType = getType(node.operand);
+    if (operandType == null || operandType.isDynamic()) {
+      return null;
+    }
+    Element operandTypeElement = operandType.element;
+    String methodName;
+    if (identical(operator9.type, sc.TokenType.PLUS_PLUS)) {
+      methodName = sc.TokenType.PLUS.lexeme;
+    } else {
+      methodName = sc.TokenType.MINUS.lexeme;
+    }
+    MethodElement member = lookUpMethod(operandTypeElement, methodName);
+    if (member == null) {
+      _resolver.reportError3(ResolverErrorCode.CANNOT_BE_RESOLVED, operator9, [methodName]);
+    } else {
+      node.element = member;
     }
     return null;
   }
   Object visitPrefixedIdentifier(PrefixedIdentifier node) {
-    SimpleIdentifier prefix5 = node.prefix;
-    SimpleIdentifier identifier10 = node.identifier;
-    Element prefixElement = prefix5.element;
+    SimpleIdentifier prefix6 = node.prefix;
+    SimpleIdentifier identifier13 = node.identifier;
+    Element prefixElement = prefix6.element;
     if (prefixElement is PrefixElement) {
       Element element = _resolver.nameScope.lookup(node, _resolver.definingLibrary);
       if (element == null) {
         return null;
       }
-      recordResolution(identifier10, element);
-      recordResolution(node, element);
+      recordResolution(identifier13, element);
       return null;
     }
     if (prefixElement is ClassElement) {
       Element memberElement;
       if (node.identifier.inSetterContext()) {
-        memberElement = lookUpSetterInType((prefixElement as ClassElement), identifier10.name);
+        memberElement = lookUpSetterInType((prefixElement as ClassElement), identifier13.name);
       } else {
-        memberElement = lookUpGetterInType((prefixElement as ClassElement), identifier10.name);
+        memberElement = lookUpGetterInType((prefixElement as ClassElement), identifier13.name);
       }
       if (memberElement == null) {
-        MethodElement methodElement = lookUpMethod(prefixElement, identifier10.name, -1, []);
+        MethodElement methodElement = lookUpMethod(prefixElement, identifier13.name);
         if (methodElement != null) {
-          recordResolution(identifier10, methodElement);
-          recordResolution(node, methodElement);
+          recordResolution(identifier13, methodElement);
           return null;
         }
       }
       if (memberElement == null) {
-        _resolver.reportError(ResolverErrorCode.CANNOT_BE_RESOLVED, identifier10, [identifier10.name]);
+        reportGetterOrSetterNotFound(node, identifier13, prefixElement.name);
       } else {
-        recordResolution(identifier10, memberElement);
-        recordResolution(node, memberElement);
+        recordResolution(identifier13, memberElement);
       }
       return null;
     }
-    Element variableType;
+    Element variableTypeElement;
     if (prefixElement is PropertyAccessorElement) {
-      PropertyAccessorElement accessor = (prefixElement as PropertyAccessorElement);
-      if (accessor.isGetter()) {
-        variableType = accessor.type.returnType.element;
-      } else {
-        variableType = accessor.type.normalParameterTypes[0].element;
+      PropertyAccessorElement accessor = prefixElement as PropertyAccessorElement;
+      FunctionType type14 = accessor.type;
+      if (type14 == null) {
+        return null;
       }
+      Type2 variableType;
+      if (accessor.isGetter()) {
+        variableType = type14.returnType;
+      } else {
+        variableType = type14.normalParameterTypes[0];
+      }
+      if (variableType == null || variableType.isDynamic()) {
+        return null;
+      }
+      variableTypeElement = variableType.element;
     } else if (prefixElement is VariableElement) {
-      variableType = ((prefixElement as VariableElement)).type.element;
+      Type2 prefixType = ((prefixElement as VariableElement)).type;
+      if (prefixType == null || prefixType.isDynamic()) {
+        return null;
+      }
+      variableTypeElement = prefixType.element;
     } else {
       return null;
     }
-    PropertyAccessorElement memberElement;
-    if (node.identifier.inGetterContext()) {
-      memberElement = lookUpGetter(variableType, identifier10.name);
-    } else {
-      memberElement = lookUpSetter(variableType, identifier10.name);
+    PropertyAccessorElement memberElement = null;
+    if (node.identifier.inSetterContext()) {
+      memberElement = lookUpSetter(variableTypeElement, identifier13.name);
+    }
+    if (memberElement == null && node.identifier.inGetterContext()) {
+      memberElement = lookUpGetter(variableTypeElement, identifier13.name);
     }
     if (memberElement == null) {
-      MethodElement methodElement = lookUpMethod(variableType, identifier10.name, -1, []);
+      MethodElement methodElement = lookUpMethod(variableTypeElement, identifier13.name);
       if (methodElement != null) {
-        recordResolution(identifier10, methodElement);
-        recordResolution(node, methodElement);
+        recordResolution(identifier13, methodElement);
         return null;
       }
     }
     if (memberElement == null) {
-      _resolver.reportError(ResolverErrorCode.CANNOT_BE_RESOLVED, identifier10, [identifier10.name]);
+      reportGetterOrSetterNotFound(node, identifier13, variableTypeElement.name);
     } else {
-      recordResolution(identifier10, memberElement);
-      recordResolution(node, memberElement);
+      recordResolution(identifier13, memberElement);
     }
     return null;
   }
   Object visitPrefixExpression(PrefixExpression node) {
-    Token operator10 = node.operator;
-    TokenType operatorType = operator10.type;
-    if (operatorType.isUserDefinableOperator() || identical(operatorType, TokenType.PLUS_PLUS) || identical(operatorType, TokenType.MINUS_MINUS)) {
+    sc.Token operator10 = node.operator;
+    sc.TokenType operatorType = operator10.type;
+    if (operatorType.isUserDefinableOperator() || identical(operatorType, sc.TokenType.PLUS_PLUS) || identical(operatorType, sc.TokenType.MINUS_MINUS)) {
       Type2 operandType = getType(node.operand);
-      if (operandType == null) {
+      if (operandType == null || operandType.isDynamic()) {
         return null;
       }
       Element operandTypeElement = operandType.element;
       String methodName;
-      if (identical(operatorType, TokenType.PLUS_PLUS)) {
-        methodName = TokenType.PLUS.lexeme;
-      } else if (identical(operatorType, TokenType.MINUS_MINUS)) {
-        methodName = TokenType.MINUS.lexeme;
-      } else if (identical(operatorType, TokenType.MINUS)) {
+      if (identical(operatorType, sc.TokenType.PLUS_PLUS)) {
+        methodName = sc.TokenType.PLUS.lexeme;
+      } else if (identical(operatorType, sc.TokenType.MINUS_MINUS)) {
+        methodName = sc.TokenType.MINUS.lexeme;
+      } else if (identical(operatorType, sc.TokenType.MINUS)) {
         methodName = "unary-";
       } else {
         methodName = operator10.lexeme;
       }
-      MethodElement member = lookUpMethod(operandTypeElement, methodName, 1, []);
+      MethodElement member = lookUpMethod(operandTypeElement, methodName);
       if (member == null) {
-        _resolver.reportError2(ResolverErrorCode.CANNOT_BE_RESOLVED, operator10, [methodName]);
+        _resolver.reportError3(ResolverErrorCode.CANNOT_BE_RESOLVED, operator10, [methodName]);
       } else {
         node.element = member;
       }
@@ -886,14 +1261,15 @@
     }
     ClassElement targetElement = ((targetType as InterfaceType)).element;
     SimpleIdentifier identifier = node.propertyName;
-    PropertyAccessorElement memberElement;
+    PropertyAccessorElement memberElement = null;
     if (identifier.inSetterContext()) {
       memberElement = lookUpSetter(targetElement, identifier.name);
-    } else {
+    }
+    if (memberElement == null && identifier.inGetterContext()) {
       memberElement = lookUpGetter(targetElement, identifier.name);
     }
     if (memberElement == null) {
-      MethodElement methodElement = lookUpMethod(targetElement, identifier.name, -1, []);
+      MethodElement methodElement = lookUpMethod(targetElement, identifier.name);
       if (methodElement != null) {
         recordResolution(identifier, methodElement);
         return null;
@@ -925,6 +1301,7 @@
       recordResolution(name, element);
     }
     node.element = element;
+    resolveNamedArguments(node.argumentList, element);
     return null;
   }
   Object visitSimpleIdentifier(SimpleIdentifier node) {
@@ -932,15 +1309,23 @@
       return null;
     }
     Element element = _resolver.nameScope.lookup(node, _resolver.definingLibrary);
-    if (element == null) {
-      if (node.inGetterContext()) {
-        element = lookUpGetter(_resolver.enclosingClass, node.name);
-      } else {
-        element = lookUpSetter(_resolver.enclosingClass, node.name);
+    if (element is PropertyAccessorElement && node.inSetterContext()) {
+      PropertyInducingElement variable4 = ((element as PropertyAccessorElement)).variable;
+      if (variable4 != null) {
+        PropertyAccessorElement setter3 = variable4.setter;
+        if (setter3 != null) {
+          element = setter3;
+        }
       }
     }
+    if (element == null && node.inSetterContext()) {
+      element = lookUpSetter(_resolver.enclosingClass, node.name);
+    }
+    if (element == null && node.inGetterContext()) {
+      element = lookUpGetter(_resolver.enclosingClass, node.name);
+    }
     if (element == null) {
-      element = lookUpMethod(_resolver.enclosingClass, node.name, -1, []);
+      element = lookUpMethod(_resolver.enclosingClass, node.name);
     }
     if (element == null) {
     }
@@ -970,6 +1355,35 @@
       recordResolution(name, element);
     }
     node.element = element;
+    resolveNamedArguments(node.argumentList, element);
+    return null;
+  }
+  Object visitTypeParameter(TypeParameter node) {
+    TypeName bound3 = node.bound;
+    if (bound3 != null) {
+      TypeVariableElementImpl variable = node.name.element as TypeVariableElementImpl;
+      if (variable != null) {
+        variable.bound = bound3.type;
+      }
+    }
+    return null;
+  }
+  /**
+   * Search through the array of parameters for a parameter whose name matches the given name.
+   * Return the parameter with the given name, or {@code null} if there is no such parameter.
+   * @param parameters the parameters being searched
+   * @param name the name being searched for
+   * @return the parameter with the given name
+   */
+  ParameterElement findNamedParameter(List<ParameterElement> parameters, String name25) {
+    for (ParameterElement parameter in parameters) {
+      if (identical(parameter.parameterKind, ParameterKind.NAMED)) {
+        String parameteName = parameter.name;
+        if (parameteName != null && parameteName == name25) {
+          return parameter;
+        }
+      }
+    }
     return null;
   }
   /**
@@ -989,7 +1403,19 @@
    * @param expression the expression whose type is to be returned
    * @return the type of the given expression
    */
-  Type2 getType(Expression expression) => expression.staticType;
+  Type2 getType(Expression expression) {
+    if (expression is NullLiteral) {
+      return _resolver.typeProvider.objectType;
+    }
+    return expression.staticType;
+  }
+  /**
+   * Return {@code true} if the given type represents an object that could be invoked using the call
+   * operator '()'.
+   * @param type the type being tested
+   * @return {@code true} if the given type represents an object that could be invoked
+   */
+  bool isExecutableType(Type2 type) => type.isDynamic() || (type is FunctionType) || type.isDartCoreFunction();
   /**
    * Look up the getter with the given name in the given type. Return the element representing the
    * getter that was found, or {@code null} if there is no getter with the given name.
@@ -1003,7 +1429,7 @@
     }
     element = resolveTypeVariable(element);
     if (element is ClassElement) {
-      ClassElement classElement = (element as ClassElement);
+      ClassElement classElement = element as ClassElement;
       PropertyAccessorElement member = classElement.lookUpGetter(getterName, _resolver.definingLibrary);
       if (member != null) {
         return member;
@@ -1070,17 +1496,18 @@
     if (labelNode == null) {
       if (labelScope2 == null) {
       } else {
-        labelElement = (labelScope2.lookup2(LabelScope.EMPTY_LABEL) as LabelElementImpl);
+        labelElement = labelScope2.lookup2(LabelScope.EMPTY_LABEL) as LabelElementImpl;
         if (labelElement == null) {
         }
+        labelElement = null;
       }
     } else {
       if (labelScope2 == null) {
-        _resolver.reportError(ResolverErrorCode.UNDEFINED_LABEL, labelNode, [labelNode.name]);
+        _resolver.reportError(CompileTimeErrorCode.LABEL_UNDEFINED, labelNode, [labelNode.name]);
       } else {
-        labelElement = (labelScope2.lookup(labelNode) as LabelElementImpl);
+        labelElement = labelScope2.lookup(labelNode) as LabelElementImpl;
         if (labelElement == null) {
-          _resolver.reportError(ResolverErrorCode.UNDEFINED_LABEL, labelNode, [labelNode.name]);
+          _resolver.reportError(CompileTimeErrorCode.LABEL_UNDEFINED, labelNode, [labelNode.name]);
         } else {
           recordResolution(labelNode, labelElement);
         }
@@ -1089,11 +1516,7 @@
     if (labelElement != null) {
       ExecutableElement labelContainer = labelElement.getAncestor(ExecutableElement);
       if (labelContainer != _resolver.enclosingFunction) {
-        if (labelNode == null) {
-          _resolver.reportError(ResolverErrorCode.LABEL_IN_OUTER_SCOPE, parentNode, [""]);
-        } else {
-          _resolver.reportError(ResolverErrorCode.LABEL_IN_OUTER_SCOPE, labelNode, [labelNode.name]);
-        }
+        _resolver.reportError(CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE, labelNode, [labelNode.name]);
         labelElement = null;
       }
     }
@@ -1106,13 +1529,13 @@
    * @param methodName the name of the method being looked up
    * @return the element representing the method that was found
    */
-  MethodElement lookUpMethod(Element element, String methodName, int parameterCount, List<String> parameterNames) {
+  MethodElement lookUpMethod(Element element, String methodName) {
     if (identical(element, DynamicTypeImpl.instance)) {
       return null;
     }
     element = resolveTypeVariable(element);
     if (element is ClassElement) {
-      ClassElement classElement = (element as ClassElement);
+      ClassElement classElement = element as ClassElement;
       MethodElement member = classElement.lookUpMethod(methodName, _resolver.definingLibrary);
       if (member != null) {
         return member;
@@ -1180,7 +1603,7 @@
     }
     element = resolveTypeVariable(element);
     if (element is ClassElement) {
-      ClassElement classElement = (element as ClassElement);
+      ClassElement classElement = element as ClassElement;
       PropertyAccessorElement member = classElement.lookUpSetter(setterName, _resolver.definingLibrary);
       if (member != null) {
         return member;
@@ -1240,29 +1663,32 @@
    * @param operator the assignment operator being mapped
    * @return the binary operator that invoked by the given assignment operator
    */
-  TokenType operatorFromCompoundAssignment(TokenType operator) {
-    if (operator == TokenType.AMPERSAND_EQ) {
-      return TokenType.AMPERSAND;
-    } else if (operator == TokenType.BAR_EQ) {
-      return TokenType.BAR;
-    } else if (operator == TokenType.CARET_EQ) {
-      return TokenType.CARET;
-    } else if (operator == TokenType.GT_GT_EQ) {
-      return TokenType.GT_GT;
-    } else if (operator == TokenType.LT_LT_EQ) {
-      return TokenType.LT_LT;
-    } else if (operator == TokenType.MINUS_EQ) {
-      return TokenType.MINUS;
-    } else if (operator == TokenType.PERCENT_EQ) {
-      return TokenType.PERCENT;
-    } else if (operator == TokenType.PLUS_EQ) {
-      return TokenType.PLUS;
-    } else if (operator == TokenType.SLASH_EQ) {
-      return TokenType.SLASH;
-    } else if (operator == TokenType.STAR_EQ) {
-      return TokenType.STAR;
-    } else if (operator == TokenType.TILDE_SLASH_EQ) {
-      return TokenType.TILDE_SLASH;
+  sc.TokenType operatorFromCompoundAssignment(sc.TokenType operator) {
+    while (true) {
+      if (operator == sc.TokenType.AMPERSAND_EQ) {
+        return sc.TokenType.AMPERSAND;
+      } else if (operator == sc.TokenType.BAR_EQ) {
+        return sc.TokenType.BAR;
+      } else if (operator == sc.TokenType.CARET_EQ) {
+        return sc.TokenType.CARET;
+      } else if (operator == sc.TokenType.GT_GT_EQ) {
+        return sc.TokenType.GT_GT;
+      } else if (operator == sc.TokenType.LT_LT_EQ) {
+        return sc.TokenType.LT_LT;
+      } else if (operator == sc.TokenType.MINUS_EQ) {
+        return sc.TokenType.MINUS;
+      } else if (operator == sc.TokenType.PERCENT_EQ) {
+        return sc.TokenType.PERCENT;
+      } else if (operator == sc.TokenType.PLUS_EQ) {
+        return sc.TokenType.PLUS;
+      } else if (operator == sc.TokenType.SLASH_EQ) {
+        return sc.TokenType.SLASH;
+      } else if (operator == sc.TokenType.STAR_EQ) {
+        return sc.TokenType.STAR;
+      } else if (operator == sc.TokenType.TILDE_SLASH_EQ) {
+        return sc.TokenType.TILDE_SLASH;
+      }
+      break;
     }
     AnalysisEngine.instance.logger.logError("Failed to map ${operator.lexeme} to it's corresponding operator");
     return operator;
@@ -1272,9 +1698,69 @@
    * @param node the AST node that was resolved
    * @param element the element to which the AST node was resolved
    */
-  void recordResolution(Identifier node, Element element39) {
-    if (element39 != null) {
-      node.element = element39;
+  void recordResolution(SimpleIdentifier node, Element element52) {
+    if (element52 != null) {
+      node.element = element52;
+    }
+  }
+  /**
+   * Report the {@link StaticTypeWarningCode}s <code>UNDEFINED_SETTER</code> and
+   * <code>UNDEFINED_GETTER</code>.
+   * @param node the prefixed identifier that gives the context to determine if the error on the
+   * undefined identifier is a getter or a setter
+   * @param identifier the identifier in the passed prefix identifier
+   * @param typeName the name of the type of the left hand side of the passed prefixed identifier
+   */
+  void reportGetterOrSetterNotFound(PrefixedIdentifier node, SimpleIdentifier identifier30, String typeName) {
+    bool isSetterContext = node.identifier.inSetterContext();
+    ErrorCode errorCode = isSetterContext ? StaticTypeWarningCode.UNDEFINED_SETTER : StaticTypeWarningCode.UNDEFINED_GETTER;
+    _resolver.reportError(errorCode, identifier30, [identifier30.name, typeName]);
+  }
+  /**
+   * Resolve the names in the given combinators in the scope of the given library.
+   * @param library the library that defines the names
+   * @param combinators the combinators containing the names to be resolved
+   */
+  void resolveCombinators(LibraryElement library, NodeList<Combinator> combinators) {
+    if (library == null) {
+      return;
+    }
+    Namespace namespace = new NamespaceBuilder().createExportNamespace(library);
+    for (Combinator combinator in combinators) {
+      NodeList<SimpleIdentifier> names;
+      if (combinator is HideCombinator) {
+        names = ((combinator as HideCombinator)).hiddenNames;
+      } else {
+        names = ((combinator as ShowCombinator)).shownNames;
+      }
+      for (SimpleIdentifier name in names) {
+        Element element = namespace.get(name.name);
+        if (element != null) {
+          name.element = element;
+        }
+      }
+    }
+  }
+  /**
+   * Resolve the names associated with any named arguments to the parameter elements named by the
+   * argument.
+   * @param argumentList the arguments to be resolved
+   * @param invokedMethod the method or function defining the parameters to which the named
+   * arguments are to be resolved
+   */
+  void resolveNamedArguments(ArgumentList argumentList, ExecutableElement invokedMethod) {
+    if (invokedMethod == null) {
+      return;
+    }
+    List<ParameterElement> parameters11 = invokedMethod.parameters;
+    for (Expression argument in argumentList.arguments) {
+      if (argument is NamedExpression) {
+        SimpleIdentifier name15 = ((argument as NamedExpression)).name.label;
+        ParameterElement parameter = findNamedParameter(parameters11, name15.name);
+        if (parameter != null) {
+          recordResolution(name15, parameter);
+        }
+      }
     }
   }
   /**
@@ -1284,23 +1770,24 @@
    * @return the class that should be used in place of the argument if it is a type variable, or the
    * original argument if it isn't a type variable
    */
-  Element resolveTypeVariable(Element element40) {
-    if (element40 is TypeVariableElement) {
-      Type2 bound3 = ((element40 as TypeVariableElement)).bound;
-      if (bound3 == null) {
+  Element resolveTypeVariable(Element element53) {
+    if (element53 is TypeVariableElement) {
+      Type2 bound4 = ((element53 as TypeVariableElement)).bound;
+      if (bound4 == null) {
         return _resolver.typeProvider.objectType.element;
       }
-      return bound3.element;
+      return bound4.element;
     }
-    return element40;
+    return element53;
   }
 }
-class Identifier_2 extends Identifier {
+class Identifier_4 extends Identifier {
   String name9;
-  Identifier_2(this.name9) : super();
+  Identifier_4(this.name9) : super();
   accept(ASTVisitor visitor) => null;
-  Token get beginToken => null;
-  Token get endToken => null;
+  sc.Token get beginToken => null;
+  Element get element => null;
+  sc.Token get endToken => null;
   String get name => name9;
   void visitChildren(ASTVisitor<Object> visitor) {
   }
@@ -1309,6 +1796,7 @@
  * Instances of the class {@code Library} represent the data about a single library during the
  * resolution of some (possibly different) library. They are not intended to be used except during
  * the resolution process.
+ * @coverage dart.engine.resolver
  */
 class Library {
   /**
@@ -1358,7 +1846,7 @@
     this._analysisContext = analysisContext;
     this._errorListener = errorListener;
     this._librarySource = librarySource;
-    this._libraryElement = (analysisContext.getLibraryElementOrNull(librarySource) as LibraryElementImpl);
+    this._libraryElement = analysisContext.getLibraryElementOrNull(librarySource) as LibraryElementImpl;
   }
   /**
    * Record that the given library is exported from this library.
@@ -1383,7 +1871,7 @@
   CompilationUnit getAST(Source source) {
     CompilationUnit unit = _astMap[source];
     if (unit == null) {
-      unit = _analysisContext.parse2(source, _errorListener);
+      unit = _analysisContext.parse3(source, _errorListener);
       _astMap[source] = unit;
     }
     return unit;
@@ -1452,7 +1940,7 @@
    */
   LibraryElementImpl get libraryElement {
     if (_libraryElement == null) {
-      _libraryElement = (_analysisContext.getLibraryElement(_librarySource) as LibraryElementImpl);
+      _libraryElement = _analysisContext.getLibraryElement(_librarySource) as LibraryElementImpl;
     }
     return _libraryElement;
   }
@@ -1477,7 +1965,13 @@
    * @param uriLiteral the string literal specifying the URI to be resolved
    * @return the result of resolving the given URI against the URI of the library
    */
-  Source getSource(StringLiteral uriLiteral) => getSource2(getStringValue(uriLiteral), uriLiteral.offset, uriLiteral.length);
+  Source getSource(StringLiteral uriLiteral) {
+    if (uriLiteral is StringInterpolation) {
+      _errorListener.onError(new AnalysisError.con2(_librarySource, uriLiteral.offset, uriLiteral.length, CompileTimeErrorCode.URI_WITH_INTERPOLATION, []));
+      return null;
+    }
+    return getSource2(getStringValue(uriLiteral));
+  }
   /**
    * Set whether this library explicitly imports core to match the given value.
    * @param explicitlyImportsCore {@code true} if this library explicitly imports core
@@ -1500,9 +1994,9 @@
    * @throws IllegalArgumentException if the string is not a constant string without any string
    * interpolation
    */
-  void appendStringValue(StringBuffer builder, StringLiteral literal) {
+  void appendStringValue(JavaStringBuilder builder, StringLiteral literal) {
     if (literal is SimpleStringLiteral) {
-      builder.add(((literal as SimpleStringLiteral)).value);
+      builder.append(((literal as SimpleStringLiteral)).value);
     } else if (literal is AdjacentStrings) {
       for (StringLiteral stringLiteral in ((literal as AdjacentStrings)).strings) {
         appendStringValue(builder, stringLiteral);
@@ -1513,15 +2007,12 @@
   }
   /**
    * Return the result of resolving the given URI against the URI of the library, or {@code null} if
-   * the URI is not valid. If the URI is not valid, report the error.
+   * the URI is not valid.
    * @param uri the URI to be resolved
-   * @param uriOffset the offset of the string literal representing the URI
-   * @param uriLength the length of the string literal representing the URI
    * @return the result of resolving the given URI against the URI of the library
    */
-  Source getSource2(String uri, int uriOffset, int uriLength) {
+  Source getSource2(String uri) {
     if (uri == null) {
-      _errorListener.onError(new AnalysisError.con2(_librarySource, uriOffset, uriLength, ResolverErrorCode.INVALID_URI, []));
       return null;
     }
     return _librarySource.resolve(uri);
@@ -1533,17 +2024,18 @@
    * @return the value of the given string literal
    */
   String getStringValue(StringLiteral literal) {
-    StringBuffer builder = new StringBuffer();
+    JavaStringBuilder builder = new JavaStringBuilder();
     try {
       appendStringValue(builder, literal);
     } on IllegalArgumentException catch (exception) {
       return null;
     }
-    return builder.toString();
+    return builder.toString().trim();
   }
 }
 /**
  * Instances of the class {@code LibraryElementBuilder} build an element model for a single library.
+ * @coverage dart.engine.resolver
  */
 class LibraryElementBuilder {
   /**
@@ -1585,8 +2077,6 @@
     LibraryIdentifier libraryNameNode = null;
     bool hasPartDirective = false;
     FunctionElement entryPoint = findEntryPoint(definingCompilationUnitElement);
-    List<ImportElement> imports = new List<ImportElement>();
-    List<ExportElement> exports = new List<ExportElement>();
     List<Directive> directivesToResolve = new List<Directive>();
     List<CompilationUnitElementImpl> sourcedCompilationUnits = new List<CompilationUnitElementImpl>();
     for (Directive directive in directives3) {
@@ -1606,7 +2096,7 @@
             _errorListener.onError(new AnalysisError.con2(librarySource2, partUri.offset, partUri.length, ResolverErrorCode.MISSING_PART_OF_DIRECTIVE, []));
           } else if (libraryNameNode == null) {
           } else if (libraryNameNode.name != partLibraryName) {
-            _errorListener.onError(new AnalysisError.con2(librarySource2, partUri.offset, partUri.length, ResolverErrorCode.PART_WITH_WRONG_LIBRARY_NAME, [partLibraryName]));
+            _errorListener.onError(new AnalysisError.con2(librarySource2, partUri.offset, partUri.length, StaticWarningCode.PART_OF_DIFFERENT_LIBRARY, [libraryNameNode.name, partLibraryName]));
           }
           if (entryPoint == null) {
             entryPoint = findEntryPoint(part);
@@ -1624,8 +2114,6 @@
     if (entryPoint != null) {
       libraryElement.entryPoint = entryPoint;
     }
-    libraryElement.imports = new List.from(imports);
-    libraryElement.exports = new List.from(exports);
     libraryElement.parts = new List.from(sourcedCompilationUnits);
     for (Directive directive in directivesToResolve) {
       directive.element = libraryElement;
@@ -1675,6 +2163,7 @@
 /**
  * Instances of the class {@code LibraryResolver} are used to resolve one or more mutually dependent
  * libraries within a single context.
+ * @coverage dart.engine.resolver
  */
 class LibraryResolver {
   /**
@@ -1682,10 +2171,17 @@
    */
   AnalysisContextImpl _analysisContext;
   /**
-   * The listener to which analysis errors will be reported.
+   * The listener to which analysis errors will be reported, this error listener is either
+   * references {@link #recordingErrorListener}, or it unions the passed{@link AnalysisErrorListener} with the {@link #recordingErrorListener}.
    */
   AnalysisErrorListener _errorListener;
   /**
+   * This error listener is used by the resolver to be able to call the listener and get back the
+   * set of errors for each {@link Source}.
+   * @see #recordErrors()
+   */
+  RecordingErrorListener _recordingErrorListener;
+  /**
    * A source object representing the core library (dart:core).
    */
   Source _coreLibrarySource;
@@ -1708,12 +2204,30 @@
   /**
    * Initialize a newly created library resolver to resolve libraries within the given context.
    * @param analysisContext the analysis context in which the library is being analyzed
+   */
+  LibraryResolver.con1(AnalysisContextImpl analysisContext) {
+    _jtd_constructor_237_impl(analysisContext);
+  }
+  _jtd_constructor_237_impl(AnalysisContextImpl analysisContext) {
+    _jtd_constructor_238_impl(analysisContext, null);
+  }
+  /**
+   * Initialize a newly created library resolver to resolve libraries within the given context.
+   * @param analysisContext the analysis context in which the library is being analyzed
    * @param errorListener the listener to which analysis errors will be reported
    */
-  LibraryResolver(AnalysisContextImpl analysisContext, AnalysisErrorListener errorListener) {
-    this._analysisContext = analysisContext;
-    this._errorListener = errorListener;
-    _coreLibrarySource = analysisContext.sourceFactory.forUri(LibraryElementBuilder.CORE_LIBRARY_URI);
+  LibraryResolver.con2(AnalysisContextImpl analysisContext2, AnalysisErrorListener additionalAnalysisErrorListener) {
+    _jtd_constructor_238_impl(analysisContext2, additionalAnalysisErrorListener);
+  }
+  _jtd_constructor_238_impl(AnalysisContextImpl analysisContext2, AnalysisErrorListener additionalAnalysisErrorListener) {
+    this._analysisContext = analysisContext2;
+    this._recordingErrorListener = new RecordingErrorListener();
+    if (additionalAnalysisErrorListener == null) {
+      this._errorListener = _recordingErrorListener;
+    } else {
+      this._errorListener = new AnalysisErrorListener_5(this, additionalAnalysisErrorListener);
+    }
+    _coreLibrarySource = analysisContext2.sourceFactory.forUri(LibraryElementBuilder.CORE_LIBRARY_URI);
   }
   /**
    * Return the analysis context in which the libraries are being analyzed.
@@ -1751,8 +2265,10 @@
     buildTypeHierarchies();
     resolveReferencesAndTypes();
     if (fullAnalysis) {
+      runAdditionalAnalyses();
     }
     recordLibraryElements();
+    recordErrors();
     return targetLibrary.libraryElement;
   }
   /**
@@ -1840,36 +2356,41 @@
       List<ExportElement> exports = new List<ExportElement>();
       for (Directive directive in library.definingCompilationUnit.directives) {
         if (directive is ImportDirective) {
-          ImportDirective importDirective = (directive as ImportDirective);
+          ImportDirective importDirective = directive as ImportDirective;
           Library importedLibrary = library.getImport(importDirective);
-          ImportElementImpl importElement = new ImportElementImpl();
-          importElement.combinators = buildCombinators(importDirective);
-          LibraryElement importedLibraryElement = importedLibrary.libraryElement;
-          if (importedLibraryElement != null) {
-            importElement.importedLibrary = importedLibraryElement;
-            directive.element = importedLibraryElement;
-          }
-          SimpleIdentifier prefixNode = ((directive as ImportDirective)).prefix;
-          if (prefixNode != null) {
-            String prefixName = prefixNode.name;
-            PrefixElementImpl prefix = nameToPrefixMap[prefixName];
-            if (prefix == null) {
-              prefix = new PrefixElementImpl(prefixNode);
-              nameToPrefixMap[prefixName] = prefix;
+          if (importedLibrary != null) {
+            ImportElementImpl importElement = new ImportElementImpl();
+            importElement.combinators = buildCombinators(importDirective);
+            LibraryElement importedLibraryElement = importedLibrary.libraryElement;
+            if (importedLibraryElement != null) {
+              importElement.importedLibrary = importedLibraryElement;
             }
-            importElement.prefix = prefix;
+            SimpleIdentifier prefixNode = ((directive as ImportDirective)).prefix;
+            if (prefixNode != null) {
+              String prefixName = prefixNode.name;
+              PrefixElementImpl prefix = nameToPrefixMap[prefixName];
+              if (prefix == null) {
+                prefix = new PrefixElementImpl(prefixNode);
+                nameToPrefixMap[prefixName] = prefix;
+              }
+              importElement.prefix = prefix;
+            }
+            directive.element = importElement;
+            imports.add(importElement);
           }
-          imports.add(importElement);
         } else if (directive is ExportDirective) {
-          ExportDirective exportDirective = (directive as ExportDirective);
+          ExportDirective exportDirective = directive as ExportDirective;
           ExportElementImpl exportElement = new ExportElementImpl();
           exportElement.combinators = buildCombinators(exportDirective);
-          LibraryElement exportedLibrary = library.getExport(exportDirective).libraryElement;
+          Library exportedLibrary = library.getExport(exportDirective);
           if (exportedLibrary != null) {
-            exportElement.exportedLibrary = exportedLibrary;
-            directive.element = exportedLibrary;
+            LibraryElement exportedLibraryElement = exportedLibrary.libraryElement;
+            if (exportedLibraryElement != null) {
+              exportElement.exportedLibrary = exportedLibraryElement;
+            }
+            directive.element = exportElement;
+            exports.add(exportElement);
           }
-          exports.add(exportElement);
         }
       }
       Source librarySource3 = library.librarySource;
@@ -1939,7 +2460,7 @@
   /**
    * Recursively traverse the libraries reachable from the given library, creating instances of the
    * class {@link Library} to represent them, and record the references in the library objects.
-   * @param library the library to be processed to find libaries that have not yet been traversed
+   * @param library the library to be processed to find libraries that have not yet been traversed
    * @throws AnalysisException if some portion of the library graph could not be traversed
    */
   void computeLibraryDependencies(Library library) {
@@ -1947,34 +2468,48 @@
     CompilationUnit unit = library.definingCompilationUnit;
     for (Directive directive in unit.directives) {
       if (directive is ImportDirective) {
-        ImportDirective importDirective = (directive as ImportDirective);
+        ImportDirective importDirective = directive as ImportDirective;
         Source importedSource = library.getSource(importDirective.uri);
-        if (importedSource == _coreLibrarySource) {
-          explicitlyImportsCore = true;
+        if (importedSource != null) {
+          if (importedSource == _coreLibrarySource) {
+            explicitlyImportsCore = true;
+          }
+          Library importedLibrary = _libraryMap[importedSource];
+          if (importedLibrary == null) {
+            importedLibrary = createLibraryOrNull(importedSource);
+            if (importedLibrary != null) {
+              computeLibraryDependencies(importedLibrary);
+            }
+          }
+          if (importedLibrary != null) {
+            library.addImport(importDirective, importedLibrary);
+          }
         }
-        Library importedLibrary = _libraryMap[importedSource];
-        if (importedLibrary == null) {
-          importedLibrary = createLibrary(importedSource);
-          computeLibraryDependencies(importedLibrary);
-        }
-        library.addImport(importDirective, importedLibrary);
       } else if (directive is ExportDirective) {
-        ExportDirective exportDirective = (directive as ExportDirective);
+        ExportDirective exportDirective = directive as ExportDirective;
         Source exportedSource = library.getSource(exportDirective.uri);
-        Library exportedLibrary = _libraryMap[exportedSource];
-        if (exportedLibrary == null) {
-          exportedLibrary = createLibrary(exportedSource);
-          computeLibraryDependencies(exportedLibrary);
+        if (exportedSource != null) {
+          Library exportedLibrary = _libraryMap[exportedSource];
+          if (exportedLibrary == null) {
+            exportedLibrary = createLibraryOrNull(exportedSource);
+            if (exportedLibrary != null) {
+              computeLibraryDependencies(exportedLibrary);
+            }
+          }
+          if (exportedLibrary != null) {
+            library.addExport(exportDirective, exportedLibrary);
+          }
         }
-        library.addExport(exportDirective, exportedLibrary);
       }
     }
     library.explicitlyImportsCore = explicitlyImportsCore;
     if (!explicitlyImportsCore && _coreLibrarySource != library.librarySource) {
       Library importedLibrary = _libraryMap[_coreLibrarySource];
       if (importedLibrary == null) {
-        importedLibrary = createLibrary(_coreLibrarySource);
-        computeLibraryDependencies(importedLibrary);
+        importedLibrary = createLibraryOrNull(_coreLibrarySource);
+        if (importedLibrary != null) {
+          computeLibraryDependencies(importedLibrary);
+        }
       }
     }
   }
@@ -1983,9 +2518,28 @@
    * with the given source.
    * @param librarySource the source of the library's defining compilation unit
    * @return the library object that was created
+   * @throws AnalysisException if the library source is not valid
    */
   Library createLibrary(Source librarySource) {
     Library library = new Library(_analysisContext, _errorListener, librarySource);
+    library.definingCompilationUnit;
+    _libraryMap[librarySource] = library;
+    return library;
+  }
+  /**
+   * Create an object to represent the information about the library defined by the compilation unit
+   * with the given source. Return the library object that was created, or {@code null} if the
+   * source is not valid.
+   * @param librarySource the source of the library's defining compilation unit
+   * @return the library object that was created
+   */
+  Library createLibraryOrNull(Source librarySource) {
+    Library library = new Library(_analysisContext, _errorListener, librarySource);
+    try {
+      library.definingCompilationUnit;
+    } on AnalysisException catch (exception) {
+      return null;
+    }
     _libraryMap[librarySource] = library;
     return library;
   }
@@ -2003,6 +2557,29 @@
     return identifiers;
   }
   /**
+   * For each library, loop through the set of all {@link CompilationUnit}s recording the set of
+   * resolution errors on each unit.
+   */
+  void recordErrors() {
+    for (Library library in _librariesInCycles) {
+      try {
+        CompilationUnit definingUnit = library.definingCompilationUnit;
+        definingUnit.resolutionErrors = _recordingErrorListener.getErrors2(library.librarySource);
+      } on AnalysisException catch (e) {
+        throw new AnalysisException();
+      }
+      Set<Source> sources = library.compilationUnitSources;
+      for (Source source in sources) {
+        try {
+          CompilationUnit unit = library.getAST(source);
+          unit.resolutionErrors = _recordingErrorListener.getErrors2(source);
+        } on JavaException catch (e) {
+          throw new AnalysisException();
+        }
+      }
+    }
+  }
+  /**
    * As the final step in the process, record the resolved element models with the analysis context.
    */
   void recordLibraryElements() {
@@ -2034,10 +2611,46 @@
       library.getAST(source).accept(visitor);
     }
   }
+  /**
+   * Run additional analyses, such as the {@link ConstantVerifier} and {@link ErrorVerifier}analysis in the current cycle.
+   * @throws AnalysisException if any of the identifiers could not be resolved or if the types in
+   * the library cannot be analyzed
+   */
+  void runAdditionalAnalyses() {
+    for (Library library in _librariesInCycles) {
+      runAdditionalAnalyses2(library);
+    }
+  }
+  /**
+   * Run additional analyses, such as the {@link ConstantVerifier} and {@link ErrorVerifier}analysis in the given library.
+   * @param library the library to have the extra analyses processes run
+   * @throws AnalysisException if any of the identifiers could not be resolved or if the types in
+   * the library cannot be analyzed
+   */
+  void runAdditionalAnalyses2(Library library) {
+    for (Source source in library.compilationUnitSources) {
+      ErrorReporter errorReporter = new ErrorReporter(_errorListener, source);
+      CompilationUnit unit = library.getAST(source);
+      ErrorVerifier errorVerifier = new ErrorVerifier(errorReporter, library.libraryElement, _typeProvider);
+      unit.accept(errorVerifier);
+      ConstantVerifier constantVerifier = new ConstantVerifier(errorReporter);
+      unit.accept(constantVerifier);
+    }
+  }
+}
+class AnalysisErrorListener_5 implements AnalysisErrorListener {
+  final LibraryResolver LibraryResolver_this;
+  AnalysisErrorListener additionalAnalysisErrorListener;
+  AnalysisErrorListener_5(this.LibraryResolver_this, this.additionalAnalysisErrorListener);
+  void onError(AnalysisError error) {
+    additionalAnalysisErrorListener.onError(error);
+    LibraryResolver_this._recordingErrorListener.onError(error);
+  }
 }
 /**
  * Instances of the class {@code ResolverVisitor} are used to resolve the nodes within a single
  * compilation unit.
+ * @coverage dart.engine.resolver
  */
 class ResolverVisitor extends ScopedVisitor {
   /**
@@ -2084,7 +2697,7 @@
     ExecutableElement outerFunction = _enclosingFunction;
     try {
       SimpleIdentifier functionName = node.name;
-      _enclosingFunction = (functionName.element as ExecutableElement);
+      _enclosingFunction = functionName.element as ExecutableElement;
       super.visitFunctionDeclaration(node);
     } finally {
       _enclosingFunction = outerFunction;
@@ -2101,6 +2714,7 @@
     }
     return null;
   }
+  Object visitLabel(Label node) => null;
   Object visitLibraryIdentifier(LibraryIdentifier node) => null;
   Object visitMethodDeclaration(MethodDeclaration node) {
     ExecutableElement outerFunction = _enclosingFunction;
@@ -2119,36 +2733,36 @@
     return null;
   }
   Object visitPrefixedIdentifier(PrefixedIdentifier node) {
-    SimpleIdentifier prefix6 = node.prefix;
-    if (prefix6 != null) {
-      prefix6.accept(this);
+    SimpleIdentifier prefix7 = node.prefix;
+    if (prefix7 != null) {
+      prefix7.accept(this);
     }
     node.accept(_elementResolver);
     node.accept(_typeAnalyzer);
     return null;
   }
   Object visitPropertyAccess(PropertyAccess node) {
-    Expression target5 = node.target;
-    if (target5 != null) {
-      target5.accept(this);
+    Expression target4 = node.target;
+    if (target4 != null) {
+      target4.accept(this);
     }
     node.accept(_elementResolver);
     node.accept(_typeAnalyzer);
     return null;
   }
   Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
-    ArgumentList argumentList11 = node.argumentList;
-    if (argumentList11 != null) {
-      argumentList11.accept(this);
+    ArgumentList argumentList10 = node.argumentList;
+    if (argumentList10 != null) {
+      argumentList10.accept(this);
     }
     node.accept(_elementResolver);
     node.accept(_typeAnalyzer);
     return null;
   }
   Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
-    ArgumentList argumentList12 = node.argumentList;
-    if (argumentList12 != null) {
-      argumentList12.accept(this);
+    ArgumentList argumentList11 = node.argumentList;
+    if (argumentList11 != null) {
+      argumentList11.accept(this);
     }
     node.accept(_elementResolver);
     node.accept(_typeAnalyzer);
@@ -2167,10 +2781,21 @@
    * @return the element representing the function containing the current node
    */
   ExecutableElement get enclosingFunction => _enclosingFunction;
+  get elementResolver_J2DAccessor => _elementResolver;
+  set elementResolver_J2DAccessor(__v) => _elementResolver = __v;
+  get labelScope_J2DAccessor => _labelScope;
+  set labelScope_J2DAccessor(__v) => _labelScope = __v;
+  get nameScope_J2DAccessor => _nameScope;
+  set nameScope_J2DAccessor(__v) => _nameScope = __v;
+  get typeAnalyzer_J2DAccessor => _typeAnalyzer;
+  set typeAnalyzer_J2DAccessor(__v) => _typeAnalyzer = __v;
+  get enclosingClass_J2DAccessor => _enclosingClass;
+  set enclosingClass_J2DAccessor(__v) => _enclosingClass = __v;
 }
 /**
  * The abstract class {@code ScopedVisitor} maintains name and label scopes as an AST structure is
  * being visited.
+ * @coverage dart.engine.resolver
  */
 abstract class ScopedVisitor extends GeneralizingASTVisitor<Object> {
   /**
@@ -2272,27 +2897,33 @@
     return null;
   }
   Object visitForEachStatement(ForEachStatement node) {
-    LabelScope outerScope = _labelScope;
-    _labelScope = new LabelScope.con1(outerScope, false, false);
+    LabelScope outerLabelScope = _labelScope;
+    _labelScope = new LabelScope.con1(outerLabelScope, false, false);
+    Scope outerNameScope = _nameScope;
+    _nameScope = new EnclosedScope(_nameScope);
     try {
       super.visitForEachStatement(node);
     } finally {
-      _labelScope = outerScope;
+      _nameScope = outerNameScope;
+      _labelScope = outerLabelScope;
     }
     return null;
   }
   Object visitForStatement(ForStatement node) {
-    LabelScope outerScope = _labelScope;
-    _labelScope = new LabelScope.con1(outerScope, false, false);
+    LabelScope outerLabelScope = _labelScope;
+    _labelScope = new LabelScope.con1(outerLabelScope, false, false);
+    Scope outerNameScope = _nameScope;
+    _nameScope = new EnclosedScope(_nameScope);
     try {
       super.visitForStatement(node);
     } finally {
-      _labelScope = outerScope;
+      _nameScope = outerNameScope;
+      _labelScope = outerLabelScope;
     }
     return null;
   }
   Object visitFunctionDeclaration(FunctionDeclaration node) {
-    FunctionElement function = node.element;
+    ExecutableElement function = node.element;
     Scope outerScope = _nameScope;
     try {
       _nameScope = new FunctionScope(_nameScope, function);
@@ -2300,13 +2931,19 @@
     } finally {
       _nameScope = outerScope;
     }
-    _nameScope.define(function);
+    if (function.enclosingElement is! CompilationUnitElement) {
+      _nameScope.define(function);
+    }
     return null;
   }
   Object visitFunctionExpression(FunctionExpression node) {
     Scope outerScope = _nameScope;
     try {
-      _nameScope = new FunctionScope(_nameScope, node.element);
+      ExecutableElement functionElement = node.element;
+      if (functionElement == null) {
+      } else {
+        _nameScope = new FunctionScope(_nameScope, functionElement);
+      }
       super.visitFunctionExpression(node);
     } finally {
       _nameScope = outerScope;
@@ -2373,7 +3010,7 @@
     for (SwitchMember member in node.members) {
       for (Label label in member.labels) {
         SimpleIdentifier labelName = label.label;
-        LabelElement labelElement = (labelName.element as LabelElement);
+        LabelElement labelElement = labelName.element as LabelElement;
         _labelScope = new LabelScope.con2(outerScope, labelName.name, labelElement);
       }
     }
@@ -2385,10 +3022,10 @@
     return null;
   }
   Object visitVariableDeclaration(VariableDeclaration node) {
-    if (node.parent.parent is! TopLevelVariableDeclaration) {
-      VariableElement element19 = node.element;
-      if (element19 != null) {
-        _nameScope.define(element19);
+    if (node.parent.parent is! TopLevelVariableDeclaration && node.parent.parent is! FieldDeclaration) {
+      VariableElement element24 = node.element;
+      if (element24 != null) {
+        _nameScope.define(element24);
       }
     }
     super.visitVariableDeclaration(node);
@@ -2420,7 +3057,7 @@
    * @param node the node specifying the location of the error
    * @param arguments the arguments to the error, used to compose the error message
    */
-  void reportError(ResolverErrorCode errorCode, ASTNode node, List<Object> arguments) {
+  void reportError(ErrorCode errorCode, ASTNode node, List<Object> arguments) {
     _errorListener.onError(new AnalysisError.con2(_source, node.offset, node.length, errorCode, [arguments]));
   }
   /**
@@ -2429,7 +3066,7 @@
    * @param token the token specifying the location of the error
    * @param arguments the arguments to the error, used to compose the error message
    */
-  void reportError2(ResolverErrorCode errorCode, Token token, List<Object> arguments) {
+  void reportError3(ErrorCode errorCode, sc.Token token, List<Object> arguments) {
     _errorListener.onError(new AnalysisError.con2(_source, token.offset, token.length, errorCode, [arguments]));
   }
   /**
@@ -2442,7 +3079,7 @@
     for (Label label in labels) {
       SimpleIdentifier labelNameNode = label.label;
       String labelName = labelNameNode.name;
-      LabelElement labelElement = (labelNameNode.element as LabelElement);
+      LabelElement labelElement = labelNameNode.element as LabelElement;
       _labelScope = new LabelScope.con2(_labelScope, labelName, labelElement);
     }
     return outerScope;
@@ -2456,17 +3093,18 @@
  * <li>Every element that refers to types should be fully populated.
  * <li>Every node representing an expression should be resolved to the Type of the expression.</li>
  * </ol>
+ * @coverage dart.engine.resolver
  */
 class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
   /**
-   * The resolver driving this participant.
-   */
-  ResolverVisitor _resolver;
-  /**
    * The object providing access to the types defined by the language.
    */
   TypeProvider _typeProvider;
   /**
+   * The type representing the type 'dynamic'.
+   */
+  Type2 _dynamicType;
+  /**
    * The type representing the class containing the nodes being analyzed, or {@code null} if the
    * nodes are not within a class.
    */
@@ -2476,8 +3114,8 @@
    * @param resolver the resolver driving this participant
    */
   StaticTypeAnalyzer(ResolverVisitor resolver) {
-    this._resolver = resolver;
     _typeProvider = resolver.typeProvider;
+    _dynamicType = _typeProvider.dynamicType;
   }
   /**
    * Set the type of the class being analyzed to the given type.
@@ -2503,7 +3141,7 @@
    * <p>
    * The static type of a cast expression <i>e as T</i> is <i>T</i>.</blockquote>
    */
-  Object visitAsExpression(AsExpression node) => recordType(node, getType2(node.type));
+  Object visitAsExpression(AsExpression node) => recordType(node, getType3(node.type));
   /**
    * The Dart Language Specification, 12.18: <blockquote> ... an assignment <i>a</i> of the form
    * <i>v = e</i> ...
@@ -2544,15 +3182,11 @@
    * <i>e<sub>3</sub></i>. </blockquote>
    */
   Object visitAssignmentExpression(AssignmentExpression node) {
-    TokenType operator11 = node.operator.type;
-    if (operator11 != TokenType.EQ) {
+    sc.TokenType operator11 = node.operator.type;
+    if (operator11 != sc.TokenType.EQ) {
       return recordReturnType(node, node.element);
     }
-    Type2 leftType = getType(node.leftHandSide);
-    Type2 rightType = getType(node.rightHandSide);
-    if (!rightType.isAssignableTo(leftType)) {
-    }
-    return recordType(node, rightType);
+    return recordType(node, getType(node.rightHandSide));
   }
   /**
    * The Dart Language Specification, 12.20: <blockquote>The static type of a logical boolean
@@ -2592,9 +3226,12 @@
    * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
    */
   Object visitBinaryExpression(BinaryExpression node) {
-    TokenType operator12 = node.operator.type;
-    if (operator12 == TokenType.AMPERSAND_AMPERSAND || operator12 == TokenType.BAR_BAR || operator12 == TokenType.EQ_EQ || operator12 == TokenType.BANG_EQ) {
-      return recordType(node, _typeProvider.boolType);
+    sc.TokenType operator12 = node.operator.type;
+    while (true) {
+      if (operator12 == sc.TokenType.AMPERSAND_AMPERSAND || operator12 == sc.TokenType.BAR_BAR || operator12 == sc.TokenType.EQ_EQ || operator12 == sc.TokenType.BANG_EQ) {
+        return recordType(node, _typeProvider.boolType);
+      }
+      break;
     }
     return recordReturnType(node, node.element);
   }
@@ -2618,14 +3255,10 @@
    * and the static type of <i>e<sub>3</sub></i>.</blockquote>
    */
   Object visitConditionalExpression(ConditionalExpression node) {
-    Type2 conditionType = getType(node.condition);
-    if (conditionType != null && !conditionType.isAssignableTo(_typeProvider.boolType)) {
-      _resolver.reportError(ResolverErrorCode.NON_BOOLEAN_CONDITION, node.condition, []);
-    }
     Type2 thenType = getType(node.thenExpression);
     Type2 elseType = getType(node.elseExpression);
     if (thenType == null) {
-      return recordType(node, _typeProvider.dynamicType);
+      return recordType(node, _dynamicType);
     }
     Type2 resultType = thenType.getLeastUpperBound(elseType);
     return recordType(node, resultType);
@@ -2634,6 +3267,12 @@
    * The Dart Language Specification, 12.3: <blockquote>The static type of a literal double is{@code double}.</blockquote>
    */
   Object visitDoubleLiteral(DoubleLiteral node) => recordType(node, _typeProvider.doubleType);
+  Object visitFunctionDeclaration(FunctionDeclaration node) {
+    FunctionExpression function = node.functionExpression;
+    FunctionTypeImpl functionType = node.element.type as FunctionTypeImpl;
+    setTypeInformation(functionType, computeReturnType(node), function.parameters);
+    return recordType(function, functionType);
+  }
   /**
    * The Dart Language Specification, 12.9: <blockquote>The static type of a function literal of the
    * form <i>(T<sub>1</sub> a<sub>1</sub>, &hellip;, T<sub>n</sub> a<sub>n</sub>, [T<sub>n+1</sub>
@@ -2665,8 +3304,11 @@
    * specified as dynamic.</blockquote>
    */
   Object visitFunctionExpression(FunctionExpression node) {
-    FunctionTypeImpl functionType = (node.element.type as FunctionTypeImpl);
-    setTypeInformation(functionType, computeReturnType(node), node.parameters);
+    if (node.parent is FunctionDeclaration) {
+      return null;
+    }
+    FunctionTypeImpl functionType = node.element.type as FunctionTypeImpl;
+    setTypeInformation(functionType, computeReturnType2(node), node.parameters);
     return recordType(node, functionType);
   }
   /**
@@ -2687,7 +3329,12 @@
    * <i>e<sub>1</sub>[e<sub>2</sub>]</i> is evaluated as a method invocation of the operator method
    * <i>[]</i> on <i>e<sub>1</sub></i> with argument <i>e<sub>2</sub></i>.</blockquote>
    */
-  Object visitIndexExpression(IndexExpression node) => recordReturnType(node, node.element);
+  Object visitIndexExpression(IndexExpression node) {
+    if (node.inSetterContext()) {
+      return recordArgumentType(node, node.element);
+    }
+    return recordReturnType(node, node.element);
+  }
   /**
    * The Dart Language Specification, 12.11.1: <blockquote>The static type of a new expression of
    * either the form <i>new T.id(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> or the form <i>new
@@ -2697,7 +3344,7 @@
    * expression of either the form <i>const T.id(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> or the
    * form <i>const T(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> is <i>T</i>. </blockquote>
    */
-  Object visitInstanceCreationExpression(InstanceCreationExpression node) => recordReturnType(node, node.element);
+  Object visitInstanceCreationExpression(InstanceCreationExpression node) => recordType(node, node.constructorName.type.type);
   /**
    * The Dart Language Specification, 12.3: <blockquote>The static type of an integer literal is{@code int}.</blockquote>
    */
@@ -2719,13 +3366,13 @@
   Object visitListLiteral(ListLiteral node) {
     TypeArgumentList typeArguments8 = node.typeArguments;
     if (typeArguments8 != null) {
-      NodeList<TypeName> arguments3 = typeArguments8.arguments;
-      if (arguments3 != null && arguments3.length == 1) {
-        TypeName argumentType = arguments3[0];
-        return recordType(node, _typeProvider.listType.substitute5(<Type2> [getType2(argumentType)]));
+      NodeList<TypeName> arguments4 = typeArguments8.arguments;
+      if (arguments4 != null && arguments4.length == 1) {
+        TypeName argumentType = arguments4[0];
+        return recordType(node, _typeProvider.listType.substitute5(<Type2> [getType3(argumentType)]));
       }
     }
-    return recordType(node, _typeProvider.listType.substitute5(<Type2> [_typeProvider.dynamicType]));
+    return recordType(node, _typeProvider.listType.substitute5(<Type2> [_dynamicType]));
   }
   /**
    * The Dart Language Specification, 12.7: <blockquote>The static type of a map literal of the form
@@ -2742,16 +3389,16 @@
   Object visitMapLiteral(MapLiteral node) {
     TypeArgumentList typeArguments9 = node.typeArguments;
     if (typeArguments9 != null) {
-      NodeList<TypeName> arguments4 = typeArguments9.arguments;
-      if (arguments4 != null && arguments4.length == 2) {
-        TypeName keyType = arguments4[0];
+      NodeList<TypeName> arguments5 = typeArguments9.arguments;
+      if (arguments5 != null && arguments5.length == 2) {
+        TypeName keyType = arguments5[0];
         if (keyType != _typeProvider.stringType) {
         }
-        TypeName valueType = arguments4[1];
-        return recordType(node, _typeProvider.mapType.substitute5(<Type2> [_typeProvider.stringType, getType2(valueType)]));
+        TypeName valueType = arguments5[1];
+        return recordType(node, _typeProvider.mapType.substitute5(<Type2> [_typeProvider.stringType, getType3(valueType)]));
       }
     }
-    return recordType(node, _typeProvider.mapType.substitute5(<Type2> [_typeProvider.stringType, _typeProvider.dynamicType]));
+    return recordType(node, _typeProvider.mapType.substitute5(<Type2> [_typeProvider.stringType, _dynamicType]));
   }
   /**
    * The Dart Language Specification, 12.15.1: <blockquote>An ordinary method invocation <i>i</i>
@@ -2829,23 +3476,23 @@
    */
   Object visitPrefixedIdentifier(PrefixedIdentifier node) {
     SimpleIdentifier prefixedIdentifier = node.identifier;
-    Element element20 = prefixedIdentifier.element;
-    if (element20 is VariableElement) {
-      Type2 variableType = ((element20 as VariableElement)).type;
+    Element element25 = prefixedIdentifier.element;
+    if (element25 is VariableElement) {
+      Type2 variableType = ((element25 as VariableElement)).type;
       recordType(prefixedIdentifier, variableType);
       return recordType(node, variableType);
-    } else if (element20 is PropertyAccessorElement) {
-      Type2 propertyType = ((element20 as PropertyAccessorElement)).type.returnType;
+    } else if (element25 is PropertyAccessorElement) {
+      Type2 propertyType = getType2((element25 as PropertyAccessorElement));
       recordType(prefixedIdentifier, propertyType);
       return recordType(node, propertyType);
-    } else if (element20 is MethodElement) {
-      Type2 returnType = ((element20 as MethodElement)).type;
+    } else if (element25 is MethodElement) {
+      Type2 returnType = ((element25 as MethodElement)).type;
       recordType(prefixedIdentifier, returnType);
       return recordType(node, returnType);
     } else {
     }
-    recordType(prefixedIdentifier, _typeProvider.dynamicType);
-    return recordType(node, _typeProvider.dynamicType);
+    recordType(prefixedIdentifier, _dynamicType);
+    return recordType(node, _dynamicType);
   }
   /**
    * The Dart Language Specification, 12.27: <blockquote>A unary expression <i>u</i> of the form
@@ -2853,8 +3500,8 @@
    * form <i>op super</i> is equivalent to the method invocation <i>super.op()<i>.</blockquote>
    */
   Object visitPrefixExpression(PrefixExpression node) {
-    TokenType operator13 = node.operator.type;
-    if (identical(operator13, TokenType.BANG)) {
+    sc.TokenType operator13 = node.operator.type;
+    if (identical(operator13, sc.TokenType.BANG)) {
       return recordType(node, _typeProvider.boolType);
     }
     return recordReturnType(node, node.element);
@@ -2904,29 +3551,19 @@
    */
   Object visitPropertyAccess(PropertyAccess node) {
     SimpleIdentifier propertyName2 = node.propertyName;
-    Element element21 = propertyName2.element;
-    if (element21 is MethodElement) {
-      FunctionType type11 = ((element21 as MethodElement)).type;
-      recordType(propertyName2, type11);
-      return recordType(node, type11);
-    } else if (element21 is PropertyAccessorElement) {
-      PropertyAccessorElement accessor = (element21 as PropertyAccessorElement);
-      if (accessor.isGetter()) {
-        if (accessor.type == null) {
-          recordType(propertyName2, _typeProvider.dynamicType);
-          return recordType(node, _typeProvider.dynamicType);
-        }
-        Type2 returnType4 = accessor.type.returnType;
-        recordType(propertyName2, returnType4);
-        return recordType(node, returnType4);
-      } else {
-        recordType(propertyName2, VoidTypeImpl.instance);
-        return recordType(node, VoidTypeImpl.instance);
-      }
+    Element element26 = propertyName2.element;
+    if (element26 is MethodElement) {
+      FunctionType type15 = ((element26 as MethodElement)).type;
+      recordType(propertyName2, type15);
+      return recordType(node, type15);
+    } else if (element26 is PropertyAccessorElement) {
+      Type2 propertyType = getType2((element26 as PropertyAccessorElement));
+      recordType(propertyName2, propertyType);
+      return recordType(node, propertyType);
     } else {
     }
-    recordType(propertyName2, _typeProvider.dynamicType);
-    return recordType(node, _typeProvider.dynamicType);
+    recordType(propertyName2, _dynamicType);
+    return recordType(node, _dynamicType);
   }
   /**
    * The Dart Language Specification, 12.30: <blockquote>Evaluation of an identifier expression
@@ -2971,35 +3608,30 @@
    * </blockquote>
    */
   Object visitSimpleIdentifier(SimpleIdentifier node) {
-    Element element22 = node.element;
-    if (element22 == null) {
-      return recordType(node, _typeProvider.dynamicType);
-    } else if (element22 is ClassElement) {
-      if (isTypeName(node)) {
-        return recordType(node, ((element22 as ClassElement)).type);
+    Element element27 = node.element;
+    if (element27 == null) {
+      return recordType(node, _dynamicType);
+    } else if (element27 is ClassElement) {
+      if (isNotTypeLiteral(node)) {
+        return recordType(node, ((element27 as ClassElement)).type);
       }
       return recordType(node, _typeProvider.typeType);
-    } else if (element22 is TypeVariableElement) {
-      return recordType(node, ((element22 as TypeVariableElement)).type);
-    } else if (element22 is TypeAliasElement) {
-      return recordType(node, ((element22 as TypeAliasElement)).type);
-    } else if (element22 is VariableElement) {
-      return recordType(node, ((element22 as VariableElement)).type);
-    } else if (element22 is MethodElement) {
-      return recordType(node, ((element22 as MethodElement)).type);
-    } else if (element22 is PropertyAccessorElement) {
-      PropertyAccessorElement accessor = (element22 as PropertyAccessorElement);
-      if (accessor.isGetter()) {
-        return recordType(node, accessor.type.returnType);
-      } else {
-        return recordType(node, accessor.type.normalParameterTypes[0]);
-      }
-    } else if (element22 is ExecutableElement) {
-      return recordType(node, ((element22 as ExecutableElement)).type);
-    } else if (element22 is PrefixElement) {
+    } else if (element27 is TypeVariableElement) {
+      return recordType(node, ((element27 as TypeVariableElement)).type);
+    } else if (element27 is FunctionTypeAliasElement) {
+      return recordType(node, ((element27 as FunctionTypeAliasElement)).type);
+    } else if (element27 is VariableElement) {
+      return recordType(node, ((element27 as VariableElement)).type);
+    } else if (element27 is MethodElement) {
+      return recordType(node, ((element27 as MethodElement)).type);
+    } else if (element27 is PropertyAccessorElement) {
+      return recordType(node, getType2((element27 as PropertyAccessorElement)));
+    } else if (element27 is ExecutableElement) {
+      return recordType(node, ((element27 as ExecutableElement)).type);
+    } else if (element27 is PrefixElement) {
       return null;
     } else {
-      return recordType(node, _typeProvider.dynamicType);
+      return recordType(node, _dynamicType);
     }
   }
   /**
@@ -3010,30 +3642,56 @@
    * The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is{@code String}.</blockquote>
    */
   Object visitStringInterpolation(StringInterpolation node) => recordType(node, _typeProvider.stringType);
-  Object visitSuperExpression(SuperExpression node) => recordType(node, _thisType == null ? _typeProvider.dynamicType : _thisType.superclass);
+  Object visitSuperExpression(SuperExpression node) {
+    if (_thisType == null) {
+      return recordType(node, _dynamicType);
+    } else {
+      return recordType(node, _thisType.superclass);
+    }
+  }
   /**
    * The Dart Language Specification, 12.10: <blockquote>The static type of {@code this} is the
    * interface of the immediately enclosing class.</blockquote>
    */
-  Object visitThisExpression(ThisExpression node) => recordType(node, _thisType);
+  Object visitThisExpression(ThisExpression node) {
+    if (_thisType == null) {
+      return recordType(node, _dynamicType);
+    } else {
+      return recordType(node, _thisType);
+    }
+  }
   /**
    * The Dart Language Specification, 12.8: <blockquote>The static type of a throw expression is
    * bottom.</blockquote>
    */
   Object visitThrowExpression(ThrowExpression node) => recordType(node, _typeProvider.bottomType);
   /**
+   * Given a function declaration, compute the return type of the function. The return type of
+   * functions with a block body is {@code dynamicType}, with an expression body it is the type of
+   * the expression.
+   * @param node the function expression whose return type is to be computed
+   * @return the return type that was computed
+   */
+  Type2 computeReturnType(FunctionDeclaration node) {
+    TypeName returnType7 = node.returnType;
+    if (returnType7 == null) {
+      return computeReturnType2(node.functionExpression);
+    }
+    return returnType7.type;
+  }
+  /**
    * Given a function expression, compute the return type of the function. The return type of
    * functions with a block body is {@code dynamicType}, with an expression body it is the type of
    * the expression.
    * @param node the function expression whose return type is to be computed
    * @return the return type that was computed
    */
-  Type2 computeReturnType(FunctionExpression node) {
+  Type2 computeReturnType2(FunctionExpression node) {
     FunctionBody body4 = node.body;
     if (body4 is ExpressionFunctionBody) {
       return getType(((body4 as ExpressionFunctionBody)).expression);
     }
-    return _typeProvider.dynamicType;
+    return _dynamicType;
   }
   /**
    * Return the type of the given expression that is to be used for type analysis.
@@ -3043,30 +3701,71 @@
   Type2 getType(Expression expression) {
     Type2 type = expression.staticType;
     if (type == null) {
-      return _typeProvider.dynamicType;
+      return _dynamicType;
     }
     return type;
   }
   /**
+   * Return the type that should be recorded for a node that resolved to the given accessor.
+   * @param accessor the accessor that the node resolved to
+   * @return the type that should be recorded for a node that resolved to the given accessor
+   */
+  Type2 getType2(PropertyAccessorElement accessor) {
+    FunctionType functionType = accessor.type;
+    if (functionType == null) {
+      return _dynamicType;
+    }
+    if (accessor.isSetter()) {
+      List<Type2> parameterTypes = functionType.normalParameterTypes;
+      if (parameterTypes != null && parameterTypes.length > 0) {
+        return parameterTypes[0];
+      }
+      PropertyAccessorElement getter4 = accessor.variable.getter;
+      if (getter4 != null) {
+        functionType = getter4.type;
+        if (functionType != null) {
+          return functionType.returnType;
+        }
+      }
+      return _dynamicType;
+    }
+    return functionType.returnType;
+  }
+  /**
    * Return the type represented by the given type name.
    * @param typeName the type name representing the type to be returned
    * @return the type represented by the type name
    */
-  Type2 getType2(TypeName typeName) {
-    Type2 type12 = typeName.type;
-    if (type12 == null) {
-      return _typeProvider.dynamicType;
+  Type2 getType3(TypeName typeName) {
+    Type2 type16 = typeName.type;
+    if (type16 == null) {
+      return _dynamicType;
     }
-    return type12;
+    return type16;
   }
   /**
-   * Return {@code true} if the given node is being used as the name of a type.
+   * Return {@code true} if the given node is not a type literal.
    * @param node the node being tested
-   * @return {@code true} if the given node is being used as the name of a type
+   * @return {@code true} if the given node is not a type literal
    */
-  bool isTypeName(SimpleIdentifier node) {
-    ASTNode parent8 = node.parent;
-    return parent8 is TypeName || (parent8 is PrefixedIdentifier && parent8.parent is TypeName) || (parent8 is MethodInvocation && identical(node, ((parent8 as MethodInvocation)).target));
+  bool isNotTypeLiteral(SimpleIdentifier node) {
+    ASTNode parent15 = node.parent;
+    return parent15 is TypeName || (parent15 is PrefixedIdentifier && (parent15.parent is TypeName || identical(((parent15 as PrefixedIdentifier)).prefix, node))) || (parent15 is PropertyAccess && identical(((parent15 as PropertyAccess)).target, node)) || (parent15 is MethodInvocation && identical(node, ((parent15 as MethodInvocation)).target));
+  }
+  /**
+   * Record that the static type of the given node is the type of the second argument to the method
+   * represented by the given element.
+   * @param expression the node whose type is to be recorded
+   * @param element the element representing the method invoked by the given node
+   */
+  Object recordArgumentType(IndexExpression expression, MethodElement element) {
+    if (element != null) {
+      List<ParameterElement> parameters12 = element.parameters;
+      if (parameters12 != null && parameters12.length == 2) {
+        return recordType(expression, parameters12[1].type);
+      }
+    }
+    return recordType(expression, _dynamicType);
   }
   /**
    * Record that the static type of the given node is the return type of the method or function
@@ -3075,10 +3774,24 @@
    * @param element the element representing the method or function invoked by the given node
    */
   Object recordReturnType(Expression expression, Element element) {
-    if (element is ExecutableElement) {
-      FunctionType type13 = ((element as ExecutableElement)).type;
-      if (type13 != null) {
-        return recordType(expression, type13.returnType);
+    if (element is PropertyAccessorElement) {
+      FunctionType propertyType = ((element as PropertyAccessorElement)).type;
+      if (propertyType != null) {
+        Type2 returnType8 = propertyType.returnType;
+        if (returnType8 is FunctionType) {
+          Type2 innerReturnType = ((returnType8 as FunctionType)).returnType;
+          if (innerReturnType != null) {
+            return recordType(expression, innerReturnType);
+          }
+        }
+        if (returnType8 != null) {
+          return recordType(expression, returnType8);
+        }
+      }
+    } else if (element is ExecutableElement) {
+      FunctionType type17 = ((element as ExecutableElement)).type;
+      if (type17 != null) {
+        return recordType(expression, type17.returnType);
       }
     } else if (element is VariableElement) {
       Type2 variableType = ((element as VariableElement)).type;
@@ -3086,7 +3799,7 @@
         return recordType(expression, ((variableType as FunctionType)).returnType);
       }
     }
-    return recordType(expression, _typeProvider.dynamicType);
+    return recordType(expression, _dynamicType);
   }
   /**
    * Record that the static type of the given node is the given type.
@@ -3095,7 +3808,7 @@
    */
   Object recordType(Expression expression, Type2 type) {
     if (type == null) {
-      expression.staticType = _typeProvider.dynamicType;
+      expression.staticType = _dynamicType;
     } else {
       expression.staticType = type;
     }
@@ -3108,30 +3821,36 @@
    * @param returnType the return type of the function, or {@code null} if no type was declared
    * @param parameters the elements representing the parameters to the function
    */
-  void setTypeInformation(FunctionTypeImpl functionType, Type2 returnType7, FormalParameterList parameterList) {
+  void setTypeInformation(FunctionTypeImpl functionType, Type2 returnType11, FormalParameterList parameterList) {
     List<Type2> normalParameterTypes = new List<Type2>();
     List<Type2> optionalParameterTypes = new List<Type2>();
     LinkedHashMap<String, Type2> namedParameterTypes = new LinkedHashMap<String, Type2>();
     if (parameterList != null) {
       for (ParameterElement parameter in parameterList.elements) {
-        if (parameter.parameterKind == ParameterKind.REQUIRED) {
-          normalParameterTypes.add(parameter.type);
-        } else if (parameter.parameterKind == ParameterKind.POSITIONAL) {
-          optionalParameterTypes.add(parameter.type);
-        } else if (parameter.parameterKind == ParameterKind.NAMED) {
-          namedParameterTypes[parameter.name] = parameter.type;
+        while (true) {
+          if (parameter.parameterKind == ParameterKind.REQUIRED) {
+            normalParameterTypes.add(parameter.type);
+          } else if (parameter.parameterKind == ParameterKind.POSITIONAL) {
+            optionalParameterTypes.add(parameter.type);
+          } else if (parameter.parameterKind == ParameterKind.NAMED) {
+            namedParameterTypes[parameter.name] = parameter.type;
+          }
+          break;
         }
       }
     }
     functionType.normalParameterTypes = new List.from(normalParameterTypes);
     functionType.optionalParameterTypes = new List.from(optionalParameterTypes);
     functionType.namedParameterTypes = namedParameterTypes;
-    functionType.returnType = returnType7;
+    functionType.returnType = returnType11;
   }
+  get thisType_J2DAccessor => _thisType;
+  set thisType_J2DAccessor(__v) => _thisType = __v;
 }
 /**
  * The interface {@code TypeProvider} defines the behavior of objects that provide access to types
  * defined by the language.
+ * @coverage dart.engine.resolver
  */
 abstract class TypeProvider {
   /**
@@ -3198,6 +3917,7 @@
 /**
  * Instances of the class {@code TypeProviderImpl} provide access to types defined by the language
  * by looking for those types in the element model for the core library.
+ * @coverage dart.engine.resolver
  */
 class TypeProviderImpl implements TypeProvider {
   /**
@@ -3307,15 +4027,21 @@
  * the elements in the element model. This includes the types of superclasses, mixins, interfaces,
  * fields, methods, parameters, and local variables. As a side-effect, this also finishes building
  * the type hierarchy.
+ * @coverage dart.engine.resolver
  */
 class TypeResolverVisitor extends ScopedVisitor {
   /**
+   * The type representing the type 'dynamic'.
+   */
+  Type2 _dynamicType;
+  /**
    * Initialize a newly created visitor to resolve the nodes in a compilation unit.
    * @param library the library containing the compilation unit being resolved
    * @param source the source representing the compilation unit being visited
    * @param typeProvider the object used to access the types from the core library
    */
   TypeResolverVisitor(Library library, Source source, TypeProvider typeProvider) : super(library, source, typeProvider) {
+    _dynamicType = typeProvider.dynamicType;
   }
   Object visitCatchClause(CatchClause node) {
     super.visitCatchClause(node);
@@ -3326,12 +4052,12 @@
       if (exceptionTypeName == null) {
         exceptionType = typeProvider.objectType;
       } else {
-        exceptionType = getType(exceptionTypeName);
+        exceptionType = getType4(exceptionTypeName);
       }
       recordType(exception, exceptionType);
-      Element element23 = exception.element;
-      if (element23 is VariableElementImpl) {
-        ((element23 as VariableElementImpl)).type = exceptionType;
+      Element element28 = exception.element;
+      if (element28 is VariableElementImpl) {
+        ((element28 as VariableElementImpl)).type = exceptionType;
       } else {
       }
     }
@@ -3347,7 +4073,10 @@
     InterfaceType superclassType = null;
     ExtendsClause extendsClause4 = node.extendsClause;
     if (extendsClause4 != null) {
-      superclassType = resolveType(extendsClause4.superclass, null, null, null);
+      superclassType = resolveType(extendsClause4.superclass, CompileTimeErrorCode.EXTENDS_NON_CLASS, CompileTimeErrorCode.EXTENDS_NON_CLASS, null);
+      if (superclassType != typeProvider.objectType) {
+        classElement.validMixin = false;
+      }
     }
     if (classElement != null) {
       if (superclassType == null) {
@@ -3364,7 +4093,7 @@
   Object visitClassTypeAlias(ClassTypeAlias node) {
     super.visitClassTypeAlias(node);
     ClassElementImpl classElement = getClassElement(node.name);
-    InterfaceType superclassType = resolveType(node.superclass, null, null, null);
+    InterfaceType superclassType = resolveType(node.superclass, CompileTimeErrorCode.EXTENDS_NON_CLASS, CompileTimeErrorCode.EXTENDS_NON_CLASS, null);
     if (superclassType == null) {
       superclassType = typeProvider.objectType;
     }
@@ -3376,11 +4105,24 @@
   }
   Object visitConstructorDeclaration(ConstructorDeclaration node) {
     super.visitConstructorDeclaration(node);
-    ExecutableElementImpl element24 = (node.element as ExecutableElementImpl);
-    FunctionTypeImpl type = new FunctionTypeImpl.con1(element24);
-    setTypeInformation(type, null, element24.parameters);
-    type.returnType = ((element24.enclosingElement as ClassElement)).type;
-    element24.type = type;
+    ExecutableElementImpl element29 = node.element as ExecutableElementImpl;
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(element29);
+    setTypeInformation(type, null, element29.parameters);
+    type.returnType = ((element29.enclosingElement as ClassElement)).type;
+    element29.type = type;
+    return null;
+  }
+  Object visitDeclaredIdentifier(DeclaredIdentifier node) {
+    super.visitDeclaredIdentifier(node);
+    Type2 declaredType;
+    TypeName typeName = node.type;
+    if (typeName == null) {
+      declaredType = _dynamicType;
+    } else {
+      declaredType = getType4(typeName);
+    }
+    LocalVariableElementImpl element30 = node.element as LocalVariableElementImpl;
+    element30.type = declaredType;
     return null;
   }
   Object visitDefaultFormalParameter(DefaultFormalParameter node) {
@@ -3389,15 +4131,15 @@
   }
   Object visitFieldFormalParameter(FieldFormalParameter node) {
     super.visitFieldFormalParameter(node);
-    Element element25 = node.identifier.element;
-    if (element25 is ParameterElementImpl) {
-      ParameterElementImpl parameter = (element25 as ParameterElementImpl);
+    Element element31 = node.identifier.element;
+    if (element31 is ParameterElementImpl) {
+      ParameterElementImpl parameter = element31 as ParameterElementImpl;
       Type2 type;
       TypeName typeName = node.type;
       if (typeName == null) {
-        type = typeProvider.dynamicType;
+        type = _dynamicType;
       } else {
-        type = getType(typeName);
+        type = getType4(typeName);
       }
       parameter.type = type;
     } else {
@@ -3406,33 +4148,45 @@
   }
   Object visitFunctionDeclaration(FunctionDeclaration node) {
     super.visitFunctionDeclaration(node);
-    ExecutableElementImpl element26 = (node.element as ExecutableElementImpl);
-    FunctionTypeImpl type = new FunctionTypeImpl.con1(element26);
-    setTypeInformation(type, node.returnType, element26.parameters);
-    element26.type = type;
+    ExecutableElementImpl element32 = node.element as ExecutableElementImpl;
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(element32);
+    setTypeInformation(type, node.returnType, element32.parameters);
+    element32.type = type;
     return null;
   }
   Object visitFunctionTypeAlias(FunctionTypeAlias node) {
     super.visitFunctionTypeAlias(node);
-    TypeAliasElementImpl element27 = (node.element as TypeAliasElementImpl);
-    FunctionTypeImpl type14 = (element27.type as FunctionTypeImpl);
-    setTypeInformation(type14, node.returnType, element27.parameters);
+    FunctionTypeAliasElementImpl element33 = node.element as FunctionTypeAliasElementImpl;
+    FunctionTypeImpl type18 = element33.type as FunctionTypeImpl;
+    setTypeInformation(type18, node.returnType, element33.parameters);
     return null;
   }
   Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
     super.visitFunctionTypedFormalParameter(node);
-    ParameterElementImpl element28 = (node.identifier.element as ParameterElementImpl);
+    ParameterElementImpl element34 = node.identifier.element as ParameterElementImpl;
     FunctionTypeImpl type = new FunctionTypeImpl.con1((null as ExecutableElement));
     setTypeInformation(type, node.returnType, getElements(node.parameters));
-    element28.type = type;
+    element34.type = type;
     return null;
   }
   Object visitMethodDeclaration(MethodDeclaration node) {
     super.visitMethodDeclaration(node);
-    ExecutableElementImpl element29 = (node.element as ExecutableElementImpl);
-    FunctionTypeImpl type = new FunctionTypeImpl.con1(element29);
-    setTypeInformation(type, node.returnType, element29.parameters);
-    element29.type = type;
+    ExecutableElementImpl element35 = node.element as ExecutableElementImpl;
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(element35);
+    setTypeInformation(type, node.returnType, element35.parameters);
+    element35.type = type;
+    if (element35 is PropertyAccessorElementImpl) {
+      PropertyAccessorElementImpl accessor = element35 as PropertyAccessorElementImpl;
+      PropertyInducingElementImpl variable5 = accessor.variable as PropertyInducingElementImpl;
+      if (accessor.isGetter()) {
+        variable5.type = type.returnType;
+      } else if (variable5.type == null) {
+        List<Type2> parameterTypes = type.normalParameterTypes;
+        if (parameterTypes != null && parameterTypes.length > 0) {
+          variable5.type = parameterTypes[0];
+        }
+      }
+    }
     return null;
   }
   Object visitSimpleFormalParameter(SimpleFormalParameter node) {
@@ -3440,13 +4194,13 @@
     Type2 declaredType;
     TypeName typeName = node.type;
     if (typeName == null) {
-      declaredType = typeProvider.dynamicType;
+      declaredType = _dynamicType;
     } else {
-      declaredType = getType(typeName);
+      declaredType = getType4(typeName);
     }
-    Element element30 = node.identifier.element;
-    if (element30 is ParameterElement) {
-      ((element30 as ParameterElementImpl)).type = declaredType;
+    Element element36 = node.identifier.element;
+    if (element36 is ParameterElement) {
+      ((element36 as ParameterElementImpl)).type = declaredType;
     } else {
     }
     return null;
@@ -3454,81 +4208,94 @@
   Object visitTypeName(TypeName node) {
     super.visitTypeName(node);
     Identifier typeName = node.name;
+    TypeArgumentList argumentList = node.typeArguments;
     Element element = nameScope.lookup(typeName, definingLibrary);
-    Type2 type = null;
     if (element == null) {
-      DynamicTypeImpl dynamicType = DynamicTypeImpl.instance;
+      if (typeName.name == _dynamicType.name) {
+        setElement(typeName, _dynamicType.element);
+        if (argumentList != null) {
+        }
+        typeName.staticType = _dynamicType;
+        node.type = _dynamicType;
+        return null;
+      }
       VoidTypeImpl voidType = VoidTypeImpl.instance;
-      if (typeName.name == dynamicType.name) {
-        element = dynamicType.element;
-        type = dynamicType;
-        setElement(typeName, element);
-      } else if (typeName.name == voidType.name) {
-        type = voidType;
-      } else {
-        ASTNode parent9 = node.parent;
-        if (typeName is PrefixedIdentifier && parent9 is ConstructorName) {
-          ConstructorName name = (parent9 as ConstructorName);
-          if (name.name == null) {
-            SimpleIdentifier prefix7 = ((typeName as PrefixedIdentifier)).prefix;
-            element = nameScope.lookup(prefix7, definingLibrary);
-            if (element is PrefixElement) {
-              return null;
-            } else if (element != null) {
-              name.name = ((typeName as PrefixedIdentifier)).identifier;
-              node.name = prefix7;
-              typeName = prefix7;
-            }
+      if (typeName.name == voidType.name) {
+        if (argumentList != null) {
+        }
+        typeName.staticType = voidType;
+        node.type = voidType;
+        return null;
+      }
+      ASTNode parent16 = node.parent;
+      if (typeName is PrefixedIdentifier && parent16 is ConstructorName && argumentList == null) {
+        ConstructorName name = parent16 as ConstructorName;
+        if (name.name == null) {
+          SimpleIdentifier prefix8 = ((typeName as PrefixedIdentifier)).prefix;
+          element = nameScope.lookup(prefix8, definingLibrary);
+          if (element is PrefixElement) {
+            return null;
+          } else if (element != null) {
+            name.name = ((typeName as PrefixedIdentifier)).identifier;
+            name.period = ((typeName as PrefixedIdentifier)).period;
+            node.name = prefix8;
+            typeName = prefix8;
           }
         }
       }
     }
-    if (element == null && type == null) {
+    if (element == null) {
+      setElement(typeName, _dynamicType.element);
+      typeName.staticType = _dynamicType;
+      node.type = _dynamicType;
       return null;
-    } else if (element is ClassElement) {
+    }
+    Type2 type = null;
+    if (element is ClassElement) {
       setElement(typeName, element);
       type = ((element as ClassElement)).type;
-    } else if (element is TypeAliasElement) {
+    } else if (element is FunctionTypeAliasElement) {
       setElement(typeName, element);
-      type = ((element as TypeAliasElement)).type;
+      type = ((element as FunctionTypeAliasElement)).type;
     } else if (element is TypeVariableElement) {
       setElement(typeName, element);
       type = ((element as TypeVariableElement)).type;
-    } else if (type == null) {
+      if (argumentList != null) {
+      }
+    } else {
+      setElement(typeName, _dynamicType.element);
+      typeName.staticType = _dynamicType;
+      node.type = _dynamicType;
       return null;
     }
-    if (type == null) {
-      return null;
-    }
-    TypeArgumentList argumentList = node.typeArguments;
     if (argumentList != null) {
-      NodeList<TypeName> arguments5 = argumentList.arguments;
-      int argumentCount = arguments5.length;
+      NodeList<TypeName> arguments6 = argumentList.arguments;
+      int argumentCount = arguments6.length;
       List<Type2> parameters = getTypeArguments(type);
       int parameterCount = parameters.length;
-      if (argumentCount != parameterCount) {
-      }
-      List<Type2> typeArguments = new List<Type2>(argumentCount);
-      for (int i = 0; i < argumentCount; i++) {
-        Type2 argumentType = getType(arguments5[i]);
+      int count = Math.min(argumentCount, parameterCount);
+      List<Type2> typeArguments = new List<Type2>();
+      for (int i = 0; i < count; i++) {
+        Type2 argumentType = getType4(arguments6[i]);
         if (argumentType != null) {
           typeArguments.add(argumentType);
         }
       }
+      if (argumentCount != parameterCount) {
+        reportError(getInvalidTypeParametersErrorCode(node), node, [typeName.name, argumentCount, parameterCount]);
+      }
+      argumentCount = typeArguments.length;
+      if (argumentCount < parameterCount) {
+        for (int i = argumentCount; i < parameterCount; i++) {
+          typeArguments.add(_dynamicType);
+        }
+      }
       if (type is InterfaceTypeImpl) {
-        InterfaceTypeImpl interfaceType = (type as InterfaceTypeImpl);
-        argumentCount = typeArguments.length;
-        if (interfaceType.typeArguments.length == argumentCount) {
-          type = interfaceType.substitute5(new List.from(typeArguments));
-        } else {
-        }
+        InterfaceTypeImpl interfaceType = type as InterfaceTypeImpl;
+        type = interfaceType.substitute5(new List.from(typeArguments));
       } else if (type is FunctionTypeImpl) {
-        FunctionTypeImpl functionType = (type as FunctionTypeImpl);
-        argumentCount = typeArguments.length;
-        if (functionType.typeArguments.length == argumentCount) {
-          type = functionType.substitute4(new List.from(typeArguments));
-        } else {
-        }
+        FunctionTypeImpl functionType = type as FunctionTypeImpl;
+        type = functionType.substitute4(new List.from(typeArguments));
       } else {
       }
     } else {
@@ -3552,25 +4319,25 @@
     Type2 declaredType;
     TypeName typeName = ((node.parent as VariableDeclarationList)).type;
     if (typeName == null) {
-      declaredType = typeProvider.dynamicType;
+      declaredType = _dynamicType;
     } else {
-      declaredType = getType(typeName);
+      declaredType = getType4(typeName);
     }
-    Element element31 = node.name.element;
-    if (element31 is VariableElement) {
-      ((element31 as VariableElementImpl)).type = declaredType;
-      if (element31 is FieldElement) {
-        FieldElement field = (element31 as FieldElement);
-        PropertyAccessorElementImpl getter3 = (field.getter as PropertyAccessorElementImpl);
-        FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter3);
+    Element element37 = node.name.element;
+    if (element37 is VariableElement) {
+      ((element37 as VariableElementImpl)).type = declaredType;
+      if (element37 is FieldElement) {
+        FieldElement field = element37 as FieldElement;
+        PropertyAccessorElementImpl getter5 = field.getter as PropertyAccessorElementImpl;
+        FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter5);
         getterType.returnType = declaredType;
-        getter3.type = getterType;
-        PropertyAccessorElementImpl setter3 = (field.setter as PropertyAccessorElementImpl);
-        if (setter3 != null) {
-          FunctionTypeImpl setterType = new FunctionTypeImpl.con1(setter3);
+        getter5.type = getterType;
+        PropertyAccessorElementImpl setter4 = field.setter as PropertyAccessorElementImpl;
+        if (setter4 != null) {
+          FunctionTypeImpl setterType = new FunctionTypeImpl.con1(setter4);
           setterType.returnType = VoidTypeImpl.instance;
           setterType.normalParameterTypes = <Type2> [declaredType];
-          setter3.type = setterType;
+          setter4.type = setterType;
         }
       }
     } else {
@@ -3586,11 +4353,11 @@
     if (identifier == null) {
       return null;
     }
-    Element element32 = identifier.element;
-    if (element32 is! ClassElementImpl) {
+    Element element38 = identifier.element;
+    if (element38 is! ClassElementImpl) {
       return null;
     }
-    return (element32 as ClassElementImpl);
+    return element38 as ClassElementImpl;
   }
   /**
    * Return an array containing all of the elements associated with the parameters in the given
@@ -3601,19 +4368,65 @@
   List<ParameterElement> getElements(FormalParameterList parameterList) {
     List<ParameterElement> elements = new List<ParameterElement>();
     for (FormalParameter parameter in parameterList.parameters) {
-      ParameterElement element33 = (parameter.identifier.element as ParameterElement);
-      if (element33 != null) {
-        elements.add(element33);
+      ParameterElement element39 = parameter.identifier.element as ParameterElement;
+      if (element39 != null) {
+        elements.add(element39);
       }
     }
     return new List.from(elements);
   }
   /**
+   * The number of type arguments in the given type name does not match the number of parameters in
+   * the corresponding class element. Return the error code that should be used to report this
+   * error.
+   * @param node the type name with the wrong number of type arguments
+   * @return the error code that should be used to report that the wrong number of type arguments
+   * were provided
+   */
+  ErrorCode getInvalidTypeParametersErrorCode(TypeName node) {
+    ASTNode parent17 = node.parent;
+    if (parent17 is ConstructorName) {
+      parent17 = parent17.parent;
+      if (parent17 is InstanceCreationExpression) {
+        if (((parent17 as InstanceCreationExpression)).isConst()) {
+          return CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS;
+        } else {
+          return CompileTimeErrorCode.NEW_WITH_INVALID_TYPE_PARAMETERS;
+        }
+      }
+    }
+    return StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS;
+  }
+  /**
+   * Given the multiple elements to which a single name could potentially be resolved, return the
+   * single interface type that should be used, or {@code null} if there is no clear choice.
+   * @param elements the elements to which a single name could potentially be resolved
+   * @return the single interface type that should be used for the type name
+   */
+  InterfaceType getType(List<Element> elements) {
+    InterfaceType type = null;
+    for (Element element in elements) {
+      if (element is ClassElement) {
+        if (type != null) {
+          return null;
+        }
+        type = ((element as ClassElement)).type;
+      }
+    }
+    return type;
+  }
+  /**
    * Return the type represented by the given type name.
    * @param typeName the type name representing the type to be returned
    * @return the type represented by the type name
    */
-  Type2 getType(TypeName typeName) => typeName.type;
+  Type2 getType4(TypeName typeName) {
+    Type2 type19 = typeName.type;
+    if (type19 == null) {
+      return _dynamicType;
+    }
+    return type19;
+  }
   /**
    * Return the type arguments associated with the given type.
    * @param type the type whole type arguments are to be returned
@@ -3634,7 +4447,7 @@
    */
   Object recordType(Expression expression, Type2 type) {
     if (type == null) {
-      expression.staticType = typeProvider.dynamicType;
+      expression.staticType = _dynamicType;
     } else {
       expression.staticType = type;
     }
@@ -3650,13 +4463,13 @@
    */
   void resolve(ClassElementImpl classElement, WithClause withClause, ImplementsClause implementsClause) {
     if (withClause != null) {
-      List<InterfaceType> mixinTypes2 = resolveTypes(withClause.mixinTypes, null, null, null);
+      List<InterfaceType> mixinTypes2 = resolveTypes(withClause.mixinTypes, CompileTimeErrorCode.MIXIN_OF_NON_CLASS, CompileTimeErrorCode.MIXIN_OF_NON_CLASS, null);
       if (classElement != null) {
         classElement.mixins = mixinTypes2;
       }
     }
     if (implementsClause != null) {
-      List<InterfaceType> interfaceTypes = resolveTypes(implementsClause.interfaces, null, null, null);
+      List<InterfaceType> interfaceTypes = resolveTypes(implementsClause.interfaces, CompileTimeErrorCode.IMPLEMENTS_NON_CLASS, CompileTimeErrorCode.IMPLEMENTS_NON_CLASS, null);
       if (classElement != null) {
         classElement.interfaces = interfaceTypes;
       }
@@ -3671,20 +4484,26 @@
    * @param nonInterfaceType the error to produce if the type is not an interface type
    * @return the type specified by the type name
    */
-  InterfaceType resolveType(TypeName typeName, ResolverErrorCode undefinedError, ResolverErrorCode nonTypeError, ResolverErrorCode nonInterfaceType) {
-    Identifier name15 = typeName.name;
-    Element element = nameScope.lookup(name15, definingLibrary);
+  InterfaceType resolveType(TypeName typeName, ErrorCode undefinedError, ErrorCode nonTypeError, ErrorCode nonInterfaceType) {
+    Identifier name16 = typeName.name;
+    Element element = nameScope.lookup(name16, definingLibrary);
     if (element == null) {
-      reportError(undefinedError, name15, []);
+      reportError(undefinedError, name16, [name16.name]);
     } else if (element is ClassElement) {
       Type2 classType = ((element as ClassElement)).type;
       typeName.type = classType;
       if (classType is InterfaceType) {
-        return (classType as InterfaceType);
+        return classType as InterfaceType;
       }
-      reportError(nonInterfaceType, name15, []);
+      reportError(nonInterfaceType, name16, [name16.name]);
+    } else if (element is MultiplyDefinedElement) {
+      List<Element> elements = ((element as MultiplyDefinedElement)).conflictingElements;
+      InterfaceType type = getType(elements);
+      if (type != null) {
+        typeName.type = type;
+      }
     } else {
-      reportError(nonTypeError, name15, []);
+      reportError(nonTypeError, name16, [name16.name]);
     }
     return null;
   }
@@ -3697,7 +4516,7 @@
    * @param nonInterfaceType the error to produce if the type is not an interface type
    * @return an array containing all of the types that were resolved.
    */
-  List<InterfaceType> resolveTypes(NodeList<TypeName> typeNames, ResolverErrorCode undefinedError, ResolverErrorCode nonTypeError, ResolverErrorCode nonInterfaceType) {
+  List<InterfaceType> resolveTypes(NodeList<TypeName> typeNames, ErrorCode undefinedError, ErrorCode nonTypeError, ErrorCode nonInterfaceType) {
     List<InterfaceType> types = new List<InterfaceType>();
     for (TypeName typeName in typeNames) {
       InterfaceType type = resolveType(typeName, undefinedError, nonTypeError, nonInterfaceType);
@@ -3707,16 +4526,17 @@
     }
     return new List.from(types);
   }
-  void setElement(Identifier typeName, Element element41) {
-    if (element41 != null) {
-      typeName.element = element41;
-      if (typeName is PrefixedIdentifier) {
-        PrefixedIdentifier identifier = (typeName as PrefixedIdentifier);
-        identifier.identifier.element = element41;
-        SimpleIdentifier prefix8 = identifier.prefix;
-        Element prefixElement = nameScope.lookup(prefix8, definingLibrary);
+  void setElement(Identifier typeName, Element element54) {
+    if (element54 != null) {
+      if (typeName is SimpleIdentifier) {
+        ((typeName as SimpleIdentifier)).element = element54;
+      } else if (typeName is PrefixedIdentifier) {
+        PrefixedIdentifier identifier = typeName as PrefixedIdentifier;
+        identifier.identifier.element = element54;
+        SimpleIdentifier prefix9 = identifier.prefix;
+        Element prefixElement = nameScope.lookup(prefix9, definingLibrary);
         if (prefixElement != null) {
-          prefix8.element = prefixElement;
+          prefix9.element = prefixElement;
         }
       }
     }
@@ -3728,31 +4548,41 @@
    * @param returnType the return type of the function, or {@code null} if no type was declared
    * @param parameters the elements representing the parameters to the function
    */
-  void setTypeInformation(FunctionTypeImpl functionType, TypeName returnType8, List<ParameterElement> parameters) {
+  void setTypeInformation(FunctionTypeImpl functionType, TypeName returnType12, List<ParameterElement> parameters) {
     List<Type2> normalParameterTypes = new List<Type2>();
     List<Type2> optionalParameterTypes = new List<Type2>();
     LinkedHashMap<String, Type2> namedParameterTypes = new LinkedHashMap<String, Type2>();
     for (ParameterElement parameter in parameters) {
-      if (parameter.parameterKind == ParameterKind.REQUIRED) {
-        normalParameterTypes.add(parameter.type);
-      } else if (parameter.parameterKind == ParameterKind.POSITIONAL) {
-        optionalParameterTypes.add(parameter.type);
-      } else if (parameter.parameterKind == ParameterKind.NAMED) {
-        namedParameterTypes[parameter.name] = parameter.type;
+      while (true) {
+        if (parameter.parameterKind == ParameterKind.REQUIRED) {
+          normalParameterTypes.add(parameter.type);
+        } else if (parameter.parameterKind == ParameterKind.POSITIONAL) {
+          optionalParameterTypes.add(parameter.type);
+        } else if (parameter.parameterKind == ParameterKind.NAMED) {
+          namedParameterTypes[parameter.name] = parameter.type;
+        }
+        break;
       }
     }
-    functionType.normalParameterTypes = new List.from(normalParameterTypes);
-    functionType.optionalParameterTypes = new List.from(optionalParameterTypes);
-    functionType.namedParameterTypes = namedParameterTypes;
-    if (returnType8 == null) {
-      functionType.returnType = typeProvider.dynamicType;
+    if (!normalParameterTypes.isEmpty) {
+      functionType.normalParameterTypes = new List.from(normalParameterTypes);
+    }
+    if (!optionalParameterTypes.isEmpty) {
+      functionType.optionalParameterTypes = new List.from(optionalParameterTypes);
+    }
+    if (!namedParameterTypes.isEmpty) {
+      functionType.namedParameterTypes = namedParameterTypes;
+    }
+    if (returnType12 == null) {
+      functionType.returnType = _dynamicType;
     } else {
-      functionType.returnType = returnType8.type;
+      functionType.returnType = returnType12.type;
     }
   }
 }
 /**
  * Instances of the class {@code ClassScope} implement the scope defined by a class.
+ * @coverage dart.engine.resolver
  */
 class ClassScope extends EnclosedScope {
   /**
@@ -3772,9 +4602,6 @@
     for (PropertyAccessorElement accessor in typeElement.accessors) {
       define(accessor);
     }
-    for (FieldElement field in typeElement.fields) {
-      define(field);
-    }
     for (MethodElement method in typeElement.methods) {
       define(method);
     }
@@ -3793,6 +4620,7 @@
 /**
  * Instances of the class {@code EnclosedScope} implement a scope that is lexically enclosed in
  * another scope.
+ * @coverage dart.engine.resolver
  */
 class EnclosedScope extends Scope {
   /**
@@ -3823,6 +4651,7 @@
 }
 /**
  * Instances of the class {@code FunctionScope} implement the scope defined by a function.
+ * @coverage dart.engine.resolver
  */
 class FunctionScope extends EnclosedScope {
   /**
@@ -3840,8 +4669,8 @@
   void defineParameters(ExecutableElement functionElement) {
     Scope parameterScope = enclosingScope;
     if (functionElement.enclosingElement is ExecutableElement) {
-      String name16 = functionElement.name;
-      if (name16 != null && !name16.isEmpty) {
+      String name17 = functionElement.name;
+      if (name17 != null && !name17.isEmpty) {
         parameterScope.define(functionElement);
       }
     }
@@ -3855,6 +4684,7 @@
 /**
  * Instances of the class {@code FunctionTypeScope} implement the scope defined by a function type
  * alias.
+ * @coverage dart.engine.resolver
  */
 class FunctionTypeScope extends EnclosedScope {
   /**
@@ -3862,14 +4692,14 @@
    * @param enclosingScope the scope in which this scope is lexically enclosed
    * @param typeElement the element representing the type alias represented by this scope
    */
-  FunctionTypeScope(Scope enclosingScope, TypeAliasElement typeElement) : super(new EnclosedScope(enclosingScope)) {
+  FunctionTypeScope(Scope enclosingScope, FunctionTypeAliasElement typeElement) : super(new EnclosedScope(enclosingScope)) {
     defineTypeParameters(typeElement);
   }
   /**
    * Define the type parameters for the function type alias.
    * @param typeElement the element representing the type represented by this scope
    */
-  void defineTypeParameters(TypeAliasElement typeElement) {
+  void defineTypeParameters(FunctionTypeAliasElement typeElement) {
     Scope parameterScope = enclosingScope;
     for (TypeVariableElement parameter in typeElement.typeVariables) {
       parameterScope.define(parameter);
@@ -3878,6 +4708,7 @@
 }
 /**
  * Instances of the class {@code LabelScope} represent a scope in which a single label is defined.
+ * @coverage dart.engine.resolver
  */
 class LabelScope {
   /**
@@ -3899,7 +4730,7 @@
   /**
    * The label element returned for scopes that can be the target of an unlabeled {@code break} or{@code continue}.
    */
-  static SimpleIdentifier _EMPTY_LABEL_IDENTIFIER = new SimpleIdentifier.full(new StringToken(TokenType.IDENTIFIER, "", 0));
+  static SimpleIdentifier _EMPTY_LABEL_IDENTIFIER = new SimpleIdentifier.full(new sc.StringToken(sc.TokenType.IDENTIFIER, "", 0));
   /**
    * Initialize a newly created scope to represent the potential target of an unlabeled{@code break} or {@code continue}.
    * @param outerScope the label scope enclosing the new label scope
@@ -3907,10 +4738,10 @@
    * @param onSwitchMember {@code true} if this label is associated with a {@code switch} member
    */
   LabelScope.con1(LabelScope outerScope, bool onSwitchStatement, bool onSwitchMember) {
-    _jtd_constructor_198_impl(outerScope, onSwitchStatement, onSwitchMember);
+    _jtd_constructor_248_impl(outerScope, onSwitchStatement, onSwitchMember);
   }
-  _jtd_constructor_198_impl(LabelScope outerScope, bool onSwitchStatement, bool onSwitchMember) {
-    _jtd_constructor_199_impl(outerScope, EMPTY_LABEL, new LabelElementImpl(_EMPTY_LABEL_IDENTIFIER, onSwitchStatement, onSwitchMember));
+  _jtd_constructor_248_impl(LabelScope outerScope, bool onSwitchStatement, bool onSwitchMember) {
+    _jtd_constructor_249_impl(outerScope, EMPTY_LABEL, new LabelElementImpl(_EMPTY_LABEL_IDENTIFIER, onSwitchStatement, onSwitchMember));
   }
   /**
    * Initialize a newly created scope to represent the given label.
@@ -3918,13 +4749,13 @@
    * @param label the label defined in this scope
    * @param element the element to which the label resolves
    */
-  LabelScope.con2(LabelScope outerScope2, String label3, LabelElement element18) {
-    _jtd_constructor_199_impl(outerScope2, label3, element18);
+  LabelScope.con2(LabelScope outerScope2, String label4, LabelElement element19) {
+    _jtd_constructor_249_impl(outerScope2, label4, element19);
   }
-  _jtd_constructor_199_impl(LabelScope outerScope2, String label3, LabelElement element18) {
+  _jtd_constructor_249_impl(LabelScope outerScope2, String label4, LabelElement element19) {
     this._outerScope = outerScope2;
-    this._label = label3;
-    this._element = element18;
+    this._label = label4;
+    this._element = element19;
   }
   /**
    * Return the label element corresponding to the given label, or {@code null} if the given label
@@ -3952,6 +4783,7 @@
 /**
  * Instances of the class {@code LibraryImportScope} represent the scope containing all of the names
  * available from imported libraries.
+ * @coverage dart.engine.resolver
  */
 class LibraryImportScope extends Scope {
   /**
@@ -4003,6 +4835,8 @@
         }
       }
     }
+    if (foundElement is MultiplyDefinedElementImpl) {
+    }
     if (foundElement != null) {
       defineWithoutChecking(foundElement);
     }
@@ -4024,6 +4858,7 @@
 /**
  * Instances of the class {@code LibraryScope} implement a scope containing all of the names defined
  * in a given library.
+ * @coverage dart.engine.resolver
  */
 class LibraryScope extends EnclosedScope {
   /**
@@ -4047,15 +4882,12 @@
     for (FunctionElement element in compilationUnit.functions) {
       define(element);
     }
-    for (TypeAliasElement element in compilationUnit.typeAliases) {
+    for (FunctionTypeAliasElement element in compilationUnit.functionTypeAliases) {
       define(element);
     }
     for (ClassElement element in compilationUnit.types) {
       define(element);
     }
-    for (VariableElement element in compilationUnit.variables) {
-      define(element);
-    }
   }
   /**
    * Add to this scope all of the names that are explicitly defined in the given library.
@@ -4075,13 +4907,18 @@
 /**
  * Instances of the class {@code Namespace} implement a mapping of identifiers to the elements
  * represented by those identifiers. Namespaces are the building blocks for scopes.
+ * @coverage dart.engine.resolver
  */
 class Namespace {
   /**
    * A table mapping names that are defined in this namespace to the element representing the thing
    * declared with that name.
    */
-  Map<String, Element> _definedNames = new Map<String, Element>();
+  Map<String, Element> _definedNames;
+  /**
+   * An empty namespace.
+   */
+  static Namespace EMPTY = new Namespace(new Map<String, Element>());
   /**
    * Initialize a newly created namespace to have the given defined names.
    * @param definedNames the mapping from names that are defined in this namespace to the
@@ -4101,11 +4938,12 @@
    * Return a table containing the same mappings as those defined by this namespace.
    * @return a table containing the same mappings as those defined by this namespace
    */
-  Map<String, Element> get definedNames => new Map<String, Element>();
+  Map<String, Element> get definedNames => new Map<String, Element>.from(_definedNames);
 }
 /**
  * Instances of the class {@code NamespaceBuilder} are used to build a {@code Namespace}. Namespace
  * builders are thread-safe and re-usable.
+ * @coverage dart.engine.resolver
  */
 class NamespaceBuilder {
   /**
@@ -4125,7 +4963,11 @@
    * @return the import namespace that was created
    */
   Namespace createImportNamespace(ImportElement element) {
-    Map<String, Element> definedNames = createExportMapping(element.importedLibrary, new Set<LibraryElement>());
+    LibraryElement importedLibrary4 = element.importedLibrary;
+    if (importedLibrary4 == null) {
+      return Namespace.EMPTY;
+    }
+    Map<String, Element> definedNames = createExportMapping(importedLibrary4, new Set<LibraryElement>());
     definedNames = apply(definedNames, element.combinators);
     definedNames = apply2(definedNames, element.prefix);
     return new Namespace(definedNames);
@@ -4167,9 +5009,9 @@
    * @param element the element to be added
    */
   void addIfPublic(Map<String, Element> definedNames, Element element) {
-    String name17 = element.name;
-    if (name17 != null && !Scope.isPrivateName(name17)) {
-      definedNames[name17] = element;
+    String name18 = element.name;
+    if (name18 != null && !Scope.isPrivateName(name18)) {
+      definedNames[name18] = element;
     }
   }
   /**
@@ -4186,13 +5028,13 @@
     for (FunctionElement element in compilationUnit.functions) {
       addIfPublic(definedNames, element);
     }
-    for (TypeAliasElement element in compilationUnit.typeAliases) {
+    for (FunctionTypeAliasElement element in compilationUnit.functionTypeAliases) {
       addIfPublic(definedNames, element);
     }
     for (ClassElement element in compilationUnit.types) {
       addIfPublic(definedNames, element);
     }
-    for (VariableElement element in compilationUnit.variables) {
+    for (VariableElement element in compilationUnit.topLevelVariables) {
       addIfPublic(definedNames, element);
     }
   }
@@ -4244,7 +5086,7 @@
       Map<String, Element> definedNames = new Map<String, Element>();
       for (ExportElement element in library.exports) {
         LibraryElement exportedLibrary3 = element.exportedLibrary;
-        if (!visitedElements.contains(exportedLibrary3)) {
+        if (exportedLibrary3 != null && !visitedElements.contains(exportedLibrary3)) {
           Map<String, Element> exportedNames = createExportMapping(exportedLibrary3, visitedElements);
           exportedNames = apply(exportedNames, element.combinators);
           addAll(definedNames, exportedNames);
@@ -4286,6 +5128,7 @@
 /**
  * The abstract class {@code Scope} defines the behavior common to name scopes used by the resolver
  * to determine which names are visible at any given point in the code.
+ * @coverage dart.engine.resolver
  */
 abstract class Scope {
   /**
@@ -4330,13 +5173,6 @@
     if (_definedNames.containsKey(name)) {
       errorListener.onError(getErrorForDuplicate(_definedNames[name], element));
     } else {
-      Element overriddenElement = lookup3(name, definingLibrary);
-      if (overriddenElement != null) {
-        AnalysisError error = getErrorForHiding(overriddenElement, element);
-        if (error != null) {
-          errorListener.onError(error);
-        }
-      }
       _definedNames[name] = element;
     }
   }
@@ -4368,15 +5204,7 @@
    * @param duplicate another element declared with the conflicting name
    * @return the error code used to report duplicate names within a scope
    */
-  AnalysisError getErrorForDuplicate(Element existing, Element duplicate) => new AnalysisError.con1(source, ResolverErrorCode.DUPLICATE_MEMBER_ERROR, [existing.name]);
-  /**
-   * Return the error code to be used when reporting that a name being defined locally hides a name
-   * defined in an outer scope.
-   * @param hidden the element whose visibility is being hidden
-   * @param hiding the element that is hiding the visibility of another declaration
-   * @return the error code used to report name hiding
-   */
-  AnalysisError getErrorForHiding(Element hidden, Element hiding) => new AnalysisError.con1(source, ResolverErrorCode.DUPLICATE_MEMBER_WARNING, [hidden.name]);
+  AnalysisError getErrorForDuplicate(Element existing, Element duplicate) => new AnalysisError.con2(source, duplicate.nameOffset, duplicate.name.length, CompileTimeErrorCode.DUPLICATE_DEFINITION, [existing.name]);
   /**
    * Return the listener that is to be informed when an error is encountered.
    * @return the listener that is to be informed when an error is encountered
@@ -4414,12 +5242,12 @@
    */
   String getName(Element element) {
     if (element is MethodElement) {
-      MethodElement method = (element as MethodElement);
+      MethodElement method = element as MethodElement;
       if (method.name == "-" && method.parameters.length == 0) {
         return UNARY_MINUS;
       }
     } else if (element is PropertyAccessorElement) {
-      PropertyAccessorElement accessor = (element as PropertyAccessorElement);
+      PropertyAccessorElement accessor = element as PropertyAccessorElement;
       if (accessor.isSetter()) {
         return "${accessor.name}${SETTER_SUFFIX}";
       }
@@ -4428,32 +5256,578 @@
   }
 }
 /**
+ * Instances of the class {@code ConstantVerifier} traverse an AST structure looking for additional
+ * errors and warnings not covered by the parser and resolver. In particular, it looks for errors
+ * and warnings related to constant expressions.
+ * @coverage dart.engine.resolver
+ */
+class ConstantVerifier extends RecursiveASTVisitor<Object> {
+  /**
+   * The error reporter by which errors will be reported.
+   */
+  ErrorReporter _errorReporter;
+  /**
+   * Initialize a newly created constant verifier.
+   * @param errorReporter the error reporter by which errors will be reported
+   */
+  ConstantVerifier(ErrorReporter errorReporter) {
+    this._errorReporter = errorReporter;
+  }
+  Object visitFunctionExpression(FunctionExpression node) {
+    super.visitFunctionExpression(node);
+    validateDefaultValues(node.parameters);
+    return null;
+  }
+  Object visitListLiteral(ListLiteral node) {
+    super.visitListLiteral(node);
+    if (node.modifier != null) {
+      for (Expression element in node.elements) {
+        validate(element, CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT);
+      }
+    }
+    return null;
+  }
+  Object visitMapLiteral(MapLiteral node) {
+    super.visitMapLiteral(node);
+    bool isConst = node.modifier != null;
+    Set<String> keys = new Set<String>();
+    for (MapLiteralEntry entry in node.entries) {
+      StringLiteral key4 = entry.key;
+      EvaluationResultImpl result = validate(key4, CompileTimeErrorCode.NON_CONSTANT_MAP_KEY);
+      if (result is ValidResult && ((result as ValidResult)).value is String) {
+        String value10 = ((result as ValidResult)).value as String;
+        if (keys.contains(value10)) {
+          _errorReporter.reportError(StaticWarningCode.EQUAL_KEYS_IN_MAP, key4, []);
+        } else {
+          javaSetAdd(keys, value10);
+        }
+      }
+      if (isConst) {
+        validate(entry.value, CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE);
+      }
+    }
+    return null;
+  }
+  Object visitMethodDeclaration(MethodDeclaration node) {
+    super.visitMethodDeclaration(node);
+    validateDefaultValues(node.parameters);
+    return null;
+  }
+  Object visitSwitchCase(SwitchCase node) {
+    super.visitSwitchCase(node);
+    validate(node.expression, CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION);
+    return null;
+  }
+  Object visitVariableDeclaration(VariableDeclaration node) {
+    super.visitVariableDeclaration(node);
+    Expression initializer4 = node.initializer;
+    if (initializer4 != null && node.isConst()) {
+      EvaluationResultImpl result = validate(initializer4, CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE);
+      VariableElementImpl element45 = node.element as VariableElementImpl;
+      element45.evaluationResult = result;
+    }
+    return null;
+  }
+  /**
+   * Validate that the given expression is a compile time constant. Return the value of the compile
+   * time constant, or {@code null} if the expression is not a compile time constant.
+   * @param expression the expression to be validated
+   * @param errorCode the error code to be used if the expression is not a compile time constant
+   * @return the value of the compile time constant
+   */
+  EvaluationResultImpl validate(Expression expression, ErrorCode errorCode4) {
+    EvaluationResultImpl result = expression.accept(new ConstantVisitor());
+    if (result is ErrorResult) {
+      for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) {
+        if (identical(data.errorCode, CompileTimeErrorCode.COMPILE_TIME_CONSTANT_RAISES_EXCEPTION_DIVIDE_BY_ZERO)) {
+          _errorReporter.reportError(data.errorCode, data.node, []);
+        } else {
+          _errorReporter.reportError(errorCode4, data.node, []);
+        }
+      }
+    }
+    return result;
+  }
+  /**
+   * Validate that the default value associated with each of the parameters in the given list is a
+   * compile time constant.
+   * @param parameters the list of parameters to be validated
+   */
+  void validateDefaultValues(FormalParameterList parameters14) {
+    if (parameters14 == null) {
+      return;
+    }
+    for (FormalParameter parameter in parameters14.parameters) {
+      if (parameter is DefaultFormalParameter) {
+        DefaultFormalParameter defaultParameter = parameter as DefaultFormalParameter;
+        Expression defaultValue2 = defaultParameter.defaultValue;
+        if (defaultValue2 != null) {
+          EvaluationResultImpl result = validate(defaultValue2, CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE);
+          if (defaultParameter.isConst()) {
+            VariableElementImpl element46 = parameter.element as VariableElementImpl;
+            element46.evaluationResult = result;
+          }
+        }
+      }
+    }
+  }
+}
+/**
+ * Instances of the class {@code ErrorVerifier} traverse an AST structure looking for additional
+ * errors and warnings not covered by the parser and resolver.
+ * @coverage dart.engine.resolver
+ */
+class ErrorVerifier extends RecursiveASTVisitor<Object> {
+  /**
+   * The error reporter by which errors will be reported.
+   */
+  ErrorReporter _errorReporter;
+  /**
+   * The current library that is being analyzed.
+   */
+  LibraryElement _currentLibrary;
+  /**
+   * The type representing the type 'dynamic'.
+   */
+  Type2 _dynamicType;
+  /**
+   * The object providing access to the types defined by the language.
+   */
+  TypeProvider _typeProvider;
+  /**
+   * The method or function that we are currently visiting, or {@code null} if we are not inside a
+   * method or function.
+   */
+  ExecutableElement _currentFunction;
+  ErrorVerifier(ErrorReporter errorReporter, LibraryElement currentLibrary, TypeProvider typeProvider) {
+    this._errorReporter = errorReporter;
+    this._currentLibrary = currentLibrary;
+    this._typeProvider = typeProvider;
+    _dynamicType = typeProvider.dynamicType;
+  }
+  Object visitArgumentDefinitionTest(ArgumentDefinitionTest node) {
+    checkForArgumentDefinitionTestNonParameter(node);
+    return super.visitArgumentDefinitionTest(node);
+  }
+  Object visitAssertStatement(AssertStatement node) {
+    checkForNonBoolExpression(node);
+    return super.visitAssertStatement(node);
+  }
+  Object visitAssignmentExpression(AssignmentExpression node) {
+    checkForInvalidAssignment(node);
+    return super.visitAssignmentExpression(node);
+  }
+  Object visitClassDeclaration(ClassDeclaration node) {
+    checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
+    return super.visitClassDeclaration(node);
+  }
+  Object visitClassTypeAlias(ClassTypeAlias node) {
+    checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
+    return super.visitClassTypeAlias(node);
+  }
+  Object visitConditionalExpression(ConditionalExpression node) {
+    checkForNonBoolCondition(node.condition);
+    return super.visitConditionalExpression(node);
+  }
+  Object visitConstructorDeclaration(ConstructorDeclaration node) {
+    ExecutableElement previousFunction = _currentFunction;
+    try {
+      _currentFunction = node.element;
+      checkForConstConstructorWithNonFinalField(node);
+      checkForConflictingConstructorNameAndMember(node);
+      return super.visitConstructorDeclaration(node);
+    } finally {
+      _currentFunction = previousFunction;
+    }
+  }
+  Object visitDoStatement(DoStatement node) {
+    checkForNonBoolCondition(node.condition);
+    return super.visitDoStatement(node);
+  }
+  Object visitFieldFormalParameter(FieldFormalParameter node) {
+    checkForConstFormalParameter(node);
+    return super.visitFieldFormalParameter(node);
+  }
+  Object visitFunctionDeclaration(FunctionDeclaration node) {
+    ExecutableElement previousFunction = _currentFunction;
+    try {
+      _currentFunction = node.element;
+      return super.visitFunctionDeclaration(node);
+    } finally {
+      _currentFunction = previousFunction;
+    }
+  }
+  Object visitFunctionExpression(FunctionExpression node) {
+    ExecutableElement previousFunction = _currentFunction;
+    try {
+      _currentFunction = node.element;
+      return super.visitFunctionExpression(node);
+    } finally {
+      _currentFunction = previousFunction;
+    }
+  }
+  Object visitFunctionTypeAlias(FunctionTypeAlias node) {
+    checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
+    return super.visitFunctionTypeAlias(node);
+  }
+  Object visitIfStatement(IfStatement node) {
+    checkForNonBoolCondition(node.condition);
+    return super.visitIfStatement(node);
+  }
+  Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+    ConstructorName constructorName4 = node.constructorName;
+    TypeName typeName = constructorName4.type;
+    Type2 type20 = typeName.type;
+    if (type20 is InterfaceType) {
+      InterfaceType interfaceType = type20 as InterfaceType;
+      checkForConstWithNonConst(node);
+      checkForConstOrNewWithAbstractClass(node, typeName, interfaceType);
+      checkForTypeArgumentNotMatchingBounds(node, constructorName4.element, typeName);
+    }
+    return super.visitInstanceCreationExpression(node);
+  }
+  Object visitMethodDeclaration(MethodDeclaration node) {
+    ExecutableElement previousFunction = _currentFunction;
+    try {
+      _currentFunction = node.element;
+      return super.visitMethodDeclaration(node);
+    } finally {
+      _currentFunction = previousFunction;
+    }
+  }
+  Object visitReturnStatement(ReturnStatement node) {
+    checkForReturnOfInvalidType(node);
+    return super.visitReturnStatement(node);
+  }
+  Object visitSimpleFormalParameter(SimpleFormalParameter node) {
+    checkForConstFormalParameter(node);
+    return super.visitSimpleFormalParameter(node);
+  }
+  Object visitSwitchStatement(SwitchStatement node) {
+    checkForCaseExpressionTypeImplementsEquals(node);
+    return super.visitSwitchStatement(node);
+  }
+  Object visitTypeParameter(TypeParameter node) {
+    checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME);
+    return super.visitTypeParameter(node);
+  }
+  Object visitVariableDeclarationList(VariableDeclarationList node) {
+    checkForBuiltInIdentifierAsName2(node);
+    return super.visitVariableDeclarationList(node);
+  }
+  Object visitWhileStatement(WhileStatement node) {
+    checkForNonBoolCondition(node.condition);
+    return super.visitWhileStatement(node);
+  }
+  /**
+   * This verifies that the passed argument definition test identifier is a parameter.
+   * @param node the {@link ArgumentDefinitionTest} to evaluate
+   * @return return <code>true</code> if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#ARGUMENT_DEFINITION_TEST_NON_PARAMETER
+   */
+  bool checkForArgumentDefinitionTestNonParameter(ArgumentDefinitionTest node) {
+    SimpleIdentifier identifier14 = node.identifier;
+    Element element47 = identifier14.element;
+    if (element47 != null && element47 is! ParameterElement) {
+      _errorReporter.reportError(CompileTimeErrorCode.ARGUMENT_DEFINITION_TEST_NON_PARAMETER, identifier14, [identifier14.name]);
+      return true;
+    }
+    return false;
+  }
+  /**
+   * This verifies that the passed identifier is not a keyword, and generates the passed error code
+   * on the identifier if it is a keyword.
+   * @param identifier the identifier to check to ensure that it is not a keyword
+   * @param errorCode if the passed identifier is a keyword then this error code is created on the
+   * identifier, the error code will be one of{@link CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_NAME},{@link CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME} or{@link CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME}
+   * @return return <code>true</code> if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_NAME
+   * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME
+   * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME
+   */
+  bool checkForBuiltInIdentifierAsName(SimpleIdentifier identifier, ErrorCode errorCode) {
+    sc.Token token13 = identifier.token;
+    if (identical(token13.type, sc.TokenType.KEYWORD)) {
+      _errorReporter.reportError(errorCode, identifier, [identifier.name]);
+      return true;
+    }
+    return false;
+  }
+  /**
+   * This verifies that the passed variable declaration list does not have a built-in identifier.
+   * @param node the variable declaration list to check
+   * @return return <code>true</code> if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE
+   */
+  bool checkForBuiltInIdentifierAsName2(VariableDeclarationList node) {
+    TypeName typeName = node.type;
+    if (typeName != null) {
+      Identifier identifier = typeName.name;
+      if (identifier is SimpleIdentifier) {
+        SimpleIdentifier simpleIdentifier = identifier as SimpleIdentifier;
+        sc.Token token14 = simpleIdentifier.token;
+        if (identical(token14.type, sc.TokenType.KEYWORD)) {
+          if (((token14 as sc.KeywordToken)).keyword != sc.Keyword.DYNAMIC) {
+            _errorReporter.reportError(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, identifier, [identifier.name]);
+            return true;
+          }
+        }
+      }
+    }
+    return false;
+  }
+  /**
+   * This verifies that the passed switch statement does not have a case expression with the
+   * operator '==' overridden.
+   * @param node the switch statement to evaluate
+   * @return return <code>true</code> if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS
+   */
+  bool checkForCaseExpressionTypeImplementsEquals(SwitchStatement node) {
+    Expression expression16 = node.expression;
+    Type2 type = expression16.staticType;
+    if (type != null && type != _typeProvider.intType && type != _typeProvider.stringType) {
+      Element element48 = type.element;
+      if (element48 is ClassElement) {
+        ClassElement classElement = element48 as ClassElement;
+        MethodElement method = classElement.lookUpMethod("==", _currentLibrary);
+        if (method != null && method.enclosingElement.type != _typeProvider.objectType) {
+          _errorReporter.reportError(CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS, expression16, [element48.name]);
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+  bool checkForConflictingConstructorNameAndMember(ConstructorDeclaration node) {
+    ConstructorElement constructorElement = node.element;
+    SimpleIdentifier constructorName = node.name;
+    if (constructorName != null && constructorElement != null && !constructorName.isSynthetic()) {
+      String name20 = constructorName.name;
+      ClassElement classElement = constructorElement.enclosingElement;
+      List<FieldElement> fields3 = classElement.fields;
+      for (FieldElement field in fields3) {
+        if (field.name == name20) {
+          _errorReporter.reportError(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD, node, [name20]);
+          return true;
+        }
+      }
+      List<MethodElement> methods3 = classElement.methods;
+      for (MethodElement method in methods3) {
+        if (method.name == name20) {
+          _errorReporter.reportError(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD, node, [name20]);
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+  /**
+   * This verifies that the passed constructor declaration is not 'const' if it has a non-final
+   * instance variable.
+   * @param node the instance creation expression to evaluate
+   * @return return <code>true</code> if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD
+   */
+  bool checkForConstConstructorWithNonFinalField(ConstructorDeclaration node) {
+    if (node.constKeyword == null) {
+      return false;
+    }
+    ConstructorElement constructorElement = node.element;
+    if (constructorElement != null) {
+      ClassElement classElement = constructorElement.enclosingElement;
+      List<FieldElement> elements = classElement.fields;
+      for (FieldElement field in elements) {
+        if (!field.isFinal() && !field.isConst() && !field.isSynthetic()) {
+          _errorReporter.reportError(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD, node, []);
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+  /**
+   * This verifies that the passed normal formal parameter is not 'const'.
+   * @param node the normal formal parameter to evaluate
+   * @return return <code>true</code> if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#CONST_FORMAL_PARAMETER
+   */
+  bool checkForConstFormalParameter(NormalFormalParameter node) {
+    if (node.isConst()) {
+      _errorReporter.reportError(CompileTimeErrorCode.CONST_FORMAL_PARAMETER, node, []);
+      return true;
+    }
+    return false;
+  }
+  /**
+   * This verifies that the passed instance creation expression is not being invoked on an abstract
+   * class.
+   * @param node the instance creation expression to evaluate
+   * @param typeName the {@link TypeName} of the {@link ConstructorName} from the{@link InstanceCreationExpression}, this is the AST node that the error is attached to
+   * @param type the type being constructed with this {@link InstanceCreationExpression}
+   * @return return <code>true</code> if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#CONST_WITH_ABSTRACT_CLASS
+   * @see StaticWarningCode#NEW_WITH_ABSTRACT_CLASS
+   */
+  bool checkForConstOrNewWithAbstractClass(InstanceCreationExpression node, TypeName typeName, InterfaceType type) {
+    if (type.element.isAbstract()) {
+      ConstructorElement element49 = node.element;
+      if (element49 != null && !element49.isFactory()) {
+        if (identical(((node.keyword as sc.KeywordToken)).keyword, sc.Keyword.CONST)) {
+          _errorReporter.reportError(StaticWarningCode.CONST_WITH_ABSTRACT_CLASS, typeName, []);
+        } else {
+          _errorReporter.reportError(StaticWarningCode.NEW_WITH_ABSTRACT_CLASS, typeName, []);
+        }
+        return true;
+      }
+    }
+    return false;
+  }
+  /**
+   * This verifies that if the passed instance creation expression is 'const', then it is not being
+   * invoked on a constructor that is not 'const'.
+   * @param node the instance creation expression to evaluate
+   * @return return <code>true</code> if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#CONST_WITH_NON_CONST
+   */
+  bool checkForConstWithNonConst(InstanceCreationExpression node) {
+    if (node.isConst() && !node.element.isConst()) {
+      _errorReporter.reportError(CompileTimeErrorCode.CONST_WITH_NON_CONST, node, []);
+      return true;
+    }
+    return false;
+  }
+  /**
+   * This verifies that the passed assignment expression represents a valid assignment.
+   * @param node the assignment expression to evaluate
+   * @return return <code>true</code> if and only if an error code is generated on the passed node
+   * @see StaticTypeWarningCode#INVALID_ASSIGNMENT
+   */
+  bool checkForInvalidAssignment(AssignmentExpression node) {
+    Expression lhs = node.leftHandSide;
+    Expression rhs = node.rightHandSide;
+    Type2 leftType = getType(lhs);
+    Type2 rightType = getType(rhs);
+    if (!rightType.isAssignableTo(leftType)) {
+      _errorReporter.reportError(StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [leftType.name, rightType.name]);
+      return true;
+    }
+    return false;
+  }
+  /**
+   * Checks to ensure that the expressions that need to be of type bool, are. Otherwise an error is
+   * reported on the expression.
+   * @param condition the conditional expression to test
+   * @return return <code>true</code> if and only if an error code is generated on the passed node
+   * @see StaticTypeWarningCode#NON_BOOL_CONDITION
+   */
+  bool checkForNonBoolCondition(Expression condition) {
+    Type2 conditionType = getType(condition);
+    if (conditionType != null && !conditionType.isAssignableTo(_typeProvider.boolType)) {
+      _errorReporter.reportError(StaticTypeWarningCode.NON_BOOL_CONDITION, condition, []);
+      return true;
+    }
+    return false;
+  }
+  /**
+   * This verifies that the passed assert statement has either a 'bool' or '() -> bool' input.
+   * @param node the assert statement to evaluate
+   * @return return <code>true</code> if and only if an error code is generated on the passed node
+   * @see StaticTypeWarningCode#NON_BOOL_EXPRESSION
+   */
+  bool checkForNonBoolExpression(AssertStatement node) {
+    Expression expression = node.condition;
+    Type2 type = getType(expression);
+    if (type is InterfaceType) {
+      if (!type.isAssignableTo(_typeProvider.boolType)) {
+        _errorReporter.reportError(StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression, []);
+        return true;
+      }
+    } else if (type is FunctionType) {
+      FunctionType functionType = type as FunctionType;
+      if (functionType.typeArguments.length == 0 && !functionType.returnType.isAssignableTo(_typeProvider.boolType)) {
+        _errorReporter.reportError(StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression, []);
+        return true;
+      }
+    }
+    return false;
+  }
+  /**
+   * This checks that the return type matches the type of the declared return type in the enclosing
+   * method or function.
+   * @param node the return statement to evaluate
+   * @return return <code>true</code> if and only if an error code is generated on the passed node
+   * @see StaticTypeWarningCode#RETURN_OF_INVALID_TYPE
+   */
+  bool checkForReturnOfInvalidType(ReturnStatement node) {
+    FunctionType functionType = _currentFunction == null ? null : _currentFunction.type;
+    Type2 expectedReturnType = functionType == null ? null : functionType.returnType;
+    Expression returnExpression = node.expression;
+    if (expectedReturnType != null && !expectedReturnType.isVoid() && returnExpression != null) {
+      Type2 actualReturnType = getType(returnExpression);
+      if (!actualReturnType.isAssignableTo(expectedReturnType)) {
+        _errorReporter.reportError(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [actualReturnType.name, expectedReturnType.name]);
+        return true;
+      }
+    }
+    return false;
+  }
+  /**
+   * This verifies that the type arguments in the passed instance creation expression are all within
+   * their bounds as specified by the class element where the constructor [that is being invoked] is
+   * declared.
+   * @param node the instance creation expression to evaluate
+   * @param typeName the {@link TypeName} of the {@link ConstructorName} from the{@link InstanceCreationExpression}, this is the AST node that the error is attached to
+   * @param constructorElement the {@link ConstructorElement} from the instance creation expression
+   * @return return <code>true</code> if and only if an error code is generated on the passed node
+   * @see StaticTypeWarningCode#TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
+   */
+  bool checkForTypeArgumentNotMatchingBounds(InstanceCreationExpression node, ConstructorElement constructorElement, TypeName typeName) {
+    if (typeName.typeArguments != null && constructorElement != null) {
+      NodeList<TypeName> typeNameArgList = typeName.typeArguments.arguments;
+      List<TypeVariableElement> boundingElts = constructorElement.enclosingElement.typeVariables;
+      int loopThroughIndex = Math.min(typeNameArgList.length, boundingElts.length);
+      for (int i = 0; i < loopThroughIndex; i++) {
+        TypeName argTypeName = typeNameArgList[i];
+        Type2 argType = argTypeName.type;
+        Type2 boundType = boundingElts[i].bound;
+        if (argType != null && boundType != null) {
+          if (!argType.isSubtypeOf(boundType)) {
+            _errorReporter.reportError(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, argTypeName, [argTypeName.name, boundingElts[i].name]);
+            return true;
+          }
+        }
+      }
+    }
+    return false;
+  }
+  /**
+   * Return the 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 type of the given expression
+   */
+  Type2 getType(Expression expression) {
+    Type2 type = expression.staticType;
+    return type == null ? _dynamicType : type;
+  }
+}
+/**
  * The enumeration {@code ResolverErrorCode} defines the error codes used for errors detected by the
  * resolver. The convention for this class is for the name of the error code to indicate the problem
  * that caused the error to be generated and for the error message to explain what is wrong and,
  * when appropriate, how the problem can be corrected.
+ * @coverage dart.engine.resolver
  */
 class ResolverErrorCode implements ErrorCode {
   static final ResolverErrorCode BREAK_LABEL_ON_SWITCH_MEMBER = new ResolverErrorCode('BREAK_LABEL_ON_SWITCH_MEMBER', 0, ErrorType.COMPILE_TIME_ERROR, "Break label resolves to case or default statement");
   static final ResolverErrorCode CANNOT_BE_RESOLVED = new ResolverErrorCode('CANNOT_BE_RESOLVED', 1, ErrorType.STATIC_WARNING, "Cannot resolve the name '%s'");
   static final ResolverErrorCode CONTINUE_LABEL_ON_SWITCH = new ResolverErrorCode('CONTINUE_LABEL_ON_SWITCH', 2, ErrorType.COMPILE_TIME_ERROR, "A continue label resolves to switch, must be loop or switch member");
-  /**
-   * It is a compile-time error if [the URI] is not a compile-time constant, or if [the URI]
-   * involves string interpolation.
-   */
-  static final ResolverErrorCode INVALID_URI = new ResolverErrorCode('INVALID_URI', 3, ErrorType.COMPILE_TIME_ERROR, "URI's used in directives must be compile time constants without interpolation expressions");
-  static final ResolverErrorCode LABEL_IN_OUTER_SCOPE = new ResolverErrorCode('LABEL_IN_OUTER_SCOPE', 4, ErrorType.COMPILE_TIME_ERROR, "Cannot reference label '%s' declared in an outer method or function");
-  static final ResolverErrorCode MISSING_LIBRARY_DIRECTIVE_IMPORTED = new ResolverErrorCode('MISSING_LIBRARY_DIRECTIVE_IMPORTED', 5, ErrorType.COMPILE_TIME_ERROR, "Libraries that are imported by other libraries must have a library directive");
-  static final ResolverErrorCode MISSING_LIBRARY_DIRECTIVE_WITH_PART = new ResolverErrorCode('MISSING_LIBRARY_DIRECTIVE_WITH_PART', 6, ErrorType.COMPILE_TIME_ERROR, "Libraries that have parts must have a library directive");
-  static final ResolverErrorCode MISSING_PART_OF_DIRECTIVE = new ResolverErrorCode('MISSING_PART_OF_DIRECTIVE', 7, ErrorType.COMPILE_TIME_ERROR, "The included part must have a part-of directive");
-  static final ResolverErrorCode NON_BOOLEAN_CONDITION = new ResolverErrorCode('NON_BOOLEAN_CONDITION', 8, ErrorType.STATIC_TYPE_WARNING, "Conditions must have a static type of 'bool'");
-  static final ResolverErrorCode PART_WITH_WRONG_LIBRARY_NAME = new ResolverErrorCode('PART_WITH_WRONG_LIBRARY_NAME', 9, ErrorType.STATIC_WARNING, "The included part appears to be part of the library '%s'");
-  static final ResolverErrorCode UNDEFINED_LABEL = new ResolverErrorCode('UNDEFINED_LABEL', 10, ErrorType.COMPILE_TIME_ERROR, "The label '%s' is not defined");
-  static final ResolverErrorCode DUPLICATE_MEMBER_ERROR = new ResolverErrorCode('DUPLICATE_MEMBER_ERROR', 11, ErrorType.COMPILE_TIME_ERROR, "Duplicate member '%s'");
-  static final ResolverErrorCode DUPLICATE_MEMBER_WARNING = new ResolverErrorCode('DUPLICATE_MEMBER_WARNING', 12, ErrorType.STATIC_WARNING, "Duplicate member '%s'");
-  static final List<ResolverErrorCode> values = [BREAK_LABEL_ON_SWITCH_MEMBER, CANNOT_BE_RESOLVED, CONTINUE_LABEL_ON_SWITCH, INVALID_URI, LABEL_IN_OUTER_SCOPE, MISSING_LIBRARY_DIRECTIVE_IMPORTED, MISSING_LIBRARY_DIRECTIVE_WITH_PART, MISSING_PART_OF_DIRECTIVE, NON_BOOLEAN_CONDITION, PART_WITH_WRONG_LIBRARY_NAME, UNDEFINED_LABEL, DUPLICATE_MEMBER_ERROR, DUPLICATE_MEMBER_WARNING];
+  static final ResolverErrorCode MISSING_LIBRARY_DIRECTIVE_WITH_PART = new ResolverErrorCode('MISSING_LIBRARY_DIRECTIVE_WITH_PART', 3, ErrorType.COMPILE_TIME_ERROR, "Libraries that have parts must have a library directive");
+  static final ResolverErrorCode MISSING_PART_OF_DIRECTIVE = new ResolverErrorCode('MISSING_PART_OF_DIRECTIVE', 4, ErrorType.COMPILE_TIME_ERROR, "The included part must have a part-of directive");
+  static final List<ResolverErrorCode> values = [BREAK_LABEL_ON_SWITCH_MEMBER, CANNOT_BE_RESOLVED, CONTINUE_LABEL_ON_SWITCH, MISSING_LIBRARY_DIRECTIVE_WITH_PART, MISSING_PART_OF_DIRECTIVE];
   final String __name;
   final int __ordinal;
+  int get ordinal => __ordinal;
   /**
    * The type of this error.
    */
diff --git a/pkg/analyzer-experimental/lib/src/generated/scanner.dart b/pkg/analyzer_experimental/lib/src/generated/scanner.dart
similarity index 97%
rename from pkg/analyzer-experimental/lib/src/generated/scanner.dart
rename to pkg/analyzer_experimental/lib/src/generated/scanner.dart
index f2bd02d..269367d 100644
--- a/pkg/analyzer-experimental/lib/src/generated/scanner.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/scanner.dart
@@ -10,7 +10,169 @@
 import 'instrumentation.dart';
 
 /**
+ * Instances of the abstract class {@code KeywordState} represent a state in a state machine used to
+ * scan keywords.
+ * @coverage dart.engine.parser
+ */
+class KeywordState {
+  /**
+   * An empty transition table used by leaf states.
+   */
+  static List<KeywordState> _EMPTY_TABLE = new List<KeywordState>(26);
+  /**
+   * The initial state in the state machine.
+   */
+  static KeywordState KEYWORD_STATE = createKeywordStateTable();
+  /**
+   * Create the next state in the state machine where we have already recognized the subset of
+   * strings in the given array of strings starting at the given offset and having the given length.
+   * All of these strings have a common prefix and the next character is at the given start index.
+   * @param start the index of the character in the strings used to transition to a new state
+   * @param strings an array containing all of the strings that will be recognized by the state
+   * machine
+   * @param offset the offset of the first string in the array that has the prefix that is assumed
+   * to have been recognized by the time we reach the state being built
+   * @param length the number of strings in the array that pass through the state being built
+   * @return the state that was created
+   */
+  static KeywordState computeKeywordStateTable(int start, List<String> strings, int offset, int length12) {
+    List<KeywordState> result = new List<KeywordState>(26);
+    assert(length12 != 0);
+    int chunk = 0x0;
+    int chunkStart = -1;
+    bool isLeaf = false;
+    for (int i = offset; i < offset + length12; i++) {
+      if (strings[i].length == start) {
+        isLeaf = true;
+      }
+      if (strings[i].length > start) {
+        int c = strings[i].codeUnitAt(start);
+        if (chunk != c) {
+          if (chunkStart != -1) {
+            result[chunk - 0x61] = computeKeywordStateTable(start + 1, strings, chunkStart, i - chunkStart);
+          }
+          chunkStart = i;
+          chunk = c;
+        }
+      }
+    }
+    if (chunkStart != -1) {
+      assert(result[chunk - 0x61] == null);
+      result[chunk - 0x61] = computeKeywordStateTable(start + 1, strings, chunkStart, offset + length12 - chunkStart);
+    } else {
+      assert(length12 == 1);
+      return new KeywordState(_EMPTY_TABLE, strings[offset]);
+    }
+    if (isLeaf) {
+      return new KeywordState(result, strings[offset]);
+    } else {
+      return new KeywordState(result, null);
+    }
+  }
+  /**
+   * Create the initial state in the state machine.
+   * @return the state that was created
+   */
+  static KeywordState createKeywordStateTable() {
+    List<Keyword> values2 = Keyword.values;
+    List<String> strings = new List<String>(values2.length);
+    for (int i = 0; i < values2.length; i++) {
+      strings[i] = values2[i].syntax;
+    }
+    strings.sort();
+    return computeKeywordStateTable(0, strings, 0, strings.length);
+  }
+  /**
+   * A table mapping characters to the states to which those characters will transition. (The index
+   * into the array is the offset from the character {@code 'a'} to the transitioning character.)
+   */
+  List<KeywordState> _table;
+  /**
+   * The keyword that is recognized by this state, or {@code null} if this state is not a terminal
+   * state.
+   */
+  Keyword _keyword2;
+  /**
+   * Initialize a newly created state to have the given transitions and to recognize the keyword
+   * with the given syntax.
+   * @param table a table mapping characters to the states to which those characters will transition
+   * @param syntax the syntax of the keyword that is recognized by the state
+   */
+  KeywordState(List<KeywordState> table, String syntax) {
+    this._table = table;
+    this._keyword2 = (syntax == null) ? null : Keyword.keywords[syntax];
+  }
+  /**
+   * Return the keyword that was recognized by this state, or {@code null} if this state does not
+   * recognized a keyword.
+   * @return the keyword that was matched by reaching this state
+   */
+  Keyword keyword() => _keyword2;
+  /**
+   * Return the state that follows this state on a transition of the given character, or{@code null} if there is no valid state reachable from this state with such a transition.
+   * @param c the character used to transition from this state to another state
+   * @return the state that follows this state on a transition of the given character
+   */
+  KeywordState next(int c) => _table[c - 0x61];
+}
+/**
+ * The enumeration {@code ScannerErrorCode} defines the error codes used for errors detected by the
+ * scanner.
+ * @coverage dart.engine.parser
+ */
+class ScannerErrorCode implements ErrorCode {
+  static final ScannerErrorCode ILLEGAL_CHARACTER = new ScannerErrorCode('ILLEGAL_CHARACTER', 0, "Illegal character %x");
+  static final ScannerErrorCode MISSING_DIGIT = new ScannerErrorCode('MISSING_DIGIT', 1, "Decimal digit expected");
+  static final ScannerErrorCode MISSING_HEX_DIGIT = new ScannerErrorCode('MISSING_HEX_DIGIT', 2, "Hexidecimal digit expected");
+  static final ScannerErrorCode MISSING_QUOTE = new ScannerErrorCode('MISSING_QUOTE', 3, "Expected quote (' or \")");
+  static final ScannerErrorCode UNTERMINATED_MULTI_LINE_COMMENT = new ScannerErrorCode('UNTERMINATED_MULTI_LINE_COMMENT', 4, "Unterminated multi-line comment");
+  static final ScannerErrorCode UNTERMINATED_STRING_LITERAL = new ScannerErrorCode('UNTERMINATED_STRING_LITERAL', 5, "Unterminated string literal");
+  static final List<ScannerErrorCode> values = [ILLEGAL_CHARACTER, MISSING_DIGIT, MISSING_HEX_DIGIT, MISSING_QUOTE, UNTERMINATED_MULTI_LINE_COMMENT, UNTERMINATED_STRING_LITERAL];
+  final String __name;
+  final int __ordinal;
+  int get ordinal => __ordinal;
+  /**
+   * The message template used to create the message to be displayed for this error.
+   */
+  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 this error
+   */
+  ScannerErrorCode(this.__name, this.__ordinal, String message) {
+    this._message = message;
+  }
+  ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
+  String get message => _message;
+  ErrorType get type => ErrorType.SYNTACTIC_ERROR;
+  bool needsRecompilation() => true;
+  String toString() => __name;
+}
+/**
+ * Instances of the class {@code TokenWithComment} represent a string token that is preceded by
+ * comments.
+ * @coverage dart.engine.parser
+ */
+class StringTokenWithComment extends StringToken {
+  /**
+   * The first comment in the list of comments that precede this token.
+   */
+  Token _precedingComment;
+  /**
+   * Initialize a newly created token to have the given type and offset and to be preceded by the
+   * comments reachable from the given comment.
+   * @param type the type of the token
+   * @param offset the offset from the beginning of the file to the first character in the token
+   * @param precedingComment the first comment in the list of comments that precede this token
+   */
+  StringTokenWithComment(TokenType type, String value, int offset, Token precedingComment) : super(type, value, offset) {
+    this._precedingComment = precedingComment;
+  }
+  Token get precedingComments => _precedingComment;
+}
+/**
  * The enumeration {@code Keyword} defines the keywords in the Dart programming language.
+ * @coverage dart.engine.parser
  */
 class Keyword {
   static final Keyword ASSERT = new Keyword.con1('ASSERT', 0, "assert");
@@ -62,6 +224,7 @@
   static final List<Keyword> values = [ASSERT, BREAK, CASE, CATCH, CLASS, CONST, CONTINUE, DEFAULT, DO, ELSE, EXTENDS, FALSE, FINAL, FINALLY, FOR, IF, IN, IS, NEW, NULL, RETURN, SUPER, SWITCH, THIS, THROW, TRUE, TRY, VAR, VOID, WHILE, WITH, ABSTRACT, AS, DYNAMIC, EXPORT, EXTERNAL, FACTORY, GET, IMPLEMENTS, IMPORT, LIBRARY, OPERATOR, PART, SET, STATIC, TYPEDEF];
   String __name;
   int __ordinal = 0;
+  int get ordinal => __ordinal;
   /**
    * The lexeme for the keyword.
    */
@@ -92,10 +255,10 @@
    * @param syntax the lexeme for the keyword
    */
   Keyword.con1(String ___name, int ___ordinal, String syntax) {
-    _jtd_constructor_224_impl(___name, ___ordinal, syntax);
+    _jtd_constructor_276_impl(___name, ___ordinal, syntax);
   }
-  _jtd_constructor_224_impl(String ___name, int ___ordinal, String syntax) {
-    _jtd_constructor_225_impl(___name, ___ordinal, syntax, false);
+  _jtd_constructor_276_impl(String ___name, int ___ordinal, String syntax) {
+    _jtd_constructor_277_impl(___name, ___ordinal, syntax, false);
   }
   /**
    * Initialize a newly created keyword to have the given syntax. The keyword is a pseudo-keyword if
@@ -104,9 +267,9 @@
    * @param isPseudoKeyword {@code true} if this keyword is a pseudo-keyword
    */
   Keyword.con2(String ___name, int ___ordinal, String syntax2, bool isPseudoKeyword) {
-    _jtd_constructor_225_impl(___name, ___ordinal, syntax2, isPseudoKeyword);
+    _jtd_constructor_277_impl(___name, ___ordinal, syntax2, isPseudoKeyword);
   }
-  _jtd_constructor_225_impl(String ___name, int ___ordinal, String syntax2, bool isPseudoKeyword) {
+  _jtd_constructor_277_impl(String ___name, int ___ordinal, String syntax2, bool isPseudoKeyword) {
     __name = ___name;
     __ordinal = ___ordinal;
     this._syntax = syntax2;
@@ -126,709 +289,6 @@
   String toString() => __name;
 }
 /**
- * Instances of the class {@code CharBufferScanner} implement a scanner that reads from a character
- * buffer. The scanning logic is in the superclass.
- */
-class CharBufferScanner extends AbstractScanner {
-  /**
-   * The buffer from which characters will be read.
-   */
-  CharBuffer _buffer;
-  /**
-   * The number of characters in the buffer.
-   */
-  int _bufferLength = 0;
-  /**
-   * The index of the last character that was read.
-   */
-  int _charOffset = 0;
-  /**
-   * Initialize a newly created scanner to scan the characters in the given character buffer.
-   * @param source the source being scanned
-   * @param buffer the buffer from which characters will be read
-   * @param errorListener the error listener that will be informed of any errors that are found
-   */
-  CharBufferScanner(Source source, CharBuffer buffer, AnalysisErrorListener errorListener) : super(source, errorListener) {
-    this._buffer = buffer;
-    this._bufferLength = buffer.length();
-    this._charOffset = -1;
-  }
-  int get offset => _charOffset;
-  int advance() {
-    if (_charOffset + 1 >= _bufferLength) {
-      return -1;
-    }
-    return _buffer.charAt(++_charOffset);
-  }
-  String getString(int start, int endDelta) => _buffer.subSequence(start, _charOffset + 1 + endDelta).toString();
-  int peek() {
-    if (_charOffset + 1 >= _buffer.length()) {
-      return -1;
-    }
-    return _buffer.charAt(_charOffset + 1);
-  }
-}
-/**
- * Instances of the class {@code TokenWithComment} represent a normal token that is preceded by
- * comments.
- */
-class TokenWithComment extends Token {
-  /**
-   * The first comment in the list of comments that precede this token.
-   */
-  Token _precedingComment;
-  /**
-   * Initialize a newly created token to have the given type and offset and to be preceded by the
-   * comments reachable from the given comment.
-   * @param type the type of the token
-   * @param offset the offset from the beginning of the file to the first character in the token
-   * @param precedingComment the first comment in the list of comments that precede this token
-   */
-  TokenWithComment(TokenType type, int offset, Token precedingComment) : super(type, offset) {
-    this._precedingComment = precedingComment;
-  }
-  Token get precedingComments => _precedingComment;
-}
-/**
- * Instances of the class {@code Token} represent a token that was scanned from the input. Each
- * token knows which token follows it, acting as the head of a linked list of tokens.
- */
-class Token {
-  /**
-   * The type of the token.
-   */
-  TokenType _type;
-  /**
-   * The offset from the beginning of the file to the first character in the token.
-   */
-  int _offset = 0;
-  /**
-   * The previous token in the token stream.
-   */
-  Token _previous;
-  /**
-   * The next token in the token stream.
-   */
-  Token _next;
-  /**
-   * Initialize a newly created token to have the given type and offset.
-   * @param type the type of the token
-   * @param offset the offset from the beginning of the file to the first character in the token
-   */
-  Token(TokenType type, int offset) {
-    this._type = type;
-    this._offset = offset;
-  }
-  /**
-   * Return the offset from the beginning of the file to the character after last character of the
-   * token.
-   * @return the offset from the beginning of the file to the first character after last character
-   * of the token
-   */
-  int get end => _offset + length;
-  /**
-   * Return the number of characters in the node's source range.
-   * @return the number of characters in the node's source range
-   */
-  int get length => lexeme.length;
-  /**
-   * Return the lexeme that represents this token.
-   * @return the lexeme that represents this token
-   */
-  String get lexeme => _type.lexeme;
-  /**
-   * Return the next token in the token stream.
-   * @return the next token in the token stream
-   */
-  Token get next => _next;
-  /**
-   * Return the offset from the beginning of the file to the first character in the token.
-   * @return the offset from the beginning of the file to the first character in the token
-   */
-  int get offset => _offset;
-  /**
-   * Return the first comment in the list of comments that precede this token, or {@code null} if
-   * there are no comments preceding this token. Additional comments can be reached by following the
-   * token stream using {@link #getNext()} until {@code null} is returned.
-   * @return the first comment in the list of comments that precede this token
-   */
-  Token get precedingComments => null;
-  /**
-   * Return the previous token in the token stream.
-   * @return the previous token in the token stream
-   */
-  Token get previous => _previous;
-  /**
-   * Return the type of the token.
-   * @return the type of the token
-   */
-  TokenType get type => _type;
-  /**
-   * Return {@code true} if this token represents an operator.
-   * @return {@code true} if this token represents an operator
-   */
-  bool isOperator() => _type.isOperator();
-  /**
-   * Return {@code true} if this token is a synthetic token. A synthetic token is a token that was
-   * introduced by the parser in order to recover from an error in the code. Synthetic tokens always
-   * have a length of zero ({@code 0}).
-   * @return {@code true} if this token is a synthetic token
-   */
-  bool isSynthetic() => length == 0;
-  /**
-   * Return {@code true} if this token represents an operator that can be defined by users.
-   * @return {@code true} if this token represents an operator that can be defined by users
-   */
-  bool isUserDefinableOperator() => _type.isUserDefinableOperator();
-  /**
-   * Set the next token in the token stream to the given token. This has the side-effect of setting
-   * this token to be the previous token for the given token.
-   * @param token the next token in the token stream
-   * @return the token that was passed in
-   */
-  Token setNext(Token token) {
-    _next = token;
-    token.previous = this;
-    return token;
-  }
-  /**
-   * Set the next token in the token stream to the given token without changing which token is the
-   * previous token for the given token.
-   * @param token the next token in the token stream
-   * @return the token that was passed in
-   */
-  Token setNextWithoutSettingPrevious(Token token) {
-    _next = token;
-    return token;
-  }
-  /**
-   * Set the offset from the beginning of the file to the first character in the token to the given
-   * offset.
-   * @param offset the offset from the beginning of the file to the first character in the token
-   */
-  void set offset(int offset3) {
-    this._offset = offset3;
-  }
-  String toString() => lexeme;
-  /**
-   * Return the value of this token. For keyword tokens, this is the keyword associated with the
-   * token, for other tokens it is the lexeme associated with the token.
-   * @return the value of this token
-   */
-  Object value() => _type.lexeme;
-  /**
-   * Set the previous token in the token stream to the given token.
-   * @param previous the previous token in the token stream
-   */
-  void set previous(Token previous2) {
-    this._previous = previous2;
-  }
-}
-/**
- * Instances of the class {@code KeywordToken} represent a keyword in the language.
- */
-class KeywordToken extends Token {
-  /**
-   * The keyword being represented by this token.
-   */
-  Keyword _keyword;
-  /**
-   * Initialize a newly created token to represent the given keyword.
-   * @param keyword the keyword being represented by this token
-   * @param offset the offset from the beginning of the file to the first character in the token
-   */
-  KeywordToken(Keyword keyword, int offset) : super(TokenType.KEYWORD, offset) {
-    this._keyword = keyword;
-  }
-  /**
-   * Return the keyword being represented by this token.
-   * @return the keyword being represented by this token
-   */
-  Keyword get keyword => _keyword;
-  String get lexeme => _keyword.syntax;
-  Keyword value() => _keyword;
-}
-/**
- * Instances of the class {@code StringToken} represent a token whose value is independent of it's
- * type.
- */
-class StringToken extends Token {
-  /**
-   * The lexeme represented by this token.
-   */
-  String _value2;
-  /**
-   * Initialize a newly created token to represent a token of the given type with the given value.
-   * @param type the type of the token
-   * @param value the lexeme represented by this token
-   * @param offset the offset from the beginning of the file to the first character in the token
-   */
-  StringToken(TokenType type, String value, int offset) : super(type, offset) {
-    this._value2 = value;
-  }
-  String get lexeme => _value2;
-  String value() => _value2;
-}
-/**
- * The enumeration {@code ScannerErrorCode} defines the error codes used for errors detected by the
- * scanner.
- */
-class ScannerErrorCode implements ErrorCode {
-  static final ScannerErrorCode ILLEGAL_CHARACTER = new ScannerErrorCode('ILLEGAL_CHARACTER', 0, "Illegal character %x");
-  static final ScannerErrorCode MISSING_DIGIT = new ScannerErrorCode('MISSING_DIGIT', 1, "Decimal digit expected");
-  static final ScannerErrorCode MISSING_HEX_DIGIT = new ScannerErrorCode('MISSING_HEX_DIGIT', 2, "Hexidecimal digit expected");
-  static final ScannerErrorCode MISSING_QUOTE = new ScannerErrorCode('MISSING_QUOTE', 3, "Expected quote (' or \")");
-  static final ScannerErrorCode UNTERMINATED_MULTI_LINE_COMMENT = new ScannerErrorCode('UNTERMINATED_MULTI_LINE_COMMENT', 4, "Unterminated multi-line comment");
-  static final ScannerErrorCode UNTERMINATED_STRING_LITERAL = new ScannerErrorCode('UNTERMINATED_STRING_LITERAL', 5, "Unterminated string literal");
-  static final List<ScannerErrorCode> values = [ILLEGAL_CHARACTER, MISSING_DIGIT, MISSING_HEX_DIGIT, MISSING_QUOTE, UNTERMINATED_MULTI_LINE_COMMENT, UNTERMINATED_STRING_LITERAL];
-  final String __name;
-  final int __ordinal;
-  /**
-   * The message template used to create the message to be displayed for this error.
-   */
-  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 this error
-   */
-  ScannerErrorCode(this.__name, this.__ordinal, String message) {
-    this._message = message;
-  }
-  ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
-  String get message => _message;
-  ErrorType get type => ErrorType.SYNTACTIC_ERROR;
-  bool needsRecompilation() => true;
-  String toString() => __name;
-}
-/**
- * Instances of the class {@code BeginTokenWithComment} represent a begin token that is preceded by
- * comments.
- */
-class BeginTokenWithComment extends BeginToken {
-  /**
-   * The first comment in the list of comments that precede this token.
-   */
-  Token _precedingComment;
-  /**
-   * Initialize a newly created token to have the given type and offset and to be preceded by the
-   * comments reachable from the given comment.
-   * @param type the type of the token
-   * @param offset the offset from the beginning of the file to the first character in the token
-   * @param precedingComment the first comment in the list of comments that precede this token
-   */
-  BeginTokenWithComment(TokenType type, int offset, Token precedingComment) : super(type, offset) {
-    this._precedingComment = precedingComment;
-  }
-  Token get precedingComments => _precedingComment;
-}
-/**
- * The enumeration {@code TokenType} defines the types of tokens that can be returned by the
- * scanner.
- */
-class TokenType {
-  /**
-   * The type of the token that marks the end of the input.
-   */
-  static final TokenType EOF = new TokenType_EOF('EOF', 0, null, "");
-  static final TokenType DOUBLE = new TokenType.con1('DOUBLE', 1);
-  static final TokenType HEXADECIMAL = new TokenType.con1('HEXADECIMAL', 2);
-  static final TokenType IDENTIFIER = new TokenType.con1('IDENTIFIER', 3);
-  static final TokenType INT = new TokenType.con1('INT', 4);
-  static final TokenType KEYWORD = new TokenType.con1('KEYWORD', 5);
-  static final TokenType MULTI_LINE_COMMENT = new TokenType.con1('MULTI_LINE_COMMENT', 6);
-  static final TokenType SCRIPT_TAG = new TokenType.con1('SCRIPT_TAG', 7);
-  static final TokenType SINGLE_LINE_COMMENT = new TokenType.con1('SINGLE_LINE_COMMENT', 8);
-  static final TokenType STRING = new TokenType.con1('STRING', 9);
-  static final TokenType AMPERSAND = new TokenType.con2('AMPERSAND', 10, TokenClass.BITWISE_AND_OPERATOR, "&");
-  static final TokenType AMPERSAND_AMPERSAND = new TokenType.con2('AMPERSAND_AMPERSAND', 11, TokenClass.LOGICAL_AND_OPERATOR, "&&");
-  static final TokenType AMPERSAND_EQ = new TokenType.con2('AMPERSAND_EQ', 12, TokenClass.ASSIGNMENT_OPERATOR, "&=");
-  static final TokenType AT = new TokenType.con2('AT', 13, null, "@");
-  static final TokenType BANG = new TokenType.con2('BANG', 14, TokenClass.UNARY_PREFIX_OPERATOR, "!");
-  static final TokenType BANG_EQ = new TokenType.con2('BANG_EQ', 15, TokenClass.EQUALITY_OPERATOR, "!=");
-  static final TokenType BAR = new TokenType.con2('BAR', 16, TokenClass.BITWISE_OR_OPERATOR, "|");
-  static final TokenType BAR_BAR = new TokenType.con2('BAR_BAR', 17, TokenClass.LOGICAL_OR_OPERATOR, "||");
-  static final TokenType BAR_EQ = new TokenType.con2('BAR_EQ', 18, TokenClass.ASSIGNMENT_OPERATOR, "|=");
-  static final TokenType COLON = new TokenType.con2('COLON', 19, null, ":");
-  static final TokenType COMMA = new TokenType.con2('COMMA', 20, null, ",");
-  static final TokenType CARET = new TokenType.con2('CARET', 21, TokenClass.BITWISE_XOR_OPERATOR, "^");
-  static final TokenType CARET_EQ = new TokenType.con2('CARET_EQ', 22, TokenClass.ASSIGNMENT_OPERATOR, "^=");
-  static final TokenType CLOSE_CURLY_BRACKET = new TokenType.con2('CLOSE_CURLY_BRACKET', 23, null, "}");
-  static final TokenType CLOSE_PAREN = new TokenType.con2('CLOSE_PAREN', 24, null, ")");
-  static final TokenType CLOSE_SQUARE_BRACKET = new TokenType.con2('CLOSE_SQUARE_BRACKET', 25, null, "]");
-  static final TokenType EQ = new TokenType.con2('EQ', 26, TokenClass.ASSIGNMENT_OPERATOR, "=");
-  static final TokenType EQ_EQ = new TokenType.con2('EQ_EQ', 27, TokenClass.EQUALITY_OPERATOR, "==");
-  static final TokenType FUNCTION = new TokenType.con2('FUNCTION', 28, null, "=>");
-  static final TokenType GT = new TokenType.con2('GT', 29, TokenClass.RELATIONAL_OPERATOR, ">");
-  static final TokenType GT_EQ = new TokenType.con2('GT_EQ', 30, TokenClass.RELATIONAL_OPERATOR, ">=");
-  static final TokenType GT_GT = new TokenType.con2('GT_GT', 31, TokenClass.SHIFT_OPERATOR, ">>");
-  static final TokenType GT_GT_EQ = new TokenType.con2('GT_GT_EQ', 32, TokenClass.ASSIGNMENT_OPERATOR, ">>=");
-  static final TokenType HASH = new TokenType.con2('HASH', 33, null, "#");
-  static final TokenType INDEX = new TokenType.con2('INDEX', 34, TokenClass.UNARY_POSTFIX_OPERATOR, "[]");
-  static final TokenType INDEX_EQ = new TokenType.con2('INDEX_EQ', 35, TokenClass.UNARY_POSTFIX_OPERATOR, "[]=");
-  static final TokenType IS = new TokenType.con2('IS', 36, TokenClass.RELATIONAL_OPERATOR, "is");
-  static final TokenType LT = new TokenType.con2('LT', 37, TokenClass.RELATIONAL_OPERATOR, "<");
-  static final TokenType LT_EQ = new TokenType.con2('LT_EQ', 38, TokenClass.RELATIONAL_OPERATOR, "<=");
-  static final TokenType LT_LT = new TokenType.con2('LT_LT', 39, TokenClass.SHIFT_OPERATOR, "<<");
-  static final TokenType LT_LT_EQ = new TokenType.con2('LT_LT_EQ', 40, TokenClass.ASSIGNMENT_OPERATOR, "<<=");
-  static final TokenType MINUS = new TokenType.con2('MINUS', 41, TokenClass.ADDITIVE_OPERATOR, "-");
-  static final TokenType MINUS_EQ = new TokenType.con2('MINUS_EQ', 42, TokenClass.ASSIGNMENT_OPERATOR, "-=");
-  static final TokenType MINUS_MINUS = new TokenType.con2('MINUS_MINUS', 43, TokenClass.UNARY_PREFIX_OPERATOR, "--");
-  static final TokenType OPEN_CURLY_BRACKET = new TokenType.con2('OPEN_CURLY_BRACKET', 44, null, "{");
-  static final TokenType OPEN_PAREN = new TokenType.con2('OPEN_PAREN', 45, TokenClass.UNARY_POSTFIX_OPERATOR, "(");
-  static final TokenType OPEN_SQUARE_BRACKET = new TokenType.con2('OPEN_SQUARE_BRACKET', 46, TokenClass.UNARY_POSTFIX_OPERATOR, "[");
-  static final TokenType PERCENT = new TokenType.con2('PERCENT', 47, TokenClass.MULTIPLICATIVE_OPERATOR, "%");
-  static final TokenType PERCENT_EQ = new TokenType.con2('PERCENT_EQ', 48, TokenClass.ASSIGNMENT_OPERATOR, "%=");
-  static final TokenType PERIOD = new TokenType.con2('PERIOD', 49, TokenClass.UNARY_POSTFIX_OPERATOR, ".");
-  static final TokenType PERIOD_PERIOD = new TokenType.con2('PERIOD_PERIOD', 50, TokenClass.CASCADE_OPERATOR, "..");
-  static final TokenType PLUS = new TokenType.con2('PLUS', 51, TokenClass.ADDITIVE_OPERATOR, "+");
-  static final TokenType PLUS_EQ = new TokenType.con2('PLUS_EQ', 52, TokenClass.ASSIGNMENT_OPERATOR, "+=");
-  static final TokenType PLUS_PLUS = new TokenType.con2('PLUS_PLUS', 53, TokenClass.UNARY_PREFIX_OPERATOR, "++");
-  static final TokenType QUESTION = new TokenType.con2('QUESTION', 54, TokenClass.CONDITIONAL_OPERATOR, "?");
-  static final TokenType SEMICOLON = new TokenType.con2('SEMICOLON', 55, null, ";");
-  static final TokenType SLASH = new TokenType.con2('SLASH', 56, TokenClass.MULTIPLICATIVE_OPERATOR, "/");
-  static final TokenType SLASH_EQ = new TokenType.con2('SLASH_EQ', 57, TokenClass.ASSIGNMENT_OPERATOR, "/=");
-  static final TokenType STAR = new TokenType.con2('STAR', 58, TokenClass.MULTIPLICATIVE_OPERATOR, "*");
-  static final TokenType STAR_EQ = new TokenType.con2('STAR_EQ', 59, TokenClass.ASSIGNMENT_OPERATOR, "*=");
-  static final TokenType STRING_INTERPOLATION_EXPRESSION = new TokenType.con2('STRING_INTERPOLATION_EXPRESSION', 60, null, "\${");
-  static final TokenType STRING_INTERPOLATION_IDENTIFIER = new TokenType.con2('STRING_INTERPOLATION_IDENTIFIER', 61, null, "\$");
-  static final TokenType TILDE = new TokenType.con2('TILDE', 62, TokenClass.UNARY_PREFIX_OPERATOR, "~");
-  static final TokenType TILDE_SLASH = new TokenType.con2('TILDE_SLASH', 63, TokenClass.MULTIPLICATIVE_OPERATOR, "~/");
-  static final TokenType TILDE_SLASH_EQ = new TokenType.con2('TILDE_SLASH_EQ', 64, TokenClass.ASSIGNMENT_OPERATOR, "~/=");
-  static final TokenType BACKPING = new TokenType.con2('BACKPING', 65, null, "`");
-  static final TokenType BACKSLASH = new TokenType.con2('BACKSLASH', 66, null, "\\");
-  static final TokenType PERIOD_PERIOD_PERIOD = new TokenType.con2('PERIOD_PERIOD_PERIOD', 67, null, "...");
-  static final List<TokenType> values = [EOF, DOUBLE, HEXADECIMAL, IDENTIFIER, INT, KEYWORD, MULTI_LINE_COMMENT, SCRIPT_TAG, SINGLE_LINE_COMMENT, STRING, AMPERSAND, AMPERSAND_AMPERSAND, AMPERSAND_EQ, AT, BANG, BANG_EQ, BAR, BAR_BAR, BAR_EQ, COLON, COMMA, CARET, CARET_EQ, CLOSE_CURLY_BRACKET, CLOSE_PAREN, CLOSE_SQUARE_BRACKET, EQ, EQ_EQ, FUNCTION, GT, GT_EQ, GT_GT, GT_GT_EQ, HASH, INDEX, INDEX_EQ, IS, LT, LT_EQ, LT_LT, LT_LT_EQ, MINUS, MINUS_EQ, MINUS_MINUS, OPEN_CURLY_BRACKET, OPEN_PAREN, OPEN_SQUARE_BRACKET, PERCENT, PERCENT_EQ, PERIOD, PERIOD_PERIOD, PLUS, PLUS_EQ, PLUS_PLUS, QUESTION, SEMICOLON, SLASH, SLASH_EQ, STAR, STAR_EQ, STRING_INTERPOLATION_EXPRESSION, STRING_INTERPOLATION_IDENTIFIER, TILDE, TILDE_SLASH, TILDE_SLASH_EQ, BACKPING, BACKSLASH, PERIOD_PERIOD_PERIOD];
-  String __name;
-  int __ordinal = 0;
-  /**
-   * The class of the token.
-   */
-  TokenClass _tokenClass;
-  /**
-   * The lexeme that defines this type of token, or {@code null} if there is more than one possible
-   * lexeme for this type of token.
-   */
-  String _lexeme;
-  TokenType.con1(String ___name, int ___ordinal) {
-    _jtd_constructor_236_impl(___name, ___ordinal);
-  }
-  _jtd_constructor_236_impl(String ___name, int ___ordinal) {
-    _jtd_constructor_237_impl(___name, ___ordinal, TokenClass.NO_CLASS, null);
-  }
-  TokenType.con2(String ___name, int ___ordinal, TokenClass tokenClass2, String lexeme2) {
-    _jtd_constructor_237_impl(___name, ___ordinal, tokenClass2, lexeme2);
-  }
-  _jtd_constructor_237_impl(String ___name, int ___ordinal, TokenClass tokenClass2, String lexeme2) {
-    __name = ___name;
-    __ordinal = ___ordinal;
-    this._tokenClass = tokenClass2 == null ? TokenClass.NO_CLASS : tokenClass2;
-    this._lexeme = lexeme2;
-  }
-  /**
-   * Return the lexeme that defines this type of token, or {@code null} if there is more than one
-   * possible lexeme for this type of token.
-   * @return the lexeme that defines this type of token
-   */
-  String get lexeme => _lexeme;
-  /**
-   * Return the precedence of the token, or {@code 0} if the token does not represent an operator.
-   * @return the precedence of the token
-   */
-  int get precedence => _tokenClass.precedence;
-  /**
-   * Return {@code true} if this type of token represents an additive operator.
-   * @return {@code true} if this type of token represents an additive operator
-   */
-  bool isAdditiveOperator() => identical(_tokenClass, TokenClass.ADDITIVE_OPERATOR);
-  /**
-   * Return {@code true} if this type of token represents an assignment operator.
-   * @return {@code true} if this type of token represents an assignment operator
-   */
-  bool isAssignmentOperator() => identical(_tokenClass, TokenClass.ASSIGNMENT_OPERATOR);
-  /**
-   * Return {@code true} if this type of token represents an associative operator. An associative
-   * operator is an operator for which the following equality is true:{@code (a * b) * c == a * (b * c)}. In other words, if the result of applying the operator to
-   * multiple operands does not depend on the order in which those applications occur.
-   * <p>
-   * Note: This method considers the logical-and and logical-or operators to be associative, even
-   * though the order in which the application of those operators can have an effect because
-   * evaluation of the right-hand operand is conditional.
-   * @return {@code true} if this type of token represents an associative operator
-   */
-  bool isAssociativeOperator() => identical(this, AMPERSAND) || identical(this, AMPERSAND_AMPERSAND) || identical(this, BAR) || identical(this, BAR_BAR) || identical(this, CARET) || identical(this, PLUS) || identical(this, STAR);
-  /**
-   * Return {@code true} if this type of token represents an equality operator.
-   * @return {@code true} if this type of token represents an equality operator
-   */
-  bool isEqualityOperator() => identical(_tokenClass, TokenClass.EQUALITY_OPERATOR);
-  /**
-   * Return {@code true} if this type of token represents an increment operator.
-   * @return {@code true} if this type of token represents an increment operator
-   */
-  bool isIncrementOperator() => identical(_lexeme, "++") || identical(_lexeme, "--");
-  /**
-   * Return {@code true} if this type of token represents a multiplicative operator.
-   * @return {@code true} if this type of token represents a multiplicative operator
-   */
-  bool isMultiplicativeOperator() => identical(_tokenClass, TokenClass.MULTIPLICATIVE_OPERATOR);
-  /**
-   * Return {@code true} if this token type represents an operator.
-   * @return {@code true} if this token type represents an operator
-   */
-  bool isOperator() => _tokenClass != TokenClass.NO_CLASS && this != OPEN_PAREN && this != OPEN_SQUARE_BRACKET && this != PERIOD;
-  /**
-   * Return {@code true} if this type of token represents a relational operator.
-   * @return {@code true} if this type of token represents a relational operator
-   */
-  bool isRelationalOperator() => identical(_tokenClass, TokenClass.RELATIONAL_OPERATOR);
-  /**
-   * Return {@code true} if this type of token represents a shift operator.
-   * @return {@code true} if this type of token represents a shift operator
-   */
-  bool isShiftOperator() => identical(_tokenClass, TokenClass.SHIFT_OPERATOR);
-  /**
-   * Return {@code true} if this type of token represents a unary postfix operator.
-   * @return {@code true} if this type of token represents a unary postfix operator
-   */
-  bool isUnaryPostfixOperator() => identical(_tokenClass, TokenClass.UNARY_POSTFIX_OPERATOR);
-  /**
-   * Return {@code true} if this type of token represents a unary prefix operator.
-   * @return {@code true} if this type of token represents a unary prefix operator
-   */
-  bool isUnaryPrefixOperator() => identical(_tokenClass, TokenClass.UNARY_PREFIX_OPERATOR);
-  /**
-   * Return {@code true} if this token type represents an operator that can be defined by users.
-   * @return {@code true} if this token type represents an operator that can be defined by users
-   */
-  bool isUserDefinableOperator() => identical(_lexeme, "==") || identical(_lexeme, "~") || identical(_lexeme, "[]") || identical(_lexeme, "[]=") || identical(_lexeme, "*") || identical(_lexeme, "/") || identical(_lexeme, "%") || identical(_lexeme, "~/") || identical(_lexeme, "+") || identical(_lexeme, "-") || identical(_lexeme, "<<") || identical(_lexeme, ">>") || identical(_lexeme, ">=") || identical(_lexeme, ">") || identical(_lexeme, "<=") || identical(_lexeme, "<") || identical(_lexeme, "&") || identical(_lexeme, "^") || identical(_lexeme, "|");
-  String toString() => __name;
-}
-class TokenType_EOF extends TokenType {
-  TokenType_EOF(String ___name, int ___ordinal, TokenClass arg0, String arg1) : super.con2(___name, ___ordinal, arg0, arg1);
-  String toString() => "-eof-";
-}
-/**
- * Instances of the class {@code TokenWithComment} represent a string token that is preceded by
- * comments.
- */
-class StringTokenWithComment extends StringToken {
-  /**
-   * The first comment in the list of comments that precede this token.
-   */
-  Token _precedingComment;
-  /**
-   * Initialize a newly created token to have the given type and offset and to be preceded by the
-   * comments reachable from the given comment.
-   * @param type the type of the token
-   * @param offset the offset from the beginning of the file to the first character in the token
-   * @param precedingComment the first comment in the list of comments that precede this token
-   */
-  StringTokenWithComment(TokenType type, String value, int offset, Token precedingComment) : super(type, value, offset) {
-    this._precedingComment = precedingComment;
-  }
-  Token get precedingComments => _precedingComment;
-}
-/**
- * Instances of the class {@code BeginToken} represent the opening half of a grouping pair of
- * tokens. This is used for curly brackets ('{'), parentheses ('('), and square brackets ('[').
- */
-class BeginToken extends Token {
-  /**
-   * The token that corresponds to this token.
-   */
-  Token _endToken;
-  /**
-   * Initialize a newly created token representing the opening half of a grouping pair of tokens.
-   * @param type the type of the token
-   * @param offset the offset from the beginning of the file to the first character in the token
-   */
-  BeginToken(TokenType type, int offset) : super(type, offset) {
-    assert((identical(type, TokenType.OPEN_CURLY_BRACKET) || identical(type, TokenType.OPEN_PAREN) || identical(type, TokenType.OPEN_SQUARE_BRACKET) || identical(type, TokenType.STRING_INTERPOLATION_EXPRESSION)));
-  }
-  /**
-   * Return the token that corresponds to this token.
-   * @return the token that corresponds to this token
-   */
-  Token get endToken => _endToken;
-  /**
-   * Set the token that corresponds to this token to the given token.
-   * @param token the token that corresponds to this token
-   */
-  void set endToken(Token token) {
-    this._endToken = token;
-  }
-}
-/**
- * The enumeration {@code TokenClass} represents classes (or groups) of tokens with a similar use.
- */
-class TokenClass {
-  /**
-   * A value used to indicate that the token type is not part of any specific class of token.
-   */
-  static final TokenClass NO_CLASS = new TokenClass.con1('NO_CLASS', 0);
-  /**
-   * A value used to indicate that the token type is an additive operator.
-   */
-  static final TokenClass ADDITIVE_OPERATOR = new TokenClass.con2('ADDITIVE_OPERATOR', 1, 12);
-  /**
-   * A value used to indicate that the token type is an assignment operator.
-   */
-  static final TokenClass ASSIGNMENT_OPERATOR = new TokenClass.con2('ASSIGNMENT_OPERATOR', 2, 1);
-  /**
-   * A value used to indicate that the token type is a bitwise-and operator.
-   */
-  static final TokenClass BITWISE_AND_OPERATOR = new TokenClass.con2('BITWISE_AND_OPERATOR', 3, 8);
-  /**
-   * A value used to indicate that the token type is a bitwise-or operator.
-   */
-  static final TokenClass BITWISE_OR_OPERATOR = new TokenClass.con2('BITWISE_OR_OPERATOR', 4, 6);
-  /**
-   * A value used to indicate that the token type is a bitwise-xor operator.
-   */
-  static final TokenClass BITWISE_XOR_OPERATOR = new TokenClass.con2('BITWISE_XOR_OPERATOR', 5, 7);
-  /**
-   * A value used to indicate that the token type is a cascade operator.
-   */
-  static final TokenClass CASCADE_OPERATOR = new TokenClass.con2('CASCADE_OPERATOR', 6, 2);
-  /**
-   * A value used to indicate that the token type is a conditional operator.
-   */
-  static final TokenClass CONDITIONAL_OPERATOR = new TokenClass.con2('CONDITIONAL_OPERATOR', 7, 3);
-  /**
-   * A value used to indicate that the token type is an equality operator.
-   */
-  static final TokenClass EQUALITY_OPERATOR = new TokenClass.con2('EQUALITY_OPERATOR', 8, 9);
-  /**
-   * A value used to indicate that the token type is a logical-and operator.
-   */
-  static final TokenClass LOGICAL_AND_OPERATOR = new TokenClass.con2('LOGICAL_AND_OPERATOR', 9, 5);
-  /**
-   * A value used to indicate that the token type is a logical-or operator.
-   */
-  static final TokenClass LOGICAL_OR_OPERATOR = new TokenClass.con2('LOGICAL_OR_OPERATOR', 10, 4);
-  /**
-   * A value used to indicate that the token type is a multiplicative operator.
-   */
-  static final TokenClass MULTIPLICATIVE_OPERATOR = new TokenClass.con2('MULTIPLICATIVE_OPERATOR', 11, 13);
-  /**
-   * A value used to indicate that the token type is a relational operator.
-   */
-  static final TokenClass RELATIONAL_OPERATOR = new TokenClass.con2('RELATIONAL_OPERATOR', 12, 10);
-  /**
-   * A value used to indicate that the token type is a shift operator.
-   */
-  static final TokenClass SHIFT_OPERATOR = new TokenClass.con2('SHIFT_OPERATOR', 13, 11);
-  /**
-   * A value used to indicate that the token type is a unary operator.
-   */
-  static final TokenClass UNARY_POSTFIX_OPERATOR = new TokenClass.con2('UNARY_POSTFIX_OPERATOR', 14, 15);
-  /**
-   * A value used to indicate that the token type is a unary operator.
-   */
-  static final TokenClass UNARY_PREFIX_OPERATOR = new TokenClass.con2('UNARY_PREFIX_OPERATOR', 15, 14);
-  static final List<TokenClass> values = [NO_CLASS, ADDITIVE_OPERATOR, ASSIGNMENT_OPERATOR, BITWISE_AND_OPERATOR, BITWISE_OR_OPERATOR, BITWISE_XOR_OPERATOR, CASCADE_OPERATOR, CONDITIONAL_OPERATOR, EQUALITY_OPERATOR, LOGICAL_AND_OPERATOR, LOGICAL_OR_OPERATOR, MULTIPLICATIVE_OPERATOR, RELATIONAL_OPERATOR, SHIFT_OPERATOR, UNARY_POSTFIX_OPERATOR, UNARY_PREFIX_OPERATOR];
-  String __name;
-  int __ordinal = 0;
-  /**
-   * The precedence of tokens of this class, or {@code 0} if the such tokens do not represent an
-   * operator.
-   */
-  int _precedence = 0;
-  TokenClass.con1(String ___name, int ___ordinal) {
-    _jtd_constructor_234_impl(___name, ___ordinal);
-  }
-  _jtd_constructor_234_impl(String ___name, int ___ordinal) {
-    _jtd_constructor_235_impl(___name, ___ordinal, 0);
-  }
-  TokenClass.con2(String ___name, int ___ordinal, int precedence2) {
-    _jtd_constructor_235_impl(___name, ___ordinal, precedence2);
-  }
-  _jtd_constructor_235_impl(String ___name, int ___ordinal, int precedence2) {
-    __name = ___name;
-    __ordinal = ___ordinal;
-    this._precedence = precedence2;
-  }
-  /**
-   * Return the precedence of tokens of this class, or {@code 0} if the such tokens do not represent
-   * an operator.
-   * @return the precedence of tokens of this class
-   */
-  int get precedence => _precedence;
-  String toString() => __name;
-}
-/**
- * Instances of the class {@code StringScanner} implement a scanner that reads from a string. The
- * scanning logic is in the superclass.
- */
-class StringScanner extends AbstractScanner {
-  /**
-   * The offset from the beginning of the file to the beginning of the source being scanned.
-   */
-  int _offsetDelta = 0;
-  /**
-   * The string from which characters will be read.
-   */
-  String _string;
-  /**
-   * The number of characters in the string.
-   */
-  int _stringLength = 0;
-  /**
-   * The index, relative to the string, of the last character that was read.
-   */
-  int _charOffset = 0;
-  /**
-   * Initialize a newly created scanner to scan the characters in the given string.
-   * @param source the source being scanned
-   * @param string the string from which characters will be read
-   * @param errorListener the error listener that will be informed of any errors that are found
-   */
-  StringScanner(Source source, String string, AnalysisErrorListener errorListener) : super(source, errorListener) {
-    this._offsetDelta = 0;
-    this._string = string;
-    this._stringLength = string.length;
-    this._charOffset = -1;
-  }
-  int get offset => _offsetDelta + _charOffset;
-  /**
-   * Record that the source begins on the given line and column at the given offset. The line starts
-   * for lines before the given line will not be correct.
-   * <p>
-   * This method must be invoked at most one time and must be invoked before scanning begins. The
-   * values provided must be sensible. The results are undefined if these conditions are violated.
-   * @param line the one-based index of the line containing the first character of the source
-   * @param column the one-based index of the column in which the first character of the source
-   * occurs
-   * @param offset the zero-based offset from the beginning of the larger context to the first
-   * character of the source
-   */
-  void setSourceStart(int line, int column, int offset) {
-    if (line < 1 || column < 1 || offset < 0 || (line + column - 2) >= offset) {
-      return;
-    }
-    _offsetDelta = 1;
-    for (int i = 2; i < line; i++) {
-      recordStartOfLine();
-    }
-    _offsetDelta = offset - column + 1;
-    recordStartOfLine();
-    _offsetDelta = offset;
-  }
-  int advance() {
-    if (_charOffset + 1 >= _stringLength) {
-      return -1;
-    }
-    return _string.codeUnitAt(++_charOffset);
-  }
-  String getString(int start, int endDelta) => _string.substring(start - _offsetDelta, _charOffset + 1 + endDelta);
-  int peek() {
-    if (_charOffset + 1 >= _string.length) {
-      return -1;
-    }
-    return _string.codeUnitAt(_charOffset + 1);
-  }
-}
-/**
  * The abstract class {@code AbstractScanner} implements a scanner for Dart code. Subclasses are
  * required to implement the interface used to access the characters being scanned.
  * <p>
@@ -837,6 +297,7 @@
  * should be scanned as a single left-shift operator or as two left angle brackets. This scanner
  * does not have any context, so it always resolves such conflicts by scanning the longest possible
  * token.
+ * @coverage dart.engine.parser
  */
 abstract class AbstractScanner {
   /**
@@ -920,14 +381,11 @@
    * @return the first token in the list of tokens that were produced
    */
   Token tokenize() {
-    int startTime = System.currentTimeMillis();
     int next = advance();
     while (next != -1) {
       next = bigSwitch(next);
     }
     appendEofToken();
-    int endTime = System.currentTimeMillis();
-    Instrumentation.metric2("Engine-Scanner", endTime - startTime).with3("chars", offset).log();
     return firstToken();
   }
   /**
@@ -976,12 +434,12 @@
       _lastComment = _lastComment.setNext(new StringToken(type, value, _tokenStart));
     }
   }
-  void appendEndToken(TokenType type26, TokenType beginType) {
+  void appendEndToken(TokenType type33, TokenType beginType) {
     Token token;
     if (_firstComment == null) {
-      token = new Token(type26, _tokenStart);
+      token = new Token(type33, _tokenStart);
     } else {
-      token = new TokenWithComment(type26, _tokenStart, _firstComment);
+      token = new TokenWithComment(type33, _tokenStart, _firstComment);
       _firstComment = null;
       _lastComment = null;
     }
@@ -1743,8 +1201,484 @@
   }
 }
 /**
+ * Instances of the class {@code StringToken} represent a token whose value is independent of it's
+ * type.
+ * @coverage dart.engine.parser
+ */
+class StringToken extends Token {
+  /**
+   * The lexeme represented by this token.
+   */
+  String _value2;
+  /**
+   * Initialize a newly created token to represent a token of the given type with the given value.
+   * @param type the type of the token
+   * @param value the lexeme represented by this token
+   * @param offset the offset from the beginning of the file to the first character in the token
+   */
+  StringToken(TokenType type, String value, int offset) : super(type, offset) {
+    this._value2 = value;
+  }
+  String get lexeme => _value2;
+  String value() => _value2;
+}
+/**
+ * Instances of the class {@code CharBufferScanner} implement a scanner that reads from a character
+ * buffer. The scanning logic is in the superclass.
+ * @coverage dart.engine.parser
+ */
+class CharBufferScanner extends AbstractScanner {
+  /**
+   * The buffer from which characters will be read.
+   */
+  CharBuffer _buffer;
+  /**
+   * The number of characters in the buffer.
+   */
+  int _bufferLength = 0;
+  /**
+   * The index of the last character that was read.
+   */
+  int _charOffset = 0;
+  /**
+   * Initialize a newly created scanner to scan the characters in the given character buffer.
+   * @param source the source being scanned
+   * @param buffer the buffer from which characters will be read
+   * @param errorListener the error listener that will be informed of any errors that are found
+   */
+  CharBufferScanner(Source source, CharBuffer buffer, AnalysisErrorListener errorListener) : super(source, errorListener) {
+    this._buffer = buffer;
+    this._bufferLength = buffer.length();
+    this._charOffset = -1;
+  }
+  int get offset => _charOffset;
+  int advance() {
+    if (_charOffset + 1 >= _bufferLength) {
+      return -1;
+    }
+    return _buffer.charAt(++_charOffset);
+  }
+  String getString(int start, int endDelta) => _buffer.subSequence(start, _charOffset + 1 + endDelta).toString();
+  int peek() {
+    if (_charOffset + 1 >= _buffer.length()) {
+      return -1;
+    }
+    return _buffer.charAt(_charOffset + 1);
+  }
+}
+/**
+ * Instances of the class {@code TokenWithComment} represent a normal token that is preceded by
+ * comments.
+ * @coverage dart.engine.parser
+ */
+class TokenWithComment extends Token {
+  /**
+   * The first comment in the list of comments that precede this token.
+   */
+  Token _precedingComment;
+  /**
+   * Initialize a newly created token to have the given type and offset and to be preceded by the
+   * comments reachable from the given comment.
+   * @param type the type of the token
+   * @param offset the offset from the beginning of the file to the first character in the token
+   * @param precedingComment the first comment in the list of comments that precede this token
+   */
+  TokenWithComment(TokenType type, int offset, Token precedingComment) : super(type, offset) {
+    this._precedingComment = precedingComment;
+  }
+  Token get precedingComments => _precedingComment;
+}
+/**
+ * Instances of the class {@code Token} represent a token that was scanned from the input. Each
+ * token knows which token follows it, acting as the head of a linked list of tokens.
+ * @coverage dart.engine.parser
+ */
+class Token {
+  /**
+   * The type of the token.
+   */
+  TokenType _type;
+  /**
+   * The offset from the beginning of the file to the first character in the token.
+   */
+  int _offset = 0;
+  /**
+   * The previous token in the token stream.
+   */
+  Token _previous;
+  /**
+   * The next token in the token stream.
+   */
+  Token _next;
+  /**
+   * Initialize a newly created token to have the given type and offset.
+   * @param type the type of the token
+   * @param offset the offset from the beginning of the file to the first character in the token
+   */
+  Token(TokenType type, int offset) {
+    this._type = type;
+    this._offset = offset;
+  }
+  /**
+   * Return the offset from the beginning of the file to the character after last character of the
+   * token.
+   * @return the offset from the beginning of the file to the first character after last character
+   * of the token
+   */
+  int get end => _offset + length;
+  /**
+   * Return the number of characters in the node's source range.
+   * @return the number of characters in the node's source range
+   */
+  int get length => lexeme.length;
+  /**
+   * Return the lexeme that represents this token.
+   * @return the lexeme that represents this token
+   */
+  String get lexeme => _type.lexeme;
+  /**
+   * Return the next token in the token stream.
+   * @return the next token in the token stream
+   */
+  Token get next => _next;
+  /**
+   * Return the offset from the beginning of the file to the first character in the token.
+   * @return the offset from the beginning of the file to the first character in the token
+   */
+  int get offset => _offset;
+  /**
+   * Return the first comment in the list of comments that precede this token, or {@code null} if
+   * there are no comments preceding this token. Additional comments can be reached by following the
+   * token stream using {@link #getNext()} until {@code null} is returned.
+   * @return the first comment in the list of comments that precede this token
+   */
+  Token get precedingComments => null;
+  /**
+   * Return the previous token in the token stream.
+   * @return the previous token in the token stream
+   */
+  Token get previous => _previous;
+  /**
+   * Return the type of the token.
+   * @return the type of the token
+   */
+  TokenType get type => _type;
+  /**
+   * Return {@code true} if this token represents an operator.
+   * @return {@code true} if this token represents an operator
+   */
+  bool isOperator() => _type.isOperator();
+  /**
+   * Return {@code true} if this token is a synthetic token. A synthetic token is a token that was
+   * introduced by the parser in order to recover from an error in the code. Synthetic tokens always
+   * have a length of zero ({@code 0}).
+   * @return {@code true} if this token is a synthetic token
+   */
+  bool isSynthetic() => length == 0;
+  /**
+   * Return {@code true} if this token represents an operator that can be defined by users.
+   * @return {@code true} if this token represents an operator that can be defined by users
+   */
+  bool isUserDefinableOperator() => _type.isUserDefinableOperator();
+  /**
+   * Set the next token in the token stream to the given token. This has the side-effect of setting
+   * this token to be the previous token for the given token.
+   * @param token the next token in the token stream
+   * @return the token that was passed in
+   */
+  Token setNext(Token token) {
+    _next = token;
+    token.previous = this;
+    return token;
+  }
+  /**
+   * Set the next token in the token stream to the given token without changing which token is the
+   * previous token for the given token.
+   * @param token the next token in the token stream
+   * @return the token that was passed in
+   */
+  Token setNextWithoutSettingPrevious(Token token) {
+    _next = token;
+    return token;
+  }
+  /**
+   * Set the offset from the beginning of the file to the first character in the token to the given
+   * offset.
+   * @param offset the offset from the beginning of the file to the first character in the token
+   */
+  void set offset(int offset4) {
+    this._offset = offset4;
+  }
+  String toString() => lexeme;
+  /**
+   * Return the value of this token. For keyword tokens, this is the keyword associated with the
+   * token, for other tokens it is the lexeme associated with the token.
+   * @return the value of this token
+   */
+  Object value() => _type.lexeme;
+  /**
+   * Set the previous token in the token stream to the given token.
+   * @param previous the previous token in the token stream
+   */
+  void set previous(Token previous3) {
+    this._previous = previous3;
+  }
+}
+/**
+ * Instances of the class {@code StringScanner} implement a scanner that reads from a string. The
+ * scanning logic is in the superclass.
+ * @coverage dart.engine.parser
+ */
+class StringScanner extends AbstractScanner {
+  /**
+   * The offset from the beginning of the file to the beginning of the source being scanned.
+   */
+  int _offsetDelta = 0;
+  /**
+   * The string from which characters will be read.
+   */
+  String _string;
+  /**
+   * The number of characters in the string.
+   */
+  int _stringLength = 0;
+  /**
+   * The index, relative to the string, of the last character that was read.
+   */
+  int _charOffset = 0;
+  /**
+   * Initialize a newly created scanner to scan the characters in the given string.
+   * @param source the source being scanned
+   * @param string the string from which characters will be read
+   * @param errorListener the error listener that will be informed of any errors that are found
+   */
+  StringScanner(Source source, String string, AnalysisErrorListener errorListener) : super(source, errorListener) {
+    this._offsetDelta = 0;
+    this._string = string;
+    this._stringLength = string.length;
+    this._charOffset = -1;
+  }
+  int get offset => _offsetDelta + _charOffset;
+  /**
+   * Record that the source begins on the given line and column at the given offset. The line starts
+   * for lines before the given line will not be correct.
+   * <p>
+   * This method must be invoked at most one time and must be invoked before scanning begins. The
+   * values provided must be sensible. The results are undefined if these conditions are violated.
+   * @param line the one-based index of the line containing the first character of the source
+   * @param column the one-based index of the column in which the first character of the source
+   * occurs
+   * @param offset the zero-based offset from the beginning of the larger context to the first
+   * character of the source
+   */
+  void setSourceStart(int line, int column, int offset) {
+    if (line < 1 || column < 1 || offset < 0 || (line + column - 2) >= offset) {
+      return;
+    }
+    _offsetDelta = 1;
+    for (int i = 2; i < line; i++) {
+      recordStartOfLine();
+    }
+    _offsetDelta = offset - column + 1;
+    recordStartOfLine();
+    _offsetDelta = offset;
+  }
+  int advance() {
+    if (_charOffset + 1 >= _stringLength) {
+      return -1;
+    }
+    return _string.codeUnitAt(++_charOffset);
+  }
+  String getString(int start, int endDelta) => _string.substring(start - _offsetDelta, _charOffset + 1 + endDelta);
+  int peek() {
+    if (_charOffset + 1 >= _string.length) {
+      return -1;
+    }
+    return _string.codeUnitAt(_charOffset + 1);
+  }
+}
+/**
+ * Instances of the class {@code BeginTokenWithComment} represent a begin token that is preceded by
+ * comments.
+ * @coverage dart.engine.parser
+ */
+class BeginTokenWithComment extends BeginToken {
+  /**
+   * The first comment in the list of comments that precede this token.
+   */
+  Token _precedingComment;
+  /**
+   * Initialize a newly created token to have the given type and offset and to be preceded by the
+   * comments reachable from the given comment.
+   * @param type the type of the token
+   * @param offset the offset from the beginning of the file to the first character in the token
+   * @param precedingComment the first comment in the list of comments that precede this token
+   */
+  BeginTokenWithComment(TokenType type, int offset, Token precedingComment) : super(type, offset) {
+    this._precedingComment = precedingComment;
+  }
+  Token get precedingComments => _precedingComment;
+}
+/**
+ * Instances of the class {@code KeywordToken} represent a keyword in the language.
+ * @coverage dart.engine.parser
+ */
+class KeywordToken extends Token {
+  /**
+   * The keyword being represented by this token.
+   */
+  Keyword _keyword;
+  /**
+   * Initialize a newly created token to represent the given keyword.
+   * @param keyword the keyword being represented by this token
+   * @param offset the offset from the beginning of the file to the first character in the token
+   */
+  KeywordToken(Keyword keyword, int offset) : super(TokenType.KEYWORD, offset) {
+    this._keyword = keyword;
+  }
+  /**
+   * Return the keyword being represented by this token.
+   * @return the keyword being represented by this token
+   */
+  Keyword get keyword => _keyword;
+  String get lexeme => _keyword.syntax;
+  Keyword value() => _keyword;
+}
+/**
+ * Instances of the class {@code BeginToken} represent the opening half of a grouping pair of
+ * tokens. This is used for curly brackets ('{'), parentheses ('('), and square brackets ('[').
+ * @coverage dart.engine.parser
+ */
+class BeginToken extends Token {
+  /**
+   * The token that corresponds to this token.
+   */
+  Token _endToken;
+  /**
+   * Initialize a newly created token representing the opening half of a grouping pair of tokens.
+   * @param type the type of the token
+   * @param offset the offset from the beginning of the file to the first character in the token
+   */
+  BeginToken(TokenType type, int offset) : super(type, offset) {
+    assert((identical(type, TokenType.OPEN_CURLY_BRACKET) || identical(type, TokenType.OPEN_PAREN) || identical(type, TokenType.OPEN_SQUARE_BRACKET) || identical(type, TokenType.STRING_INTERPOLATION_EXPRESSION)));
+  }
+  /**
+   * Return the token that corresponds to this token.
+   * @return the token that corresponds to this token
+   */
+  Token get endToken => _endToken;
+  /**
+   * Set the token that corresponds to this token to the given token.
+   * @param token the token that corresponds to this token
+   */
+  void set endToken(Token token) {
+    this._endToken = token;
+  }
+}
+/**
+ * The enumeration {@code TokenClass} represents classes (or groups) of tokens with a similar use.
+ * @coverage dart.engine.parser
+ */
+class TokenClass {
+  /**
+   * A value used to indicate that the token type is not part of any specific class of token.
+   */
+  static final TokenClass NO_CLASS = new TokenClass.con1('NO_CLASS', 0);
+  /**
+   * A value used to indicate that the token type is an additive operator.
+   */
+  static final TokenClass ADDITIVE_OPERATOR = new TokenClass.con2('ADDITIVE_OPERATOR', 1, 12);
+  /**
+   * A value used to indicate that the token type is an assignment operator.
+   */
+  static final TokenClass ASSIGNMENT_OPERATOR = new TokenClass.con2('ASSIGNMENT_OPERATOR', 2, 1);
+  /**
+   * A value used to indicate that the token type is a bitwise-and operator.
+   */
+  static final TokenClass BITWISE_AND_OPERATOR = new TokenClass.con2('BITWISE_AND_OPERATOR', 3, 8);
+  /**
+   * A value used to indicate that the token type is a bitwise-or operator.
+   */
+  static final TokenClass BITWISE_OR_OPERATOR = new TokenClass.con2('BITWISE_OR_OPERATOR', 4, 6);
+  /**
+   * A value used to indicate that the token type is a bitwise-xor operator.
+   */
+  static final TokenClass BITWISE_XOR_OPERATOR = new TokenClass.con2('BITWISE_XOR_OPERATOR', 5, 7);
+  /**
+   * A value used to indicate that the token type is a cascade operator.
+   */
+  static final TokenClass CASCADE_OPERATOR = new TokenClass.con2('CASCADE_OPERATOR', 6, 2);
+  /**
+   * A value used to indicate that the token type is a conditional operator.
+   */
+  static final TokenClass CONDITIONAL_OPERATOR = new TokenClass.con2('CONDITIONAL_OPERATOR', 7, 3);
+  /**
+   * A value used to indicate that the token type is an equality operator.
+   */
+  static final TokenClass EQUALITY_OPERATOR = new TokenClass.con2('EQUALITY_OPERATOR', 8, 9);
+  /**
+   * A value used to indicate that the token type is a logical-and operator.
+   */
+  static final TokenClass LOGICAL_AND_OPERATOR = new TokenClass.con2('LOGICAL_AND_OPERATOR', 9, 5);
+  /**
+   * A value used to indicate that the token type is a logical-or operator.
+   */
+  static final TokenClass LOGICAL_OR_OPERATOR = new TokenClass.con2('LOGICAL_OR_OPERATOR', 10, 4);
+  /**
+   * A value used to indicate that the token type is a multiplicative operator.
+   */
+  static final TokenClass MULTIPLICATIVE_OPERATOR = new TokenClass.con2('MULTIPLICATIVE_OPERATOR', 11, 13);
+  /**
+   * A value used to indicate that the token type is a relational operator.
+   */
+  static final TokenClass RELATIONAL_OPERATOR = new TokenClass.con2('RELATIONAL_OPERATOR', 12, 10);
+  /**
+   * A value used to indicate that the token type is a shift operator.
+   */
+  static final TokenClass SHIFT_OPERATOR = new TokenClass.con2('SHIFT_OPERATOR', 13, 11);
+  /**
+   * A value used to indicate that the token type is a unary operator.
+   */
+  static final TokenClass UNARY_POSTFIX_OPERATOR = new TokenClass.con2('UNARY_POSTFIX_OPERATOR', 14, 15);
+  /**
+   * A value used to indicate that the token type is a unary operator.
+   */
+  static final TokenClass UNARY_PREFIX_OPERATOR = new TokenClass.con2('UNARY_PREFIX_OPERATOR', 15, 14);
+  static final List<TokenClass> values = [NO_CLASS, ADDITIVE_OPERATOR, ASSIGNMENT_OPERATOR, BITWISE_AND_OPERATOR, BITWISE_OR_OPERATOR, BITWISE_XOR_OPERATOR, CASCADE_OPERATOR, CONDITIONAL_OPERATOR, EQUALITY_OPERATOR, LOGICAL_AND_OPERATOR, LOGICAL_OR_OPERATOR, MULTIPLICATIVE_OPERATOR, RELATIONAL_OPERATOR, SHIFT_OPERATOR, UNARY_POSTFIX_OPERATOR, UNARY_PREFIX_OPERATOR];
+  String __name;
+  int __ordinal = 0;
+  int get ordinal => __ordinal;
+  /**
+   * The precedence of tokens of this class, or {@code 0} if the such tokens do not represent an
+   * operator.
+   */
+  int _precedence = 0;
+  TokenClass.con1(String ___name, int ___ordinal) {
+    _jtd_constructor_286_impl(___name, ___ordinal);
+  }
+  _jtd_constructor_286_impl(String ___name, int ___ordinal) {
+    _jtd_constructor_287_impl(___name, ___ordinal, 0);
+  }
+  TokenClass.con2(String ___name, int ___ordinal, int precedence2) {
+    _jtd_constructor_287_impl(___name, ___ordinal, precedence2);
+  }
+  _jtd_constructor_287_impl(String ___name, int ___ordinal, int precedence2) {
+    __name = ___name;
+    __ordinal = ___ordinal;
+    this._precedence = precedence2;
+  }
+  /**
+   * Return the precedence of tokens of this class, or {@code 0} if the such tokens do not represent
+   * an operator.
+   * @return the precedence of tokens of this class
+   */
+  int get precedence => _precedence;
+  String toString() => __name;
+}
+/**
  * Instances of the class {@code KeywordTokenWithComment} implement a keyword token that is preceded
  * by comments.
+ * @coverage dart.engine.parser
  */
 class KeywordTokenWithComment extends KeywordToken {
   /**
@@ -1764,107 +1698,190 @@
   Token get precedingComments => _precedingComment;
 }
 /**
- * Instances of the abstract class {@code KeywordState} represent a state in a state machine used to
- * scan keywords.
+ * The enumeration {@code TokenType} defines the types of tokens that can be returned by the
+ * scanner.
+ * @coverage dart.engine.parser
  */
-class KeywordState {
+class TokenType {
   /**
-   * An empty transition table used by leaf states.
+   * The type of the token that marks the end of the input.
    */
-  static List<KeywordState> _EMPTY_TABLE = new List<KeywordState>(26);
+  static final TokenType EOF = new TokenType_EOF('EOF', 0, null, "");
+  static final TokenType DOUBLE = new TokenType.con1('DOUBLE', 1);
+  static final TokenType HEXADECIMAL = new TokenType.con1('HEXADECIMAL', 2);
+  static final TokenType IDENTIFIER = new TokenType.con1('IDENTIFIER', 3);
+  static final TokenType INT = new TokenType.con1('INT', 4);
+  static final TokenType KEYWORD = new TokenType.con1('KEYWORD', 5);
+  static final TokenType MULTI_LINE_COMMENT = new TokenType.con1('MULTI_LINE_COMMENT', 6);
+  static final TokenType SCRIPT_TAG = new TokenType.con1('SCRIPT_TAG', 7);
+  static final TokenType SINGLE_LINE_COMMENT = new TokenType.con1('SINGLE_LINE_COMMENT', 8);
+  static final TokenType STRING = new TokenType.con1('STRING', 9);
+  static final TokenType AMPERSAND = new TokenType.con2('AMPERSAND', 10, TokenClass.BITWISE_AND_OPERATOR, "&");
+  static final TokenType AMPERSAND_AMPERSAND = new TokenType.con2('AMPERSAND_AMPERSAND', 11, TokenClass.LOGICAL_AND_OPERATOR, "&&");
+  static final TokenType AMPERSAND_EQ = new TokenType.con2('AMPERSAND_EQ', 12, TokenClass.ASSIGNMENT_OPERATOR, "&=");
+  static final TokenType AT = new TokenType.con2('AT', 13, null, "@");
+  static final TokenType BANG = new TokenType.con2('BANG', 14, TokenClass.UNARY_PREFIX_OPERATOR, "!");
+  static final TokenType BANG_EQ = new TokenType.con2('BANG_EQ', 15, TokenClass.EQUALITY_OPERATOR, "!=");
+  static final TokenType BAR = new TokenType.con2('BAR', 16, TokenClass.BITWISE_OR_OPERATOR, "|");
+  static final TokenType BAR_BAR = new TokenType.con2('BAR_BAR', 17, TokenClass.LOGICAL_OR_OPERATOR, "||");
+  static final TokenType BAR_EQ = new TokenType.con2('BAR_EQ', 18, TokenClass.ASSIGNMENT_OPERATOR, "|=");
+  static final TokenType COLON = new TokenType.con2('COLON', 19, null, ":");
+  static final TokenType COMMA = new TokenType.con2('COMMA', 20, null, ",");
+  static final TokenType CARET = new TokenType.con2('CARET', 21, TokenClass.BITWISE_XOR_OPERATOR, "^");
+  static final TokenType CARET_EQ = new TokenType.con2('CARET_EQ', 22, TokenClass.ASSIGNMENT_OPERATOR, "^=");
+  static final TokenType CLOSE_CURLY_BRACKET = new TokenType.con2('CLOSE_CURLY_BRACKET', 23, null, "}");
+  static final TokenType CLOSE_PAREN = new TokenType.con2('CLOSE_PAREN', 24, null, ")");
+  static final TokenType CLOSE_SQUARE_BRACKET = new TokenType.con2('CLOSE_SQUARE_BRACKET', 25, null, "]");
+  static final TokenType EQ = new TokenType.con2('EQ', 26, TokenClass.ASSIGNMENT_OPERATOR, "=");
+  static final TokenType EQ_EQ = new TokenType.con2('EQ_EQ', 27, TokenClass.EQUALITY_OPERATOR, "==");
+  static final TokenType FUNCTION = new TokenType.con2('FUNCTION', 28, null, "=>");
+  static final TokenType GT = new TokenType.con2('GT', 29, TokenClass.RELATIONAL_OPERATOR, ">");
+  static final TokenType GT_EQ = new TokenType.con2('GT_EQ', 30, TokenClass.RELATIONAL_OPERATOR, ">=");
+  static final TokenType GT_GT = new TokenType.con2('GT_GT', 31, TokenClass.SHIFT_OPERATOR, ">>");
+  static final TokenType GT_GT_EQ = new TokenType.con2('GT_GT_EQ', 32, TokenClass.ASSIGNMENT_OPERATOR, ">>=");
+  static final TokenType HASH = new TokenType.con2('HASH', 33, null, "#");
+  static final TokenType INDEX = new TokenType.con2('INDEX', 34, TokenClass.UNARY_POSTFIX_OPERATOR, "[]");
+  static final TokenType INDEX_EQ = new TokenType.con2('INDEX_EQ', 35, TokenClass.UNARY_POSTFIX_OPERATOR, "[]=");
+  static final TokenType IS = new TokenType.con2('IS', 36, TokenClass.RELATIONAL_OPERATOR, "is");
+  static final TokenType LT = new TokenType.con2('LT', 37, TokenClass.RELATIONAL_OPERATOR, "<");
+  static final TokenType LT_EQ = new TokenType.con2('LT_EQ', 38, TokenClass.RELATIONAL_OPERATOR, "<=");
+  static final TokenType LT_LT = new TokenType.con2('LT_LT', 39, TokenClass.SHIFT_OPERATOR, "<<");
+  static final TokenType LT_LT_EQ = new TokenType.con2('LT_LT_EQ', 40, TokenClass.ASSIGNMENT_OPERATOR, "<<=");
+  static final TokenType MINUS = new TokenType.con2('MINUS', 41, TokenClass.ADDITIVE_OPERATOR, "-");
+  static final TokenType MINUS_EQ = new TokenType.con2('MINUS_EQ', 42, TokenClass.ASSIGNMENT_OPERATOR, "-=");
+  static final TokenType MINUS_MINUS = new TokenType.con2('MINUS_MINUS', 43, TokenClass.UNARY_PREFIX_OPERATOR, "--");
+  static final TokenType OPEN_CURLY_BRACKET = new TokenType.con2('OPEN_CURLY_BRACKET', 44, null, "{");
+  static final TokenType OPEN_PAREN = new TokenType.con2('OPEN_PAREN', 45, TokenClass.UNARY_POSTFIX_OPERATOR, "(");
+  static final TokenType OPEN_SQUARE_BRACKET = new TokenType.con2('OPEN_SQUARE_BRACKET', 46, TokenClass.UNARY_POSTFIX_OPERATOR, "[");
+  static final TokenType PERCENT = new TokenType.con2('PERCENT', 47, TokenClass.MULTIPLICATIVE_OPERATOR, "%");
+  static final TokenType PERCENT_EQ = new TokenType.con2('PERCENT_EQ', 48, TokenClass.ASSIGNMENT_OPERATOR, "%=");
+  static final TokenType PERIOD = new TokenType.con2('PERIOD', 49, TokenClass.UNARY_POSTFIX_OPERATOR, ".");
+  static final TokenType PERIOD_PERIOD = new TokenType.con2('PERIOD_PERIOD', 50, TokenClass.CASCADE_OPERATOR, "..");
+  static final TokenType PLUS = new TokenType.con2('PLUS', 51, TokenClass.ADDITIVE_OPERATOR, "+");
+  static final TokenType PLUS_EQ = new TokenType.con2('PLUS_EQ', 52, TokenClass.ASSIGNMENT_OPERATOR, "+=");
+  static final TokenType PLUS_PLUS = new TokenType.con2('PLUS_PLUS', 53, TokenClass.UNARY_PREFIX_OPERATOR, "++");
+  static final TokenType QUESTION = new TokenType.con2('QUESTION', 54, TokenClass.CONDITIONAL_OPERATOR, "?");
+  static final TokenType SEMICOLON = new TokenType.con2('SEMICOLON', 55, null, ";");
+  static final TokenType SLASH = new TokenType.con2('SLASH', 56, TokenClass.MULTIPLICATIVE_OPERATOR, "/");
+  static final TokenType SLASH_EQ = new TokenType.con2('SLASH_EQ', 57, TokenClass.ASSIGNMENT_OPERATOR, "/=");
+  static final TokenType STAR = new TokenType.con2('STAR', 58, TokenClass.MULTIPLICATIVE_OPERATOR, "*");
+  static final TokenType STAR_EQ = new TokenType.con2('STAR_EQ', 59, TokenClass.ASSIGNMENT_OPERATOR, "*=");
+  static final TokenType STRING_INTERPOLATION_EXPRESSION = new TokenType.con2('STRING_INTERPOLATION_EXPRESSION', 60, null, "\${");
+  static final TokenType STRING_INTERPOLATION_IDENTIFIER = new TokenType.con2('STRING_INTERPOLATION_IDENTIFIER', 61, null, "\$");
+  static final TokenType TILDE = new TokenType.con2('TILDE', 62, TokenClass.UNARY_PREFIX_OPERATOR, "~");
+  static final TokenType TILDE_SLASH = new TokenType.con2('TILDE_SLASH', 63, TokenClass.MULTIPLICATIVE_OPERATOR, "~/");
+  static final TokenType TILDE_SLASH_EQ = new TokenType.con2('TILDE_SLASH_EQ', 64, TokenClass.ASSIGNMENT_OPERATOR, "~/=");
+  static final TokenType BACKPING = new TokenType.con2('BACKPING', 65, null, "`");
+  static final TokenType BACKSLASH = new TokenType.con2('BACKSLASH', 66, null, "\\");
+  static final TokenType PERIOD_PERIOD_PERIOD = new TokenType.con2('PERIOD_PERIOD_PERIOD', 67, null, "...");
+  static final List<TokenType> values = [EOF, DOUBLE, HEXADECIMAL, IDENTIFIER, INT, KEYWORD, MULTI_LINE_COMMENT, SCRIPT_TAG, SINGLE_LINE_COMMENT, STRING, AMPERSAND, AMPERSAND_AMPERSAND, AMPERSAND_EQ, AT, BANG, BANG_EQ, BAR, BAR_BAR, BAR_EQ, COLON, COMMA, CARET, CARET_EQ, CLOSE_CURLY_BRACKET, CLOSE_PAREN, CLOSE_SQUARE_BRACKET, EQ, EQ_EQ, FUNCTION, GT, GT_EQ, GT_GT, GT_GT_EQ, HASH, INDEX, INDEX_EQ, IS, LT, LT_EQ, LT_LT, LT_LT_EQ, MINUS, MINUS_EQ, MINUS_MINUS, OPEN_CURLY_BRACKET, OPEN_PAREN, OPEN_SQUARE_BRACKET, PERCENT, PERCENT_EQ, PERIOD, PERIOD_PERIOD, PLUS, PLUS_EQ, PLUS_PLUS, QUESTION, SEMICOLON, SLASH, SLASH_EQ, STAR, STAR_EQ, STRING_INTERPOLATION_EXPRESSION, STRING_INTERPOLATION_IDENTIFIER, TILDE, TILDE_SLASH, TILDE_SLASH_EQ, BACKPING, BACKSLASH, PERIOD_PERIOD_PERIOD];
+  String __name;
+  int __ordinal = 0;
+  int get ordinal => __ordinal;
   /**
-   * The initial state in the state machine.
+   * The class of the token.
    */
-  static KeywordState KEYWORD_STATE = createKeywordStateTable();
+  TokenClass _tokenClass;
   /**
-   * Create the next state in the state machine where we have already recognized the subset of
-   * strings in the given array of strings starting at the given offset and having the given length.
-   * All of these strings have a common prefix and the next character is at the given start index.
-   * @param start the index of the character in the strings used to transition to a new state
-   * @param strings an array containing all of the strings that will be recognized by the state
-   * machine
-   * @param offset the offset of the first string in the array that has the prefix that is assumed
-   * to have been recognized by the time we reach the state being built
-   * @param length the number of strings in the array that pass through the state being built
-   * @return the state that was created
+   * The lexeme that defines this type of token, or {@code null} if there is more than one possible
+   * lexeme for this type of token.
    */
-  static KeywordState computeKeywordStateTable(int start, List<String> strings, int offset, int length12) {
-    List<KeywordState> result = new List<KeywordState>(26);
-    assert(length12 != 0);
-    int chunk = 0x0;
-    int chunkStart = -1;
-    bool isLeaf = false;
-    for (int i = offset; i < offset + length12; i++) {
-      if (strings[i].length == start) {
-        isLeaf = true;
-      }
-      if (strings[i].length > start) {
-        int c = strings[i].codeUnitAt(start);
-        if (chunk != c) {
-          if (chunkStart != -1) {
-            result[chunk - 0x61] = computeKeywordStateTable(start + 1, strings, chunkStart, i - chunkStart);
-          }
-          chunkStart = i;
-          chunk = c;
-        }
-      }
-    }
-    if (chunkStart != -1) {
-      assert(result[chunk - 0x61] == null);
-      result[chunk - 0x61] = computeKeywordStateTable(start + 1, strings, chunkStart, offset + length12 - chunkStart);
-    } else {
-      assert(length12 == 1);
-      return new KeywordState(_EMPTY_TABLE, strings[offset]);
-    }
-    if (isLeaf) {
-      return new KeywordState(result, strings[offset]);
-    } else {
-      return new KeywordState(result, null);
-    }
+  String _lexeme;
+  TokenType.con1(String ___name, int ___ordinal) {
+    _jtd_constructor_288_impl(___name, ___ordinal);
+  }
+  _jtd_constructor_288_impl(String ___name, int ___ordinal) {
+    _jtd_constructor_289_impl(___name, ___ordinal, TokenClass.NO_CLASS, null);
+  }
+  TokenType.con2(String ___name, int ___ordinal, TokenClass tokenClass2, String lexeme2) {
+    _jtd_constructor_289_impl(___name, ___ordinal, tokenClass2, lexeme2);
+  }
+  _jtd_constructor_289_impl(String ___name, int ___ordinal, TokenClass tokenClass2, String lexeme2) {
+    __name = ___name;
+    __ordinal = ___ordinal;
+    this._tokenClass = tokenClass2 == null ? TokenClass.NO_CLASS : tokenClass2;
+    this._lexeme = lexeme2;
   }
   /**
-   * Create the initial state in the state machine.
-   * @return the state that was created
+   * Return the lexeme that defines this type of token, or {@code null} if there is more than one
+   * possible lexeme for this type of token.
+   * @return the lexeme that defines this type of token
    */
-  static KeywordState createKeywordStateTable() {
-    List<Keyword> values2 = Keyword.values;
-    List<String> strings = new List<String>(values2.length);
-    for (int i = 0; i < values2.length; i++) {
-      strings[i] = values2[i].syntax;
-    }
-    strings.sort();
-    return computeKeywordStateTable(0, strings, 0, strings.length);
-  }
+  String get lexeme => _lexeme;
   /**
-   * A table mapping characters to the states to which those characters will transition. (The index
-   * into the array is the offset from the character {@code 'a'} to the transitioning character.)
+   * Return the precedence of the token, or {@code 0} if the token does not represent an operator.
+   * @return the precedence of the token
    */
-  List<KeywordState> _table;
+  int get precedence => _tokenClass.precedence;
   /**
-   * The keyword that is recognized by this state, or {@code null} if this state is not a terminal
-   * state.
+   * Return {@code true} if this type of token represents an additive operator.
+   * @return {@code true} if this type of token represents an additive operator
    */
-  Keyword _keyword2;
+  bool isAdditiveOperator() => identical(_tokenClass, TokenClass.ADDITIVE_OPERATOR);
   /**
-   * Initialize a newly created state to have the given transitions and to recognize the keyword
-   * with the given syntax.
-   * @param table a table mapping characters to the states to which those characters will transition
-   * @param syntax the syntax of the keyword that is recognized by the state
+   * Return {@code true} if this type of token represents an assignment operator.
+   * @return {@code true} if this type of token represents an assignment operator
    */
-  KeywordState(List<KeywordState> table, String syntax) {
-    this._table = table;
-    this._keyword2 = (syntax == null) ? null : Keyword.keywords[syntax];
-  }
+  bool isAssignmentOperator() => identical(_tokenClass, TokenClass.ASSIGNMENT_OPERATOR);
   /**
-   * Return the keyword that was recognized by this state, or {@code null} if this state does not
-   * recognized a keyword.
-   * @return the keyword that was matched by reaching this state
+   * Return {@code true} if this type of token represents an associative operator. An associative
+   * operator is an operator for which the following equality is true:{@code (a * b) * c == a * (b * c)}. In other words, if the result of applying the operator to
+   * multiple operands does not depend on the order in which those applications occur.
+   * <p>
+   * Note: This method considers the logical-and and logical-or operators to be associative, even
+   * though the order in which the application of those operators can have an effect because
+   * evaluation of the right-hand operand is conditional.
+   * @return {@code true} if this type of token represents an associative operator
    */
-  Keyword keyword() => _keyword2;
+  bool isAssociativeOperator() => identical(this, AMPERSAND) || identical(this, AMPERSAND_AMPERSAND) || identical(this, BAR) || identical(this, BAR_BAR) || identical(this, CARET) || identical(this, PLUS) || identical(this, STAR);
   /**
-   * Return the state that follows this state on a transition of the given character, or{@code null} if there is no valid state reachable from this state with such a transition.
-   * @param c the character used to transition from this state to another state
-   * @return the state that follows this state on a transition of the given character
+   * Return {@code true} if this type of token represents an equality operator.
+   * @return {@code true} if this type of token represents an equality operator
    */
-  KeywordState next(int c) => _table[c - 0x61];
+  bool isEqualityOperator() => identical(_tokenClass, TokenClass.EQUALITY_OPERATOR);
+  /**
+   * Return {@code true} if this type of token represents an increment operator.
+   * @return {@code true} if this type of token represents an increment operator
+   */
+  bool isIncrementOperator() => identical(_lexeme, "++") || identical(_lexeme, "--");
+  /**
+   * Return {@code true} if this type of token represents a multiplicative operator.
+   * @return {@code true} if this type of token represents a multiplicative operator
+   */
+  bool isMultiplicativeOperator() => identical(_tokenClass, TokenClass.MULTIPLICATIVE_OPERATOR);
+  /**
+   * Return {@code true} if this token type represents an operator.
+   * @return {@code true} if this token type represents an operator
+   */
+  bool isOperator() => _tokenClass != TokenClass.NO_CLASS && this != OPEN_PAREN && this != OPEN_SQUARE_BRACKET && this != PERIOD;
+  /**
+   * Return {@code true} if this type of token represents a relational operator.
+   * @return {@code true} if this type of token represents a relational operator
+   */
+  bool isRelationalOperator() => identical(_tokenClass, TokenClass.RELATIONAL_OPERATOR);
+  /**
+   * Return {@code true} if this type of token represents a shift operator.
+   * @return {@code true} if this type of token represents a shift operator
+   */
+  bool isShiftOperator() => identical(_tokenClass, TokenClass.SHIFT_OPERATOR);
+  /**
+   * Return {@code true} if this type of token represents a unary postfix operator.
+   * @return {@code true} if this type of token represents a unary postfix operator
+   */
+  bool isUnaryPostfixOperator() => identical(_tokenClass, TokenClass.UNARY_POSTFIX_OPERATOR);
+  /**
+   * Return {@code true} if this type of token represents a unary prefix operator.
+   * @return {@code true} if this type of token represents a unary prefix operator
+   */
+  bool isUnaryPrefixOperator() => identical(_tokenClass, TokenClass.UNARY_PREFIX_OPERATOR);
+  /**
+   * Return {@code true} if this token type represents an operator that can be defined by users.
+   * @return {@code true} if this token type represents an operator that can be defined by users
+   */
+  bool isUserDefinableOperator() => identical(_lexeme, "==") || identical(_lexeme, "~") || identical(_lexeme, "[]") || identical(_lexeme, "[]=") || identical(_lexeme, "*") || identical(_lexeme, "/") || identical(_lexeme, "%") || identical(_lexeme, "~/") || identical(_lexeme, "+") || identical(_lexeme, "-") || identical(_lexeme, "<<") || identical(_lexeme, ">>") || identical(_lexeme, ">=") || identical(_lexeme, ">") || identical(_lexeme, "<=") || identical(_lexeme, "<") || identical(_lexeme, "&") || identical(_lexeme, "^") || identical(_lexeme, "|");
+  String toString() => __name;
 }
+class TokenType_EOF extends TokenType {
+  TokenType_EOF(String ___name, int ___ordinal, TokenClass arg0, String arg1) : super.con2(___name, ___ordinal, arg0, arg1);
+  String toString() => "-eof-";
+}
\ No newline at end of file
diff --git a/pkg/analyzer-experimental/lib/src/generated/sdk.dart b/pkg/analyzer_experimental/lib/src/generated/sdk.dart
similarity index 86%
rename from pkg/analyzer-experimental/lib/src/generated/sdk.dart
rename to pkg/analyzer_experimental/lib/src/generated/sdk.dart
index de9c3de..b8855c6 100644
--- a/pkg/analyzer-experimental/lib/src/generated/sdk.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/sdk.dart
@@ -6,13 +6,15 @@
 import 'dart:io';
 import 'dart:uri';
 import 'java_core.dart';
+import 'java_io.dart';
 import 'java_engine.dart';
-import 'package:analyzer-experimental/src/generated/source.dart';
-import 'package:analyzer-experimental/src/generated/error.dart';
-import 'package:analyzer-experimental/src/generated/scanner.dart';
-import 'package:analyzer-experimental/src/generated/parser.dart';
-import 'package:analyzer-experimental/src/generated/ast.dart';
-import 'package:analyzer-experimental/src/generated/engine.dart' show AnalysisEngine;
+import 'java_engine_io.dart';
+import 'package:analyzer_experimental/src/generated/source_io.dart';
+import 'package:analyzer_experimental/src/generated/error.dart';
+import 'package:analyzer_experimental/src/generated/scanner.dart';
+import 'package:analyzer_experimental/src/generated/parser.dart';
+import 'package:analyzer_experimental/src/generated/ast.dart';
+import 'package:analyzer_experimental/src/generated/engine.dart' show AnalysisEngine;
 
 /**
  * Represents a single library in the SDK
@@ -60,505 +62,9 @@
   bool isVmLibrary();
 }
 /**
- * Instances of the class {@code LibraryMap} map Dart library URI's to the {@link SdkLibraryImpllibrary}.
- */
-class LibraryMap {
-  /**
-   * A table mapping Dart library URI's to the library.
-   */
-  Map<String, SdkLibraryImpl> _libraryMap = new Map<String, SdkLibraryImpl>();
-  /**
-   * Initialize a newly created library map to be empty.
-   */
-  LibraryMap() : super() {
-  }
-  /**
-   * Return the library with the given URI, or {@code null} if the URI does not map to a library.
-   * @param dartUri the URI of the library to be returned
-   * @return the library with the given URI
-   */
-  SdkLibrary getLibrary(String dartUri) => _libraryMap[dartUri];
-  /**
-   * Return an array containing all the sdk libraries {@link SdkLibraryImpl} in the mapping
-   * @return the sdk libraries in the mapping
-   */
-  List<SdkLibrary> get sdkLibraries => new List.from(_libraryMap.values);
-  /**
-   * Return an array containing the library URI's for which a mapping is available.
-   * @return the library URI's for which a mapping is available
-   */
-  List<String> get uris => new List.from(_libraryMap.keys.toSet());
-  /**
-   * Return the library with the given URI, or {@code null} if the URI does not map to a library.
-   * @param dartUri the URI of the library to be returned
-   * @param library the library with the given URI
-   */
-  void setLibrary(String dartUri, SdkLibraryImpl library) {
-    _libraryMap[dartUri] = library;
-  }
-  /**
-   * Return the number of library URI's for which a mapping is available.
-   * @return the number of library URI's for which a mapping is available
-   */
-  int size() => _libraryMap.length;
-}
-/**
- * Instances of the class {@code DartSdk} represent a Dart SDK installed in a specified location.
- */
-class DartSdk {
-  /**
-   * The short name of the dart SDK html library.
-   */
-  static String DART_HTML = "dart:html";
-  /**
-   * The directory containing the SDK.
-   */
-  File _sdkDirectory;
-  /**
-   * The revision number of this SDK, or {@code "0"} if the revision number cannot be discovered.
-   */
-  String _sdkVersion;
-  /**
-   * The file containing the Dartium executable.
-   */
-  File _dartiumExecutable;
-  /**
-   * The file containing the VM executable.
-   */
-  File _vmExecutable;
-  /**
-   * A mapping from Dart library URI's to the library represented by that URI.
-   */
-  LibraryMap _libraryMap;
-  /**
-   * The name of the directory within the SDK directory that contains executables.
-   */
-  static String _BIN_DIRECTORY_NAME = "bin";
-  /**
-   * The name of the directory within the SDK directory that contains Chromium.
-   */
-  static String _CHROMIUM_DIRECTORY_NAME = "chromium";
-  /**
-   * The name of the environment variable whose value is the path to the default Dart SDK directory.
-   */
-  static String _DART_SDK_ENVIRONMENT_VARIABLE_NAME = "DART_SDK";
-  /**
-   * The name of the file containing the Dartium executable on Linux.
-   */
-  static String _DARTIUM_EXECUTABLE_NAME_LINUX = "chromium/chrome";
-  /**
-   * The name of the file containing the Dartium executable on Macintosh.
-   */
-  static String _DARTIUM_EXECUTABLE_NAME_MAC = "Chromium.app/Contents/MacOS/Chromium";
-  /**
-   * The name of the file containing the Dartium executable on Windows.
-   */
-  static String _DARTIUM_EXECUTABLE_NAME_WIN = "chromium/Chrome.exe";
-  /**
-   * The name of the {@link System} property whose value is the path to the default Dart SDK
-   * directory.
-   */
-  static String _DEFAULT_DIRECTORY_PROPERTY_NAME = "com.google.dart.sdk";
-  /**
-   * The version number that is returned when the real version number could not be determined.
-   */
-  static String _DEFAULT_VERSION = "0";
-  /**
-   * The name of the directory within the SDK directory that contains documentation for the
-   * libraries.
-   */
-  static String _DOCS_DIRECTORY_NAME = "docs";
-  /**
-   * The suffix added to the name of a library to derive the name of the file containing the
-   * documentation for that library.
-   */
-  static String _DOC_FILE_SUFFIX = "_api.json";
-  /**
-   * The name of the directory within the SDK directory that contains the libraries file.
-   */
-  static String _INTERNAL_DIR = "_internal";
-  /**
-   * The name of the directory within the SDK directory that contains the libraries.
-   */
-  static String _LIB_DIRECTORY_NAME = "lib";
-  /**
-   * The name of the libraries file.
-   */
-  static String _LIBRARIES_FILE = "libraries.dart";
-  /**
-   * The name of the directory within the SDK directory that contains the packages.
-   */
-  static String _PKG_DIRECTORY_NAME = "pkg";
-  /**
-   * The name of the file within the SDK directory that contains the revision number of the SDK.
-   */
-  static String _REVISION_FILE_NAME = "revision";
-  /**
-   * The name of the file containing the VM executable on the Windows operating system.
-   */
-  static String _VM_EXECUTABLE_NAME_WIN = "dart.exe";
-  /**
-   * The name of the file containing the VM executable on non-Windows operating systems.
-   */
-  static String _VM_EXECUTABLE_NAME = "dart";
-  /**
-   * Return the default Dart SDK, or {@code null} if the directory containing the default SDK cannot
-   * be determined (or does not exist).
-   * @return the default Dart SDK
-   */
-  static DartSdk get defaultSdk {
-    File sdkDirectory = defaultSdkDirectory;
-    if (sdkDirectory == null) {
-      return null;
-    }
-    return new DartSdk(sdkDirectory);
-  }
-  /**
-   * Return the default directory for the Dart SDK, or {@code null} if the directory cannot be
-   * determined (or does not exist). The default directory is provided by a {@link System} property
-   * named {@code com.google.dart.sdk}, or, if the property is not defined, an environment variable
-   * named {@code DART_SDK}.
-   * @return the default directory for the Dart SDK
-   */
-  static File get defaultSdkDirectory {
-    String sdkProperty = System.getProperty(_DEFAULT_DIRECTORY_PROPERTY_NAME);
-    if (sdkProperty == null) {
-      sdkProperty = System.getenv(_DART_SDK_ENVIRONMENT_VARIABLE_NAME);
-      if (sdkProperty == null) {
-        return null;
-      }
-    }
-    File sdkDirectory = new File(sdkProperty);
-    if (!sdkDirectory.existsSync()) {
-      return null;
-    }
-    return sdkDirectory;
-  }
-  /**
-   * Initialize a newly created SDK to represent the Dart SDK installed in the given directory.
-   * @param sdkDirectory the directory containing the SDK
-   */
-  DartSdk(File sdkDirectory) {
-    this._sdkDirectory = getAbsoluteFile(sdkDirectory);
-    initializeSdk();
-    initializeLibraryMap();
-  }
-  /**
-   * Return the file containing the Dartium executable, or {@code null} if it does not exist.
-   * @return the file containing the Dartium executable
-   */
-  File get dartiumExecutable {
-    {
-      if (_dartiumExecutable == null) {
-        File file = newRelativeFile(_sdkDirectory, dartiumBinaryName);
-        if (file.existsSync()) {
-          _dartiumExecutable = file;
-        }
-      }
-    }
-    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
-   */
-  File get dartiumWorkingDirectory {
-    if (OSUtilities.isWindows() || OSUtilities.isMac()) {
-      return _sdkDirectory;
-    } else {
-      return newRelativeFile(_sdkDirectory, _CHROMIUM_DIRECTORY_NAME);
-    }
-  }
-  /**
-   * Return the directory containing the SDK.
-   * @return the directory containing the SDK
-   */
-  File get directory => _sdkDirectory;
-  /**
-   * Return the directory containing documentation for the SDK.
-   * @return the SDK's documentation directory
-   */
-  File get docDirectory => newRelativeFile(_sdkDirectory, _DOCS_DIRECTORY_NAME);
-  /**
-   * Return the auxiliary documentation file for the given library, or {@code null} if no such file
-   * exists.
-   * @param libraryName the name of the library associated with the documentation file to be
-   * returned
-   * @return the auxiliary documentation file for the library
-   */
-  File getDocFileFor(String libraryName) {
-    File dir = docDirectory;
-    if (!dir.existsSync()) {
-      return null;
-    }
-    File libDir = newRelativeFile(dir, libraryName);
-    File docFile = newRelativeFile(libDir, "${libraryName}${_DOC_FILE_SUFFIX}");
-    if (docFile.existsSync()) {
-      return docFile;
-    }
-    return null;
-  }
-  /**
-   * Return the directory within the SDK directory that contains the libraries.
-   * @return the directory that contains the libraries
-   */
-  File get libraryDirectory => newRelativeFile(_sdkDirectory, _LIB_DIRECTORY_NAME);
-  /**
-   * Return the directory within the SDK directory that contains the packages.
-   * @return the directory that contains the packages
-   */
-  File get packageDirectory => newRelativeFile(directory, _PKG_DIRECTORY_NAME);
-  /**
-   * Return an array containing all of the libraries defined in this SDK.
-   * @return the libraries defined in this SDK
-   */
-  List<SdkLibrary> get sdkLibraries => _libraryMap.sdkLibraries;
-  /**
-   * Return the revision number of this SDK, or {@code "0"} if the revision number cannot be
-   * discovered.
-   * @return the revision number of this SDK
-   */
-  String get sdkVersion {
-    {
-      if (_sdkVersion == null) {
-        _sdkVersion = _DEFAULT_VERSION;
-        File revisionFile = newRelativeFile(_sdkDirectory, _REVISION_FILE_NAME);
-        try {
-          String revision = revisionFile.readAsStringSync();
-          if (revision != null) {
-            _sdkVersion = revision;
-          }
-        } on IOException catch (exception) {
-        }
-      }
-    }
-    return _sdkVersion;
-  }
-  /**
-   * Return an array containing the library URI's for the libraries defined in this SDK.
-   * @return the library URI's for the libraries defined in this SDK
-   */
-  List<String> get uris => _libraryMap.uris;
-  /**
-   * Return the file containing the VM executable, or {@code null} if it does not exist.
-   * @return the file containing the VM executable
-   */
-  File get vmExecutable {
-    {
-      if (_vmExecutable == null) {
-        File file = newRelativeFile(newRelativeFile(_sdkDirectory, _BIN_DIRECTORY_NAME), binaryName);
-        if (file.existsSync()) {
-          _vmExecutable = file;
-        }
-      }
-    }
-    return _vmExecutable;
-  }
-  /**
-   * Return {@code true} if this SDK includes documentation.
-   * @return {@code true} if this installation of the SDK has documentation
-   */
-  bool hasDocumentation() => docDirectory.existsSync();
-  /**
-   * Return {@code true} if the Dartium binary is available.
-   * @return {@code true} if the Dartium binary is available
-   */
-  bool isDartiumInstalled() => dartiumExecutable != null;
-  /**
-   * Return the file representing the library with the given {@code dart:} URI, or {@code null} if
-   * the given URI does not denote a library in this SDK.
-   * @param dartUri the URI of the library to be returned
-   * @return the file representing the specified library
-   */
-  File mapDartUri(String dartUri) {
-    SdkLibrary library = _libraryMap.getLibrary(dartUri);
-    if (library == null) {
-      return null;
-    }
-    return newRelativeFile(libraryDirectory, library.path);
-  }
-  /**
-   * 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.
-   */
-  void ensureVmIsExecutable() {
-  }
-  /**
-   * Return the name of the file containing the VM executable.
-   * @return the name of the file containing the VM executable
-   */
-  String get binaryName {
-    if (OSUtilities.isWindows()) {
-      return _VM_EXECUTABLE_NAME_WIN;
-    } else {
-      return _VM_EXECUTABLE_NAME;
-    }
-  }
-  /**
-   * Return the name of the file containing the Dartium executable.
-   * @return the name of the file containing the Dartium executable
-   */
-  String get dartiumBinaryName {
-    if (OSUtilities.isWindows()) {
-      return _DARTIUM_EXECUTABLE_NAME_WIN;
-    } else if (OSUtilities.isMac()) {
-      return _DARTIUM_EXECUTABLE_NAME_MAC;
-    } else {
-      return _DARTIUM_EXECUTABLE_NAME_LINUX;
-    }
-  }
-  /**
-   * Read all of the configuration files to initialize the library maps.
-   */
-  void initializeLibraryMap() {
-    try {
-      File librariesFile = newRelativeFile(newRelativeFile(libraryDirectory, _INTERNAL_DIR), _LIBRARIES_FILE);
-      String contents = librariesFile.readAsStringSync();
-      _libraryMap = new SdkLibrariesReader().readFrom(librariesFile, contents);
-    } on JavaException catch (exception) {
-      AnalysisEngine.instance.logger.logError3(exception);
-      _libraryMap = new LibraryMap();
-    }
-  }
-  /**
-   * Initialize the state of the SDK.
-   */
-  void initializeSdk() {
-    if (!OSUtilities.isWindows()) {
-      ensureVmIsExecutable();
-    }
-  }
-}
-/**
- * Instances of the class {@code SdkLibrariesReader} read and parse the libraries file
- * (dart-sdk/lib/_internal/libraries.dart) for information about the libraries in an SDK. The
- * library information is represented as a Dart file containing a single top-level variable whose
- * value is a const map. The keys of the map are the names of libraries defined in the SDK and the
- * values in the map are info objects defining the library. For example, a subset of a typical SDK
- * might have a libraries file that looks like the following:
- * <pre>
- * final Map&lt;String, LibraryInfo&gt; LIBRARIES = const &lt;LibraryInfo&gt; {
- * // Used by VM applications
- * "builtin" : const LibraryInfo(
- * "builtin/builtin_runtime.dart",
- * category: "Server",
- * platforms: VM_PLATFORM),
- * "compiler" : const LibraryInfo(
- * "compiler/compiler.dart",
- * category: "Tools",
- * platforms: 0),
- * };
- * </pre>
- */
-class SdkLibrariesReader {
-  /**
-   * Return the library map read from the given source.
-   * @return the library map read from the given source
-   */
-  LibraryMap readFrom(File librariesFile, String libraryFileContents) {
-    List<bool> foundError = [false];
-    AnalysisErrorListener errorListener = new AnalysisErrorListener_3(foundError);
-    Source source = new FileBasedSource.con2(null, librariesFile, false);
-    StringScanner scanner = new StringScanner(source, libraryFileContents, errorListener);
-    Parser parser = new Parser(source, errorListener);
-    CompilationUnit unit = parser.parseCompilationUnit(scanner.tokenize());
-    SdkLibrariesReader_LibraryBuilder libraryBuilder = new SdkLibrariesReader_LibraryBuilder();
-    if (!foundError[0]) {
-      unit.accept(libraryBuilder);
-    }
-    return libraryBuilder.librariesMap;
-  }
-}
-class SdkLibrariesReader_LibraryBuilder extends RecursiveASTVisitor<Object> {
-  /**
-   * The prefix added to the name of a library to form the URI used in code to reference the
-   * library.
-   */
-  static String _LIBRARY_PREFIX = "dart:";
-  /**
-   * The name of the optional parameter used to indicate whether the library is an implementation
-   * library.
-   */
-  static String _IMPLEMENTATION = "implementation";
-  /**
-   * The name of the optional parameter used to indicate whether the library is documented.
-   */
-  static String _DOCUMENTED = "documented";
-  /**
-   * The name of the optional parameter used to specify the category of the library.
-   */
-  static String _CATEGORY = "category";
-  /**
-   * The name of the optional parameter used to specify the platforms on which the library can be
-   * used.
-   */
-  static String _PLATFORMS = "platforms";
-  /**
-   * The value of the {@link #PLATFORMS platforms} parameter used to specify that the library can
-   * be used on the VM.
-   */
-  static String _VM_PLATFORM = "VM_PLATFORM";
-  /**
-   * The library map that is populated by visiting the AST structure parsed from the contents of
-   * the libraries file.
-   */
-  LibraryMap _librariesMap = new LibraryMap();
-  /**
-   * Return the library map that was populated by visiting the AST structure parsed from the
-   * contents of the libraries file.
-   * @return the library map describing the contents of the SDK
-   */
-  LibraryMap get librariesMap => _librariesMap;
-  Object visitMapLiteralEntry(MapLiteralEntry node) {
-    String libraryName = null;
-    Expression key3 = node.key;
-    if (key3 is SimpleStringLiteral) {
-      libraryName = "${_LIBRARY_PREFIX}${((key3 as SimpleStringLiteral)).value}";
-    }
-    Expression value8 = node.value;
-    if (value8 is InstanceCreationExpression) {
-      SdkLibraryImpl library = new SdkLibraryImpl(libraryName);
-      List<Expression> arguments6 = ((value8 as InstanceCreationExpression)).argumentList.arguments;
-      for (Expression argument in arguments6) {
-        if (argument is SimpleStringLiteral) {
-          library.path = ((argument as SimpleStringLiteral)).value;
-        } else if (argument is NamedExpression) {
-          String name18 = ((argument as NamedExpression)).name.label.name;
-          Expression expression15 = ((argument as NamedExpression)).expression;
-          if (name18 == _CATEGORY) {
-            library.category = ((expression15 as SimpleStringLiteral)).value;
-          } else if (name18 == _IMPLEMENTATION) {
-            library.implementation = ((expression15 as BooleanLiteral)).value;
-          } else if (name18 == _DOCUMENTED) {
-            library.documented = ((expression15 as BooleanLiteral)).value;
-          } else if (name18 == _PLATFORMS) {
-            if (expression15 is SimpleIdentifier) {
-              String identifier = ((expression15 as SimpleIdentifier)).name;
-              if (identifier == _VM_PLATFORM) {
-                library.setVmLibrary();
-              } else {
-                library.setDart2JsLibrary();
-              }
-            }
-          }
-        }
-      }
-      _librariesMap.setLibrary(libraryName, library);
-    }
-    return null;
-  }
-}
-class AnalysisErrorListener_3 implements AnalysisErrorListener {
-  List<bool> foundError;
-  AnalysisErrorListener_3(this.foundError);
-  void onError(AnalysisError error) {
-    foundError[0] = true;
-  }
-}
-/**
  * Instances of the class {@code SdkLibrary} represent the information known about a single library
  * within the SDK.
+ * @coverage dart.engine.sdk
  */
 class SdkLibraryImpl implements SdkLibrary {
   /**
@@ -659,4 +165,508 @@
   void setVmLibrary() {
     _platforms |= VM_PLATFORM;
   }
+}
+/**
+ * Instances of the class {@code SdkLibrariesReader} read and parse the libraries file
+ * (dart-sdk/lib/_internal/libraries.dart) for information about the libraries in an SDK. The
+ * library information is represented as a Dart file containing a single top-level variable whose
+ * value is a const map. The keys of the map are the names of libraries defined in the SDK and the
+ * values in the map are info objects defining the library. For example, a subset of a typical SDK
+ * might have a libraries file that looks like the following:
+ * <pre>
+ * final Map&lt;String, LibraryInfo&gt; LIBRARIES = const &lt;LibraryInfo&gt; {
+ * // Used by VM applications
+ * "builtin" : const LibraryInfo(
+ * "builtin/builtin_runtime.dart",
+ * category: "Server",
+ * platforms: VM_PLATFORM),
+ * "compiler" : const LibraryInfo(
+ * "compiler/compiler.dart",
+ * category: "Tools",
+ * platforms: 0),
+ * };
+ * </pre>
+ * @coverage dart.engine.sdk
+ */
+class SdkLibrariesReader {
+  /**
+   * Return the library map read from the given source.
+   * @return the library map read from the given source
+   */
+  LibraryMap readFrom(JavaFile librariesFile, String libraryFileContents) {
+    List<bool> foundError = [false];
+    AnalysisErrorListener errorListener = new AnalysisErrorListener_6(foundError);
+    Source source = new FileBasedSource.con2(null, librariesFile, false);
+    StringScanner scanner = new StringScanner(source, libraryFileContents, errorListener);
+    Parser parser = new Parser(source, errorListener);
+    CompilationUnit unit = parser.parseCompilationUnit(scanner.tokenize());
+    SdkLibrariesReader_LibraryBuilder libraryBuilder = new SdkLibrariesReader_LibraryBuilder();
+    if (!foundError[0]) {
+      unit.accept(libraryBuilder);
+    }
+    return libraryBuilder.librariesMap;
+  }
+}
+class SdkLibrariesReader_LibraryBuilder extends RecursiveASTVisitor<Object> {
+  /**
+   * The prefix added to the name of a library to form the URI used in code to reference the
+   * library.
+   */
+  static String _LIBRARY_PREFIX = "dart:";
+  /**
+   * The name of the optional parameter used to indicate whether the library is an implementation
+   * library.
+   */
+  static String _IMPLEMENTATION = "implementation";
+  /**
+   * The name of the optional parameter used to indicate whether the library is documented.
+   */
+  static String _DOCUMENTED = "documented";
+  /**
+   * The name of the optional parameter used to specify the category of the library.
+   */
+  static String _CATEGORY = "category";
+  /**
+   * The name of the optional parameter used to specify the platforms on which the library can be
+   * used.
+   */
+  static String _PLATFORMS = "platforms";
+  /**
+   * The value of the {@link #PLATFORMS platforms} parameter used to specify that the library can
+   * be used on the VM.
+   */
+  static String _VM_PLATFORM = "VM_PLATFORM";
+  /**
+   * The library map that is populated by visiting the AST structure parsed from the contents of
+   * the libraries file.
+   */
+  LibraryMap _librariesMap = new LibraryMap();
+  /**
+   * Return the library map that was populated by visiting the AST structure parsed from the
+   * contents of the libraries file.
+   * @return the library map describing the contents of the SDK
+   */
+  LibraryMap get librariesMap => _librariesMap;
+  Object visitMapLiteralEntry(MapLiteralEntry node) {
+    String libraryName = null;
+    Expression key3 = node.key;
+    if (key3 is SimpleStringLiteral) {
+      libraryName = "${_LIBRARY_PREFIX}${((key3 as SimpleStringLiteral)).value}";
+    }
+    Expression value9 = node.value;
+    if (value9 is InstanceCreationExpression) {
+      SdkLibraryImpl library = new SdkLibraryImpl(libraryName);
+      List<Expression> arguments7 = ((value9 as InstanceCreationExpression)).argumentList.arguments;
+      for (Expression argument in arguments7) {
+        if (argument is SimpleStringLiteral) {
+          library.path = ((argument as SimpleStringLiteral)).value;
+        } else if (argument is NamedExpression) {
+          String name19 = ((argument as NamedExpression)).name.label.name;
+          Expression expression15 = ((argument as NamedExpression)).expression;
+          if (name19 == _CATEGORY) {
+            library.category = ((expression15 as SimpleStringLiteral)).value;
+          } else if (name19 == _IMPLEMENTATION) {
+            library.implementation = ((expression15 as BooleanLiteral)).value;
+          } else if (name19 == _DOCUMENTED) {
+            library.documented = ((expression15 as BooleanLiteral)).value;
+          } else if (name19 == _PLATFORMS) {
+            if (expression15 is SimpleIdentifier) {
+              String identifier = ((expression15 as SimpleIdentifier)).name;
+              if (identifier == _VM_PLATFORM) {
+                library.setVmLibrary();
+              } else {
+                library.setDart2JsLibrary();
+              }
+            }
+          }
+        }
+      }
+      _librariesMap.setLibrary(libraryName, library);
+    }
+    return null;
+  }
+}
+class AnalysisErrorListener_6 implements AnalysisErrorListener {
+  List<bool> foundError;
+  AnalysisErrorListener_6(this.foundError);
+  void onError(AnalysisError error) {
+    foundError[0] = true;
+  }
+}
+/**
+ * Instances of the class {@code LibraryMap} map Dart library URI's to the {@link SdkLibraryImpllibrary}.
+ * @coverage dart.engine.sdk
+ */
+class LibraryMap {
+  /**
+   * A table mapping Dart library URI's to the library.
+   */
+  Map<String, SdkLibraryImpl> _libraryMap = new Map<String, SdkLibraryImpl>();
+  /**
+   * Initialize a newly created library map to be empty.
+   */
+  LibraryMap() : super() {
+  }
+  /**
+   * Return the library with the given URI, or {@code null} if the URI does not map to a library.
+   * @param dartUri the URI of the library to be returned
+   * @return the library with the given URI
+   */
+  SdkLibrary getLibrary(String dartUri) => _libraryMap[dartUri];
+  /**
+   * Return an array containing all the sdk libraries {@link SdkLibraryImpl} in the mapping
+   * @return the sdk libraries in the mapping
+   */
+  List<SdkLibrary> get sdkLibraries => new List.from(_libraryMap.values);
+  /**
+   * Return an array containing the library URI's for which a mapping is available.
+   * @return the library URI's for which a mapping is available
+   */
+  List<String> get uris => new List.from(_libraryMap.keys.toSet());
+  /**
+   * Return the library with the given URI, or {@code null} if the URI does not map to a library.
+   * @param dartUri the URI of the library to be returned
+   * @param library the library with the given URI
+   */
+  void setLibrary(String dartUri, SdkLibraryImpl library) {
+    _libraryMap[dartUri] = library;
+  }
+  /**
+   * Return the number of library URI's for which a mapping is available.
+   * @return the number of library URI's for which a mapping is available
+   */
+  int size() => _libraryMap.length;
+}
+/**
+ * Instances of the class {@code DartSdk} represent a Dart SDK installed in a specified location.
+ * @coverage dart.engine.sdk
+ */
+class DartSdk {
+  /**
+   * The short name of the dart SDK core library.
+   */
+  static String DART_CORE = "dart:core";
+  /**
+   * The short name of the dart SDK html library.
+   */
+  static String DART_HTML = "dart:html";
+  /**
+   * The directory containing the SDK.
+   */
+  JavaFile _sdkDirectory;
+  /**
+   * The revision number of this SDK, or {@code "0"} if the revision number cannot be discovered.
+   */
+  String _sdkVersion;
+  /**
+   * The file containing the Dartium executable.
+   */
+  JavaFile _dartiumExecutable;
+  /**
+   * The file containing the VM executable.
+   */
+  JavaFile _vmExecutable;
+  /**
+   * A mapping from Dart library URI's to the library represented by that URI.
+   */
+  LibraryMap _libraryMap;
+  /**
+   * The name of the directory within the SDK directory that contains executables.
+   */
+  static String _BIN_DIRECTORY_NAME = "bin";
+  /**
+   * The name of the directory within the SDK directory that contains Chromium.
+   */
+  static String _CHROMIUM_DIRECTORY_NAME = "chromium";
+  /**
+   * The name of the environment variable whose value is the path to the default Dart SDK directory.
+   */
+  static String _DART_SDK_ENVIRONMENT_VARIABLE_NAME = "DART_SDK";
+  /**
+   * The name of the file containing the Dartium executable on Linux.
+   */
+  static String _DARTIUM_EXECUTABLE_NAME_LINUX = "chromium/chrome";
+  /**
+   * The name of the file containing the Dartium executable on Macintosh.
+   */
+  static String _DARTIUM_EXECUTABLE_NAME_MAC = "Chromium.app/Contents/MacOS/Chromium";
+  /**
+   * The name of the file containing the Dartium executable on Windows.
+   */
+  static String _DARTIUM_EXECUTABLE_NAME_WIN = "chromium/Chrome.exe";
+  /**
+   * The name of the {@link System} property whose value is the path to the default Dart SDK
+   * directory.
+   */
+  static String _DEFAULT_DIRECTORY_PROPERTY_NAME = "com.google.dart.sdk";
+  /**
+   * The version number that is returned when the real version number could not be determined.
+   */
+  static String _DEFAULT_VERSION = "0";
+  /**
+   * The name of the directory within the SDK directory that contains documentation for the
+   * libraries.
+   */
+  static String _DOCS_DIRECTORY_NAME = "docs";
+  /**
+   * The suffix added to the name of a library to derive the name of the file containing the
+   * documentation for that library.
+   */
+  static String _DOC_FILE_SUFFIX = "_api.json";
+  /**
+   * The name of the directory within the SDK directory that contains the libraries file.
+   */
+  static String _INTERNAL_DIR = "_internal";
+  /**
+   * The name of the directory within the SDK directory that contains the libraries.
+   */
+  static String _LIB_DIRECTORY_NAME = "lib";
+  /**
+   * The name of the libraries file.
+   */
+  static String _LIBRARIES_FILE = "libraries.dart";
+  /**
+   * The name of the directory within the SDK directory that contains the packages.
+   */
+  static String _PKG_DIRECTORY_NAME = "pkg";
+  /**
+   * The name of the file within the SDK directory that contains the revision number of the SDK.
+   */
+  static String _REVISION_FILE_NAME = "revision";
+  /**
+   * The name of the file containing the VM executable on the Windows operating system.
+   */
+  static String _VM_EXECUTABLE_NAME_WIN = "dart.exe";
+  /**
+   * The name of the file containing the VM executable on non-Windows operating systems.
+   */
+  static String _VM_EXECUTABLE_NAME = "dart";
+  /**
+   * Return the default Dart SDK, or {@code null} if the directory containing the default SDK cannot
+   * be determined (or does not exist).
+   * @return the default Dart SDK
+   */
+  static DartSdk get defaultSdk {
+    JavaFile sdkDirectory = defaultSdkDirectory;
+    if (sdkDirectory == null) {
+      return null;
+    }
+    return new DartSdk(sdkDirectory);
+  }
+  /**
+   * Return the default directory for the Dart SDK, or {@code null} if the directory cannot be
+   * determined (or does not exist). The default directory is provided by a {@link System} property
+   * named {@code com.google.dart.sdk}, or, if the property is not defined, an environment variable
+   * named {@code DART_SDK}.
+   * @return the default directory for the Dart SDK
+   */
+  static JavaFile get defaultSdkDirectory {
+    String sdkProperty = JavaSystemIO.getProperty(_DEFAULT_DIRECTORY_PROPERTY_NAME);
+    if (sdkProperty == null) {
+      sdkProperty = JavaSystemIO.getenv(_DART_SDK_ENVIRONMENT_VARIABLE_NAME);
+      if (sdkProperty == null) {
+        return null;
+      }
+    }
+    JavaFile sdkDirectory = new JavaFile(sdkProperty);
+    if (!sdkDirectory.exists()) {
+      return null;
+    }
+    return sdkDirectory;
+  }
+  /**
+   * Initialize a newly created SDK to represent the Dart SDK installed in the given directory.
+   * @param sdkDirectory the directory containing the SDK
+   */
+  DartSdk(JavaFile sdkDirectory) {
+    this._sdkDirectory = sdkDirectory.getAbsoluteFile();
+    initializeSdk();
+    initializeLibraryMap();
+  }
+  /**
+   * Return the file containing the Dartium executable, or {@code null} if it does not exist.
+   * @return the file containing the Dartium executable
+   */
+  JavaFile get dartiumExecutable {
+    {
+      if (_dartiumExecutable == null) {
+        JavaFile file = new JavaFile.relative(_sdkDirectory, dartiumBinaryName);
+        if (file.exists()) {
+          _dartiumExecutable = file;
+        }
+      }
+    }
+    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
+   */
+  JavaFile get dartiumWorkingDirectory {
+    if (OSUtilities.isWindows() || OSUtilities.isMac()) {
+      return _sdkDirectory;
+    } else {
+      return new JavaFile.relative(_sdkDirectory, _CHROMIUM_DIRECTORY_NAME);
+    }
+  }
+  /**
+   * Return the directory containing the SDK.
+   * @return the directory containing the SDK
+   */
+  JavaFile get directory => _sdkDirectory;
+  /**
+   * Return the directory containing documentation for the SDK.
+   * @return the SDK's documentation directory
+   */
+  JavaFile get docDirectory => new JavaFile.relative(_sdkDirectory, _DOCS_DIRECTORY_NAME);
+  /**
+   * Return the auxiliary documentation file for the given library, or {@code null} if no such file
+   * exists.
+   * @param libraryName the name of the library associated with the documentation file to be
+   * returned
+   * @return the auxiliary documentation file for the library
+   */
+  JavaFile getDocFileFor(String libraryName) {
+    JavaFile dir = docDirectory;
+    if (!dir.exists()) {
+      return null;
+    }
+    JavaFile libDir = new JavaFile.relative(dir, libraryName);
+    JavaFile docFile = new JavaFile.relative(libDir, "${libraryName}${_DOC_FILE_SUFFIX}");
+    if (docFile.exists()) {
+      return docFile;
+    }
+    return null;
+  }
+  /**
+   * Return the directory within the SDK directory that contains the libraries.
+   * @return the directory that contains the libraries
+   */
+  JavaFile get libraryDirectory => new JavaFile.relative(_sdkDirectory, _LIB_DIRECTORY_NAME);
+  /**
+   * Return the directory within the SDK directory that contains the packages.
+   * @return the directory that contains the packages
+   */
+  JavaFile get packageDirectory => new JavaFile.relative(directory, _PKG_DIRECTORY_NAME);
+  /**
+   * Return an array containing all of the libraries defined in this SDK.
+   * @return the libraries defined in this SDK
+   */
+  List<SdkLibrary> get sdkLibraries => _libraryMap.sdkLibraries;
+  /**
+   * Return the revision number of this SDK, or {@code "0"} if the revision number cannot be
+   * discovered.
+   * @return the revision number of this SDK
+   */
+  String get sdkVersion {
+    {
+      if (_sdkVersion == null) {
+        _sdkVersion = _DEFAULT_VERSION;
+        JavaFile revisionFile = new JavaFile.relative(_sdkDirectory, _REVISION_FILE_NAME);
+        try {
+          String revision = revisionFile.readAsStringSync();
+          if (revision != null) {
+            _sdkVersion = revision;
+          }
+        } on IOException catch (exception) {
+        }
+      }
+    }
+    return _sdkVersion;
+  }
+  /**
+   * Return an array containing the library URI's for the libraries defined in this SDK.
+   * @return the library URI's for the libraries defined in this SDK
+   */
+  List<String> get uris => _libraryMap.uris;
+  /**
+   * Return the file containing the VM executable, or {@code null} if it does not exist.
+   * @return the file containing the VM executable
+   */
+  JavaFile get vmExecutable {
+    {
+      if (_vmExecutable == null) {
+        JavaFile file = new JavaFile.relative(new JavaFile.relative(_sdkDirectory, _BIN_DIRECTORY_NAME), binaryName);
+        if (file.exists()) {
+          _vmExecutable = file;
+        }
+      }
+    }
+    return _vmExecutable;
+  }
+  /**
+   * Return {@code true} if this SDK includes documentation.
+   * @return {@code true} if this installation of the SDK has documentation
+   */
+  bool hasDocumentation() => docDirectory.exists();
+  /**
+   * Return {@code true} if the Dartium binary is available.
+   * @return {@code true} if the Dartium binary is available
+   */
+  bool isDartiumInstalled() => dartiumExecutable != null;
+  /**
+   * Return the file representing the library with the given {@code dart:} URI, or {@code null} if
+   * the given URI does not denote a library in this SDK.
+   * @param dartUri the URI of the library to be returned
+   * @return the file representing the specified library
+   */
+  JavaFile mapDartUri(String dartUri) {
+    SdkLibrary library = _libraryMap.getLibrary(dartUri);
+    if (library == null) {
+      return null;
+    }
+    return new JavaFile.relative(libraryDirectory, library.path);
+  }
+  /**
+   * 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.
+   */
+  void ensureVmIsExecutable() {
+  }
+  /**
+   * Return the name of the file containing the VM executable.
+   * @return the name of the file containing the VM executable
+   */
+  String get binaryName {
+    if (OSUtilities.isWindows()) {
+      return _VM_EXECUTABLE_NAME_WIN;
+    } else {
+      return _VM_EXECUTABLE_NAME;
+    }
+  }
+  /**
+   * Return the name of the file containing the Dartium executable.
+   * @return the name of the file containing the Dartium executable
+   */
+  String get dartiumBinaryName {
+    if (OSUtilities.isWindows()) {
+      return _DARTIUM_EXECUTABLE_NAME_WIN;
+    } else if (OSUtilities.isMac()) {
+      return _DARTIUM_EXECUTABLE_NAME_MAC;
+    } else {
+      return _DARTIUM_EXECUTABLE_NAME_LINUX;
+    }
+  }
+  /**
+   * Read all of the configuration files to initialize the library maps.
+   */
+  void initializeLibraryMap() {
+    try {
+      JavaFile librariesFile = new JavaFile.relative(new JavaFile.relative(libraryDirectory, _INTERNAL_DIR), _LIBRARIES_FILE);
+      String contents = librariesFile.readAsStringSync();
+      _libraryMap = new SdkLibrariesReader().readFrom(librariesFile, contents);
+    } on JavaException catch (exception) {
+      AnalysisEngine.instance.logger.logError3(exception);
+      _libraryMap = new LibraryMap();
+    }
+  }
+  /**
+   * Initialize the state of the SDK.
+   */
+  void initializeSdk() {
+    if (!OSUtilities.isWindows()) {
+      ensureVmIsExecutable();
+    }
+  }
 }
\ No newline at end of file
diff --git a/pkg/analyzer_experimental/lib/src/generated/source.dart b/pkg/analyzer_experimental/lib/src/generated/source.dart
new file mode 100644
index 0000000..e99a657
--- /dev/null
+++ b/pkg/analyzer_experimental/lib/src/generated/source.dart
@@ -0,0 +1,548 @@
+// This code was auto-generated, is not intended to be edited, and is subject to
+// significant change. Please see the README file for more information.
+
+library engine.source;
+
+import 'dart:uri';
+import 'java_core.dart';
+
+/**
+ * Instances of the class {@code SourceFactory} resolve possibly relative URI's against an existing{@link Source source}.
+ * @coverage dart.engine.source
+ */
+class SourceFactory {
+  /**
+   * The resolvers used to resolve absolute URI's.
+   */
+  List<UriResolver> _resolvers;
+  /**
+   * A cache of content used to override the default content of a source.
+   */
+  ContentCache _contentCache;
+  /**
+   * Initialize a newly created source factory.
+   * @param contentCache the cache holding content used to override the default content of a source.
+   * @param resolvers the resolvers used to resolve absolute URI's
+   */
+  SourceFactory.con1(ContentCache contentCache2, List<UriResolver> resolvers2) {
+    _jtd_constructor_300_impl(contentCache2, resolvers2);
+  }
+  _jtd_constructor_300_impl(ContentCache contentCache2, List<UriResolver> resolvers2) {
+    this._contentCache = contentCache2;
+    this._resolvers = resolvers2;
+  }
+  /**
+   * Initialize a newly created source factory.
+   * @param resolvers the resolvers used to resolve absolute URI's
+   */
+  SourceFactory.con2(List<UriResolver> resolvers) {
+    _jtd_constructor_301_impl(resolvers);
+  }
+  _jtd_constructor_301_impl(List<UriResolver> resolvers) {
+    _jtd_constructor_300_impl(new ContentCache(), resolvers);
+  }
+  /**
+   * Return a source object representing the given absolute URI, or {@code null} if the URI is not a
+   * valid URI or if it is not an absolute URI.
+   * @param absoluteUri the absolute URI to be resolved
+   * @return a source object representing the absolute URI
+   */
+  Source forUri(String absoluteUri) {
+    try {
+      Uri uri = new Uri(absoluteUri);
+      if (uri.isAbsolute) {
+        return resolveUri2(null, uri);
+      }
+    } on URISyntaxException catch (exception) {
+    }
+    return null;
+  }
+  /**
+   * Return a source object that is equal to the source object used to obtain the given encoding, or{@code null} if the argument is not a valid encoding.
+   * @param encoding the encoding of a source object
+   * @return a source object that is described by the given encoding
+   * @see Source#getEncoding()
+   */
+  Source fromEncoding(String encoding) => forUri(encoding);
+  /**
+   * Return a source object representing the URI that results from resolving the given (possibly
+   * relative) contained URI against the URI associated with an existing source object, or{@code null} if either the contained URI is invalid or if it cannot be resolved against the
+   * source object's URI.
+   * @param containingSource the source containing the given URI
+   * @param containedUri the (possibly relative) URI to be resolved against the containing source
+   * @return the source representing the contained URI
+   */
+  Source resolveUri(Source containingSource, String containedUri) {
+    try {
+      return resolveUri2(containingSource, new Uri.fromComponents(path: containedUri));
+    } on URISyntaxException catch (exception) {
+      return null;
+    }
+  }
+  /**
+   * Set the contents of the given source to the given contents. This has the effect of overriding
+   * the default contents of the source. If the contents are {@code null} the override is removed so
+   * that the default contents will be returned.
+   * @param source the source whose contents are being overridden
+   * @param contents the new contents of the source
+   */
+  void setContents(Source source, String contents) {
+    _contentCache.setContents(source, contents);
+  }
+  /**
+   * Return the contents of the given source, or {@code null} if this factory does not override the
+   * contents of the source.
+   * <p>
+   * <b>Note:</b> This method is not intended to be used except by{@link FileBasedSource#getContents(com.google.dart.engine.source.Source.ContentReceiver)}.
+   * @param source the source whose content is to be returned
+   * @return the contents of the given source
+   */
+  String getContents(Source source) => _contentCache.getContents(source);
+  /**
+   * Return the modification stamp of the given source, or {@code null} if this factory does not
+   * override the contents of the source.
+   * <p>
+   * <b>Note:</b> This method is not intended to be used except by{@link FileBasedSource#getModificationStamp()}.
+   * @param source the source whose modification stamp is to be returned
+   * @return the modification stamp of the given source
+   */
+  int getModificationStamp(Source source) => _contentCache.getModificationStamp(source);
+  /**
+   * Return a source object representing the URI that results from resolving the given (possibly
+   * relative) contained URI against the URI associated with an existing source object, or{@code null} if either the contained URI is invalid or if it cannot be resolved against the
+   * source object's URI.
+   * @param containingSource the source containing the given URI
+   * @param containedUri the (possibly relative) URI to be resolved against the containing source
+   * @return the source representing the contained URI
+   */
+  Source resolveUri2(Source containingSource, Uri containedUri) {
+    if (containedUri.isAbsolute) {
+      for (UriResolver resolver in _resolvers) {
+        Source result = resolver.resolveAbsolute(this, containedUri);
+        if (result != null) {
+          return result;
+        }
+      }
+      return null;
+    } else {
+      return containingSource.resolveRelative(containedUri);
+    }
+  }
+}
+/**
+ * The abstract class {@code UriResolver} defines the behavior of objects that are used to resolve
+ * URI's for a source factory. Subclasses of this class are expected to resolve a single scheme of
+ * absolute URI.
+ * @coverage dart.engine.source
+ */
+abstract class UriResolver {
+  /**
+   * Initialize a newly created resolver.
+   */
+  UriResolver() : super() {
+  }
+  /**
+   * Resolve the given absolute URI. Return a {@link Source source} representing the file to which
+   * it was resolved, or {@code null} if it could not be resolved.
+   * @param uri the URI to be resolved
+   * @return a {@link Source source} representing the URI to which given URI was resolved
+   */
+  Source resolveAbsolute(SourceFactory factory, Uri uri);
+}
+/**
+ * The interface {@code Source} defines the behavior of objects representing source code that can be
+ * compiled.
+ * @coverage dart.engine.source
+ */
+abstract class Source {
+  /**
+   * An empty array of sources.
+   */
+  static List<Source> EMPTY_ARRAY = new List<Source>(0);
+  /**
+   * Return {@code true} if the given object is a source that represents the same source code as
+   * this source.
+   * @param object the object to be compared with this object
+   * @return {@code true} if the given object is a source that represents the same source code as
+   * this source
+   * @see Object#equals(Object)
+   */
+  bool operator ==(Object object);
+  /**
+   * Return {@code true} if this source exists.
+   * @return {@code true} if this source exists
+   */
+  bool exists();
+  /**
+   * Get the contents of this source and pass it to the given receiver. Exactly one of the methods
+   * defined on the receiver will be invoked unless an exception is thrown. The method that will be
+   * invoked depends on which of the possible representations of the contents is the most efficient.
+   * Whichever method is invoked, it will be invoked before this method returns.
+   * @param receiver the content receiver to which the content of this source will be passed
+   * @throws Exception if the contents of this source could not be accessed
+   */
+  void getContents(Source_ContentReceiver receiver);
+  /**
+   * Return an encoded representation of this source that can be used to create a source that is
+   * equal to this source.
+   * @return an encoded representation of this source
+   * @see SourceFactory#fromEncoding(String)
+   */
+  String get encoding;
+  /**
+   * Return the full (long) version of the name that can be displayed to the user to denote this
+   * source. For example, for a source representing a file this would typically be the absolute path
+   * of the file.
+   * @return a name that can be displayed to the user to denote this source
+   */
+  String get fullName;
+  /**
+   * Return the modification stamp for this source. A modification stamp is a non-negative integer
+   * with the property that if the contents of the source have not been modified since the last time
+   * the modification stamp was accessed then the same value will be returned, but if the contents
+   * of the source have been modified one or more times (even if the net change is zero) the stamps
+   * will be different.
+   * @return the modification stamp for this source
+   */
+  int get modificationStamp;
+  /**
+   * Return a short version of the name that can be displayed to the user to denote this source. For
+   * example, for a source representing a file this would typically be the name of the file.
+   * @return a name that can be displayed to the user to denote this source
+   */
+  String get shortName;
+  /**
+   * Return a hash code for this source.
+   * @return a hash code for this source
+   * @see Object#hashCode()
+   */
+  int get hashCode;
+  /**
+   * Return {@code true} if this source is in one of the system libraries.
+   * @return {@code true} if this is in a system library
+   */
+  bool isInSystemLibrary();
+  /**
+   * Resolve the given URI relative to the location of this source.
+   * @param uri the URI to be resolved against this source
+   * @return a source representing the resolved URI
+   */
+  Source resolve(String uri);
+  /**
+   * Resolve the relative URI against the URI associated with this source object. Return a{@link Source source} representing the URI to which it was resolved, or {@code null} if it
+   * could not be resolved.
+   * <p>
+   * Note: This method is not intended for public use, it is only visible out of necessity. It is
+   * only intended to be invoked by a {@link SourceFactory source factory}. Source factories will
+   * only invoke this method if the URI is relative, so implementations of this method are not
+   * required to, and generally do not, verify the argument. The result of invoking this method with
+   * an absolute URI is intentionally left unspecified.
+   * @param relativeUri the relative URI to be resolved against the containing source
+   * @return a {@link Source source} representing the URI to which given URI was resolved
+   */
+  Source resolveRelative(Uri relativeUri);
+}
+/**
+ * The interface {@code ContentReceiver} defines the behavior of objects that can receive the
+ * content of a source.
+ */
+abstract class Source_ContentReceiver {
+  /**
+   * Accept the contents of a source represented as a character buffer.
+   * @param contents the contents of the source
+   */
+  accept(CharBuffer contents);
+  /**
+   * Accept the contents of a source represented as a string.
+   * @param contents the contents of the source
+   */
+  void accept2(String contents);
+}
+/**
+ * The enumeration {@code SourceKind} defines the different kinds of sources that are known to the
+ * analysis engine.
+ * @coverage dart.engine.source
+ */
+class SourceKind {
+  /**
+   * A source containing HTML. The HTML might or might not contain Dart scripts.
+   */
+  static final SourceKind HTML = new SourceKind('HTML', 0);
+  /**
+   * A Dart compilation unit that is not a part of another library. Libraries might or might not
+   * contain any directives, including a library directive.
+   */
+  static final SourceKind LIBRARY = new SourceKind('LIBRARY', 1);
+  /**
+   * A Dart compilation unit that is part of another library. Parts contain a part-of directive.
+   */
+  static final SourceKind PART = new SourceKind('PART', 2);
+  /**
+   * An unknown kind of source. Used both when it is not possible to identify the kind of a source
+   * and also when the kind of a source is not known without performing a computation and the client
+   * does not want to spend the time to identify the kind.
+   */
+  static final SourceKind UNKNOWN = new SourceKind('UNKNOWN', 3);
+  static final List<SourceKind> values = [HTML, LIBRARY, PART, UNKNOWN];
+  final String __name;
+  final int __ordinal;
+  int get ordinal => __ordinal;
+  SourceKind(this.__name, this.__ordinal) {
+  }
+  String toString() => __name;
+}
+/**
+ * A source range defines an {@link Element}'s source coordinates relative to its {@link Source}.
+ * @coverage dart.engine.utilities
+ */
+class SourceRange {
+  /**
+   * The 0-based index of the first character of the source code for this element, relative to the
+   * source buffer in which this element is contained.
+   */
+  int _offset = 0;
+  /**
+   * The number of characters of the source code for this element, relative to the source buffer in
+   * which this element is contained.
+   */
+  int _length = 0;
+  /**
+   * Initialize a newly created source range using the given offset and the given length.
+   * @param offset the given offset
+   * @param length the given length
+   */
+  SourceRange(int offset, int length) {
+    this._offset = offset;
+    this._length = length;
+  }
+  /**
+   * @return <code>true</code> if <code>x</code> is in [offset, offset + length) interval.
+   */
+  bool contains(int x) => _offset <= x && x < _offset + _length;
+  /**
+   * @return <code>true</code> if <code>x</code> is in (offset, offset + length) interval.
+   */
+  bool containsExclusive(int x) => _offset < x && x < _offset + _length;
+  /**
+   * @return <code>true</code> if <code>otherRange</code> covers this {@link SourceRange}.
+   */
+  bool coveredBy(SourceRange otherRange) => otherRange.covers(this);
+  /**
+   * @return <code>true</code> if this {@link SourceRange} covers <code>otherRange</code>.
+   */
+  bool covers(SourceRange otherRange) => offset <= otherRange.offset && otherRange.end <= end;
+  /**
+   * @return <code>true</code> if this {@link SourceRange} ends in <code>otherRange</code>.
+   */
+  bool endsIn(SourceRange otherRange) {
+    int thisEnd = end;
+    return otherRange.contains(thisEnd);
+  }
+  bool operator ==(Object obj) {
+    if (obj is! SourceRange) {
+      return false;
+    }
+    SourceRange sourceRange = obj as SourceRange;
+    return sourceRange.offset == _offset && sourceRange.length == _length;
+  }
+  /**
+   * @return the 0-based index of the after-last character of the source code for this element,
+   * relative to the source buffer in which this element is contained.
+   */
+  int get end => _offset + _length;
+  /**
+   * @return the expanded instance of {@link SourceRange}, which has the same center.
+   */
+  SourceRange getExpanded(int delta) => new SourceRange(_offset - delta, delta + _length + delta);
+  /**
+   * Returns the number of characters of the source code for this element, relative to the source
+   * buffer in which this element is contained.
+   * @return the number of characters of the source code for this element, relative to the source
+   * buffer in which this element is contained
+   */
+  int get length => _length;
+  /**
+   * @return the instance of {@link SourceRange} with end moved on "delta".
+   */
+  SourceRange getMoveEnd(int delta) => new SourceRange(_offset, _length + delta);
+  /**
+   * Returns the 0-based index of the first character of the source code for this element, relative
+   * to the source buffer in which this element is contained.
+   * @return the 0-based index of the first character of the source code for this element, relative
+   * to the source buffer in which this element is contained
+   */
+  int get offset => _offset;
+  int get hashCode => 31 * _offset + _length;
+  /**
+   * @return <code>true</code> if this {@link SourceRange} intersects with given.
+   */
+  bool intersects(SourceRange other) {
+    if (other == null) {
+      return false;
+    }
+    if (end <= other.offset) {
+      return false;
+    }
+    if (offset >= other.end) {
+      return false;
+    }
+    return true;
+  }
+  /**
+   * @return <code>true</code> if this {@link SourceRange} starts in <code>otherRange</code>.
+   */
+  bool startsIn(SourceRange otherRange) => otherRange.contains(_offset);
+  String toString() {
+    JavaStringBuilder builder = new JavaStringBuilder();
+    builder.append("[offset=");
+    builder.append(_offset);
+    builder.append(", length=");
+    builder.append(_length);
+    builder.append("]");
+    return builder.toString();
+  }
+}
+/**
+ * The interface {@code SourceContainer} is used by clients to define a collection of sources
+ * <p>
+ * Source containers are not used within analysis engine, but can be used by clients to group
+ * sources for the purposes of accessing composite dependency information. For example, the Eclipse
+ * client uses source containers to represent Eclipse projects, which allows it to easily compute
+ * project-level dependencies.
+ * @coverage dart.engine.source
+ */
+abstract class SourceContainer {
+  /**
+   * Determine if the specified source is part of the receiver's collection of sources.
+   * @param source the source in question
+   * @return {@code true} if the receiver contains the source, else {@code false}
+   */
+  bool contains(Source source);
+}
+/**
+ * Instances of the class {@code LineInfo} encapsulate information about line and column information
+ * within a source file.
+ * @coverage dart.engine.utilities
+ */
+class LineInfo {
+  /**
+   * An array containing the offsets of the first character of each line in the source code.
+   */
+  List<int> _lineStarts;
+  /**
+   * Initialize a newly created set of line information to represent the data encoded in the given
+   * array.
+   * @param lineStarts the offsets of the first character of each line in the source code
+   */
+  LineInfo(List<int> lineStarts) {
+    if (lineStarts == null) {
+      throw new IllegalArgumentException("lineStarts must be non-null");
+    } else if (lineStarts.length < 1) {
+      throw new IllegalArgumentException("lineStarts must be non-empty");
+    }
+    this._lineStarts = lineStarts;
+  }
+  /**
+   * Return the location information for the character at the given offset.
+   * @param offset the offset of the character for which location information is to be returned
+   * @return the location information for the character at the given offset
+   */
+  LineInfo_Location getLocation(int offset) {
+    int lineCount = _lineStarts.length;
+    for (int i = 1; i < lineCount; i++) {
+      if (offset < _lineStarts[i]) {
+        return new LineInfo_Location(i, offset - _lineStarts[i - 1] + 1);
+      }
+    }
+    return new LineInfo_Location(lineCount, offset - _lineStarts[lineCount - 1] + 1);
+  }
+}
+/**
+ * Instances of the class {@code Location} represent the location of a character as a line and
+ * column pair.
+ */
+class LineInfo_Location {
+  /**
+   * The one-based index of the line containing the character.
+   */
+  int _lineNumber = 0;
+  /**
+   * The one-based index of the column containing the character.
+   */
+  int _columnNumber = 0;
+  /**
+   * Initialize a newly created location to represent the location of the character at the given
+   * line and column position.
+   * @param lineNumber the one-based index of the line containing the character
+   * @param columnNumber the one-based index of the column containing the character
+   */
+  LineInfo_Location(int lineNumber, int columnNumber) {
+    this._lineNumber = lineNumber;
+    this._columnNumber = columnNumber;
+  }
+  /**
+   * Return the one-based index of the column containing the character.
+   * @return the one-based index of the column containing the character
+   */
+  int get columnNumber => _columnNumber;
+  /**
+   * Return the one-based index of the line containing the character.
+   * @return the one-based index of the line containing the character
+   */
+  int get lineNumber => _lineNumber;
+}
+/**
+ * Instances of class {@code ContentCache} hold content used to override the default content of a{@link Source}.
+ * @coverage dart.engine.source
+ */
+class ContentCache {
+  /**
+   * A table mapping sources to the contents of those sources. This is used to override the default
+   * contents of a source.
+   */
+  Map<Source, String> _contentMap = new Map<Source, String>();
+  /**
+   * A table mapping sources to the modification stamps of those sources. This is used when the
+   * default contents of a source has been overridden.
+   */
+  Map<Source, int> _stampMap = new Map<Source, int>();
+  /**
+   * Initialize a newly created cache to be empty.
+   */
+  ContentCache() : super() {
+  }
+  /**
+   * Return the contents of the given source, or {@code null} if this cache does not override the
+   * contents of the source.
+   * <p>
+   * <b>Note:</b> This method is not intended to be used except by{@link SourceFactory#getContents(com.google.dart.engine.source.Source.ContentReceiver)}.
+   * @param source the source whose content is to be returned
+   * @return the contents of the given source
+   */
+  String getContents(Source source) => _contentMap[source];
+  /**
+   * Return the modification stamp of the given source, or {@code null} if this cache does not
+   * override the contents of the source.
+   * <p>
+   * <b>Note:</b> This method is not intended to be used except by{@link SourceFactory#getModificationStamp(com.google.dart.engine.source.Source)}.
+   * @param source the source whose modification stamp is to be returned
+   * @return the modification stamp of the given source
+   */
+  int getModificationStamp(Source source) => _stampMap[source];
+  /**
+   * Set the contents of the given source to the given contents. This has the effect of overriding
+   * the default contents of the source. If the contents are {@code null} the override is removed so
+   * that the default contents will be returned.
+   * @param source the source whose contents are being overridden
+   * @param contents the new contents of the source
+   */
+  void setContents(Source source, String contents) {
+    if (contents == null) {
+      _contentMap.remove(source);
+      _stampMap.remove(source);
+    } else {
+      _contentMap[source] = contents;
+      _stampMap[source] = JavaSystem.currentTimeMillis();
+    }
+  }
+}
\ No newline at end of file
diff --git a/pkg/analyzer_experimental/lib/src/generated/source_io.dart b/pkg/analyzer_experimental/lib/src/generated/source_io.dart
new file mode 100644
index 0000000..d57574f
--- /dev/null
+++ b/pkg/analyzer_experimental/lib/src/generated/source_io.dart
@@ -0,0 +1,270 @@
+// This code was auto-generated, is not intended to be edited, and is subject to
+// significant change. Please see the README file for more information.
+
+library engine.source.io;
+
+import 'source.dart';
+import 'dart:io';
+import 'dart:uri';
+import 'java_core.dart';
+import 'java_io.dart';
+import 'package:analyzer_experimental/src/generated/sdk.dart' show DartSdk;
+export 'source.dart';
+
+/**
+ * Instances of the class {@code FileBasedSource} implement a source that represents a file.
+ * @coverage dart.engine.source
+ */
+class FileBasedSource implements Source {
+  /**
+   * The source factory that created this source and that should be used to resolve URI's against
+   * this source.
+   */
+  SourceFactory _factory;
+  /**
+   * The file represented by this source.
+   */
+  JavaFile _file;
+  /**
+   * A flag indicating whether this source is in one of the system libraries.
+   */
+  bool _inSystemLibrary = false;
+  /**
+   * Initialize a newly created source object. The source object is assumed to not be in a system
+   * library.
+   * @param factory the source factory that created this source
+   * @param file the file represented by this source
+   */
+  FileBasedSource.con1(SourceFactory factory, JavaFile file) {
+    _jtd_constructor_296_impl(factory, file);
+  }
+  _jtd_constructor_296_impl(SourceFactory factory, JavaFile file) {
+    _jtd_constructor_297_impl(factory, file, false);
+  }
+  /**
+   * Initialize a newly created source object.
+   * @param factory the source factory that created this source
+   * @param file the file represented by this source
+   * @param inSystemLibrary {@code true} if this source is in one of the system libraries
+   */
+  FileBasedSource.con2(SourceFactory factory2, JavaFile file3, bool inSystemLibrary2) {
+    _jtd_constructor_297_impl(factory2, file3, inSystemLibrary2);
+  }
+  _jtd_constructor_297_impl(SourceFactory factory2, JavaFile file3, bool inSystemLibrary2) {
+    this._factory = factory2;
+    this._file = file3;
+    this._inSystemLibrary = inSystemLibrary2;
+  }
+  bool operator ==(Object object) => object != null && identical(this.runtimeType, object.runtimeType) && _file == ((object as FileBasedSource))._file;
+  bool exists() => _file.exists();
+  void getContents(Source_ContentReceiver receiver) {
+    {
+      String contents = _factory.getContents(this);
+      if (contents != null) {
+        receiver.accept2(contents);
+        return;
+      }
+    }
+    receiver.accept2(_file.readAsStringSync());
+  }
+  String get encoding => _file.toURI().toString();
+  String get fullName => _file.getAbsolutePath();
+  int get modificationStamp {
+    int stamp = _factory.getModificationStamp(this);
+    if (stamp != null) {
+      return stamp;
+    }
+    return _file.lastModified();
+  }
+  String get shortName => _file.getName();
+  int get hashCode => _file.hashCode;
+  bool isInSystemLibrary() => _inSystemLibrary;
+  Source resolve(String uri) => _factory.resolveUri(this, uri);
+  Source resolveRelative(Uri containedUri) {
+    try {
+      Uri resolvedUri = file.toURI().resolveUri(containedUri);
+      return new FileBasedSource.con1(_factory, new JavaFile.fromUri(resolvedUri));
+    } on JavaException catch (exception) {
+    }
+    return null;
+  }
+  String toString() {
+    if (_file == null) {
+      return "<unknown source>";
+    }
+    return _file.getAbsolutePath();
+  }
+  /**
+   * Return the file represented by this source. This is an internal method that is only intended to
+   * be used by {@link UriResolver}.
+   * @return the file represented by this source
+   */
+  JavaFile get file => _file;
+}
+/**
+ * Instances of the class {@code DartUriResolver} resolve {@code dart} URI's.
+ * @coverage dart.engine.source
+ */
+class DartUriResolver extends UriResolver {
+  /**
+   * The Dart SDK against which URI's are to be resolved.
+   */
+  DartSdk _sdk;
+  /**
+   * The name of the {@code dart} scheme.
+   */
+  static String _DART_SCHEME = "dart";
+  /**
+   * Return {@code true} if the given URI is a {@code dart:} URI.
+   * @param uri the URI being tested
+   * @return {@code true} if the given URI is a {@code dart:} URI
+   */
+  static bool isDartUri(Uri uri) => uri.scheme == _DART_SCHEME;
+  /**
+   * Initialize a newly created resolver to resolve Dart URI's against the given platform within the
+   * given Dart SDK.
+   * @param sdk the Dart SDK against which URI's are to be resolved
+   */
+  DartUriResolver(DartSdk sdk) {
+    this._sdk = sdk;
+  }
+  Source resolveAbsolute(SourceFactory factory, Uri uri) {
+    if (!isDartUri(uri)) {
+      return null;
+    }
+    JavaFile resolvedFile = _sdk.mapDartUri(uri.toString());
+    return new FileBasedSource.con2(factory, resolvedFile, true);
+  }
+}
+/**
+ * Instances of the class {@code PackageUriResolver} resolve {@code package} URI's in the context of
+ * an application.
+ * @coverage dart.engine.source
+ */
+class PackageUriResolver extends UriResolver {
+  /**
+   * The package directories that {@code package} URI's are assumed to be relative to.
+   */
+  List<JavaFile> _packagesDirectories;
+  /**
+   * The name of the {@code package} scheme.
+   */
+  static String _PACKAGE_SCHEME = "package";
+  /**
+   * Return {@code true} if the given URI is a {@code package} URI.
+   * @param uri the URI being tested
+   * @return {@code true} if the given URI is a {@code package} URI
+   */
+  static bool isPackageUri(Uri uri) => uri.scheme == _PACKAGE_SCHEME;
+  /**
+   * Initialize a newly created resolver to resolve {@code package} URI's relative to the given
+   * package directories.
+   * @param packagesDirectories the package directories that {@code package} URI's are assumed to be
+   * relative to
+   */
+  PackageUriResolver(List<JavaFile> packagesDirectories) {
+    if (packagesDirectories.length < 1) {
+      throw new IllegalArgumentException("At least one package directory must be provided");
+    }
+    this._packagesDirectories = packagesDirectories;
+  }
+  Source resolveAbsolute(SourceFactory factory, Uri uri) {
+    if (!isPackageUri(uri)) {
+      return null;
+    }
+    String path4 = uri.path;
+    if (path4 == null) {
+      path4 = uri.path;
+      if (path4 == null) {
+        return null;
+      }
+    }
+    for (JavaFile packagesDirectory in _packagesDirectories) {
+      JavaFile resolvedFile = new JavaFile.relative(packagesDirectory, path4);
+      if (resolvedFile.exists()) {
+        return new FileBasedSource.con1(factory, resolvedFile);
+      }
+    }
+    return new FileBasedSource.con1(factory, new JavaFile.relative(_packagesDirectories[0], path4));
+  }
+}
+/**
+ * Instances of the class {@link DirectoryBasedSourceContainer} represent a source container that
+ * contains all sources within a given directory.
+ * @coverage dart.engine.source
+ */
+class DirectoryBasedSourceContainer implements SourceContainer {
+  /**
+   * Append the system file separator to the given path unless the path already ends with a
+   * separator.
+   * @param path the path to which the file separator is to be added
+   * @return a path that ends with the system file separator
+   */
+  static String appendFileSeparator(String path) {
+    if (path == null || path.length <= 0 || path.codeUnitAt(path.length - 1) == JavaFile.separatorChar) {
+      return path;
+    }
+    return "${path}${JavaFile.separator}";
+  }
+  /**
+   * The container's path (not {@code null}).
+   */
+  String _path;
+  /**
+   * Construct a container representing the specified directory and containing any sources whose{@link Source#getFullName()} starts with the directory's path. This is a convenience method,
+   * fully equivalent to {@link DirectoryBasedSourceContainer#DirectoryBasedSourceContainer(String)}.
+   * @param directory the directory (not {@code null})
+   */
+  DirectoryBasedSourceContainer.con1(JavaFile directory) {
+    _jtd_constructor_294_impl(directory);
+  }
+  _jtd_constructor_294_impl(JavaFile directory) {
+    _jtd_constructor_295_impl(directory.getPath());
+  }
+  /**
+   * Construct a container representing the specified path and containing any sources whose{@link Source#getFullName()} starts with the specified path.
+   * @param path the path (not {@code null} and not empty)
+   */
+  DirectoryBasedSourceContainer.con2(String path3) {
+    _jtd_constructor_295_impl(path3);
+  }
+  _jtd_constructor_295_impl(String path3) {
+    this._path = appendFileSeparator(path3);
+  }
+  bool contains(Source source) => source.fullName.startsWith(_path);
+  bool operator ==(Object obj) => (obj is DirectoryBasedSourceContainer) && ((obj as DirectoryBasedSourceContainer)).path == path;
+  /**
+   * Answer the receiver's path, used to determine if a source is contained in the receiver.
+   * @return the path (not {@code null}, not empty)
+   */
+  String get path => _path;
+  int get hashCode => _path.hashCode;
+}
+/**
+ * Instances of the class {@code FileUriResolver} resolve {@code file} URI's.
+ * @coverage dart.engine.source
+ */
+class FileUriResolver extends UriResolver {
+  /**
+   * The name of the {@code file} scheme.
+   */
+  static String _FILE_SCHEME = "file";
+  /**
+   * Return {@code true} if the given URI is a {@code file} URI.
+   * @param uri the URI being tested
+   * @return {@code true} if the given URI is a {@code file} URI
+   */
+  static bool isFileUri(Uri uri) => uri.scheme == _FILE_SCHEME;
+  /**
+   * Initialize a newly created resolver to resolve {@code file} URI's relative to the given root
+   * directory.
+   */
+  FileUriResolver() : super() {
+  }
+  Source resolveAbsolute(SourceFactory factory, Uri uri) {
+    if (!isFileUri(uri)) {
+      return null;
+    }
+    return new FileBasedSource.con1(factory, new JavaFile.fromUri(uri));
+  }
+}
\ No newline at end of file
diff --git a/pkg/analyzer-experimental/lib/src/generated/utilities_dart.dart b/pkg/analyzer_experimental/lib/src/generated/utilities_dart.dart
similarity index 95%
rename from pkg/analyzer-experimental/lib/src/generated/utilities_dart.dart
rename to pkg/analyzer_experimental/lib/src/generated/utilities_dart.dart
index de12488..185d559 100644
--- a/pkg/analyzer-experimental/lib/src/generated/utilities_dart.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/utilities_dart.dart
@@ -8,6 +8,7 @@
  * The enumeration {@code ParameterKind} defines the different kinds of parameters. There are two
  * basic kinds of parameters: required and optional. Optional parameters are further divided into
  * two kinds: positional optional and named optional.
+ * @coverage dart.engine.utilities
  */
 class ParameterKind {
   static final ParameterKind REQUIRED = new ParameterKind('REQUIRED', 0, false);
@@ -16,6 +17,7 @@
   static final List<ParameterKind> values = [REQUIRED, POSITIONAL, NAMED];
   final String __name;
   final int __ordinal;
+  int get ordinal => __ordinal;
   /**
    * A flag indicating whether this is an optional parameter.
    */
diff --git a/pkg/analyzer-experimental/pubspec.yaml b/pkg/analyzer_experimental/pubspec.yaml
similarity index 60%
rename from pkg/analyzer-experimental/pubspec.yaml
rename to pkg/analyzer_experimental/pubspec.yaml
index 7882f67..de2c719 100644
--- a/pkg/analyzer-experimental/pubspec.yaml
+++ b/pkg/analyzer_experimental/pubspec.yaml
@@ -1,8 +1,8 @@
-name:  analyzer-experimental
-author: "Dart Team <misc@dartlang.org>"
-homepage: http://www.dartlang.org
+name: analyzer_experimental
+version: 0.1.5
+author: Dart Team <misc@dartlang.org>
 description: Experimental static analyzer for Dart.
-
+homepage: http://www.dartlang.org
 dependencies:
+  unittest: any
   args: any
-  unittest: any
\ No newline at end of file
diff --git a/pkg/analyzer-experimental/test/generated/ast_test.dart b/pkg/analyzer_experimental/test/generated/ast_test.dart
similarity index 88%
rename from pkg/analyzer-experimental/test/generated/ast_test.dart
rename to pkg/analyzer_experimental/test/generated/ast_test.dart
index 3246180..68db34a 100644
--- a/pkg/analyzer-experimental/test/generated/ast_test.dart
+++ b/pkg/analyzer_experimental/test/generated/ast_test.dart
@@ -4,15 +4,15 @@
 library engine.ast_test;
 
 import 'dart:collection';
-import 'package:analyzer-experimental/src/generated/java_core.dart';
-import 'package:analyzer-experimental/src/generated/java_engine.dart';
-import 'package:analyzer-experimental/src/generated/java_junit.dart';
-import 'package:analyzer-experimental/src/generated/source.dart';
-import 'package:analyzer-experimental/src/generated/error.dart';
-import 'package:analyzer-experimental/src/generated/scanner.dart';
-import 'package:analyzer-experimental/src/generated/ast.dart';
-import 'package:analyzer-experimental/src/generated/utilities_dart.dart';
-import 'package:analyzer-experimental/src/generated/element.dart' show ClassElement;
+import 'package:analyzer_experimental/src/generated/java_core.dart';
+import 'package:analyzer_experimental/src/generated/java_engine.dart';
+import 'package:analyzer_experimental/src/generated/java_junit.dart';
+import 'package:analyzer_experimental/src/generated/source.dart';
+import 'package:analyzer_experimental/src/generated/error.dart';
+import 'package:analyzer_experimental/src/generated/scanner.dart';
+import 'package:analyzer_experimental/src/generated/ast.dart';
+import 'package:analyzer_experimental/src/generated/utilities_dart.dart';
+import 'package:analyzer_experimental/src/generated/element.dart' show ClassElement;
 import 'package:unittest/unittest.dart' as _ut;
 import 'parser_test.dart' show ParserTestCase;
 import 'test_support.dart';
@@ -51,10 +51,131 @@
     });
   }
 }
+class IndexExpressionTest extends EngineTestCase {
+  void test_inGetterContext_assignment_compound_left() {
+    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
+    ASTFactory.assignmentExpression(expression, TokenType.PLUS_EQ, null);
+    JUnitTestCase.assertTrue(expression.inGetterContext());
+  }
+  void test_inGetterContext_assignment_simple_left() {
+    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
+    ASTFactory.assignmentExpression(expression, TokenType.EQ, null);
+    JUnitTestCase.assertFalse(expression.inGetterContext());
+  }
+  void test_inGetterContext_nonAssignment() {
+    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
+    ASTFactory.binaryExpression(expression, TokenType.PLUS, null);
+    JUnitTestCase.assertTrue(expression.inGetterContext());
+  }
+  void test_inSetterContext_assignment_compound_left() {
+    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
+    ASTFactory.assignmentExpression(expression, TokenType.PLUS_EQ, null);
+    JUnitTestCase.assertTrue(expression.inSetterContext());
+  }
+  void test_inSetterContext_assignment_compound_right() {
+    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
+    ASTFactory.assignmentExpression(null, TokenType.PLUS_EQ, expression);
+    JUnitTestCase.assertFalse(expression.inSetterContext());
+  }
+  void test_inSetterContext_assignment_simple_left() {
+    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
+    ASTFactory.assignmentExpression(expression, TokenType.EQ, null);
+    JUnitTestCase.assertTrue(expression.inSetterContext());
+  }
+  void test_inSetterContext_assignment_simple_right() {
+    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
+    ASTFactory.assignmentExpression(null, TokenType.EQ, expression);
+    JUnitTestCase.assertFalse(expression.inSetterContext());
+  }
+  void test_inSetterContext_nonAssignment() {
+    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
+    ASTFactory.binaryExpression(expression, TokenType.PLUS, null);
+    JUnitTestCase.assertFalse(expression.inSetterContext());
+  }
+  void test_inSetterContext_postfix() {
+    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
+    ASTFactory.postfixExpression(expression, TokenType.PLUS_PLUS);
+    JUnitTestCase.assertTrue(expression.inSetterContext());
+  }
+  void test_inSetterContext_prefix_bang() {
+    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
+    ASTFactory.prefixExpression(TokenType.BANG, expression);
+    JUnitTestCase.assertFalse(expression.inSetterContext());
+  }
+  void test_inSetterContext_prefix_minusMinus() {
+    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
+    ASTFactory.prefixExpression(TokenType.MINUS_MINUS, expression);
+    JUnitTestCase.assertTrue(expression.inSetterContext());
+  }
+  void test_inSetterContext_prefix_plusPlus() {
+    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
+    ASTFactory.prefixExpression(TokenType.PLUS_PLUS, expression);
+    JUnitTestCase.assertTrue(expression.inSetterContext());
+  }
+  static dartSuite() {
+    _ut.group('IndexExpressionTest', () {
+      _ut.test('test_inGetterContext_assignment_compound_left', () {
+        final __test = new IndexExpressionTest();
+        runJUnitTest(__test, __test.test_inGetterContext_assignment_compound_left);
+      });
+      _ut.test('test_inGetterContext_assignment_simple_left', () {
+        final __test = new IndexExpressionTest();
+        runJUnitTest(__test, __test.test_inGetterContext_assignment_simple_left);
+      });
+      _ut.test('test_inGetterContext_nonAssignment', () {
+        final __test = new IndexExpressionTest();
+        runJUnitTest(__test, __test.test_inGetterContext_nonAssignment);
+      });
+      _ut.test('test_inSetterContext_assignment_compound_left', () {
+        final __test = new IndexExpressionTest();
+        runJUnitTest(__test, __test.test_inSetterContext_assignment_compound_left);
+      });
+      _ut.test('test_inSetterContext_assignment_compound_right', () {
+        final __test = new IndexExpressionTest();
+        runJUnitTest(__test, __test.test_inSetterContext_assignment_compound_right);
+      });
+      _ut.test('test_inSetterContext_assignment_simple_left', () {
+        final __test = new IndexExpressionTest();
+        runJUnitTest(__test, __test.test_inSetterContext_assignment_simple_left);
+      });
+      _ut.test('test_inSetterContext_assignment_simple_right', () {
+        final __test = new IndexExpressionTest();
+        runJUnitTest(__test, __test.test_inSetterContext_assignment_simple_right);
+      });
+      _ut.test('test_inSetterContext_nonAssignment', () {
+        final __test = new IndexExpressionTest();
+        runJUnitTest(__test, __test.test_inSetterContext_nonAssignment);
+      });
+      _ut.test('test_inSetterContext_postfix', () {
+        final __test = new IndexExpressionTest();
+        runJUnitTest(__test, __test.test_inSetterContext_postfix);
+      });
+      _ut.test('test_inSetterContext_prefix_bang', () {
+        final __test = new IndexExpressionTest();
+        runJUnitTest(__test, __test.test_inSetterContext_prefix_bang);
+      });
+      _ut.test('test_inSetterContext_prefix_minusMinus', () {
+        final __test = new IndexExpressionTest();
+        runJUnitTest(__test, __test.test_inSetterContext_prefix_minusMinus);
+      });
+      _ut.test('test_inSetterContext_prefix_plusPlus', () {
+        final __test = new IndexExpressionTest();
+        runJUnitTest(__test, __test.test_inSetterContext_prefix_plusPlus);
+      });
+    });
+  }
+}
 /**
  * The class {@code ASTFactory} defines utility methods that can be used to create AST nodes. The
  * nodes that are created are complete in the sense that all of the tokens that would have been
  * associated with the nodes by a parser are also created, but the token stream is not constructed.
+ * None of the nodes are resolved.
+ * <p>
+ * The general pattern is for the name of the factory method to be the same as the name of the class
+ * of AST node being created. There are two notable exceptions. The first is for methods creating
+ * nodes that are part of a cascade expression. These methods are all prefixed with 'cascaded'. The
+ * second is places where a shorter name seemed unambiguous and easier to read, such as using
+ * 'identifier' rather than 'prefixedIdentifier', or 'integer' rather than 'integerLiteral'.
  */
 class ASTFactory {
   static AdjacentStrings adjacentStrings(List<StringLiteral> strings) => new AdjacentStrings.full(list(strings));
@@ -97,6 +218,10 @@
   static ConstructorName constructorName(TypeName type, String name) => new ConstructorName.full(type, name == null ? null : TokenFactory.token3(TokenType.PERIOD), name == null ? null : identifier2(name));
   static ContinueStatement continueStatement() => new ContinueStatement.full(TokenFactory.token(Keyword.CONTINUE), null, TokenFactory.token3(TokenType.SEMICOLON));
   static ContinueStatement continueStatement2(String label) => new ContinueStatement.full(TokenFactory.token(Keyword.CONTINUE), identifier2(label), TokenFactory.token3(TokenType.SEMICOLON));
+  static DeclaredIdentifier declaredIdentifier(Keyword keyword, String identifier) => declaredIdentifier2(keyword, null, identifier);
+  static DeclaredIdentifier declaredIdentifier2(Keyword keyword, TypeName type, String identifier) => new DeclaredIdentifier.full(null, null, keyword == null ? null : TokenFactory.token(keyword), type, identifier2(identifier));
+  static DeclaredIdentifier declaredIdentifier3(String identifier) => declaredIdentifier2(null, null, identifier);
+  static DeclaredIdentifier declaredIdentifier4(TypeName type, String identifier) => declaredIdentifier2(null, type, identifier);
   static DoStatement doStatement(Statement body, Expression condition) => new DoStatement.full(TokenFactory.token(Keyword.DO), body, TokenFactory.token(Keyword.WHILE), TokenFactory.token3(TokenType.OPEN_PAREN), condition, TokenFactory.token3(TokenType.CLOSE_PAREN), TokenFactory.token3(TokenType.SEMICOLON));
   static DoubleLiteral doubleLiteral(double value) => new DoubleLiteral.full(TokenFactory.token2(value.toString()), value);
   static EmptyFunctionBody emptyFunctionBody() => new EmptyFunctionBody.full(TokenFactory.token3(TokenType.SEMICOLON));
@@ -109,7 +234,7 @@
   static FieldDeclaration fieldDeclaration(bool isStatic, Keyword keyword, TypeName type, List<VariableDeclaration> variables) => new FieldDeclaration.full(null, null, isStatic ? TokenFactory.token(Keyword.STATIC) : null, variableDeclarationList(keyword, type, variables), TokenFactory.token3(TokenType.SEMICOLON));
   static FieldDeclaration fieldDeclaration2(bool isStatic, Keyword keyword, List<VariableDeclaration> variables) => fieldDeclaration(isStatic, keyword, null, variables);
   static FieldFormalParameter fieldFormalParameter(Keyword keyword, TypeName type, String identifier) => new FieldFormalParameter.full(null, null, keyword == null ? null : TokenFactory.token(keyword), type, TokenFactory.token(Keyword.THIS), TokenFactory.token3(TokenType.PERIOD), identifier2(identifier));
-  static ForEachStatement forEachStatement(SimpleFormalParameter loopParameter, Expression iterator, Statement body) => new ForEachStatement.full(TokenFactory.token(Keyword.FOR), TokenFactory.token3(TokenType.OPEN_PAREN), loopParameter, TokenFactory.token(Keyword.IN), iterator, TokenFactory.token3(TokenType.CLOSE_PAREN), body);
+  static ForEachStatement forEachStatement(DeclaredIdentifier loopVariable, Expression iterator, Statement body) => new ForEachStatement.full(TokenFactory.token(Keyword.FOR), TokenFactory.token3(TokenType.OPEN_PAREN), loopVariable, TokenFactory.token(Keyword.IN), iterator, TokenFactory.token3(TokenType.CLOSE_PAREN), body);
   static FormalParameterList formalParameterList(List<FormalParameter> parameters) => new FormalParameterList.full(TokenFactory.token3(TokenType.OPEN_PAREN), list(parameters), null, null, TokenFactory.token3(TokenType.CLOSE_PAREN));
   static ForStatement forStatement(Expression initialization, Expression condition, List<Expression> updaters, Statement body) => new ForStatement.full(TokenFactory.token(Keyword.FOR), TokenFactory.token3(TokenType.OPEN_PAREN), null, initialization, TokenFactory.token3(TokenType.SEMICOLON), condition, TokenFactory.token3(TokenType.SEMICOLON), updaters, TokenFactory.token3(TokenType.CLOSE_PAREN), body);
   static ForStatement forStatement2(VariableDeclarationList variableList, Expression condition, List<Expression> updaters, Statement body) => new ForStatement.full(TokenFactory.token(Keyword.FOR), TokenFactory.token3(TokenType.OPEN_PAREN), variableList, null, TokenFactory.token3(TokenType.SEMICOLON), condition, TokenFactory.token3(TokenType.SEMICOLON), updaters, TokenFactory.token3(TokenType.CLOSE_PAREN), body);
@@ -119,7 +244,15 @@
   static FunctionExpression functionExpression2(FormalParameterList parameters, FunctionBody body) => new FunctionExpression.full(parameters, body);
   static FunctionExpressionInvocation functionExpressionInvocation(Expression function, List<Expression> arguments) => new FunctionExpressionInvocation.full(function, argumentList(arguments));
   static FunctionTypedFormalParameter functionTypedFormalParameter(TypeName returnType, String identifier, List<FormalParameter> parameters) => new FunctionTypedFormalParameter.full(null, null, returnType, identifier2(identifier), formalParameterList(parameters));
-  static PrefixedIdentifier identifier(SimpleIdentifier prefix, SimpleIdentifier identifier8) => new PrefixedIdentifier.full(prefix, TokenFactory.token3(TokenType.PERIOD), identifier8);
+  static HideCombinator hideCombinator(List<SimpleIdentifier> identifiers) => new HideCombinator.full(TokenFactory.token2("hide"), list(identifiers));
+  static HideCombinator hideCombinator2(List<String> identifiers) {
+    List<SimpleIdentifier> identifierList = new List<SimpleIdentifier>();
+    for (String identifier in identifiers) {
+      identifierList.add(identifier2(identifier));
+    }
+    return new HideCombinator.full(TokenFactory.token2("hide"), identifierList);
+  }
+  static PrefixedIdentifier identifier(SimpleIdentifier prefix, SimpleIdentifier identifier10) => new PrefixedIdentifier.full(prefix, TokenFactory.token3(TokenType.PERIOD), identifier10);
   static SimpleIdentifier identifier2(String lexeme) => new SimpleIdentifier.full(TokenFactory.token4(TokenType.IDENTIFIER, lexeme));
   static PrefixedIdentifier identifier3(String prefix, SimpleIdentifier identifier) => new PrefixedIdentifier.full(identifier2(prefix), TokenFactory.token3(TokenType.PERIOD), identifier);
   static PrefixedIdentifier identifier4(String prefix, String identifier) => new PrefixedIdentifier.full(identifier2(prefix), TokenFactory.token3(TokenType.PERIOD), identifier2(identifier));
@@ -128,17 +261,16 @@
   static ImplementsClause implementsClause(List<TypeName> types) => new ImplementsClause.full(TokenFactory.token(Keyword.IMPLEMENTS), list(types));
   static ImportDirective importDirective(List<Annotation> metadata, String uri, String prefix, List<Combinator> combinators) => new ImportDirective.full(null, metadata, TokenFactory.token(Keyword.IMPORT), string2(uri), prefix == null ? null : TokenFactory.token(Keyword.AS), prefix == null ? null : identifier2(prefix), list(combinators), TokenFactory.token3(TokenType.SEMICOLON));
   static ImportDirective importDirective2(String uri, String prefix, List<Combinator> combinators) => importDirective(new List<Annotation>(), uri, prefix, combinators);
-  static HideCombinator importHideCombinator(List<SimpleIdentifier> identifiers) => new HideCombinator.full(TokenFactory.token2("hide"), list(identifiers));
-  static ShowCombinator importShowCombinator(List<SimpleIdentifier> identifiers) => new ShowCombinator.full(TokenFactory.token2("show"), list(identifiers));
   static IndexExpression indexExpression(Expression array, Expression index) => new IndexExpression.forTarget_full(array, TokenFactory.token3(TokenType.OPEN_SQUARE_BRACKET), index, TokenFactory.token3(TokenType.CLOSE_SQUARE_BRACKET));
-  static InstanceCreationExpression instanceCreationExpression(Keyword keyword, TypeName type, List<Expression> arguments) => instanceCreationExpression2(keyword, type, null, arguments);
-  static InstanceCreationExpression instanceCreationExpression2(Keyword keyword, TypeName type, String identifier, List<Expression> arguments) => new InstanceCreationExpression.full(keyword == null ? null : TokenFactory.token(keyword), new ConstructorName.full(type, identifier == null ? null : TokenFactory.token3(TokenType.PERIOD), identifier == null ? null : identifier2(identifier)), argumentList(arguments));
+  static InstanceCreationExpression instanceCreationExpression(Keyword keyword, ConstructorName name, List<Expression> arguments) => new InstanceCreationExpression.full(keyword == null ? null : TokenFactory.token(keyword), name, argumentList(arguments));
+  static InstanceCreationExpression instanceCreationExpression2(Keyword keyword, TypeName type, List<Expression> arguments) => instanceCreationExpression3(keyword, type, null, arguments);
+  static InstanceCreationExpression instanceCreationExpression3(Keyword keyword, TypeName type, String identifier, List<Expression> arguments) => instanceCreationExpression(keyword, new ConstructorName.full(type, identifier == null ? null : TokenFactory.token3(TokenType.PERIOD), identifier == null ? null : identifier2(identifier)), arguments);
   static IntegerLiteral integer(int value) => new IntegerLiteral.full(TokenFactory.token4(TokenType.INT, value.toString()), value);
   static InterpolationExpression interpolationExpression(Expression expression) => new InterpolationExpression.full(TokenFactory.token3(TokenType.STRING_INTERPOLATION_EXPRESSION), expression, TokenFactory.token3(TokenType.CLOSE_CURLY_BRACKET));
   static InterpolationExpression interpolationExpression2(String identifier) => new InterpolationExpression.full(TokenFactory.token3(TokenType.STRING_INTERPOLATION_IDENTIFIER), identifier2(identifier), null);
   static InterpolationString interpolationString(String contents, String value) => new InterpolationString.full(TokenFactory.token2(contents), value);
   static IsExpression isExpression(Expression expression, bool negated, TypeName type) => new IsExpression.full(expression, TokenFactory.token(Keyword.IS), negated ? TokenFactory.token3(TokenType.BANG) : null, type);
-  static Label label(String label4) => new Label.full(identifier2(label4), TokenFactory.token3(TokenType.COLON));
+  static Label label(String label5) => new Label.full(identifier2(label5), TokenFactory.token3(TokenType.COLON));
   static LabeledStatement labeledStatement(List<Label> labels, Statement statement) => new LabeledStatement.full(labels, statement);
   static LibraryDirective libraryDirective(List<Annotation> metadata, LibraryIdentifier libraryName) => new LibraryDirective.full(null, metadata, TokenFactory.token(Keyword.LIBRARY), libraryName, TokenFactory.token3(TokenType.SEMICOLON));
   static LibraryDirective libraryDirective2(String libraryName) => libraryDirective(new List<Annotation>(), libraryIdentifier2([libraryName]));
@@ -162,11 +294,11 @@
   static MapLiteral mapLiteral(Keyword keyword, TypeArgumentList typeArguments, List<MapLiteralEntry> entries) => new MapLiteral.full(keyword == null ? null : TokenFactory.token(keyword), typeArguments, TokenFactory.token3(TokenType.OPEN_CURLY_BRACKET), list(entries), TokenFactory.token3(TokenType.CLOSE_CURLY_BRACKET));
   static MapLiteral mapLiteral2(List<MapLiteralEntry> entries) => mapLiteral(null, null, entries);
   static MapLiteralEntry mapLiteralEntry(String key, Expression value) => new MapLiteralEntry.full(string2(key), TokenFactory.token3(TokenType.COLON), value);
-  static MethodDeclaration methodDeclaration(Keyword modifier, TypeName returnType, Keyword property, Keyword operator, Identifier name, FormalParameterList parameters) => new MethodDeclaration.full(null, null, TokenFactory.token(Keyword.EXTERNAL), modifier == null ? null : TokenFactory.token(modifier), returnType, property == null ? null : TokenFactory.token(property), operator == null ? null : TokenFactory.token(operator), name, parameters, emptyFunctionBody());
-  static MethodDeclaration methodDeclaration2(Keyword modifier, TypeName returnType, Keyword property, Keyword operator, Identifier name, FormalParameterList parameters, FunctionBody body) => new MethodDeclaration.full(null, null, null, modifier == null ? null : TokenFactory.token(modifier), returnType, property == null ? null : TokenFactory.token(property), operator == null ? null : TokenFactory.token(operator), name, parameters, body);
+  static MethodDeclaration methodDeclaration(Keyword modifier, TypeName returnType, Keyword property, Keyword operator, SimpleIdentifier name, FormalParameterList parameters) => new MethodDeclaration.full(null, null, TokenFactory.token(Keyword.EXTERNAL), modifier == null ? null : TokenFactory.token(modifier), returnType, property == null ? null : TokenFactory.token(property), operator == null ? null : TokenFactory.token(operator), name, parameters, emptyFunctionBody());
+  static MethodDeclaration methodDeclaration2(Keyword modifier, TypeName returnType, Keyword property, Keyword operator, SimpleIdentifier name, FormalParameterList parameters, FunctionBody body) => new MethodDeclaration.full(null, null, null, modifier == null ? null : TokenFactory.token(modifier), returnType, property == null ? null : TokenFactory.token(property), operator == null ? null : TokenFactory.token(operator), name, parameters, body);
   static MethodInvocation methodInvocation(Expression target, String methodName, List<Expression> arguments) => new MethodInvocation.full(target, target == null ? null : TokenFactory.token3(TokenType.PERIOD), identifier2(methodName), argumentList(arguments));
   static MethodInvocation methodInvocation2(String methodName, List<Expression> arguments) => methodInvocation(null, methodName, arguments);
-  static NamedExpression namedExpression(String label5, Expression expression) => new NamedExpression.full(label(label5), expression);
+  static NamedExpression namedExpression(String label6, Expression expression) => new NamedExpression.full(label(label6), expression);
   static DefaultFormalParameter namedFormalParameter(NormalFormalParameter parameter, Expression expression) => new DefaultFormalParameter.full(parameter, ParameterKind.NAMED, expression == null ? null : TokenFactory.token3(TokenType.COLON), expression);
   static NullLiteral nullLiteral() => new NullLiteral.full(TokenFactory.token(Keyword.NULL));
   static ParenthesizedExpression parenthesizedExpression(Expression expression) => new ParenthesizedExpression.full(TokenFactory.token3(TokenType.OPEN_PAREN), expression, TokenFactory.token3(TokenType.CLOSE_PAREN));
@@ -177,12 +309,21 @@
   static DefaultFormalParameter positionalFormalParameter(NormalFormalParameter parameter, Expression expression) => new DefaultFormalParameter.full(parameter, ParameterKind.POSITIONAL, expression == null ? null : TokenFactory.token3(TokenType.EQ), expression);
   static PostfixExpression postfixExpression(Expression expression, TokenType operator) => new PostfixExpression.full(expression, TokenFactory.token3(operator));
   static PrefixExpression prefixExpression(TokenType operator, Expression expression) => new PrefixExpression.full(TokenFactory.token3(operator), expression);
-  static PropertyAccess propertyAccess(Expression target, String propertyName) => new PropertyAccess.full(target, TokenFactory.token3(TokenType.PERIOD), identifier2(propertyName));
+  static PropertyAccess propertyAccess(Expression target, SimpleIdentifier propertyName) => new PropertyAccess.full(target, TokenFactory.token3(TokenType.PERIOD), propertyName);
+  static PropertyAccess propertyAccess2(Expression target, String propertyName) => new PropertyAccess.full(target, TokenFactory.token3(TokenType.PERIOD), identifier2(propertyName));
   static RedirectingConstructorInvocation redirectingConstructorInvocation(List<Expression> arguments) => redirectingConstructorInvocation2(null, arguments);
   static RedirectingConstructorInvocation redirectingConstructorInvocation2(String constructorName, List<Expression> arguments) => new RedirectingConstructorInvocation.full(TokenFactory.token(Keyword.THIS), constructorName == null ? null : TokenFactory.token3(TokenType.PERIOD), constructorName == null ? null : identifier2(constructorName), argumentList(arguments));
   static ReturnStatement returnStatement() => returnStatement2(null);
   static ReturnStatement returnStatement2(Expression expression) => new ReturnStatement.full(TokenFactory.token(Keyword.RETURN), expression, TokenFactory.token3(TokenType.SEMICOLON));
   static ScriptTag scriptTag(String scriptTag5) => new ScriptTag.full(TokenFactory.token2(scriptTag5));
+  static ShowCombinator showCombinator(List<SimpleIdentifier> identifiers) => new ShowCombinator.full(TokenFactory.token2("show"), list(identifiers));
+  static ShowCombinator showCombinator2(List<String> identifiers) {
+    List<SimpleIdentifier> identifierList = new List<SimpleIdentifier>();
+    for (String identifier in identifiers) {
+      identifierList.add(identifier2(identifier));
+    }
+    return new ShowCombinator.full(TokenFactory.token2("show"), identifierList);
+  }
   static SimpleFormalParameter simpleFormalParameter(Keyword keyword, String parameterName) => simpleFormalParameter2(keyword, null, parameterName);
   static SimpleFormalParameter simpleFormalParameter2(Keyword keyword, TypeName type, String parameterName) => new SimpleFormalParameter.full(null, null, keyword == null ? null : TokenFactory.token(keyword), type, identifier2(parameterName));
   static SimpleFormalParameter simpleFormalParameter3(String parameterName) => simpleFormalParameter2(null, null, parameterName);
@@ -215,11 +356,11 @@
    * @param element the element defining the type represented by the type name
    * @return the type name that was created
    */
-  static TypeName typeName(ClassElement element42, List<TypeName> arguments) {
-    SimpleIdentifier name19 = identifier2(element42.name);
-    name19.element = element42;
-    TypeName typeName = typeName2(name19, arguments);
-    typeName.type = element42.type;
+  static TypeName typeName(ClassElement element55, List<TypeName> arguments) {
+    SimpleIdentifier name21 = identifier2(element55.name);
+    name21.element = element55;
+    TypeName typeName = typeName2(name21, arguments);
+    typeName.type = element55.type;
     return typeName;
   }
   static TypeName typeName2(Identifier name, List<TypeName> arguments) {
@@ -258,173 +399,717 @@
   }
 }
 class SimpleIdentifierTest extends ParserTestCase {
-  void test_inGetterContext_assignmentParent_notPure() {
-    SimpleIdentifier identifier = ASTFactory.identifier2("field");
-    ASTFactory.assignmentExpression(identifier, TokenType.PLUS_EQ, null);
-    JUnitTestCase.assertTrue(identifier.inGetterContext());
+  void test_inDeclarationContext_argumentDefinition() {
+    SimpleIdentifier identifier15 = ASTFactory.argumentDefinitionTest("p").identifier;
+    JUnitTestCase.assertFalse(identifier15.inDeclarationContext());
   }
-  void test_inGetterContext_assignmentParent_pure() {
-    SimpleIdentifier identifier = ASTFactory.identifier2("field");
-    ASTFactory.assignmentExpression(identifier, TokenType.EQ, null);
-    JUnitTestCase.assertFalse(identifier.inGetterContext());
+  void test_inDeclarationContext_catch_exception() {
+    SimpleIdentifier identifier = ASTFactory.catchClause("e", []).exceptionParameter;
+    JUnitTestCase.assertTrue(identifier.inDeclarationContext());
   }
-  void test_inGetterContext_notAssignmentParent() {
-    SimpleIdentifier identifier = ASTFactory.identifier2("field");
-    ASTFactory.binaryExpression(identifier, TokenType.PLUS, null);
-    JUnitTestCase.assertTrue(identifier.inGetterContext());
+  void test_inDeclarationContext_catch_stack() {
+    SimpleIdentifier identifier = ASTFactory.catchClause2("e", "s", []).stackTraceParameter;
+    JUnitTestCase.assertTrue(identifier.inDeclarationContext());
   }
-  void test_inGetterContext_qualifier() {
-    SimpleIdentifier identifier = ASTFactory.identifier2("field");
-    ASTFactory.identifier(identifier, null);
-    JUnitTestCase.assertTrue(identifier.inGetterContext());
+  void test_inDeclarationContext_classDeclaration() {
+    SimpleIdentifier identifier = ASTFactory.classDeclaration(null, "C", null, null, null, null, []).name;
+    JUnitTestCase.assertTrue(identifier.inDeclarationContext());
   }
-  void test_inGetterContext_whenQualified_false() {
-    SimpleIdentifier identifier = ASTFactory.identifier2("field");
-    PrefixedIdentifier prefixedIdentifier = ASTFactory.identifier3("myPrefix", identifier);
-    ASTFactory.assignmentExpression(prefixedIdentifier, TokenType.PLUS_EQ, null);
-    JUnitTestCase.assertTrue(identifier.inGetterContext());
+  void test_inDeclarationContext_classTypeAlias() {
+    SimpleIdentifier identifier = ASTFactory.classTypeAlias("C", null, null, null, null, null).name;
+    JUnitTestCase.assertTrue(identifier.inDeclarationContext());
   }
-  void test_inGetterContext_whenQualified_true() {
-    SimpleIdentifier identifier = ASTFactory.identifier2("field");
-    PrefixedIdentifier prefixedIdentifier = ASTFactory.identifier3("myPrefix", identifier);
-    ASTFactory.assignmentExpression(prefixedIdentifier, TokenType.EQ, null);
-    JUnitTestCase.assertFalse(identifier.inGetterContext());
+  void test_inDeclarationContext_constructorDeclaration() {
+    SimpleIdentifier identifier = ASTFactory.constructorDeclaration(ASTFactory.identifier2("C"), "c", null, null).name;
+    JUnitTestCase.assertTrue(identifier.inDeclarationContext());
   }
-  void test_inSetterContext_assignmentParent_leftEq() {
-    SimpleIdentifier identifier = ASTFactory.identifier2("field");
-    ASTFactory.assignmentExpression(identifier, TokenType.EQ, null);
-    JUnitTestCase.assertTrue(identifier.inSetterContext());
+  void test_inDeclarationContext_functionDeclaration() {
+    SimpleIdentifier identifier = ASTFactory.functionDeclaration(null, null, "f", null).name;
+    JUnitTestCase.assertTrue(identifier.inDeclarationContext());
   }
-  void test_inSetterContext_assignmentParent_leftPlusEq() {
-    SimpleIdentifier identifier = ASTFactory.identifier2("field");
-    ASTFactory.assignmentExpression(identifier, TokenType.PLUS_EQ, null);
-    JUnitTestCase.assertTrue(identifier.inSetterContext());
+  void test_inDeclarationContext_functionTypeAlias() {
+    SimpleIdentifier identifier = ASTFactory.typeAlias(null, "F", null, null).name;
+    JUnitTestCase.assertTrue(identifier.inDeclarationContext());
   }
-  void test_inSetterContext_assignmentParent_rightEq() {
-    SimpleIdentifier identifier = ASTFactory.identifier2("field");
-    ASTFactory.assignmentExpression(null, TokenType.EQ, identifier);
-    JUnitTestCase.assertFalse(identifier.inSetterContext());
+  void test_inDeclarationContext_label_false() {
+    SimpleIdentifier identifier = ASTFactory.namedExpression("l", ASTFactory.integer(0)).name.label;
+    JUnitTestCase.assertFalse(identifier.inDeclarationContext());
   }
-  void test_inSetterContext_assignmentParent_rightPlusEq() {
-    SimpleIdentifier identifier = ASTFactory.identifier2("field");
-    ASTFactory.assignmentExpression(null, TokenType.PLUS_EQ, identifier);
-    JUnitTestCase.assertFalse(identifier.inSetterContext());
+  void test_inDeclarationContext_label_true() {
+    Label label2 = ASTFactory.label("l");
+    SimpleIdentifier identifier = label2.label;
+    ASTFactory.labeledStatement(ASTFactory.list([label2]), ASTFactory.emptyStatement());
+    JUnitTestCase.assertTrue(identifier.inDeclarationContext());
   }
-  void test_inSetterContext_notInterestingParent() {
-    SimpleIdentifier identifier = ASTFactory.identifier2("field");
-    ASTFactory.binaryExpression(identifier, null, null);
-    JUnitTestCase.assertFalse(identifier.inSetterContext());
+  void test_inDeclarationContext_methodDeclaration() {
+    SimpleIdentifier identifier = ASTFactory.identifier2("m");
+    ASTFactory.methodDeclaration2(null, null, null, null, identifier, null, null);
+    JUnitTestCase.assertTrue(identifier.inDeclarationContext());
   }
-  void test_inSetterContext_postfixParent() {
-    SimpleIdentifier identifier = ASTFactory.identifier2("field");
-    ASTFactory.postfixExpression(identifier, null);
-    JUnitTestCase.assertTrue(identifier.inSetterContext());
+  void test_inDeclarationContext_normalFormalParameter() {
+    SimpleIdentifier identifier16 = ASTFactory.simpleFormalParameter3("p").identifier;
+    JUnitTestCase.assertTrue(identifier16.inDeclarationContext());
   }
-  void test_inSetterContext_prefixParent_bang() {
-    SimpleIdentifier identifier = ASTFactory.identifier2("field");
-    ASTFactory.prefixExpression(TokenType.BANG, identifier);
-    JUnitTestCase.assertFalse(identifier.inSetterContext());
+  void test_inDeclarationContext_typeParameter_bound() {
+    TypeName bound = ASTFactory.typeName3("A", []);
+    SimpleIdentifier identifier = bound.name as SimpleIdentifier;
+    ASTFactory.typeParameter2("E", bound);
+    JUnitTestCase.assertFalse(identifier.inDeclarationContext());
   }
-  void test_inSetterContext_prefixParent_minusMinus() {
-    SimpleIdentifier identifier = ASTFactory.identifier2("field");
-    ASTFactory.prefixExpression(TokenType.MINUS_MINUS, identifier);
-    JUnitTestCase.assertTrue(identifier.inSetterContext());
+  void test_inDeclarationContext_typeParameter_name() {
+    SimpleIdentifier identifier = ASTFactory.typeParameter("E").name;
+    JUnitTestCase.assertTrue(identifier.inDeclarationContext());
   }
-  void test_inSetterContext_prefixParent_plusPlus() {
-    SimpleIdentifier identifier = ASTFactory.identifier2("field");
-    ASTFactory.prefixExpression(TokenType.PLUS_PLUS, identifier);
-    JUnitTestCase.assertTrue(identifier.inSetterContext());
+  void test_inDeclarationContext_variableDeclaration() {
+    SimpleIdentifier identifier = ASTFactory.variableDeclaration("v").name;
+    JUnitTestCase.assertTrue(identifier.inDeclarationContext());
   }
-  void test_inSetterContext_qualifier() {
-    SimpleIdentifier identifier = ASTFactory.identifier2("field");
-    ASTFactory.identifier(identifier, null);
-    JUnitTestCase.assertFalse(identifier.inSetterContext());
+  void test_inGetterContext() {
+    for (WrapperKind wrapper in WrapperKind.values) {
+      for (AssignmentKind assignment in AssignmentKind.values) {
+        SimpleIdentifier identifier = createIdentifier(wrapper, assignment);
+        if (identical(assignment, AssignmentKind.SIMPLE_LEFT) && wrapper != WrapperKind.PREFIXED_LEFT && wrapper != WrapperKind.PROPERTY_LEFT) {
+          if (identifier.inGetterContext()) {
+            JUnitTestCase.fail("Expected ${topMostNode(identifier).toSource()} to be false");
+          }
+        } else {
+          if (!identifier.inGetterContext()) {
+            JUnitTestCase.fail("Expected ${topMostNode(identifier).toSource()} to be true");
+          }
+        }
+      }
+    }
   }
-  void test_inSetterContext_whenQualified_prefixParent_bang() {
-    SimpleIdentifier identifier = ASTFactory.identifier2("field");
-    PrefixedIdentifier prefixedIdentifier = ASTFactory.identifier3("myPrefix", identifier);
-    ASTFactory.prefixExpression(TokenType.BANG, prefixedIdentifier);
-    JUnitTestCase.assertFalse(identifier.inSetterContext());
+  void test_inSetterContext() {
+    for (WrapperKind wrapper in WrapperKind.values) {
+      for (AssignmentKind assignment in AssignmentKind.values) {
+        SimpleIdentifier identifier = createIdentifier(wrapper, assignment);
+        if (identical(wrapper, WrapperKind.PREFIXED_LEFT) || identical(wrapper, WrapperKind.PROPERTY_LEFT) || identical(assignment, AssignmentKind.BINARY) || identical(assignment, AssignmentKind.COMPOUND_RIGHT) || identical(assignment, AssignmentKind.PREFIX_NOT) || identical(assignment, AssignmentKind.SIMPLE_RIGHT) || identical(assignment, AssignmentKind.NONE)) {
+          if (identifier.inSetterContext()) {
+            JUnitTestCase.fail("Expected ${topMostNode(identifier).toSource()} to be false");
+          }
+        } else {
+          if (!identifier.inSetterContext()) {
+            JUnitTestCase.fail("Expected ${topMostNode(identifier).toSource()} to be true");
+          }
+        }
+      }
+    }
   }
-  void test_inSetterContext_whenQualified_prefixParent_plusPlus() {
-    SimpleIdentifier identifier = ASTFactory.identifier2("field");
-    PrefixedIdentifier prefixedIdentifier = ASTFactory.identifier3("myPrefix", identifier);
-    ASTFactory.prefixExpression(TokenType.PLUS_PLUS, prefixedIdentifier);
-    JUnitTestCase.assertTrue(identifier.inSetterContext());
+  SimpleIdentifier createIdentifier(WrapperKind wrapper, AssignmentKind assignment) {
+    SimpleIdentifier identifier = ASTFactory.identifier2("a");
+    Expression expression = identifier;
+    while (true) {
+      if (wrapper == WrapperKind.PREFIXED_LEFT) {
+        expression = ASTFactory.identifier(identifier, ASTFactory.identifier2("_"));
+      } else if (wrapper == WrapperKind.PREFIXED_RIGHT) {
+        expression = ASTFactory.identifier(ASTFactory.identifier2("_"), identifier);
+      } else if (wrapper == WrapperKind.PROPERTY_LEFT) {
+        expression = ASTFactory.propertyAccess2(expression, "_");
+      } else if (wrapper == WrapperKind.PROPERTY_RIGHT) {
+        expression = ASTFactory.propertyAccess(ASTFactory.identifier2("_"), identifier);
+      }
+      break;
+    }
+    while (true) {
+      if (assignment == AssignmentKind.BINARY) {
+        ASTFactory.binaryExpression(expression, TokenType.PLUS, ASTFactory.identifier2("_"));
+      } else if (assignment == AssignmentKind.COMPOUND_LEFT) {
+        ASTFactory.assignmentExpression(expression, TokenType.PLUS_EQ, ASTFactory.identifier2("_"));
+      } else if (assignment == AssignmentKind.COMPOUND_RIGHT) {
+        ASTFactory.assignmentExpression(ASTFactory.identifier2("_"), TokenType.PLUS_EQ, expression);
+      } else if (assignment == AssignmentKind.POSTFIX_INC) {
+        ASTFactory.postfixExpression(expression, TokenType.PLUS_PLUS);
+      } else if (assignment == AssignmentKind.PREFIX_DEC) {
+        ASTFactory.prefixExpression(TokenType.MINUS_MINUS, expression);
+      } else if (assignment == AssignmentKind.PREFIX_INC) {
+        ASTFactory.prefixExpression(TokenType.PLUS_PLUS, expression);
+      } else if (assignment == AssignmentKind.PREFIX_NOT) {
+        ASTFactory.prefixExpression(TokenType.BANG, expression);
+      } else if (assignment == AssignmentKind.SIMPLE_LEFT) {
+        ASTFactory.assignmentExpression(expression, TokenType.EQ, ASTFactory.identifier2("_"));
+      } else if (assignment == AssignmentKind.SIMPLE_RIGHT) {
+        ASTFactory.assignmentExpression(ASTFactory.identifier2("_"), TokenType.EQ, expression);
+      }
+      break;
+    }
+    return identifier;
+  }
+  /**
+   * Return the top-most node in the AST structure containing the given identifier.
+   * @param identifier the identifier in the AST structure being traversed
+   * @return the root of the AST structure containing the identifier
+   */
+  ASTNode topMostNode(SimpleIdentifier identifier) {
+    ASTNode child = identifier;
+    ASTNode parent18 = identifier.parent;
+    while (parent18 != null) {
+      child = parent18;
+      parent18 = parent18.parent;
+    }
+    return child;
   }
   static dartSuite() {
     _ut.group('SimpleIdentifierTest', () {
-      _ut.test('test_inGetterContext_assignmentParent_notPure', () {
+      _ut.test('test_inDeclarationContext_argumentDefinition', () {
         final __test = new SimpleIdentifierTest();
-        runJUnitTest(__test, __test.test_inGetterContext_assignmentParent_notPure);
+        runJUnitTest(__test, __test.test_inDeclarationContext_argumentDefinition);
       });
-      _ut.test('test_inGetterContext_assignmentParent_pure', () {
+      _ut.test('test_inDeclarationContext_catch_exception', () {
         final __test = new SimpleIdentifierTest();
-        runJUnitTest(__test, __test.test_inGetterContext_assignmentParent_pure);
+        runJUnitTest(__test, __test.test_inDeclarationContext_catch_exception);
       });
-      _ut.test('test_inGetterContext_notAssignmentParent', () {
+      _ut.test('test_inDeclarationContext_catch_stack', () {
         final __test = new SimpleIdentifierTest();
-        runJUnitTest(__test, __test.test_inGetterContext_notAssignmentParent);
+        runJUnitTest(__test, __test.test_inDeclarationContext_catch_stack);
       });
-      _ut.test('test_inGetterContext_qualifier', () {
+      _ut.test('test_inDeclarationContext_classDeclaration', () {
         final __test = new SimpleIdentifierTest();
-        runJUnitTest(__test, __test.test_inGetterContext_qualifier);
+        runJUnitTest(__test, __test.test_inDeclarationContext_classDeclaration);
       });
-      _ut.test('test_inGetterContext_whenQualified_false', () {
+      _ut.test('test_inDeclarationContext_classTypeAlias', () {
         final __test = new SimpleIdentifierTest();
-        runJUnitTest(__test, __test.test_inGetterContext_whenQualified_false);
+        runJUnitTest(__test, __test.test_inDeclarationContext_classTypeAlias);
       });
-      _ut.test('test_inGetterContext_whenQualified_true', () {
+      _ut.test('test_inDeclarationContext_constructorDeclaration', () {
         final __test = new SimpleIdentifierTest();
-        runJUnitTest(__test, __test.test_inGetterContext_whenQualified_true);
+        runJUnitTest(__test, __test.test_inDeclarationContext_constructorDeclaration);
       });
-      _ut.test('test_inSetterContext_assignmentParent_leftEq', () {
+      _ut.test('test_inDeclarationContext_functionDeclaration', () {
         final __test = new SimpleIdentifierTest();
-        runJUnitTest(__test, __test.test_inSetterContext_assignmentParent_leftEq);
+        runJUnitTest(__test, __test.test_inDeclarationContext_functionDeclaration);
       });
-      _ut.test('test_inSetterContext_assignmentParent_leftPlusEq', () {
+      _ut.test('test_inDeclarationContext_functionTypeAlias', () {
         final __test = new SimpleIdentifierTest();
-        runJUnitTest(__test, __test.test_inSetterContext_assignmentParent_leftPlusEq);
+        runJUnitTest(__test, __test.test_inDeclarationContext_functionTypeAlias);
       });
-      _ut.test('test_inSetterContext_assignmentParent_rightEq', () {
+      _ut.test('test_inDeclarationContext_label_false', () {
         final __test = new SimpleIdentifierTest();
-        runJUnitTest(__test, __test.test_inSetterContext_assignmentParent_rightEq);
+        runJUnitTest(__test, __test.test_inDeclarationContext_label_false);
       });
-      _ut.test('test_inSetterContext_assignmentParent_rightPlusEq', () {
+      _ut.test('test_inDeclarationContext_label_true', () {
         final __test = new SimpleIdentifierTest();
-        runJUnitTest(__test, __test.test_inSetterContext_assignmentParent_rightPlusEq);
+        runJUnitTest(__test, __test.test_inDeclarationContext_label_true);
       });
-      _ut.test('test_inSetterContext_notInterestingParent', () {
+      _ut.test('test_inDeclarationContext_methodDeclaration', () {
         final __test = new SimpleIdentifierTest();
-        runJUnitTest(__test, __test.test_inSetterContext_notInterestingParent);
+        runJUnitTest(__test, __test.test_inDeclarationContext_methodDeclaration);
       });
-      _ut.test('test_inSetterContext_postfixParent', () {
+      _ut.test('test_inDeclarationContext_normalFormalParameter', () {
         final __test = new SimpleIdentifierTest();
-        runJUnitTest(__test, __test.test_inSetterContext_postfixParent);
+        runJUnitTest(__test, __test.test_inDeclarationContext_normalFormalParameter);
       });
-      _ut.test('test_inSetterContext_prefixParent_bang', () {
+      _ut.test('test_inDeclarationContext_typeParameter_bound', () {
         final __test = new SimpleIdentifierTest();
-        runJUnitTest(__test, __test.test_inSetterContext_prefixParent_bang);
+        runJUnitTest(__test, __test.test_inDeclarationContext_typeParameter_bound);
       });
-      _ut.test('test_inSetterContext_prefixParent_minusMinus', () {
+      _ut.test('test_inDeclarationContext_typeParameter_name', () {
         final __test = new SimpleIdentifierTest();
-        runJUnitTest(__test, __test.test_inSetterContext_prefixParent_minusMinus);
+        runJUnitTest(__test, __test.test_inDeclarationContext_typeParameter_name);
       });
-      _ut.test('test_inSetterContext_prefixParent_plusPlus', () {
+      _ut.test('test_inDeclarationContext_variableDeclaration', () {
         final __test = new SimpleIdentifierTest();
-        runJUnitTest(__test, __test.test_inSetterContext_prefixParent_plusPlus);
+        runJUnitTest(__test, __test.test_inDeclarationContext_variableDeclaration);
       });
-      _ut.test('test_inSetterContext_qualifier', () {
+      _ut.test('test_inGetterContext', () {
         final __test = new SimpleIdentifierTest();
-        runJUnitTest(__test, __test.test_inSetterContext_qualifier);
+        runJUnitTest(__test, __test.test_inGetterContext);
       });
-      _ut.test('test_inSetterContext_whenQualified_prefixParent_bang', () {
+      _ut.test('test_inSetterContext', () {
         final __test = new SimpleIdentifierTest();
-        runJUnitTest(__test, __test.test_inSetterContext_whenQualified_prefixParent_bang);
+        runJUnitTest(__test, __test.test_inSetterContext);
       });
-      _ut.test('test_inSetterContext_whenQualified_prefixParent_plusPlus', () {
-        final __test = new SimpleIdentifierTest();
-        runJUnitTest(__test, __test.test_inSetterContext_whenQualified_prefixParent_plusPlus);
+    });
+  }
+}
+class AssignmentKind {
+  static final AssignmentKind BINARY = new AssignmentKind('BINARY', 0);
+  static final AssignmentKind COMPOUND_LEFT = new AssignmentKind('COMPOUND_LEFT', 1);
+  static final AssignmentKind COMPOUND_RIGHT = new AssignmentKind('COMPOUND_RIGHT', 2);
+  static final AssignmentKind POSTFIX_INC = new AssignmentKind('POSTFIX_INC', 3);
+  static final AssignmentKind PREFIX_DEC = new AssignmentKind('PREFIX_DEC', 4);
+  static final AssignmentKind PREFIX_INC = new AssignmentKind('PREFIX_INC', 5);
+  static final AssignmentKind PREFIX_NOT = new AssignmentKind('PREFIX_NOT', 6);
+  static final AssignmentKind SIMPLE_LEFT = new AssignmentKind('SIMPLE_LEFT', 7);
+  static final AssignmentKind SIMPLE_RIGHT = new AssignmentKind('SIMPLE_RIGHT', 8);
+  static final AssignmentKind NONE = new AssignmentKind('NONE', 9);
+  static final List<AssignmentKind> values = [BINARY, COMPOUND_LEFT, COMPOUND_RIGHT, POSTFIX_INC, PREFIX_DEC, PREFIX_INC, PREFIX_NOT, SIMPLE_LEFT, SIMPLE_RIGHT, NONE];
+  final String __name;
+  final int __ordinal;
+  int get ordinal => __ordinal;
+  AssignmentKind(this.__name, this.__ordinal) {
+  }
+  String toString() => __name;
+}
+class WrapperKind {
+  static final WrapperKind PREFIXED_LEFT = new WrapperKind('PREFIXED_LEFT', 0);
+  static final WrapperKind PREFIXED_RIGHT = new WrapperKind('PREFIXED_RIGHT', 1);
+  static final WrapperKind PROPERTY_LEFT = new WrapperKind('PROPERTY_LEFT', 2);
+  static final WrapperKind PROPERTY_RIGHT = new WrapperKind('PROPERTY_RIGHT', 3);
+  static final WrapperKind NONE = new WrapperKind('NONE', 4);
+  static final List<WrapperKind> values = [PREFIXED_LEFT, PREFIXED_RIGHT, PROPERTY_LEFT, PROPERTY_RIGHT, NONE];
+  final String __name;
+  final int __ordinal;
+  int get ordinal => __ordinal;
+  WrapperKind(this.__name, this.__ordinal) {
+  }
+  String toString() => __name;
+}
+class ConstantEvaluatorTest extends ParserTestCase {
+  void fail_constructor() {
+    Object value = getConstantValue("?");
+    JUnitTestCase.assertEquals(null, value);
+  }
+  void fail_identifier_class() {
+    Object value = getConstantValue("?");
+    JUnitTestCase.assertEquals(null, value);
+  }
+  void fail_identifier_function() {
+    Object value = getConstantValue("?");
+    JUnitTestCase.assertEquals(null, value);
+  }
+  void fail_identifier_static() {
+    Object value = getConstantValue("?");
+    JUnitTestCase.assertEquals(null, value);
+  }
+  void fail_identifier_staticMethod() {
+    Object value = getConstantValue("?");
+    JUnitTestCase.assertEquals(null, value);
+  }
+  void fail_identifier_topLevel() {
+    Object value = getConstantValue("?");
+    JUnitTestCase.assertEquals(null, value);
+  }
+  void fail_identifier_typeVariable() {
+    Object value = getConstantValue("?");
+    JUnitTestCase.assertEquals(null, value);
+  }
+  void test_binary_bitAnd() {
+    Object value = getConstantValue("74 & 42");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(74 & 42, ((value as int)));
+  }
+  void test_binary_bitOr() {
+    Object value = getConstantValue("74 | 42");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(74 | 42, ((value as int)));
+  }
+  void test_binary_bitXor() {
+    Object value = getConstantValue("74 ^ 42");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(74 ^ 42, ((value as int)));
+  }
+  void test_binary_divide_double() {
+    Object value = getConstantValue("3.2 / 2.3");
+    EngineTestCase.assertInstanceOf(double, value);
+    JUnitTestCase.assertEquals(3.2 / 2.3, ((value as double)));
+  }
+  void test_binary_divide_integer() {
+    Object value = getConstantValue("3 / 2");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(1, ((value as int)));
+  }
+  void test_binary_equal_boolean() {
+    Object value = getConstantValue("true == false");
+    JUnitTestCase.assertEquals(false, value);
+  }
+  void test_binary_equal_integer() {
+    Object value = getConstantValue("2 == 3");
+    JUnitTestCase.assertEquals(false, value);
+  }
+  void test_binary_equal_invalidLeft() {
+    Object value = getConstantValue("a == 3");
+    JUnitTestCase.assertEquals(ConstantEvaluator.NOT_A_CONSTANT, value);
+  }
+  void test_binary_equal_invalidRight() {
+    Object value = getConstantValue("2 == a");
+    JUnitTestCase.assertEquals(ConstantEvaluator.NOT_A_CONSTANT, value);
+  }
+  void test_binary_equal_string() {
+    Object value = getConstantValue("'a' == 'b'");
+    JUnitTestCase.assertEquals(false, value);
+  }
+  void test_binary_greaterThan() {
+    Object value = getConstantValue("2 > 3");
+    JUnitTestCase.assertEquals(false, value);
+  }
+  void test_binary_greaterThanOrEqual() {
+    Object value = getConstantValue("2 >= 3");
+    JUnitTestCase.assertEquals(false, value);
+  }
+  void test_binary_leftShift() {
+    Object value = getConstantValue("16 << 2");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(64, ((value as int)));
+  }
+  void test_binary_lessThan() {
+    Object value = getConstantValue("2 < 3");
+    JUnitTestCase.assertEquals(true, value);
+  }
+  void test_binary_lessThanOrEqual() {
+    Object value = getConstantValue("2 <= 3");
+    JUnitTestCase.assertEquals(true, value);
+  }
+  void test_binary_logicalAnd() {
+    Object value = getConstantValue("true && false");
+    JUnitTestCase.assertEquals(false, value);
+  }
+  void test_binary_logicalOr() {
+    Object value = getConstantValue("true || false");
+    JUnitTestCase.assertEquals(true, value);
+  }
+  void test_binary_minus_double() {
+    Object value = getConstantValue("3.2 - 2.3");
+    EngineTestCase.assertInstanceOf(double, value);
+    JUnitTestCase.assertEquals(3.2 - 2.3, ((value as double)));
+  }
+  void test_binary_minus_integer() {
+    Object value = getConstantValue("3 - 2");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(1, ((value as int)));
+  }
+  void test_binary_notEqual_boolean() {
+    Object value = getConstantValue("true != false");
+    JUnitTestCase.assertEquals(true, value);
+  }
+  void test_binary_notEqual_integer() {
+    Object value = getConstantValue("2 != 3");
+    JUnitTestCase.assertEquals(true, value);
+  }
+  void test_binary_notEqual_invalidLeft() {
+    Object value = getConstantValue("a != 3");
+    JUnitTestCase.assertEquals(ConstantEvaluator.NOT_A_CONSTANT, value);
+  }
+  void test_binary_notEqual_invalidRight() {
+    Object value = getConstantValue("2 != a");
+    JUnitTestCase.assertEquals(ConstantEvaluator.NOT_A_CONSTANT, value);
+  }
+  void test_binary_notEqual_string() {
+    Object value = getConstantValue("'a' != 'b'");
+    JUnitTestCase.assertEquals(true, value);
+  }
+  void test_binary_plus_double() {
+    Object value = getConstantValue("2.3 + 3.2");
+    EngineTestCase.assertInstanceOf(double, value);
+    JUnitTestCase.assertEquals(2.3 + 3.2, ((value as double)));
+  }
+  void test_binary_plus_integer() {
+    Object value = getConstantValue("2 + 3");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(5, ((value as int)));
+  }
+  void test_binary_remainder_double() {
+    Object value = getConstantValue("3.2 % 2.3");
+    EngineTestCase.assertInstanceOf(double, value);
+    JUnitTestCase.assertEquals(3.2 % 2.3, ((value as double)));
+  }
+  void test_binary_remainder_integer() {
+    Object value = getConstantValue("8 % 3");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(2, ((value as int)));
+  }
+  void test_binary_rightShift() {
+    Object value = getConstantValue("64 >> 2");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(16, ((value as int)));
+  }
+  void test_binary_times_double() {
+    Object value = getConstantValue("2.3 * 3.2");
+    EngineTestCase.assertInstanceOf(double, value);
+    JUnitTestCase.assertEquals(2.3 * 3.2, ((value as double)));
+  }
+  void test_binary_times_integer() {
+    Object value = getConstantValue("2 * 3");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(6, ((value as int)));
+  }
+  void test_binary_truncatingDivide_double() {
+    Object value = getConstantValue("3.2 ~/ 2.3");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(1, ((value as int)));
+  }
+  void test_binary_truncatingDivide_integer() {
+    Object value = getConstantValue("10 ~/ 3");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(3, ((value as int)));
+  }
+  void test_literal_boolean_false() {
+    Object value = getConstantValue("false");
+    JUnitTestCase.assertEquals(false, value);
+  }
+  void test_literal_boolean_true() {
+    Object value = getConstantValue("true");
+    JUnitTestCase.assertEquals(true, value);
+  }
+  void test_literal_list() {
+    Object value = getConstantValue("['a', 'b', 'c']");
+    EngineTestCase.assertInstanceOf(List, value);
+    List<Object> list = value as List<Object>;
+    JUnitTestCase.assertEquals(3, list.length);
+    JUnitTestCase.assertEquals("a", list[0]);
+    JUnitTestCase.assertEquals("b", list[1]);
+    JUnitTestCase.assertEquals("c", list[2]);
+  }
+  void test_literal_map() {
+    Object value = getConstantValue("{'a' : 'm', 'b' : 'n', 'c' : 'o'}");
+    EngineTestCase.assertInstanceOf(Map, value);
+    Map<Object, Object> map = value as Map<Object, Object>;
+    JUnitTestCase.assertEquals(3, map.length);
+    JUnitTestCase.assertEquals("m", map["a"]);
+    JUnitTestCase.assertEquals("n", map["b"]);
+    JUnitTestCase.assertEquals("o", map["c"]);
+  }
+  void test_literal_null() {
+    Object value = getConstantValue("null");
+    JUnitTestCase.assertEquals(null, value);
+  }
+  void test_literal_number_double() {
+    Object value = getConstantValue("3.45");
+    EngineTestCase.assertInstanceOf(double, value);
+    JUnitTestCase.assertEquals(3.45, ((value as double)));
+  }
+  void test_literal_number_integer() {
+    Object value = getConstantValue("42");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(42, ((value as int)));
+  }
+  void test_literal_string_adjacent() {
+    Object value = getConstantValue("'abc' 'def'");
+    JUnitTestCase.assertEquals("abcdef", value);
+  }
+  void test_literal_string_interpolation_invalid() {
+    Object value = getConstantValue("'a\${f()}c'");
+    JUnitTestCase.assertEquals(ConstantEvaluator.NOT_A_CONSTANT, value);
+  }
+  void test_literal_string_interpolation_valid() {
+    Object value = getConstantValue("'a\${3}c'");
+    JUnitTestCase.assertEquals("a3c", value);
+  }
+  void test_literal_string_simple() {
+    Object value = getConstantValue("'abc'");
+    JUnitTestCase.assertEquals("abc", value);
+  }
+  void test_parenthesizedExpression() {
+    Object value = getConstantValue("('a')");
+    JUnitTestCase.assertEquals("a", value);
+  }
+  void test_unary_bitNot() {
+    Object value = getConstantValue("~42");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(~42, ((value as int)));
+  }
+  void test_unary_logicalNot() {
+    Object value = getConstantValue("!true");
+    JUnitTestCase.assertEquals(false, value);
+  }
+  void test_unary_negated_double() {
+    Object value = getConstantValue("-42.3");
+    EngineTestCase.assertInstanceOf(double, value);
+    JUnitTestCase.assertEquals(-42.3, ((value as double)));
+  }
+  void test_unary_negated_integer() {
+    Object value = getConstantValue("-42");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(-42, ((value as int)));
+  }
+  Object getConstantValue(String source) => ParserTestCase.parseExpression(source, []).accept(new ConstantEvaluator(null));
+  static dartSuite() {
+    _ut.group('ConstantEvaluatorTest', () {
+      _ut.test('test_binary_bitAnd', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_bitAnd);
+      });
+      _ut.test('test_binary_bitOr', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_bitOr);
+      });
+      _ut.test('test_binary_bitXor', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_bitXor);
+      });
+      _ut.test('test_binary_divide_double', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_divide_double);
+      });
+      _ut.test('test_binary_divide_integer', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_divide_integer);
+      });
+      _ut.test('test_binary_equal_boolean', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_equal_boolean);
+      });
+      _ut.test('test_binary_equal_integer', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_equal_integer);
+      });
+      _ut.test('test_binary_equal_invalidLeft', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_equal_invalidLeft);
+      });
+      _ut.test('test_binary_equal_invalidRight', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_equal_invalidRight);
+      });
+      _ut.test('test_binary_equal_string', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_equal_string);
+      });
+      _ut.test('test_binary_greaterThan', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_greaterThan);
+      });
+      _ut.test('test_binary_greaterThanOrEqual', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_greaterThanOrEqual);
+      });
+      _ut.test('test_binary_leftShift', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_leftShift);
+      });
+      _ut.test('test_binary_lessThan', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_lessThan);
+      });
+      _ut.test('test_binary_lessThanOrEqual', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_lessThanOrEqual);
+      });
+      _ut.test('test_binary_logicalAnd', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_logicalAnd);
+      });
+      _ut.test('test_binary_logicalOr', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_logicalOr);
+      });
+      _ut.test('test_binary_minus_double', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_minus_double);
+      });
+      _ut.test('test_binary_minus_integer', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_minus_integer);
+      });
+      _ut.test('test_binary_notEqual_boolean', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_notEqual_boolean);
+      });
+      _ut.test('test_binary_notEqual_integer', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_notEqual_integer);
+      });
+      _ut.test('test_binary_notEqual_invalidLeft', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_notEqual_invalidLeft);
+      });
+      _ut.test('test_binary_notEqual_invalidRight', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_notEqual_invalidRight);
+      });
+      _ut.test('test_binary_notEqual_string', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_notEqual_string);
+      });
+      _ut.test('test_binary_plus_double', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_plus_double);
+      });
+      _ut.test('test_binary_plus_integer', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_plus_integer);
+      });
+      _ut.test('test_binary_remainder_double', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_remainder_double);
+      });
+      _ut.test('test_binary_remainder_integer', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_remainder_integer);
+      });
+      _ut.test('test_binary_rightShift', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_rightShift);
+      });
+      _ut.test('test_binary_times_double', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_times_double);
+      });
+      _ut.test('test_binary_times_integer', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_times_integer);
+      });
+      _ut.test('test_binary_truncatingDivide_double', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_truncatingDivide_double);
+      });
+      _ut.test('test_binary_truncatingDivide_integer', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_truncatingDivide_integer);
+      });
+      _ut.test('test_literal_boolean_false', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_literal_boolean_false);
+      });
+      _ut.test('test_literal_boolean_true', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_literal_boolean_true);
+      });
+      _ut.test('test_literal_list', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_literal_list);
+      });
+      _ut.test('test_literal_map', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_literal_map);
+      });
+      _ut.test('test_literal_null', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_literal_null);
+      });
+      _ut.test('test_literal_number_double', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_literal_number_double);
+      });
+      _ut.test('test_literal_number_integer', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_literal_number_integer);
+      });
+      _ut.test('test_literal_string_adjacent', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_literal_string_adjacent);
+      });
+      _ut.test('test_literal_string_interpolation_invalid', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_literal_string_interpolation_invalid);
+      });
+      _ut.test('test_literal_string_interpolation_valid', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_literal_string_interpolation_valid);
+      });
+      _ut.test('test_literal_string_simple', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_literal_string_simple);
+      });
+      _ut.test('test_parenthesizedExpression', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_parenthesizedExpression);
+      });
+      _ut.test('test_unary_bitNot', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_unary_bitNot);
+      });
+      _ut.test('test_unary_logicalNot', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_unary_logicalNot);
+      });
+      _ut.test('test_unary_negated_double', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_unary_negated_double);
+      });
+      _ut.test('test_unary_negated_integer', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_unary_negated_integer);
       });
     });
   }
@@ -668,10 +1353,10 @@
     assertSource(";", ASTFactory.emptyStatement());
   }
   void test_visitExportDirective_combinator() {
-    assertSource("export 'a.dart' show A;", ASTFactory.exportDirective2("a.dart", [(ASTFactory.importShowCombinator([ASTFactory.identifier2("A")]) as Combinator)]));
+    assertSource("export 'a.dart' show A;", ASTFactory.exportDirective2("a.dart", [(ASTFactory.showCombinator([ASTFactory.identifier2("A")]) as Combinator)]));
   }
   void test_visitExportDirective_combinators() {
-    assertSource("export 'a.dart' show A hide B;", ASTFactory.exportDirective2("a.dart", [ASTFactory.importShowCombinator([ASTFactory.identifier2("A")]), ASTFactory.importHideCombinator([ASTFactory.identifier2("B")])]));
+    assertSource("export 'a.dart' show A hide B;", ASTFactory.exportDirective2("a.dart", [ASTFactory.showCombinator([ASTFactory.identifier2("A")]), ASTFactory.hideCombinator([ASTFactory.identifier2("B")])]));
   }
   void test_visitExportDirective_minimal() {
     assertSource("export 'a.dart';", ASTFactory.exportDirective2("a.dart", []));
@@ -701,7 +1386,7 @@
     assertSource("A this.a", ASTFactory.fieldFormalParameter(null, ASTFactory.typeName3("A", []), "a"));
   }
   void test_visitForEachStatement() {
-    assertSource("for (a in b) {}", ASTFactory.forEachStatement(ASTFactory.simpleFormalParameter3("a"), ASTFactory.identifier2("b"), ASTFactory.block([])));
+    assertSource("for (a in b) {}", ASTFactory.forEachStatement(ASTFactory.declaredIdentifier3("a"), ASTFactory.identifier2("b"), ASTFactory.block([])));
   }
   void test_visitFormalParameterList_empty() {
     assertSource("()", ASTFactory.formalParameterList([]));
@@ -818,10 +1503,10 @@
     assertSource("implements A", ASTFactory.implementsClause([ASTFactory.typeName3("A", [])]));
   }
   void test_visitImportDirective_combinator() {
-    assertSource("import 'a.dart' show A;", ASTFactory.importDirective2("a.dart", null, [ASTFactory.importShowCombinator([ASTFactory.identifier2("A")])]));
+    assertSource("import 'a.dart' show A;", ASTFactory.importDirective2("a.dart", null, [ASTFactory.showCombinator([ASTFactory.identifier2("A")])]));
   }
   void test_visitImportDirective_combinators() {
-    assertSource("import 'a.dart' show A hide B;", ASTFactory.importDirective2("a.dart", null, [ASTFactory.importShowCombinator([ASTFactory.identifier2("A")]), ASTFactory.importHideCombinator([ASTFactory.identifier2("B")])]));
+    assertSource("import 'a.dart' show A hide B;", ASTFactory.importDirective2("a.dart", null, [ASTFactory.showCombinator([ASTFactory.identifier2("A")]), ASTFactory.hideCombinator([ASTFactory.identifier2("B")])]));
   }
   void test_visitImportDirective_minimal() {
     assertSource("import 'a.dart';", ASTFactory.importDirective2("a.dart", null, []));
@@ -830,31 +1515,34 @@
     assertSource("import 'a.dart' as p;", ASTFactory.importDirective2("a.dart", "p", []));
   }
   void test_visitImportDirective_prefix_combinator() {
-    assertSource("import 'a.dart' as p show A;", ASTFactory.importDirective2("a.dart", "p", [ASTFactory.importShowCombinator([ASTFactory.identifier2("A")])]));
+    assertSource("import 'a.dart' as p show A;", ASTFactory.importDirective2("a.dart", "p", [ASTFactory.showCombinator([ASTFactory.identifier2("A")])]));
   }
   void test_visitImportDirective_prefix_combinators() {
-    assertSource("import 'a.dart' as p show A hide B;", ASTFactory.importDirective2("a.dart", "p", [ASTFactory.importShowCombinator([ASTFactory.identifier2("A")]), ASTFactory.importHideCombinator([ASTFactory.identifier2("B")])]));
+    assertSource("import 'a.dart' as p show A hide B;", ASTFactory.importDirective2("a.dart", "p", [ASTFactory.showCombinator([ASTFactory.identifier2("A")]), ASTFactory.hideCombinator([ASTFactory.identifier2("B")])]));
   }
   void test_visitImportHideCombinator_multiple() {
-    assertSource("hide a, b", ASTFactory.importHideCombinator([ASTFactory.identifier2("a"), ASTFactory.identifier2("b")]));
+    assertSource("hide a, b", ASTFactory.hideCombinator([ASTFactory.identifier2("a"), ASTFactory.identifier2("b")]));
   }
   void test_visitImportHideCombinator_single() {
-    assertSource("hide a", ASTFactory.importHideCombinator([ASTFactory.identifier2("a")]));
+    assertSource("hide a", ASTFactory.hideCombinator([ASTFactory.identifier2("a")]));
   }
   void test_visitImportShowCombinator_multiple() {
-    assertSource("show a, b", ASTFactory.importShowCombinator([ASTFactory.identifier2("a"), ASTFactory.identifier2("b")]));
+    assertSource("show a, b", ASTFactory.showCombinator([ASTFactory.identifier2("a"), ASTFactory.identifier2("b")]));
   }
   void test_visitImportShowCombinator_single() {
-    assertSource("show a", ASTFactory.importShowCombinator([ASTFactory.identifier2("a")]));
+    assertSource("show a", ASTFactory.showCombinator([ASTFactory.identifier2("a")]));
   }
   void test_visitIndexExpression() {
     assertSource("a[i]", ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("i")));
   }
+  void test_visitInstanceCreationExpression_const() {
+    assertSource("const C()", ASTFactory.instanceCreationExpression2(Keyword.CONST, ASTFactory.typeName3("C", []), []));
+  }
   void test_visitInstanceCreationExpression_named() {
-    assertSource("new C.c()", ASTFactory.instanceCreationExpression2(Keyword.NEW, ASTFactory.typeName3("C", []), "c", []));
+    assertSource("new C.c()", ASTFactory.instanceCreationExpression3(Keyword.NEW, ASTFactory.typeName3("C", []), "c", []));
   }
   void test_visitInstanceCreationExpression_unnamed() {
-    assertSource("new C()", ASTFactory.instanceCreationExpression(Keyword.NEW, ASTFactory.typeName3("C", []), []));
+    assertSource("new C()", ASTFactory.instanceCreationExpression2(Keyword.NEW, ASTFactory.typeName3("C", []), []));
   }
   void test_visitIntegerLiteral() {
     assertSource("42", ASTFactory.integer(42));
@@ -989,7 +1677,7 @@
     assertSource("-a", ASTFactory.prefixExpression(TokenType.MINUS, ASTFactory.identifier2("a")));
   }
   void test_visitPropertyAccess() {
-    assertSource("a.b", ASTFactory.propertyAccess(ASTFactory.identifier2("a"), "b"));
+    assertSource("a.b", ASTFactory.propertyAccess2(ASTFactory.identifier2("a"), "b"));
   }
   void test_visitRedirectingConstructorInvocation_named() {
     assertSource("this.c()", ASTFactory.redirectingConstructorInvocation2("c", []));
@@ -1725,6 +2413,10 @@
         final __test = new ToSourceVisitorTest();
         runJUnitTest(__test, __test.test_visitIndexExpression);
       });
+      _ut.test('test_visitInstanceCreationExpression_const', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitInstanceCreationExpression_const);
+      });
       _ut.test('test_visitInstanceCreationExpression_named', () {
         final __test = new ToSourceVisitorTest();
         runJUnitTest(__test, __test.test_visitInstanceCreationExpression_named);
@@ -2128,579 +2820,6 @@
     });
   }
 }
-class IndexExpressionTest extends EngineTestCase {
-  void test_inGetterContext_assignment_compound_left() {
-    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
-    ASTFactory.assignmentExpression(expression, TokenType.PLUS_EQ, null);
-    JUnitTestCase.assertTrue(expression.inGetterContext());
-  }
-  void test_inGetterContext_assignment_simple_left() {
-    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
-    ASTFactory.assignmentExpression(expression, TokenType.EQ, null);
-    JUnitTestCase.assertFalse(expression.inGetterContext());
-  }
-  void test_inGetterContext_nonAssignment() {
-    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
-    ASTFactory.binaryExpression(expression, TokenType.PLUS, null);
-    JUnitTestCase.assertTrue(expression.inGetterContext());
-  }
-  void test_inSetterContext_assignment_compound_left() {
-    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
-    ASTFactory.assignmentExpression(expression, TokenType.PLUS_EQ, null);
-    JUnitTestCase.assertTrue(expression.inSetterContext());
-  }
-  void test_inSetterContext_assignment_compound_right() {
-    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
-    ASTFactory.assignmentExpression(null, TokenType.PLUS_EQ, expression);
-    JUnitTestCase.assertFalse(expression.inSetterContext());
-  }
-  void test_inSetterContext_assignment_simple_left() {
-    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
-    ASTFactory.assignmentExpression(expression, TokenType.EQ, null);
-    JUnitTestCase.assertTrue(expression.inSetterContext());
-  }
-  void test_inSetterContext_assignment_simple_right() {
-    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
-    ASTFactory.assignmentExpression(null, TokenType.EQ, expression);
-    JUnitTestCase.assertFalse(expression.inSetterContext());
-  }
-  void test_inSetterContext_nonAssignment() {
-    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
-    ASTFactory.binaryExpression(expression, TokenType.PLUS, null);
-    JUnitTestCase.assertFalse(expression.inSetterContext());
-  }
-  void test_inSetterContext_postfix() {
-    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
-    ASTFactory.postfixExpression(expression, TokenType.PLUS_PLUS);
-    JUnitTestCase.assertTrue(expression.inSetterContext());
-  }
-  void test_inSetterContext_prefix_bang() {
-    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
-    ASTFactory.prefixExpression(TokenType.BANG, expression);
-    JUnitTestCase.assertFalse(expression.inSetterContext());
-  }
-  void test_inSetterContext_prefix_minusMinus() {
-    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
-    ASTFactory.prefixExpression(TokenType.MINUS_MINUS, expression);
-    JUnitTestCase.assertTrue(expression.inSetterContext());
-  }
-  void test_inSetterContext_prefix_plusPlus() {
-    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
-    ASTFactory.prefixExpression(TokenType.PLUS_PLUS, expression);
-    JUnitTestCase.assertTrue(expression.inSetterContext());
-  }
-  static dartSuite() {
-    _ut.group('IndexExpressionTest', () {
-      _ut.test('test_inGetterContext_assignment_compound_left', () {
-        final __test = new IndexExpressionTest();
-        runJUnitTest(__test, __test.test_inGetterContext_assignment_compound_left);
-      });
-      _ut.test('test_inGetterContext_assignment_simple_left', () {
-        final __test = new IndexExpressionTest();
-        runJUnitTest(__test, __test.test_inGetterContext_assignment_simple_left);
-      });
-      _ut.test('test_inGetterContext_nonAssignment', () {
-        final __test = new IndexExpressionTest();
-        runJUnitTest(__test, __test.test_inGetterContext_nonAssignment);
-      });
-      _ut.test('test_inSetterContext_assignment_compound_left', () {
-        final __test = new IndexExpressionTest();
-        runJUnitTest(__test, __test.test_inSetterContext_assignment_compound_left);
-      });
-      _ut.test('test_inSetterContext_assignment_compound_right', () {
-        final __test = new IndexExpressionTest();
-        runJUnitTest(__test, __test.test_inSetterContext_assignment_compound_right);
-      });
-      _ut.test('test_inSetterContext_assignment_simple_left', () {
-        final __test = new IndexExpressionTest();
-        runJUnitTest(__test, __test.test_inSetterContext_assignment_simple_left);
-      });
-      _ut.test('test_inSetterContext_assignment_simple_right', () {
-        final __test = new IndexExpressionTest();
-        runJUnitTest(__test, __test.test_inSetterContext_assignment_simple_right);
-      });
-      _ut.test('test_inSetterContext_nonAssignment', () {
-        final __test = new IndexExpressionTest();
-        runJUnitTest(__test, __test.test_inSetterContext_nonAssignment);
-      });
-      _ut.test('test_inSetterContext_postfix', () {
-        final __test = new IndexExpressionTest();
-        runJUnitTest(__test, __test.test_inSetterContext_postfix);
-      });
-      _ut.test('test_inSetterContext_prefix_bang', () {
-        final __test = new IndexExpressionTest();
-        runJUnitTest(__test, __test.test_inSetterContext_prefix_bang);
-      });
-      _ut.test('test_inSetterContext_prefix_minusMinus', () {
-        final __test = new IndexExpressionTest();
-        runJUnitTest(__test, __test.test_inSetterContext_prefix_minusMinus);
-      });
-      _ut.test('test_inSetterContext_prefix_plusPlus', () {
-        final __test = new IndexExpressionTest();
-        runJUnitTest(__test, __test.test_inSetterContext_prefix_plusPlus);
-      });
-    });
-  }
-}
-class ConstantEvaluatorTest extends ParserTestCase {
-  void fail_constructor() {
-    Object value = getConstantValue("?");
-    JUnitTestCase.assertEquals(null, value);
-  }
-  void fail_identifier_class() {
-    Object value = getConstantValue("?");
-    JUnitTestCase.assertEquals(null, value);
-  }
-  void fail_identifier_function() {
-    Object value = getConstantValue("?");
-    JUnitTestCase.assertEquals(null, value);
-  }
-  void fail_identifier_static() {
-    Object value = getConstantValue("?");
-    JUnitTestCase.assertEquals(null, value);
-  }
-  void fail_identifier_staticMethod() {
-    Object value = getConstantValue("?");
-    JUnitTestCase.assertEquals(null, value);
-  }
-  void fail_identifier_topLevel() {
-    Object value = getConstantValue("?");
-    JUnitTestCase.assertEquals(null, value);
-  }
-  void fail_identifier_typeVariable() {
-    Object value = getConstantValue("?");
-    JUnitTestCase.assertEquals(null, value);
-  }
-  void test_binary_bitAnd() {
-    Object value = getConstantValue("74 & 42");
-    EngineTestCase.assertInstanceOf(int, value);
-    JUnitTestCase.assertEquals(74 & 42, ((value as int)));
-  }
-  void test_binary_bitOr() {
-    Object value = getConstantValue("74 | 42");
-    EngineTestCase.assertInstanceOf(int, value);
-    JUnitTestCase.assertEquals(74 | 42, ((value as int)));
-  }
-  void test_binary_bitXor() {
-    Object value = getConstantValue("74 ^ 42");
-    EngineTestCase.assertInstanceOf(int, value);
-    JUnitTestCase.assertEquals(74 ^ 42, ((value as int)));
-  }
-  void test_binary_divide_double() {
-    Object value = getConstantValue("3.2 / 2.3");
-    EngineTestCase.assertInstanceOf(double, value);
-    JUnitTestCase.assertEquals(3.2 / 2.3, ((value as double)));
-  }
-  void test_binary_divide_integer() {
-    Object value = getConstantValue("3 / 2");
-    EngineTestCase.assertInstanceOf(int, value);
-    JUnitTestCase.assertEquals(1, ((value as int)));
-  }
-  void test_binary_equal_boolean() {
-    Object value = getConstantValue("true == false");
-    JUnitTestCase.assertEquals(false, value);
-  }
-  void test_binary_equal_integer() {
-    Object value = getConstantValue("2 == 3");
-    JUnitTestCase.assertEquals(false, value);
-  }
-  void test_binary_equal_invalidLeft() {
-    Object value = getConstantValue("a == 3");
-    JUnitTestCase.assertEquals(ConstantEvaluator.NOT_A_CONSTANT, value);
-  }
-  void test_binary_equal_invalidRight() {
-    Object value = getConstantValue("2 == a");
-    JUnitTestCase.assertEquals(ConstantEvaluator.NOT_A_CONSTANT, value);
-  }
-  void test_binary_equal_string() {
-    Object value = getConstantValue("'a' == 'b'");
-    JUnitTestCase.assertEquals(false, value);
-  }
-  void test_binary_greaterThan() {
-    Object value = getConstantValue("2 > 3");
-    JUnitTestCase.assertEquals(false, value);
-  }
-  void test_binary_greaterThanOrEqual() {
-    Object value = getConstantValue("2 >= 3");
-    JUnitTestCase.assertEquals(false, value);
-  }
-  void test_binary_leftShift() {
-    Object value = getConstantValue("16 << 2");
-    EngineTestCase.assertInstanceOf(int, value);
-    JUnitTestCase.assertEquals(64, ((value as int)));
-  }
-  void test_binary_lessThan() {
-    Object value = getConstantValue("2 < 3");
-    JUnitTestCase.assertEquals(true, value);
-  }
-  void test_binary_lessThanOrEqual() {
-    Object value = getConstantValue("2 <= 3");
-    JUnitTestCase.assertEquals(true, value);
-  }
-  void test_binary_logicalAnd() {
-    Object value = getConstantValue("true && false");
-    JUnitTestCase.assertEquals(false, value);
-  }
-  void test_binary_logicalOr() {
-    Object value = getConstantValue("true || false");
-    JUnitTestCase.assertEquals(true, value);
-  }
-  void test_binary_minus_double() {
-    Object value = getConstantValue("3.2 - 2.3");
-    EngineTestCase.assertInstanceOf(double, value);
-    JUnitTestCase.assertEquals(3.2 - 2.3, ((value as double)));
-  }
-  void test_binary_minus_integer() {
-    Object value = getConstantValue("3 - 2");
-    EngineTestCase.assertInstanceOf(int, value);
-    JUnitTestCase.assertEquals(1, ((value as int)));
-  }
-  void test_binary_notEqual_boolean() {
-    Object value = getConstantValue("true != false");
-    JUnitTestCase.assertEquals(true, value);
-  }
-  void test_binary_notEqual_integer() {
-    Object value = getConstantValue("2 != 3");
-    JUnitTestCase.assertEquals(true, value);
-  }
-  void test_binary_notEqual_invalidLeft() {
-    Object value = getConstantValue("a != 3");
-    JUnitTestCase.assertEquals(ConstantEvaluator.NOT_A_CONSTANT, value);
-  }
-  void test_binary_notEqual_invalidRight() {
-    Object value = getConstantValue("2 != a");
-    JUnitTestCase.assertEquals(ConstantEvaluator.NOT_A_CONSTANT, value);
-  }
-  void test_binary_notEqual_string() {
-    Object value = getConstantValue("'a' != 'b'");
-    JUnitTestCase.assertEquals(true, value);
-  }
-  void test_binary_plus_double() {
-    Object value = getConstantValue("2.3 + 3.2");
-    EngineTestCase.assertInstanceOf(double, value);
-    JUnitTestCase.assertEquals(2.3 + 3.2, ((value as double)));
-  }
-  void test_binary_plus_integer() {
-    Object value = getConstantValue("2 + 3");
-    EngineTestCase.assertInstanceOf(int, value);
-    JUnitTestCase.assertEquals(5, ((value as int)));
-  }
-  void test_binary_remainder_double() {
-    Object value = getConstantValue("3.2 % 2.3");
-    EngineTestCase.assertInstanceOf(double, value);
-    JUnitTestCase.assertEquals(3.2 % 2.3, ((value as double)));
-  }
-  void test_binary_remainder_integer() {
-    Object value = getConstantValue("8 % 3");
-    EngineTestCase.assertInstanceOf(int, value);
-    JUnitTestCase.assertEquals(2, ((value as int)));
-  }
-  void test_binary_rightShift() {
-    Object value = getConstantValue("64 >> 2");
-    EngineTestCase.assertInstanceOf(int, value);
-    JUnitTestCase.assertEquals(16, ((value as int)));
-  }
-  void test_binary_times_double() {
-    Object value = getConstantValue("2.3 * 3.2");
-    EngineTestCase.assertInstanceOf(double, value);
-    JUnitTestCase.assertEquals(2.3 * 3.2, ((value as double)));
-  }
-  void test_binary_times_integer() {
-    Object value = getConstantValue("2 * 3");
-    EngineTestCase.assertInstanceOf(int, value);
-    JUnitTestCase.assertEquals(6, ((value as int)));
-  }
-  void test_binary_truncatingDivide_double() {
-    Object value = getConstantValue("3.2 ~/ 2.3");
-    EngineTestCase.assertInstanceOf(int, value);
-    JUnitTestCase.assertEquals(1, ((value as int)));
-  }
-  void test_binary_truncatingDivide_integer() {
-    Object value = getConstantValue("10 ~/ 3");
-    EngineTestCase.assertInstanceOf(int, value);
-    JUnitTestCase.assertEquals(3, ((value as int)));
-  }
-  void test_literal_boolean_false() {
-    Object value = getConstantValue("false");
-    JUnitTestCase.assertEquals(false, value);
-  }
-  void test_literal_boolean_true() {
-    Object value = getConstantValue("true");
-    JUnitTestCase.assertEquals(true, value);
-  }
-  void test_literal_list() {
-    Object value = getConstantValue("['a', 'b', 'c']");
-    EngineTestCase.assertInstanceOf(List, value);
-    List<Object> list = (value as List<Object>);
-    JUnitTestCase.assertEquals(3, list.length);
-    JUnitTestCase.assertEquals("a", list[0]);
-    JUnitTestCase.assertEquals("b", list[1]);
-    JUnitTestCase.assertEquals("c", list[2]);
-  }
-  void test_literal_map() {
-    Object value = getConstantValue("{'a' : 'm', 'b' : 'n', 'c' : 'o'}");
-    EngineTestCase.assertInstanceOf(Map, value);
-    Map<Object, Object> map = (value as Map<Object, Object>);
-    JUnitTestCase.assertEquals(3, map.length);
-    JUnitTestCase.assertEquals("m", map["a"]);
-    JUnitTestCase.assertEquals("n", map["b"]);
-    JUnitTestCase.assertEquals("o", map["c"]);
-  }
-  void test_literal_null() {
-    Object value = getConstantValue("null");
-    JUnitTestCase.assertEquals(null, value);
-  }
-  void test_literal_number_double() {
-    Object value = getConstantValue("3.45");
-    EngineTestCase.assertInstanceOf(double, value);
-    JUnitTestCase.assertEquals(3.45, ((value as double)));
-  }
-  void test_literal_number_integer() {
-    Object value = getConstantValue("42");
-    EngineTestCase.assertInstanceOf(int, value);
-    JUnitTestCase.assertEquals(42, ((value as int)));
-  }
-  void test_literal_string_adjacent() {
-    Object value = getConstantValue("'abc' 'def'");
-    JUnitTestCase.assertEquals("abcdef", value);
-  }
-  void test_literal_string_interpolation_invalid() {
-    Object value = getConstantValue("'a\${f()}c'");
-    JUnitTestCase.assertEquals(ConstantEvaluator.NOT_A_CONSTANT, value);
-  }
-  void test_literal_string_interpolation_valid() {
-    Object value = getConstantValue("'a\${3}c'");
-    JUnitTestCase.assertEquals("a3c", value);
-  }
-  void test_literal_string_simple() {
-    Object value = getConstantValue("'abc'");
-    JUnitTestCase.assertEquals("abc", value);
-  }
-  void test_parenthesizedExpression() {
-    Object value = getConstantValue("('a')");
-    JUnitTestCase.assertEquals("a", value);
-  }
-  void test_unary_bitNot() {
-    Object value = getConstantValue("~42");
-    EngineTestCase.assertInstanceOf(int, value);
-    JUnitTestCase.assertEquals(~42, ((value as int)));
-  }
-  void test_unary_logicalNot() {
-    Object value = getConstantValue("!true");
-    JUnitTestCase.assertEquals(false, value);
-  }
-  void test_unary_negated_double() {
-    Object value = getConstantValue("-42.3");
-    EngineTestCase.assertInstanceOf(double, value);
-    JUnitTestCase.assertEquals(-42.3, ((value as double)));
-  }
-  void test_unary_negated_integer() {
-    Object value = getConstantValue("-42");
-    EngineTestCase.assertInstanceOf(int, value);
-    JUnitTestCase.assertEquals(-42, ((value as int)));
-  }
-  Object getConstantValue(String source) => ParserTestCase.parseExpression(source, []).accept(new ConstantEvaluator());
-  static dartSuite() {
-    _ut.group('ConstantEvaluatorTest', () {
-      _ut.test('test_binary_bitAnd', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_bitAnd);
-      });
-      _ut.test('test_binary_bitOr', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_bitOr);
-      });
-      _ut.test('test_binary_bitXor', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_bitXor);
-      });
-      _ut.test('test_binary_divide_double', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_divide_double);
-      });
-      _ut.test('test_binary_divide_integer', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_divide_integer);
-      });
-      _ut.test('test_binary_equal_boolean', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_equal_boolean);
-      });
-      _ut.test('test_binary_equal_integer', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_equal_integer);
-      });
-      _ut.test('test_binary_equal_invalidLeft', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_equal_invalidLeft);
-      });
-      _ut.test('test_binary_equal_invalidRight', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_equal_invalidRight);
-      });
-      _ut.test('test_binary_equal_string', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_equal_string);
-      });
-      _ut.test('test_binary_greaterThan', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_greaterThan);
-      });
-      _ut.test('test_binary_greaterThanOrEqual', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_greaterThanOrEqual);
-      });
-      _ut.test('test_binary_leftShift', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_leftShift);
-      });
-      _ut.test('test_binary_lessThan', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_lessThan);
-      });
-      _ut.test('test_binary_lessThanOrEqual', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_lessThanOrEqual);
-      });
-      _ut.test('test_binary_logicalAnd', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_logicalAnd);
-      });
-      _ut.test('test_binary_logicalOr', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_logicalOr);
-      });
-      _ut.test('test_binary_minus_double', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_minus_double);
-      });
-      _ut.test('test_binary_minus_integer', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_minus_integer);
-      });
-      _ut.test('test_binary_notEqual_boolean', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_notEqual_boolean);
-      });
-      _ut.test('test_binary_notEqual_integer', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_notEqual_integer);
-      });
-      _ut.test('test_binary_notEqual_invalidLeft', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_notEqual_invalidLeft);
-      });
-      _ut.test('test_binary_notEqual_invalidRight', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_notEqual_invalidRight);
-      });
-      _ut.test('test_binary_notEqual_string', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_notEqual_string);
-      });
-      _ut.test('test_binary_plus_double', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_plus_double);
-      });
-      _ut.test('test_binary_plus_integer', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_plus_integer);
-      });
-      _ut.test('test_binary_remainder_double', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_remainder_double);
-      });
-      _ut.test('test_binary_remainder_integer', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_remainder_integer);
-      });
-      _ut.test('test_binary_rightShift', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_rightShift);
-      });
-      _ut.test('test_binary_times_double', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_times_double);
-      });
-      _ut.test('test_binary_times_integer', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_times_integer);
-      });
-      _ut.test('test_binary_truncatingDivide_double', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_truncatingDivide_double);
-      });
-      _ut.test('test_binary_truncatingDivide_integer', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_binary_truncatingDivide_integer);
-      });
-      _ut.test('test_literal_boolean_false', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_literal_boolean_false);
-      });
-      _ut.test('test_literal_boolean_true', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_literal_boolean_true);
-      });
-      _ut.test('test_literal_list', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_literal_list);
-      });
-      _ut.test('test_literal_map', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_literal_map);
-      });
-      _ut.test('test_literal_null', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_literal_null);
-      });
-      _ut.test('test_literal_number_double', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_literal_number_double);
-      });
-      _ut.test('test_literal_number_integer', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_literal_number_integer);
-      });
-      _ut.test('test_literal_string_adjacent', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_literal_string_adjacent);
-      });
-      _ut.test('test_literal_string_interpolation_invalid', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_literal_string_interpolation_invalid);
-      });
-      _ut.test('test_literal_string_interpolation_valid', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_literal_string_interpolation_valid);
-      });
-      _ut.test('test_literal_string_simple', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_literal_string_simple);
-      });
-      _ut.test('test_parenthesizedExpression', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_parenthesizedExpression);
-      });
-      _ut.test('test_unary_bitNot', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_unary_bitNot);
-      });
-      _ut.test('test_unary_logicalNot', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_unary_logicalNot);
-      });
-      _ut.test('test_unary_negated_double', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_unary_negated_double);
-      });
-      _ut.test('test_unary_negated_integer', () {
-        final __test = new ConstantEvaluatorTest();
-        runJUnitTest(__test, __test.test_unary_negated_integer);
-      });
-    });
-  }
-}
 main() {
   ConstantEvaluatorTest.dartSuite();
   NodeLocatorTest.dartSuite();
diff --git a/pkg/analyzer-experimental/test/generated/element_test.dart b/pkg/analyzer_experimental/test/generated/element_test.dart
similarity index 86%
rename from pkg/analyzer-experimental/test/generated/element_test.dart
rename to pkg/analyzer_experimental/test/generated/element_test.dart
index 0610a55..f8712ad 100644
--- a/pkg/analyzer-experimental/test/generated/element_test.dart
+++ b/pkg/analyzer_experimental/test/generated/element_test.dart
@@ -4,15 +4,18 @@
 library engine.element_test;
 
 import 'dart:collection';
-import 'package:analyzer-experimental/src/generated/java_core.dart';
-import 'package:analyzer-experimental/src/generated/java_engine.dart';
-import 'package:analyzer-experimental/src/generated/java_junit.dart';
-import 'package:analyzer-experimental/src/generated/source.dart';
-import 'package:analyzer-experimental/src/generated/error.dart';
-import 'package:analyzer-experimental/src/generated/scanner.dart';
-import 'package:analyzer-experimental/src/generated/ast.dart' hide Annotation;
-import 'package:analyzer-experimental/src/generated/element.dart' hide Annotation;
-import 'package:analyzer-experimental/src/generated/engine.dart' show AnalysisContext, AnalysisContextImpl;
+import 'dart:io';
+import 'package:analyzer_experimental/src/generated/java_core.dart';
+import 'package:analyzer_experimental/src/generated/java_engine.dart';
+import 'package:analyzer_experimental/src/generated/java_engine_io.dart';
+import 'package:analyzer_experimental/src/generated/java_junit.dart';
+import 'package:analyzer_experimental/src/generated/source_io.dart';
+import 'package:analyzer_experimental/src/generated/error.dart';
+import 'package:analyzer_experimental/src/generated/scanner.dart';
+import 'package:analyzer_experimental/src/generated/utilities_dart.dart';
+import 'package:analyzer_experimental/src/generated/ast.dart' hide Annotation;
+import 'package:analyzer_experimental/src/generated/element.dart' hide Annotation;
+import 'package:analyzer_experimental/src/generated/engine.dart' show AnalysisContext, AnalysisContextImpl;
 import 'package:unittest/unittest.dart' as _ut;
 import 'test_support.dart';
 import 'scanner_test.dart' show TokenFactory;
@@ -91,447 +94,6 @@
     });
   }
 }
-class FunctionTypeImplTest extends EngineTestCase {
-  void test_creation() {
-    JUnitTestCase.assertNotNull(new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f"))));
-  }
-  void test_getElement() {
-    FunctionElementImpl typeElement = new FunctionElementImpl.con1(ASTFactory.identifier2("f"));
-    FunctionTypeImpl type = new FunctionTypeImpl.con1(typeElement);
-    JUnitTestCase.assertEquals(typeElement, type.element);
-  }
-  void test_getNamedParameterTypes() {
-    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
-    Map<String, Type2> types = type.namedParameterTypes;
-    EngineTestCase.assertSize2(0, types);
-  }
-  void test_getNormalParameterTypes() {
-    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
-    List<Type2> types = type.normalParameterTypes;
-    EngineTestCase.assertLength(0, types);
-  }
-  void test_getReturnType() {
-    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
-    Type2 returnType5 = type.returnType;
-    JUnitTestCase.assertEquals(VoidTypeImpl.instance, returnType5);
-  }
-  void test_getTypeArguments() {
-    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
-    List<Type2> types = type.typeArguments;
-    EngineTestCase.assertLength(0, types);
-  }
-  void test_hashCode_element() {
-    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
-    type.hashCode;
-  }
-  void test_hashCode_noElement() {
-    FunctionTypeImpl type = new FunctionTypeImpl.con1((null as ExecutableElement));
-    type.hashCode;
-  }
-  void test_isSubtypeOf_baseCase_notFunctionType() {
-    FunctionType f = ElementFactory.functionElement("f").type;
-    InterfaceType t = ElementFactory.classElement2("C", []).type;
-    JUnitTestCase.assertFalse(f.isSubtypeOf(t));
-  }
-  void test_isSubtypeOf_baseCase_null() {
-    FunctionType f = ElementFactory.functionElement("f").type;
-    JUnitTestCase.assertFalse(f.isSubtypeOf(null));
-  }
-  void test_isSubtypeOf_baseCase_self() {
-    FunctionType f = ElementFactory.functionElement("f").type;
-    JUnitTestCase.assertTrue(f.isSubtypeOf(f));
-  }
-  void test_isSubtypeOf_namedParameters_isAssignable() {
-    ClassElement a = ElementFactory.classElement2("A", []);
-    ClassElement b = ElementFactory.classElement("B", a.type, []);
-    FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["name"], <ClassElement> [a]).type;
-    FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["name"], <ClassElement> [b]).type;
-    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
-    JUnitTestCase.assertTrue(s.isSubtypeOf(t));
-  }
-  void test_isSubtypeOf_namedParameters_isNotAssignable() {
-    FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["name"], <ClassElement> [ElementFactory.classElement2("A", [])]).type;
-    FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["name"], <ClassElement> [ElementFactory.classElement2("B", [])]).type;
-    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
-  }
-  void test_isSubtypeOf_namedParameters_namesDifferent() {
-    ClassElement a = ElementFactory.classElement2("A", []);
-    ClassElement b = ElementFactory.classElement("B", a.type, []);
-    FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["name"], <ClassElement> [a]).type;
-    FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["diff"], <ClassElement> [b]).type;
-    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
-    JUnitTestCase.assertFalse(s.isSubtypeOf(t));
-  }
-  void test_isSubtypeOf_namedParameters_orderOfParams() {
-    ClassElement a = ElementFactory.classElement2("A", []);
-    ClassElement b = ElementFactory.classElement("B", a.type, []);
-    FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["A", "B"], <ClassElement> [a, b]).type;
-    FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["B", "A"], <ClassElement> [b, a]).type;
-    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
-  }
-  void test_isSubtypeOf_namedParameters_orderOfParams2() {
-    ClassElement a = ElementFactory.classElement2("A", []);
-    ClassElement b = ElementFactory.classElement("B", a.type, []);
-    FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["B"], <ClassElement> [b]).type;
-    FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["B", "A"], <ClassElement> [b, a]).type;
-    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
-  }
-  void test_isSubtypeOf_namedParameters_orderOfParams3() {
-    ClassElement a = ElementFactory.classElement2("A", []);
-    ClassElement b = ElementFactory.classElement("B", a.type, []);
-    FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["A", "B"], <ClassElement> [a, b]).type;
-    FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["B"], <ClassElement> [b]).type;
-    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
-  }
-  void test_isSubtypeOf_namedParameters_sHasMoreParams() {
-    ClassElement a = ElementFactory.classElement2("A", []);
-    ClassElement b = ElementFactory.classElement("B", a.type, []);
-    FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["name"], <ClassElement> [a]).type;
-    FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["name", "name2"], <ClassElement> [b, b]).type;
-    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
-  }
-  void test_isSubtypeOf_namedParameters_tHasMoreParams() {
-    ClassElement a = ElementFactory.classElement2("A", []);
-    ClassElement b = ElementFactory.classElement("B", a.type, []);
-    FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["name", "name2"], <ClassElement> [a, a]).type;
-    FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["name"], <ClassElement> [b]).type;
-    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
-  }
-  void test_isSubtypeOf_normalParameters_isAssignable() {
-    ClassElement a = ElementFactory.classElement2("A", []);
-    ClassElement b = ElementFactory.classElement("B", a.type, []);
-    FunctionType t = ElementFactory.functionElement5("t", <ClassElement> [a]).type;
-    FunctionType s = ElementFactory.functionElement5("s", <ClassElement> [b]).type;
-    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
-    JUnitTestCase.assertTrue(s.isSubtypeOf(t));
-  }
-  void test_isSubtypeOf_normalParameters_isNotAssignable() {
-    FunctionType t = ElementFactory.functionElement5("t", <ClassElement> [ElementFactory.classElement2("A", [])]).type;
-    FunctionType s = ElementFactory.functionElement5("s", <ClassElement> [ElementFactory.classElement2("B", [])]).type;
-    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
-  }
-  void test_isSubtypeOf_normalParameters_sHasMoreParams() {
-    ClassElement a = ElementFactory.classElement2("A", []);
-    ClassElement b = ElementFactory.classElement("B", a.type, []);
-    FunctionType t = ElementFactory.functionElement5("t", <ClassElement> [a]).type;
-    FunctionType s = ElementFactory.functionElement5("s", <ClassElement> [b, b]).type;
-    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
-  }
-  void test_isSubtypeOf_normalParameters_tHasMoreParams() {
-    ClassElement a = ElementFactory.classElement2("A", []);
-    ClassElement b = ElementFactory.classElement("B", a.type, []);
-    FunctionType t = ElementFactory.functionElement5("t", <ClassElement> [a, a]).type;
-    FunctionType s = ElementFactory.functionElement5("s", <ClassElement> [b]).type;
-    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
-  }
-  void test_isSubtypeOf_optionalParameters_isAssignable() {
-    ClassElement a = ElementFactory.classElement2("A", []);
-    ClassElement b = ElementFactory.classElement("B", a.type, []);
-    FunctionType t = ElementFactory.functionElement6("t", null, <ClassElement> [a]).type;
-    FunctionType s = ElementFactory.functionElement6("s", null, <ClassElement> [b]).type;
-    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
-    JUnitTestCase.assertTrue(s.isSubtypeOf(t));
-  }
-  void test_isSubtypeOf_optionalParameters_isNotAssignable() {
-    FunctionType t = ElementFactory.functionElement6("t", null, <ClassElement> [ElementFactory.classElement2("A", [])]).type;
-    FunctionType s = ElementFactory.functionElement6("s", null, <ClassElement> [ElementFactory.classElement2("B", [])]).type;
-    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
-  }
-  void test_isSubtypeOf_optionalParameters_sHasMoreParams() {
-    ClassElement a = ElementFactory.classElement2("A", []);
-    ClassElement b = ElementFactory.classElement("B", a.type, []);
-    FunctionType t = ElementFactory.functionElement6("t", null, <ClassElement> [a]).type;
-    FunctionType s = ElementFactory.functionElement6("s", null, <ClassElement> [b, b]).type;
-    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
-  }
-  void test_isSubtypeOf_optionalParameters_tHasMoreParams() {
-    ClassElement a = ElementFactory.classElement2("A", []);
-    ClassElement b = ElementFactory.classElement("B", a.type, []);
-    FunctionType t = ElementFactory.functionElement6("t", null, <ClassElement> [a, a]).type;
-    FunctionType s = ElementFactory.functionElement6("s", null, <ClassElement> [b]).type;
-    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
-  }
-  void test_isSubtypeOf_returnType_sIsVoid() {
-    FunctionType t = ElementFactory.functionElement2("t", ElementFactory.classElement2("A", [])).type;
-    FunctionType s = ElementFactory.functionElement("s").type;
-    JUnitTestCase.assertTrue(VoidTypeImpl.instance == s.returnType);
-    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
-  }
-  void test_isSubtypeOf_returnType_tAssignableToS() {
-    ClassElement a = ElementFactory.classElement2("A", []);
-    ClassElement b = ElementFactory.classElement("B", a.type, []);
-    FunctionType t = ElementFactory.functionElement2("t", a).type;
-    FunctionType s = ElementFactory.functionElement2("s", b).type;
-    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
-    JUnitTestCase.assertTrue(s.isSubtypeOf(t));
-  }
-  void test_isSubtypeOf_returnType_tNotAssignableToS() {
-    FunctionType t = ElementFactory.functionElement2("t", ElementFactory.classElement2("A", [])).type;
-    FunctionType s = ElementFactory.functionElement2("s", ElementFactory.classElement2("B", [])).type;
-    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
-  }
-  void test_isSubtypeOf_wrongFunctionType_normal_named() {
-    ClassElement a = ElementFactory.classElement2("A", []);
-    FunctionType t = ElementFactory.functionElement5("t", <ClassElement> [a]).type;
-    FunctionType s = ElementFactory.functionElement7("s", null, <String> ["name"], <ClassElement> [a]).type;
-    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
-    JUnitTestCase.assertFalse(s.isSubtypeOf(t));
-  }
-  void test_isSubtypeOf_wrongFunctionType_normal_optional() {
-    ClassElement a = ElementFactory.classElement2("A", []);
-    FunctionType t = ElementFactory.functionElement5("t", <ClassElement> [a]).type;
-    FunctionType s = ElementFactory.functionElement6("s", null, <ClassElement> [a]).type;
-    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
-    JUnitTestCase.assertFalse(s.isSubtypeOf(t));
-  }
-  void test_isSubtypeOf_wrongFunctionType_optional_named() {
-    ClassElement a = ElementFactory.classElement2("A", []);
-    FunctionType t = ElementFactory.functionElement6("t", null, <ClassElement> [a]).type;
-    FunctionType s = ElementFactory.functionElement7("s", null, <String> ["name"], <ClassElement> [a]).type;
-    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
-    JUnitTestCase.assertFalse(s.isSubtypeOf(t));
-  }
-  void test_setNamedParameterTypes() {
-    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
-    LinkedHashMap<String, Type2> expectedTypes = new LinkedHashMap<String, Type2>();
-    expectedTypes["a"] = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("C")));
-    type.namedParameterTypes = expectedTypes;
-    Map<String, Type2> types = type.namedParameterTypes;
-    JUnitTestCase.assertEquals(expectedTypes, types);
-  }
-  void test_setNormalParameterTypes() {
-    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
-    List<Type2> expectedTypes = <Type2> [new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("C")))];
-    type.normalParameterTypes = expectedTypes;
-    List<Type2> types = type.normalParameterTypes;
-    JUnitTestCase.assertEquals(expectedTypes, types);
-  }
-  void test_setReturnType() {
-    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
-    Type2 expectedType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("C")));
-    type.returnType = expectedType;
-    Type2 returnType6 = type.returnType;
-    JUnitTestCase.assertEquals(expectedType, returnType6);
-  }
-  void test_setTypeArguments() {
-    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
-    Type2 expectedType = new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier2("C")));
-    type.typeArguments = <Type2> [expectedType];
-    List<Type2> arguments = type.typeArguments;
-    EngineTestCase.assertLength(1, arguments);
-    JUnitTestCase.assertEquals(expectedType, arguments[0]);
-  }
-  void test_substitute2_equal() {
-    FunctionTypeImpl functionType = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
-    TypeVariableTypeImpl parameterType = new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier2("E")));
-    functionType.returnType = parameterType;
-    functionType.normalParameterTypes = <Type2> [parameterType];
-    functionType.optionalParameterTypes = <Type2> [parameterType];
-    LinkedHashMap<String, Type2> namedParameterTypes = new LinkedHashMap<String, Type2>();
-    String namedParameterName = "c";
-    namedParameterTypes[namedParameterName] = parameterType;
-    functionType.namedParameterTypes = namedParameterTypes;
-    InterfaceTypeImpl argumentType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("D")));
-    FunctionType result = functionType.substitute2(<Type2> [argumentType], <Type2> [parameterType]);
-    JUnitTestCase.assertEquals(argumentType, result.returnType);
-    List<Type2> normalParameters = result.normalParameterTypes;
-    EngineTestCase.assertLength(1, normalParameters);
-    JUnitTestCase.assertEquals(argumentType, normalParameters[0]);
-    List<Type2> optionalParameters = result.optionalParameterTypes;
-    EngineTestCase.assertLength(1, optionalParameters);
-    JUnitTestCase.assertEquals(argumentType, optionalParameters[0]);
-    Map<String, Type2> namedParameters = result.namedParameterTypes;
-    EngineTestCase.assertSize2(1, namedParameters);
-    JUnitTestCase.assertEquals(argumentType, namedParameters[namedParameterName]);
-  }
-  void test_substitute2_notEqual() {
-    FunctionTypeImpl functionType = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
-    Type2 returnType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("R")));
-    Type2 normalParameterType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("A")));
-    Type2 optionalParameterType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("B")));
-    Type2 namedParameterType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("C")));
-    functionType.returnType = returnType;
-    functionType.normalParameterTypes = <Type2> [normalParameterType];
-    functionType.optionalParameterTypes = <Type2> [optionalParameterType];
-    LinkedHashMap<String, Type2> namedParameterTypes = new LinkedHashMap<String, Type2>();
-    String namedParameterName = "c";
-    namedParameterTypes[namedParameterName] = namedParameterType;
-    functionType.namedParameterTypes = namedParameterTypes;
-    InterfaceTypeImpl argumentType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("D")));
-    TypeVariableTypeImpl parameterType = new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier2("E")));
-    FunctionType result = functionType.substitute2(<Type2> [argumentType], <Type2> [parameterType]);
-    JUnitTestCase.assertEquals(returnType, result.returnType);
-    List<Type2> normalParameters = result.normalParameterTypes;
-    EngineTestCase.assertLength(1, normalParameters);
-    JUnitTestCase.assertEquals(normalParameterType, normalParameters[0]);
-    List<Type2> optionalParameters = result.optionalParameterTypes;
-    EngineTestCase.assertLength(1, optionalParameters);
-    JUnitTestCase.assertEquals(optionalParameterType, optionalParameters[0]);
-    Map<String, Type2> namedParameters = result.namedParameterTypes;
-    EngineTestCase.assertSize2(1, namedParameters);
-    JUnitTestCase.assertEquals(namedParameterType, namedParameters[namedParameterName]);
-  }
-  static dartSuite() {
-    _ut.group('FunctionTypeImplTest', () {
-      _ut.test('test_creation', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_creation);
-      });
-      _ut.test('test_getElement', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_getElement);
-      });
-      _ut.test('test_getNamedParameterTypes', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_getNamedParameterTypes);
-      });
-      _ut.test('test_getNormalParameterTypes', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_getNormalParameterTypes);
-      });
-      _ut.test('test_getReturnType', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_getReturnType);
-      });
-      _ut.test('test_getTypeArguments', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_getTypeArguments);
-      });
-      _ut.test('test_hashCode_element', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_hashCode_element);
-      });
-      _ut.test('test_hashCode_noElement', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_hashCode_noElement);
-      });
-      _ut.test('test_isSubtypeOf_baseCase_notFunctionType', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_baseCase_notFunctionType);
-      });
-      _ut.test('test_isSubtypeOf_baseCase_null', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_baseCase_null);
-      });
-      _ut.test('test_isSubtypeOf_baseCase_self', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_baseCase_self);
-      });
-      _ut.test('test_isSubtypeOf_namedParameters_isAssignable', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_namedParameters_isAssignable);
-      });
-      _ut.test('test_isSubtypeOf_namedParameters_isNotAssignable', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_namedParameters_isNotAssignable);
-      });
-      _ut.test('test_isSubtypeOf_namedParameters_namesDifferent', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_namedParameters_namesDifferent);
-      });
-      _ut.test('test_isSubtypeOf_namedParameters_orderOfParams', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_namedParameters_orderOfParams);
-      });
-      _ut.test('test_isSubtypeOf_namedParameters_orderOfParams2', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_namedParameters_orderOfParams2);
-      });
-      _ut.test('test_isSubtypeOf_namedParameters_orderOfParams3', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_namedParameters_orderOfParams3);
-      });
-      _ut.test('test_isSubtypeOf_namedParameters_sHasMoreParams', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_namedParameters_sHasMoreParams);
-      });
-      _ut.test('test_isSubtypeOf_namedParameters_tHasMoreParams', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_namedParameters_tHasMoreParams);
-      });
-      _ut.test('test_isSubtypeOf_normalParameters_isAssignable', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_normalParameters_isAssignable);
-      });
-      _ut.test('test_isSubtypeOf_normalParameters_isNotAssignable', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_normalParameters_isNotAssignable);
-      });
-      _ut.test('test_isSubtypeOf_normalParameters_sHasMoreParams', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_normalParameters_sHasMoreParams);
-      });
-      _ut.test('test_isSubtypeOf_normalParameters_tHasMoreParams', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_normalParameters_tHasMoreParams);
-      });
-      _ut.test('test_isSubtypeOf_optionalParameters_isAssignable', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_optionalParameters_isAssignable);
-      });
-      _ut.test('test_isSubtypeOf_optionalParameters_isNotAssignable', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_optionalParameters_isNotAssignable);
-      });
-      _ut.test('test_isSubtypeOf_optionalParameters_sHasMoreParams', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_optionalParameters_sHasMoreParams);
-      });
-      _ut.test('test_isSubtypeOf_optionalParameters_tHasMoreParams', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_optionalParameters_tHasMoreParams);
-      });
-      _ut.test('test_isSubtypeOf_returnType_sIsVoid', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_returnType_sIsVoid);
-      });
-      _ut.test('test_isSubtypeOf_returnType_tAssignableToS', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_returnType_tAssignableToS);
-      });
-      _ut.test('test_isSubtypeOf_returnType_tNotAssignableToS', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_returnType_tNotAssignableToS);
-      });
-      _ut.test('test_isSubtypeOf_wrongFunctionType_normal_named', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_wrongFunctionType_normal_named);
-      });
-      _ut.test('test_isSubtypeOf_wrongFunctionType_normal_optional', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_wrongFunctionType_normal_optional);
-      });
-      _ut.test('test_isSubtypeOf_wrongFunctionType_optional_named', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_isSubtypeOf_wrongFunctionType_optional_named);
-      });
-      _ut.test('test_setNamedParameterTypes', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_setNamedParameterTypes);
-      });
-      _ut.test('test_setNormalParameterTypes', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_setNormalParameterTypes);
-      });
-      _ut.test('test_setReturnType', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_setReturnType);
-      });
-      _ut.test('test_setTypeArguments', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_setTypeArguments);
-      });
-      _ut.test('test_substitute2_equal', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_substitute2_equal);
-      });
-      _ut.test('test_substitute2_notEqual', () {
-        final __test = new FunctionTypeImplTest();
-        runJUnitTest(__test, __test.test_substitute2_notEqual);
-      });
-    });
-  }
-}
 class LibraryElementImplTest extends EngineTestCase {
   void test_creation() {
     JUnitTestCase.assertNotNull(new LibraryElementImpl(new AnalysisContextImpl(), ASTFactory.libraryIdentifier2(["l"])));
@@ -551,20 +113,28 @@
   }
   void test_getPrefixes() {
     AnalysisContext context = new AnalysisContextImpl();
-    LibraryElementImpl library17 = ElementFactory.library(context, "l1");
+    LibraryElementImpl library18 = ElementFactory.library(context, "l1");
     PrefixElement prefixA = new PrefixElementImpl(ASTFactory.identifier2("a"));
     PrefixElement prefixB = new PrefixElementImpl(ASTFactory.identifier2("b"));
     List<ImportElementImpl> imports = [ElementFactory.importFor(ElementFactory.library(context, "l2"), null, []), ElementFactory.importFor(ElementFactory.library(context, "l3"), null, []), ElementFactory.importFor(ElementFactory.library(context, "l4"), prefixA, []), ElementFactory.importFor(ElementFactory.library(context, "l5"), prefixA, []), ElementFactory.importFor(ElementFactory.library(context, "l6"), prefixB, [])];
-    library17.imports = imports;
-    List<PrefixElement> prefixes2 = library17.prefixes;
+    library18.imports = imports;
+    List<PrefixElement> prefixes2 = library18.prefixes;
     EngineTestCase.assertLength(2, prefixes2);
     if (identical(prefixA, prefixes2[0])) {
-      JUnitTestCase.assertEquals(prefixB, prefixes2[1]);
+      JUnitTestCase.assertSame(prefixB, prefixes2[1]);
     } else {
-      JUnitTestCase.assertEquals(prefixB, prefixes2[0]);
-      JUnitTestCase.assertEquals(prefixA, prefixes2[1]);
+      JUnitTestCase.assertSame(prefixB, prefixes2[0]);
+      JUnitTestCase.assertSame(prefixA, prefixes2[1]);
     }
   }
+  void test_isUpToDate() {
+    AnalysisContext context = new AnalysisContextImpl();
+    context.sourceFactory = new SourceFactory.con2([]);
+    LibraryElement library19 = ElementFactory.library(context, "foo");
+    context.sourceFactory.setContents(library19.definingCompilationUnit.source, "sdfsdff");
+    JUnitTestCase.assertFalse(library19.isUpToDate2(0));
+    JUnitTestCase.assertTrue(library19.isUpToDate2(JavaSystem.currentTimeMillis() + 1000));
+  }
   void test_setImports() {
     AnalysisContext context = new AnalysisContextImpl();
     LibraryElementImpl library = new LibraryElementImpl(context, ASTFactory.libraryIdentifier2(["l1"]));
@@ -573,7 +143,7 @@
     List<ImportElement> actualImports = library.imports;
     EngineTestCase.assertLength(expectedImports.length, actualImports);
     for (int i = 0; i < actualImports.length; i++) {
-      JUnitTestCase.assertEquals(expectedImports[i], actualImports[i]);
+      JUnitTestCase.assertSame(expectedImports[i], actualImports[i]);
     }
   }
   static dartSuite() {
@@ -590,6 +160,10 @@
         final __test = new LibraryElementImplTest();
         runJUnitTest(__test, __test.test_getPrefixes);
       });
+      _ut.test('test_isUpToDate', () {
+        final __test = new LibraryElementImplTest();
+        runJUnitTest(__test, __test.test_isUpToDate);
+      });
       _ut.test('test_setImports', () {
         final __test = new LibraryElementImplTest();
         runJUnitTest(__test, __test.test_setImports);
@@ -597,254 +171,13 @@
     });
   }
 }
-/**
- * The class {@code ElementFactory} defines utility methods used to create elements for testing
- * purposes.
- */
-class ElementFactory {
-  /**
-   * The element representing the class 'Object'.
-   */
-  static ClassElement _objectElement;
-  static ClassElement classElement(String typeName, InterfaceType superclassType, List<String> parameterNames) {
-    ClassElementImpl element = new ClassElementImpl(ASTFactory.identifier2(typeName));
-    element.supertype = superclassType;
-    InterfaceTypeImpl type = new InterfaceTypeImpl.con1(element);
-    element.type = type;
-    int count = parameterNames.length;
-    if (count > 0) {
-      List<TypeVariableElementImpl> typeVariables = new List<TypeVariableElementImpl>(count);
-      List<TypeVariableTypeImpl> typeArguments = new List<TypeVariableTypeImpl>(count);
-      for (int i = 0; i < count; i++) {
-        TypeVariableElementImpl variable = new TypeVariableElementImpl(ASTFactory.identifier2(parameterNames[i]));
-        typeVariables[i] = variable;
-        typeArguments[i] = new TypeVariableTypeImpl(variable);
-        variable.type = typeArguments[i];
-      }
-      element.typeVariables = typeVariables;
-      type.typeArguments = typeArguments;
-    }
-    return element;
-  }
-  static ClassElement classElement2(String typeName, List<String> parameterNames) => classElement(typeName, object.type, parameterNames);
-  static ConstructorElement constructorElement(String name) => new ConstructorElementImpl(name == null ? null : ASTFactory.identifier2(name));
-  static FieldElement fieldElement(String name, bool isStatic, bool isFinal, bool isConst, Type2 type27) {
-    FieldElementImpl field = new FieldElementImpl.con1(ASTFactory.identifier2(name));
-    field.const2 = isConst;
-    field.final2 = isFinal;
-    field.static = isStatic;
-    field.type = type27;
-    PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con1(field);
-    getter.getter = true;
-    getter.synthetic = true;
-    field.getter = getter;
-    FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter);
-    getterType.returnType = type27;
-    getter.type = getterType;
-    if (!isConst && !isFinal) {
-      PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con1(field);
-      setter.setter = true;
-      setter.synthetic = true;
-      field.setter = setter;
-      FunctionTypeImpl setterType = new FunctionTypeImpl.con1(getter);
-      setterType.normalParameterTypes = <Type2> [type27];
-      setterType.returnType = VoidTypeImpl.instance;
-      setter.type = setterType;
-    }
-    return field;
-  }
-  static FunctionElement functionElement(String functionName) => functionElement4(functionName, null, null, null, null);
-  static FunctionElement functionElement2(String functionName, ClassElement returnElement) => functionElement3(functionName, returnElement, null, null);
-  static FunctionElement functionElement3(String functionName, ClassElement returnElement, List<ClassElement> normalParameters, List<ClassElement> optionalParameters) {
-    FunctionElementImpl functionElement = new FunctionElementImpl.con1(ASTFactory.identifier2(functionName));
-    FunctionTypeImpl functionType = new FunctionTypeImpl.con1(functionElement);
-    functionElement.type = functionType;
-    if (returnElement != null) {
-      functionType.returnType = returnElement.type;
-    }
-    int count = normalParameters == null ? 0 : normalParameters.length;
-    if (count > 0) {
-      List<InterfaceType> normalParameterTypes = new List<InterfaceType>(count);
-      for (int i = 0; i < count; i++) {
-        normalParameterTypes[i] = normalParameters[i].type;
-      }
-      functionType.normalParameterTypes = normalParameterTypes;
-    }
-    count = optionalParameters == null ? 0 : optionalParameters.length;
-    if (count > 0) {
-      List<InterfaceType> optionalParameterTypes = new List<InterfaceType>(count);
-      for (int i = 0; i < count; i++) {
-        optionalParameterTypes[i] = optionalParameters[i].type;
-      }
-      functionType.optionalParameterTypes = optionalParameterTypes;
-    }
-    return functionElement;
-  }
-  static FunctionElement functionElement4(String functionName, ClassElement returnElement, List<ClassElement> normalParameters, List<String> names, List<ClassElement> namedParameters) {
-    FunctionElementImpl functionElement = new FunctionElementImpl.con1(ASTFactory.identifier2(functionName));
-    FunctionTypeImpl functionType = new FunctionTypeImpl.con1(functionElement);
-    functionElement.type = functionType;
-    if (returnElement != null) {
-      functionType.returnType = returnElement.type;
-    }
-    int count = normalParameters == null ? 0 : normalParameters.length;
-    if (count > 0) {
-      List<InterfaceType> normalParameterTypes = new List<InterfaceType>(count);
-      for (int i = 0; i < count; i++) {
-        normalParameterTypes[i] = normalParameters[i].type;
-      }
-      functionType.normalParameterTypes = normalParameterTypes;
-    }
-    if (names != null && names.length > 0 && names.length == namedParameters.length) {
-      LinkedHashMap<String, Type2> map = new LinkedHashMap<String, Type2>();
-      for (int i = 0; i < names.length; i++) {
-        map[names[i]] = namedParameters[i].type;
-      }
-      functionType.namedParameterTypes = map;
-    } else if (names != null) {
-      throw new IllegalStateException("The passed String[] and ClassElement[] arrays had different lengths.");
-    }
-    return functionElement;
-  }
-  static FunctionElement functionElement5(String functionName, List<ClassElement> normalParameters) => functionElement3(functionName, null, normalParameters, null);
-  static FunctionElement functionElement6(String functionName, List<ClassElement> normalParameters, List<ClassElement> optionalParameters) => functionElement3(functionName, null, normalParameters, optionalParameters);
-  static FunctionElement functionElement7(String functionName, List<ClassElement> normalParameters, List<String> names, List<ClassElement> namedParameters) => functionElement4(functionName, null, normalParameters, names, namedParameters);
-  static ClassElement get object {
-    if (_objectElement == null) {
-      _objectElement = classElement("Object", (null as InterfaceType), []);
-    }
-    return _objectElement;
-  }
-  static PropertyAccessorElement getterElement(String name, bool isStatic, Type2 type28) {
-    FieldElementImpl field = new FieldElementImpl.con1(ASTFactory.identifier2(name));
-    field.static = isStatic;
-    field.synthetic = true;
-    field.type = type28;
-    PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con1(field);
-    getter.getter = true;
-    field.getter = getter;
-    FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter);
-    getterType.returnType = type28;
-    getter.type = getterType;
-    return getter;
-  }
-  static ImportElementImpl importFor(LibraryElement importedLibrary4, PrefixElement prefix12, List<NamespaceCombinator> combinators4) {
-    ImportElementImpl spec = new ImportElementImpl();
-    spec.importedLibrary = importedLibrary4;
-    spec.prefix = prefix12;
-    spec.combinators = combinators4;
-    return spec;
-  }
-  static LibraryElementImpl library(AnalysisContext context, String libraryName) {
-    String fileName = "${libraryName}.dart";
-    FileBasedSource source = new FileBasedSource.con1(null, createFile(fileName));
-    CompilationUnitElementImpl unit = new CompilationUnitElementImpl(fileName);
-    unit.source = source;
-    LibraryElementImpl library = new LibraryElementImpl(context, ASTFactory.libraryIdentifier2([libraryName]));
-    library.definingCompilationUnit = unit;
-    return library;
-  }
-  static MethodElement methodElement(String methodName, Type2 returnType9, List<Type2> argumentTypes) {
-    MethodElementImpl method = new MethodElementImpl.con1(ASTFactory.identifier2(methodName));
-    int count = argumentTypes.length;
-    List<ParameterElement> parameters = new List<ParameterElement>(count);
-    for (int i = 0; i < count; i++) {
-      ParameterElementImpl parameter = new ParameterElementImpl(ASTFactory.identifier2("a${i}"));
-      parameter.type = argumentTypes[i];
-      parameters[i] = parameter;
-    }
-    method.parameters = parameters;
-    FunctionTypeImpl methodType = new FunctionTypeImpl.con1(method);
-    methodType.normalParameterTypes = argumentTypes;
-    methodType.returnType = returnType9;
-    method.type = methodType;
-    return method;
-  }
-  static PropertyAccessorElement setterElement(String name, bool isStatic, Type2 type29) {
-    FieldElementImpl field = new FieldElementImpl.con1(ASTFactory.identifier2(name));
-    field.static = isStatic;
-    field.synthetic = true;
-    field.type = type29;
-    PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con1(field);
-    getter.getter = true;
-    field.getter = getter;
-    FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter);
-    getterType.returnType = type29;
-    getter.type = getterType;
-    PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con1(field);
-    setter.setter = true;
-    setter.synthetic = true;
-    field.setter = setter;
-    FunctionTypeImpl setterType = new FunctionTypeImpl.con1(getter);
-    setterType.normalParameterTypes = <Type2> [type29];
-    setterType.returnType = VoidTypeImpl.instance;
-    setter.type = setterType;
-    return setter;
-  }
-  static VariableElement variableElement(String name) => new VariableElementImpl.con2(name, -1);
-  /**
-   * Prevent the creation of instances of this class.
-   */
-  ElementFactory() {
-  }
-}
-class ElementImplTest extends EngineTestCase {
-  void test_isAccessibleIn_private_differentLibrary() {
-    AnalysisContextImpl context = new AnalysisContextImpl();
-    LibraryElementImpl library1 = ElementFactory.library(context, "lib1");
-    ClassElement classElement = ElementFactory.classElement2("_C", []);
-    ((library1.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classElement];
-    LibraryElementImpl library2 = ElementFactory.library(context, "lib2");
-    JUnitTestCase.assertFalse(classElement.isAccessibleIn(library2));
-  }
-  void test_isAccessibleIn_private_sameLibrary() {
-    LibraryElementImpl library15 = ElementFactory.library(new AnalysisContextImpl(), "lib");
-    ClassElement classElement = ElementFactory.classElement2("_C", []);
-    ((library15.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classElement];
-    JUnitTestCase.assertTrue(classElement.isAccessibleIn(library15));
-  }
-  void test_isAccessibleIn_public_differentLibrary() {
-    AnalysisContextImpl context = new AnalysisContextImpl();
-    LibraryElementImpl library1 = ElementFactory.library(context, "lib1");
-    ClassElement classElement = ElementFactory.classElement2("C", []);
-    ((library1.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classElement];
-    LibraryElementImpl library2 = ElementFactory.library(context, "lib2");
-    JUnitTestCase.assertTrue(classElement.isAccessibleIn(library2));
-  }
-  void test_isAccessibleIn_public_sameLibrary() {
-    LibraryElementImpl library16 = ElementFactory.library(new AnalysisContextImpl(), "lib");
-    ClassElement classElement = ElementFactory.classElement2("C", []);
-    ((library16.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classElement];
-    JUnitTestCase.assertTrue(classElement.isAccessibleIn(library16));
-  }
-  static dartSuite() {
-    _ut.group('ElementImplTest', () {
-      _ut.test('test_isAccessibleIn_private_differentLibrary', () {
-        final __test = new ElementImplTest();
-        runJUnitTest(__test, __test.test_isAccessibleIn_private_differentLibrary);
-      });
-      _ut.test('test_isAccessibleIn_private_sameLibrary', () {
-        final __test = new ElementImplTest();
-        runJUnitTest(__test, __test.test_isAccessibleIn_private_sameLibrary);
-      });
-      _ut.test('test_isAccessibleIn_public_differentLibrary', () {
-        final __test = new ElementImplTest();
-        runJUnitTest(__test, __test.test_isAccessibleIn_public_differentLibrary);
-      });
-      _ut.test('test_isAccessibleIn_public_sameLibrary', () {
-        final __test = new ElementImplTest();
-        runJUnitTest(__test, __test.test_isAccessibleIn_public_sameLibrary);
-      });
-    });
-  }
-}
 class InterfaceTypeImplTest extends EngineTestCase {
   void test_computeLongestInheritancePathToObject_multipleInterfacePaths() {
-    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
-    ClassElementImpl elementB = (ElementFactory.classElement2("B", []) as ClassElementImpl);
-    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
-    ClassElementImpl elementD = (ElementFactory.classElement2("D", []) as ClassElementImpl);
-    ClassElementImpl elementE = (ElementFactory.classElement2("E", []) as ClassElementImpl);
+    ClassElementImpl elementA = ElementFactory.classElement2("A", []);
+    ClassElementImpl elementB = ElementFactory.classElement2("B", []);
+    ClassElementImpl elementC = ElementFactory.classElement2("C", []);
+    ClassElementImpl elementD = ElementFactory.classElement2("D", []);
+    ClassElementImpl elementE = ElementFactory.classElement2("E", []);
     elementB.interfaces = <InterfaceType> [elementA.type];
     elementC.interfaces = <InterfaceType> [elementA.type];
     elementD.interfaces = <InterfaceType> [elementC.type];
@@ -857,7 +190,7 @@
     ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
     ClassElement elementC = ElementFactory.classElement("C", elementA.type, []);
     ClassElement elementD = ElementFactory.classElement("D", elementC.type, []);
-    ClassElementImpl elementE = (ElementFactory.classElement("E", elementB.type, []) as ClassElementImpl);
+    ClassElementImpl elementE = ElementFactory.classElement("E", elementB.type, []);
     elementE.interfaces = <InterfaceType> [elementD.type];
     JUnitTestCase.assertEquals(2, InterfaceTypeImpl.computeLongestInheritancePathToObject(elementB.type));
     JUnitTestCase.assertEquals(4, InterfaceTypeImpl.computeLongestInheritancePathToObject(elementE.type));
@@ -868,9 +201,9 @@
     JUnitTestCase.assertEquals(0, InterfaceTypeImpl.computeLongestInheritancePathToObject(object));
   }
   void test_computeLongestInheritancePathToObject_singleInterfacePath() {
-    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
-    ClassElementImpl elementB = (ElementFactory.classElement2("B", []) as ClassElementImpl);
-    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    ClassElementImpl elementA = ElementFactory.classElement2("A", []);
+    ClassElementImpl elementB = ElementFactory.classElement2("B", []);
+    ClassElementImpl elementC = ElementFactory.classElement2("C", []);
     elementB.interfaces = <InterfaceType> [elementA.type];
     elementC.interfaces = <InterfaceType> [elementB.type];
     JUnitTestCase.assertEquals(1, InterfaceTypeImpl.computeLongestInheritancePathToObject(elementA.type));
@@ -886,11 +219,11 @@
     JUnitTestCase.assertEquals(3, InterfaceTypeImpl.computeLongestInheritancePathToObject(elementC.type));
   }
   void test_computeSuperinterfaceSet_multipleInterfacePaths() {
-    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
-    ClassElementImpl elementB = (ElementFactory.classElement2("B", []) as ClassElementImpl);
-    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
-    ClassElementImpl elementD = (ElementFactory.classElement2("D", []) as ClassElementImpl);
-    ClassElementImpl elementE = (ElementFactory.classElement2("E", []) as ClassElementImpl);
+    ClassElementImpl elementA = ElementFactory.classElement2("A", []);
+    ClassElementImpl elementB = ElementFactory.classElement2("B", []);
+    ClassElementImpl elementC = ElementFactory.classElement2("C", []);
+    ClassElementImpl elementD = ElementFactory.classElement2("D", []);
+    ClassElementImpl elementE = ElementFactory.classElement2("E", []);
     elementB.interfaces = <InterfaceType> [elementA.type];
     elementC.interfaces = <InterfaceType> [elementA.type];
     elementD.interfaces = <InterfaceType> [elementC.type];
@@ -915,7 +248,7 @@
     ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
     ClassElement elementC = ElementFactory.classElement("C", elementA.type, []);
     ClassElement elementD = ElementFactory.classElement("D", elementC.type, []);
-    ClassElementImpl elementE = (ElementFactory.classElement("E", elementB.type, []) as ClassElementImpl);
+    ClassElementImpl elementE = ElementFactory.classElement("E", elementB.type, []);
     elementE.interfaces = <InterfaceType> [elementD.type];
     Set<InterfaceType> superinterfacesOfD = InterfaceTypeImpl.computeSuperinterfaceSet(elementD.type);
     JUnitTestCase.assertNotNull(superinterfacesOfD);
@@ -933,9 +266,9 @@
     JUnitTestCase.assertEquals(5, superinterfacesOfE.length);
   }
   void test_computeSuperinterfaceSet_singleInterfacePath() {
-    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
-    ClassElementImpl elementB = (ElementFactory.classElement2("B", []) as ClassElementImpl);
-    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    ClassElementImpl elementA = ElementFactory.classElement2("A", []);
+    ClassElementImpl elementB = ElementFactory.classElement2("B", []);
+    ClassElementImpl elementC = ElementFactory.classElement2("C", []);
     elementB.interfaces = <InterfaceType> [elementA.type];
     elementC.interfaces = <InterfaceType> [elementB.type];
     Set<InterfaceType> superinterfacesOfA = InterfaceTypeImpl.computeSuperinterfaceSet(elementA.type);
@@ -983,9 +316,9 @@
     JUnitTestCase.assertEquals(typeElement, type.element);
   }
   void test_getLeastUpperBound_directInterfaceCase() {
-    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
-    ClassElementImpl elementB = (ElementFactory.classElement2("B", []) as ClassElementImpl);
-    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    ClassElementImpl elementA = ElementFactory.classElement2("A", []);
+    ClassElementImpl elementB = ElementFactory.classElement2("B", []);
+    ClassElementImpl elementC = ElementFactory.classElement2("C", []);
     InterfaceType typeA = elementA.type;
     InterfaceType typeB = elementB.type;
     InterfaceType typeC = elementC.type;
@@ -995,9 +328,9 @@
     JUnitTestCase.assertEquals(typeB, typeC.getLeastUpperBound(typeB));
   }
   void test_getLeastUpperBound_directSubclassCase() {
-    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
-    ClassElementImpl elementB = (ElementFactory.classElement("B", elementA.type, []) as ClassElementImpl);
-    ClassElementImpl elementC = (ElementFactory.classElement("C", elementB.type, []) as ClassElementImpl);
+    ClassElementImpl elementA = ElementFactory.classElement2("A", []);
+    ClassElementImpl elementB = ElementFactory.classElement("B", elementA.type, []);
+    ClassElementImpl elementC = ElementFactory.classElement("C", elementB.type, []);
     InterfaceType typeB = elementB.type;
     InterfaceType typeC = elementC.type;
     JUnitTestCase.assertEquals(typeB, typeB.getLeastUpperBound(typeC));
@@ -1012,7 +345,7 @@
     ClassElement elementA = ElementFactory.classElement2("A", []);
     ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
     ClassElement elementC = ElementFactory.classElement("C", elementA.type, []);
-    ClassElementImpl elementD = (ElementFactory.classElement("D", elementB.type, []) as ClassElementImpl);
+    ClassElementImpl elementD = ElementFactory.classElement("D", elementB.type, []);
     InterfaceType typeA = elementA.type;
     InterfaceType typeC = elementC.type;
     InterfaceType typeD = elementD.type;
@@ -1025,8 +358,8 @@
     JUnitTestCase.assertNull(interfaceType.getLeastUpperBound(null));
   }
   void test_getLeastUpperBound_object() {
-    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
-    ClassElementImpl elementB = (ElementFactory.classElement2("B", []) as ClassElementImpl);
+    ClassElementImpl elementA = ElementFactory.classElement2("A", []);
+    ClassElementImpl elementB = ElementFactory.classElement2("B", []);
     InterfaceType typeA = elementA.type;
     InterfaceType typeB = elementB.type;
     Type2 typeObject = typeA.element.supertype;
@@ -1040,9 +373,9 @@
     JUnitTestCase.assertEquals(typeA, typeA.getLeastUpperBound(typeA));
   }
   void test_getLeastUpperBound_sharedSuperclass1() {
-    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
-    ClassElementImpl elementB = (ElementFactory.classElement("B", elementA.type, []) as ClassElementImpl);
-    ClassElementImpl elementC = (ElementFactory.classElement("C", elementA.type, []) as ClassElementImpl);
+    ClassElementImpl elementA = ElementFactory.classElement2("A", []);
+    ClassElementImpl elementB = ElementFactory.classElement("B", elementA.type, []);
+    ClassElementImpl elementC = ElementFactory.classElement("C", elementA.type, []);
     InterfaceType typeA = elementA.type;
     InterfaceType typeB = elementB.type;
     InterfaceType typeC = elementC.type;
@@ -1050,10 +383,10 @@
     JUnitTestCase.assertEquals(typeA, typeC.getLeastUpperBound(typeB));
   }
   void test_getLeastUpperBound_sharedSuperclass2() {
-    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
-    ClassElementImpl elementB = (ElementFactory.classElement("B", elementA.type, []) as ClassElementImpl);
-    ClassElementImpl elementC = (ElementFactory.classElement("C", elementA.type, []) as ClassElementImpl);
-    ClassElementImpl elementD = (ElementFactory.classElement("D", elementC.type, []) as ClassElementImpl);
+    ClassElementImpl elementA = ElementFactory.classElement2("A", []);
+    ClassElementImpl elementB = ElementFactory.classElement("B", elementA.type, []);
+    ClassElementImpl elementC = ElementFactory.classElement("C", elementA.type, []);
+    ClassElementImpl elementD = ElementFactory.classElement("D", elementC.type, []);
     InterfaceType typeA = elementA.type;
     InterfaceType typeB = elementB.type;
     InterfaceType typeD = elementD.type;
@@ -1061,10 +394,10 @@
     JUnitTestCase.assertEquals(typeA, typeD.getLeastUpperBound(typeB));
   }
   void test_getLeastUpperBound_sharedSuperclass3() {
-    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
-    ClassElementImpl elementB = (ElementFactory.classElement("B", elementA.type, []) as ClassElementImpl);
-    ClassElementImpl elementC = (ElementFactory.classElement("C", elementB.type, []) as ClassElementImpl);
-    ClassElementImpl elementD = (ElementFactory.classElement("D", elementB.type, []) as ClassElementImpl);
+    ClassElementImpl elementA = ElementFactory.classElement2("A", []);
+    ClassElementImpl elementB = ElementFactory.classElement("B", elementA.type, []);
+    ClassElementImpl elementC = ElementFactory.classElement("C", elementB.type, []);
+    ClassElementImpl elementD = ElementFactory.classElement("D", elementB.type, []);
     InterfaceType typeB = elementB.type;
     InterfaceType typeC = elementC.type;
     InterfaceType typeD = elementD.type;
@@ -1075,8 +408,8 @@
     ClassElement elementA = ElementFactory.classElement2("A", []);
     ClassElement elementA2 = ElementFactory.classElement2("A2", []);
     ClassElement elementA3 = ElementFactory.classElement2("A3", []);
-    ClassElementImpl elementB = (ElementFactory.classElement("B", elementA.type, []) as ClassElementImpl);
-    ClassElementImpl elementC = (ElementFactory.classElement("C", elementA.type, []) as ClassElementImpl);
+    ClassElementImpl elementB = ElementFactory.classElement("B", elementA.type, []);
+    ClassElementImpl elementC = ElementFactory.classElement("C", elementA.type, []);
     InterfaceType typeA = elementA.type;
     InterfaceType typeA2 = elementA2.type;
     InterfaceType typeA3 = elementA3.type;
@@ -1088,9 +421,9 @@
     JUnitTestCase.assertEquals(typeA, typeC.getLeastUpperBound(typeB));
   }
   void test_getLeastUpperBound_sharedSuperinterface1() {
-    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
-    ClassElementImpl elementB = (ElementFactory.classElement2("B", []) as ClassElementImpl);
-    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    ClassElementImpl elementA = ElementFactory.classElement2("A", []);
+    ClassElementImpl elementB = ElementFactory.classElement2("B", []);
+    ClassElementImpl elementC = ElementFactory.classElement2("C", []);
     InterfaceType typeA = elementA.type;
     InterfaceType typeB = elementB.type;
     InterfaceType typeC = elementC.type;
@@ -1100,10 +433,10 @@
     JUnitTestCase.assertEquals(typeA, typeC.getLeastUpperBound(typeB));
   }
   void test_getLeastUpperBound_sharedSuperinterface2() {
-    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
-    ClassElementImpl elementB = (ElementFactory.classElement2("B", []) as ClassElementImpl);
-    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
-    ClassElementImpl elementD = (ElementFactory.classElement2("D", []) as ClassElementImpl);
+    ClassElementImpl elementA = ElementFactory.classElement2("A", []);
+    ClassElementImpl elementB = ElementFactory.classElement2("B", []);
+    ClassElementImpl elementC = ElementFactory.classElement2("C", []);
+    ClassElementImpl elementD = ElementFactory.classElement2("D", []);
     InterfaceType typeA = elementA.type;
     InterfaceType typeB = elementB.type;
     InterfaceType typeC = elementC.type;
@@ -1115,10 +448,10 @@
     JUnitTestCase.assertEquals(typeA, typeD.getLeastUpperBound(typeB));
   }
   void test_getLeastUpperBound_sharedSuperinterface3() {
-    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
-    ClassElementImpl elementB = (ElementFactory.classElement2("B", []) as ClassElementImpl);
-    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
-    ClassElementImpl elementD = (ElementFactory.classElement2("D", []) as ClassElementImpl);
+    ClassElementImpl elementA = ElementFactory.classElement2("A", []);
+    ClassElementImpl elementB = ElementFactory.classElement2("B", []);
+    ClassElementImpl elementC = ElementFactory.classElement2("C", []);
+    ClassElementImpl elementD = ElementFactory.classElement2("D", []);
     InterfaceType typeA = elementA.type;
     InterfaceType typeB = elementB.type;
     InterfaceType typeC = elementC.type;
@@ -1133,8 +466,8 @@
     ClassElement elementA = ElementFactory.classElement2("A", []);
     ClassElement elementA2 = ElementFactory.classElement2("A2", []);
     ClassElement elementA3 = ElementFactory.classElement2("A3", []);
-    ClassElementImpl elementB = (ElementFactory.classElement2("B", []) as ClassElementImpl);
-    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    ClassElementImpl elementB = ElementFactory.classElement2("B", []);
+    ClassElementImpl elementC = ElementFactory.classElement2("C", []);
     InterfaceType typeA = elementA.type;
     InterfaceType typeA2 = elementA2.type;
     InterfaceType typeA3 = elementA3.type;
@@ -1165,24 +498,24 @@
     JUnitTestCase.assertFalse(typeA.isDirectSupertypeOf(typeC));
   }
   void test_isDirectSupertypeOf_implements() {
-    ClassElement elementA = ElementFactory.classElement2("A", []);
-    ClassElement elementB = ElementFactory.classElement2("B", []);
-    ((elementB as ClassElementImpl)).interfaces = <InterfaceType> [elementA.type];
+    ClassElementImpl elementA = ElementFactory.classElement2("A", []);
+    ClassElementImpl elementB = ElementFactory.classElement2("B", []);
+    elementB.interfaces = <InterfaceType> [elementA.type];
     InterfaceTypeImpl typeA = new InterfaceTypeImpl.con1(elementA);
     InterfaceTypeImpl typeB = new InterfaceTypeImpl.con1(elementB);
     JUnitTestCase.assertTrue(typeA.isDirectSupertypeOf(typeB));
   }
   void test_isDirectSupertypeOf_with() {
-    ClassElement elementA = ElementFactory.classElement2("A", []);
-    ClassElement elementB = ElementFactory.classElement2("B", []);
-    ((elementB as ClassElementImpl)).mixins = <InterfaceType> [elementA.type];
+    ClassElementImpl elementA = ElementFactory.classElement2("A", []);
+    ClassElementImpl elementB = ElementFactory.classElement2("B", []);
+    elementB.mixins = <InterfaceType> [elementA.type];
     InterfaceTypeImpl typeA = new InterfaceTypeImpl.con1(elementA);
     InterfaceTypeImpl typeB = new InterfaceTypeImpl.con1(elementB);
     JUnitTestCase.assertTrue(typeA.isDirectSupertypeOf(typeB));
   }
   void test_isMoreSpecificThan_bottom() {
-    Type2 type19 = ElementFactory.classElement2("A", []).type;
-    JUnitTestCase.assertTrue(BottomTypeImpl.instance.isMoreSpecificThan(type19));
+    Type2 type25 = ElementFactory.classElement2("A", []).type;
+    JUnitTestCase.assertTrue(BottomTypeImpl.instance.isMoreSpecificThan(type25));
   }
   void test_isMoreSpecificThan_covariance() {
     ClassElement elementA = ElementFactory.classElement2("A", ["E"]);
@@ -1204,8 +537,8 @@
     JUnitTestCase.assertFalse(typeA.isMoreSpecificThan(typeB));
   }
   void test_isMoreSpecificThan_dynamic() {
-    InterfaceType type20 = ElementFactory.classElement2("A", []).type;
-    JUnitTestCase.assertTrue(type20.isMoreSpecificThan(DynamicTypeImpl.instance));
+    InterfaceType type26 = ElementFactory.classElement2("A", []).type;
+    JUnitTestCase.assertTrue(type26.isMoreSpecificThan(DynamicTypeImpl.instance));
   }
   void test_isMoreSpecificThan_indirectSupertype() {
     ClassElement elementA = ElementFactory.classElement2("A", []);
@@ -1216,8 +549,8 @@
     JUnitTestCase.assertTrue(typeC.isMoreSpecificThan(typeA));
   }
   void test_isMoreSpecificThan_self() {
-    InterfaceType type21 = ElementFactory.classElement2("A", []).type;
-    JUnitTestCase.assertTrue(type21.isMoreSpecificThan(type21));
+    InterfaceType type27 = ElementFactory.classElement2("A", []).type;
+    JUnitTestCase.assertTrue(type27.isMoreSpecificThan(type27));
   }
   void test_isSubtypeOf_directSubtype() {
     ClassElement elementA = ElementFactory.classElement2("A", []);
@@ -1246,7 +579,7 @@
   void test_isSubtypeOf_interface() {
     ClassElement elementA = ElementFactory.classElement2("A", []);
     ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
-    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    ClassElementImpl elementC = ElementFactory.classElement2("C", []);
     InterfaceType typeObject = elementA.supertype;
     InterfaceType typeA = elementA.type;
     InterfaceType typeB = elementB.type;
@@ -1260,7 +593,7 @@
   void test_isSubtypeOf_mixins() {
     ClassElement elementA = ElementFactory.classElement2("A", []);
     ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
-    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    ClassElementImpl elementC = ElementFactory.classElement2("C", []);
     InterfaceType typeObject = elementA.supertype;
     InterfaceType typeA = elementA.type;
     InterfaceType typeB = elementB.type;
@@ -1332,7 +665,7 @@
   void test_isSupertypeOf_interface() {
     ClassElement elementA = ElementFactory.classElement2("A", []);
     ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
-    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    ClassElementImpl elementC = ElementFactory.classElement2("C", []);
     InterfaceType typeObject = elementA.supertype;
     InterfaceType typeA = elementA.type;
     InterfaceType typeB = elementB.type;
@@ -1346,7 +679,7 @@
   void test_isSupertypeOf_mixins() {
     ClassElement elementA = ElementFactory.classElement2("A", []);
     ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
-    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    ClassElementImpl elementC = ElementFactory.classElement2("C", []);
     InterfaceType typeObject = elementA.supertype;
     InterfaceType typeA = elementA.type;
     InterfaceType typeB = elementB.type;
@@ -1370,10 +703,10 @@
     JUnitTestCase.assertTrue(typeA.isSupertypeOf(typeA));
   }
   void test_setTypeArguments() {
-    InterfaceTypeImpl type22 = (ElementFactory.classElement2("A", []).type as InterfaceTypeImpl);
+    InterfaceTypeImpl type28 = ElementFactory.classElement2("A", []).type as InterfaceTypeImpl;
     List<Type2> typeArguments = <Type2> [new InterfaceTypeImpl.con1(ElementFactory.classElement2("B", [])), new InterfaceTypeImpl.con1(ElementFactory.classElement2("C", []))];
-    type22.typeArguments = typeArguments;
-    JUnitTestCase.assertEquals(typeArguments, type22.typeArguments);
+    type28.typeArguments = typeArguments;
+    JUnitTestCase.assertEquals(typeArguments, type28.typeArguments);
   }
   void test_substitute_equal() {
     ClassElementImpl classElement = new ClassElementImpl(ASTFactory.identifier2("A"));
@@ -1627,11 +960,272 @@
     });
   }
 }
+class TypeVariableTypeImplTest extends EngineTestCase {
+  void test_creation() {
+    JUnitTestCase.assertNotNull(new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier2("E"))));
+  }
+  void test_getElement() {
+    TypeVariableElementImpl element = new TypeVariableElementImpl(ASTFactory.identifier2("E"));
+    TypeVariableTypeImpl type = new TypeVariableTypeImpl(element);
+    JUnitTestCase.assertEquals(element, type.element);
+  }
+  void test_substitute_equal() {
+    TypeVariableElementImpl element = new TypeVariableElementImpl(ASTFactory.identifier2("E"));
+    TypeVariableTypeImpl type = new TypeVariableTypeImpl(element);
+    InterfaceTypeImpl argument = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("A")));
+    TypeVariableTypeImpl parameter = new TypeVariableTypeImpl(element);
+    JUnitTestCase.assertSame(argument, type.substitute2(<Type2> [argument], <Type2> [parameter]));
+  }
+  void test_substitute_notEqual() {
+    TypeVariableTypeImpl type = new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier2("E")));
+    InterfaceTypeImpl argument = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("A")));
+    TypeVariableTypeImpl parameter = new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier2("F")));
+    JUnitTestCase.assertSame(type, type.substitute2(<Type2> [argument], <Type2> [parameter]));
+  }
+  static dartSuite() {
+    _ut.group('TypeVariableTypeImplTest', () {
+      _ut.test('test_creation', () {
+        final __test = new TypeVariableTypeImplTest();
+        runJUnitTest(__test, __test.test_creation);
+      });
+      _ut.test('test_getElement', () {
+        final __test = new TypeVariableTypeImplTest();
+        runJUnitTest(__test, __test.test_getElement);
+      });
+      _ut.test('test_substitute_equal', () {
+        final __test = new TypeVariableTypeImplTest();
+        runJUnitTest(__test, __test.test_substitute_equal);
+      });
+      _ut.test('test_substitute_notEqual', () {
+        final __test = new TypeVariableTypeImplTest();
+        runJUnitTest(__test, __test.test_substitute_notEqual);
+      });
+    });
+  }
+}
+/**
+ * The class {@code ElementFactory} defines utility methods used to create elements for testing
+ * purposes. The elements that are created are complete in the sense that as much of the element
+ * model as can be created, given the provided information, has been created.
+ */
+class ElementFactory {
+  /**
+   * The element representing the class 'Object'.
+   */
+  static ClassElementImpl _objectElement;
+  static ClassElementImpl classElement(String typeName, InterfaceType superclassType, List<String> parameterNames) {
+    ClassElementImpl element = new ClassElementImpl(ASTFactory.identifier2(typeName));
+    element.supertype = superclassType;
+    InterfaceTypeImpl type = new InterfaceTypeImpl.con1(element);
+    element.type = type;
+    int count = parameterNames.length;
+    if (count > 0) {
+      List<TypeVariableElementImpl> typeVariables = new List<TypeVariableElementImpl>(count);
+      List<TypeVariableTypeImpl> typeArguments = new List<TypeVariableTypeImpl>(count);
+      for (int i = 0; i < count; i++) {
+        TypeVariableElementImpl variable = new TypeVariableElementImpl(ASTFactory.identifier2(parameterNames[i]));
+        typeVariables[i] = variable;
+        typeArguments[i] = new TypeVariableTypeImpl(variable);
+        variable.type = typeArguments[i];
+      }
+      element.typeVariables = typeVariables;
+      type.typeArguments = typeArguments;
+    }
+    return element;
+  }
+  static ClassElementImpl classElement2(String typeName, List<String> parameterNames) => classElement(typeName, object.type, parameterNames);
+  static ConstructorElementImpl constructorElement(String name) => new ConstructorElementImpl(name == null ? null : ASTFactory.identifier2(name));
+  static ExportElementImpl exportFor(LibraryElement exportedLibrary4, List<NamespaceCombinator> combinators4) {
+    ExportElementImpl spec = new ExportElementImpl();
+    spec.exportedLibrary = exportedLibrary4;
+    spec.combinators = combinators4;
+    return spec;
+  }
+  static FieldElementImpl fieldElement(String name, bool isStatic, bool isFinal, bool isConst, Type2 type34) {
+    FieldElementImpl field = new FieldElementImpl.con1(ASTFactory.identifier2(name));
+    field.const3 = isConst;
+    field.final2 = isFinal;
+    field.static = isStatic;
+    field.type = type34;
+    PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con2(field);
+    getter.getter = true;
+    getter.synthetic = true;
+    field.getter = getter;
+    FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter);
+    getterType.returnType = type34;
+    getter.type = getterType;
+    if (!isConst && !isFinal) {
+      PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con2(field);
+      setter.setter = true;
+      setter.synthetic = true;
+      field.setter = setter;
+      FunctionTypeImpl setterType = new FunctionTypeImpl.con1(getter);
+      setterType.normalParameterTypes = <Type2> [type34];
+      setterType.returnType = VoidTypeImpl.instance;
+      setter.type = setterType;
+    }
+    return field;
+  }
+  static FunctionElementImpl functionElement(String functionName) => functionElement4(functionName, null, null, null, null);
+  static FunctionElementImpl functionElement2(String functionName, ClassElement returnElement) => functionElement3(functionName, returnElement, null, null);
+  static FunctionElementImpl functionElement3(String functionName, ClassElement returnElement, List<ClassElement> normalParameters, List<ClassElement> optionalParameters) {
+    FunctionElementImpl functionElement = new FunctionElementImpl.con1(ASTFactory.identifier2(functionName));
+    FunctionTypeImpl functionType = new FunctionTypeImpl.con1(functionElement);
+    functionElement.type = functionType;
+    if (returnElement != null) {
+      functionType.returnType = returnElement.type;
+    }
+    int count = normalParameters == null ? 0 : normalParameters.length;
+    if (count > 0) {
+      List<InterfaceType> normalParameterTypes = new List<InterfaceType>(count);
+      for (int i = 0; i < count; i++) {
+        normalParameterTypes[i] = normalParameters[i].type;
+      }
+      functionType.normalParameterTypes = normalParameterTypes;
+    }
+    count = optionalParameters == null ? 0 : optionalParameters.length;
+    if (count > 0) {
+      List<InterfaceType> optionalParameterTypes = new List<InterfaceType>(count);
+      for (int i = 0; i < count; i++) {
+        optionalParameterTypes[i] = optionalParameters[i].type;
+      }
+      functionType.optionalParameterTypes = optionalParameterTypes;
+    }
+    return functionElement;
+  }
+  static FunctionElementImpl functionElement4(String functionName, ClassElement returnElement, List<ClassElement> normalParameters, List<String> names, List<ClassElement> namedParameters) {
+    FunctionElementImpl functionElement = new FunctionElementImpl.con1(ASTFactory.identifier2(functionName));
+    FunctionTypeImpl functionType = new FunctionTypeImpl.con1(functionElement);
+    functionElement.type = functionType;
+    if (returnElement != null) {
+      functionType.returnType = returnElement.type;
+    }
+    int count = normalParameters == null ? 0 : normalParameters.length;
+    if (count > 0) {
+      List<InterfaceType> normalParameterTypes = new List<InterfaceType>(count);
+      for (int i = 0; i < count; i++) {
+        normalParameterTypes[i] = normalParameters[i].type;
+      }
+      functionType.normalParameterTypes = normalParameterTypes;
+    }
+    if (names != null && names.length > 0 && names.length == namedParameters.length) {
+      LinkedHashMap<String, Type2> map = new LinkedHashMap<String, Type2>();
+      for (int i = 0; i < names.length; i++) {
+        map[names[i]] = namedParameters[i].type;
+      }
+      functionType.namedParameterTypes = map;
+    } else if (names != null) {
+      throw new IllegalStateException("The passed String[] and ClassElement[] arrays had different lengths.");
+    }
+    return functionElement;
+  }
+  static FunctionElementImpl functionElement5(String functionName, List<ClassElement> normalParameters) => functionElement3(functionName, null, normalParameters, null);
+  static FunctionElementImpl functionElement6(String functionName, List<ClassElement> normalParameters, List<ClassElement> optionalParameters) => functionElement3(functionName, null, normalParameters, optionalParameters);
+  static FunctionElementImpl functionElement7(String functionName, List<ClassElement> normalParameters, List<String> names, List<ClassElement> namedParameters) => functionElement4(functionName, null, normalParameters, names, namedParameters);
+  static ClassElementImpl get object {
+    if (_objectElement == null) {
+      _objectElement = classElement("Object", (null as InterfaceType), []);
+    }
+    return _objectElement;
+  }
+  static PropertyAccessorElementImpl getterElement(String name, bool isStatic, Type2 type35) {
+    FieldElementImpl field = new FieldElementImpl.con1(ASTFactory.identifier2(name));
+    field.static = isStatic;
+    field.synthetic = true;
+    field.type = type35;
+    PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con2(field);
+    getter.getter = true;
+    field.getter = getter;
+    FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter);
+    getterType.returnType = type35;
+    getter.type = getterType;
+    return getter;
+  }
+  static ImportElementImpl importFor(LibraryElement importedLibrary5, PrefixElement prefix13, List<NamespaceCombinator> combinators5) {
+    ImportElementImpl spec = new ImportElementImpl();
+    spec.importedLibrary = importedLibrary5;
+    spec.prefix = prefix13;
+    spec.combinators = combinators5;
+    return spec;
+  }
+  static LibraryElementImpl library(AnalysisContext context, String libraryName) {
+    String fileName = "${libraryName}.dart";
+    FileBasedSource source = new FileBasedSource.con1(context.sourceFactory, FileUtilities2.createFile(fileName));
+    CompilationUnitElementImpl unit = new CompilationUnitElementImpl(fileName);
+    unit.source = source;
+    LibraryElementImpl library = new LibraryElementImpl(context, ASTFactory.libraryIdentifier2([libraryName]));
+    library.definingCompilationUnit = unit;
+    return library;
+  }
+  static LocalVariableElementImpl localVariableElement(Identifier name) => new LocalVariableElementImpl(name);
+  static LocalVariableElementImpl localVariableElement2(String name) => new LocalVariableElementImpl(ASTFactory.identifier2(name));
+  static MethodElementImpl methodElement(String methodName, Type2 returnType13, List<Type2> argumentTypes) {
+    MethodElementImpl method = new MethodElementImpl.con1(ASTFactory.identifier2(methodName));
+    int count = argumentTypes.length;
+    List<ParameterElement> parameters = new List<ParameterElement>(count);
+    for (int i = 0; i < count; i++) {
+      ParameterElementImpl parameter = new ParameterElementImpl(ASTFactory.identifier2("a${i}"));
+      parameter.type = argumentTypes[i];
+      parameter.parameterKind = ParameterKind.REQUIRED;
+      parameters[i] = parameter;
+    }
+    method.parameters = parameters;
+    FunctionTypeImpl methodType = new FunctionTypeImpl.con1(method);
+    methodType.normalParameterTypes = argumentTypes;
+    methodType.returnType = returnType13;
+    method.type = methodType;
+    return method;
+  }
+  static ParameterElementImpl namedParameter(String name) {
+    ParameterElementImpl parameter = new ParameterElementImpl(ASTFactory.identifier2(name));
+    parameter.parameterKind = ParameterKind.NAMED;
+    return parameter;
+  }
+  static ParameterElementImpl positionalParameter(String name) {
+    ParameterElementImpl parameter = new ParameterElementImpl(ASTFactory.identifier2(name));
+    parameter.parameterKind = ParameterKind.POSITIONAL;
+    return parameter;
+  }
+  static PrefixElementImpl prefix(String name) => new PrefixElementImpl(ASTFactory.identifier2(name));
+  static ParameterElementImpl requiredParameter(String name) {
+    ParameterElementImpl parameter = new ParameterElementImpl(ASTFactory.identifier2(name));
+    parameter.parameterKind = ParameterKind.REQUIRED;
+    return parameter;
+  }
+  static PropertyAccessorElementImpl setterElement(String name, bool isStatic, Type2 type36) {
+    FieldElementImpl field = new FieldElementImpl.con1(ASTFactory.identifier2(name));
+    field.static = isStatic;
+    field.synthetic = true;
+    field.type = type36;
+    PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con2(field);
+    getter.getter = true;
+    field.getter = getter;
+    FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter);
+    getterType.returnType = type36;
+    getter.type = getterType;
+    PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con2(field);
+    setter.setter = true;
+    setter.synthetic = true;
+    field.setter = setter;
+    FunctionTypeImpl setterType = new FunctionTypeImpl.con1(getter);
+    setterType.normalParameterTypes = <Type2> [type36];
+    setterType.returnType = VoidTypeImpl.instance;
+    setter.type = setterType;
+    return setter;
+  }
+  static TopLevelVariableElementImpl topLevelVariableElement(Identifier name) => new TopLevelVariableElementImpl.con1(name);
+  static TopLevelVariableElementImpl topLevelVariableElement2(String name) => new TopLevelVariableElementImpl.con2(name);
+  /**
+   * Prevent the creation of instances of this class.
+   */
+  ElementFactory() {
+  }
+}
 class ClassElementImplTest extends EngineTestCase {
   void test_allSupertypes_interface() {
     ClassElement elementA = ElementFactory.classElement2("A", []);
     ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
-    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    ClassElementImpl elementC = ElementFactory.classElement2("C", []);
     InterfaceType typeObject = elementA.supertype;
     InterfaceType typeA = elementA.type;
     InterfaceType typeB = elementB.type;
@@ -1648,7 +1242,7 @@
   void test_allSupertypes_mixins() {
     ClassElement elementA = ElementFactory.classElement2("A", []);
     ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
-    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    ClassElementImpl elementC = ElementFactory.classElement2("C", []);
     InterfaceType typeObject = elementA.supertype;
     InterfaceType typeA = elementA.type;
     InterfaceType typeB = elementB.type;
@@ -1664,7 +1258,7 @@
   }
   void test_lookUpGetter_declared() {
     LibraryElementImpl library6 = ElementFactory.library(new AnalysisContextImpl(), "lib");
-    ClassElementImpl classA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
     String getterName = "g";
     PropertyAccessorElement getter = ElementFactory.getterElement(getterName, false, null);
     classA.accessors = <PropertyAccessorElement> [getter];
@@ -1673,23 +1267,23 @@
   }
   void test_lookUpGetter_inherited() {
     LibraryElementImpl library7 = ElementFactory.library(new AnalysisContextImpl(), "lib");
-    ClassElementImpl classA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
     String getterName = "g";
     PropertyAccessorElement getter = ElementFactory.getterElement(getterName, false, null);
     classA.accessors = <PropertyAccessorElement> [getter];
-    ClassElementImpl classB = (ElementFactory.classElement("B", classA.type, []) as ClassElementImpl);
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type, []);
     ((library7.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classA, classB];
     JUnitTestCase.assertSame(getter, classB.lookUpGetter(getterName, library7));
   }
   void test_lookUpGetter_undeclared() {
     LibraryElementImpl library8 = ElementFactory.library(new AnalysisContextImpl(), "lib");
-    ClassElementImpl classA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
     ((library8.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classA];
     JUnitTestCase.assertNull(classA.lookUpGetter("g", library8));
   }
   void test_lookUpMethod_declared() {
     LibraryElementImpl library9 = ElementFactory.library(new AnalysisContextImpl(), "lib");
-    ClassElementImpl classA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
     String methodName = "m";
     MethodElement method = ElementFactory.methodElement(methodName, null, []);
     classA.methods = <MethodElement> [method];
@@ -1698,23 +1292,23 @@
   }
   void test_lookUpMethod_inherited() {
     LibraryElementImpl library10 = ElementFactory.library(new AnalysisContextImpl(), "lib");
-    ClassElementImpl classA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
     String methodName = "m";
     MethodElement method = ElementFactory.methodElement(methodName, null, []);
     classA.methods = <MethodElement> [method];
-    ClassElementImpl classB = (ElementFactory.classElement("B", classA.type, []) as ClassElementImpl);
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type, []);
     ((library10.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classA, classB];
     JUnitTestCase.assertSame(method, classB.lookUpMethod(methodName, library10));
   }
   void test_lookUpMethod_undeclared() {
     LibraryElementImpl library11 = ElementFactory.library(new AnalysisContextImpl(), "lib");
-    ClassElementImpl classA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
     ((library11.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classA];
     JUnitTestCase.assertNull(classA.lookUpMethod("m", library11));
   }
   void test_lookUpSetter_declared() {
     LibraryElementImpl library12 = ElementFactory.library(new AnalysisContextImpl(), "lib");
-    ClassElementImpl classA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
     String setterName = "s";
     PropertyAccessorElement setter = ElementFactory.setterElement(setterName, false, null);
     classA.accessors = <PropertyAccessorElement> [setter];
@@ -1723,17 +1317,17 @@
   }
   void test_lookUpSetter_inherited() {
     LibraryElementImpl library13 = ElementFactory.library(new AnalysisContextImpl(), "lib");
-    ClassElementImpl classA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
     String setterName = "s";
     PropertyAccessorElement setter = ElementFactory.setterElement(setterName, false, null);
     classA.accessors = <PropertyAccessorElement> [setter];
-    ClassElementImpl classB = (ElementFactory.classElement("B", classA.type, []) as ClassElementImpl);
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type, []);
     ((library13.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classA, classB];
     JUnitTestCase.assertSame(setter, classB.lookUpSetter(setterName, library13));
   }
   void test_lookUpSetter_undeclared() {
     LibraryElementImpl library14 = ElementFactory.library(new AnalysisContextImpl(), "lib");
-    ClassElementImpl classA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
     ((library14.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classA];
     JUnitTestCase.assertNull(classA.lookUpSetter("s", library14));
   }
@@ -1786,55 +1380,532 @@
     });
   }
 }
-class TypeVariableTypeImplTest extends EngineTestCase {
-  void test_creation() {
-    JUnitTestCase.assertNotNull(new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier2("E"))));
+class ElementImplTest extends EngineTestCase {
+  void test_equals() {
+    LibraryElementImpl library15 = ElementFactory.library(new AnalysisContextImpl(), "lib");
+    ClassElementImpl classElement = ElementFactory.classElement2("C", []);
+    ((library15.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classElement];
+    FieldElement field = ElementFactory.fieldElement("next", false, false, false, classElement.type);
+    classElement.fields = <FieldElement> [field];
+    JUnitTestCase.assertTrue(field == field);
+    JUnitTestCase.assertFalse(field == field.getter);
+    JUnitTestCase.assertFalse(field == field.setter);
+    JUnitTestCase.assertFalse(field.getter == field.setter);
   }
-  void test_getElement() {
-    TypeVariableElementImpl element = new TypeVariableElementImpl(ASTFactory.identifier2("E"));
-    TypeVariableTypeImpl type = new TypeVariableTypeImpl(element);
-    JUnitTestCase.assertEquals(element, type.element);
+  void test_isAccessibleIn_private_differentLibrary() {
+    AnalysisContextImpl context = new AnalysisContextImpl();
+    LibraryElementImpl library1 = ElementFactory.library(context, "lib1");
+    ClassElement classElement = ElementFactory.classElement2("_C", []);
+    ((library1.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classElement];
+    LibraryElementImpl library2 = ElementFactory.library(context, "lib2");
+    JUnitTestCase.assertFalse(classElement.isAccessibleIn(library2));
   }
-  void test_substitute_equal() {
-    TypeVariableElementImpl element = new TypeVariableElementImpl(ASTFactory.identifier2("E"));
-    TypeVariableTypeImpl type = new TypeVariableTypeImpl(element);
-    InterfaceTypeImpl argument = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("A")));
-    TypeVariableTypeImpl parameter = new TypeVariableTypeImpl(element);
-    JUnitTestCase.assertSame(argument, type.substitute2(<Type2> [argument], <Type2> [parameter]));
+  void test_isAccessibleIn_private_sameLibrary() {
+    LibraryElementImpl library16 = ElementFactory.library(new AnalysisContextImpl(), "lib");
+    ClassElement classElement = ElementFactory.classElement2("_C", []);
+    ((library16.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classElement];
+    JUnitTestCase.assertTrue(classElement.isAccessibleIn(library16));
   }
-  void test_substitute_notEqual() {
-    TypeVariableTypeImpl type = new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier2("E")));
-    InterfaceTypeImpl argument = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("A")));
-    TypeVariableTypeImpl parameter = new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier2("F")));
-    JUnitTestCase.assertSame(type, type.substitute2(<Type2> [argument], <Type2> [parameter]));
+  void test_isAccessibleIn_public_differentLibrary() {
+    AnalysisContextImpl context = new AnalysisContextImpl();
+    LibraryElementImpl library1 = ElementFactory.library(context, "lib1");
+    ClassElement classElement = ElementFactory.classElement2("C", []);
+    ((library1.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classElement];
+    LibraryElementImpl library2 = ElementFactory.library(context, "lib2");
+    JUnitTestCase.assertTrue(classElement.isAccessibleIn(library2));
+  }
+  void test_isAccessibleIn_public_sameLibrary() {
+    LibraryElementImpl library17 = ElementFactory.library(new AnalysisContextImpl(), "lib");
+    ClassElement classElement = ElementFactory.classElement2("C", []);
+    ((library17.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classElement];
+    JUnitTestCase.assertTrue(classElement.isAccessibleIn(library17));
   }
   static dartSuite() {
-    _ut.group('TypeVariableTypeImplTest', () {
-      _ut.test('test_creation', () {
-        final __test = new TypeVariableTypeImplTest();
-        runJUnitTest(__test, __test.test_creation);
+    _ut.group('ElementImplTest', () {
+      _ut.test('test_equals', () {
+        final __test = new ElementImplTest();
+        runJUnitTest(__test, __test.test_equals);
       });
-      _ut.test('test_getElement', () {
-        final __test = new TypeVariableTypeImplTest();
-        runJUnitTest(__test, __test.test_getElement);
+      _ut.test('test_isAccessibleIn_private_differentLibrary', () {
+        final __test = new ElementImplTest();
+        runJUnitTest(__test, __test.test_isAccessibleIn_private_differentLibrary);
       });
-      _ut.test('test_substitute_equal', () {
-        final __test = new TypeVariableTypeImplTest();
-        runJUnitTest(__test, __test.test_substitute_equal);
+      _ut.test('test_isAccessibleIn_private_sameLibrary', () {
+        final __test = new ElementImplTest();
+        runJUnitTest(__test, __test.test_isAccessibleIn_private_sameLibrary);
       });
-      _ut.test('test_substitute_notEqual', () {
-        final __test = new TypeVariableTypeImplTest();
-        runJUnitTest(__test, __test.test_substitute_notEqual);
+      _ut.test('test_isAccessibleIn_public_differentLibrary', () {
+        final __test = new ElementImplTest();
+        runJUnitTest(__test, __test.test_isAccessibleIn_public_differentLibrary);
+      });
+      _ut.test('test_isAccessibleIn_public_sameLibrary', () {
+        final __test = new ElementImplTest();
+        runJUnitTest(__test, __test.test_isAccessibleIn_public_sameLibrary);
       });
     });
   }
 }
+class FunctionTypeImplTest extends EngineTestCase {
+  void test_creation() {
+    JUnitTestCase.assertNotNull(new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f"))));
+  }
+  void test_getElement() {
+    FunctionElementImpl typeElement = new FunctionElementImpl.con1(ASTFactory.identifier2("f"));
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(typeElement);
+    JUnitTestCase.assertEquals(typeElement, type.element);
+  }
+  void test_getNamedParameterTypes() {
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
+    Map<String, Type2> types = type.namedParameterTypes;
+    EngineTestCase.assertSize2(0, types);
+  }
+  void test_getNormalParameterTypes() {
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
+    List<Type2> types = type.normalParameterTypes;
+    EngineTestCase.assertLength(0, types);
+  }
+  void test_getReturnType() {
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
+    Type2 returnType9 = type.returnType;
+    JUnitTestCase.assertEquals(VoidTypeImpl.instance, returnType9);
+  }
+  void test_getTypeArguments() {
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
+    List<Type2> types = type.typeArguments;
+    EngineTestCase.assertLength(0, types);
+  }
+  void test_hashCode_element() {
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
+    type.hashCode;
+  }
+  void test_hashCode_noElement() {
+    FunctionTypeImpl type = new FunctionTypeImpl.con1((null as ExecutableElement));
+    type.hashCode;
+  }
+  void test_isSubtypeOf_baseCase_classFunction() {
+    ClassElementImpl functionElement = ElementFactory.classElement2("Function", []);
+    InterfaceTypeImpl functionType = new InterfaceTypeImpl_12(functionElement);
+    FunctionType f = ElementFactory.functionElement("f").type;
+    JUnitTestCase.assertTrue(f.isSubtypeOf(functionType));
+  }
+  void test_isSubtypeOf_baseCase_notFunctionType() {
+    FunctionType f = ElementFactory.functionElement("f").type;
+    InterfaceType t = ElementFactory.classElement2("C", []).type;
+    JUnitTestCase.assertFalse(f.isSubtypeOf(t));
+  }
+  void test_isSubtypeOf_baseCase_null() {
+    FunctionType f = ElementFactory.functionElement("f").type;
+    JUnitTestCase.assertFalse(f.isSubtypeOf(null));
+  }
+  void test_isSubtypeOf_baseCase_self() {
+    FunctionType f = ElementFactory.functionElement("f").type;
+    JUnitTestCase.assertTrue(f.isSubtypeOf(f));
+  }
+  void test_isSubtypeOf_namedParameters_isAssignable() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["name"], <ClassElement> [a]).type;
+    FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["name"], <ClassElement> [b]).type;
+    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
+    JUnitTestCase.assertTrue(s.isSubtypeOf(t));
+  }
+  void test_isSubtypeOf_namedParameters_isNotAssignable() {
+    FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["name"], <ClassElement> [ElementFactory.classElement2("A", [])]).type;
+    FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["name"], <ClassElement> [ElementFactory.classElement2("B", [])]).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_namedParameters_namesDifferent() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["name"], <ClassElement> [a]).type;
+    FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["diff"], <ClassElement> [b]).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+    JUnitTestCase.assertFalse(s.isSubtypeOf(t));
+  }
+  void test_isSubtypeOf_namedParameters_orderOfParams() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["A", "B"], <ClassElement> [a, b]).type;
+    FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["B", "A"], <ClassElement> [b, a]).type;
+    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_namedParameters_orderOfParams2() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["B"], <ClassElement> [b]).type;
+    FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["B", "A"], <ClassElement> [b, a]).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_namedParameters_orderOfParams3() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["A", "B"], <ClassElement> [a, b]).type;
+    FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["B"], <ClassElement> [b]).type;
+    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_namedParameters_sHasMoreParams() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["name"], <ClassElement> [a]).type;
+    FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["name", "name2"], <ClassElement> [b, b]).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_namedParameters_tHasMoreParams() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["name", "name2"], <ClassElement> [a, a]).type;
+    FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["name"], <ClassElement> [b]).type;
+    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_normalParameters_isAssignable() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement5("t", <ClassElement> [a]).type;
+    FunctionType s = ElementFactory.functionElement5("s", <ClassElement> [b]).type;
+    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
+    JUnitTestCase.assertTrue(s.isSubtypeOf(t));
+  }
+  void test_isSubtypeOf_normalParameters_isNotAssignable() {
+    FunctionType t = ElementFactory.functionElement5("t", <ClassElement> [ElementFactory.classElement2("A", [])]).type;
+    FunctionType s = ElementFactory.functionElement5("s", <ClassElement> [ElementFactory.classElement2("B", [])]).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_normalParameters_sHasMoreParams() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement5("t", <ClassElement> [a]).type;
+    FunctionType s = ElementFactory.functionElement5("s", <ClassElement> [b, b]).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_normalParameters_tHasMoreParams() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement5("t", <ClassElement> [a, a]).type;
+    FunctionType s = ElementFactory.functionElement5("s", <ClassElement> [b]).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_optionalParameters_isAssignable() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement6("t", null, <ClassElement> [a]).type;
+    FunctionType s = ElementFactory.functionElement6("s", null, <ClassElement> [b]).type;
+    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
+    JUnitTestCase.assertTrue(s.isSubtypeOf(t));
+  }
+  void test_isSubtypeOf_optionalParameters_isNotAssignable() {
+    FunctionType t = ElementFactory.functionElement6("t", null, <ClassElement> [ElementFactory.classElement2("A", [])]).type;
+    FunctionType s = ElementFactory.functionElement6("s", null, <ClassElement> [ElementFactory.classElement2("B", [])]).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_optionalParameters_sHasMoreParams() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement6("t", null, <ClassElement> [a]).type;
+    FunctionType s = ElementFactory.functionElement6("s", null, <ClassElement> [b, b]).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_optionalParameters_tHasMoreParams() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement6("t", null, <ClassElement> [a, a]).type;
+    FunctionType s = ElementFactory.functionElement6("s", null, <ClassElement> [b]).type;
+    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_returnType_sIsVoid() {
+    FunctionType t = ElementFactory.functionElement2("t", ElementFactory.classElement2("A", [])).type;
+    FunctionType s = ElementFactory.functionElement("s").type;
+    JUnitTestCase.assertTrue(VoidTypeImpl.instance == s.returnType);
+    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_returnType_tAssignableToS() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement2("t", a).type;
+    FunctionType s = ElementFactory.functionElement2("s", b).type;
+    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
+    JUnitTestCase.assertTrue(s.isSubtypeOf(t));
+  }
+  void test_isSubtypeOf_returnType_tNotAssignableToS() {
+    FunctionType t = ElementFactory.functionElement2("t", ElementFactory.classElement2("A", [])).type;
+    FunctionType s = ElementFactory.functionElement2("s", ElementFactory.classElement2("B", [])).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_wrongFunctionType_normal_named() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    FunctionType t = ElementFactory.functionElement5("t", <ClassElement> [a]).type;
+    FunctionType s = ElementFactory.functionElement7("s", null, <String> ["name"], <ClassElement> [a]).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+    JUnitTestCase.assertFalse(s.isSubtypeOf(t));
+  }
+  void test_isSubtypeOf_wrongFunctionType_normal_optional() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    FunctionType t = ElementFactory.functionElement5("t", <ClassElement> [a]).type;
+    FunctionType s = ElementFactory.functionElement6("s", null, <ClassElement> [a]).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+    JUnitTestCase.assertFalse(s.isSubtypeOf(t));
+  }
+  void test_isSubtypeOf_wrongFunctionType_optional_named() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    FunctionType t = ElementFactory.functionElement6("t", null, <ClassElement> [a]).type;
+    FunctionType s = ElementFactory.functionElement7("s", null, <String> ["name"], <ClassElement> [a]).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+    JUnitTestCase.assertFalse(s.isSubtypeOf(t));
+  }
+  void test_setNamedParameterTypes() {
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
+    LinkedHashMap<String, Type2> expectedTypes = new LinkedHashMap<String, Type2>();
+    expectedTypes["a"] = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("C")));
+    type.namedParameterTypes = expectedTypes;
+    Map<String, Type2> types = type.namedParameterTypes;
+    JUnitTestCase.assertEquals(expectedTypes, types);
+  }
+  void test_setNormalParameterTypes() {
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
+    List<Type2> expectedTypes = <Type2> [new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("C")))];
+    type.normalParameterTypes = expectedTypes;
+    List<Type2> types = type.normalParameterTypes;
+    JUnitTestCase.assertEquals(expectedTypes, types);
+  }
+  void test_setReturnType() {
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
+    Type2 expectedType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("C")));
+    type.returnType = expectedType;
+    Type2 returnType10 = type.returnType;
+    JUnitTestCase.assertEquals(expectedType, returnType10);
+  }
+  void test_setTypeArguments() {
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
+    Type2 expectedType = new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier2("C")));
+    type.typeArguments = <Type2> [expectedType];
+    List<Type2> arguments = type.typeArguments;
+    EngineTestCase.assertLength(1, arguments);
+    JUnitTestCase.assertEquals(expectedType, arguments[0]);
+  }
+  void test_substitute2_equal() {
+    FunctionTypeImpl functionType = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
+    TypeVariableTypeImpl parameterType = new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier2("E")));
+    functionType.returnType = parameterType;
+    functionType.normalParameterTypes = <Type2> [parameterType];
+    functionType.optionalParameterTypes = <Type2> [parameterType];
+    LinkedHashMap<String, Type2> namedParameterTypes = new LinkedHashMap<String, Type2>();
+    String namedParameterName = "c";
+    namedParameterTypes[namedParameterName] = parameterType;
+    functionType.namedParameterTypes = namedParameterTypes;
+    InterfaceTypeImpl argumentType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("D")));
+    FunctionType result = functionType.substitute2(<Type2> [argumentType], <Type2> [parameterType]);
+    JUnitTestCase.assertEquals(argumentType, result.returnType);
+    List<Type2> normalParameters = result.normalParameterTypes;
+    EngineTestCase.assertLength(1, normalParameters);
+    JUnitTestCase.assertEquals(argumentType, normalParameters[0]);
+    List<Type2> optionalParameters = result.optionalParameterTypes;
+    EngineTestCase.assertLength(1, optionalParameters);
+    JUnitTestCase.assertEquals(argumentType, optionalParameters[0]);
+    Map<String, Type2> namedParameters = result.namedParameterTypes;
+    EngineTestCase.assertSize2(1, namedParameters);
+    JUnitTestCase.assertEquals(argumentType, namedParameters[namedParameterName]);
+  }
+  void test_substitute2_notEqual() {
+    FunctionTypeImpl functionType = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
+    Type2 returnType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("R")));
+    Type2 normalParameterType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("A")));
+    Type2 optionalParameterType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("B")));
+    Type2 namedParameterType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("C")));
+    functionType.returnType = returnType;
+    functionType.normalParameterTypes = <Type2> [normalParameterType];
+    functionType.optionalParameterTypes = <Type2> [optionalParameterType];
+    LinkedHashMap<String, Type2> namedParameterTypes = new LinkedHashMap<String, Type2>();
+    String namedParameterName = "c";
+    namedParameterTypes[namedParameterName] = namedParameterType;
+    functionType.namedParameterTypes = namedParameterTypes;
+    InterfaceTypeImpl argumentType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("D")));
+    TypeVariableTypeImpl parameterType = new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier2("E")));
+    FunctionType result = functionType.substitute2(<Type2> [argumentType], <Type2> [parameterType]);
+    JUnitTestCase.assertEquals(returnType, result.returnType);
+    List<Type2> normalParameters = result.normalParameterTypes;
+    EngineTestCase.assertLength(1, normalParameters);
+    JUnitTestCase.assertEquals(normalParameterType, normalParameters[0]);
+    List<Type2> optionalParameters = result.optionalParameterTypes;
+    EngineTestCase.assertLength(1, optionalParameters);
+    JUnitTestCase.assertEquals(optionalParameterType, optionalParameters[0]);
+    Map<String, Type2> namedParameters = result.namedParameterTypes;
+    EngineTestCase.assertSize2(1, namedParameters);
+    JUnitTestCase.assertEquals(namedParameterType, namedParameters[namedParameterName]);
+  }
+  static dartSuite() {
+    _ut.group('FunctionTypeImplTest', () {
+      _ut.test('test_creation', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_creation);
+      });
+      _ut.test('test_getElement', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_getElement);
+      });
+      _ut.test('test_getNamedParameterTypes', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_getNamedParameterTypes);
+      });
+      _ut.test('test_getNormalParameterTypes', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_getNormalParameterTypes);
+      });
+      _ut.test('test_getReturnType', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_getReturnType);
+      });
+      _ut.test('test_getTypeArguments', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_getTypeArguments);
+      });
+      _ut.test('test_hashCode_element', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_hashCode_element);
+      });
+      _ut.test('test_hashCode_noElement', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_hashCode_noElement);
+      });
+      _ut.test('test_isSubtypeOf_baseCase_classFunction', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_baseCase_classFunction);
+      });
+      _ut.test('test_isSubtypeOf_baseCase_notFunctionType', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_baseCase_notFunctionType);
+      });
+      _ut.test('test_isSubtypeOf_baseCase_null', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_baseCase_null);
+      });
+      _ut.test('test_isSubtypeOf_baseCase_self', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_baseCase_self);
+      });
+      _ut.test('test_isSubtypeOf_namedParameters_isAssignable', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_namedParameters_isAssignable);
+      });
+      _ut.test('test_isSubtypeOf_namedParameters_isNotAssignable', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_namedParameters_isNotAssignable);
+      });
+      _ut.test('test_isSubtypeOf_namedParameters_namesDifferent', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_namedParameters_namesDifferent);
+      });
+      _ut.test('test_isSubtypeOf_namedParameters_orderOfParams', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_namedParameters_orderOfParams);
+      });
+      _ut.test('test_isSubtypeOf_namedParameters_orderOfParams2', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_namedParameters_orderOfParams2);
+      });
+      _ut.test('test_isSubtypeOf_namedParameters_orderOfParams3', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_namedParameters_orderOfParams3);
+      });
+      _ut.test('test_isSubtypeOf_namedParameters_sHasMoreParams', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_namedParameters_sHasMoreParams);
+      });
+      _ut.test('test_isSubtypeOf_namedParameters_tHasMoreParams', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_namedParameters_tHasMoreParams);
+      });
+      _ut.test('test_isSubtypeOf_normalParameters_isAssignable', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_normalParameters_isAssignable);
+      });
+      _ut.test('test_isSubtypeOf_normalParameters_isNotAssignable', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_normalParameters_isNotAssignable);
+      });
+      _ut.test('test_isSubtypeOf_normalParameters_sHasMoreParams', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_normalParameters_sHasMoreParams);
+      });
+      _ut.test('test_isSubtypeOf_normalParameters_tHasMoreParams', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_normalParameters_tHasMoreParams);
+      });
+      _ut.test('test_isSubtypeOf_optionalParameters_isAssignable', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_optionalParameters_isAssignable);
+      });
+      _ut.test('test_isSubtypeOf_optionalParameters_isNotAssignable', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_optionalParameters_isNotAssignable);
+      });
+      _ut.test('test_isSubtypeOf_optionalParameters_sHasMoreParams', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_optionalParameters_sHasMoreParams);
+      });
+      _ut.test('test_isSubtypeOf_optionalParameters_tHasMoreParams', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_optionalParameters_tHasMoreParams);
+      });
+      _ut.test('test_isSubtypeOf_returnType_sIsVoid', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_returnType_sIsVoid);
+      });
+      _ut.test('test_isSubtypeOf_returnType_tAssignableToS', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_returnType_tAssignableToS);
+      });
+      _ut.test('test_isSubtypeOf_returnType_tNotAssignableToS', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_returnType_tNotAssignableToS);
+      });
+      _ut.test('test_isSubtypeOf_wrongFunctionType_normal_named', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_wrongFunctionType_normal_named);
+      });
+      _ut.test('test_isSubtypeOf_wrongFunctionType_normal_optional', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_wrongFunctionType_normal_optional);
+      });
+      _ut.test('test_isSubtypeOf_wrongFunctionType_optional_named', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_wrongFunctionType_optional_named);
+      });
+      _ut.test('test_setNamedParameterTypes', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_setNamedParameterTypes);
+      });
+      _ut.test('test_setNormalParameterTypes', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_setNormalParameterTypes);
+      });
+      _ut.test('test_setReturnType', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_setReturnType);
+      });
+      _ut.test('test_setTypeArguments', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_setTypeArguments);
+      });
+      _ut.test('test_substitute2_equal', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_substitute2_equal);
+      });
+      _ut.test('test_substitute2_notEqual', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_substitute2_notEqual);
+      });
+    });
+  }
+}
+class InterfaceTypeImpl_12 extends InterfaceTypeImpl {
+  InterfaceTypeImpl_12(ClassElement arg0) : super.con1(arg0);
+  bool isDartCoreFunction() => true;
+}
 main() {
+  FunctionTypeImplTest.dartSuite();
+  InterfaceTypeImplTest.dartSuite();
+  TypeVariableTypeImplTest.dartSuite();
   ClassElementImplTest.dartSuite();
   ElementLocationImplTest.dartSuite();
   ElementImplTest.dartSuite();
   LibraryElementImplTest.dartSuite();
-  FunctionTypeImplTest.dartSuite();
-  InterfaceTypeImplTest.dartSuite();
-  TypeVariableTypeImplTest.dartSuite();
 }
\ No newline at end of file
diff --git a/pkg/analyzer-experimental/test/generated/parser_test.dart b/pkg/analyzer_experimental/test/generated/parser_test.dart
similarity index 89%
rename from pkg/analyzer-experimental/test/generated/parser_test.dart
rename to pkg/analyzer_experimental/test/generated/parser_test.dart
index 421feee..41eae27 100644
--- a/pkg/analyzer-experimental/test/generated/parser_test.dart
+++ b/pkg/analyzer_experimental/test/generated/parser_test.dart
@@ -4,999 +4,19 @@
 library engine.parser_test;
 
 import 'dart:collection';
-import 'package:analyzer-experimental/src/generated/java_core.dart';
-import 'package:analyzer-experimental/src/generated/java_engine.dart';
-import 'package:analyzer-experimental/src/generated/java_junit.dart';
-import 'package:analyzer-experimental/src/generated/source.dart';
-import 'package:analyzer-experimental/src/generated/error.dart';
-import 'package:analyzer-experimental/src/generated/scanner.dart';
-import 'package:analyzer-experimental/src/generated/ast.dart';
-import 'package:analyzer-experimental/src/generated/parser.dart';
-import 'package:analyzer-experimental/src/generated/utilities_dart.dart';
+import 'package:analyzer_experimental/src/generated/java_core.dart';
+import 'package:analyzer_experimental/src/generated/java_engine.dart';
+import 'package:analyzer_experimental/src/generated/java_junit.dart';
+import 'package:analyzer_experimental/src/generated/source.dart';
+import 'package:analyzer_experimental/src/generated/error.dart';
+import 'package:analyzer_experimental/src/generated/scanner.dart';
+import 'package:analyzer_experimental/src/generated/ast.dart';
+import 'package:analyzer_experimental/src/generated/parser.dart';
+import 'package:analyzer_experimental/src/generated/utilities_dart.dart';
 import 'package:unittest/unittest.dart' as _ut;
 import 'test_support.dart';
 import 'scanner_test.dart' show TokenFactory;
 
-class ParserTestCase extends EngineTestCase {
-  /**
-   * An empty array of objects used as arguments to zero-argument methods.
-   */
-  static List<Object> _EMPTY_ARGUMENTS = new List<Object>(0);
-  /**
-   * Invoke a parse method in {@link Parser}. The method is assumed to have the given number and
-   * type of parameters and will be invoked with the given arguments.
-   * <p>
-   * The given source is scanned and the parser is initialized to start with the first token in the
-   * source before the parse method is invoked.
-   * @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
-   * @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 {@code null} or if any errors are produced
-   */
-  static Object parse(String methodName, List<Object> objects, String source) => parse3(methodName, objects, source, new List<AnalysisError>(0));
-  /**
-   * Invoke a parse method in {@link Parser}. The method is assumed to have the given number and
-   * type of parameters and will be invoked with the given arguments.
-   * <p>
-   * The given source is scanned and the parser is initialized to start with the first token in the
-   * source before the parse method is invoked.
-   * @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
-   * @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 {@code null} or the errors produced while
-   * scanning and parsing the source do not match the expected errors
-   */
-  static Object parse3(String methodName, List<Object> objects, String source, List<AnalysisError> errors) {
-    GatheringErrorListener listener = new GatheringErrorListener();
-    Object result = invokeParserMethod(methodName, objects, source, listener);
-    listener.assertErrors(errors);
-    return result;
-  }
-  /**
-   * Invoke a parse method in {@link Parser}. The method is assumed to have the given number and
-   * type of parameters and will be invoked with the given arguments.
-   * <p>
-   * The given source is scanned and the parser is initialized to start with the first token in the
-   * source before the parse method is invoked.
-   * @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
-   * @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 {@code null} or the errors produced while
-   * scanning and parsing the source do not match the expected errors
-   */
-  static Object parse4(String methodName, List<Object> objects, String source, List<ErrorCode> errorCodes) {
-    GatheringErrorListener listener = new GatheringErrorListener();
-    Object result = invokeParserMethod(methodName, objects, source, listener);
-    listener.assertErrors2(errorCodes);
-    return result;
-  }
-  /**
-   * Invoke a parse method in {@link Parser}. The method is assumed to have no arguments.
-   * <p>
-   * The given source is scanned and the parser is initialized to start with the first token in the
-   * source before the parse method is invoked.
-   * @param methodName the name of the parse method that should be invoked to parse the source
-   * @param source the source to be parsed by the parse method
-   * @param errorCodes the error codes of 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 {@code null} or the errors produced while
-   * scanning and parsing the source do not match the expected errors
-   */
-  static Object parse5(String methodName, String source, List<ErrorCode> errorCodes) => parse4(methodName, _EMPTY_ARGUMENTS, source, errorCodes);
-  /**
-   * Parse the given source as a compilation unit.
-   * @param source the source to be parsed
-   * @param errorCodes the error codes of the errors that are expected to be found
-   * @return the compilation unit that was parsed
-   * @throws Exception if the source could not be parsed, if the compilation errors in the source do
-   * not match those that are expected, or if the result would have been {@code null}
-   */
-  static CompilationUnit parseCompilationUnit(String source, List<ErrorCode> errorCodes) {
-    GatheringErrorListener listener = new GatheringErrorListener();
-    StringScanner scanner = new StringScanner(null, source, listener);
-    listener.setLineInfo(new TestSource(), scanner.lineStarts);
-    Token token = scanner.tokenize();
-    Parser parser = new Parser(null, listener);
-    CompilationUnit unit = parser.parseCompilationUnit(token);
-    JUnitTestCase.assertNotNull(unit);
-    listener.assertErrors2(errorCodes);
-    return unit;
-  }
-  /**
-   * Parse the given source as an expression.
-   * @param source the source to be parsed
-   * @param errorCodes the error codes of the errors that are expected to be found
-   * @return the expression that was parsed
-   * @throws Exception if the source could not be parsed, if the compilation errors in the source do
-   * not match those that are expected, or if the result would have been {@code null}
-   */
-  static Expression parseExpression(String source, List<ErrorCode> errorCodes) {
-    GatheringErrorListener listener = new GatheringErrorListener();
-    StringScanner scanner = new StringScanner(null, source, listener);
-    listener.setLineInfo(new TestSource(), scanner.lineStarts);
-    Token token = scanner.tokenize();
-    Parser parser = new Parser(null, listener);
-    Expression expression = parser.parseExpression(token);
-    JUnitTestCase.assertNotNull(expression);
-    listener.assertErrors2(errorCodes);
-    return (expression as Expression);
-  }
-  /**
-   * Parse the given source as a statement.
-   * @param source the source to be parsed
-   * @param errorCodes the error codes of the errors that are expected to be found
-   * @return the statement that was parsed
-   * @throws Exception if the source could not be parsed, if the compilation errors in the source do
-   * not match those that are expected, or if the result would have been {@code null}
-   */
-  static Statement parseStatement(String source, List<ErrorCode> errorCodes) {
-    GatheringErrorListener listener = new GatheringErrorListener();
-    StringScanner scanner = new StringScanner(null, source, listener);
-    listener.setLineInfo(new TestSource(), scanner.lineStarts);
-    Token token = scanner.tokenize();
-    Parser parser = new Parser(null, listener);
-    Statement statement = parser.parseStatement(token);
-    JUnitTestCase.assertNotNull(statement);
-    listener.assertErrors2(errorCodes);
-    return (statement as Statement);
-  }
-  /**
-   * Parse the given source as a sequence of statements.
-   * @param source the source to be parsed
-   * @param expectedCount the number of statements that are expected
-   * @param errorCodes the error codes of the errors that are expected to be found
-   * @return the statements that were parsed
-   * @throws Exception if the source could not be parsed, if the number of statements does not match
-   * the expected count, if the compilation errors in the source do not match those that
-   * are expected, or if the result would have been {@code null}
-   */
-  static List<Statement> parseStatements(String source, int expectedCount, List<ErrorCode> errorCodes) {
-    GatheringErrorListener listener = new GatheringErrorListener();
-    StringScanner scanner = new StringScanner(null, source, listener);
-    listener.setLineInfo(new TestSource(), scanner.lineStarts);
-    Token token = scanner.tokenize();
-    Parser parser = new Parser(null, listener);
-    List<Statement> statements = parser.parseStatements(token);
-    EngineTestCase.assertSize(expectedCount, statements);
-    listener.assertErrors2(errorCodes);
-    return statements;
-  }
-  /**
-   * Invoke a method in {@link Parser}. The method is assumed to have the given number and type of
-   * parameters and will be invoked with the given arguments.
-   * <p>
-   * The given source is scanned and the parser is initialized to start with the first token in the
-   * source before the method is invoked.
-   * @param methodName the name of the method that should be invoked
-   * @param objects the values of the arguments to the method
-   * @param source the source to be processed by the parse method
-   * @param listener the error listener that will be used for both scanning and parsing
-   * @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 {@code null} or the errors produced while
-   * scanning and parsing the source do not match the expected errors
-   */
-  static Object invokeParserMethod(String methodName, List<Object> objects, String source, GatheringErrorListener listener) {
-    StringScanner scanner = new StringScanner(null, source, listener);
-    Token tokenStream = scanner.tokenize();
-    listener.setLineInfo(new TestSource(), scanner.lineStarts);
-    Parser parser = new Parser(null, listener);
-    Object result = invokeParserMethodImpl(parser, methodName, objects, tokenStream);
-    JUnitTestCase.assertNotNull(result);
-    return (result as Object);
-  }
-  /**
-   * Invoke a method in {@link Parser}. The method is assumed to have no arguments.
-   * <p>
-   * The given source is scanned and the parser is initialized to start with the first token in the
-   * source before the method is invoked.
-   * @param methodName the name of the method that should be invoked
-   * @param source the source to be processed by the parse method
-   * @param listener the error listener that will be used for both scanning and parsing
-   * @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 {@code null} or the errors produced while
-   * scanning and parsing the source do not match the expected errors
-   */
-  static Object invokeParserMethod2(String methodName, String source, GatheringErrorListener listener) => invokeParserMethod(methodName, _EMPTY_ARGUMENTS, source, listener);
-  /**
-   * Return a CommentAndMetadata object with the given values that can be used for testing.
-   * @param comment the comment to be wrapped in the object
-   * @param annotations the annotations to be wrapped in the object
-   * @return a CommentAndMetadata object that can be used for testing
-   */
-  CommentAndMetadata commentAndMetadata(Comment comment, List<Annotation> annotations) {
-    List<Annotation> metadata = new List<Annotation>();
-    for (Annotation annotation in annotations) {
-      metadata.add(annotation);
-    }
-    return new CommentAndMetadata(comment, metadata);
-  }
-  /**
-   * Return an empty CommentAndMetadata object that can be used for testing.
-   * @return an empty CommentAndMetadata object that can be used for testing
-   */
-  CommentAndMetadata emptyCommentAndMetadata() => new CommentAndMetadata(null, new List<Annotation>());
-  static dartSuite() {
-    _ut.group('ParserTestCase', () {
-    });
-  }
-}
-/**
- * Instances of the class {@code ASTValidator} are used to validate the correct construction of an
- * AST structure.
- */
-class ASTValidator extends GeneralizingASTVisitor<Object> {
-  /**
-   * A list containing the errors found while traversing the AST structure.
-   */
-  List<String> _errors = new List<String>();
-  /**
-   * Assert that no errors were found while traversing any of the AST structures that have been
-   * visited.
-   */
-  void assertValid() {
-    if (!_errors.isEmpty) {
-      StringBuffer builder = new StringBuffer();
-      builder.add("Invalid AST structure:");
-      for (String message in _errors) {
-        builder.add("\r\n   ");
-        builder.add(message);
-      }
-      JUnitTestCase.fail(builder.toString());
-    }
-  }
-  Object visitNode(ASTNode node) {
-    validate(node);
-    return super.visitNode(node);
-  }
-  /**
-   * Validate that the given AST node is correctly constructed.
-   * @param node the AST node being validated
-   */
-  void validate(ASTNode node) {
-    ASTNode parent11 = node.parent;
-    if (node is CompilationUnit) {
-      if (parent11 != null) {
-        _errors.add("Compilation units should not have a parent");
-      }
-    } else {
-      if (parent11 == null) {
-        _errors.add("No parent for ${node.runtimeType.toString()}");
-      }
-    }
-    if (node.beginToken == null) {
-      _errors.add("No begin token for ${node.runtimeType.toString()}");
-    }
-    if (node.endToken == null) {
-      _errors.add("No end token for ${node.runtimeType.toString()}");
-    }
-    int nodeStart = node.offset;
-    int nodeLength = node.length;
-    if (nodeStart < 0 || nodeLength < 0) {
-      _errors.add("No source info for ${node.runtimeType.toString()}");
-    }
-    if (parent11 != null) {
-      int nodeEnd = nodeStart + nodeLength;
-      int parentStart = parent11.offset;
-      int parentEnd = parentStart + parent11.length;
-      if (nodeStart < parentStart) {
-        _errors.add("Invalid source start (${nodeStart}) for ${node.runtimeType.toString()} inside ${parent11.runtimeType.toString()} (${parentStart})");
-      }
-      if (nodeEnd > parentEnd) {
-        _errors.add("Invalid source end (${nodeEnd}) for ${node.runtimeType.toString()} inside ${parent11.runtimeType.toString()} (${parentStart})");
-      }
-    }
-  }
-}
-/**
- * The class {@code RecoveryParserTest} defines parser tests that test the parsing of invalid code
- * sequences to ensure that the correct recovery steps are taken in the parser.
- */
-class RecoveryParserTest extends ParserTestCase {
-  void test_additiveExpression_missing_LHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("+ y", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
-  }
-  void test_additiveExpression_missing_LHS_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("+", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_additiveExpression_missing_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x +", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_additiveExpression_missing_RHS_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression("super +", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_additiveExpression_precedence_multiplicative_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("* +", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
-    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
-  }
-  void test_additiveExpression_precedence_multiplicative_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("+ *", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
-    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
-  }
-  void test_additiveExpression_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression("super + +", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
-    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
-  }
-  void test_argumentDefinitionTest_missing_identifier() {
-    ArgumentDefinitionTest expression = ParserTestCase.parseExpression("?", [ParserErrorCode.MISSING_IDENTIFIER]);
-    JUnitTestCase.assertTrue(expression.identifier.isSynthetic());
-  }
-  void test_assignmentExpression_missing_compound1() {
-    AssignmentExpression expression = ParserTestCase.parseExpression("= y = 0", []);
-    Expression syntheticExpression = expression.leftHandSide;
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
-    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
-  }
-  void test_assignmentExpression_missing_compound2() {
-    AssignmentExpression expression = ParserTestCase.parseExpression("x = = 0", []);
-    Expression syntheticExpression = ((expression.rightHandSide as AssignmentExpression)).leftHandSide;
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
-    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
-  }
-  void test_assignmentExpression_missing_compound3() {
-    AssignmentExpression expression = ParserTestCase.parseExpression("x = y =", []);
-    Expression syntheticExpression = ((expression.rightHandSide as AssignmentExpression)).rightHandSide;
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
-    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
-  }
-  void test_assignmentExpression_missing_LHS() {
-    AssignmentExpression expression = ParserTestCase.parseExpression("= 0", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftHandSide);
-    JUnitTestCase.assertTrue(expression.leftHandSide.isSynthetic());
-  }
-  void test_assignmentExpression_missing_RHS() {
-    AssignmentExpression expression = ParserTestCase.parseExpression("x =", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftHandSide);
-    JUnitTestCase.assertTrue(expression.rightHandSide.isSynthetic());
-  }
-  void test_bitwiseAndExpression_missing_LHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("& y", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
-  }
-  void test_bitwiseAndExpression_missing_LHS_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("&", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_bitwiseAndExpression_missing_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x &", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_bitwiseAndExpression_missing_RHS_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression("super &", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_bitwiseAndExpression_precedence_equality_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("== &", []);
-    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
-  }
-  void test_bitwiseAndExpression_precedence_equality_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("& ==", []);
-    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
-  }
-  void test_bitwiseAndExpression_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression("super &  &", []);
-    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
-  }
-  void test_bitwiseOrExpression_missing_LHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("| y", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
-  }
-  void test_bitwiseOrExpression_missing_LHS_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("|", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_bitwiseOrExpression_missing_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x |", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_bitwiseOrExpression_missing_RHS_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression("super |", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_bitwiseOrExpression_precedence_xor_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("^ |", []);
-    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
-  }
-  void test_bitwiseOrExpression_precedence_xor_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("| ^", []);
-    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
-  }
-  void test_bitwiseOrExpression_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression("super |  |", []);
-    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
-  }
-  void test_bitwiseXorExpression_missing_LHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("^ y", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
-  }
-  void test_bitwiseXorExpression_missing_LHS_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("^", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_bitwiseXorExpression_missing_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x ^", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_bitwiseXorExpression_missing_RHS_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression("super ^", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_bitwiseXorExpression_precedence_and_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("& ^", []);
-    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
-  }
-  void test_bitwiseXorExpression_precedence_and_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("^ &", []);
-    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
-  }
-  void test_bitwiseXorExpression_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression("super ^  ^", []);
-    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
-  }
-  void test_conditionalExpression_missingElse() {
-    ConditionalExpression expression = ParserTestCase.parse5("parseConditionalExpression", "x ? y :", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.elseExpression);
-    JUnitTestCase.assertTrue(expression.elseExpression.isSynthetic());
-  }
-  void test_conditionalExpression_missingThen() {
-    ConditionalExpression expression = ParserTestCase.parse5("parseConditionalExpression", "x ? : z", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.thenExpression);
-    JUnitTestCase.assertTrue(expression.thenExpression.isSynthetic());
-  }
-  void test_equalityExpression_missing_LHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("== y", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
-  }
-  void test_equalityExpression_missing_LHS_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("==", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_equalityExpression_missing_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x ==", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_equalityExpression_missing_RHS_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression("super ==", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_equalityExpression_precedence_relational_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("is ==", [ParserErrorCode.MISSING_IDENTIFIER]);
-    EngineTestCase.assertInstanceOf(IsExpression, expression.leftOperand);
-  }
-  void test_equalityExpression_precedence_relational_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("== is", [ParserErrorCode.MISSING_IDENTIFIER]);
-    EngineTestCase.assertInstanceOf(IsExpression, expression.rightOperand);
-  }
-  void test_equalityExpression_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression("super ==  ==", []);
-    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
-  }
-  void test_expressionList_multiple_end() {
-    List<Expression> result = ParserTestCase.parse5("parseExpressionList", ", 2, 3, 4", []);
-    EngineTestCase.assertSize(4, result);
-    Expression syntheticExpression = result[0];
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
-    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
-  }
-  void test_expressionList_multiple_middle() {
-    List<Expression> result = ParserTestCase.parse5("parseExpressionList", "1, 2, , 4", []);
-    EngineTestCase.assertSize(4, result);
-    Expression syntheticExpression = result[2];
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
-    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
-  }
-  void test_expressionList_multiple_start() {
-    List<Expression> result = ParserTestCase.parse5("parseExpressionList", "1, 2, 3,", []);
-    EngineTestCase.assertSize(4, result);
-    Expression syntheticExpression = result[3];
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
-    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
-  }
-  void test_logicalAndExpression_missing_LHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("&& y", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
-  }
-  void test_logicalAndExpression_missing_LHS_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("&&", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_logicalAndExpression_missing_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x &&", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_logicalAndExpression_precedence_bitwiseOr_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("| &&", []);
-    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
-  }
-  void test_logicalAndExpression_precedence_bitwiseOr_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("&& |", []);
-    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
-  }
-  void test_logicalOrExpression_missing_LHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("|| y", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
-  }
-  void test_logicalOrExpression_missing_LHS_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("||", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_logicalOrExpression_missing_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x ||", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_logicalOrExpression_precedence_logicalAnd_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("&& ||", []);
-    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
-  }
-  void test_logicalOrExpression_precedence_logicalAnd_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("|| &&", []);
-    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
-  }
-  void test_multiplicativeExpression_missing_LHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("* y", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
-  }
-  void test_multiplicativeExpression_missing_LHS_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("*", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_multiplicativeExpression_missing_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x *", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_multiplicativeExpression_missing_RHS_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression("super *", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_multiplicativeExpression_precedence_unary_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("-x *", []);
-    EngineTestCase.assertInstanceOf(PrefixExpression, expression.leftOperand);
-  }
-  void test_multiplicativeExpression_precedence_unary_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("* -y", []);
-    EngineTestCase.assertInstanceOf(PrefixExpression, expression.rightOperand);
-  }
-  void test_multiplicativeExpression_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression("super ==  ==", []);
-    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
-  }
-  void test_prefixExpression_missing_operand_minus() {
-    PrefixExpression expression = ParserTestCase.parseExpression("-", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.operand);
-    JUnitTestCase.assertTrue(expression.operand.isSynthetic());
-    JUnitTestCase.assertEquals(TokenType.MINUS, expression.operator.type);
-  }
-  void test_relationalExpression_missing_LHS() {
-    IsExpression expression = ParserTestCase.parseExpression("is y", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.expression);
-    JUnitTestCase.assertTrue(expression.expression.isSynthetic());
-  }
-  void test_relationalExpression_missing_LHS_RHS() {
-    IsExpression expression = ParserTestCase.parseExpression("is", [ParserErrorCode.MISSING_IDENTIFIER]);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.expression);
-    JUnitTestCase.assertTrue(expression.expression.isSynthetic());
-    EngineTestCase.assertInstanceOf(TypeName, expression.type);
-    JUnitTestCase.assertTrue(expression.type.isSynthetic());
-  }
-  void test_relationalExpression_missing_RHS() {
-    IsExpression expression = ParserTestCase.parseExpression("x is", [ParserErrorCode.MISSING_IDENTIFIER]);
-    EngineTestCase.assertInstanceOf(TypeName, expression.type);
-    JUnitTestCase.assertTrue(expression.type.isSynthetic());
-  }
-  void test_relationalExpression_precedence_shift_right() {
-    IsExpression expression = ParserTestCase.parseExpression("<< is", [ParserErrorCode.MISSING_IDENTIFIER]);
-    EngineTestCase.assertInstanceOf(BinaryExpression, expression.expression);
-  }
-  void test_shiftExpression_missing_LHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("<< y", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
-  }
-  void test_shiftExpression_missing_LHS_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("<<", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_shiftExpression_missing_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x <<", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_shiftExpression_missing_RHS_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression("super <<", []);
-    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
-  }
-  void test_shiftExpression_precedence_unary_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("+ <<", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
-    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
-  }
-  void test_shiftExpression_precedence_unary_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("<< +", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
-    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
-  }
-  void test_shiftExpression_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression("super << <<", []);
-    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
-  }
-  void test_topLevelExternalFunction_extraSemicolon() {
-    CompilationUnit unit = ParserTestCase.parseCompilationUnit("external void f(A a);", [ParserErrorCode.UNEXPECTED_TOKEN]);
-    NodeList<CompilationUnitMember> declarations3 = unit.declarations;
-    EngineTestCase.assertSize(1, declarations3);
-    FunctionDeclaration declaration = (declarations3[0] as FunctionDeclaration);
-    JUnitTestCase.assertNotNull(declaration);
-  }
-  static dartSuite() {
-    _ut.group('RecoveryParserTest', () {
-      _ut.test('test_additiveExpression_missing_LHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_additiveExpression_missing_LHS);
-      });
-      _ut.test('test_additiveExpression_missing_LHS_RHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_additiveExpression_missing_LHS_RHS);
-      });
-      _ut.test('test_additiveExpression_missing_RHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_additiveExpression_missing_RHS);
-      });
-      _ut.test('test_additiveExpression_missing_RHS_super', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_additiveExpression_missing_RHS_super);
-      });
-      _ut.test('test_additiveExpression_precedence_multiplicative_left', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_additiveExpression_precedence_multiplicative_left);
-      });
-      _ut.test('test_additiveExpression_precedence_multiplicative_right', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_additiveExpression_precedence_multiplicative_right);
-      });
-      _ut.test('test_additiveExpression_super', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_additiveExpression_super);
-      });
-      _ut.test('test_argumentDefinitionTest_missing_identifier', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_argumentDefinitionTest_missing_identifier);
-      });
-      _ut.test('test_assignmentExpression_missing_LHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_assignmentExpression_missing_LHS);
-      });
-      _ut.test('test_assignmentExpression_missing_RHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_assignmentExpression_missing_RHS);
-      });
-      _ut.test('test_assignmentExpression_missing_compound1', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_assignmentExpression_missing_compound1);
-      });
-      _ut.test('test_assignmentExpression_missing_compound2', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_assignmentExpression_missing_compound2);
-      });
-      _ut.test('test_assignmentExpression_missing_compound3', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_assignmentExpression_missing_compound3);
-      });
-      _ut.test('test_bitwiseAndExpression_missing_LHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_bitwiseAndExpression_missing_LHS);
-      });
-      _ut.test('test_bitwiseAndExpression_missing_LHS_RHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_bitwiseAndExpression_missing_LHS_RHS);
-      });
-      _ut.test('test_bitwiseAndExpression_missing_RHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_bitwiseAndExpression_missing_RHS);
-      });
-      _ut.test('test_bitwiseAndExpression_missing_RHS_super', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_bitwiseAndExpression_missing_RHS_super);
-      });
-      _ut.test('test_bitwiseAndExpression_precedence_equality_left', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_bitwiseAndExpression_precedence_equality_left);
-      });
-      _ut.test('test_bitwiseAndExpression_precedence_equality_right', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_bitwiseAndExpression_precedence_equality_right);
-      });
-      _ut.test('test_bitwiseAndExpression_super', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_bitwiseAndExpression_super);
-      });
-      _ut.test('test_bitwiseOrExpression_missing_LHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_bitwiseOrExpression_missing_LHS);
-      });
-      _ut.test('test_bitwiseOrExpression_missing_LHS_RHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_bitwiseOrExpression_missing_LHS_RHS);
-      });
-      _ut.test('test_bitwiseOrExpression_missing_RHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_bitwiseOrExpression_missing_RHS);
-      });
-      _ut.test('test_bitwiseOrExpression_missing_RHS_super', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_bitwiseOrExpression_missing_RHS_super);
-      });
-      _ut.test('test_bitwiseOrExpression_precedence_xor_left', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_bitwiseOrExpression_precedence_xor_left);
-      });
-      _ut.test('test_bitwiseOrExpression_precedence_xor_right', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_bitwiseOrExpression_precedence_xor_right);
-      });
-      _ut.test('test_bitwiseOrExpression_super', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_bitwiseOrExpression_super);
-      });
-      _ut.test('test_bitwiseXorExpression_missing_LHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_bitwiseXorExpression_missing_LHS);
-      });
-      _ut.test('test_bitwiseXorExpression_missing_LHS_RHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_bitwiseXorExpression_missing_LHS_RHS);
-      });
-      _ut.test('test_bitwiseXorExpression_missing_RHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_bitwiseXorExpression_missing_RHS);
-      });
-      _ut.test('test_bitwiseXorExpression_missing_RHS_super', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_bitwiseXorExpression_missing_RHS_super);
-      });
-      _ut.test('test_bitwiseXorExpression_precedence_and_left', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_bitwiseXorExpression_precedence_and_left);
-      });
-      _ut.test('test_bitwiseXorExpression_precedence_and_right', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_bitwiseXorExpression_precedence_and_right);
-      });
-      _ut.test('test_bitwiseXorExpression_super', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_bitwiseXorExpression_super);
-      });
-      _ut.test('test_conditionalExpression_missingElse', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_conditionalExpression_missingElse);
-      });
-      _ut.test('test_conditionalExpression_missingThen', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_conditionalExpression_missingThen);
-      });
-      _ut.test('test_equalityExpression_missing_LHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_equalityExpression_missing_LHS);
-      });
-      _ut.test('test_equalityExpression_missing_LHS_RHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_equalityExpression_missing_LHS_RHS);
-      });
-      _ut.test('test_equalityExpression_missing_RHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_equalityExpression_missing_RHS);
-      });
-      _ut.test('test_equalityExpression_missing_RHS_super', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_equalityExpression_missing_RHS_super);
-      });
-      _ut.test('test_equalityExpression_precedence_relational_left', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_equalityExpression_precedence_relational_left);
-      });
-      _ut.test('test_equalityExpression_precedence_relational_right', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_equalityExpression_precedence_relational_right);
-      });
-      _ut.test('test_equalityExpression_super', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_equalityExpression_super);
-      });
-      _ut.test('test_expressionList_multiple_end', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_expressionList_multiple_end);
-      });
-      _ut.test('test_expressionList_multiple_middle', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_expressionList_multiple_middle);
-      });
-      _ut.test('test_expressionList_multiple_start', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_expressionList_multiple_start);
-      });
-      _ut.test('test_logicalAndExpression_missing_LHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_logicalAndExpression_missing_LHS);
-      });
-      _ut.test('test_logicalAndExpression_missing_LHS_RHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_logicalAndExpression_missing_LHS_RHS);
-      });
-      _ut.test('test_logicalAndExpression_missing_RHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_logicalAndExpression_missing_RHS);
-      });
-      _ut.test('test_logicalAndExpression_precedence_bitwiseOr_left', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_logicalAndExpression_precedence_bitwiseOr_left);
-      });
-      _ut.test('test_logicalAndExpression_precedence_bitwiseOr_right', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_logicalAndExpression_precedence_bitwiseOr_right);
-      });
-      _ut.test('test_logicalOrExpression_missing_LHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_logicalOrExpression_missing_LHS);
-      });
-      _ut.test('test_logicalOrExpression_missing_LHS_RHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_logicalOrExpression_missing_LHS_RHS);
-      });
-      _ut.test('test_logicalOrExpression_missing_RHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_logicalOrExpression_missing_RHS);
-      });
-      _ut.test('test_logicalOrExpression_precedence_logicalAnd_left', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_logicalOrExpression_precedence_logicalAnd_left);
-      });
-      _ut.test('test_logicalOrExpression_precedence_logicalAnd_right', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_logicalOrExpression_precedence_logicalAnd_right);
-      });
-      _ut.test('test_multiplicativeExpression_missing_LHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_multiplicativeExpression_missing_LHS);
-      });
-      _ut.test('test_multiplicativeExpression_missing_LHS_RHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_multiplicativeExpression_missing_LHS_RHS);
-      });
-      _ut.test('test_multiplicativeExpression_missing_RHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_multiplicativeExpression_missing_RHS);
-      });
-      _ut.test('test_multiplicativeExpression_missing_RHS_super', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_multiplicativeExpression_missing_RHS_super);
-      });
-      _ut.test('test_multiplicativeExpression_precedence_unary_left', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_multiplicativeExpression_precedence_unary_left);
-      });
-      _ut.test('test_multiplicativeExpression_precedence_unary_right', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_multiplicativeExpression_precedence_unary_right);
-      });
-      _ut.test('test_multiplicativeExpression_super', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_multiplicativeExpression_super);
-      });
-      _ut.test('test_prefixExpression_missing_operand_minus', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_prefixExpression_missing_operand_minus);
-      });
-      _ut.test('test_relationalExpression_missing_LHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_relationalExpression_missing_LHS);
-      });
-      _ut.test('test_relationalExpression_missing_LHS_RHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_relationalExpression_missing_LHS_RHS);
-      });
-      _ut.test('test_relationalExpression_missing_RHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_relationalExpression_missing_RHS);
-      });
-      _ut.test('test_relationalExpression_precedence_shift_right', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_relationalExpression_precedence_shift_right);
-      });
-      _ut.test('test_shiftExpression_missing_LHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_shiftExpression_missing_LHS);
-      });
-      _ut.test('test_shiftExpression_missing_LHS_RHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_shiftExpression_missing_LHS_RHS);
-      });
-      _ut.test('test_shiftExpression_missing_RHS', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_shiftExpression_missing_RHS);
-      });
-      _ut.test('test_shiftExpression_missing_RHS_super', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_shiftExpression_missing_RHS_super);
-      });
-      _ut.test('test_shiftExpression_precedence_unary_left', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_shiftExpression_precedence_unary_left);
-      });
-      _ut.test('test_shiftExpression_precedence_unary_right', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_shiftExpression_precedence_unary_right);
-      });
-      _ut.test('test_shiftExpression_super', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_shiftExpression_super);
-      });
-      _ut.test('test_topLevelExternalFunction_extraSemicolon', () {
-        final __test = new RecoveryParserTest();
-        runJUnitTest(__test, __test.test_topLevelExternalFunction_extraSemicolon);
-      });
-    });
-  }
-}
 /**
  * The class {@code SimpleParserTest} defines parser tests that test individual parsing method. The
  * code fragments should be as minimal as possible in order to test the method, but should not test
@@ -1007,10 +27,10 @@
 class SimpleParserTest extends ParserTestCase {
   void fail_parseCommentReference_this() {
     CommentReference reference = ParserTestCase.parse("parseCommentReference", <Object> ["this", 5], "");
-    SimpleIdentifier identifier13 = EngineTestCase.assertInstanceOf(SimpleIdentifier, reference.identifier);
-    JUnitTestCase.assertNotNull(identifier13.token);
-    JUnitTestCase.assertEquals("a", identifier13.name);
-    JUnitTestCase.assertEquals(5, identifier13.offset);
+    SimpleIdentifier identifier19 = EngineTestCase.assertInstanceOf(SimpleIdentifier, reference.identifier);
+    JUnitTestCase.assertNotNull(identifier19.token);
+    JUnitTestCase.assertEquals("a", identifier19.name);
+    JUnitTestCase.assertEquals(5, identifier19.offset);
   }
   void test_computeStringValue_emptyInterpolationPrefix() {
     JUnitTestCase.assertEquals("", computeStringValue("'''"));
@@ -1180,21 +200,21 @@
     JUnitTestCase.assertFalse(isSwitchMember("break;"));
   }
   void test_parseAdditiveExpression_normal() {
-    BinaryExpression expression = ParserTestCase.parse5("parseAdditiveExpression", "x + y", []);
+    BinaryExpression expression = ParserTestCase.parse6("parseAdditiveExpression", "x + y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.PLUS, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseAdditiveExpression_super() {
-    BinaryExpression expression = ParserTestCase.parse5("parseAdditiveExpression", "super + y", []);
+    BinaryExpression expression = ParserTestCase.parse6("parseAdditiveExpression", "super + y", []);
     EngineTestCase.assertInstanceOf(SuperExpression, expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.PLUS, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseAnnotation_n1() {
-    Annotation annotation = ParserTestCase.parse5("parseAnnotation", "@A", []);
+    Annotation annotation = ParserTestCase.parse6("parseAnnotation", "@A", []);
     JUnitTestCase.assertNotNull(annotation.atSign);
     JUnitTestCase.assertNotNull(annotation.name);
     JUnitTestCase.assertNull(annotation.period);
@@ -1202,7 +222,7 @@
     JUnitTestCase.assertNull(annotation.arguments);
   }
   void test_parseAnnotation_n1_a() {
-    Annotation annotation = ParserTestCase.parse5("parseAnnotation", "@A(x,y)", []);
+    Annotation annotation = ParserTestCase.parse6("parseAnnotation", "@A(x,y)", []);
     JUnitTestCase.assertNotNull(annotation.atSign);
     JUnitTestCase.assertNotNull(annotation.name);
     JUnitTestCase.assertNull(annotation.period);
@@ -1210,7 +230,7 @@
     JUnitTestCase.assertNotNull(annotation.arguments);
   }
   void test_parseAnnotation_n2() {
-    Annotation annotation = ParserTestCase.parse5("parseAnnotation", "@A.B", []);
+    Annotation annotation = ParserTestCase.parse6("parseAnnotation", "@A.B", []);
     JUnitTestCase.assertNotNull(annotation.atSign);
     JUnitTestCase.assertNotNull(annotation.name);
     JUnitTestCase.assertNull(annotation.period);
@@ -1218,7 +238,7 @@
     JUnitTestCase.assertNull(annotation.arguments);
   }
   void test_parseAnnotation_n2_a() {
-    Annotation annotation = ParserTestCase.parse5("parseAnnotation", "@A.B(x,y)", []);
+    Annotation annotation = ParserTestCase.parse6("parseAnnotation", "@A.B(x,y)", []);
     JUnitTestCase.assertNotNull(annotation.atSign);
     JUnitTestCase.assertNotNull(annotation.name);
     JUnitTestCase.assertNull(annotation.period);
@@ -1226,7 +246,7 @@
     JUnitTestCase.assertNotNull(annotation.arguments);
   }
   void test_parseAnnotation_n3() {
-    Annotation annotation = ParserTestCase.parse5("parseAnnotation", "@A.B.C", []);
+    Annotation annotation = ParserTestCase.parse6("parseAnnotation", "@A.B.C", []);
     JUnitTestCase.assertNotNull(annotation.atSign);
     JUnitTestCase.assertNotNull(annotation.name);
     JUnitTestCase.assertNotNull(annotation.period);
@@ -1234,7 +254,7 @@
     JUnitTestCase.assertNull(annotation.arguments);
   }
   void test_parseAnnotation_n3_a() {
-    Annotation annotation = ParserTestCase.parse5("parseAnnotation", "@A.B.C(x,y)", []);
+    Annotation annotation = ParserTestCase.parse6("parseAnnotation", "@A.B.C(x,y)", []);
     JUnitTestCase.assertNotNull(annotation.atSign);
     JUnitTestCase.assertNotNull(annotation.name);
     JUnitTestCase.assertNotNull(annotation.period);
@@ -1242,45 +262,45 @@
     JUnitTestCase.assertNotNull(annotation.arguments);
   }
   void test_parseArgument_named() {
-    NamedExpression expression = ParserTestCase.parse5("parseArgument", "n: x", []);
-    Label name20 = expression.name;
-    JUnitTestCase.assertNotNull(name20);
-    JUnitTestCase.assertNotNull(name20.label);
-    JUnitTestCase.assertNotNull(name20.colon);
+    NamedExpression expression = ParserTestCase.parse6("parseArgument", "n: x", []);
+    Label name22 = expression.name;
+    JUnitTestCase.assertNotNull(name22);
+    JUnitTestCase.assertNotNull(name22.label);
+    JUnitTestCase.assertNotNull(name22.colon);
     JUnitTestCase.assertNotNull(expression.expression);
   }
   void test_parseArgument_unnamed() {
     String lexeme = "x";
-    SimpleIdentifier identifier = ParserTestCase.parse5("parseArgument", lexeme, []);
+    SimpleIdentifier identifier = ParserTestCase.parse6("parseArgument", lexeme, []);
     JUnitTestCase.assertEquals(lexeme, identifier.name);
   }
   void test_parseArgumentDefinitionTest() {
-    ArgumentDefinitionTest test = ParserTestCase.parse5("parseArgumentDefinitionTest", "?x", []);
+    ArgumentDefinitionTest test = ParserTestCase.parse6("parseArgumentDefinitionTest", "?x", []);
     JUnitTestCase.assertNotNull(test.question);
     JUnitTestCase.assertNotNull(test.identifier);
   }
   void test_parseArgumentList_empty() {
-    ArgumentList argumentList = ParserTestCase.parse5("parseArgumentList", "()", []);
-    NodeList<Expression> arguments7 = argumentList.arguments;
-    EngineTestCase.assertSize(0, arguments7);
+    ArgumentList argumentList = ParserTestCase.parse6("parseArgumentList", "()", []);
+    NodeList<Expression> arguments8 = argumentList.arguments;
+    EngineTestCase.assertSize(0, arguments8);
   }
   void test_parseArgumentList_mixed() {
-    ArgumentList argumentList = ParserTestCase.parse5("parseArgumentList", "(w, x, y: y, z: z)", []);
-    NodeList<Expression> arguments8 = argumentList.arguments;
-    EngineTestCase.assertSize(4, arguments8);
+    ArgumentList argumentList = ParserTestCase.parse6("parseArgumentList", "(w, x, y: y, z: z)", []);
+    NodeList<Expression> arguments9 = argumentList.arguments;
+    EngineTestCase.assertSize(4, arguments9);
   }
   void test_parseArgumentList_noNamed() {
-    ArgumentList argumentList = ParserTestCase.parse5("parseArgumentList", "(x, y, z)", []);
-    NodeList<Expression> arguments9 = argumentList.arguments;
-    EngineTestCase.assertSize(3, arguments9);
+    ArgumentList argumentList = ParserTestCase.parse6("parseArgumentList", "(x, y, z)", []);
+    NodeList<Expression> arguments10 = argumentList.arguments;
+    EngineTestCase.assertSize(3, arguments10);
   }
   void test_parseArgumentList_onlyNamed() {
-    ArgumentList argumentList = ParserTestCase.parse5("parseArgumentList", "(x: x, y: y)", []);
-    NodeList<Expression> arguments10 = argumentList.arguments;
-    EngineTestCase.assertSize(2, arguments10);
+    ArgumentList argumentList = ParserTestCase.parse6("parseArgumentList", "(x: x, y: y)", []);
+    NodeList<Expression> arguments11 = argumentList.arguments;
+    EngineTestCase.assertSize(2, arguments11);
   }
   void test_parseAssertStatement() {
-    AssertStatement statement = ParserTestCase.parse5("parseAssertStatement", "assert (x);", []);
+    AssertStatement statement = ParserTestCase.parse6("parseAssertStatement", "assert (x);", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.condition);
@@ -1289,11 +309,11 @@
   }
   void test_parseAssignableExpression_expression_args_dot() {
     PropertyAccess propertyAccess = ParserTestCase.parse("parseAssignableExpression", <Object> [false], "(x)(y).z");
-    FunctionExpressionInvocation invocation = (propertyAccess.target as FunctionExpressionInvocation);
+    FunctionExpressionInvocation invocation = propertyAccess.target as FunctionExpressionInvocation;
     JUnitTestCase.assertNotNull(invocation.function);
-    ArgumentList argumentList13 = invocation.argumentList;
-    JUnitTestCase.assertNotNull(argumentList13);
-    EngineTestCase.assertSize(1, argumentList13.arguments);
+    ArgumentList argumentList12 = invocation.argumentList;
+    JUnitTestCase.assertNotNull(argumentList12);
+    EngineTestCase.assertSize(1, argumentList12.arguments);
     JUnitTestCase.assertNotNull(propertyAccess.operator);
     JUnitTestCase.assertNotNull(propertyAccess.propertyName);
   }
@@ -1316,11 +336,11 @@
   }
   void test_parseAssignableExpression_identifier_args_dot() {
     PropertyAccess propertyAccess = ParserTestCase.parse("parseAssignableExpression", <Object> [false], "x(y).z");
-    MethodInvocation invocation = (propertyAccess.target as MethodInvocation);
+    MethodInvocation invocation = propertyAccess.target as MethodInvocation;
     JUnitTestCase.assertEquals("x", invocation.methodName.name);
-    ArgumentList argumentList14 = invocation.argumentList;
-    JUnitTestCase.assertNotNull(argumentList14);
-    EngineTestCase.assertSize(1, argumentList14.arguments);
+    ArgumentList argumentList13 = invocation.argumentList;
+    JUnitTestCase.assertNotNull(argumentList13);
+    EngineTestCase.assertSize(1, argumentList13.arguments);
     JUnitTestCase.assertNotNull(propertyAccess.operator);
     JUnitTestCase.assertNotNull(propertyAccess.propertyName);
   }
@@ -1366,103 +386,111 @@
     JUnitTestCase.assertNotNull(selector);
   }
   void test_parseBitwiseAndExpression_normal() {
-    BinaryExpression expression = ParserTestCase.parse5("parseBitwiseAndExpression", "x & y", []);
+    BinaryExpression expression = ParserTestCase.parse6("parseBitwiseAndExpression", "x & y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.AMPERSAND, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseBitwiseAndExpression_super() {
-    BinaryExpression expression = ParserTestCase.parse5("parseBitwiseAndExpression", "super & y", []);
+    BinaryExpression expression = ParserTestCase.parse6("parseBitwiseAndExpression", "super & y", []);
     EngineTestCase.assertInstanceOf(SuperExpression, expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.AMPERSAND, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseBitwiseOrExpression_normal() {
-    BinaryExpression expression = ParserTestCase.parse5("parseBitwiseOrExpression", "x | y", []);
+    BinaryExpression expression = ParserTestCase.parse6("parseBitwiseOrExpression", "x | y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.BAR, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseBitwiseOrExpression_super() {
-    BinaryExpression expression = ParserTestCase.parse5("parseBitwiseOrExpression", "super | y", []);
+    BinaryExpression expression = ParserTestCase.parse6("parseBitwiseOrExpression", "super | y", []);
     EngineTestCase.assertInstanceOf(SuperExpression, expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.BAR, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseBitwiseXorExpression_normal() {
-    BinaryExpression expression = ParserTestCase.parse5("parseBitwiseXorExpression", "x ^ y", []);
+    BinaryExpression expression = ParserTestCase.parse6("parseBitwiseXorExpression", "x ^ y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.CARET, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseBitwiseXorExpression_super() {
-    BinaryExpression expression = ParserTestCase.parse5("parseBitwiseXorExpression", "super ^ y", []);
+    BinaryExpression expression = ParserTestCase.parse6("parseBitwiseXorExpression", "super ^ y", []);
     EngineTestCase.assertInstanceOf(SuperExpression, expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.CARET, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseBlock_empty() {
-    Block block = ParserTestCase.parse5("parseBlock", "{}", []);
+    Block block = ParserTestCase.parse6("parseBlock", "{}", []);
     JUnitTestCase.assertNotNull(block.leftBracket);
     EngineTestCase.assertSize(0, block.statements);
     JUnitTestCase.assertNotNull(block.rightBracket);
   }
   void test_parseBlock_nonEmpty() {
-    Block block = ParserTestCase.parse5("parseBlock", "{;}", []);
+    Block block = ParserTestCase.parse6("parseBlock", "{;}", []);
     JUnitTestCase.assertNotNull(block.leftBracket);
     EngineTestCase.assertSize(1, block.statements);
     JUnitTestCase.assertNotNull(block.rightBracket);
   }
   void test_parseBreakStatement_label() {
-    BreakStatement statement = ParserTestCase.parse5("parseBreakStatement", "break foo;", []);
+    BreakStatement statement = ParserTestCase.parse6("parseBreakStatement", "break foo;", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNotNull(statement.label);
     JUnitTestCase.assertNotNull(statement.semicolon);
   }
   void test_parseBreakStatement_noLabel() {
-    BreakStatement statement = ParserTestCase.parse5("parseBreakStatement", "break;", [ParserErrorCode.BREAK_OUTSIDE_OF_LOOP]);
+    BreakStatement statement = ParserTestCase.parse6("parseBreakStatement", "break;", [ParserErrorCode.BREAK_OUTSIDE_OF_LOOP]);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNull(statement.label);
     JUnitTestCase.assertNotNull(statement.semicolon);
   }
   void test_parseCascadeSection_i() {
-    IndexExpression section = ParserTestCase.parse5("parseCascadeSection", "..[i]", []);
+    IndexExpression section = ParserTestCase.parse6("parseCascadeSection", "..[i]", []);
     JUnitTestCase.assertNull(section.array);
     JUnitTestCase.assertNotNull(section.leftBracket);
     JUnitTestCase.assertNotNull(section.index);
     JUnitTestCase.assertNotNull(section.rightBracket);
   }
   void test_parseCascadeSection_ia() {
-    FunctionExpressionInvocation section = ParserTestCase.parse5("parseCascadeSection", "..[i](b)", []);
+    FunctionExpressionInvocation section = ParserTestCase.parse6("parseCascadeSection", "..[i](b)", []);
     EngineTestCase.assertInstanceOf(IndexExpression, section.function);
     JUnitTestCase.assertNotNull(section.argumentList);
   }
   void test_parseCascadeSection_p() {
-    PropertyAccess section = ParserTestCase.parse5("parseCascadeSection", "..a", []);
+    PropertyAccess section = ParserTestCase.parse6("parseCascadeSection", "..a", []);
     JUnitTestCase.assertNull(section.target);
     JUnitTestCase.assertNotNull(section.operator);
     JUnitTestCase.assertNotNull(section.propertyName);
   }
   void test_parseCascadeSection_p_assign() {
-    AssignmentExpression section = ParserTestCase.parse5("parseCascadeSection", "..a = 3", []);
+    AssignmentExpression section = ParserTestCase.parse6("parseCascadeSection", "..a = 3", []);
     JUnitTestCase.assertNotNull(section.leftHandSide);
     JUnitTestCase.assertNotNull(section.operator);
-    JUnitTestCase.assertNotNull(section.rightHandSide);
+    Expression rhs = section.rightHandSide;
+    JUnitTestCase.assertNotNull(rhs);
+  }
+  void test_parseCascadeSection_p_assign_withCascade() {
+    AssignmentExpression section = ParserTestCase.parse6("parseCascadeSection", "..a = 3..m()", []);
+    JUnitTestCase.assertNotNull(section.leftHandSide);
+    JUnitTestCase.assertNotNull(section.operator);
+    Expression rhs = section.rightHandSide;
+    EngineTestCase.assertInstanceOf(IntegerLiteral, rhs);
   }
   void test_parseCascadeSection_p_builtIn() {
-    PropertyAccess section = ParserTestCase.parse5("parseCascadeSection", "..as", []);
+    PropertyAccess section = ParserTestCase.parse6("parseCascadeSection", "..as", []);
     JUnitTestCase.assertNull(section.target);
     JUnitTestCase.assertNotNull(section.operator);
     JUnitTestCase.assertNotNull(section.propertyName);
   }
   void test_parseCascadeSection_pa() {
-    MethodInvocation section = ParserTestCase.parse5("parseCascadeSection", "..a(b)", []);
+    MethodInvocation section = ParserTestCase.parse6("parseCascadeSection", "..a(b)", []);
     JUnitTestCase.assertNull(section.target);
     JUnitTestCase.assertNotNull(section.period);
     JUnitTestCase.assertNotNull(section.methodName);
@@ -1470,19 +498,19 @@
     EngineTestCase.assertSize(1, section.argumentList.arguments);
   }
   void test_parseCascadeSection_paa() {
-    FunctionExpressionInvocation section = ParserTestCase.parse5("parseCascadeSection", "..a(b)(c)", []);
+    FunctionExpressionInvocation section = ParserTestCase.parse6("parseCascadeSection", "..a(b)(c)", []);
     EngineTestCase.assertInstanceOf(MethodInvocation, section.function);
     JUnitTestCase.assertNotNull(section.argumentList);
     EngineTestCase.assertSize(1, section.argumentList.arguments);
   }
   void test_parseCascadeSection_paapaa() {
-    FunctionExpressionInvocation section = ParserTestCase.parse5("parseCascadeSection", "..a(b)(c).d(e)(f)", []);
+    FunctionExpressionInvocation section = ParserTestCase.parse6("parseCascadeSection", "..a(b)(c).d(e)(f)", []);
     EngineTestCase.assertInstanceOf(FunctionExpressionInvocation, section.function);
     JUnitTestCase.assertNotNull(section.argumentList);
     EngineTestCase.assertSize(1, section.argumentList.arguments);
   }
   void test_parseCascadeSection_pap() {
-    PropertyAccess section = ParserTestCase.parse5("parseCascadeSection", "..a(b).c", []);
+    PropertyAccess section = ParserTestCase.parse6("parseCascadeSection", "..a(b).c", []);
     JUnitTestCase.assertNotNull(section.target);
     JUnitTestCase.assertNotNull(section.operator);
     JUnitTestCase.assertNotNull(section.propertyName);
@@ -1876,121 +904,121 @@
     JUnitTestCase.assertNotNull(constructor.body);
   }
   void test_parseCombinators_h() {
-    List<Combinator> combinators = ParserTestCase.parse5("parseCombinators", "hide a;", []);
+    List<Combinator> combinators = ParserTestCase.parse6("parseCombinators", "hide a;", []);
     EngineTestCase.assertSize(1, combinators);
-    HideCombinator combinator = (combinators[0] as HideCombinator);
+    HideCombinator combinator = combinators[0] as HideCombinator;
     JUnitTestCase.assertNotNull(combinator);
     JUnitTestCase.assertNotNull(combinator.keyword);
     EngineTestCase.assertSize(1, combinator.hiddenNames);
   }
   void test_parseCombinators_hs() {
-    List<Combinator> combinators = ParserTestCase.parse5("parseCombinators", "hide a show b;", []);
+    List<Combinator> combinators = ParserTestCase.parse6("parseCombinators", "hide a show b;", []);
     EngineTestCase.assertSize(2, combinators);
-    HideCombinator hideCombinator = (combinators[0] as HideCombinator);
+    HideCombinator hideCombinator = combinators[0] as HideCombinator;
     JUnitTestCase.assertNotNull(hideCombinator);
     JUnitTestCase.assertNotNull(hideCombinator.keyword);
     EngineTestCase.assertSize(1, hideCombinator.hiddenNames);
-    ShowCombinator showCombinator = (combinators[1] as ShowCombinator);
+    ShowCombinator showCombinator = combinators[1] as ShowCombinator;
     JUnitTestCase.assertNotNull(showCombinator);
     JUnitTestCase.assertNotNull(showCombinator.keyword);
     EngineTestCase.assertSize(1, showCombinator.shownNames);
   }
   void test_parseCombinators_hshs() {
-    List<Combinator> combinators = ParserTestCase.parse5("parseCombinators", "hide a show b hide c show d;", []);
+    List<Combinator> combinators = ParserTestCase.parse6("parseCombinators", "hide a show b hide c show d;", []);
     EngineTestCase.assertSize(4, combinators);
   }
   void test_parseCombinators_s() {
-    List<Combinator> combinators = ParserTestCase.parse5("parseCombinators", "show a;", []);
+    List<Combinator> combinators = ParserTestCase.parse6("parseCombinators", "show a;", []);
     EngineTestCase.assertSize(1, combinators);
-    ShowCombinator combinator = (combinators[0] as ShowCombinator);
+    ShowCombinator combinator = combinators[0] as ShowCombinator;
     JUnitTestCase.assertNotNull(combinator);
     JUnitTestCase.assertNotNull(combinator.keyword);
     EngineTestCase.assertSize(1, combinator.shownNames);
   }
   void test_parseCommentAndMetadata_c() {
-    CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "/** 1 */ void", []);
+    CommentAndMetadata commentAndMetadata = ParserTestCase.parse6("parseCommentAndMetadata", "/** 1 */ void", []);
     JUnitTestCase.assertNotNull(commentAndMetadata.comment);
     EngineTestCase.assertSize(0, commentAndMetadata.metadata);
   }
   void test_parseCommentAndMetadata_cmc() {
-    CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "/** 1 */ @A /** 2 */ void", []);
+    CommentAndMetadata commentAndMetadata = ParserTestCase.parse6("parseCommentAndMetadata", "/** 1 */ @A /** 2 */ void", []);
     JUnitTestCase.assertNotNull(commentAndMetadata.comment);
     EngineTestCase.assertSize(1, commentAndMetadata.metadata);
   }
   void test_parseCommentAndMetadata_cmcm() {
-    CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "/** 1 */ @A /** 2 */ @B void", []);
+    CommentAndMetadata commentAndMetadata = ParserTestCase.parse6("parseCommentAndMetadata", "/** 1 */ @A /** 2 */ @B void", []);
     JUnitTestCase.assertNotNull(commentAndMetadata.comment);
     EngineTestCase.assertSize(2, commentAndMetadata.metadata);
   }
   void test_parseCommentAndMetadata_cmm() {
-    CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "/** 1 */ @A @B void", []);
+    CommentAndMetadata commentAndMetadata = ParserTestCase.parse6("parseCommentAndMetadata", "/** 1 */ @A @B void", []);
     JUnitTestCase.assertNotNull(commentAndMetadata.comment);
     EngineTestCase.assertSize(2, commentAndMetadata.metadata);
   }
   void test_parseCommentAndMetadata_m() {
-    CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "@A void", []);
+    CommentAndMetadata commentAndMetadata = ParserTestCase.parse6("parseCommentAndMetadata", "@A void", []);
     JUnitTestCase.assertNull(commentAndMetadata.comment);
     EngineTestCase.assertSize(1, commentAndMetadata.metadata);
   }
   void test_parseCommentAndMetadata_mcm() {
-    CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "@A /** 1 */ @B void", []);
+    CommentAndMetadata commentAndMetadata = ParserTestCase.parse6("parseCommentAndMetadata", "@A /** 1 */ @B void", []);
     JUnitTestCase.assertNotNull(commentAndMetadata.comment);
     EngineTestCase.assertSize(2, commentAndMetadata.metadata);
   }
   void test_parseCommentAndMetadata_mcmc() {
-    CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "@A /** 1 */ @B /** 2 */ void", []);
+    CommentAndMetadata commentAndMetadata = ParserTestCase.parse6("parseCommentAndMetadata", "@A /** 1 */ @B /** 2 */ void", []);
     JUnitTestCase.assertNotNull(commentAndMetadata.comment);
     EngineTestCase.assertSize(2, commentAndMetadata.metadata);
   }
   void test_parseCommentAndMetadata_mm() {
-    CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "@A @B(x) void", []);
+    CommentAndMetadata commentAndMetadata = ParserTestCase.parse6("parseCommentAndMetadata", "@A @B(x) void", []);
     JUnitTestCase.assertNull(commentAndMetadata.comment);
     EngineTestCase.assertSize(2, commentAndMetadata.metadata);
   }
   void test_parseCommentAndMetadata_none() {
-    CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "void", []);
+    CommentAndMetadata commentAndMetadata = ParserTestCase.parse6("parseCommentAndMetadata", "void", []);
     JUnitTestCase.assertNull(commentAndMetadata.comment);
     EngineTestCase.assertSize(0, commentAndMetadata.metadata);
   }
   void test_parseCommentReference_new_prefixed() {
     CommentReference reference = ParserTestCase.parse("parseCommentReference", <Object> ["new a.b", 7], "");
     PrefixedIdentifier prefixedIdentifier = EngineTestCase.assertInstanceOf(PrefixedIdentifier, reference.identifier);
-    SimpleIdentifier prefix10 = prefixedIdentifier.prefix;
-    JUnitTestCase.assertNotNull(prefix10.token);
-    JUnitTestCase.assertEquals("a", prefix10.name);
-    JUnitTestCase.assertEquals(11, prefix10.offset);
+    SimpleIdentifier prefix11 = prefixedIdentifier.prefix;
+    JUnitTestCase.assertNotNull(prefix11.token);
+    JUnitTestCase.assertEquals("a", prefix11.name);
+    JUnitTestCase.assertEquals(11, prefix11.offset);
     JUnitTestCase.assertNotNull(prefixedIdentifier.period);
-    SimpleIdentifier identifier14 = prefixedIdentifier.identifier;
-    JUnitTestCase.assertNotNull(identifier14.token);
-    JUnitTestCase.assertEquals("b", identifier14.name);
-    JUnitTestCase.assertEquals(13, identifier14.offset);
+    SimpleIdentifier identifier20 = prefixedIdentifier.identifier;
+    JUnitTestCase.assertNotNull(identifier20.token);
+    JUnitTestCase.assertEquals("b", identifier20.name);
+    JUnitTestCase.assertEquals(13, identifier20.offset);
   }
   void test_parseCommentReference_new_simple() {
     CommentReference reference = ParserTestCase.parse("parseCommentReference", <Object> ["new a", 5], "");
-    SimpleIdentifier identifier15 = EngineTestCase.assertInstanceOf(SimpleIdentifier, reference.identifier);
-    JUnitTestCase.assertNotNull(identifier15.token);
-    JUnitTestCase.assertEquals("a", identifier15.name);
-    JUnitTestCase.assertEquals(9, identifier15.offset);
+    SimpleIdentifier identifier21 = EngineTestCase.assertInstanceOf(SimpleIdentifier, reference.identifier);
+    JUnitTestCase.assertNotNull(identifier21.token);
+    JUnitTestCase.assertEquals("a", identifier21.name);
+    JUnitTestCase.assertEquals(9, identifier21.offset);
   }
   void test_parseCommentReference_prefixed() {
     CommentReference reference = ParserTestCase.parse("parseCommentReference", <Object> ["a.b", 7], "");
     PrefixedIdentifier prefixedIdentifier = EngineTestCase.assertInstanceOf(PrefixedIdentifier, reference.identifier);
-    SimpleIdentifier prefix11 = prefixedIdentifier.prefix;
-    JUnitTestCase.assertNotNull(prefix11.token);
-    JUnitTestCase.assertEquals("a", prefix11.name);
-    JUnitTestCase.assertEquals(7, prefix11.offset);
+    SimpleIdentifier prefix12 = prefixedIdentifier.prefix;
+    JUnitTestCase.assertNotNull(prefix12.token);
+    JUnitTestCase.assertEquals("a", prefix12.name);
+    JUnitTestCase.assertEquals(7, prefix12.offset);
     JUnitTestCase.assertNotNull(prefixedIdentifier.period);
-    SimpleIdentifier identifier16 = prefixedIdentifier.identifier;
-    JUnitTestCase.assertNotNull(identifier16.token);
-    JUnitTestCase.assertEquals("b", identifier16.name);
-    JUnitTestCase.assertEquals(9, identifier16.offset);
+    SimpleIdentifier identifier22 = prefixedIdentifier.identifier;
+    JUnitTestCase.assertNotNull(identifier22.token);
+    JUnitTestCase.assertEquals("b", identifier22.name);
+    JUnitTestCase.assertEquals(9, identifier22.offset);
   }
   void test_parseCommentReference_simple() {
     CommentReference reference = ParserTestCase.parse("parseCommentReference", <Object> ["a", 5], "");
-    SimpleIdentifier identifier17 = EngineTestCase.assertInstanceOf(SimpleIdentifier, reference.identifier);
-    JUnitTestCase.assertNotNull(identifier17.token);
-    JUnitTestCase.assertEquals("a", identifier17.name);
-    JUnitTestCase.assertEquals(5, identifier17.offset);
+    SimpleIdentifier identifier23 = EngineTestCase.assertInstanceOf(SimpleIdentifier, reference.identifier);
+    JUnitTestCase.assertNotNull(identifier23.token);
+    JUnitTestCase.assertEquals("a", identifier23.name);
+    JUnitTestCase.assertEquals(5, identifier23.offset);
   }
   void test_parseCommentReferences_multiLine() {
     List<Token> tokens = <Token> [new StringToken(TokenType.MULTI_LINE_COMMENT, "/** xxx [a] yyy [b] zzz */", 3)];
@@ -2022,36 +1050,71 @@
     JUnitTestCase.assertNotNull(reference.identifier);
     JUnitTestCase.assertEquals(35, reference.offset);
   }
+  void test_parseCompilationUnit_abstractAsPrefix_parameterized() {
+    CompilationUnit unit = ParserTestCase.parse6("parseCompilationUnit", "abstract<dynamic> _abstract = new abstract.A();", []);
+    JUnitTestCase.assertNull(unit.scriptTag);
+    EngineTestCase.assertSize(0, unit.directives);
+    EngineTestCase.assertSize(1, unit.declarations);
+  }
   void test_parseCompilationUnit_directives_multiple() {
-    CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "library l;\npart 'a.dart';", []);
+    CompilationUnit unit = ParserTestCase.parse6("parseCompilationUnit", "library l;\npart 'a.dart';", []);
     JUnitTestCase.assertNull(unit.scriptTag);
     EngineTestCase.assertSize(2, unit.directives);
     EngineTestCase.assertSize(0, unit.declarations);
   }
   void test_parseCompilationUnit_directives_single() {
-    CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "library l;", []);
+    CompilationUnit unit = ParserTestCase.parse6("parseCompilationUnit", "library l;", []);
     JUnitTestCase.assertNull(unit.scriptTag);
     EngineTestCase.assertSize(1, unit.directives);
     EngineTestCase.assertSize(0, unit.declarations);
   }
   void test_parseCompilationUnit_empty() {
-    CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "", []);
+    CompilationUnit unit = ParserTestCase.parse6("parseCompilationUnit", "", []);
     JUnitTestCase.assertNull(unit.scriptTag);
     EngineTestCase.assertSize(0, unit.directives);
     EngineTestCase.assertSize(0, unit.declarations);
   }
+  void test_parseCompilationUnit_exportAsPrefix() {
+    CompilationUnit unit = ParserTestCase.parse6("parseCompilationUnit", "export.A _export = new export.A();", []);
+    JUnitTestCase.assertNull(unit.scriptTag);
+    EngineTestCase.assertSize(0, unit.directives);
+    EngineTestCase.assertSize(1, unit.declarations);
+  }
+  void test_parseCompilationUnit_exportAsPrefix_parameterized() {
+    CompilationUnit unit = ParserTestCase.parse6("parseCompilationUnit", "export<dynamic> _export = new export.A();", []);
+    JUnitTestCase.assertNull(unit.scriptTag);
+    EngineTestCase.assertSize(0, unit.directives);
+    EngineTestCase.assertSize(1, unit.declarations);
+  }
+  void test_parseCompilationUnit_operatorAsPrefix_parameterized() {
+    CompilationUnit unit = ParserTestCase.parse6("parseCompilationUnit", "operator<dynamic> _operator = new operator.A();", []);
+    JUnitTestCase.assertNull(unit.scriptTag);
+    EngineTestCase.assertSize(0, unit.directives);
+    EngineTestCase.assertSize(1, unit.declarations);
+  }
   void test_parseCompilationUnit_script() {
-    CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "#! /bin/dart", []);
+    CompilationUnit unit = ParserTestCase.parse6("parseCompilationUnit", "#! /bin/dart", []);
     JUnitTestCase.assertNotNull(unit.scriptTag);
     EngineTestCase.assertSize(0, unit.directives);
     EngineTestCase.assertSize(0, unit.declarations);
   }
   void test_parseCompilationUnit_topLevelDeclaration() {
-    CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "class A {}", []);
+    CompilationUnit unit = ParserTestCase.parse6("parseCompilationUnit", "class A {}", []);
     JUnitTestCase.assertNull(unit.scriptTag);
     EngineTestCase.assertSize(0, unit.directives);
     EngineTestCase.assertSize(1, unit.declarations);
   }
+  void test_parseCompilationUnit_typedefAsPrefix() {
+    CompilationUnit unit = ParserTestCase.parse6("parseCompilationUnit", "typedef.A _typedef = new typedef.A();", []);
+    JUnitTestCase.assertNull(unit.scriptTag);
+    EngineTestCase.assertSize(0, unit.directives);
+    EngineTestCase.assertSize(1, unit.declarations);
+  }
+  void test_parseCompilationUnitMember_abstractAsPrefix() {
+    TopLevelVariableDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "abstract.A _abstract = new abstract.A();");
+    JUnitTestCase.assertNotNull(declaration.semicolon);
+    JUnitTestCase.assertNotNull(declaration.variables);
+  }
   void test_parseCompilationUnitMember_class() {
     ClassDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "class A {}");
     JUnitTestCase.assertEquals("A", declaration.name.name);
@@ -2068,13 +1131,13 @@
     JUnitTestCase.assertNotNull(declaration.variables);
   }
   void test_parseCompilationUnitMember_function_external_noType() {
-    FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "external f()");
+    FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "external f();");
     JUnitTestCase.assertNotNull(declaration.externalKeyword);
     JUnitTestCase.assertNotNull(declaration.functionExpression);
     JUnitTestCase.assertNull(declaration.propertyKeyword);
   }
   void test_parseCompilationUnitMember_function_external_type() {
-    FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "external int f()");
+    FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "external int f();");
     JUnitTestCase.assertNotNull(declaration.externalKeyword);
     JUnitTestCase.assertNotNull(declaration.functionExpression);
     JUnitTestCase.assertNull(declaration.propertyKeyword);
@@ -2090,13 +1153,13 @@
     JUnitTestCase.assertNull(declaration.propertyKeyword);
   }
   void test_parseCompilationUnitMember_getter_external_noType() {
-    FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "external get p");
+    FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "external get p;");
     JUnitTestCase.assertNotNull(declaration.externalKeyword);
     JUnitTestCase.assertNotNull(declaration.functionExpression);
     JUnitTestCase.assertNotNull(declaration.propertyKeyword);
   }
   void test_parseCompilationUnitMember_getter_external_type() {
-    FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "external int get p");
+    FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "external int get p;");
     JUnitTestCase.assertNotNull(declaration.externalKeyword);
     JUnitTestCase.assertNotNull(declaration.functionExpression);
     JUnitTestCase.assertNotNull(declaration.propertyKeyword);
@@ -2112,13 +1175,13 @@
     JUnitTestCase.assertNotNull(declaration.propertyKeyword);
   }
   void test_parseCompilationUnitMember_setter_external_noType() {
-    FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "external set p(v)");
+    FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "external set p(v);");
     JUnitTestCase.assertNotNull(declaration.externalKeyword);
     JUnitTestCase.assertNotNull(declaration.functionExpression);
     JUnitTestCase.assertNotNull(declaration.propertyKeyword);
   }
   void test_parseCompilationUnitMember_setter_external_type() {
-    FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "external void set p(int v)");
+    FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "external void set p(int v);");
     JUnitTestCase.assertNotNull(declaration.externalKeyword);
     JUnitTestCase.assertNotNull(declaration.functionExpression);
     JUnitTestCase.assertNotNull(declaration.propertyKeyword);
@@ -2192,7 +1255,7 @@
     JUnitTestCase.assertNotNull(declaration.variables);
   }
   void test_parseConditionalExpression() {
-    ConditionalExpression expression = ParserTestCase.parse5("parseConditionalExpression", "x ? y : z", []);
+    ConditionalExpression expression = ParserTestCase.parse6("parseConditionalExpression", "x ? y : z", []);
     JUnitTestCase.assertNotNull(expression.condition);
     JUnitTestCase.assertNotNull(expression.question);
     JUnitTestCase.assertNotNull(expression.thenExpression);
@@ -2200,7 +1263,7 @@
     JUnitTestCase.assertNotNull(expression.elseExpression);
   }
   void test_parseConstExpression_instanceCreation() {
-    InstanceCreationExpression expression = ParserTestCase.parse5("parseConstExpression", "const A()", []);
+    InstanceCreationExpression expression = ParserTestCase.parse6("parseConstExpression", "const A()", []);
     JUnitTestCase.assertNotNull(expression.keyword);
     ConstructorName name = expression.constructorName;
     JUnitTestCase.assertNotNull(name);
@@ -2210,7 +1273,7 @@
     JUnitTestCase.assertNotNull(expression.argumentList);
   }
   void test_parseConstExpression_listLiteral_typed() {
-    ListLiteral literal = ParserTestCase.parse5("parseConstExpression", "const <A> []", []);
+    ListLiteral literal = ParserTestCase.parse6("parseConstExpression", "const <A> []", []);
     JUnitTestCase.assertNotNull(literal.modifier);
     JUnitTestCase.assertNotNull(literal.typeArguments);
     JUnitTestCase.assertNotNull(literal.leftBracket);
@@ -2218,7 +1281,7 @@
     JUnitTestCase.assertNotNull(literal.rightBracket);
   }
   void test_parseConstExpression_listLiteral_untyped() {
-    ListLiteral literal = ParserTestCase.parse5("parseConstExpression", "const []", []);
+    ListLiteral literal = ParserTestCase.parse6("parseConstExpression", "const []", []);
     JUnitTestCase.assertNotNull(literal.modifier);
     JUnitTestCase.assertNull(literal.typeArguments);
     JUnitTestCase.assertNotNull(literal.leftBracket);
@@ -2226,14 +1289,14 @@
     JUnitTestCase.assertNotNull(literal.rightBracket);
   }
   void test_parseConstExpression_mapLiteral_typed() {
-    MapLiteral literal = ParserTestCase.parse5("parseConstExpression", "const <A> {}", []);
+    MapLiteral literal = ParserTestCase.parse6("parseConstExpression", "const <A> {}", []);
     JUnitTestCase.assertNotNull(literal.leftBracket);
     EngineTestCase.assertSize(0, literal.entries);
     JUnitTestCase.assertNotNull(literal.rightBracket);
     JUnitTestCase.assertNotNull(literal.typeArguments);
   }
   void test_parseConstExpression_mapLiteral_untyped() {
-    MapLiteral literal = ParserTestCase.parse5("parseConstExpression", "const {}", []);
+    MapLiteral literal = ParserTestCase.parse6("parseConstExpression", "const {}", []);
     JUnitTestCase.assertNotNull(literal.leftBracket);
     EngineTestCase.assertSize(0, literal.entries);
     JUnitTestCase.assertNotNull(literal.rightBracket);
@@ -2242,7 +1305,7 @@
   void test_parseConstructor() {
   }
   void test_parseConstructorFieldInitializer_qualified() {
-    ConstructorFieldInitializer invocation = ParserTestCase.parse5("parseConstructorFieldInitializer", "this.a = b", []);
+    ConstructorFieldInitializer invocation = ParserTestCase.parse6("parseConstructorFieldInitializer", "this.a = b", []);
     JUnitTestCase.assertNotNull(invocation.equals);
     JUnitTestCase.assertNotNull(invocation.expression);
     JUnitTestCase.assertNotNull(invocation.fieldName);
@@ -2250,7 +1313,7 @@
     JUnitTestCase.assertNotNull(invocation.period);
   }
   void test_parseConstructorFieldInitializer_unqualified() {
-    ConstructorFieldInitializer invocation = ParserTestCase.parse5("parseConstructorFieldInitializer", "a = b", []);
+    ConstructorFieldInitializer invocation = ParserTestCase.parse6("parseConstructorFieldInitializer", "a = b", []);
     JUnitTestCase.assertNotNull(invocation.equals);
     JUnitTestCase.assertNotNull(invocation.expression);
     JUnitTestCase.assertNotNull(invocation.fieldName);
@@ -2258,37 +1321,37 @@
     JUnitTestCase.assertNull(invocation.period);
   }
   void test_parseConstructorName_named_noPrefix() {
-    ConstructorName name = ParserTestCase.parse5("parseConstructorName", "A.n;", []);
+    ConstructorName name = ParserTestCase.parse6("parseConstructorName", "A.n;", []);
     JUnitTestCase.assertNotNull(name.type);
     JUnitTestCase.assertNull(name.period);
     JUnitTestCase.assertNull(name.name);
   }
   void test_parseConstructorName_named_prefixed() {
-    ConstructorName name = ParserTestCase.parse5("parseConstructorName", "p.A.n;", []);
+    ConstructorName name = ParserTestCase.parse6("parseConstructorName", "p.A.n;", []);
     JUnitTestCase.assertNotNull(name.type);
     JUnitTestCase.assertNotNull(name.period);
     JUnitTestCase.assertNotNull(name.name);
   }
   void test_parseConstructorName_unnamed_noPrefix() {
-    ConstructorName name = ParserTestCase.parse5("parseConstructorName", "A;", []);
+    ConstructorName name = ParserTestCase.parse6("parseConstructorName", "A;", []);
     JUnitTestCase.assertNotNull(name.type);
     JUnitTestCase.assertNull(name.period);
     JUnitTestCase.assertNull(name.name);
   }
   void test_parseConstructorName_unnamed_prefixed() {
-    ConstructorName name = ParserTestCase.parse5("parseConstructorName", "p.A;", []);
+    ConstructorName name = ParserTestCase.parse6("parseConstructorName", "p.A;", []);
     JUnitTestCase.assertNotNull(name.type);
     JUnitTestCase.assertNull(name.period);
     JUnitTestCase.assertNull(name.name);
   }
   void test_parseContinueStatement_label() {
-    ContinueStatement statement = ParserTestCase.parse5("parseContinueStatement", "continue foo;", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]);
+    ContinueStatement statement = ParserTestCase.parse6("parseContinueStatement", "continue foo;", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNotNull(statement.label);
     JUnitTestCase.assertNotNull(statement.semicolon);
   }
   void test_parseContinueStatement_noLabel() {
-    ContinueStatement statement = ParserTestCase.parse5("parseContinueStatement", "continue;", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]);
+    ContinueStatement statement = ParserTestCase.parse6("parseContinueStatement", "continue;", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNull(statement.label);
     JUnitTestCase.assertNotNull(statement.semicolon);
@@ -2329,13 +1392,13 @@
     JUnitTestCase.assertNotNull(directive.semicolon);
   }
   void test_parseDocumentationComment_block() {
-    Comment comment = ParserTestCase.parse5("parseDocumentationComment", "/** */ class", []);
+    Comment comment = ParserTestCase.parse6("parseDocumentationComment", "/** */ class", []);
     JUnitTestCase.assertFalse(comment.isBlock());
     JUnitTestCase.assertTrue(comment.isDocumentation());
     JUnitTestCase.assertFalse(comment.isEndOfLine());
   }
   void test_parseDocumentationComment_block_withReference() {
-    Comment comment = ParserTestCase.parse5("parseDocumentationComment", "/** [a] */ class", []);
+    Comment comment = ParserTestCase.parse6("parseDocumentationComment", "/** [a] */ class", []);
     JUnitTestCase.assertFalse(comment.isBlock());
     JUnitTestCase.assertTrue(comment.isDocumentation());
     JUnitTestCase.assertFalse(comment.isEndOfLine());
@@ -2346,13 +1409,13 @@
     JUnitTestCase.assertEquals(5, reference.offset);
   }
   void test_parseDocumentationComment_endOfLine() {
-    Comment comment = ParserTestCase.parse5("parseDocumentationComment", "/// \n/// \n class", []);
+    Comment comment = ParserTestCase.parse6("parseDocumentationComment", "/// \n/// \n class", []);
     JUnitTestCase.assertFalse(comment.isBlock());
     JUnitTestCase.assertTrue(comment.isDocumentation());
     JUnitTestCase.assertFalse(comment.isEndOfLine());
   }
   void test_parseDoStatement() {
-    DoStatement statement = ParserTestCase.parse5("parseDoStatement", "do {} while (x);", []);
+    DoStatement statement = ParserTestCase.parse6("parseDoStatement", "do {} while (x);", []);
     JUnitTestCase.assertNotNull(statement.doKeyword);
     JUnitTestCase.assertNotNull(statement.body);
     JUnitTestCase.assertNotNull(statement.whileKeyword);
@@ -2362,18 +1425,18 @@
     JUnitTestCase.assertNotNull(statement.semicolon);
   }
   void test_parseEmptyStatement() {
-    EmptyStatement statement = ParserTestCase.parse5("parseEmptyStatement", ";", []);
+    EmptyStatement statement = ParserTestCase.parse6("parseEmptyStatement", ";", []);
     JUnitTestCase.assertNotNull(statement.semicolon);
   }
   void test_parseEqualityExpression_normal() {
-    BinaryExpression expression = ParserTestCase.parse5("parseEqualityExpression", "x == y", []);
+    BinaryExpression expression = ParserTestCase.parse6("parseEqualityExpression", "x == y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.EQ_EQ, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseEqualityExpression_super() {
-    BinaryExpression expression = ParserTestCase.parse5("parseEqualityExpression", "super == y", []);
+    BinaryExpression expression = ParserTestCase.parse6("parseEqualityExpression", "super == y", []);
     EngineTestCase.assertInstanceOf(SuperExpression, expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.EQ_EQ, expression.operator.type);
@@ -2415,23 +1478,23 @@
     JUnitTestCase.assertNotNull(directive.semicolon);
   }
   void test_parseExpression_assign() {
-    AssignmentExpression expression = ParserTestCase.parse5("parseExpression", "x = y", []);
+    AssignmentExpression expression = ParserTestCase.parse6("parseExpression", "x = y", []);
     JUnitTestCase.assertNotNull(expression.leftHandSide);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.EQ, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightHandSide);
   }
   void test_parseExpression_comparison() {
-    BinaryExpression expression = ParserTestCase.parse5("parseExpression", "--a.b == c", []);
+    BinaryExpression expression = ParserTestCase.parse6("parseExpression", "--a.b == c", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.EQ_EQ, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseExpression_invokeFunctionExpression() {
-    FunctionExpressionInvocation invocation = ParserTestCase.parse5("parseExpression", "(a) {return a + a;} (3)", []);
+    FunctionExpressionInvocation invocation = ParserTestCase.parse6("parseExpression", "(a) {return a + a;} (3)", []);
     EngineTestCase.assertInstanceOf(FunctionExpression, invocation.function);
-    FunctionExpression expression = (invocation.function as FunctionExpression);
+    FunctionExpression expression = invocation.function as FunctionExpression;
     JUnitTestCase.assertNotNull(expression.parameters);
     JUnitTestCase.assertNotNull(expression.body);
     ArgumentList list = invocation.argumentList;
@@ -2439,75 +1502,75 @@
     EngineTestCase.assertSize(1, list.arguments);
   }
   void test_parseExpression_superMethodInvocation() {
-    MethodInvocation invocation = ParserTestCase.parse5("parseExpression", "super.m()", []);
+    MethodInvocation invocation = ParserTestCase.parse6("parseExpression", "super.m()", []);
     JUnitTestCase.assertNotNull(invocation.target);
     JUnitTestCase.assertNotNull(invocation.methodName);
     JUnitTestCase.assertNotNull(invocation.argumentList);
   }
   void test_parseExpressionList_multiple() {
-    List<Expression> result = ParserTestCase.parse5("parseExpressionList", "1, 2, 3", []);
+    List<Expression> result = ParserTestCase.parse6("parseExpressionList", "1, 2, 3", []);
     EngineTestCase.assertSize(3, result);
   }
   void test_parseExpressionList_single() {
-    List<Expression> result = ParserTestCase.parse5("parseExpressionList", "1", []);
+    List<Expression> result = ParserTestCase.parse6("parseExpressionList", "1", []);
     EngineTestCase.assertSize(1, result);
   }
   void test_parseExpressionWithoutCascade_assign() {
-    AssignmentExpression expression = ParserTestCase.parse5("parseExpressionWithoutCascade", "x = y", []);
+    AssignmentExpression expression = ParserTestCase.parse6("parseExpressionWithoutCascade", "x = y", []);
     JUnitTestCase.assertNotNull(expression.leftHandSide);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.EQ, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightHandSide);
   }
   void test_parseExpressionWithoutCascade_comparison() {
-    BinaryExpression expression = ParserTestCase.parse5("parseExpressionWithoutCascade", "--a.b == c", []);
+    BinaryExpression expression = ParserTestCase.parse6("parseExpressionWithoutCascade", "--a.b == c", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.EQ_EQ, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseExpressionWithoutCascade_superMethodInvocation() {
-    MethodInvocation invocation = ParserTestCase.parse5("parseExpressionWithoutCascade", "super.m()", []);
+    MethodInvocation invocation = ParserTestCase.parse6("parseExpressionWithoutCascade", "super.m()", []);
     JUnitTestCase.assertNotNull(invocation.target);
     JUnitTestCase.assertNotNull(invocation.methodName);
     JUnitTestCase.assertNotNull(invocation.argumentList);
   }
   void test_parseExtendsClause() {
-    ExtendsClause clause = ParserTestCase.parse5("parseExtendsClause", "extends B", []);
+    ExtendsClause clause = ParserTestCase.parse6("parseExtendsClause", "extends B", []);
     JUnitTestCase.assertNotNull(clause.keyword);
     JUnitTestCase.assertNotNull(clause.superclass);
     EngineTestCase.assertInstanceOf(TypeName, clause.superclass);
   }
   void test_parseFinalConstVarOrType_const_noType() {
     FinalConstVarOrType result = ParserTestCase.parse("parseFinalConstVarOrType", <Object> [false], "const");
-    Token keyword29 = result.keyword;
-    JUnitTestCase.assertNotNull(keyword29);
-    JUnitTestCase.assertEquals(TokenType.KEYWORD, keyword29.type);
-    JUnitTestCase.assertEquals(Keyword.CONST, ((keyword29 as KeywordToken)).keyword);
+    Token keyword31 = result.keyword;
+    JUnitTestCase.assertNotNull(keyword31);
+    JUnitTestCase.assertEquals(TokenType.KEYWORD, keyword31.type);
+    JUnitTestCase.assertEquals(Keyword.CONST, ((keyword31 as KeywordToken)).keyword);
     JUnitTestCase.assertNull(result.type);
   }
   void test_parseFinalConstVarOrType_const_type() {
     FinalConstVarOrType result = ParserTestCase.parse("parseFinalConstVarOrType", <Object> [false], "const A a");
-    Token keyword30 = result.keyword;
-    JUnitTestCase.assertNotNull(keyword30);
-    JUnitTestCase.assertEquals(TokenType.KEYWORD, keyword30.type);
-    JUnitTestCase.assertEquals(Keyword.CONST, ((keyword30 as KeywordToken)).keyword);
+    Token keyword32 = result.keyword;
+    JUnitTestCase.assertNotNull(keyword32);
+    JUnitTestCase.assertEquals(TokenType.KEYWORD, keyword32.type);
+    JUnitTestCase.assertEquals(Keyword.CONST, ((keyword32 as KeywordToken)).keyword);
     JUnitTestCase.assertNotNull(result.type);
   }
   void test_parseFinalConstVarOrType_final_noType() {
     FinalConstVarOrType result = ParserTestCase.parse("parseFinalConstVarOrType", <Object> [false], "final");
-    Token keyword31 = result.keyword;
-    JUnitTestCase.assertNotNull(keyword31);
-    JUnitTestCase.assertEquals(TokenType.KEYWORD, keyword31.type);
-    JUnitTestCase.assertEquals(Keyword.FINAL, ((keyword31 as KeywordToken)).keyword);
+    Token keyword33 = result.keyword;
+    JUnitTestCase.assertNotNull(keyword33);
+    JUnitTestCase.assertEquals(TokenType.KEYWORD, keyword33.type);
+    JUnitTestCase.assertEquals(Keyword.FINAL, ((keyword33 as KeywordToken)).keyword);
     JUnitTestCase.assertNull(result.type);
   }
   void test_parseFinalConstVarOrType_final_type() {
     FinalConstVarOrType result = ParserTestCase.parse("parseFinalConstVarOrType", <Object> [false], "final A a");
-    Token keyword32 = result.keyword;
-    JUnitTestCase.assertNotNull(keyword32);
-    JUnitTestCase.assertEquals(TokenType.KEYWORD, keyword32.type);
-    JUnitTestCase.assertEquals(Keyword.FINAL, ((keyword32 as KeywordToken)).keyword);
+    Token keyword34 = result.keyword;
+    JUnitTestCase.assertNotNull(keyword34);
+    JUnitTestCase.assertEquals(TokenType.KEYWORD, keyword34.type);
+    JUnitTestCase.assertEquals(Keyword.FINAL, ((keyword34 as KeywordToken)).keyword);
     JUnitTestCase.assertNotNull(result.type);
   }
   void test_parseFinalConstVarOrType_type_parameterized() {
@@ -2532,16 +1595,16 @@
   }
   void test_parseFinalConstVarOrType_var() {
     FinalConstVarOrType result = ParserTestCase.parse("parseFinalConstVarOrType", <Object> [false], "var");
-    Token keyword33 = result.keyword;
-    JUnitTestCase.assertNotNull(keyword33);
-    JUnitTestCase.assertEquals(TokenType.KEYWORD, keyword33.type);
-    JUnitTestCase.assertEquals(Keyword.VAR, ((keyword33 as KeywordToken)).keyword);
+    Token keyword35 = result.keyword;
+    JUnitTestCase.assertNotNull(keyword35);
+    JUnitTestCase.assertEquals(TokenType.KEYWORD, keyword35.type);
+    JUnitTestCase.assertEquals(Keyword.VAR, ((keyword35 as KeywordToken)).keyword);
     JUnitTestCase.assertNull(result.type);
   }
   void test_parseFormalParameter_final_withType_named() {
     ParameterKind kind = ParameterKind.NAMED;
     DefaultFormalParameter parameter = ParserTestCase.parse("parseFormalParameter", <Object> [kind], "final A a : null");
-    SimpleFormalParameter simpleParameter = (parameter.parameter as SimpleFormalParameter);
+    SimpleFormalParameter simpleParameter = parameter.parameter as SimpleFormalParameter;
     JUnitTestCase.assertNotNull(simpleParameter.identifier);
     JUnitTestCase.assertNotNull(simpleParameter.keyword);
     JUnitTestCase.assertNotNull(simpleParameter.type);
@@ -2561,7 +1624,7 @@
   void test_parseFormalParameter_final_withType_positional() {
     ParameterKind kind = ParameterKind.POSITIONAL;
     DefaultFormalParameter parameter = ParserTestCase.parse("parseFormalParameter", <Object> [kind], "final A a = null");
-    SimpleFormalParameter simpleParameter = (parameter.parameter as SimpleFormalParameter);
+    SimpleFormalParameter simpleParameter = parameter.parameter as SimpleFormalParameter;
     JUnitTestCase.assertNotNull(simpleParameter.identifier);
     JUnitTestCase.assertNotNull(simpleParameter.keyword);
     JUnitTestCase.assertNotNull(simpleParameter.type);
@@ -2573,7 +1636,7 @@
   void test_parseFormalParameter_nonFinal_withType_named() {
     ParameterKind kind = ParameterKind.NAMED;
     DefaultFormalParameter parameter = ParserTestCase.parse("parseFormalParameter", <Object> [kind], "A a : null");
-    SimpleFormalParameter simpleParameter = (parameter.parameter as SimpleFormalParameter);
+    SimpleFormalParameter simpleParameter = parameter.parameter as SimpleFormalParameter;
     JUnitTestCase.assertNotNull(simpleParameter.identifier);
     JUnitTestCase.assertNull(simpleParameter.keyword);
     JUnitTestCase.assertNotNull(simpleParameter.type);
@@ -2593,7 +1656,7 @@
   void test_parseFormalParameter_nonFinal_withType_positional() {
     ParameterKind kind = ParameterKind.POSITIONAL;
     DefaultFormalParameter parameter = ParserTestCase.parse("parseFormalParameter", <Object> [kind], "A a = null");
-    SimpleFormalParameter simpleParameter = (parameter.parameter as SimpleFormalParameter);
+    SimpleFormalParameter simpleParameter = parameter.parameter as SimpleFormalParameter;
     JUnitTestCase.assertNotNull(simpleParameter.identifier);
     JUnitTestCase.assertNull(simpleParameter.keyword);
     JUnitTestCase.assertNotNull(simpleParameter.type);
@@ -2613,7 +1676,7 @@
   void test_parseFormalParameter_var_named() {
     ParameterKind kind = ParameterKind.NAMED;
     DefaultFormalParameter parameter = ParserTestCase.parse("parseFormalParameter", <Object> [kind], "var a : null");
-    SimpleFormalParameter simpleParameter = (parameter.parameter as SimpleFormalParameter);
+    SimpleFormalParameter simpleParameter = parameter.parameter as SimpleFormalParameter;
     JUnitTestCase.assertNotNull(simpleParameter.identifier);
     JUnitTestCase.assertNotNull(simpleParameter.keyword);
     JUnitTestCase.assertNull(simpleParameter.type);
@@ -2625,7 +1688,7 @@
   void test_parseFormalParameter_var_positional() {
     ParameterKind kind = ParameterKind.POSITIONAL;
     DefaultFormalParameter parameter = ParserTestCase.parse("parseFormalParameter", <Object> [kind], "var a = null");
-    SimpleFormalParameter simpleParameter = (parameter.parameter as SimpleFormalParameter);
+    SimpleFormalParameter simpleParameter = parameter.parameter as SimpleFormalParameter;
     JUnitTestCase.assertNotNull(simpleParameter.identifier);
     JUnitTestCase.assertNotNull(simpleParameter.keyword);
     JUnitTestCase.assertNull(simpleParameter.type);
@@ -2635,7 +1698,7 @@
     JUnitTestCase.assertEquals(kind, parameter.kind);
   }
   void test_parseFormalParameterList_empty() {
-    FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "()", []);
+    FormalParameterList parameterList = ParserTestCase.parse6("parseFormalParameterList", "()", []);
     JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
     JUnitTestCase.assertNull(parameterList.leftDelimiter);
     EngineTestCase.assertSize(0, parameterList.parameters);
@@ -2643,7 +1706,7 @@
     JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
   }
   void test_parseFormalParameterList_named_multiple() {
-    FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "({A a : 1, B b, C c : 3})", []);
+    FormalParameterList parameterList = ParserTestCase.parse6("parseFormalParameterList", "({A a : 1, B b, C c : 3})", []);
     JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
     JUnitTestCase.assertNotNull(parameterList.leftDelimiter);
     EngineTestCase.assertSize(3, parameterList.parameters);
@@ -2651,7 +1714,7 @@
     JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
   }
   void test_parseFormalParameterList_named_single() {
-    FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "({A a})", []);
+    FormalParameterList parameterList = ParserTestCase.parse6("parseFormalParameterList", "({A a})", []);
     JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
     JUnitTestCase.assertNotNull(parameterList.leftDelimiter);
     EngineTestCase.assertSize(1, parameterList.parameters);
@@ -2659,7 +1722,7 @@
     JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
   }
   void test_parseFormalParameterList_normal_multiple() {
-    FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "(A a, B b, C c)", []);
+    FormalParameterList parameterList = ParserTestCase.parse6("parseFormalParameterList", "(A a, B b, C c)", []);
     JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
     JUnitTestCase.assertNull(parameterList.leftDelimiter);
     EngineTestCase.assertSize(3, parameterList.parameters);
@@ -2667,7 +1730,7 @@
     JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
   }
   void test_parseFormalParameterList_normal_named() {
-    FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "(A a, {B b})", []);
+    FormalParameterList parameterList = ParserTestCase.parse6("parseFormalParameterList", "(A a, {B b})", []);
     JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
     JUnitTestCase.assertNotNull(parameterList.leftDelimiter);
     EngineTestCase.assertSize(2, parameterList.parameters);
@@ -2675,7 +1738,7 @@
     JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
   }
   void test_parseFormalParameterList_normal_positional() {
-    FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "(A a, [B b])", []);
+    FormalParameterList parameterList = ParserTestCase.parse6("parseFormalParameterList", "(A a, [B b])", []);
     JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
     JUnitTestCase.assertNotNull(parameterList.leftDelimiter);
     EngineTestCase.assertSize(2, parameterList.parameters);
@@ -2683,7 +1746,7 @@
     JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
   }
   void test_parseFormalParameterList_normal_single() {
-    FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "(A a)", []);
+    FormalParameterList parameterList = ParserTestCase.parse6("parseFormalParameterList", "(A a)", []);
     JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
     JUnitTestCase.assertNull(parameterList.leftDelimiter);
     EngineTestCase.assertSize(1, parameterList.parameters);
@@ -2691,7 +1754,7 @@
     JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
   }
   void test_parseFormalParameterList_positional_multiple() {
-    FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "([A a = null, B b, C c = null])", []);
+    FormalParameterList parameterList = ParserTestCase.parse6("parseFormalParameterList", "([A a = null, B b, C c = null])", []);
     JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
     JUnitTestCase.assertNotNull(parameterList.leftDelimiter);
     EngineTestCase.assertSize(3, parameterList.parameters);
@@ -2699,7 +1762,7 @@
     JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
   }
   void test_parseFormalParameterList_positional_single() {
-    FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "([A a = null])", []);
+    FormalParameterList parameterList = ParserTestCase.parse6("parseFormalParameterList", "([A a = null])", []);
     JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
     JUnitTestCase.assertNotNull(parameterList.leftDelimiter);
     EngineTestCase.assertSize(1, parameterList.parameters);
@@ -2707,47 +1770,47 @@
     JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
   }
   void test_parseForStatement_each_identifier() {
-    ForEachStatement statement = ParserTestCase.parse5("parseForStatement", "for (element in list) {}", []);
+    ForEachStatement statement = ParserTestCase.parse6("parseForStatement", "for (element in list) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
-    JUnitTestCase.assertNotNull(statement.loopParameter);
+    JUnitTestCase.assertNotNull(statement.loopVariable);
     JUnitTestCase.assertNotNull(statement.inKeyword);
     JUnitTestCase.assertNotNull(statement.iterator);
     JUnitTestCase.assertNotNull(statement.rightParenthesis);
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseForStatement_each_noType() {
-    ForEachStatement statement = ParserTestCase.parse5("parseForStatement", "for (element in list) {}", []);
+    ForEachStatement statement = ParserTestCase.parse6("parseForStatement", "for (element in list) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
-    JUnitTestCase.assertNotNull(statement.loopParameter);
+    JUnitTestCase.assertNotNull(statement.loopVariable);
     JUnitTestCase.assertNotNull(statement.inKeyword);
     JUnitTestCase.assertNotNull(statement.iterator);
     JUnitTestCase.assertNotNull(statement.rightParenthesis);
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseForStatement_each_type() {
-    ForEachStatement statement = ParserTestCase.parse5("parseForStatement", "for (A element in list) {}", []);
+    ForEachStatement statement = ParserTestCase.parse6("parseForStatement", "for (A element in list) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
-    JUnitTestCase.assertNotNull(statement.loopParameter);
+    JUnitTestCase.assertNotNull(statement.loopVariable);
     JUnitTestCase.assertNotNull(statement.inKeyword);
     JUnitTestCase.assertNotNull(statement.iterator);
     JUnitTestCase.assertNotNull(statement.rightParenthesis);
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseForStatement_each_var() {
-    ForEachStatement statement = ParserTestCase.parse5("parseForStatement", "for (var element in list) {}", []);
+    ForEachStatement statement = ParserTestCase.parse6("parseForStatement", "for (var element in list) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
-    JUnitTestCase.assertNotNull(statement.loopParameter);
+    JUnitTestCase.assertNotNull(statement.loopVariable);
     JUnitTestCase.assertNotNull(statement.inKeyword);
     JUnitTestCase.assertNotNull(statement.iterator);
     JUnitTestCase.assertNotNull(statement.rightParenthesis);
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseForStatement_loop_c() {
-    ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (; i < count;) {}", []);
+    ForStatement statement = ParserTestCase.parse6("parseForStatement", "for (; i < count;) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNull(statement.variables);
@@ -2760,7 +1823,7 @@
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseForStatement_loop_cu() {
-    ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (; i < count; i++) {}", []);
+    ForStatement statement = ParserTestCase.parse6("parseForStatement", "for (; i < count; i++) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNull(statement.variables);
@@ -2773,7 +1836,7 @@
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseForStatement_loop_ecu() {
-    ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (i--; i < count; i++) {}", []);
+    ForStatement statement = ParserTestCase.parse6("parseForStatement", "for (i--; i < count; i++) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNull(statement.variables);
@@ -2786,7 +1849,7 @@
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseForStatement_loop_i() {
-    ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (var i = 0;;) {}", []);
+    ForStatement statement = ParserTestCase.parse6("parseForStatement", "for (var i = 0;;) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     VariableDeclarationList variables8 = statement.variables;
@@ -2801,7 +1864,7 @@
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseForStatement_loop_ic() {
-    ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (var i = 0; i < count;) {}", []);
+    ForStatement statement = ParserTestCase.parse6("parseForStatement", "for (var i = 0; i < count;) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     VariableDeclarationList variables9 = statement.variables;
@@ -2816,7 +1879,7 @@
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseForStatement_loop_icu() {
-    ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (var i = 0; i < count; i++) {}", []);
+    ForStatement statement = ParserTestCase.parse6("parseForStatement", "for (var i = 0; i < count; i++) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     VariableDeclarationList variables10 = statement.variables;
@@ -2831,7 +1894,7 @@
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseForStatement_loop_iicuu() {
-    ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (int i = 0, j = count; i < j; i++, j--) {}", []);
+    ForStatement statement = ParserTestCase.parse6("parseForStatement", "for (int i = 0, j = count; i < j; i++, j--) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     VariableDeclarationList variables11 = statement.variables;
@@ -2846,7 +1909,7 @@
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseForStatement_loop_iu() {
-    ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (var i = 0;; i++) {}", []);
+    ForStatement statement = ParserTestCase.parse6("parseForStatement", "for (var i = 0;; i++) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     VariableDeclarationList variables12 = statement.variables;
@@ -2861,7 +1924,7 @@
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseForStatement_loop_u() {
-    ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (;; i++) {}", []);
+    ForStatement statement = ParserTestCase.parse6("parseForStatement", "for (;; i++) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNull(statement.variables);
@@ -2890,20 +1953,7 @@
   void test_parseFunctionDeclaration_function() {
     Comment comment = Comment.createDocumentationComment(new List<Token>(0));
     TypeName returnType = new TypeName.full(new SimpleIdentifier.full(null), null);
-    FunctionDeclaration declaration = ParserTestCase.parse("parseFunctionDeclaration", <Object> [commentAndMetadata(comment, []), null, returnType, false], "f() {}");
-    JUnitTestCase.assertEquals(comment, declaration.documentationComment);
-    JUnitTestCase.assertEquals(returnType, declaration.returnType);
-    JUnitTestCase.assertNotNull(declaration.name);
-    FunctionExpression expression = declaration.functionExpression;
-    JUnitTestCase.assertNotNull(expression);
-    JUnitTestCase.assertNotNull(expression.body);
-    JUnitTestCase.assertNotNull(expression.parameters);
-    JUnitTestCase.assertNull(declaration.propertyKeyword);
-  }
-  void test_parseFunctionDeclaration_function_inStatement() {
-    Comment comment = Comment.createDocumentationComment(new List<Token>(0));
-    TypeName returnType = new TypeName.full(new SimpleIdentifier.full(null), null);
-    FunctionDeclaration declaration = ParserTestCase.parse("parseFunctionDeclaration", <Object> [commentAndMetadata(comment, []), null, returnType, true], "f() {};");
+    FunctionDeclaration declaration = ParserTestCase.parse("parseFunctionDeclaration", <Object> [commentAndMetadata(comment, []), null, returnType], "f() {}");
     JUnitTestCase.assertEquals(comment, declaration.documentationComment);
     JUnitTestCase.assertEquals(returnType, declaration.returnType);
     JUnitTestCase.assertNotNull(declaration.name);
@@ -2916,7 +1966,7 @@
   void test_parseFunctionDeclaration_getter() {
     Comment comment = Comment.createDocumentationComment(new List<Token>(0));
     TypeName returnType = new TypeName.full(new SimpleIdentifier.full(null), null);
-    FunctionDeclaration declaration = ParserTestCase.parse("parseFunctionDeclaration", <Object> [commentAndMetadata(comment, []), null, returnType, false], "get p => 0;");
+    FunctionDeclaration declaration = ParserTestCase.parse("parseFunctionDeclaration", <Object> [commentAndMetadata(comment, []), null, returnType], "get p => 0;");
     JUnitTestCase.assertEquals(comment, declaration.documentationComment);
     JUnitTestCase.assertEquals(returnType, declaration.returnType);
     JUnitTestCase.assertNotNull(declaration.name);
@@ -2929,7 +1979,7 @@
   void test_parseFunctionDeclaration_setter() {
     Comment comment = Comment.createDocumentationComment(new List<Token>(0));
     TypeName returnType = new TypeName.full(new SimpleIdentifier.full(null), null);
-    FunctionDeclaration declaration = ParserTestCase.parse("parseFunctionDeclaration", <Object> [commentAndMetadata(comment, []), null, returnType, false], "set p(v) {}");
+    FunctionDeclaration declaration = ParserTestCase.parse("parseFunctionDeclaration", <Object> [commentAndMetadata(comment, []), null, returnType], "set p(v) {}");
     JUnitTestCase.assertEquals(comment, declaration.documentationComment);
     JUnitTestCase.assertEquals(returnType, declaration.returnType);
     JUnitTestCase.assertNotNull(declaration.name);
@@ -2940,17 +1990,17 @@
     JUnitTestCase.assertNotNull(declaration.propertyKeyword);
   }
   void test_parseFunctionDeclarationStatement() {
-    FunctionDeclarationStatement statement = ParserTestCase.parse5("parseFunctionDeclarationStatement", "void f(int p) => p * 2;", []);
+    FunctionDeclarationStatement statement = ParserTestCase.parse6("parseFunctionDeclarationStatement", "void f(int p) => p * 2;", []);
     JUnitTestCase.assertNotNull(statement.functionDeclaration);
   }
   void test_parseFunctionExpression_body_inExpression() {
-    FunctionExpression expression = ParserTestCase.parse5("parseFunctionExpression", "(int i) => i++", []);
+    FunctionExpression expression = ParserTestCase.parse6("parseFunctionExpression", "(int i) => i++", []);
     JUnitTestCase.assertNotNull(expression.body);
     JUnitTestCase.assertNotNull(expression.parameters);
     JUnitTestCase.assertNull(((expression.body as ExpressionFunctionBody)).semicolon);
   }
   void test_parseFunctionExpression_minimal() {
-    FunctionExpression expression = ParserTestCase.parse5("parseFunctionExpression", "() {}", []);
+    FunctionExpression expression = ParserTestCase.parse6("parseFunctionExpression", "() {}", []);
     JUnitTestCase.assertNotNull(expression.body);
     JUnitTestCase.assertNotNull(expression.parameters);
   }
@@ -2984,15 +2034,15 @@
     JUnitTestCase.assertEquals(returnType, method.returnType);
   }
   void test_parseIdentifierList_multiple() {
-    List<SimpleIdentifier> list = ParserTestCase.parse5("parseIdentifierList", "a, b, c", []);
+    List<SimpleIdentifier> list = ParserTestCase.parse6("parseIdentifierList", "a, b, c", []);
     EngineTestCase.assertSize(3, list);
   }
   void test_parseIdentifierList_single() {
-    List<SimpleIdentifier> list = ParserTestCase.parse5("parseIdentifierList", "a", []);
+    List<SimpleIdentifier> list = ParserTestCase.parse6("parseIdentifierList", "a", []);
     EngineTestCase.assertSize(1, list);
   }
   void test_parseIfStatement_else_block() {
-    IfStatement statement = ParserTestCase.parse5("parseIfStatement", "if (x) {} else {}", []);
+    IfStatement statement = ParserTestCase.parse6("parseIfStatement", "if (x) {} else {}", []);
     JUnitTestCase.assertNotNull(statement.ifKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.condition);
@@ -3002,7 +2052,7 @@
     JUnitTestCase.assertNotNull(statement.elseStatement);
   }
   void test_parseIfStatement_else_statement() {
-    IfStatement statement = ParserTestCase.parse5("parseIfStatement", "if (x) f(x); else f(y);", []);
+    IfStatement statement = ParserTestCase.parse6("parseIfStatement", "if (x) f(x); else f(y);", []);
     JUnitTestCase.assertNotNull(statement.ifKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.condition);
@@ -3012,7 +2062,7 @@
     JUnitTestCase.assertNotNull(statement.elseStatement);
   }
   void test_parseIfStatement_noElse_block() {
-    IfStatement statement = ParserTestCase.parse5("parseIfStatement", "if (x) {}", []);
+    IfStatement statement = ParserTestCase.parse6("parseIfStatement", "if (x) {}", []);
     JUnitTestCase.assertNotNull(statement.ifKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.condition);
@@ -3022,7 +2072,7 @@
     JUnitTestCase.assertNull(statement.elseStatement);
   }
   void test_parseIfStatement_noElse_statement() {
-    IfStatement statement = ParserTestCase.parse5("parseIfStatement", "if (x) f(x);", []);
+    IfStatement statement = ParserTestCase.parse6("parseIfStatement", "if (x) f(x);", []);
     JUnitTestCase.assertNotNull(statement.ifKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.condition);
@@ -3032,12 +2082,12 @@
     JUnitTestCase.assertNull(statement.elseStatement);
   }
   void test_parseImplementsClause_multiple() {
-    ImplementsClause clause = ParserTestCase.parse5("parseImplementsClause", "implements A, B, C", []);
+    ImplementsClause clause = ParserTestCase.parse6("parseImplementsClause", "implements A, B, C", []);
     EngineTestCase.assertSize(3, clause.interfaces);
     JUnitTestCase.assertNotNull(clause.keyword);
   }
   void test_parseImplementsClause_single() {
-    ImplementsClause clause = ParserTestCase.parse5("parseImplementsClause", "implements A", []);
+    ImplementsClause clause = ParserTestCase.parse6("parseImplementsClause", "implements A", []);
     EngineTestCase.assertSize(1, clause.interfaces);
     JUnitTestCase.assertNotNull(clause.keyword);
   }
@@ -3101,11 +2151,11 @@
     TypeName type = new TypeName.full(new SimpleIdentifier.full(null), null);
     FieldDeclaration declaration = ParserTestCase.parse("parseInitializedIdentifierList", <Object> [commentAndMetadata(comment, []), staticKeyword, null, type], "a = 1, b, c = 3;");
     JUnitTestCase.assertEquals(comment, declaration.documentationComment);
-    VariableDeclarationList fields3 = declaration.fields;
-    JUnitTestCase.assertNotNull(fields3);
-    JUnitTestCase.assertNull(fields3.keyword);
-    JUnitTestCase.assertEquals(type, fields3.type);
-    EngineTestCase.assertSize(3, fields3.variables);
+    VariableDeclarationList fields4 = declaration.fields;
+    JUnitTestCase.assertNotNull(fields4);
+    JUnitTestCase.assertNull(fields4.keyword);
+    JUnitTestCase.assertEquals(type, fields4.type);
+    EngineTestCase.assertSize(3, fields4.variables);
     JUnitTestCase.assertEquals(staticKeyword, declaration.keyword);
     JUnitTestCase.assertNotNull(declaration.semicolon);
   }
@@ -3115,11 +2165,11 @@
     Token varKeyword = TokenFactory.token(Keyword.VAR);
     FieldDeclaration declaration = ParserTestCase.parse("parseInitializedIdentifierList", <Object> [commentAndMetadata(comment, []), staticKeyword, varKeyword, null], "a = 1, b, c = 3;");
     JUnitTestCase.assertEquals(comment, declaration.documentationComment);
-    VariableDeclarationList fields4 = declaration.fields;
-    JUnitTestCase.assertNotNull(fields4);
-    JUnitTestCase.assertEquals(varKeyword, fields4.keyword);
-    JUnitTestCase.assertNull(fields4.type);
-    EngineTestCase.assertSize(3, fields4.variables);
+    VariableDeclarationList fields5 = declaration.fields;
+    JUnitTestCase.assertNotNull(fields5);
+    JUnitTestCase.assertEquals(varKeyword, fields5.keyword);
+    JUnitTestCase.assertNull(fields5.type);
+    EngineTestCase.assertSize(3, fields5.variables);
     JUnitTestCase.assertEquals(staticKeyword, declaration.keyword);
     JUnitTestCase.assertNotNull(declaration.semicolon);
   }
@@ -3175,12 +2225,12 @@
   }
   void test_parseLibraryIdentifier_multiple() {
     String name = "a.b.c";
-    LibraryIdentifier identifier = ParserTestCase.parse5("parseLibraryIdentifier", name, []);
+    LibraryIdentifier identifier = ParserTestCase.parse6("parseLibraryIdentifier", name, []);
     JUnitTestCase.assertEquals(name, identifier.name);
   }
   void test_parseLibraryIdentifier_single() {
     String name = "a";
-    LibraryIdentifier identifier = ParserTestCase.parse5("parseLibraryIdentifier", name, []);
+    LibraryIdentifier identifier = ParserTestCase.parse6("parseLibraryIdentifier", name, []);
     JUnitTestCase.assertEquals(name, identifier.name);
   }
   void test_parseListLiteral_empty_oneToken() {
@@ -3252,14 +2302,14 @@
     JUnitTestCase.assertNotNull(literal.rightBracket);
   }
   void test_parseLogicalAndExpression() {
-    BinaryExpression expression = ParserTestCase.parse5("parseLogicalAndExpression", "x && y", []);
+    BinaryExpression expression = ParserTestCase.parse6("parseLogicalAndExpression", "x && y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.AMPERSAND_AMPERSAND, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseLogicalOrExpression() {
-    BinaryExpression expression = ParserTestCase.parse5("parseLogicalOrExpression", "x || y", []);
+    BinaryExpression expression = ParserTestCase.parse6("parseLogicalOrExpression", "x || y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.BAR_BAR, expression.operator.type);
@@ -3288,55 +2338,55 @@
     JUnitTestCase.assertNotNull(literal.rightBracket);
   }
   void test_parseMapLiteralEntry() {
-    MapLiteralEntry entry = ParserTestCase.parse5("parseMapLiteralEntry", "'x' : y", []);
+    MapLiteralEntry entry = ParserTestCase.parse6("parseMapLiteralEntry", "'x' : y", []);
     JUnitTestCase.assertNotNull(entry.key);
     JUnitTestCase.assertNotNull(entry.separator);
     JUnitTestCase.assertNotNull(entry.value);
   }
   void test_parseModifiers_abstract() {
-    Modifiers modifiers = ParserTestCase.parse5("parseModifiers", "abstract A", []);
+    Modifiers modifiers = ParserTestCase.parse6("parseModifiers", "abstract A", []);
     JUnitTestCase.assertNotNull(modifiers.abstractKeyword);
   }
   void test_parseModifiers_const() {
-    Modifiers modifiers = ParserTestCase.parse5("parseModifiers", "const A", []);
+    Modifiers modifiers = ParserTestCase.parse6("parseModifiers", "const A", []);
     JUnitTestCase.assertNotNull(modifiers.constKeyword);
   }
   void test_parseModifiers_external() {
-    Modifiers modifiers = ParserTestCase.parse5("parseModifiers", "external A", []);
+    Modifiers modifiers = ParserTestCase.parse6("parseModifiers", "external A", []);
     JUnitTestCase.assertNotNull(modifiers.externalKeyword);
   }
   void test_parseModifiers_factory() {
-    Modifiers modifiers = ParserTestCase.parse5("parseModifiers", "factory A", []);
+    Modifiers modifiers = ParserTestCase.parse6("parseModifiers", "factory A", []);
     JUnitTestCase.assertNotNull(modifiers.factoryKeyword);
   }
   void test_parseModifiers_final() {
-    Modifiers modifiers = ParserTestCase.parse5("parseModifiers", "final A", []);
+    Modifiers modifiers = ParserTestCase.parse6("parseModifiers", "final A", []);
     JUnitTestCase.assertNotNull(modifiers.finalKeyword);
   }
   void test_parseModifiers_static() {
-    Modifiers modifiers = ParserTestCase.parse5("parseModifiers", "static A", []);
+    Modifiers modifiers = ParserTestCase.parse6("parseModifiers", "static A", []);
     JUnitTestCase.assertNotNull(modifiers.staticKeyword);
   }
   void test_parseModifiers_var() {
-    Modifiers modifiers = ParserTestCase.parse5("parseModifiers", "var A", []);
+    Modifiers modifiers = ParserTestCase.parse6("parseModifiers", "var A", []);
     JUnitTestCase.assertNotNull(modifiers.varKeyword);
   }
   void test_parseMultiplicativeExpression_normal() {
-    BinaryExpression expression = ParserTestCase.parse5("parseMultiplicativeExpression", "x * y", []);
+    BinaryExpression expression = ParserTestCase.parse6("parseMultiplicativeExpression", "x * y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.STAR, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseMultiplicativeExpression_super() {
-    BinaryExpression expression = ParserTestCase.parse5("parseMultiplicativeExpression", "super * y", []);
+    BinaryExpression expression = ParserTestCase.parse6("parseMultiplicativeExpression", "super * y", []);
     EngineTestCase.assertInstanceOf(SuperExpression, expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.STAR, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseNewExpression() {
-    InstanceCreationExpression expression = ParserTestCase.parse5("parseNewExpression", "new A()", []);
+    InstanceCreationExpression expression = ParserTestCase.parse6("parseNewExpression", "new A()", []);
     JUnitTestCase.assertNotNull(expression.keyword);
     ConstructorName name = expression.constructorName;
     JUnitTestCase.assertNotNull(name);
@@ -3346,56 +2396,56 @@
     JUnitTestCase.assertNotNull(expression.argumentList);
   }
   void test_parseNonLabeledStatement_const_list_empty() {
-    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "const [];", []);
+    ExpressionStatement statement = ParserTestCase.parse6("parseNonLabeledStatement", "const [];", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNonLabeledStatement_const_list_nonEmpty() {
-    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "const [1, 2];", []);
+    ExpressionStatement statement = ParserTestCase.parse6("parseNonLabeledStatement", "const [1, 2];", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNonLabeledStatement_const_map_empty() {
-    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "const {};", []);
+    ExpressionStatement statement = ParserTestCase.parse6("parseNonLabeledStatement", "const {};", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNonLabeledStatement_const_map_nonEmpty() {
-    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "const {'a' : 1};", []);
+    ExpressionStatement statement = ParserTestCase.parse6("parseNonLabeledStatement", "const {'a' : 1};", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNonLabeledStatement_const_object() {
-    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "const A();", []);
+    ExpressionStatement statement = ParserTestCase.parse6("parseNonLabeledStatement", "const A();", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNonLabeledStatement_const_object_named_typeParameters() {
-    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "const A<B>.c();", []);
+    ExpressionStatement statement = ParserTestCase.parse6("parseNonLabeledStatement", "const A<B>.c();", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNonLabeledStatement_constructorInvocation() {
-    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "new C().m();", []);
+    ExpressionStatement statement = ParserTestCase.parse6("parseNonLabeledStatement", "new C().m();", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNonLabeledStatement_false() {
-    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "false;", []);
+    ExpressionStatement statement = ParserTestCase.parse6("parseNonLabeledStatement", "false;", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNonLabeledStatement_functionDeclaration() {
-    ParserTestCase.parse5("parseNonLabeledStatement", "f() {};", []);
+    ParserTestCase.parse6("parseNonLabeledStatement", "f() {};", []);
   }
   void test_parseNonLabeledStatement_functionDeclaration_arguments() {
-    ParserTestCase.parse5("parseNonLabeledStatement", "f(void g()) {};", []);
+    ParserTestCase.parse6("parseNonLabeledStatement", "f(void g()) {};", []);
   }
   void test_parseNonLabeledStatement_functionExpressionIndex() {
-    ParserTestCase.parse5("parseNonLabeledStatement", "() {}[0] = null;", []);
+    ParserTestCase.parse6("parseNonLabeledStatement", "() {}[0] = null;", []);
   }
   void test_parseNonLabeledStatement_functionInvocation() {
-    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "f();", []);
+    ExpressionStatement statement = ParserTestCase.parse6("parseNonLabeledStatement", "f();", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNonLabeledStatement_invokeFunctionExpression() {
-    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "(a) {return a + a;} (3);", []);
+    ExpressionStatement statement = ParserTestCase.parse6("parseNonLabeledStatement", "(a) {return a + a;} (3);", []);
     EngineTestCase.assertInstanceOf(FunctionExpressionInvocation, statement.expression);
-    FunctionExpressionInvocation invocation = (statement.expression as FunctionExpressionInvocation);
+    FunctionExpressionInvocation invocation = statement.expression as FunctionExpressionInvocation;
     EngineTestCase.assertInstanceOf(FunctionExpression, invocation.function);
-    FunctionExpression expression = (invocation.function as FunctionExpression);
+    FunctionExpression expression = invocation.function as FunctionExpression;
     JUnitTestCase.assertNotNull(expression.parameters);
     JUnitTestCase.assertNotNull(expression.body);
     ArgumentList list = invocation.argumentList;
@@ -3403,113 +2453,113 @@
     EngineTestCase.assertSize(1, list.arguments);
   }
   void test_parseNonLabeledStatement_null() {
-    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "null;", []);
+    ExpressionStatement statement = ParserTestCase.parse6("parseNonLabeledStatement", "null;", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNonLabeledStatement_startingWithBuiltInIdentifier() {
-    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "library.getName();", []);
+    ExpressionStatement statement = ParserTestCase.parse6("parseNonLabeledStatement", "library.getName();", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNonLabeledStatement_true() {
-    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "true;", []);
+    ExpressionStatement statement = ParserTestCase.parse6("parseNonLabeledStatement", "true;", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNonLabeledStatement_typeCast() {
-    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "double.NAN as num;", []);
+    ExpressionStatement statement = ParserTestCase.parse6("parseNonLabeledStatement", "double.NAN as num;", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNormalFormalParameter_field_const_noType() {
-    FieldFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "const this.a)", []);
+    FieldFormalParameter parameter = ParserTestCase.parse6("parseNormalFormalParameter", "const this.a)", []);
     JUnitTestCase.assertNotNull(parameter.keyword);
     JUnitTestCase.assertNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseNormalFormalParameter_field_const_type() {
-    FieldFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "const A this.a)", []);
+    FieldFormalParameter parameter = ParserTestCase.parse6("parseNormalFormalParameter", "const A this.a)", []);
     JUnitTestCase.assertNotNull(parameter.keyword);
     JUnitTestCase.assertNotNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseNormalFormalParameter_field_final_noType() {
-    FieldFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "final this.a)", []);
+    FieldFormalParameter parameter = ParserTestCase.parse6("parseNormalFormalParameter", "final this.a)", []);
     JUnitTestCase.assertNotNull(parameter.keyword);
     JUnitTestCase.assertNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseNormalFormalParameter_field_final_type() {
-    FieldFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "final A this.a)", []);
+    FieldFormalParameter parameter = ParserTestCase.parse6("parseNormalFormalParameter", "final A this.a)", []);
     JUnitTestCase.assertNotNull(parameter.keyword);
     JUnitTestCase.assertNotNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseNormalFormalParameter_field_noType() {
-    FieldFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "this.a)", []);
+    FieldFormalParameter parameter = ParserTestCase.parse6("parseNormalFormalParameter", "this.a)", []);
     JUnitTestCase.assertNull(parameter.keyword);
     JUnitTestCase.assertNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseNormalFormalParameter_field_type() {
-    FieldFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "A this.a)", []);
+    FieldFormalParameter parameter = ParserTestCase.parse6("parseNormalFormalParameter", "A this.a)", []);
     JUnitTestCase.assertNull(parameter.keyword);
     JUnitTestCase.assertNotNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseNormalFormalParameter_field_var() {
-    FieldFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "var this.a)", []);
+    FieldFormalParameter parameter = ParserTestCase.parse6("parseNormalFormalParameter", "var this.a)", []);
     JUnitTestCase.assertNotNull(parameter.keyword);
     JUnitTestCase.assertNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseNormalFormalParameter_function_noType() {
-    FunctionTypedFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "a())", []);
+    FunctionTypedFormalParameter parameter = ParserTestCase.parse6("parseNormalFormalParameter", "a())", []);
     JUnitTestCase.assertNull(parameter.returnType);
     JUnitTestCase.assertNotNull(parameter.identifier);
     JUnitTestCase.assertNotNull(parameter.parameters);
   }
   void test_parseNormalFormalParameter_function_type() {
-    FunctionTypedFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "A a())", []);
+    FunctionTypedFormalParameter parameter = ParserTestCase.parse6("parseNormalFormalParameter", "A a())", []);
     JUnitTestCase.assertNotNull(parameter.returnType);
     JUnitTestCase.assertNotNull(parameter.identifier);
     JUnitTestCase.assertNotNull(parameter.parameters);
   }
   void test_parseNormalFormalParameter_function_void() {
-    FunctionTypedFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "void a())", []);
+    FunctionTypedFormalParameter parameter = ParserTestCase.parse6("parseNormalFormalParameter", "void a())", []);
     JUnitTestCase.assertNotNull(parameter.returnType);
     JUnitTestCase.assertNotNull(parameter.identifier);
     JUnitTestCase.assertNotNull(parameter.parameters);
   }
   void test_parseNormalFormalParameter_simple_const_noType() {
-    SimpleFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "const a)", []);
+    SimpleFormalParameter parameter = ParserTestCase.parse6("parseNormalFormalParameter", "const a)", []);
     JUnitTestCase.assertNotNull(parameter.keyword);
     JUnitTestCase.assertNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseNormalFormalParameter_simple_const_type() {
-    SimpleFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "const A a)", []);
+    SimpleFormalParameter parameter = ParserTestCase.parse6("parseNormalFormalParameter", "const A a)", []);
     JUnitTestCase.assertNotNull(parameter.keyword);
     JUnitTestCase.assertNotNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseNormalFormalParameter_simple_final_noType() {
-    SimpleFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "final a)", []);
+    SimpleFormalParameter parameter = ParserTestCase.parse6("parseNormalFormalParameter", "final a)", []);
     JUnitTestCase.assertNotNull(parameter.keyword);
     JUnitTestCase.assertNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseNormalFormalParameter_simple_final_type() {
-    SimpleFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "final A a)", []);
+    SimpleFormalParameter parameter = ParserTestCase.parse6("parseNormalFormalParameter", "final A a)", []);
     JUnitTestCase.assertNotNull(parameter.keyword);
     JUnitTestCase.assertNotNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseNormalFormalParameter_simple_noType() {
-    SimpleFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "a)", []);
+    SimpleFormalParameter parameter = ParserTestCase.parse6("parseNormalFormalParameter", "a)", []);
     JUnitTestCase.assertNull(parameter.keyword);
     JUnitTestCase.assertNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseNormalFormalParameter_simple_type() {
-    SimpleFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "A a)", []);
+    SimpleFormalParameter parameter = ParserTestCase.parse6("parseNormalFormalParameter", "A a)", []);
     JUnitTestCase.assertNull(parameter.keyword);
     JUnitTestCase.assertNotNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
@@ -3544,144 +2594,144 @@
     JUnitTestCase.assertNotNull(directive.semicolon);
   }
   void test_parsePostfixExpression_decrement() {
-    PostfixExpression expression = ParserTestCase.parse5("parsePostfixExpression", "i--", []);
+    PostfixExpression expression = ParserTestCase.parse6("parsePostfixExpression", "i--", []);
     JUnitTestCase.assertNotNull(expression.operand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.MINUS_MINUS, expression.operator.type);
   }
   void test_parsePostfixExpression_increment() {
-    PostfixExpression expression = ParserTestCase.parse5("parsePostfixExpression", "i++", []);
+    PostfixExpression expression = ParserTestCase.parse6("parsePostfixExpression", "i++", []);
     JUnitTestCase.assertNotNull(expression.operand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.PLUS_PLUS, expression.operator.type);
   }
   void test_parsePostfixExpression_none_indexExpression() {
-    IndexExpression expression = ParserTestCase.parse5("parsePostfixExpression", "a[0]", []);
+    IndexExpression expression = ParserTestCase.parse6("parsePostfixExpression", "a[0]", []);
     JUnitTestCase.assertNotNull(expression.array);
     JUnitTestCase.assertNotNull(expression.index);
   }
   void test_parsePostfixExpression_none_methodInvocation() {
-    MethodInvocation expression = ParserTestCase.parse5("parsePostfixExpression", "a.m()", []);
+    MethodInvocation expression = ParserTestCase.parse6("parsePostfixExpression", "a.m()", []);
     JUnitTestCase.assertNotNull(expression.target);
     JUnitTestCase.assertNotNull(expression.methodName);
     JUnitTestCase.assertNotNull(expression.argumentList);
   }
   void test_parsePostfixExpression_none_propertyAccess() {
-    PrefixedIdentifier expression = ParserTestCase.parse5("parsePostfixExpression", "a.b", []);
+    PrefixedIdentifier expression = ParserTestCase.parse6("parsePostfixExpression", "a.b", []);
     JUnitTestCase.assertNotNull(expression.prefix);
     JUnitTestCase.assertNotNull(expression.identifier);
   }
   void test_parsePrefixedIdentifier_noPrefix() {
     String lexeme = "bar";
-    SimpleIdentifier identifier = ParserTestCase.parse5("parsePrefixedIdentifier", lexeme, []);
+    SimpleIdentifier identifier = ParserTestCase.parse6("parsePrefixedIdentifier", lexeme, []);
     JUnitTestCase.assertNotNull(identifier.token);
     JUnitTestCase.assertEquals(lexeme, identifier.name);
   }
   void test_parsePrefixedIdentifier_prefix() {
     String lexeme = "foo.bar";
-    PrefixedIdentifier identifier = ParserTestCase.parse5("parsePrefixedIdentifier", lexeme, []);
+    PrefixedIdentifier identifier = ParserTestCase.parse6("parsePrefixedIdentifier", lexeme, []);
     JUnitTestCase.assertEquals("foo", identifier.prefix.name);
     JUnitTestCase.assertNotNull(identifier.period);
     JUnitTestCase.assertEquals("bar", identifier.identifier.name);
   }
   void test_parsePrimaryExpression_argumentDefinitionTest() {
-    ArgumentDefinitionTest expression = ParserTestCase.parse5("parseArgumentDefinitionTest", "?a", []);
+    ArgumentDefinitionTest expression = ParserTestCase.parse6("parseArgumentDefinitionTest", "?a", []);
     JUnitTestCase.assertNotNull(expression.question);
     JUnitTestCase.assertNotNull(expression.identifier);
   }
   void test_parsePrimaryExpression_const() {
-    InstanceCreationExpression expression = ParserTestCase.parse5("parsePrimaryExpression", "const A()", []);
+    InstanceCreationExpression expression = ParserTestCase.parse6("parsePrimaryExpression", "const A()", []);
     JUnitTestCase.assertNotNull(expression);
   }
   void test_parsePrimaryExpression_double() {
     String doubleLiteral = "3.2e4";
-    DoubleLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", doubleLiteral, []);
+    DoubleLiteral literal = ParserTestCase.parse6("parsePrimaryExpression", doubleLiteral, []);
     JUnitTestCase.assertNotNull(literal.literal);
     JUnitTestCase.assertEquals(double.parse(doubleLiteral), literal.value);
   }
   void test_parsePrimaryExpression_false() {
-    BooleanLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "false", []);
+    BooleanLiteral literal = ParserTestCase.parse6("parsePrimaryExpression", "false", []);
     JUnitTestCase.assertNotNull(literal.literal);
     JUnitTestCase.assertFalse(literal.value);
   }
   void test_parsePrimaryExpression_function_arguments() {
-    FunctionExpression expression = ParserTestCase.parse5("parsePrimaryExpression", "(int i) => i + 1", []);
+    FunctionExpression expression = ParserTestCase.parse6("parsePrimaryExpression", "(int i) => i + 1", []);
     JUnitTestCase.assertNotNull(expression.parameters);
     JUnitTestCase.assertNotNull(expression.body);
   }
   void test_parsePrimaryExpression_function_noArguments() {
-    FunctionExpression expression = ParserTestCase.parse5("parsePrimaryExpression", "() => 42", []);
+    FunctionExpression expression = ParserTestCase.parse6("parsePrimaryExpression", "() => 42", []);
     JUnitTestCase.assertNotNull(expression.parameters);
     JUnitTestCase.assertNotNull(expression.body);
   }
   void test_parsePrimaryExpression_hex() {
     String hexLiteral = "3F";
-    IntegerLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "0x${hexLiteral}", []);
+    IntegerLiteral literal = ParserTestCase.parse6("parsePrimaryExpression", "0x${hexLiteral}", []);
     JUnitTestCase.assertNotNull(literal.literal);
     JUnitTestCase.assertEquals(int.parse(hexLiteral, radix: 16), literal.value);
   }
   void test_parsePrimaryExpression_identifier() {
-    SimpleIdentifier identifier = ParserTestCase.parse5("parsePrimaryExpression", "a", []);
+    SimpleIdentifier identifier = ParserTestCase.parse6("parsePrimaryExpression", "a", []);
     JUnitTestCase.assertNotNull(identifier);
   }
   void test_parsePrimaryExpression_int() {
     String intLiteral = "472";
-    IntegerLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", intLiteral, []);
+    IntegerLiteral literal = ParserTestCase.parse6("parsePrimaryExpression", intLiteral, []);
     JUnitTestCase.assertNotNull(literal.literal);
     JUnitTestCase.assertEquals(int.parse(intLiteral), literal.value);
   }
   void test_parsePrimaryExpression_listLiteral() {
-    ListLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "[ ]", []);
+    ListLiteral literal = ParserTestCase.parse6("parsePrimaryExpression", "[ ]", []);
     JUnitTestCase.assertNotNull(literal);
   }
   void test_parsePrimaryExpression_listLiteral_index() {
-    ListLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "[]", []);
+    ListLiteral literal = ParserTestCase.parse6("parsePrimaryExpression", "[]", []);
     JUnitTestCase.assertNotNull(literal);
   }
   void test_parsePrimaryExpression_listLiteral_typed() {
-    ListLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "<A>[ ]", []);
+    ListLiteral literal = ParserTestCase.parse6("parsePrimaryExpression", "<A>[ ]", []);
     JUnitTestCase.assertNotNull(literal.typeArguments);
     EngineTestCase.assertSize(1, literal.typeArguments.arguments);
   }
   void test_parsePrimaryExpression_mapLiteral() {
-    MapLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "{}", []);
+    MapLiteral literal = ParserTestCase.parse6("parsePrimaryExpression", "{}", []);
     JUnitTestCase.assertNotNull(literal);
   }
   void test_parsePrimaryExpression_mapLiteral_typed() {
-    MapLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "<A>{}", []);
+    MapLiteral literal = ParserTestCase.parse6("parsePrimaryExpression", "<A>{}", []);
     JUnitTestCase.assertNotNull(literal.typeArguments);
     EngineTestCase.assertSize(1, literal.typeArguments.arguments);
   }
   void test_parsePrimaryExpression_new() {
-    InstanceCreationExpression expression = ParserTestCase.parse5("parsePrimaryExpression", "new A()", []);
+    InstanceCreationExpression expression = ParserTestCase.parse6("parsePrimaryExpression", "new A()", []);
     JUnitTestCase.assertNotNull(expression);
   }
   void test_parsePrimaryExpression_null() {
-    NullLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "null", []);
+    NullLiteral literal = ParserTestCase.parse6("parsePrimaryExpression", "null", []);
     JUnitTestCase.assertNotNull(literal.literal);
   }
   void test_parsePrimaryExpression_parenthesized() {
-    ParenthesizedExpression expression = ParserTestCase.parse5("parsePrimaryExpression", "()", []);
+    ParenthesizedExpression expression = ParserTestCase.parse6("parsePrimaryExpression", "()", []);
     JUnitTestCase.assertNotNull(expression);
   }
   void test_parsePrimaryExpression_string() {
-    SimpleStringLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "\"string\"", []);
+    SimpleStringLiteral literal = ParserTestCase.parse6("parsePrimaryExpression", "\"string\"", []);
     JUnitTestCase.assertFalse(literal.isMultiline());
     JUnitTestCase.assertEquals("string", literal.value);
   }
   void test_parsePrimaryExpression_super() {
-    PropertyAccess propertyAccess = ParserTestCase.parse5("parsePrimaryExpression", "super.x", []);
+    PropertyAccess propertyAccess = ParserTestCase.parse6("parsePrimaryExpression", "super.x", []);
     JUnitTestCase.assertTrue(propertyAccess.target is SuperExpression);
     JUnitTestCase.assertNotNull(propertyAccess.operator);
     JUnitTestCase.assertEquals(TokenType.PERIOD, propertyAccess.operator.type);
     JUnitTestCase.assertNotNull(propertyAccess.propertyName);
   }
   void test_parsePrimaryExpression_this() {
-    ThisExpression expression = ParserTestCase.parse5("parsePrimaryExpression", "this", []);
+    ThisExpression expression = ParserTestCase.parse6("parsePrimaryExpression", "this", []);
     JUnitTestCase.assertNotNull(expression.keyword);
   }
   void test_parsePrimaryExpression_true() {
-    BooleanLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "true", []);
+    BooleanLiteral literal = ParserTestCase.parse6("parsePrimaryExpression", "true", []);
     JUnitTestCase.assertNotNull(literal.literal);
     JUnitTestCase.assertTrue(literal.value);
   }
@@ -3689,72 +2739,72 @@
     JUnitTestCase.assertNotNull(new Parser(null, null));
   }
   void test_parseRedirectingConstructorInvocation_named() {
-    RedirectingConstructorInvocation invocation = ParserTestCase.parse5("parseRedirectingConstructorInvocation", "this.a()", []);
+    RedirectingConstructorInvocation invocation = ParserTestCase.parse6("parseRedirectingConstructorInvocation", "this.a()", []);
     JUnitTestCase.assertNotNull(invocation.argumentList);
     JUnitTestCase.assertNotNull(invocation.constructorName);
     JUnitTestCase.assertNotNull(invocation.keyword);
     JUnitTestCase.assertNotNull(invocation.period);
   }
   void test_parseRedirectingConstructorInvocation_unnamed() {
-    RedirectingConstructorInvocation invocation = ParserTestCase.parse5("parseRedirectingConstructorInvocation", "this()", []);
+    RedirectingConstructorInvocation invocation = ParserTestCase.parse6("parseRedirectingConstructorInvocation", "this()", []);
     JUnitTestCase.assertNotNull(invocation.argumentList);
     JUnitTestCase.assertNull(invocation.constructorName);
     JUnitTestCase.assertNotNull(invocation.keyword);
     JUnitTestCase.assertNull(invocation.period);
   }
   void test_parseRelationalExpression_as() {
-    AsExpression expression = ParserTestCase.parse5("parseRelationalExpression", "x as Y", []);
+    AsExpression expression = ParserTestCase.parse6("parseRelationalExpression", "x as Y", []);
     JUnitTestCase.assertNotNull(expression.expression);
     JUnitTestCase.assertNotNull(expression.asOperator);
     JUnitTestCase.assertNotNull(expression.type);
   }
   void test_parseRelationalExpression_is() {
-    IsExpression expression = ParserTestCase.parse5("parseRelationalExpression", "x is y", []);
+    IsExpression expression = ParserTestCase.parse6("parseRelationalExpression", "x is y", []);
     JUnitTestCase.assertNotNull(expression.expression);
     JUnitTestCase.assertNotNull(expression.isOperator);
     JUnitTestCase.assertNull(expression.notOperator);
     JUnitTestCase.assertNotNull(expression.type);
   }
   void test_parseRelationalExpression_isNot() {
-    IsExpression expression = ParserTestCase.parse5("parseRelationalExpression", "x is! y", []);
+    IsExpression expression = ParserTestCase.parse6("parseRelationalExpression", "x is! y", []);
     JUnitTestCase.assertNotNull(expression.expression);
     JUnitTestCase.assertNotNull(expression.isOperator);
     JUnitTestCase.assertNotNull(expression.notOperator);
     JUnitTestCase.assertNotNull(expression.type);
   }
   void test_parseRelationalExpression_normal() {
-    BinaryExpression expression = ParserTestCase.parse5("parseRelationalExpression", "x < y", []);
+    BinaryExpression expression = ParserTestCase.parse6("parseRelationalExpression", "x < y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.LT, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseRelationalExpression_super() {
-    BinaryExpression expression = ParserTestCase.parse5("parseRelationalExpression", "super < y", []);
+    BinaryExpression expression = ParserTestCase.parse6("parseRelationalExpression", "super < y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.LT, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseReturnStatement_noValue() {
-    ReturnStatement statement = ParserTestCase.parse5("parseReturnStatement", "return;", []);
+    ReturnStatement statement = ParserTestCase.parse6("parseReturnStatement", "return;", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNull(statement.expression);
     JUnitTestCase.assertNotNull(statement.semicolon);
   }
   void test_parseReturnStatement_value() {
-    ReturnStatement statement = ParserTestCase.parse5("parseReturnStatement", "return x;", []);
+    ReturnStatement statement = ParserTestCase.parse6("parseReturnStatement", "return x;", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNotNull(statement.expression);
     JUnitTestCase.assertNotNull(statement.semicolon);
   }
   void test_parseReturnType_nonVoid() {
-    TypeName typeName = ParserTestCase.parse5("parseReturnType", "A<B>", []);
+    TypeName typeName = ParserTestCase.parse6("parseReturnType", "A<B>", []);
     JUnitTestCase.assertNotNull(typeName.name);
     JUnitTestCase.assertNotNull(typeName.typeArguments);
   }
   void test_parseReturnType_void() {
-    TypeName typeName = ParserTestCase.parse5("parseReturnType", "void", []);
+    TypeName typeName = ParserTestCase.parse6("parseReturnType", "void", []);
     JUnitTestCase.assertNotNull(typeName.name);
     JUnitTestCase.assertNull(typeName.typeArguments);
   }
@@ -3788,14 +2838,14 @@
     JUnitTestCase.assertEquals(returnType, method.returnType);
   }
   void test_parseShiftExpression_normal() {
-    BinaryExpression expression = ParserTestCase.parse5("parseShiftExpression", "x << y", []);
+    BinaryExpression expression = ParserTestCase.parse6("parseShiftExpression", "x << y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.LT_LT, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseShiftExpression_super() {
-    BinaryExpression expression = ParserTestCase.parse5("parseShiftExpression", "super << y", []);
+    BinaryExpression expression = ParserTestCase.parse6("parseShiftExpression", "super << y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.LT_LT, expression.operator.type);
@@ -3803,32 +2853,32 @@
   }
   void test_parseSimpleIdentifier_builtInIdentifier() {
     String lexeme = "as";
-    SimpleIdentifier identifier = ParserTestCase.parse5("parseSimpleIdentifier", lexeme, []);
+    SimpleIdentifier identifier = ParserTestCase.parse6("parseSimpleIdentifier", lexeme, []);
     JUnitTestCase.assertNotNull(identifier.token);
     JUnitTestCase.assertEquals(lexeme, identifier.name);
   }
   void test_parseSimpleIdentifier_normalIdentifier() {
     String lexeme = "foo";
-    SimpleIdentifier identifier = ParserTestCase.parse5("parseSimpleIdentifier", lexeme, []);
+    SimpleIdentifier identifier = ParserTestCase.parse6("parseSimpleIdentifier", lexeme, []);
     JUnitTestCase.assertNotNull(identifier.token);
     JUnitTestCase.assertEquals(lexeme, identifier.name);
   }
   void test_parseSimpleIdentifier1_normalIdentifier() {
   }
   void test_parseStatement_functionDeclaration() {
-    FunctionDeclarationStatement statement = ParserTestCase.parse5("parseStatement", "int f(a, b) {};", []);
+    FunctionDeclarationStatement statement = ParserTestCase.parse6("parseStatement", "int f(a, b) {};", []);
     JUnitTestCase.assertNotNull(statement.functionDeclaration);
   }
   void test_parseStatement_mulipleLabels() {
-    LabeledStatement statement = ParserTestCase.parse5("parseStatement", "l: m: return x;", []);
+    LabeledStatement statement = ParserTestCase.parse6("parseStatement", "l: m: return x;", []);
     EngineTestCase.assertSize(2, statement.labels);
     JUnitTestCase.assertNotNull(statement.statement);
   }
   void test_parseStatement_noLabels() {
-    ParserTestCase.parse5("parseStatement", "return x;", []);
+    ParserTestCase.parse6("parseStatement", "return x;", []);
   }
   void test_parseStatement_singleLabel() {
-    LabeledStatement statement = ParserTestCase.parse5("parseStatement", "l: return x;", []);
+    LabeledStatement statement = ParserTestCase.parse6("parseStatement", "l: return x;", []);
     EngineTestCase.assertSize(1, statement.labels);
     JUnitTestCase.assertNotNull(statement.statement);
   }
@@ -3841,7 +2891,7 @@
     EngineTestCase.assertSize(1, statements);
   }
   void test_parseStringLiteral_adjacent() {
-    AdjacentStrings literal = ParserTestCase.parse5("parseStringLiteral", "'a' 'b'", []);
+    AdjacentStrings literal = ParserTestCase.parse6("parseStringLiteral", "'a' 'b'", []);
     NodeList<StringLiteral> strings2 = literal.strings;
     EngineTestCase.assertSize(2, strings2);
     StringLiteral firstString = strings2[0];
@@ -3850,7 +2900,7 @@
     JUnitTestCase.assertEquals("b", ((secondString as SimpleStringLiteral)).value);
   }
   void test_parseStringLiteral_interpolated() {
-    StringInterpolation literal = ParserTestCase.parse5("parseStringLiteral", "'a \${b} c \$this d'", []);
+    StringInterpolation literal = ParserTestCase.parse6("parseStringLiteral", "'a \${b} c \$this d'", []);
     NodeList<InterpolationElement> elements2 = literal.elements;
     EngineTestCase.assertSize(5, elements2);
     JUnitTestCase.assertTrue(elements2[0] is InterpolationString);
@@ -3860,26 +2910,26 @@
     JUnitTestCase.assertTrue(elements2[4] is InterpolationString);
   }
   void test_parseStringLiteral_single() {
-    SimpleStringLiteral literal = ParserTestCase.parse5("parseStringLiteral", "'a'", []);
+    SimpleStringLiteral literal = ParserTestCase.parse6("parseStringLiteral", "'a'", []);
     JUnitTestCase.assertNotNull(literal.literal);
     JUnitTestCase.assertEquals("a", literal.value);
   }
   void test_parseSuperConstructorInvocation_named() {
-    SuperConstructorInvocation invocation = ParserTestCase.parse5("parseSuperConstructorInvocation", "super.a()", []);
+    SuperConstructorInvocation invocation = ParserTestCase.parse6("parseSuperConstructorInvocation", "super.a()", []);
     JUnitTestCase.assertNotNull(invocation.argumentList);
     JUnitTestCase.assertNotNull(invocation.constructorName);
     JUnitTestCase.assertNotNull(invocation.keyword);
     JUnitTestCase.assertNotNull(invocation.period);
   }
   void test_parseSuperConstructorInvocation_unnamed() {
-    SuperConstructorInvocation invocation = ParserTestCase.parse5("parseSuperConstructorInvocation", "super()", []);
+    SuperConstructorInvocation invocation = ParserTestCase.parse6("parseSuperConstructorInvocation", "super()", []);
     JUnitTestCase.assertNotNull(invocation.argumentList);
     JUnitTestCase.assertNull(invocation.constructorName);
     JUnitTestCase.assertNotNull(invocation.keyword);
     JUnitTestCase.assertNull(invocation.period);
   }
   void test_parseSwitchStatement_case() {
-    SwitchStatement statement = ParserTestCase.parse5("parseSwitchStatement", "switch (a) {case 1: return 'I';}", []);
+    SwitchStatement statement = ParserTestCase.parse6("parseSwitchStatement", "switch (a) {case 1: return 'I';}", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.expression);
@@ -3889,7 +2939,7 @@
     JUnitTestCase.assertNotNull(statement.rightBracket);
   }
   void test_parseSwitchStatement_empty() {
-    SwitchStatement statement = ParserTestCase.parse5("parseSwitchStatement", "switch (a) {}", []);
+    SwitchStatement statement = ParserTestCase.parse6("parseSwitchStatement", "switch (a) {}", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.expression);
@@ -3899,7 +2949,7 @@
     JUnitTestCase.assertNotNull(statement.rightBracket);
   }
   void test_parseSwitchStatement_labeledCase() {
-    SwitchStatement statement = ParserTestCase.parse5("parseSwitchStatement", "switch (a) {l1: l2: l3: case(1):}", []);
+    SwitchStatement statement = ParserTestCase.parse6("parseSwitchStatement", "switch (a) {l1: l2: l3: case(1):}", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.expression);
@@ -3910,7 +2960,7 @@
     JUnitTestCase.assertNotNull(statement.rightBracket);
   }
   void test_parseSwitchStatement_labeledStatementInCase() {
-    SwitchStatement statement = ParserTestCase.parse5("parseSwitchStatement", "switch (a) {case 0: f(); l1: g(); break;}", []);
+    SwitchStatement statement = ParserTestCase.parse6("parseSwitchStatement", "switch (a) {case 0: f(); l1: g(); break;}", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.expression);
@@ -3921,27 +2971,27 @@
     JUnitTestCase.assertNotNull(statement.rightBracket);
   }
   void test_parseThrowExpression_expression() {
-    ThrowExpression statement = ParserTestCase.parse5("parseThrowExpression", "throw x;", []);
+    ThrowExpression statement = ParserTestCase.parse6("parseThrowExpression", "throw x;", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseThrowExpression_noExpression() {
-    ThrowExpression statement = ParserTestCase.parse5("parseThrowExpression", "throw;", []);
+    ThrowExpression statement = ParserTestCase.parse6("parseThrowExpression", "throw;", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNull(statement.expression);
   }
   void test_parseThrowExpressionWithoutCascade_expression() {
-    ThrowExpression statement = ParserTestCase.parse5("parseThrowExpressionWithoutCascade", "throw x;", []);
+    ThrowExpression statement = ParserTestCase.parse6("parseThrowExpressionWithoutCascade", "throw x;", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseThrowExpressionWithoutCascade_noExpression() {
-    ThrowExpression statement = ParserTestCase.parse5("parseThrowExpressionWithoutCascade", "throw;", []);
+    ThrowExpression statement = ParserTestCase.parse6("parseThrowExpressionWithoutCascade", "throw;", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNull(statement.expression);
   }
   void test_parseTryStatement_catch() {
-    TryStatement statement = ParserTestCase.parse5("parseTryStatement", "try {} catch (e) {}", []);
+    TryStatement statement = ParserTestCase.parse6("parseTryStatement", "try {} catch (e) {}", []);
     JUnitTestCase.assertNotNull(statement.tryKeyword);
     JUnitTestCase.assertNotNull(statement.body);
     NodeList<CatchClause> catchClauses2 = statement.catchClauses;
@@ -3958,7 +3008,7 @@
     JUnitTestCase.assertNull(statement.finallyClause);
   }
   void test_parseTryStatement_catch_finally() {
-    TryStatement statement = ParserTestCase.parse5("parseTryStatement", "try {} catch (e, s) {} finally {}", []);
+    TryStatement statement = ParserTestCase.parse6("parseTryStatement", "try {} catch (e, s) {} finally {}", []);
     JUnitTestCase.assertNotNull(statement.tryKeyword);
     JUnitTestCase.assertNotNull(statement.body);
     NodeList<CatchClause> catchClauses3 = statement.catchClauses;
@@ -3975,7 +3025,7 @@
     JUnitTestCase.assertNotNull(statement.finallyClause);
   }
   void test_parseTryStatement_finally() {
-    TryStatement statement = ParserTestCase.parse5("parseTryStatement", "try {} finally {}", []);
+    TryStatement statement = ParserTestCase.parse6("parseTryStatement", "try {} finally {}", []);
     JUnitTestCase.assertNotNull(statement.tryKeyword);
     JUnitTestCase.assertNotNull(statement.body);
     EngineTestCase.assertSize(0, statement.catchClauses);
@@ -3983,7 +3033,7 @@
     JUnitTestCase.assertNotNull(statement.finallyClause);
   }
   void test_parseTryStatement_multiple() {
-    TryStatement statement = ParserTestCase.parse5("parseTryStatement", "try {} on NPE catch (e) {} on Error {} catch (e) {}", []);
+    TryStatement statement = ParserTestCase.parse6("parseTryStatement", "try {} on NPE catch (e) {} on Error {} catch (e) {}", []);
     JUnitTestCase.assertNotNull(statement.tryKeyword);
     JUnitTestCase.assertNotNull(statement.body);
     EngineTestCase.assertSize(3, statement.catchClauses);
@@ -3991,7 +3041,7 @@
     JUnitTestCase.assertNull(statement.finallyClause);
   }
   void test_parseTryStatement_on() {
-    TryStatement statement = ParserTestCase.parse5("parseTryStatement", "try {} on Error {}", []);
+    TryStatement statement = ParserTestCase.parse6("parseTryStatement", "try {} on Error {}", []);
     JUnitTestCase.assertNotNull(statement.tryKeyword);
     JUnitTestCase.assertNotNull(statement.body);
     NodeList<CatchClause> catchClauses4 = statement.catchClauses;
@@ -4008,7 +3058,7 @@
     JUnitTestCase.assertNull(statement.finallyClause);
   }
   void test_parseTryStatement_on_catch() {
-    TryStatement statement = ParserTestCase.parse5("parseTryStatement", "try {} on Error catch (e, s) {}", []);
+    TryStatement statement = ParserTestCase.parse6("parseTryStatement", "try {} on Error catch (e, s) {}", []);
     JUnitTestCase.assertNotNull(statement.tryKeyword);
     JUnitTestCase.assertNotNull(statement.body);
     NodeList<CatchClause> catchClauses5 = statement.catchClauses;
@@ -4025,7 +3075,7 @@
     JUnitTestCase.assertNull(statement.finallyClause);
   }
   void test_parseTryStatement_on_catch_finally() {
-    TryStatement statement = ParserTestCase.parse5("parseTryStatement", "try {} on Error catch (e, s) {} finally {}", []);
+    TryStatement statement = ParserTestCase.parse6("parseTryStatement", "try {} on Error catch (e, s) {} finally {}", []);
     JUnitTestCase.assertNotNull(statement.tryKeyword);
     JUnitTestCase.assertNotNull(statement.body);
     NodeList<CatchClause> catchClauses6 = statement.catchClauses;
@@ -4041,7 +3091,29 @@
     JUnitTestCase.assertNotNull(statement.finallyKeyword);
     JUnitTestCase.assertNotNull(statement.finallyClause);
   }
-  void test_parseTypeAlias_noParameters() {
+  void test_parseTypeAlias_class_implementsC() {
+    ClassTypeAlias typeAlias = ParserTestCase.parse("parseTypeAlias", <Object> [emptyCommentAndMetadata()], "typedef A = Object with B implements C;");
+    JUnitTestCase.assertNotNull(typeAlias.keyword);
+    JUnitTestCase.assertNotNull(typeAlias.name);
+    JUnitTestCase.assertNull(typeAlias.typeParameters);
+    JUnitTestCase.assertNotNull(typeAlias.withClause);
+    JUnitTestCase.assertNotNull(typeAlias.implementsClause);
+    JUnitTestCase.assertNotNull(typeAlias.implementsClause.keyword);
+    JUnitTestCase.assertEquals(1, typeAlias.implementsClause.interfaces.length);
+    JUnitTestCase.assertNotNull(typeAlias.semicolon);
+  }
+  void test_parseTypeAlias_class_withB() {
+    ClassTypeAlias typeAlias = ParserTestCase.parse("parseTypeAlias", <Object> [emptyCommentAndMetadata()], "typedef A = Object with B;");
+    JUnitTestCase.assertNotNull(typeAlias.keyword);
+    JUnitTestCase.assertNotNull(typeAlias.name);
+    JUnitTestCase.assertNull(typeAlias.typeParameters);
+    JUnitTestCase.assertNotNull(typeAlias.withClause);
+    JUnitTestCase.assertNotNull(typeAlias.withClause.withKeyword);
+    JUnitTestCase.assertEquals(1, typeAlias.withClause.mixinTypes.length);
+    JUnitTestCase.assertNull(typeAlias.implementsClause);
+    JUnitTestCase.assertNotNull(typeAlias.semicolon);
+  }
+  void test_parseTypeAlias_function_noParameters() {
     FunctionTypeAlias typeAlias = ParserTestCase.parse("parseTypeAlias", <Object> [emptyCommentAndMetadata()], "typedef bool F();");
     JUnitTestCase.assertNotNull(typeAlias.keyword);
     JUnitTestCase.assertNotNull(typeAlias.name);
@@ -4050,7 +3122,7 @@
     JUnitTestCase.assertNotNull(typeAlias.semicolon);
     JUnitTestCase.assertNull(typeAlias.typeParameters);
   }
-  void test_parseTypeAlias_noReturnType() {
+  void test_parseTypeAlias_function_noReturnType() {
     FunctionTypeAlias typeAlias = ParserTestCase.parse("parseTypeAlias", <Object> [emptyCommentAndMetadata()], "typedef F();");
     JUnitTestCase.assertNotNull(typeAlias.keyword);
     JUnitTestCase.assertNotNull(typeAlias.name);
@@ -4059,7 +3131,7 @@
     JUnitTestCase.assertNotNull(typeAlias.semicolon);
     JUnitTestCase.assertNull(typeAlias.typeParameters);
   }
-  void test_parseTypeAlias_parameterizedReturnType() {
+  void test_parseTypeAlias_function_parameterizedReturnType() {
     FunctionTypeAlias typeAlias = ParserTestCase.parse("parseTypeAlias", <Object> [emptyCommentAndMetadata()], "typedef A<B> F();");
     JUnitTestCase.assertNotNull(typeAlias.keyword);
     JUnitTestCase.assertNotNull(typeAlias.name);
@@ -4068,7 +3140,7 @@
     JUnitTestCase.assertNotNull(typeAlias.semicolon);
     JUnitTestCase.assertNull(typeAlias.typeParameters);
   }
-  void test_parseTypeAlias_parameters() {
+  void test_parseTypeAlias_function_parameters() {
     FunctionTypeAlias typeAlias = ParserTestCase.parse("parseTypeAlias", <Object> [emptyCommentAndMetadata()], "typedef bool F(Object value);");
     JUnitTestCase.assertNotNull(typeAlias.keyword);
     JUnitTestCase.assertNotNull(typeAlias.name);
@@ -4077,7 +3149,7 @@
     JUnitTestCase.assertNotNull(typeAlias.semicolon);
     JUnitTestCase.assertNull(typeAlias.typeParameters);
   }
-  void test_parseTypeAlias_typeParameters() {
+  void test_parseTypeAlias_function_typeParameters() {
     FunctionTypeAlias typeAlias = ParserTestCase.parse("parseTypeAlias", <Object> [emptyCommentAndMetadata()], "typedef bool F<E>();");
     JUnitTestCase.assertNotNull(typeAlias.keyword);
     JUnitTestCase.assertNotNull(typeAlias.name);
@@ -4086,7 +3158,7 @@
     JUnitTestCase.assertNotNull(typeAlias.semicolon);
     JUnitTestCase.assertNotNull(typeAlias.typeParameters);
   }
-  void test_parseTypeAlias_voidReturnType() {
+  void test_parseTypeAlias_function_voidReturnType() {
     FunctionTypeAlias typeAlias = ParserTestCase.parse("parseTypeAlias", <Object> [emptyCommentAndMetadata()], "typedef void F();");
     JUnitTestCase.assertNotNull(typeAlias.keyword);
     JUnitTestCase.assertNotNull(typeAlias.name);
@@ -4096,13 +3168,13 @@
     JUnitTestCase.assertNull(typeAlias.typeParameters);
   }
   void test_parseTypeArgumentList_multiple() {
-    TypeArgumentList argumentList = ParserTestCase.parse5("parseTypeArgumentList", "<int, int, int>", []);
+    TypeArgumentList argumentList = ParserTestCase.parse6("parseTypeArgumentList", "<int, int, int>", []);
     JUnitTestCase.assertNotNull(argumentList.leftBracket);
     EngineTestCase.assertSize(3, argumentList.arguments);
     JUnitTestCase.assertNotNull(argumentList.rightBracket);
   }
   void test_parseTypeArgumentList_nested() {
-    TypeArgumentList argumentList = ParserTestCase.parse5("parseTypeArgumentList", "<A<B>>", []);
+    TypeArgumentList argumentList = ParserTestCase.parse6("parseTypeArgumentList", "<A<B>>", []);
     JUnitTestCase.assertNotNull(argumentList.leftBracket);
     EngineTestCase.assertSize(1, argumentList.arguments);
     TypeName argument = argumentList.arguments[0];
@@ -4113,173 +3185,173 @@
     JUnitTestCase.assertNotNull(argumentList.rightBracket);
   }
   void test_parseTypeArgumentList_single() {
-    TypeArgumentList argumentList = ParserTestCase.parse5("parseTypeArgumentList", "<int>", []);
+    TypeArgumentList argumentList = ParserTestCase.parse6("parseTypeArgumentList", "<int>", []);
     JUnitTestCase.assertNotNull(argumentList.leftBracket);
     EngineTestCase.assertSize(1, argumentList.arguments);
     JUnitTestCase.assertNotNull(argumentList.rightBracket);
   }
   void test_parseTypeName_parameterized() {
-    TypeName typeName = ParserTestCase.parse5("parseTypeName", "List<int>", []);
+    TypeName typeName = ParserTestCase.parse6("parseTypeName", "List<int>", []);
     JUnitTestCase.assertNotNull(typeName.name);
     JUnitTestCase.assertNotNull(typeName.typeArguments);
   }
   void test_parseTypeName_simple() {
-    TypeName typeName = ParserTestCase.parse5("parseTypeName", "int", []);
+    TypeName typeName = ParserTestCase.parse6("parseTypeName", "int", []);
     JUnitTestCase.assertNotNull(typeName.name);
     JUnitTestCase.assertNull(typeName.typeArguments);
   }
   void test_parseTypeParameter_bounded() {
-    TypeParameter parameter = ParserTestCase.parse5("parseTypeParameter", "A extends B", []);
+    TypeParameter parameter = ParserTestCase.parse6("parseTypeParameter", "A extends B", []);
     JUnitTestCase.assertNotNull(parameter.bound);
     JUnitTestCase.assertNotNull(parameter.keyword);
     JUnitTestCase.assertNotNull(parameter.name);
   }
   void test_parseTypeParameter_simple() {
-    TypeParameter parameter = ParserTestCase.parse5("parseTypeParameter", "A", []);
+    TypeParameter parameter = ParserTestCase.parse6("parseTypeParameter", "A", []);
     JUnitTestCase.assertNull(parameter.bound);
     JUnitTestCase.assertNull(parameter.keyword);
     JUnitTestCase.assertNotNull(parameter.name);
   }
   void test_parseTypeParameterList_multiple() {
-    TypeParameterList parameterList = ParserTestCase.parse5("parseTypeParameterList", "<A, B extends C, D>", []);
+    TypeParameterList parameterList = ParserTestCase.parse6("parseTypeParameterList", "<A, B extends C, D>", []);
     JUnitTestCase.assertNotNull(parameterList.leftBracket);
     JUnitTestCase.assertNotNull(parameterList.rightBracket);
     EngineTestCase.assertSize(3, parameterList.typeParameters);
   }
   void test_parseTypeParameterList_parameterizedWithTrailingEquals() {
-    TypeParameterList parameterList = ParserTestCase.parse5("parseTypeParameterList", "<A extends B<E>>=", []);
+    TypeParameterList parameterList = ParserTestCase.parse6("parseTypeParameterList", "<A extends B<E>>=", []);
     JUnitTestCase.assertNotNull(parameterList.leftBracket);
     JUnitTestCase.assertNotNull(parameterList.rightBracket);
     EngineTestCase.assertSize(1, parameterList.typeParameters);
   }
   void test_parseTypeParameterList_single() {
-    TypeParameterList parameterList = ParserTestCase.parse5("parseTypeParameterList", "<A>", []);
+    TypeParameterList parameterList = ParserTestCase.parse6("parseTypeParameterList", "<A>", []);
     JUnitTestCase.assertNotNull(parameterList.leftBracket);
     JUnitTestCase.assertNotNull(parameterList.rightBracket);
     EngineTestCase.assertSize(1, parameterList.typeParameters);
   }
   void test_parseTypeParameterList_withTrailingEquals() {
-    TypeParameterList parameterList = ParserTestCase.parse5("parseTypeParameterList", "<A>=", []);
+    TypeParameterList parameterList = ParserTestCase.parse6("parseTypeParameterList", "<A>=", []);
     JUnitTestCase.assertNotNull(parameterList.leftBracket);
     JUnitTestCase.assertNotNull(parameterList.rightBracket);
     EngineTestCase.assertSize(1, parameterList.typeParameters);
   }
   void test_parseUnaryExpression_decrement_normal() {
-    PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "--x", []);
+    PrefixExpression expression = ParserTestCase.parse6("parseUnaryExpression", "--x", []);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.MINUS_MINUS, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.operand);
   }
   void test_parseUnaryExpression_decrement_super() {
-    PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "--super", []);
+    PrefixExpression expression = ParserTestCase.parse6("parseUnaryExpression", "--super", []);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.MINUS, expression.operator.type);
     Expression innerExpression = expression.operand;
     JUnitTestCase.assertNotNull(innerExpression);
     JUnitTestCase.assertTrue(innerExpression is PrefixExpression);
-    PrefixExpression operand = (innerExpression as PrefixExpression);
+    PrefixExpression operand = innerExpression as PrefixExpression;
     JUnitTestCase.assertNotNull(operand.operator);
     JUnitTestCase.assertEquals(TokenType.MINUS, operand.operator.type);
     JUnitTestCase.assertNotNull(operand.operand);
   }
   void test_parseUnaryExpression_increment_normal() {
-    PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "++x", []);
+    PrefixExpression expression = ParserTestCase.parse6("parseUnaryExpression", "++x", []);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.PLUS_PLUS, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.operand);
   }
   void test_parseUnaryExpression_minus_normal() {
-    PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "-x", []);
+    PrefixExpression expression = ParserTestCase.parse6("parseUnaryExpression", "-x", []);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.MINUS, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.operand);
   }
   void test_parseUnaryExpression_minus_super() {
-    PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "-super", []);
+    PrefixExpression expression = ParserTestCase.parse6("parseUnaryExpression", "-super", []);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.MINUS, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.operand);
   }
   void test_parseUnaryExpression_not_normal() {
-    PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "!x", []);
+    PrefixExpression expression = ParserTestCase.parse6("parseUnaryExpression", "!x", []);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.BANG, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.operand);
   }
   void test_parseUnaryExpression_not_super() {
-    PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "!super", []);
+    PrefixExpression expression = ParserTestCase.parse6("parseUnaryExpression", "!super", []);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.BANG, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.operand);
   }
   void test_parseUnaryExpression_tilda_normal() {
-    PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "~x", []);
+    PrefixExpression expression = ParserTestCase.parse6("parseUnaryExpression", "~x", []);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.TILDE, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.operand);
   }
   void test_parseUnaryExpression_tilda_super() {
-    PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "~super", []);
+    PrefixExpression expression = ParserTestCase.parse6("parseUnaryExpression", "~super", []);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.TILDE, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.operand);
   }
   void test_parseVariableDeclaration_equals() {
-    VariableDeclaration declaration = ParserTestCase.parse5("parseVariableDeclaration", "a = b", []);
+    VariableDeclaration declaration = ParserTestCase.parse6("parseVariableDeclaration", "a = b", []);
     JUnitTestCase.assertNotNull(declaration.name);
     JUnitTestCase.assertNotNull(declaration.equals);
     JUnitTestCase.assertNotNull(declaration.initializer);
   }
   void test_parseVariableDeclaration_noEquals() {
-    VariableDeclaration declaration = ParserTestCase.parse5("parseVariableDeclaration", "a", []);
+    VariableDeclaration declaration = ParserTestCase.parse6("parseVariableDeclaration", "a", []);
     JUnitTestCase.assertNotNull(declaration.name);
     JUnitTestCase.assertNull(declaration.equals);
     JUnitTestCase.assertNull(declaration.initializer);
   }
   void test_parseVariableDeclarationList_const_noType() {
-    VariableDeclarationList declarationList = ParserTestCase.parse5("parseVariableDeclarationList", "const a", []);
+    VariableDeclarationList declarationList = ParserTestCase.parse6("parseVariableDeclarationList", "const a", []);
     JUnitTestCase.assertNotNull(declarationList.keyword);
     JUnitTestCase.assertNull(declarationList.type);
     EngineTestCase.assertSize(1, declarationList.variables);
   }
   void test_parseVariableDeclarationList_const_type() {
-    VariableDeclarationList declarationList = ParserTestCase.parse5("parseVariableDeclarationList", "const A a", []);
+    VariableDeclarationList declarationList = ParserTestCase.parse6("parseVariableDeclarationList", "const A a", []);
     JUnitTestCase.assertNotNull(declarationList.keyword);
     JUnitTestCase.assertNotNull(declarationList.type);
     EngineTestCase.assertSize(1, declarationList.variables);
   }
   void test_parseVariableDeclarationList_final_noType() {
-    VariableDeclarationList declarationList = ParserTestCase.parse5("parseVariableDeclarationList", "final a", []);
+    VariableDeclarationList declarationList = ParserTestCase.parse6("parseVariableDeclarationList", "final a", []);
     JUnitTestCase.assertNotNull(declarationList.keyword);
     JUnitTestCase.assertNull(declarationList.type);
     EngineTestCase.assertSize(1, declarationList.variables);
   }
   void test_parseVariableDeclarationList_final_type() {
-    VariableDeclarationList declarationList = ParserTestCase.parse5("parseVariableDeclarationList", "final A a", []);
+    VariableDeclarationList declarationList = ParserTestCase.parse6("parseVariableDeclarationList", "final A a", []);
     JUnitTestCase.assertNotNull(declarationList.keyword);
     JUnitTestCase.assertNotNull(declarationList.type);
     EngineTestCase.assertSize(1, declarationList.variables);
   }
   void test_parseVariableDeclarationList_type_multiple() {
-    VariableDeclarationList declarationList = ParserTestCase.parse5("parseVariableDeclarationList", "A a, b, c", []);
+    VariableDeclarationList declarationList = ParserTestCase.parse6("parseVariableDeclarationList", "A a, b, c", []);
     JUnitTestCase.assertNull(declarationList.keyword);
     JUnitTestCase.assertNotNull(declarationList.type);
     EngineTestCase.assertSize(3, declarationList.variables);
   }
   void test_parseVariableDeclarationList_type_single() {
-    VariableDeclarationList declarationList = ParserTestCase.parse5("parseVariableDeclarationList", "A a", []);
+    VariableDeclarationList declarationList = ParserTestCase.parse6("parseVariableDeclarationList", "A a", []);
     JUnitTestCase.assertNull(declarationList.keyword);
     JUnitTestCase.assertNotNull(declarationList.type);
     EngineTestCase.assertSize(1, declarationList.variables);
   }
   void test_parseVariableDeclarationList_var_multiple() {
-    VariableDeclarationList declarationList = ParserTestCase.parse5("parseVariableDeclarationList", "var a, b, c", []);
+    VariableDeclarationList declarationList = ParserTestCase.parse6("parseVariableDeclarationList", "var a, b, c", []);
     JUnitTestCase.assertNotNull(declarationList.keyword);
     JUnitTestCase.assertNull(declarationList.type);
     EngineTestCase.assertSize(3, declarationList.variables);
   }
   void test_parseVariableDeclarationList_var_single() {
-    VariableDeclarationList declarationList = ParserTestCase.parse5("parseVariableDeclarationList", "var a", []);
+    VariableDeclarationList declarationList = ParserTestCase.parse6("parseVariableDeclarationList", "var a", []);
     JUnitTestCase.assertNotNull(declarationList.keyword);
     JUnitTestCase.assertNull(declarationList.type);
     EngineTestCase.assertSize(1, declarationList.variables);
@@ -4299,21 +3371,21 @@
     EngineTestCase.assertSize(3, declarationList.variables);
   }
   void test_parseVariableDeclarationStatement_multiple() {
-    VariableDeclarationStatement statement = ParserTestCase.parse5("parseVariableDeclarationStatement", "var x, y, z;", []);
+    VariableDeclarationStatement statement = ParserTestCase.parse6("parseVariableDeclarationStatement", "var x, y, z;", []);
     JUnitTestCase.assertNotNull(statement.semicolon);
     VariableDeclarationList variableList = statement.variables;
     JUnitTestCase.assertNotNull(variableList);
     EngineTestCase.assertSize(3, variableList.variables);
   }
   void test_parseVariableDeclarationStatement_single() {
-    VariableDeclarationStatement statement = ParserTestCase.parse5("parseVariableDeclarationStatement", "var x;", []);
+    VariableDeclarationStatement statement = ParserTestCase.parse6("parseVariableDeclarationStatement", "var x;", []);
     JUnitTestCase.assertNotNull(statement.semicolon);
     VariableDeclarationList variableList = statement.variables;
     JUnitTestCase.assertNotNull(variableList);
     EngineTestCase.assertSize(1, variableList.variables);
   }
   void test_parseWhileStatement() {
-    WhileStatement statement = ParserTestCase.parse5("parseWhileStatement", "while (x) {}", []);
+    WhileStatement statement = ParserTestCase.parse6("parseWhileStatement", "while (x) {}", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.condition);
@@ -4321,12 +3393,12 @@
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseWithClause_multiple() {
-    WithClause clause = ParserTestCase.parse5("parseWithClause", "with A, B, C", []);
+    WithClause clause = ParserTestCase.parse6("parseWithClause", "with A, B, C", []);
     JUnitTestCase.assertNotNull(clause.withKeyword);
     EngineTestCase.assertSize(3, clause.mixinTypes);
   }
   void test_parseWithClause_single() {
-    WithClause clause = ParserTestCase.parse5("parseWithClause", "with M", []);
+    WithClause clause = ParserTestCase.parse6("parseWithClause", "with M", []);
     JUnitTestCase.assertNotNull(clause.withKeyword);
     EngineTestCase.assertSize(1, clause.mixinTypes);
   }
@@ -4426,9 +3498,9 @@
    * @throws Exception if the method could not be invoked or throws an exception
    */
   String computeStringValue(String lexeme) {
-    AnalysisErrorListener listener = new AnalysisErrorListener_10();
+    AnalysisErrorListener listener = new AnalysisErrorListener_13();
     Parser parser = new Parser(null, listener);
-    return (invokeParserMethodImpl(parser, "computeStringValue", <Object> [lexeme], null) as String);
+    return invokeParserMethodImpl(parser, "computeStringValue", <Object> [lexeme], null) as String;
   }
   /**
    * Invoke the method {@link Parser#createSyntheticIdentifier()} with the parser set to the token
@@ -4461,7 +3533,7 @@
    */
   bool isFunctionDeclaration(String source) {
     GatheringErrorListener listener = new GatheringErrorListener();
-    return ParserTestCase.invokeParserMethod2("isFunctionDeclaration", source, listener);
+    return ParserTestCase.invokeParserMethod2("isFunctionDeclaration", source, listener) as bool;
   }
   /**
    * Invoke the method {@link Parser#isFunctionExpression()} with the parser set to the token stream
@@ -4475,7 +3547,7 @@
     StringScanner scanner = new StringScanner(null, source, listener);
     Token tokenStream = scanner.tokenize();
     Parser parser = new Parser(null, listener);
-    return (invokeParserMethodImpl(parser, "isFunctionExpression", <Object> [tokenStream], tokenStream) as bool);
+    return invokeParserMethodImpl(parser, "isFunctionExpression", <Object> [tokenStream], tokenStream) as bool;
   }
   /**
    * Invoke the method {@link Parser#isInitializedVariableDeclaration()} with the parser set to the
@@ -4486,7 +3558,7 @@
    */
   bool isInitializedVariableDeclaration(String source) {
     GatheringErrorListener listener = new GatheringErrorListener();
-    return ParserTestCase.invokeParserMethod2("isInitializedVariableDeclaration", source, listener);
+    return ParserTestCase.invokeParserMethod2("isInitializedVariableDeclaration", source, listener) as bool;
   }
   /**
    * Invoke the method {@link Parser#isSwitchMember()} with the parser set to the token stream
@@ -4497,7 +3569,7 @@
    */
   bool isSwitchMember(String source) {
     GatheringErrorListener listener = new GatheringErrorListener();
-    return ParserTestCase.invokeParserMethod2("isSwitchMember", source, listener);
+    return ParserTestCase.invokeParserMethod2("isSwitchMember", source, listener) as bool;
   }
   /**
    * Invoke a "skip" method in {@link Parser}. The method is assumed to take a token as it's
@@ -4513,7 +3585,7 @@
     StringScanner scanner = new StringScanner(null, source, listener);
     Token tokenStream = scanner.tokenize();
     Parser parser = new Parser(null, listener);
-    return (invokeParserMethodImpl(parser, methodName, <Object> [tokenStream], tokenStream) as Token);
+    return invokeParserMethodImpl(parser, methodName, <Object> [tokenStream], tokenStream) as Token;
   }
   static dartSuite() {
     _ut.group('SimpleParserTest', () {
@@ -4909,6 +3981,10 @@
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseCascadeSection_p_assign);
       });
+      _ut.test('test_parseCascadeSection_p_assign_withCascade', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCascadeSection_p_assign_withCascade);
+      });
       _ut.test('test_parseCascadeSection_p_builtIn', () {
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseCascadeSection_p_builtIn);
@@ -5129,6 +4205,10 @@
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseCommentReferences_singleLine);
       });
+      _ut.test('test_parseCompilationUnitMember_abstractAsPrefix', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnitMember_abstractAsPrefix);
+      });
       _ut.test('test_parseCompilationUnitMember_class', () {
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseCompilationUnitMember_class);
@@ -5213,6 +4293,10 @@
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseCompilationUnitMember_variable);
       });
+      _ut.test('test_parseCompilationUnit_abstractAsPrefix_parameterized', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnit_abstractAsPrefix_parameterized);
+      });
       _ut.test('test_parseCompilationUnit_directives_multiple', () {
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseCompilationUnit_directives_multiple);
@@ -5225,6 +4309,18 @@
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseCompilationUnit_empty);
       });
+      _ut.test('test_parseCompilationUnit_exportAsPrefix', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnit_exportAsPrefix);
+      });
+      _ut.test('test_parseCompilationUnit_exportAsPrefix_parameterized', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnit_exportAsPrefix_parameterized);
+      });
+      _ut.test('test_parseCompilationUnit_operatorAsPrefix_parameterized', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnit_operatorAsPrefix_parameterized);
+      });
       _ut.test('test_parseCompilationUnit_script', () {
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseCompilationUnit_script);
@@ -5233,6 +4329,10 @@
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseCompilationUnit_topLevelDeclaration);
       });
+      _ut.test('test_parseCompilationUnit_typedefAsPrefix', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnit_typedefAsPrefix);
+      });
       _ut.test('test_parseConditionalExpression', () {
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseConditionalExpression);
@@ -5581,10 +4681,6 @@
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseFunctionDeclaration_function);
       });
-      _ut.test('test_parseFunctionDeclaration_function_inStatement', () {
-        final __test = new SimpleParserTest();
-        runJUnitTest(__test, __test.test_parseFunctionDeclaration_function_inStatement);
-      });
       _ut.test('test_parseFunctionDeclaration_getter', () {
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseFunctionDeclaration_getter);
@@ -6233,29 +5329,37 @@
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseTryStatement_on_catch_finally);
       });
-      _ut.test('test_parseTypeAlias_noParameters', () {
+      _ut.test('test_parseTypeAlias_class_implementsC', () {
         final __test = new SimpleParserTest();
-        runJUnitTest(__test, __test.test_parseTypeAlias_noParameters);
+        runJUnitTest(__test, __test.test_parseTypeAlias_class_implementsC);
       });
-      _ut.test('test_parseTypeAlias_noReturnType', () {
+      _ut.test('test_parseTypeAlias_class_withB', () {
         final __test = new SimpleParserTest();
-        runJUnitTest(__test, __test.test_parseTypeAlias_noReturnType);
+        runJUnitTest(__test, __test.test_parseTypeAlias_class_withB);
       });
-      _ut.test('test_parseTypeAlias_parameterizedReturnType', () {
+      _ut.test('test_parseTypeAlias_function_noParameters', () {
         final __test = new SimpleParserTest();
-        runJUnitTest(__test, __test.test_parseTypeAlias_parameterizedReturnType);
+        runJUnitTest(__test, __test.test_parseTypeAlias_function_noParameters);
       });
-      _ut.test('test_parseTypeAlias_parameters', () {
+      _ut.test('test_parseTypeAlias_function_noReturnType', () {
         final __test = new SimpleParserTest();
-        runJUnitTest(__test, __test.test_parseTypeAlias_parameters);
+        runJUnitTest(__test, __test.test_parseTypeAlias_function_noReturnType);
       });
-      _ut.test('test_parseTypeAlias_typeParameters', () {
+      _ut.test('test_parseTypeAlias_function_parameterizedReturnType', () {
         final __test = new SimpleParserTest();
-        runJUnitTest(__test, __test.test_parseTypeAlias_typeParameters);
+        runJUnitTest(__test, __test.test_parseTypeAlias_function_parameterizedReturnType);
       });
-      _ut.test('test_parseTypeAlias_voidReturnType', () {
+      _ut.test('test_parseTypeAlias_function_parameters', () {
         final __test = new SimpleParserTest();
-        runJUnitTest(__test, __test.test_parseTypeAlias_voidReturnType);
+        runJUnitTest(__test, __test.test_parseTypeAlias_function_parameters);
+      });
+      _ut.test('test_parseTypeAlias_function_typeParameters', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTypeAlias_function_typeParameters);
+      });
+      _ut.test('test_parseTypeAlias_function_voidReturnType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTypeAlias_function_voidReturnType);
       });
       _ut.test('test_parseTypeArgumentList_multiple', () {
         final __test = new SimpleParserTest();
@@ -6484,7 +5588,7 @@
     });
   }
 }
-class AnalysisErrorListener_10 implements AnalysisErrorListener {
+class AnalysisErrorListener_13 implements AnalysisErrorListener {
   void onError(AnalysisError event) {
     JUnitTestCase.fail("Unexpected compilation error: ${event.message} (${event.offset}, ${event.length})");
   }
@@ -6897,522 +6001,1530 @@
   }
 }
 /**
+ * Instances of the class {@code ASTValidator} are used to validate the correct construction of an
+ * AST structure.
+ */
+class ASTValidator extends GeneralizingASTVisitor<Object> {
+  /**
+   * A list containing the errors found while traversing the AST structure.
+   */
+  List<String> _errors = new List<String>();
+  /**
+   * Assert that no errors were found while traversing any of the AST structures that have been
+   * visited.
+   */
+  void assertValid() {
+    if (!_errors.isEmpty) {
+      JavaStringBuilder builder = new JavaStringBuilder();
+      builder.append("Invalid AST structure:");
+      for (String message in _errors) {
+        builder.append("\r\n   ");
+        builder.append(message);
+      }
+      JUnitTestCase.fail(builder.toString());
+    }
+  }
+  Object visitNode(ASTNode node) {
+    validate(node);
+    return super.visitNode(node);
+  }
+  /**
+   * Validate that the given AST node is correctly constructed.
+   * @param node the AST node being validated
+   */
+  void validate(ASTNode node) {
+    ASTNode parent20 = node.parent;
+    if (node is CompilationUnit) {
+      if (parent20 != null) {
+        _errors.add("Compilation units should not have a parent");
+      }
+    } else {
+      if (parent20 == null) {
+        _errors.add("No parent for ${node.runtimeType.toString()}");
+      }
+    }
+    if (node.beginToken == null) {
+      _errors.add("No begin token for ${node.runtimeType.toString()}");
+    }
+    if (node.endToken == null) {
+      _errors.add("No end token for ${node.runtimeType.toString()}");
+    }
+    int nodeStart = node.offset;
+    int nodeLength = node.length;
+    if (nodeStart < 0 || nodeLength < 0) {
+      _errors.add("No source info for ${node.runtimeType.toString()}");
+    }
+    if (parent20 != null) {
+      int nodeEnd = nodeStart + nodeLength;
+      int parentStart = parent20.offset;
+      int parentEnd = parentStart + parent20.length;
+      if (nodeStart < parentStart) {
+        _errors.add("Invalid source start (${nodeStart}) for ${node.runtimeType.toString()} inside ${parent20.runtimeType.toString()} (${parentStart})");
+      }
+      if (nodeEnd > parentEnd) {
+        _errors.add("Invalid source end (${nodeEnd}) for ${node.runtimeType.toString()} inside ${parent20.runtimeType.toString()} (${parentStart})");
+      }
+    }
+  }
+}
+class ParserTestCase extends EngineTestCase {
+  /**
+   * An empty array of objects used as arguments to zero-argument methods.
+   */
+  static List<Object> _EMPTY_ARGUMENTS = new List<Object>(0);
+  /**
+   * Invoke a parse method in {@link Parser}. The method is assumed to have the given number and
+   * type of parameters and will be invoked with the given arguments.
+   * <p>
+   * The given source is scanned and the parser is initialized to start with the first token in the
+   * source before the parse method is invoked.
+   * @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
+   * @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 {@code null} or if any errors are produced
+   */
+  static Object parse(String methodName, List<Object> objects, String source) => parse4(methodName, objects, source, new List<AnalysisError>(0));
+  /**
+   * Invoke a parse method in {@link Parser}. The method is assumed to have the given number and
+   * type of parameters and will be invoked with the given arguments.
+   * <p>
+   * The given source is scanned and the parser is initialized to start with the first token in the
+   * source before the parse method is invoked.
+   * @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
+   * @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 {@code null} or the errors produced while
+   * scanning and parsing the source do not match the expected errors
+   */
+  static Object parse4(String methodName, List<Object> objects, String source, List<AnalysisError> errors) {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    Object result = invokeParserMethod(methodName, objects, source, listener);
+    listener.assertErrors(errors);
+    return result;
+  }
+  /**
+   * Invoke a parse method in {@link Parser}. The method is assumed to have the given number and
+   * type of parameters and will be invoked with the given arguments.
+   * <p>
+   * The given source is scanned and the parser is initialized to start with the first token in the
+   * source before the parse method is invoked.
+   * @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
+   * @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 {@code null} or the errors produced while
+   * scanning and parsing the source do not match the expected errors
+   */
+  static Object parse5(String methodName, List<Object> objects, String source, List<ErrorCode> errorCodes) {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    Object result = invokeParserMethod(methodName, objects, source, listener);
+    listener.assertErrors2(errorCodes);
+    return result;
+  }
+  /**
+   * Invoke a parse method in {@link Parser}. The method is assumed to have no arguments.
+   * <p>
+   * The given source is scanned and the parser is initialized to start with the first token in the
+   * source before the parse method is invoked.
+   * @param methodName the name of the parse method that should be invoked to parse the source
+   * @param source the source to be parsed by the parse method
+   * @param errorCodes the error codes of 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 {@code null} or the errors produced while
+   * scanning and parsing the source do not match the expected errors
+   */
+  static Object parse6(String methodName, String source, List<ErrorCode> errorCodes) => parse5(methodName, _EMPTY_ARGUMENTS, source, errorCodes);
+  /**
+   * Parse the given source as a compilation unit.
+   * @param source the source to be parsed
+   * @param errorCodes the error codes of the errors that are expected to be found
+   * @return the compilation unit that was parsed
+   * @throws Exception if the source could not be parsed, if the compilation errors in the source do
+   * not match those that are expected, or if the result would have been {@code null}
+   */
+  static CompilationUnit parseCompilationUnit(String source, List<ErrorCode> errorCodes) {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    StringScanner scanner = new StringScanner(null, source, listener);
+    listener.setLineInfo(new TestSource(), scanner.lineStarts);
+    Token token = scanner.tokenize();
+    Parser parser = new Parser(null, listener);
+    CompilationUnit unit = parser.parseCompilationUnit(token);
+    JUnitTestCase.assertNotNull(unit);
+    listener.assertErrors2(errorCodes);
+    return unit;
+  }
+  /**
+   * Parse the given source as an expression.
+   * @param source the source to be parsed
+   * @param errorCodes the error codes of the errors that are expected to be found
+   * @return the expression that was parsed
+   * @throws Exception if the source could not be parsed, if the compilation errors in the source do
+   * not match those that are expected, or if the result would have been {@code null}
+   */
+  static Expression parseExpression(String source, List<ErrorCode> errorCodes) {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    StringScanner scanner = new StringScanner(null, source, listener);
+    listener.setLineInfo(new TestSource(), scanner.lineStarts);
+    Token token = scanner.tokenize();
+    Parser parser = new Parser(null, listener);
+    Expression expression = parser.parseExpression(token);
+    JUnitTestCase.assertNotNull(expression);
+    listener.assertErrors2(errorCodes);
+    return expression as Expression;
+  }
+  /**
+   * Parse the given source as a statement.
+   * @param source the source to be parsed
+   * @param errorCodes the error codes of the errors that are expected to be found
+   * @return the statement that was parsed
+   * @throws Exception if the source could not be parsed, if the compilation errors in the source do
+   * not match those that are expected, or if the result would have been {@code null}
+   */
+  static Statement parseStatement(String source, List<ErrorCode> errorCodes) {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    StringScanner scanner = new StringScanner(null, source, listener);
+    listener.setLineInfo(new TestSource(), scanner.lineStarts);
+    Token token = scanner.tokenize();
+    Parser parser = new Parser(null, listener);
+    Statement statement = parser.parseStatement(token);
+    JUnitTestCase.assertNotNull(statement);
+    listener.assertErrors2(errorCodes);
+    return statement as Statement;
+  }
+  /**
+   * Parse the given source as a sequence of statements.
+   * @param source the source to be parsed
+   * @param expectedCount the number of statements that are expected
+   * @param errorCodes the error codes of the errors that are expected to be found
+   * @return the statements that were parsed
+   * @throws Exception if the source could not be parsed, if the number of statements does not match
+   * the expected count, if the compilation errors in the source do not match those that
+   * are expected, or if the result would have been {@code null}
+   */
+  static List<Statement> parseStatements(String source, int expectedCount, List<ErrorCode> errorCodes) {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    StringScanner scanner = new StringScanner(null, source, listener);
+    listener.setLineInfo(new TestSource(), scanner.lineStarts);
+    Token token = scanner.tokenize();
+    Parser parser = new Parser(null, listener);
+    List<Statement> statements = parser.parseStatements(token);
+    EngineTestCase.assertSize(expectedCount, statements);
+    listener.assertErrors2(errorCodes);
+    return statements;
+  }
+  /**
+   * Invoke a method in {@link Parser}. The method is assumed to have the given number and type of
+   * parameters and will be invoked with the given arguments.
+   * <p>
+   * The given source is scanned and the parser is initialized to start with the first token in the
+   * source before the method is invoked.
+   * @param methodName the name of the method that should be invoked
+   * @param objects the values of the arguments to the method
+   * @param source the source to be processed by the parse method
+   * @param listener the error listener that will be used for both scanning and parsing
+   * @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 {@code null} or the errors produced while
+   * scanning and parsing the source do not match the expected errors
+   */
+  static Object invokeParserMethod(String methodName, List<Object> objects, String source, GatheringErrorListener listener) {
+    StringScanner scanner = new StringScanner(null, source, listener);
+    Token tokenStream = scanner.tokenize();
+    listener.setLineInfo(new TestSource(), scanner.lineStarts);
+    Parser parser = new Parser(null, listener);
+    Object result = invokeParserMethodImpl(parser, methodName, objects, tokenStream);
+    JUnitTestCase.assertNotNull(result);
+    return result as Object;
+  }
+  /**
+   * Invoke a method in {@link Parser}. The method is assumed to have no arguments.
+   * <p>
+   * The given source is scanned and the parser is initialized to start with the first token in the
+   * source before the method is invoked.
+   * @param methodName the name of the method that should be invoked
+   * @param source the source to be processed by the parse method
+   * @param listener the error listener that will be used for both scanning and parsing
+   * @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 {@code null} or the errors produced while
+   * scanning and parsing the source do not match the expected errors
+   */
+  static Object invokeParserMethod2(String methodName, String source, GatheringErrorListener listener) => invokeParserMethod(methodName, _EMPTY_ARGUMENTS, source, listener);
+  /**
+   * Return a CommentAndMetadata object with the given values that can be used for testing.
+   * @param comment the comment to be wrapped in the object
+   * @param annotations the annotations to be wrapped in the object
+   * @return a CommentAndMetadata object that can be used for testing
+   */
+  CommentAndMetadata commentAndMetadata(Comment comment, List<Annotation> annotations) {
+    List<Annotation> metadata = new List<Annotation>();
+    for (Annotation annotation in annotations) {
+      metadata.add(annotation);
+    }
+    return new CommentAndMetadata(comment, metadata);
+  }
+  /**
+   * Return an empty CommentAndMetadata object that can be used for testing.
+   * @return an empty CommentAndMetadata object that can be used for testing
+   */
+  CommentAndMetadata emptyCommentAndMetadata() => new CommentAndMetadata(null, new List<Annotation>());
+  static dartSuite() {
+    _ut.group('ParserTestCase', () {
+    });
+  }
+}
+/**
+ * The class {@code RecoveryParserTest} defines parser tests that test the parsing of invalid code
+ * sequences to ensure that the correct recovery steps are taken in the parser.
+ */
+class RecoveryParserTest extends ParserTestCase {
+  void test_additiveExpression_missing_LHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("+ y", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+  }
+  void test_additiveExpression_missing_LHS_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("+", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_additiveExpression_missing_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x +", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_additiveExpression_missing_RHS_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super +", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_additiveExpression_precedence_multiplicative_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("* +", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_additiveExpression_precedence_multiplicative_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("+ *", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
+  }
+  void test_additiveExpression_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super + +", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_argumentDefinitionTest_missing_identifier() {
+    ArgumentDefinitionTest expression = ParserTestCase.parseExpression("?", [ParserErrorCode.MISSING_IDENTIFIER]);
+    JUnitTestCase.assertTrue(expression.identifier.isSynthetic());
+  }
+  void test_assignmentExpression_missing_compound1() {
+    AssignmentExpression expression = ParserTestCase.parseExpression("= y = 0", []);
+    Expression syntheticExpression = expression.leftHandSide;
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
+    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
+  }
+  void test_assignmentExpression_missing_compound2() {
+    AssignmentExpression expression = ParserTestCase.parseExpression("x = = 0", []);
+    Expression syntheticExpression = ((expression.rightHandSide as AssignmentExpression)).leftHandSide;
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
+    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
+  }
+  void test_assignmentExpression_missing_compound3() {
+    AssignmentExpression expression = ParserTestCase.parseExpression("x = y =", []);
+    Expression syntheticExpression = ((expression.rightHandSide as AssignmentExpression)).rightHandSide;
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
+    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
+  }
+  void test_assignmentExpression_missing_LHS() {
+    AssignmentExpression expression = ParserTestCase.parseExpression("= 0", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftHandSide);
+    JUnitTestCase.assertTrue(expression.leftHandSide.isSynthetic());
+  }
+  void test_assignmentExpression_missing_RHS() {
+    AssignmentExpression expression = ParserTestCase.parseExpression("x =", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftHandSide);
+    JUnitTestCase.assertTrue(expression.rightHandSide.isSynthetic());
+  }
+  void test_bitwiseAndExpression_missing_LHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("& y", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+  }
+  void test_bitwiseAndExpression_missing_LHS_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("&", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_bitwiseAndExpression_missing_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x &", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_bitwiseAndExpression_missing_RHS_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super &", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_bitwiseAndExpression_precedence_equality_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("== &", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_bitwiseAndExpression_precedence_equality_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("& ==", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
+  }
+  void test_bitwiseAndExpression_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super &  &", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_bitwiseOrExpression_missing_LHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("| y", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+  }
+  void test_bitwiseOrExpression_missing_LHS_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("|", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_bitwiseOrExpression_missing_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x |", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_bitwiseOrExpression_missing_RHS_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super |", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_bitwiseOrExpression_precedence_xor_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("^ |", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_bitwiseOrExpression_precedence_xor_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("| ^", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
+  }
+  void test_bitwiseOrExpression_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super |  |", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_bitwiseXorExpression_missing_LHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("^ y", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+  }
+  void test_bitwiseXorExpression_missing_LHS_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("^", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_bitwiseXorExpression_missing_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x ^", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_bitwiseXorExpression_missing_RHS_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super ^", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_bitwiseXorExpression_precedence_and_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("& ^", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_bitwiseXorExpression_precedence_and_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("^ &", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
+  }
+  void test_bitwiseXorExpression_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super ^  ^", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_conditionalExpression_missingElse() {
+    ConditionalExpression expression = ParserTestCase.parse6("parseConditionalExpression", "x ? y :", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.elseExpression);
+    JUnitTestCase.assertTrue(expression.elseExpression.isSynthetic());
+  }
+  void test_conditionalExpression_missingThen() {
+    ConditionalExpression expression = ParserTestCase.parse6("parseConditionalExpression", "x ? : z", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.thenExpression);
+    JUnitTestCase.assertTrue(expression.thenExpression.isSynthetic());
+  }
+  void test_equalityExpression_missing_LHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("== y", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+  }
+  void test_equalityExpression_missing_LHS_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("==", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_equalityExpression_missing_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x ==", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_equalityExpression_missing_RHS_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super ==", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_equalityExpression_precedence_relational_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("is ==", [ParserErrorCode.MISSING_IDENTIFIER]);
+    EngineTestCase.assertInstanceOf(IsExpression, expression.leftOperand);
+  }
+  void test_equalityExpression_precedence_relational_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("== is", [ParserErrorCode.MISSING_IDENTIFIER]);
+    EngineTestCase.assertInstanceOf(IsExpression, expression.rightOperand);
+  }
+  void test_equalityExpression_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super ==  ==", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_expressionList_multiple_end() {
+    List<Expression> result = ParserTestCase.parse6("parseExpressionList", ", 2, 3, 4", []);
+    EngineTestCase.assertSize(4, result);
+    Expression syntheticExpression = result[0];
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
+    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
+  }
+  void test_expressionList_multiple_middle() {
+    List<Expression> result = ParserTestCase.parse6("parseExpressionList", "1, 2, , 4", []);
+    EngineTestCase.assertSize(4, result);
+    Expression syntheticExpression = result[2];
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
+    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
+  }
+  void test_expressionList_multiple_start() {
+    List<Expression> result = ParserTestCase.parse6("parseExpressionList", "1, 2, 3,", []);
+    EngineTestCase.assertSize(4, result);
+    Expression syntheticExpression = result[3];
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
+    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
+  }
+  void test_isExpression_noType() {
+    CompilationUnit unit = ParserTestCase.parseCompilationUnit("class Bar<T extends Foo> {m(x){if (x is ) return;if (x is !)}}", [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_STATEMENT]);
+    ClassDeclaration declaration = unit.declarations[0] as ClassDeclaration;
+    MethodDeclaration method = declaration.members[0] as MethodDeclaration;
+    BlockFunctionBody body5 = method.body as BlockFunctionBody;
+    IfStatement ifStatement = body5.block.statements[1] as IfStatement;
+    IsExpression expression = ifStatement.condition as IsExpression;
+    JUnitTestCase.assertNotNull(expression.expression);
+    JUnitTestCase.assertNotNull(expression.isOperator);
+    JUnitTestCase.assertNotNull(expression.notOperator);
+    TypeName type29 = expression.type;
+    JUnitTestCase.assertNotNull(type29);
+    JUnitTestCase.assertTrue(type29.name.isSynthetic());
+    EngineTestCase.assertInstanceOf(EmptyStatement, ifStatement.thenStatement);
+  }
+  void test_logicalAndExpression_missing_LHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("&& y", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+  }
+  void test_logicalAndExpression_missing_LHS_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("&&", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_logicalAndExpression_missing_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x &&", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_logicalAndExpression_precedence_bitwiseOr_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("| &&", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_logicalAndExpression_precedence_bitwiseOr_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("&& |", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
+  }
+  void test_logicalOrExpression_missing_LHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("|| y", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+  }
+  void test_logicalOrExpression_missing_LHS_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("||", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_logicalOrExpression_missing_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x ||", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_logicalOrExpression_precedence_logicalAnd_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("&& ||", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_logicalOrExpression_precedence_logicalAnd_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("|| &&", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
+  }
+  void test_multiplicativeExpression_missing_LHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("* y", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+  }
+  void test_multiplicativeExpression_missing_LHS_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("*", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_multiplicativeExpression_missing_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x *", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_multiplicativeExpression_missing_RHS_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super *", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_multiplicativeExpression_precedence_unary_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("-x *", []);
+    EngineTestCase.assertInstanceOf(PrefixExpression, expression.leftOperand);
+  }
+  void test_multiplicativeExpression_precedence_unary_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("* -y", []);
+    EngineTestCase.assertInstanceOf(PrefixExpression, expression.rightOperand);
+  }
+  void test_multiplicativeExpression_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super ==  ==", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_prefixExpression_missing_operand_minus() {
+    PrefixExpression expression = ParserTestCase.parseExpression("-", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.operand);
+    JUnitTestCase.assertTrue(expression.operand.isSynthetic());
+    JUnitTestCase.assertEquals(TokenType.MINUS, expression.operator.type);
+  }
+  void test_relationalExpression_missing_LHS() {
+    IsExpression expression = ParserTestCase.parseExpression("is y", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.expression);
+    JUnitTestCase.assertTrue(expression.expression.isSynthetic());
+  }
+  void test_relationalExpression_missing_LHS_RHS() {
+    IsExpression expression = ParserTestCase.parseExpression("is", [ParserErrorCode.MISSING_IDENTIFIER]);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.expression);
+    JUnitTestCase.assertTrue(expression.expression.isSynthetic());
+    EngineTestCase.assertInstanceOf(TypeName, expression.type);
+    JUnitTestCase.assertTrue(expression.type.isSynthetic());
+  }
+  void test_relationalExpression_missing_RHS() {
+    IsExpression expression = ParserTestCase.parseExpression("x is", [ParserErrorCode.MISSING_IDENTIFIER]);
+    EngineTestCase.assertInstanceOf(TypeName, expression.type);
+    JUnitTestCase.assertTrue(expression.type.isSynthetic());
+  }
+  void test_relationalExpression_precedence_shift_right() {
+    IsExpression expression = ParserTestCase.parseExpression("<< is", [ParserErrorCode.MISSING_IDENTIFIER]);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.expression);
+  }
+  void test_shiftExpression_missing_LHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("<< y", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+  }
+  void test_shiftExpression_missing_LHS_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("<<", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_shiftExpression_missing_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x <<", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_shiftExpression_missing_RHS_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super <<", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_shiftExpression_precedence_unary_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("+ <<", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_shiftExpression_precedence_unary_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("<< +", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
+  }
+  void test_shiftExpression_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super << <<", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_typedef_eof() {
+    CompilationUnit unit = ParserTestCase.parseCompilationUnit("typedef n", [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.MISSING_TYPEDEF_PARAMETERS]);
+    NodeList<CompilationUnitMember> declarations3 = unit.declarations;
+    EngineTestCase.assertSize(1, declarations3);
+    CompilationUnitMember member = declarations3[0];
+    EngineTestCase.assertInstanceOf(FunctionTypeAlias, member);
+  }
+  static dartSuite() {
+    _ut.group('RecoveryParserTest', () {
+      _ut.test('test_additiveExpression_missing_LHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_additiveExpression_missing_LHS);
+      });
+      _ut.test('test_additiveExpression_missing_LHS_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_additiveExpression_missing_LHS_RHS);
+      });
+      _ut.test('test_additiveExpression_missing_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_additiveExpression_missing_RHS);
+      });
+      _ut.test('test_additiveExpression_missing_RHS_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_additiveExpression_missing_RHS_super);
+      });
+      _ut.test('test_additiveExpression_precedence_multiplicative_left', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_additiveExpression_precedence_multiplicative_left);
+      });
+      _ut.test('test_additiveExpression_precedence_multiplicative_right', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_additiveExpression_precedence_multiplicative_right);
+      });
+      _ut.test('test_additiveExpression_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_additiveExpression_super);
+      });
+      _ut.test('test_argumentDefinitionTest_missing_identifier', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_argumentDefinitionTest_missing_identifier);
+      });
+      _ut.test('test_assignmentExpression_missing_LHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_assignmentExpression_missing_LHS);
+      });
+      _ut.test('test_assignmentExpression_missing_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_assignmentExpression_missing_RHS);
+      });
+      _ut.test('test_assignmentExpression_missing_compound1', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_assignmentExpression_missing_compound1);
+      });
+      _ut.test('test_assignmentExpression_missing_compound2', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_assignmentExpression_missing_compound2);
+      });
+      _ut.test('test_assignmentExpression_missing_compound3', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_assignmentExpression_missing_compound3);
+      });
+      _ut.test('test_bitwiseAndExpression_missing_LHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseAndExpression_missing_LHS);
+      });
+      _ut.test('test_bitwiseAndExpression_missing_LHS_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseAndExpression_missing_LHS_RHS);
+      });
+      _ut.test('test_bitwiseAndExpression_missing_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseAndExpression_missing_RHS);
+      });
+      _ut.test('test_bitwiseAndExpression_missing_RHS_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseAndExpression_missing_RHS_super);
+      });
+      _ut.test('test_bitwiseAndExpression_precedence_equality_left', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseAndExpression_precedence_equality_left);
+      });
+      _ut.test('test_bitwiseAndExpression_precedence_equality_right', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseAndExpression_precedence_equality_right);
+      });
+      _ut.test('test_bitwiseAndExpression_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseAndExpression_super);
+      });
+      _ut.test('test_bitwiseOrExpression_missing_LHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseOrExpression_missing_LHS);
+      });
+      _ut.test('test_bitwiseOrExpression_missing_LHS_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseOrExpression_missing_LHS_RHS);
+      });
+      _ut.test('test_bitwiseOrExpression_missing_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseOrExpression_missing_RHS);
+      });
+      _ut.test('test_bitwiseOrExpression_missing_RHS_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseOrExpression_missing_RHS_super);
+      });
+      _ut.test('test_bitwiseOrExpression_precedence_xor_left', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseOrExpression_precedence_xor_left);
+      });
+      _ut.test('test_bitwiseOrExpression_precedence_xor_right', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseOrExpression_precedence_xor_right);
+      });
+      _ut.test('test_bitwiseOrExpression_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseOrExpression_super);
+      });
+      _ut.test('test_bitwiseXorExpression_missing_LHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseXorExpression_missing_LHS);
+      });
+      _ut.test('test_bitwiseXorExpression_missing_LHS_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseXorExpression_missing_LHS_RHS);
+      });
+      _ut.test('test_bitwiseXorExpression_missing_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseXorExpression_missing_RHS);
+      });
+      _ut.test('test_bitwiseXorExpression_missing_RHS_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseXorExpression_missing_RHS_super);
+      });
+      _ut.test('test_bitwiseXorExpression_precedence_and_left', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseXorExpression_precedence_and_left);
+      });
+      _ut.test('test_bitwiseXorExpression_precedence_and_right', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseXorExpression_precedence_and_right);
+      });
+      _ut.test('test_bitwiseXorExpression_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseXorExpression_super);
+      });
+      _ut.test('test_conditionalExpression_missingElse', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_conditionalExpression_missingElse);
+      });
+      _ut.test('test_conditionalExpression_missingThen', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_conditionalExpression_missingThen);
+      });
+      _ut.test('test_equalityExpression_missing_LHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_equalityExpression_missing_LHS);
+      });
+      _ut.test('test_equalityExpression_missing_LHS_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_equalityExpression_missing_LHS_RHS);
+      });
+      _ut.test('test_equalityExpression_missing_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_equalityExpression_missing_RHS);
+      });
+      _ut.test('test_equalityExpression_missing_RHS_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_equalityExpression_missing_RHS_super);
+      });
+      _ut.test('test_equalityExpression_precedence_relational_left', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_equalityExpression_precedence_relational_left);
+      });
+      _ut.test('test_equalityExpression_precedence_relational_right', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_equalityExpression_precedence_relational_right);
+      });
+      _ut.test('test_equalityExpression_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_equalityExpression_super);
+      });
+      _ut.test('test_expressionList_multiple_end', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_expressionList_multiple_end);
+      });
+      _ut.test('test_expressionList_multiple_middle', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_expressionList_multiple_middle);
+      });
+      _ut.test('test_expressionList_multiple_start', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_expressionList_multiple_start);
+      });
+      _ut.test('test_isExpression_noType', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_isExpression_noType);
+      });
+      _ut.test('test_logicalAndExpression_missing_LHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_logicalAndExpression_missing_LHS);
+      });
+      _ut.test('test_logicalAndExpression_missing_LHS_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_logicalAndExpression_missing_LHS_RHS);
+      });
+      _ut.test('test_logicalAndExpression_missing_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_logicalAndExpression_missing_RHS);
+      });
+      _ut.test('test_logicalAndExpression_precedence_bitwiseOr_left', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_logicalAndExpression_precedence_bitwiseOr_left);
+      });
+      _ut.test('test_logicalAndExpression_precedence_bitwiseOr_right', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_logicalAndExpression_precedence_bitwiseOr_right);
+      });
+      _ut.test('test_logicalOrExpression_missing_LHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_logicalOrExpression_missing_LHS);
+      });
+      _ut.test('test_logicalOrExpression_missing_LHS_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_logicalOrExpression_missing_LHS_RHS);
+      });
+      _ut.test('test_logicalOrExpression_missing_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_logicalOrExpression_missing_RHS);
+      });
+      _ut.test('test_logicalOrExpression_precedence_logicalAnd_left', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_logicalOrExpression_precedence_logicalAnd_left);
+      });
+      _ut.test('test_logicalOrExpression_precedence_logicalAnd_right', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_logicalOrExpression_precedence_logicalAnd_right);
+      });
+      _ut.test('test_multiplicativeExpression_missing_LHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_multiplicativeExpression_missing_LHS);
+      });
+      _ut.test('test_multiplicativeExpression_missing_LHS_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_multiplicativeExpression_missing_LHS_RHS);
+      });
+      _ut.test('test_multiplicativeExpression_missing_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_multiplicativeExpression_missing_RHS);
+      });
+      _ut.test('test_multiplicativeExpression_missing_RHS_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_multiplicativeExpression_missing_RHS_super);
+      });
+      _ut.test('test_multiplicativeExpression_precedence_unary_left', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_multiplicativeExpression_precedence_unary_left);
+      });
+      _ut.test('test_multiplicativeExpression_precedence_unary_right', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_multiplicativeExpression_precedence_unary_right);
+      });
+      _ut.test('test_multiplicativeExpression_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_multiplicativeExpression_super);
+      });
+      _ut.test('test_prefixExpression_missing_operand_minus', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_prefixExpression_missing_operand_minus);
+      });
+      _ut.test('test_relationalExpression_missing_LHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_relationalExpression_missing_LHS);
+      });
+      _ut.test('test_relationalExpression_missing_LHS_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_relationalExpression_missing_LHS_RHS);
+      });
+      _ut.test('test_relationalExpression_missing_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_relationalExpression_missing_RHS);
+      });
+      _ut.test('test_relationalExpression_precedence_shift_right', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_relationalExpression_precedence_shift_right);
+      });
+      _ut.test('test_shiftExpression_missing_LHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_shiftExpression_missing_LHS);
+      });
+      _ut.test('test_shiftExpression_missing_LHS_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_shiftExpression_missing_LHS_RHS);
+      });
+      _ut.test('test_shiftExpression_missing_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_shiftExpression_missing_RHS);
+      });
+      _ut.test('test_shiftExpression_missing_RHS_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_shiftExpression_missing_RHS_super);
+      });
+      _ut.test('test_shiftExpression_precedence_unary_left', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_shiftExpression_precedence_unary_left);
+      });
+      _ut.test('test_shiftExpression_precedence_unary_right', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_shiftExpression_precedence_unary_right);
+      });
+      _ut.test('test_shiftExpression_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_shiftExpression_super);
+      });
+      _ut.test('test_typedef_eof', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_typedef_eof);
+      });
+    });
+  }
+}
+/**
  * The class {@code ErrorParserTest} defines parser tests that test the parsing of code to ensure
  * that errors are correctly reported, and in some cases, not reported.
  */
 class ErrorParserTest extends ParserTestCase {
   void fail_expectedListOrMapLiteral() {
-    TypedLiteral literal = ParserTestCase.parse4("parseListOrMapLiteral", <Object> [null], "1", [ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL]);
+    TypedLiteral literal = ParserTestCase.parse5("parseListOrMapLiteral", <Object> [null], "1", [ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL]);
     JUnitTestCase.assertTrue(literal.isSynthetic());
   }
   void fail_illegalAssignmentToNonAssignable_superAssigned() {
-    ParserTestCase.parse5("parseExpression", "super = x;", [ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]);
+    ParserTestCase.parse6("parseExpression", "super = x;", [ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]);
   }
   void fail_invalidCommentReference__new_nonIdentifier() {
-    ParserTestCase.parse4("parseCommentReference", <Object> ["new 42", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]);
+    ParserTestCase.parse5("parseCommentReference", <Object> ["new 42", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]);
   }
   void fail_invalidCommentReference__new_tooMuch() {
-    ParserTestCase.parse4("parseCommentReference", <Object> ["new a.b.c.d", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]);
+    ParserTestCase.parse5("parseCommentReference", <Object> ["new a.b.c.d", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]);
   }
   void fail_invalidCommentReference__nonNew_nonIdentifier() {
-    ParserTestCase.parse4("parseCommentReference", <Object> ["42", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]);
+    ParserTestCase.parse5("parseCommentReference", <Object> ["42", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]);
   }
   void fail_invalidCommentReference__nonNew_tooMuch() {
-    ParserTestCase.parse4("parseCommentReference", <Object> ["a.b.c.d", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]);
+    ParserTestCase.parse5("parseCommentReference", <Object> ["a.b.c.d", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]);
   }
   void fail_missingFunctionParameters_local_nonVoid_block() {
-    ParserTestCase.parse5("parseStatement", "int f { return x;}", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
+    ParserTestCase.parse6("parseStatement", "int f { return x;}", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
   }
   void fail_missingFunctionParameters_local_nonVoid_expression() {
-    ParserTestCase.parse5("parseStatement", "int f => x;", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
+    ParserTestCase.parse6("parseStatement", "int f => x;", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
   }
   void fail_unexpectedToken_invalidPostfixExpression() {
-    ParserTestCase.parse5("parseExpression", "f()++", [ParserErrorCode.UNEXPECTED_TOKEN]);
+    ParserTestCase.parse6("parseExpression", "f()++", [ParserErrorCode.UNEXPECTED_TOKEN]);
   }
   void fail_voidVariable_initializer() {
-    ParserTestCase.parse5("parseStatement", "void x = 0;", [ParserErrorCode.VOID_VARIABLE]);
+    ParserTestCase.parse6("parseStatement", "void x = 0;", [ParserErrorCode.VOID_VARIABLE]);
   }
   void fail_voidVariable_noInitializer() {
-    ParserTestCase.parse5("parseStatement", "void x;", [ParserErrorCode.VOID_VARIABLE]);
+    ParserTestCase.parse6("parseStatement", "void x;", [ParserErrorCode.VOID_VARIABLE]);
   }
   void test_abstractClassMember_constructor() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "abstract C.c();", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "abstract C.c();", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
   }
   void test_abstractClassMember_field() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "abstract C f;", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "abstract C f;", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
   }
   void test_abstractClassMember_getter() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "abstract get m;", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "abstract get m;", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
   }
   void test_abstractClassMember_method() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "abstract m();", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "abstract m();", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
   }
   void test_abstractClassMember_setter() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "abstract set m(v);", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "abstract set m(v);", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
   }
   void test_abstractTopLevelFunction_function() {
-    ParserTestCase.parse5("parseCompilationUnit", "abstract f(v) {}", [ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION]);
+    ParserTestCase.parse6("parseCompilationUnit", "abstract f(v) {}", [ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION]);
   }
   void test_abstractTopLevelFunction_getter() {
-    ParserTestCase.parse5("parseCompilationUnit", "abstract get m {}", [ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION]);
+    ParserTestCase.parse6("parseCompilationUnit", "abstract get m {}", [ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION]);
   }
   void test_abstractTopLevelFunction_setter() {
-    ParserTestCase.parse5("parseCompilationUnit", "abstract set m(v) {}", [ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION]);
+    ParserTestCase.parse6("parseCompilationUnit", "abstract set m(v) {}", [ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION]);
   }
   void test_abstractTopLevelVariable() {
-    ParserTestCase.parse5("parseCompilationUnit", "abstract C f;", [ParserErrorCode.ABSTRACT_TOP_LEVEL_VARIABLE]);
+    ParserTestCase.parse6("parseCompilationUnit", "abstract C f;", [ParserErrorCode.ABSTRACT_TOP_LEVEL_VARIABLE]);
   }
   void test_abstractTypeDef() {
-    ParserTestCase.parse5("parseCompilationUnit", "abstract typedef F();", [ParserErrorCode.ABSTRACT_TYPEDEF]);
+    ParserTestCase.parse6("parseCompilationUnit", "abstract typedef F();", [ParserErrorCode.ABSTRACT_TYPEDEF]);
   }
   void test_breakOutsideOfLoop_breakInDoStatement() {
-    ParserTestCase.parse5("parseDoStatement", "do {break;} while (x);", []);
+    ParserTestCase.parse6("parseDoStatement", "do {break;} while (x);", []);
   }
   void test_breakOutsideOfLoop_breakInForStatement() {
-    ParserTestCase.parse5("parseForStatement", "for (; x;) {break;}", []);
+    ParserTestCase.parse6("parseForStatement", "for (; x;) {break;}", []);
   }
   void test_breakOutsideOfLoop_breakInIfStatement() {
-    ParserTestCase.parse5("parseIfStatement", "if (x) {break;}", [ParserErrorCode.BREAK_OUTSIDE_OF_LOOP]);
+    ParserTestCase.parse6("parseIfStatement", "if (x) {break;}", [ParserErrorCode.BREAK_OUTSIDE_OF_LOOP]);
   }
   void test_breakOutsideOfLoop_breakInSwitchStatement() {
-    ParserTestCase.parse5("parseSwitchStatement", "switch (x) {case 1: break;}", []);
+    ParserTestCase.parse6("parseSwitchStatement", "switch (x) {case 1: break;}", []);
   }
   void test_breakOutsideOfLoop_breakInWhileStatement() {
-    ParserTestCase.parse5("parseWhileStatement", "while (x) {break;}", []);
+    ParserTestCase.parse6("parseWhileStatement", "while (x) {break;}", []);
   }
   void test_breakOutsideOfLoop_functionExpression_inALoop() {
-    ParserTestCase.parse5("parseStatement", "for(; x;) {() {break;};}", [ParserErrorCode.BREAK_OUTSIDE_OF_LOOP]);
+    ParserTestCase.parse6("parseStatement", "for(; x;) {() {break;};}", [ParserErrorCode.BREAK_OUTSIDE_OF_LOOP]);
   }
   void test_breakOutsideOfLoop_functionExpression_withALoop() {
-    ParserTestCase.parse5("parseStatement", "() {for (; x;) {break;}};", []);
-  }
-  void test_builtInIdentifierAsTypeDefName() {
-    ParserTestCase.parse4("parseTypeAlias", <Object> [emptyCommentAndMetadata()], "typedef as();", [ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME]);
-  }
-  void test_builtInIdentifierAsTypeName() {
-    ParserTestCase.parse4("parseClassDeclaration", <Object> [emptyCommentAndMetadata(), null], "class as {}", [ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME]);
-  }
-  void test_builtInIdentifierAsTypeVariableName() {
-    ParserTestCase.parse5("parseTypeParameter", "as", [ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME]);
+    ParserTestCase.parse6("parseStatement", "() {for (; x;) {break;}};", []);
   }
   void test_constAndFinal() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "const final int x;", [ParserErrorCode.CONST_AND_FINAL]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "const final int x;", [ParserErrorCode.CONST_AND_FINAL]);
   }
   void test_constAndVar() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "const var x;", [ParserErrorCode.CONST_AND_VAR]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "const var x;", [ParserErrorCode.CONST_AND_VAR]);
   }
   void test_constClass() {
-    ParserTestCase.parse5("parseCompilationUnit", "const class C {}", [ParserErrorCode.CONST_CLASS]);
+    ParserTestCase.parse6("parseCompilationUnit", "const class C {}", [ParserErrorCode.CONST_CLASS]);
   }
   void test_constMethod() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "const int m() {}", [ParserErrorCode.CONST_METHOD]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "const int m() {}", [ParserErrorCode.CONST_METHOD]);
   }
   void test_constTypedef() {
-    ParserTestCase.parse5("parseCompilationUnit", "const typedef F();", [ParserErrorCode.CONST_TYPEDEF]);
+    ParserTestCase.parse6("parseCompilationUnit", "const typedef F();", [ParserErrorCode.CONST_TYPEDEF]);
   }
   void test_continueOutsideOfLoop_continueInDoStatement() {
-    ParserTestCase.parse5("parseDoStatement", "do {continue;} while (x);", []);
+    ParserTestCase.parse6("parseDoStatement", "do {continue;} while (x);", []);
   }
   void test_continueOutsideOfLoop_continueInForStatement() {
-    ParserTestCase.parse5("parseForStatement", "for (; x;) {continue;}", []);
+    ParserTestCase.parse6("parseForStatement", "for (; x;) {continue;}", []);
   }
   void test_continueOutsideOfLoop_continueInIfStatement() {
-    ParserTestCase.parse5("parseIfStatement", "if (x) {continue;}", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]);
+    ParserTestCase.parse6("parseIfStatement", "if (x) {continue;}", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]);
   }
   void test_continueOutsideOfLoop_continueInSwitchStatement() {
-    ParserTestCase.parse5("parseSwitchStatement", "switch (x) {case 1: continue a;}", []);
+    ParserTestCase.parse6("parseSwitchStatement", "switch (x) {case 1: continue a;}", []);
   }
   void test_continueOutsideOfLoop_continueInWhileStatement() {
-    ParserTestCase.parse5("parseWhileStatement", "while (x) {continue;}", []);
+    ParserTestCase.parse6("parseWhileStatement", "while (x) {continue;}", []);
   }
   void test_continueOutsideOfLoop_functionExpression_inALoop() {
-    ParserTestCase.parse5("parseStatement", "for(; x;) {() {continue;};}", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]);
+    ParserTestCase.parse6("parseStatement", "for(; x;) {() {continue;};}", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]);
   }
   void test_continueOutsideOfLoop_functionExpression_withALoop() {
-    ParserTestCase.parse5("parseStatement", "() {for (; x;) {continue;}};", []);
+    ParserTestCase.parse6("parseStatement", "() {for (; x;) {continue;}};", []);
   }
   void test_continueWithoutLabelInCase_error() {
-    ParserTestCase.parse5("parseSwitchStatement", "switch (x) {case 1: continue;}", [ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE]);
+    ParserTestCase.parse6("parseSwitchStatement", "switch (x) {case 1: continue;}", [ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE]);
   }
   void test_continueWithoutLabelInCase_noError() {
-    ParserTestCase.parse5("parseSwitchStatement", "switch (x) {case 1: continue a;}", []);
+    ParserTestCase.parse6("parseSwitchStatement", "switch (x) {case 1: continue a;}", []);
   }
   void test_continueWithoutLabelInCase_noError_switchInLoop() {
-    ParserTestCase.parse5("parseWhileStatement", "while (a) { switch (b) {default: continue;}}", []);
+    ParserTestCase.parse6("parseWhileStatement", "while (a) { switch (b) {default: continue;}}", []);
   }
   void test_directiveAfterDeclaration_classBeforeDirective() {
-    CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "class Foo{} library l;", [ParserErrorCode.DIRECTIVE_AFTER_DECLARATION]);
+    CompilationUnit unit = ParserTestCase.parse6("parseCompilationUnit", "class Foo{} library l;", [ParserErrorCode.DIRECTIVE_AFTER_DECLARATION]);
     JUnitTestCase.assertNotNull(unit);
   }
   void test_directiveAfterDeclaration_classBetweenDirectives() {
-    CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "library l;\nclass Foo{}\npart 'a.dart';", [ParserErrorCode.DIRECTIVE_AFTER_DECLARATION]);
+    CompilationUnit unit = ParserTestCase.parse6("parseCompilationUnit", "library l;\nclass Foo{}\npart 'a.dart';", [ParserErrorCode.DIRECTIVE_AFTER_DECLARATION]);
     JUnitTestCase.assertNotNull(unit);
   }
   void test_duplicatedModifier_const() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "const const m;", [ParserErrorCode.DUPLICATED_MODIFIER]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "const const m;", [ParserErrorCode.DUPLICATED_MODIFIER]);
   }
   void test_duplicatedModifier_external() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "external external f();", [ParserErrorCode.DUPLICATED_MODIFIER]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "external external f();", [ParserErrorCode.DUPLICATED_MODIFIER]);
   }
   void test_duplicatedModifier_factory() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "factory factory C() {}", [ParserErrorCode.DUPLICATED_MODIFIER]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "factory factory C() {}", [ParserErrorCode.DUPLICATED_MODIFIER]);
   }
   void test_duplicatedModifier_final() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "final final m;", [ParserErrorCode.DUPLICATED_MODIFIER]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "final final m;", [ParserErrorCode.DUPLICATED_MODIFIER]);
   }
   void test_duplicatedModifier_static() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "static static m;", [ParserErrorCode.DUPLICATED_MODIFIER]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "static static m;", [ParserErrorCode.DUPLICATED_MODIFIER]);
   }
   void test_duplicatedModifier_var() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "var var m;", [ParserErrorCode.DUPLICATED_MODIFIER]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "var var m;", [ParserErrorCode.DUPLICATED_MODIFIER]);
   }
   void test_duplicateLabelInSwitchStatement() {
-    ParserTestCase.parse5("parseSwitchStatement", "switch (e) {l1: case 0: break; l1: case 1: break;}", [ParserErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT]);
+    ParserTestCase.parse6("parseSwitchStatement", "switch (e) {l1: case 0: break; l1: case 1: break;}", [ParserErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT]);
   }
   void test_expectedCaseOrDefault() {
-    ParserTestCase.parse5("parseSwitchStatement", "switch (e) {break;}", [ParserErrorCode.EXPECTED_CASE_OR_DEFAULT]);
+    ParserTestCase.parse6("parseSwitchStatement", "switch (e) {break;}", [ParserErrorCode.EXPECTED_CASE_OR_DEFAULT]);
   }
   void test_expectedStringLiteral() {
-    StringLiteral expression = ParserTestCase.parse5("parseStringLiteral", "1", [ParserErrorCode.EXPECTED_STRING_LITERAL]);
+    StringLiteral expression = ParserTestCase.parse6("parseStringLiteral", "1", [ParserErrorCode.EXPECTED_STRING_LITERAL]);
     JUnitTestCase.assertTrue(expression.isSynthetic());
   }
   void test_expectedToken_commaMissingInArgumentList() {
-    ParserTestCase.parse5("parseArgumentList", "(x, y z)", [ParserErrorCode.EXPECTED_TOKEN]);
+    ParserTestCase.parse6("parseArgumentList", "(x, y z)", [ParserErrorCode.EXPECTED_TOKEN]);
   }
   void test_expectedToken_semicolonMissingAfterExpression() {
-    ParserTestCase.parse5("parseStatement", "x", [ParserErrorCode.EXPECTED_TOKEN]);
+    ParserTestCase.parse6("parseStatement", "x", [ParserErrorCode.EXPECTED_TOKEN]);
   }
   void test_expectedToken_whileMissingInDoStatement() {
-    ParserTestCase.parse5("parseStatement", "do {} (x);", [ParserErrorCode.EXPECTED_TOKEN]);
+    ParserTestCase.parse6("parseStatement", "do {} (x);", [ParserErrorCode.EXPECTED_TOKEN]);
   }
   void test_exportDirectiveAfterPartDirective() {
-    ParserTestCase.parse5("parseCompilationUnit", "part 'a.dart'; export 'b.dart';", [ParserErrorCode.EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE]);
+    ParserTestCase.parse6("parseCompilationUnit", "part 'a.dart'; export 'b.dart';", [ParserErrorCode.EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE]);
   }
   void test_externalAfterConst() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "const external C();", [ParserErrorCode.EXTERNAL_AFTER_CONST]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "const external C();", [ParserErrorCode.EXTERNAL_AFTER_CONST]);
   }
   void test_externalAfterFactory() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "factory external C();", [ParserErrorCode.EXTERNAL_AFTER_FACTORY]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "factory external C();", [ParserErrorCode.EXTERNAL_AFTER_FACTORY]);
   }
   void test_externalAfterStatic() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "static external int m();", [ParserErrorCode.EXTERNAL_AFTER_STATIC]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "static external int m();", [ParserErrorCode.EXTERNAL_AFTER_STATIC]);
   }
   void test_externalClass() {
-    ParserTestCase.parse5("parseCompilationUnit", "external class C {}", [ParserErrorCode.EXTERNAL_CLASS]);
+    ParserTestCase.parse6("parseCompilationUnit", "external class C {}", [ParserErrorCode.EXTERNAL_CLASS]);
   }
   void test_externalConstructorWithBody_factory() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "external factory C() {}", [ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "external factory C() {}", [ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY]);
   }
   void test_externalConstructorWithBody_named() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "external C.c() {}", [ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "external C.c() {}", [ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY]);
   }
   void test_externalField_const() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "external const A f;", [ParserErrorCode.EXTERNAL_FIELD]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "external const A f;", [ParserErrorCode.EXTERNAL_FIELD]);
   }
   void test_externalField_final() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "external final A f;", [ParserErrorCode.EXTERNAL_FIELD]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "external final A f;", [ParserErrorCode.EXTERNAL_FIELD]);
   }
   void test_externalField_static() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "external static A f;", [ParserErrorCode.EXTERNAL_FIELD]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "external static A f;", [ParserErrorCode.EXTERNAL_FIELD]);
   }
   void test_externalField_typed() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "external A f;", [ParserErrorCode.EXTERNAL_FIELD]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "external A f;", [ParserErrorCode.EXTERNAL_FIELD]);
   }
   void test_externalField_untyped() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "external var f;", [ParserErrorCode.EXTERNAL_FIELD]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "external var f;", [ParserErrorCode.EXTERNAL_FIELD]);
   }
   void test_externalGetterWithBody() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "external int get x {}", [ParserErrorCode.EXTERNAL_GETTER_WITH_BODY]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "external int get x {}", [ParserErrorCode.EXTERNAL_GETTER_WITH_BODY]);
   }
   void test_externalMethodWithBody() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "external m() {}", [ParserErrorCode.EXTERNAL_METHOD_WITH_BODY]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "external m() {}", [ParserErrorCode.EXTERNAL_METHOD_WITH_BODY]);
   }
   void test_externalOperatorWithBody() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "external operator +(int value) {}", [ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "external operator +(int value) {}", [ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY]);
   }
   void test_externalSetterWithBody() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "external set x(int value) {}", [ParserErrorCode.EXTERNAL_SETTER_WITH_BODY]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "external set x(int value) {}", [ParserErrorCode.EXTERNAL_SETTER_WITH_BODY]);
   }
   void test_externalTypedef() {
-    ParserTestCase.parse5("parseCompilationUnit", "external typedef F();", [ParserErrorCode.EXTERNAL_TYPEDEF]);
+    ParserTestCase.parse6("parseCompilationUnit", "external typedef F();", [ParserErrorCode.EXTERNAL_TYPEDEF]);
   }
   void test_factoryTopLevelDeclaration_class() {
-    ParserTestCase.parse5("parseCompilationUnit", "factory class C {}", [ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION]);
+    ParserTestCase.parse6("parseCompilationUnit", "factory class C {}", [ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION]);
   }
   void test_factoryTopLevelDeclaration_typedef() {
-    ParserTestCase.parse5("parseCompilationUnit", "factory typedef F();", [ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION]);
+    ParserTestCase.parse6("parseCompilationUnit", "factory typedef F();", [ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION]);
   }
   void test_fieldInitializerOutsideConstructor() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "void m(this.x);", [ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "void m(this.x);", [ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]);
   }
   void test_finalAndVar() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "final var x;", [ParserErrorCode.FINAL_AND_VAR]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "final var x;", [ParserErrorCode.FINAL_AND_VAR]);
   }
   void test_finalClass() {
-    ParserTestCase.parse5("parseCompilationUnit", "final class C {}", [ParserErrorCode.FINAL_CLASS]);
+    ParserTestCase.parse6("parseCompilationUnit", "final class C {}", [ParserErrorCode.FINAL_CLASS]);
   }
   void test_finalConstructor() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "final C() {}", [ParserErrorCode.FINAL_CONSTRUCTOR]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "final C() {}", [ParserErrorCode.FINAL_CONSTRUCTOR]);
   }
   void test_finalMethod() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "final int m() {}", [ParserErrorCode.FINAL_METHOD]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "final int m() {}", [ParserErrorCode.FINAL_METHOD]);
   }
   void test_finalTypedef() {
-    ParserTestCase.parse5("parseCompilationUnit", "final typedef F();", [ParserErrorCode.FINAL_TYPEDEF]);
+    ParserTestCase.parse6("parseCompilationUnit", "final typedef F();", [ParserErrorCode.FINAL_TYPEDEF]);
   }
   void test_getterWithParameters() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "int get x() {}", [ParserErrorCode.GETTER_WITH_PARAMETERS]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "int get x() {}", [ParserErrorCode.GETTER_WITH_PARAMETERS]);
   }
   void test_illegalAssignmentToNonAssignable_superAssigned() {
-    ParserTestCase.parse5("parseExpression", "super = x;", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]);
+    ParserTestCase.parse6("parseExpression", "super = x;", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]);
   }
   void test_implementsBeforeExtends() {
-    ParserTestCase.parse5("parseCompilationUnit", "class A implements B extends C {}", [ParserErrorCode.IMPLEMENTS_BEFORE_EXTENDS]);
+    ParserTestCase.parse6("parseCompilationUnit", "class A implements B extends C {}", [ParserErrorCode.IMPLEMENTS_BEFORE_EXTENDS]);
   }
   void test_implementsBeforeWith() {
-    ParserTestCase.parse5("parseCompilationUnit", "class A extends B implements C with D {}", [ParserErrorCode.IMPLEMENTS_BEFORE_WITH]);
+    ParserTestCase.parse6("parseCompilationUnit", "class A extends B implements C with D {}", [ParserErrorCode.IMPLEMENTS_BEFORE_WITH]);
   }
   void test_importDirectiveAfterPartDirective() {
-    ParserTestCase.parse5("parseCompilationUnit", "part 'a.dart'; import 'b.dart';", [ParserErrorCode.IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE]);
+    ParserTestCase.parse6("parseCompilationUnit", "part 'a.dart'; import 'b.dart';", [ParserErrorCode.IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE]);
   }
   void test_initializedVariableInForEach() {
-    ParserTestCase.parse5("parseForStatement", "for (int a = 0 in foo) {}", [ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH]);
+    ParserTestCase.parse6("parseForStatement", "for (int a = 0 in foo) {}", [ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH]);
   }
   void test_invalidCodePoint() {
-    ParserTestCase.parse5("parseStringLiteral", "'\\uD900'", [ParserErrorCode.INVALID_CODE_POINT]);
+    ParserTestCase.parse6("parseStringLiteral", "'\\uD900'", [ParserErrorCode.INVALID_CODE_POINT]);
   }
   void test_invalidHexEscape_invalidDigit() {
-    ParserTestCase.parse5("parseStringLiteral", "'\\x0 a'", [ParserErrorCode.INVALID_HEX_ESCAPE]);
+    ParserTestCase.parse6("parseStringLiteral", "'\\x0 a'", [ParserErrorCode.INVALID_HEX_ESCAPE]);
   }
   void test_invalidHexEscape_tooFewDigits() {
-    ParserTestCase.parse5("parseStringLiteral", "'\\x0'", [ParserErrorCode.INVALID_HEX_ESCAPE]);
+    ParserTestCase.parse6("parseStringLiteral", "'\\x0'", [ParserErrorCode.INVALID_HEX_ESCAPE]);
   }
   void test_invalidOperatorForSuper() {
-    ParserTestCase.parse5("parseUnaryExpression", "++super", [ParserErrorCode.INVALID_OPERATOR_FOR_SUPER]);
+    ParserTestCase.parse6("parseUnaryExpression", "++super", [ParserErrorCode.INVALID_OPERATOR_FOR_SUPER]);
   }
   void test_invalidUnicodeEscape_incomplete_noDigits() {
-    ParserTestCase.parse5("parseStringLiteral", "'\\u{'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
+    ParserTestCase.parse6("parseStringLiteral", "'\\u{'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
   }
   void test_invalidUnicodeEscape_incomplete_someDigits() {
-    ParserTestCase.parse5("parseStringLiteral", "'\\u{0A'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
+    ParserTestCase.parse6("parseStringLiteral", "'\\u{0A'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
   }
   void test_invalidUnicodeEscape_invalidDigit() {
-    ParserTestCase.parse5("parseStringLiteral", "'\\u0 a'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
+    ParserTestCase.parse6("parseStringLiteral", "'\\u0 a'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
   }
   void test_invalidUnicodeEscape_tooFewDigits_fixed() {
-    ParserTestCase.parse5("parseStringLiteral", "'\\u04'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
+    ParserTestCase.parse6("parseStringLiteral", "'\\u04'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
   }
   void test_invalidUnicodeEscape_tooFewDigits_variable() {
-    ParserTestCase.parse5("parseStringLiteral", "'\\u{}'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
+    ParserTestCase.parse6("parseStringLiteral", "'\\u{}'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
   }
   void test_invalidUnicodeEscape_tooManyDigits_variable() {
-    ParserTestCase.parse5("parseStringLiteral", "'\\u{12345678}'", [ParserErrorCode.INVALID_UNICODE_ESCAPE, ParserErrorCode.INVALID_CODE_POINT]);
+    ParserTestCase.parse6("parseStringLiteral", "'\\u{12345678}'", [ParserErrorCode.INVALID_UNICODE_ESCAPE, ParserErrorCode.INVALID_CODE_POINT]);
   }
   void test_libraryDirectiveNotFirst() {
-    ParserTestCase.parse5("parseCompilationUnit", "import 'x.dart'; library l;", [ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST]);
+    ParserTestCase.parse6("parseCompilationUnit", "import 'x.dart'; library l;", [ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST]);
   }
   void test_libraryDirectiveNotFirst_afterPart() {
-    CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "part 'a.dart';\nlibrary l;", [ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST]);
+    CompilationUnit unit = ParserTestCase.parse6("parseCompilationUnit", "part 'a.dart';\nlibrary l;", [ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST]);
     JUnitTestCase.assertNotNull(unit);
   }
   void test_missingAssignableSelector_identifiersAssigned() {
-    ParserTestCase.parse5("parseExpression", "x.y = y;", []);
+    ParserTestCase.parse6("parseExpression", "x.y = y;", []);
   }
   void test_missingAssignableSelector_primarySelectorPostfix() {
-    ParserTestCase.parse5("parseExpression", "x(y)(z)++", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR]);
+    ParserTestCase.parse6("parseExpression", "x(y)(z)++", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR]);
   }
   void test_missingAssignableSelector_selector() {
-    ParserTestCase.parse5("parseExpression", "x(y)(z).a++", []);
+    ParserTestCase.parse6("parseExpression", "x(y)(z).a++", []);
   }
   void test_missingAssignableSelector_superPrimaryExpression() {
-    SuperExpression expression = ParserTestCase.parse5("parsePrimaryExpression", "super", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR]);
+    SuperExpression expression = ParserTestCase.parse6("parsePrimaryExpression", "super", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR]);
     JUnitTestCase.assertNotNull(expression.keyword);
   }
   void test_missingAssignableSelector_superPropertyAccessAssigned() {
-    ParserTestCase.parse5("parseExpression", "super.x = x;", []);
+    ParserTestCase.parse6("parseExpression", "super.x = x;", []);
   }
   void test_missingCatchOrFinally() {
-    TryStatement statement = ParserTestCase.parse5("parseTryStatement", "try {}", [ParserErrorCode.MISSING_CATCH_OR_FINALLY]);
+    TryStatement statement = ParserTestCase.parse6("parseTryStatement", "try {}", [ParserErrorCode.MISSING_CATCH_OR_FINALLY]);
     JUnitTestCase.assertNotNull(statement);
   }
   void test_missingClassBody() {
-    ParserTestCase.parse5("parseCompilationUnit", "class A class B {}", [ParserErrorCode.MISSING_CLASS_BODY]);
+    ParserTestCase.parse6("parseCompilationUnit", "class A class B {}", [ParserErrorCode.MISSING_CLASS_BODY]);
   }
   void test_missingConstFinalVarOrType() {
-    ParserTestCase.parse4("parseFinalConstVarOrType", <Object> [false], "a;", [ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE]);
+    ParserTestCase.parse5("parseFinalConstVarOrType", <Object> [false], "a;", [ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE]);
   }
   void test_missingFunctionBody_emptyNotAllowed() {
-    ParserTestCase.parse4("parseFunctionBody", <Object> [false, false], ";", [ParserErrorCode.MISSING_FUNCTION_BODY]);
+    ParserTestCase.parse5("parseFunctionBody", <Object> [false, false], ";", [ParserErrorCode.MISSING_FUNCTION_BODY]);
   }
   void test_missingFunctionBody_invalid() {
-    ParserTestCase.parse4("parseFunctionBody", <Object> [false, false], "return 0;", [ParserErrorCode.MISSING_FUNCTION_BODY]);
+    ParserTestCase.parse5("parseFunctionBody", <Object> [false, false], "return 0;", [ParserErrorCode.MISSING_FUNCTION_BODY]);
   }
   void test_missingFunctionParameters_local_void_block() {
-    ParserTestCase.parse5("parseStatement", "void f { return x;}", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
+    ParserTestCase.parse6("parseStatement", "void f { return x;}", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
   }
   void test_missingFunctionParameters_local_void_expression() {
-    ParserTestCase.parse5("parseStatement", "void f => x;", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
+    ParserTestCase.parse6("parseStatement", "void f => x;", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
   }
   void test_missingFunctionParameters_topLevel_nonVoid_block() {
-    ParserTestCase.parse5("parseCompilationUnit", "int f { return x;}", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
+    ParserTestCase.parse6("parseCompilationUnit", "int f { return x;}", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
   }
   void test_missingFunctionParameters_topLevel_nonVoid_expression() {
-    ParserTestCase.parse5("parseCompilationUnit", "int f => x;", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
+    ParserTestCase.parse6("parseCompilationUnit", "int f => x;", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
   }
   void test_missingFunctionParameters_topLevel_void_block() {
-    ParserTestCase.parse5("parseCompilationUnit", "void f { return x;}", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
+    ParserTestCase.parse6("parseCompilationUnit", "void f { return x;}", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
   }
   void test_missingFunctionParameters_topLevel_void_expression() {
-    ParserTestCase.parse5("parseCompilationUnit", "void f => x;", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
+    ParserTestCase.parse6("parseCompilationUnit", "void f => x;", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
   }
   void test_missingIdentifier_functionDeclaration_returnTypeWithoutName() {
-    ParserTestCase.parse5("parseFunctionDeclarationStatement", "A<T> () {}", [ParserErrorCode.MISSING_IDENTIFIER]);
+    ParserTestCase.parse6("parseFunctionDeclarationStatement", "A<T> () {}", [ParserErrorCode.MISSING_IDENTIFIER]);
   }
   void test_missingIdentifier_number() {
-    SimpleIdentifier expression = ParserTestCase.parse5("parseSimpleIdentifier", "1", [ParserErrorCode.MISSING_IDENTIFIER]);
+    SimpleIdentifier expression = ParserTestCase.parse6("parseSimpleIdentifier", "1", [ParserErrorCode.MISSING_IDENTIFIER]);
     JUnitTestCase.assertTrue(expression.isSynthetic());
   }
   void test_missingNameInLibraryDirective() {
-    CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "library;", [ParserErrorCode.MISSING_NAME_IN_LIBRARY_DIRECTIVE]);
+    CompilationUnit unit = ParserTestCase.parse6("parseCompilationUnit", "library;", [ParserErrorCode.MISSING_NAME_IN_LIBRARY_DIRECTIVE]);
     JUnitTestCase.assertNotNull(unit);
   }
   void test_missingNameInPartOfDirective() {
-    CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "part of;", [ParserErrorCode.MISSING_NAME_IN_PART_OF_DIRECTIVE]);
+    CompilationUnit unit = ParserTestCase.parse6("parseCompilationUnit", "part of;", [ParserErrorCode.MISSING_NAME_IN_PART_OF_DIRECTIVE]);
     JUnitTestCase.assertNotNull(unit);
   }
+  void test_missingTerminatorForParameterGroup_named() {
+    ParserTestCase.parse6("parseFormalParameterList", "(a, {b: 0)", [ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP]);
+  }
+  void test_missingTerminatorForParameterGroup_optional() {
+    ParserTestCase.parse6("parseFormalParameterList", "(a, [b = 0)", [ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP]);
+  }
   void test_missingTypedefParameters_nonVoid() {
-    ParserTestCase.parse5("parseCompilationUnit", "typedef int F;", [ParserErrorCode.MISSING_TYPEDEF_PARAMETERS]);
+    ParserTestCase.parse6("parseCompilationUnit", "typedef int F;", [ParserErrorCode.MISSING_TYPEDEF_PARAMETERS]);
   }
   void test_missingTypedefParameters_typeParameters() {
-    ParserTestCase.parse5("parseCompilationUnit", "typedef F<E>;", [ParserErrorCode.MISSING_TYPEDEF_PARAMETERS]);
+    ParserTestCase.parse6("parseCompilationUnit", "typedef F<E>;", [ParserErrorCode.MISSING_TYPEDEF_PARAMETERS]);
   }
   void test_missingTypedefParameters_void() {
-    ParserTestCase.parse5("parseCompilationUnit", "typedef void F;", [ParserErrorCode.MISSING_TYPEDEF_PARAMETERS]);
+    ParserTestCase.parse6("parseCompilationUnit", "typedef void F;", [ParserErrorCode.MISSING_TYPEDEF_PARAMETERS]);
   }
   void test_missingVariableInForEach() {
-    ParserTestCase.parse5("parseForStatement", "for (a < b in foo) {}", [ParserErrorCode.MISSING_VARIABLE_IN_FOR_EACH]);
+    ParserTestCase.parse6("parseForStatement", "for (a < b in foo) {}", [ParserErrorCode.MISSING_VARIABLE_IN_FOR_EACH]);
   }
   void test_mixedParameterGroups_namedPositional() {
-    ParserTestCase.parse5("parseFormalParameterList", "(a, {b}, [c])", [ParserErrorCode.MIXED_PARAMETER_GROUPS]);
+    ParserTestCase.parse6("parseFormalParameterList", "(a, {b}, [c])", [ParserErrorCode.MIXED_PARAMETER_GROUPS]);
   }
   void test_mixedParameterGroups_positionalNamed() {
-    ParserTestCase.parse5("parseFormalParameterList", "(a, [b], {c})", [ParserErrorCode.MIXED_PARAMETER_GROUPS]);
+    ParserTestCase.parse6("parseFormalParameterList", "(a, [b], {c})", [ParserErrorCode.MIXED_PARAMETER_GROUPS]);
   }
   void test_multipleLibraryDirectives() {
-    ParserTestCase.parse5("parseCompilationUnit", "library l; library m;", [ParserErrorCode.MULTIPLE_LIBRARY_DIRECTIVES]);
+    ParserTestCase.parse6("parseCompilationUnit", "library l; library m;", [ParserErrorCode.MULTIPLE_LIBRARY_DIRECTIVES]);
   }
   void test_multipleNamedParameterGroups() {
-    ParserTestCase.parse5("parseFormalParameterList", "(a, {b}, {c})", [ParserErrorCode.MULTIPLE_NAMED_PARAMETER_GROUPS]);
+    ParserTestCase.parse6("parseFormalParameterList", "(a, {b}, {c})", [ParserErrorCode.MULTIPLE_NAMED_PARAMETER_GROUPS]);
   }
   void test_multiplePartOfDirectives() {
-    ParserTestCase.parse5("parseCompilationUnit", "part of l; part of m;", [ParserErrorCode.MULTIPLE_PART_OF_DIRECTIVES]);
+    ParserTestCase.parse6("parseCompilationUnit", "part of l; part of m;", [ParserErrorCode.MULTIPLE_PART_OF_DIRECTIVES]);
   }
   void test_multiplePositionalParameterGroups() {
-    ParserTestCase.parse5("parseFormalParameterList", "(a, [b], [c])", [ParserErrorCode.MULTIPLE_POSITIONAL_PARAMETER_GROUPS]);
+    ParserTestCase.parse6("parseFormalParameterList", "(a, [b], [c])", [ParserErrorCode.MULTIPLE_POSITIONAL_PARAMETER_GROUPS]);
   }
   void test_multipleVariablesInForEach() {
-    ParserTestCase.parse5("parseForStatement", "for (int a, b in foo) {}", [ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH]);
+    ParserTestCase.parse6("parseForStatement", "for (int a, b in foo) {}", [ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH]);
   }
   void test_namedParameterOutsideGroup() {
-    ParserTestCase.parse5("parseFormalParameterList", "(a, b : 0)", [ParserErrorCode.NAMED_PARAMETER_OUTSIDE_GROUP]);
+    ParserTestCase.parse6("parseFormalParameterList", "(a, b : 0)", [ParserErrorCode.NAMED_PARAMETER_OUTSIDE_GROUP]);
   }
   void test_nonConstructorFactory_field() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "factory int x;", [ParserErrorCode.NON_CONSTRUCTOR_FACTORY]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "factory int x;", [ParserErrorCode.NON_CONSTRUCTOR_FACTORY]);
   }
   void test_nonConstructorFactory_method() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "factory int m() {}", [ParserErrorCode.NON_CONSTRUCTOR_FACTORY]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "factory int m() {}", [ParserErrorCode.NON_CONSTRUCTOR_FACTORY]);
   }
   void test_nonIdentifierLibraryName_library() {
-    CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "library 'lib';", [ParserErrorCode.NON_IDENTIFIER_LIBRARY_NAME]);
+    CompilationUnit unit = ParserTestCase.parse6("parseCompilationUnit", "library 'lib';", [ParserErrorCode.NON_IDENTIFIER_LIBRARY_NAME]);
     JUnitTestCase.assertNotNull(unit);
   }
   void test_nonIdentifierLibraryName_partOf() {
-    CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "part of 'lib';", [ParserErrorCode.NON_IDENTIFIER_LIBRARY_NAME]);
+    CompilationUnit unit = ParserTestCase.parse6("parseCompilationUnit", "part of 'lib';", [ParserErrorCode.NON_IDENTIFIER_LIBRARY_NAME]);
     JUnitTestCase.assertNotNull(unit);
   }
   void test_nonPartOfDirectiveInPart_after() {
-    ParserTestCase.parse5("parseCompilationUnit", "part of l; part 'f.dart';", [ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART]);
+    ParserTestCase.parse6("parseCompilationUnit", "part of l; part 'f.dart';", [ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART]);
   }
   void test_nonPartOfDirectiveInPart_before() {
-    ParserTestCase.parse5("parseCompilationUnit", "part 'f.dart'; part of m;", [ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART]);
+    ParserTestCase.parse6("parseCompilationUnit", "part 'f.dart'; part of m;", [ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART]);
   }
   void test_nonUserDefinableOperator() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "operator +=(int x) => x + 1;", [ParserErrorCode.NON_USER_DEFINABLE_OPERATOR]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "operator +=(int x) => x + 1;", [ParserErrorCode.NON_USER_DEFINABLE_OPERATOR]);
   }
   void test_positionalAfterNamedArgument() {
-    ParserTestCase.parse5("parseArgumentList", "(x: 1, 2)", [ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT]);
+    ParserTestCase.parse6("parseArgumentList", "(x: 1, 2)", [ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT]);
   }
   void test_positionalParameterOutsideGroup() {
-    ParserTestCase.parse5("parseFormalParameterList", "(a, b = 0)", [ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP]);
+    ParserTestCase.parse6("parseFormalParameterList", "(a, b = 0)", [ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP]);
   }
   void test_staticAfterConst() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "final static int f;", [ParserErrorCode.STATIC_AFTER_FINAL]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "final static int f;", [ParserErrorCode.STATIC_AFTER_FINAL]);
   }
   void test_staticAfterFinal() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "const static int f;", [ParserErrorCode.STATIC_AFTER_CONST]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "const static int f;", [ParserErrorCode.STATIC_AFTER_CONST]);
   }
   void test_staticAfterVar() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "var static f;", [ParserErrorCode.STATIC_AFTER_VAR]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "var static f;", [ParserErrorCode.STATIC_AFTER_VAR]);
   }
   void test_staticConstructor() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "static C.m() {}", [ParserErrorCode.STATIC_CONSTRUCTOR]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "static C.m() {}", [ParserErrorCode.STATIC_CONSTRUCTOR]);
   }
   void test_staticOperator_noReturnType() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "static operator +(int x) => x + 1;", [ParserErrorCode.STATIC_OPERATOR]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "static operator +(int x) => x + 1;", [ParserErrorCode.STATIC_OPERATOR]);
   }
   void test_staticOperator_returnType() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "static int operator +(int x) => x + 1;", [ParserErrorCode.STATIC_OPERATOR]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "static int operator +(int x) => x + 1;", [ParserErrorCode.STATIC_OPERATOR]);
   }
   void test_staticTopLevelDeclaration_class() {
-    ParserTestCase.parse5("parseCompilationUnit", "static class C {}", [ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION]);
+    ParserTestCase.parse6("parseCompilationUnit", "static class C {}", [ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION]);
   }
   void test_staticTopLevelDeclaration_typedef() {
-    ParserTestCase.parse5("parseCompilationUnit", "static typedef F();", [ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION]);
+    ParserTestCase.parse6("parseCompilationUnit", "static typedef F();", [ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION]);
   }
   void test_staticTopLevelDeclaration_variable() {
-    ParserTestCase.parse5("parseCompilationUnit", "static var x;", [ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION]);
+    ParserTestCase.parse6("parseCompilationUnit", "static var x;", [ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION]);
+  }
+  void test_unexpectedTerminatorForParameterGroup_named() {
+    ParserTestCase.parse6("parseFormalParameterList", "(a, b})", [ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP]);
+  }
+  void test_unexpectedTerminatorForParameterGroup_optional() {
+    ParserTestCase.parse6("parseFormalParameterList", "(a, b])", [ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP]);
   }
   void test_unexpectedToken_semicolonBetweenClassMembers() {
-    ParserTestCase.parse4("parseClassDeclaration", <Object> [emptyCommentAndMetadata(), null], "class C { int x; ; int y;}", [ParserErrorCode.UNEXPECTED_TOKEN]);
+    ParserTestCase.parse5("parseClassDeclaration", <Object> [emptyCommentAndMetadata(), null], "class C { int x; ; int y;}", [ParserErrorCode.UNEXPECTED_TOKEN]);
   }
   void test_unexpectedToken_semicolonBetweenCompilationUnitMembers() {
-    ParserTestCase.parse5("parseCompilationUnit", "int x; ; int y;", [ParserErrorCode.UNEXPECTED_TOKEN]);
+    ParserTestCase.parse6("parseCompilationUnit", "int x; ; int y;", [ParserErrorCode.UNEXPECTED_TOKEN]);
   }
   void test_useOfUnaryPlusOperator() {
-    ParserTestCase.parse5("parseUnaryExpression", "+x", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
+    ParserTestCase.parse6("parseUnaryExpression", "+x", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
   }
   void test_varClass() {
-    ParserTestCase.parse5("parseCompilationUnit", "var class C {}", [ParserErrorCode.VAR_CLASS]);
+    ParserTestCase.parse6("parseCompilationUnit", "var class C {}", [ParserErrorCode.VAR_CLASS]);
   }
   void test_varConstructor() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "var C() {}", [ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "var C() {}", [ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE]);
   }
   void test_varReturnType() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "var m() {}", [ParserErrorCode.VAR_RETURN_TYPE]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "var m() {}", [ParserErrorCode.VAR_RETURN_TYPE]);
   }
   void test_varTypedef() {
-    ParserTestCase.parse5("parseCompilationUnit", "var typedef F();", [ParserErrorCode.VAR_TYPEDEF]);
+    ParserTestCase.parse6("parseCompilationUnit", "var typedef F();", [ParserErrorCode.VAR_TYPEDEF]);
   }
   void test_voidField_initializer() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "void x = 0;", [ParserErrorCode.VOID_VARIABLE]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "void x = 0;", [ParserErrorCode.VOID_VARIABLE]);
   }
   void test_voidField_noInitializer() {
-    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "void x;", [ParserErrorCode.VOID_VARIABLE]);
+    ParserTestCase.parse5("parseClassMember", <Object> ["C"], "void x;", [ParserErrorCode.VOID_VARIABLE]);
   }
   void test_voidParameter() {
-    ParserTestCase.parse5("parseNormalFormalParameter", "void a)", [ParserErrorCode.VOID_PARAMETER]);
+    ParserTestCase.parse6("parseNormalFormalParameter", "void a)", [ParserErrorCode.VOID_PARAMETER]);
   }
   void test_withBeforeExtends() {
-    ParserTestCase.parse5("parseCompilationUnit", "class A with B extends C {}", [ParserErrorCode.WITH_BEFORE_EXTENDS]);
+    ParserTestCase.parse6("parseCompilationUnit", "class A with B extends C {}", [ParserErrorCode.WITH_BEFORE_EXTENDS]);
   }
   void test_withWithoutExtends() {
-    ParserTestCase.parse4("parseClassDeclaration", <Object> [emptyCommentAndMetadata(), null], "class A with B, C {}", [ParserErrorCode.WITH_WITHOUT_EXTENDS]);
+    ParserTestCase.parse5("parseClassDeclaration", <Object> [emptyCommentAndMetadata(), null], "class A with B, C {}", [ParserErrorCode.WITH_WITHOUT_EXTENDS]);
   }
   void test_wrongSeparatorForNamedParameter() {
-    ParserTestCase.parse5("parseFormalParameterList", "(a, {b = 0})", [ParserErrorCode.WRONG_SEPARATOR_FOR_NAMED_PARAMETER]);
+    ParserTestCase.parse6("parseFormalParameterList", "(a, {b = 0})", [ParserErrorCode.WRONG_SEPARATOR_FOR_NAMED_PARAMETER]);
   }
   void test_wrongSeparatorForPositionalParameter() {
-    ParserTestCase.parse5("parseFormalParameterList", "(a, [b : 0])", [ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER]);
+    ParserTestCase.parse6("parseFormalParameterList", "(a, [b : 0])", [ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER]);
+  }
+  void test_wrongTerminatorForParameterGroup_named() {
+    ParserTestCase.parse6("parseFormalParameterList", "(a, {b, c])", [ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP]);
+  }
+  void test_wrongTerminatorForParameterGroup_optional() {
+    ParserTestCase.parse6("parseFormalParameterList", "(a, [b, c})", [ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP]);
   }
   static dartSuite() {
     _ut.group('ErrorParserTest', () {
@@ -7484,18 +7596,6 @@
         final __test = new ErrorParserTest();
         runJUnitTest(__test, __test.test_breakOutsideOfLoop_functionExpression_withALoop);
       });
-      _ut.test('test_builtInIdentifierAsTypeDefName', () {
-        final __test = new ErrorParserTest();
-        runJUnitTest(__test, __test.test_builtInIdentifierAsTypeDefName);
-      });
-      _ut.test('test_builtInIdentifierAsTypeName', () {
-        final __test = new ErrorParserTest();
-        runJUnitTest(__test, __test.test_builtInIdentifierAsTypeName);
-      });
-      _ut.test('test_builtInIdentifierAsTypeVariableName', () {
-        final __test = new ErrorParserTest();
-        runJUnitTest(__test, __test.test_builtInIdentifierAsTypeVariableName);
-      });
       _ut.test('test_constAndFinal', () {
         final __test = new ErrorParserTest();
         runJUnitTest(__test, __test.test_constAndFinal);
@@ -7864,6 +7964,14 @@
         final __test = new ErrorParserTest();
         runJUnitTest(__test, __test.test_missingNameInPartOfDirective);
       });
+      _ut.test('test_missingTerminatorForParameterGroup_named', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingTerminatorForParameterGroup_named);
+      });
+      _ut.test('test_missingTerminatorForParameterGroup_optional', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingTerminatorForParameterGroup_optional);
+      });
       _ut.test('test_missingTypedefParameters_nonVoid', () {
         final __test = new ErrorParserTest();
         runJUnitTest(__test, __test.test_missingTypedefParameters_nonVoid);
@@ -7984,6 +8092,14 @@
         final __test = new ErrorParserTest();
         runJUnitTest(__test, __test.test_staticTopLevelDeclaration_variable);
       });
+      _ut.test('test_unexpectedTerminatorForParameterGroup_named', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_unexpectedTerminatorForParameterGroup_named);
+      });
+      _ut.test('test_unexpectedTerminatorForParameterGroup_optional', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_unexpectedTerminatorForParameterGroup_optional);
+      });
       _ut.test('test_unexpectedToken_semicolonBetweenClassMembers', () {
         final __test = new ErrorParserTest();
         runJUnitTest(__test, __test.test_unexpectedToken_semicolonBetweenClassMembers);
@@ -8040,6 +8156,14 @@
         final __test = new ErrorParserTest();
         runJUnitTest(__test, __test.test_wrongSeparatorForPositionalParameter);
       });
+      _ut.test('test_wrongTerminatorForParameterGroup_named', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_wrongTerminatorForParameterGroup_named);
+      });
+      _ut.test('test_wrongTerminatorForParameterGroup_optional', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_wrongTerminatorForParameterGroup_optional);
+      });
     });
   }
 }
@@ -8091,7 +8215,7 @@
   'parseCascadeSection_0': new MethodTrampoline(0, (Parser target) => target.parseCascadeSection()),
   'parseClassDeclaration_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.parseClassDeclaration(arg0, arg1)),
   'parseClassMember_1': new MethodTrampoline(1, (Parser target, arg0) => target.parseClassMember(arg0)),
-  'parseClassMembers_1': new MethodTrampoline(1, (Parser target, arg0) => target.parseClassMembers(arg0)),
+  'parseClassMembers_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.parseClassMembers(arg0, arg1)),
   'parseClassTypeAlias_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.parseClassTypeAlias(arg0, arg1)),
   'parseCombinators_0': new MethodTrampoline(0, (Parser target) => target.parseCombinators()),
   'parseCommentAndMetadata_0': new MethodTrampoline(0, (Parser target) => target.parseCommentAndMetadata()),
@@ -8120,7 +8244,7 @@
   'parseFormalParameterList_0': new MethodTrampoline(0, (Parser target) => target.parseFormalParameterList()),
   'parseForStatement_0': new MethodTrampoline(0, (Parser target) => target.parseForStatement()),
   'parseFunctionBody_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.parseFunctionBody(arg0, arg1)),
-  'parseFunctionDeclaration_4': new MethodTrampoline(4, (Parser target, arg0, arg1, arg2, arg3) => target.parseFunctionDeclaration(arg0, arg1, arg2, arg3)),
+  'parseFunctionDeclaration_3': new MethodTrampoline(3, (Parser target, arg0, arg1, arg2) => target.parseFunctionDeclaration(arg0, arg1, arg2)),
   'parseFunctionDeclarationStatement_0': new MethodTrampoline(0, (Parser target) => target.parseFunctionDeclarationStatement()),
   'parseFunctionDeclarationStatement_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.parseFunctionDeclarationStatement2(arg0, arg1)),
   'parseFunctionExpression_0': new MethodTrampoline(0, (Parser target) => target.parseFunctionExpression()),
@@ -8161,7 +8285,6 @@
   'parseSetter_4': new MethodTrampoline(4, (Parser target, arg0, arg1, arg2, arg3) => target.parseSetter(arg0, arg1, arg2, arg3)),
   'parseShiftExpression_0': new MethodTrampoline(0, (Parser target) => target.parseShiftExpression()),
   'parseSimpleIdentifier_0': new MethodTrampoline(0, (Parser target) => target.parseSimpleIdentifier()),
-  'parseSimpleIdentifier_1': new MethodTrampoline(1, (Parser target, arg0) => target.parseSimpleIdentifier2(arg0)),
   'parseStatement_0': new MethodTrampoline(0, (Parser target) => target.parseStatement2()),
   'parseStatements_0': new MethodTrampoline(0, (Parser target) => target.parseStatements2()),
   'parseStringInterpolation_1': new MethodTrampoline(1, (Parser target, arg0) => target.parseStringInterpolation(arg0)),
@@ -8186,7 +8309,7 @@
   'peek_0': new MethodTrampoline(0, (Parser target) => target.peek()),
   'peek_1': new MethodTrampoline(1, (Parser target, arg0) => target.peek2(arg0)),
   'reportError_3': new MethodTrampoline(3, (Parser target, arg0, arg1, arg2) => target.reportError(arg0, arg1, arg2)),
-  'reportError_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.reportError3(arg0, arg1)),
+  'reportError_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.reportError4(arg0, arg1)),
   'skipFinalConstVarOrType_1': new MethodTrampoline(1, (Parser target, arg0) => target.skipFinalConstVarOrType(arg0)),
   'skipFormalParameterList_1': new MethodTrampoline(1, (Parser target, arg0) => target.skipFormalParameterList(arg0)),
   'skipPastMatchingToken_1': new MethodTrampoline(1, (Parser target, arg0) => target.skipPastMatchingToken(arg0)),
diff --git a/pkg/analyzer_experimental/test/generated/resolver_test.dart b/pkg/analyzer_experimental/test/generated/resolver_test.dart
new file mode 100644
index 0000000..e1343b4
--- /dev/null
+++ b/pkg/analyzer_experimental/test/generated/resolver_test.dart
@@ -0,0 +1,5168 @@
+// This code was auto-generated, is not intended to be edited, and is subject to
+// significant change. Please see the README file for more information.
+
+library engine.resolver_test;
+
+import 'dart:collection';
+import 'package:analyzer_experimental/src/generated/java_core.dart';
+import 'package:analyzer_experimental/src/generated/java_engine.dart';
+import 'package:analyzer_experimental/src/generated/java_junit.dart';
+import 'package:analyzer_experimental/src/generated/source_io.dart';
+import 'package:analyzer_experimental/src/generated/error.dart';
+import 'package:analyzer_experimental/src/generated/scanner.dart';
+import 'package:analyzer_experimental/src/generated/element.dart';
+import 'package:analyzer_experimental/src/generated/resolver.dart';
+import 'package:analyzer_experimental/src/generated/engine.dart';
+import 'package:analyzer_experimental/src/generated/java_engine_io.dart';
+import 'package:analyzer_experimental/src/generated/ast.dart' hide Annotation;
+import 'package:analyzer_experimental/src/generated/sdk.dart' show DartSdk;
+import 'package:unittest/unittest.dart' as _ut;
+import 'test_support.dart';
+import 'ast_test.dart' show ASTFactory;
+import 'element_test.dart' show ElementFactory;
+
+class LibraryTest extends EngineTestCase {
+  /**
+   * The error listener to which all errors will be reported.
+   */
+  GatheringErrorListener _errorListener;
+  /**
+   * The source factory used to create libraries.
+   */
+  SourceFactory _sourceFactory;
+  /**
+   * The analysis context to pass in to all libraries created by the tests.
+   */
+  AnalysisContextImpl _analysisContext;
+  /**
+   * The library used by the tests.
+   */
+  Library _library5;
+  void setUp() {
+    _sourceFactory = new SourceFactory.con2([new FileUriResolver()]);
+    _analysisContext = new AnalysisContextImpl();
+    _analysisContext.sourceFactory = _sourceFactory;
+    _errorListener = new GatheringErrorListener();
+    _library5 = library("/lib.dart");
+  }
+  void test_addExport() {
+    Library exportLibrary = library("/exported.dart");
+    _library5.addExport(ASTFactory.exportDirective2("exported.dart", []), exportLibrary);
+    List<Library> exports3 = _library5.exports;
+    EngineTestCase.assertLength(1, exports3);
+    JUnitTestCase.assertSame(exportLibrary, exports3[0]);
+    _errorListener.assertNoErrors();
+  }
+  void test_addImport() {
+    Library importLibrary = library("/imported.dart");
+    _library5.addImport(ASTFactory.importDirective2("imported.dart", null, []), importLibrary);
+    List<Library> imports3 = _library5.imports;
+    EngineTestCase.assertLength(1, imports3);
+    JUnitTestCase.assertSame(importLibrary, imports3[0]);
+    _errorListener.assertNoErrors();
+  }
+  void test_getExplicitlyImportsCore() {
+    JUnitTestCase.assertFalse(_library5.explicitlyImportsCore);
+    _errorListener.assertNoErrors();
+  }
+  void test_getExport() {
+    ExportDirective directive = ASTFactory.exportDirective2("exported.dart", []);
+    Library exportLibrary = library("/exported.dart");
+    _library5.addExport(directive, exportLibrary);
+    JUnitTestCase.assertSame(exportLibrary, _library5.getExport(directive));
+    _errorListener.assertNoErrors();
+  }
+  void test_getExports() {
+    EngineTestCase.assertLength(0, _library5.exports);
+    _errorListener.assertNoErrors();
+  }
+  void test_getImport() {
+    ImportDirective directive = ASTFactory.importDirective2("imported.dart", null, []);
+    Library importLibrary = library("/imported.dart");
+    _library5.addImport(directive, importLibrary);
+    JUnitTestCase.assertSame(importLibrary, _library5.getImport(directive));
+    _errorListener.assertNoErrors();
+  }
+  void test_getImports() {
+    EngineTestCase.assertLength(0, _library5.imports);
+    _errorListener.assertNoErrors();
+  }
+  void test_getImportsAndExports() {
+    _library5.addImport(ASTFactory.importDirective2("imported.dart", null, []), library("/imported.dart"));
+    _library5.addExport(ASTFactory.exportDirective2("exported.dart", []), library("/exported.dart"));
+    EngineTestCase.assertLength(2, _library5.importsAndExports);
+    _errorListener.assertNoErrors();
+  }
+  void test_getLibraryScope() {
+    LibraryElementImpl element = new LibraryElementImpl(_analysisContext, ASTFactory.libraryIdentifier2(["lib"]));
+    element.definingCompilationUnit = new CompilationUnitElementImpl("lib.dart");
+    _library5.libraryElement = element;
+    JUnitTestCase.assertNotNull(_library5.libraryScope);
+    _errorListener.assertNoErrors();
+  }
+  void test_getLibrarySource() {
+    JUnitTestCase.assertNotNull(_library5.librarySource);
+  }
+  void test_setExplicitlyImportsCore() {
+    _library5.explicitlyImportsCore = true;
+    JUnitTestCase.assertTrue(_library5.explicitlyImportsCore);
+    _errorListener.assertNoErrors();
+  }
+  void test_setLibraryElement() {
+    LibraryElementImpl element = new LibraryElementImpl(_analysisContext, ASTFactory.libraryIdentifier2(["lib"]));
+    _library5.libraryElement = element;
+    JUnitTestCase.assertSame(element, _library5.libraryElement);
+  }
+  Library library(String definingCompilationUnitPath) => new Library(_analysisContext, _errorListener, new FileBasedSource.con1(_sourceFactory, FileUtilities2.createFile(definingCompilationUnitPath)));
+  static dartSuite() {
+    _ut.group('LibraryTest', () {
+      _ut.test('test_addExport', () {
+        final __test = new LibraryTest();
+        runJUnitTest(__test, __test.test_addExport);
+      });
+      _ut.test('test_addImport', () {
+        final __test = new LibraryTest();
+        runJUnitTest(__test, __test.test_addImport);
+      });
+      _ut.test('test_getExplicitlyImportsCore', () {
+        final __test = new LibraryTest();
+        runJUnitTest(__test, __test.test_getExplicitlyImportsCore);
+      });
+      _ut.test('test_getExport', () {
+        final __test = new LibraryTest();
+        runJUnitTest(__test, __test.test_getExport);
+      });
+      _ut.test('test_getExports', () {
+        final __test = new LibraryTest();
+        runJUnitTest(__test, __test.test_getExports);
+      });
+      _ut.test('test_getImport', () {
+        final __test = new LibraryTest();
+        runJUnitTest(__test, __test.test_getImport);
+      });
+      _ut.test('test_getImports', () {
+        final __test = new LibraryTest();
+        runJUnitTest(__test, __test.test_getImports);
+      });
+      _ut.test('test_getImportsAndExports', () {
+        final __test = new LibraryTest();
+        runJUnitTest(__test, __test.test_getImportsAndExports);
+      });
+      _ut.test('test_getLibraryScope', () {
+        final __test = new LibraryTest();
+        runJUnitTest(__test, __test.test_getLibraryScope);
+      });
+      _ut.test('test_getLibrarySource', () {
+        final __test = new LibraryTest();
+        runJUnitTest(__test, __test.test_getLibrarySource);
+      });
+      _ut.test('test_setExplicitlyImportsCore', () {
+        final __test = new LibraryTest();
+        runJUnitTest(__test, __test.test_setExplicitlyImportsCore);
+      });
+      _ut.test('test_setLibraryElement', () {
+        final __test = new LibraryTest();
+        runJUnitTest(__test, __test.test_setLibraryElement);
+      });
+    });
+  }
+}
+class StaticTypeWarningCodeTest extends ResolverTestCase {
+  void fail_inaccessibleSetter() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.INACCESSIBLE_SETTER]);
+    verify([source]);
+  }
+  void fail_inconsistentMethodInheritance() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
+    verify([source]);
+  }
+  void fail_nonTypeAsTypeArgument() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["int A;", "class B<E> {}", "f(B<A> b) {}"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT]);
+    verify([source]);
+  }
+  void fail_redirectWithInvalidTypeParameters() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.REDIRECT_WITH_INVALID_TYPE_PARAMETERS]);
+    verify([source]);
+  }
+  void fail_typeArgumentViolatesBounds() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.TYPE_ARGUMENT_VIOLATES_BOUNDS]);
+    verify([source]);
+  }
+  void test_invalidAssignment_instanceVariable() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", " int x;", "}", "f() {", "  A a;", "  a.x = '0';", "}"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+    verify([source]);
+  }
+  void test_invalidAssignment_localVariable() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() {", "  int x;", "  x = '0';", "}"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+    verify([source]);
+  }
+  void test_invalidAssignment_staticVariable() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", " static int x;", "}", "f() {", "  A.x = '0';", "}"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+    verify([source]);
+  }
+  void test_invocationOfNonFunction_class() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", " void m() {", "  A();", " }", "}"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
+    verify([source]);
+  }
+  void test_invocationOfNonFunction_localVariable() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() {", " int x;", " return x();", "}"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
+    verify([source]);
+  }
+  void test_invocationOfNonFunction_ordinaryInvocation() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", " int x;", "}", "class B {", " m() {", "  A.x();", " }", "}"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
+  }
+  void test_invocationOfNonFunction_staticInvocation() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", " static int get g => 0;", " f() {", "  A.g();", " }", "}"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
+  }
+  void test_nonBoolCondition_conditional() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() { return 3 ? 2 : 1; }"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.NON_BOOL_CONDITION]);
+    verify([source]);
+  }
+  void test_nonBoolCondition_do() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() {", " do {} while (3);", "}"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.NON_BOOL_CONDITION]);
+    verify([source]);
+  }
+  void test_nonBoolCondition_if() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() {", " if (3) return 2; else return 1;", "}"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.NON_BOOL_CONDITION]);
+    verify([source]);
+  }
+  void test_nonBoolCondition_while() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() {", " while (3) {}", "}"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.NON_BOOL_CONDITION]);
+    verify([source]);
+  }
+  void test_nonBoolExpression() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() {", "  assert(0);", "}"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.NON_BOOL_EXPRESSION]);
+    verify([source]);
+  }
+  void test_returnOfInvalidType_function() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["int f() { return '0'; }"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+    verify([source]);
+  }
+  void test_returnOfInvalidType_localFunction() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  String m() {", "    int f() { return '0'; }", "  }", "}"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+    verify([source]);
+  }
+  void test_returnOfInvalidType_method() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  int f() { return '0'; }", "}"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+    verify([source]);
+  }
+  void test_typeArgumentNotMatchingBounds_const() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {}", "class B {}", "class G<E extends A> {", "  const G() {}", "}", "f() { return const G<B>(); }"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+    verify([source]);
+  }
+  void test_typeArgumentNotMatchingBounds_new() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {}", "class B {}", "class G<E extends A> {}", "f() { return new G<B>(); }"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+    verify([source]);
+  }
+  void test_undefinedGetter() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class T {}", "f(T e) { return e.m; }"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+  void test_undefinedGetter_static() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {}", "var a = A.B;"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+  void test_undefinedSetter() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class T {}", "f(T e1) { e1.m = 0; }"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.UNDEFINED_SETTER]);
+  }
+  void test_undefinedSetter_static() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {}", "f() { A.B = 0;}"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.UNDEFINED_SETTER]);
+  }
+  void test_undefinedSuperMethod() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {}", "class B extends A {", "  m() { return super.m(); }", "}"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.UNDEFINED_SUPER_METHOD]);
+    verify([source]);
+  }
+  void test_wrongNumberOfTypeArguments_tooFew() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A<E, F> {}", "A<A> a = null;"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+    verify([source]);
+  }
+  void test_wrongNumberOfTypeArguments_tooMany() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A<E> {}", "A<A, A> a = null;"]));
+    resolve(source, []);
+    assertErrors([StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+    verify([source]);
+  }
+  static dartSuite() {
+    _ut.group('StaticTypeWarningCodeTest', () {
+      _ut.test('test_invalidAssignment_instanceVariable', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_invalidAssignment_instanceVariable);
+      });
+      _ut.test('test_invalidAssignment_localVariable', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_invalidAssignment_localVariable);
+      });
+      _ut.test('test_invalidAssignment_staticVariable', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_invalidAssignment_staticVariable);
+      });
+      _ut.test('test_invocationOfNonFunction_class', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_invocationOfNonFunction_class);
+      });
+      _ut.test('test_invocationOfNonFunction_localVariable', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_invocationOfNonFunction_localVariable);
+      });
+      _ut.test('test_invocationOfNonFunction_ordinaryInvocation', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_invocationOfNonFunction_ordinaryInvocation);
+      });
+      _ut.test('test_invocationOfNonFunction_staticInvocation', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_invocationOfNonFunction_staticInvocation);
+      });
+      _ut.test('test_nonBoolCondition_conditional', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_nonBoolCondition_conditional);
+      });
+      _ut.test('test_nonBoolCondition_do', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_nonBoolCondition_do);
+      });
+      _ut.test('test_nonBoolCondition_if', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_nonBoolCondition_if);
+      });
+      _ut.test('test_nonBoolCondition_while', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_nonBoolCondition_while);
+      });
+      _ut.test('test_nonBoolExpression', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_nonBoolExpression);
+      });
+      _ut.test('test_returnOfInvalidType_function', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_returnOfInvalidType_function);
+      });
+      _ut.test('test_returnOfInvalidType_localFunction', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_returnOfInvalidType_localFunction);
+      });
+      _ut.test('test_returnOfInvalidType_method', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_returnOfInvalidType_method);
+      });
+      _ut.test('test_typeArgumentNotMatchingBounds_const', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_typeArgumentNotMatchingBounds_const);
+      });
+      _ut.test('test_typeArgumentNotMatchingBounds_new', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_typeArgumentNotMatchingBounds_new);
+      });
+      _ut.test('test_undefinedGetter', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_undefinedGetter);
+      });
+      _ut.test('test_undefinedGetter_static', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_undefinedGetter_static);
+      });
+      _ut.test('test_undefinedSetter', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_undefinedSetter);
+      });
+      _ut.test('test_undefinedSetter_static', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_undefinedSetter_static);
+      });
+      _ut.test('test_undefinedSuperMethod', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_undefinedSuperMethod);
+      });
+      _ut.test('test_wrongNumberOfTypeArguments_tooFew', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_wrongNumberOfTypeArguments_tooFew);
+      });
+      _ut.test('test_wrongNumberOfTypeArguments_tooMany', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_wrongNumberOfTypeArguments_tooMany);
+      });
+    });
+  }
+}
+class TypeResolverVisitorTest extends EngineTestCase {
+  /**
+   * The error listener to which errors will be reported.
+   */
+  GatheringErrorListener _listener;
+  /**
+   * The object representing the information about the library in which the types are being
+   * resolved.
+   */
+  Library _library;
+  /**
+   * The type provider used to access the types.
+   */
+  TestTypeProvider _typeProvider;
+  /**
+   * The visitor used to resolve types needed to form the type hierarchy.
+   */
+  TypeResolverVisitor _visitor;
+  void fail_visitConstructorDeclaration() {
+    JUnitTestCase.fail("Not yet tested");
+    _listener.assertNoErrors();
+  }
+  void fail_visitFieldFormalParameter_noType() {
+    FormalParameter node = ASTFactory.fieldFormalParameter(Keyword.VAR, null, "p");
+    JUnitTestCase.assertSame(_typeProvider.dynamicType, resolve5(node, []));
+    _listener.assertNoErrors();
+  }
+  void fail_visitFieldFormalParameter_type() {
+    FormalParameter node = ASTFactory.fieldFormalParameter(null, ASTFactory.typeName3("int", []), "p");
+    JUnitTestCase.assertSame(_typeProvider.intType, resolve5(node, []));
+    _listener.assertNoErrors();
+  }
+  void fail_visitFunctionDeclaration() {
+    JUnitTestCase.fail("Not yet tested");
+    _listener.assertNoErrors();
+  }
+  void fail_visitFunctionTypeAlias() {
+    JUnitTestCase.fail("Not yet tested");
+    _listener.assertNoErrors();
+  }
+  void fail_visitFunctionTypedFormalParameter() {
+    JUnitTestCase.fail("Not yet tested");
+    _listener.assertNoErrors();
+  }
+  void fail_visitMethodDeclaration() {
+    JUnitTestCase.fail("Not yet tested");
+    _listener.assertNoErrors();
+  }
+  void fail_visitVariableDeclaration() {
+    JUnitTestCase.fail("Not yet tested");
+    ClassElement type = ElementFactory.classElement2("A", []);
+    VariableDeclaration node = ASTFactory.variableDeclaration("a");
+    ASTFactory.variableDeclarationList(null, ASTFactory.typeName(type, []), [node]);
+    JUnitTestCase.assertSame(type.type, node.name.staticType);
+    _listener.assertNoErrors();
+  }
+  void setUp() {
+    _listener = new GatheringErrorListener();
+    SourceFactory factory = new SourceFactory.con2([new FileUriResolver()]);
+    AnalysisContextImpl context = new AnalysisContextImpl();
+    context.sourceFactory = factory;
+    Source librarySource = new FileBasedSource.con1(factory, FileUtilities2.createFile("/lib.dart"));
+    _library = new Library(context, _listener, librarySource);
+    LibraryElementImpl element = new LibraryElementImpl(context, ASTFactory.libraryIdentifier2(["lib"]));
+    element.definingCompilationUnit = new CompilationUnitElementImpl("lib.dart");
+    _library.libraryElement = element;
+    _typeProvider = new TestTypeProvider();
+    _visitor = new TypeResolverVisitor(_library, librarySource, _typeProvider);
+  }
+  void test_visitCatchClause_exception() {
+    CatchClause clause = ASTFactory.catchClause("e", []);
+    resolve(clause, _typeProvider.objectType, null, []);
+    _listener.assertNoErrors();
+  }
+  void test_visitCatchClause_exception_stackTrace() {
+    CatchClause clause = ASTFactory.catchClause2("e", "s", []);
+    resolve(clause, _typeProvider.objectType, _typeProvider.stackTraceType, []);
+    _listener.assertNoErrors();
+  }
+  void test_visitCatchClause_on_exception() {
+    ClassElement exceptionElement = ElementFactory.classElement2("E", []);
+    TypeName exceptionType = ASTFactory.typeName(exceptionElement, []);
+    CatchClause clause = ASTFactory.catchClause4(exceptionType, "e", []);
+    resolve(clause, exceptionElement.type, null, [exceptionElement]);
+    _listener.assertNoErrors();
+  }
+  void test_visitCatchClause_on_exception_stackTrace() {
+    ClassElement exceptionElement = ElementFactory.classElement2("E", []);
+    TypeName exceptionType = ASTFactory.typeName(exceptionElement, []);
+    ((exceptionType.name as SimpleIdentifier)).element = exceptionElement;
+    CatchClause clause = ASTFactory.catchClause5(exceptionType, "e", "s", []);
+    resolve(clause, exceptionElement.type, _typeProvider.stackTraceType, [exceptionElement]);
+    _listener.assertNoErrors();
+  }
+  void test_visitClassDeclaration() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementB = ElementFactory.classElement2("B", []);
+    ClassElement elementC = ElementFactory.classElement2("C", []);
+    ClassElement elementD = ElementFactory.classElement2("D", []);
+    ExtendsClause extendsClause2 = ASTFactory.extendsClause(ASTFactory.typeName(elementB, []));
+    WithClause withClause2 = ASTFactory.withClause([ASTFactory.typeName(elementC, [])]);
+    ImplementsClause implementsClause2 = ASTFactory.implementsClause([ASTFactory.typeName(elementD, [])]);
+    ClassDeclaration declaration = ASTFactory.classDeclaration(null, "A", null, extendsClause2, withClause2, implementsClause2, []);
+    declaration.name.element = elementA;
+    resolveNode(declaration, [elementA, elementB, elementC, elementD]);
+    JUnitTestCase.assertSame(elementB.type, elementA.supertype);
+    List<InterfaceType> mixins3 = elementA.mixins;
+    EngineTestCase.assertLength(1, mixins3);
+    JUnitTestCase.assertSame(elementC.type, mixins3[0]);
+    List<InterfaceType> interfaces3 = elementA.interfaces;
+    EngineTestCase.assertLength(1, interfaces3);
+    JUnitTestCase.assertSame(elementD.type, interfaces3[0]);
+    _listener.assertNoErrors();
+  }
+  void test_visitClassTypeAlias() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementB = ElementFactory.classElement2("B", []);
+    ClassElement elementC = ElementFactory.classElement2("C", []);
+    ClassElement elementD = ElementFactory.classElement2("D", []);
+    WithClause withClause3 = ASTFactory.withClause([ASTFactory.typeName(elementC, [])]);
+    ImplementsClause implementsClause3 = ASTFactory.implementsClause([ASTFactory.typeName(elementD, [])]);
+    ClassTypeAlias alias = ASTFactory.classTypeAlias("A", null, null, ASTFactory.typeName(elementB, []), withClause3, implementsClause3);
+    alias.name.element = elementA;
+    resolveNode(alias, [elementA, elementB, elementC, elementD]);
+    JUnitTestCase.assertSame(elementB.type, elementA.supertype);
+    List<InterfaceType> mixins4 = elementA.mixins;
+    EngineTestCase.assertLength(1, mixins4);
+    JUnitTestCase.assertSame(elementC.type, mixins4[0]);
+    List<InterfaceType> interfaces4 = elementA.interfaces;
+    EngineTestCase.assertLength(1, interfaces4);
+    JUnitTestCase.assertSame(elementD.type, interfaces4[0]);
+    _listener.assertNoErrors();
+  }
+  void test_visitSimpleFormalParameter_noType() {
+    FormalParameter node = ASTFactory.simpleFormalParameter3("p");
+    node.identifier.element = new ParameterElementImpl(ASTFactory.identifier2("p"));
+    JUnitTestCase.assertSame(_typeProvider.dynamicType, resolve5(node, []));
+    _listener.assertNoErrors();
+  }
+  void test_visitSimpleFormalParameter_type() {
+    InterfaceType intType8 = _typeProvider.intType;
+    ClassElement intElement = intType8.element;
+    FormalParameter node = ASTFactory.simpleFormalParameter4(ASTFactory.typeName(intElement, []), "p");
+    SimpleIdentifier identifier18 = node.identifier;
+    ParameterElementImpl element = new ParameterElementImpl(identifier18);
+    identifier18.element = element;
+    JUnitTestCase.assertSame(intType8, resolve5(node, [intElement]));
+    _listener.assertNoErrors();
+  }
+  void test_visitTypeName_noParameters_noArguments() {
+    ClassElement classA = ElementFactory.classElement2("A", []);
+    TypeName typeName5 = ASTFactory.typeName(classA, []);
+    typeName5.type = null;
+    resolveNode(typeName5, [classA]);
+    JUnitTestCase.assertSame(classA.type, typeName5.type);
+    _listener.assertNoErrors();
+  }
+  void test_visitTypeName_parameters_arguments() {
+    ClassElement classA = ElementFactory.classElement2("A", ["E"]);
+    ClassElement classB = ElementFactory.classElement2("B", []);
+    TypeName typeName6 = ASTFactory.typeName(classA, [ASTFactory.typeName(classB, [])]);
+    typeName6.type = null;
+    resolveNode(typeName6, [classA, classB]);
+    InterfaceType resultType = typeName6.type as InterfaceType;
+    JUnitTestCase.assertSame(classA, resultType.element);
+    List<Type2> resultArguments = resultType.typeArguments;
+    EngineTestCase.assertLength(1, resultArguments);
+    JUnitTestCase.assertSame(classB.type, resultArguments[0]);
+    _listener.assertNoErrors();
+  }
+  void test_visitTypeName_parameters_noArguments() {
+    ClassElement classA = ElementFactory.classElement2("A", ["E"]);
+    TypeName typeName7 = ASTFactory.typeName(classA, []);
+    typeName7.type = null;
+    resolveNode(typeName7, [classA]);
+    InterfaceType resultType = typeName7.type as InterfaceType;
+    JUnitTestCase.assertSame(classA, resultType.element);
+    List<Type2> resultArguments = resultType.typeArguments;
+    EngineTestCase.assertLength(1, resultArguments);
+    JUnitTestCase.assertSame(DynamicTypeImpl.instance, resultArguments[0]);
+    _listener.assertNoErrors();
+  }
+  /**
+   * Analyze the given catch clause and assert that the types of the parameters have been set to the
+   * given types. The types can be null if the catch clause does not have the corresponding
+   * parameter.
+   * @param node the catch clause to be analyzed
+   * @param exceptionType the expected type of the exception parameter
+   * @param stackTraceType the expected type of the stack trace parameter
+   * @param definedElements the elements that are to be defined in the scope in which the element is
+   * being resolved
+   */
+  void resolve(CatchClause node, InterfaceType exceptionType, InterfaceType stackTraceType, List<Element> definedElements) {
+    resolveNode(node, definedElements);
+    SimpleIdentifier exceptionParameter3 = node.exceptionParameter;
+    if (exceptionParameter3 != null) {
+      JUnitTestCase.assertSame(exceptionType, exceptionParameter3.staticType);
+    }
+    SimpleIdentifier stackTraceParameter3 = node.stackTraceParameter;
+    if (stackTraceParameter3 != null) {
+      JUnitTestCase.assertSame(stackTraceType, stackTraceParameter3.staticType);
+    }
+  }
+  /**
+   * Return the type associated with the given parameter after the static type analyzer has computed
+   * a type for it.
+   * @param node the parameter with which the type is associated
+   * @param definedElements the elements that are to be defined in the scope in which the element is
+   * being resolved
+   * @return the type associated with the parameter
+   */
+  Type2 resolve5(FormalParameter node, List<Element> definedElements) {
+    resolveNode(node, definedElements);
+    return ((node.identifier.element as ParameterElement)).type;
+  }
+  /**
+   * Return the element associated with the given identifier after the resolver has resolved the
+   * identifier.
+   * @param node the expression to be resolved
+   * @param definedElements the elements that are to be defined in the scope in which the element is
+   * being resolved
+   * @return the element to which the expression was resolved
+   */
+  void resolveNode(ASTNode node, List<Element> definedElements) {
+    for (Element element in definedElements) {
+      _library.libraryScope.define(element);
+    }
+    node.accept(_visitor);
+  }
+  static dartSuite() {
+    _ut.group('TypeResolverVisitorTest', () {
+      _ut.test('test_visitCatchClause_exception', () {
+        final __test = new TypeResolverVisitorTest();
+        runJUnitTest(__test, __test.test_visitCatchClause_exception);
+      });
+      _ut.test('test_visitCatchClause_exception_stackTrace', () {
+        final __test = new TypeResolverVisitorTest();
+        runJUnitTest(__test, __test.test_visitCatchClause_exception_stackTrace);
+      });
+      _ut.test('test_visitCatchClause_on_exception', () {
+        final __test = new TypeResolverVisitorTest();
+        runJUnitTest(__test, __test.test_visitCatchClause_on_exception);
+      });
+      _ut.test('test_visitCatchClause_on_exception_stackTrace', () {
+        final __test = new TypeResolverVisitorTest();
+        runJUnitTest(__test, __test.test_visitCatchClause_on_exception_stackTrace);
+      });
+      _ut.test('test_visitClassDeclaration', () {
+        final __test = new TypeResolverVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassDeclaration);
+      });
+      _ut.test('test_visitClassTypeAlias', () {
+        final __test = new TypeResolverVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassTypeAlias);
+      });
+      _ut.test('test_visitSimpleFormalParameter_noType', () {
+        final __test = new TypeResolverVisitorTest();
+        runJUnitTest(__test, __test.test_visitSimpleFormalParameter_noType);
+      });
+      _ut.test('test_visitSimpleFormalParameter_type', () {
+        final __test = new TypeResolverVisitorTest();
+        runJUnitTest(__test, __test.test_visitSimpleFormalParameter_type);
+      });
+      _ut.test('test_visitTypeName_noParameters_noArguments', () {
+        final __test = new TypeResolverVisitorTest();
+        runJUnitTest(__test, __test.test_visitTypeName_noParameters_noArguments);
+      });
+      _ut.test('test_visitTypeName_parameters_arguments', () {
+        final __test = new TypeResolverVisitorTest();
+        runJUnitTest(__test, __test.test_visitTypeName_parameters_arguments);
+      });
+      _ut.test('test_visitTypeName_parameters_noArguments', () {
+        final __test = new TypeResolverVisitorTest();
+        runJUnitTest(__test, __test.test_visitTypeName_parameters_noArguments);
+      });
+    });
+  }
+}
+class ResolverTestCase extends EngineTestCase {
+  /**
+   * The source factory used to create {@link Source sources}.
+   */
+  SourceFactory _sourceFactory;
+  /**
+   * The error listener used during resolution.
+   */
+  GatheringErrorListener _errorListener;
+  /**
+   * The analysis context used to parse the compilation units being resolved.
+   */
+  AnalysisContextImpl _analysisContext;
+  /**
+   * Assert that the number of errors that have been gathered matches the number of errors that are
+   * given and that they have the expected error codes. The order in which the errors were gathered
+   * is ignored.
+   * @param expectedErrorCodes the error codes of the errors that should have been gathered
+   * @throws AssertionFailedError if a different number of errors have been gathered than were
+   * expected
+   */
+  void assertErrors(List<ErrorCode> expectedErrorCodes) {
+    _errorListener.assertErrors2(expectedErrorCodes);
+  }
+  void setUp() {
+    _errorListener = new GatheringErrorListener();
+    _analysisContext = AnalysisContextFactory.contextWithCore();
+    _sourceFactory = _analysisContext.sourceFactory;
+  }
+  /**
+   * Add a source file to the content provider. The file path should be absolute.
+   * @param filePath the path of the file being added
+   * @param contents the contents to be returned by the content provider for the specified file
+   * @return the source object representing the added file
+   */
+  Source addSource(String filePath, String contents) {
+    Source source = new FileBasedSource.con1(_sourceFactory, FileUtilities2.createFile(filePath));
+    _sourceFactory.setContents(source, contents);
+    return source;
+  }
+  /**
+   * Assert that no errors have been gathered.
+   * @throws AssertionFailedError if any errors have been gathered
+   */
+  void assertNoErrors() {
+    _errorListener.assertNoErrors();
+  }
+  /**
+   * Create a library element that represents a library named {@code "test"} containing a single
+   * empty compilation unit.
+   * @return the library element that was created
+   */
+  LibraryElementImpl createTestLibrary() => createTestLibrary2(new AnalysisContextImpl(), "test", []);
+  /**
+   * Create a library element that represents a library with the given name containing a single
+   * empty compilation unit.
+   * @param libraryName the name of the library to be created
+   * @return the library element that was created
+   */
+  LibraryElementImpl createTestLibrary2(AnalysisContext context, String libraryName, List<String> typeNames) {
+    int count = typeNames.length;
+    List<CompilationUnitElementImpl> sourcedCompilationUnits = new List<CompilationUnitElementImpl>(count);
+    for (int i = 0; i < count; i++) {
+      String typeName = typeNames[i];
+      ClassElementImpl type = new ClassElementImpl(ASTFactory.identifier2(typeName));
+      String fileName = "${typeName}.dart";
+      CompilationUnitElementImpl compilationUnit = new CompilationUnitElementImpl(fileName);
+      compilationUnit.source = new FileBasedSource.con1(_sourceFactory, FileUtilities2.createFile(fileName));
+      compilationUnit.types = <ClassElement> [type];
+      sourcedCompilationUnits[i] = compilationUnit;
+    }
+    String fileName = "${libraryName}.dart";
+    CompilationUnitElementImpl compilationUnit = new CompilationUnitElementImpl(fileName);
+    compilationUnit.source = new FileBasedSource.con1(_sourceFactory, FileUtilities2.createFile(fileName));
+    LibraryElementImpl library = new LibraryElementImpl(context, ASTFactory.libraryIdentifier2([libraryName]));
+    library.definingCompilationUnit = compilationUnit;
+    library.parts = sourcedCompilationUnits;
+    return library;
+  }
+  AnalysisContext get analysisContext => _analysisContext;
+  GatheringErrorListener get errorListener => _errorListener;
+  SourceFactory get sourceFactory => _sourceFactory;
+  /**
+   * Given a library and all of its parts, resolve the contents of the library and the contents of
+   * the parts. This assumes that the sources for the library and its parts have already been added
+   * to the content provider using the method {@link #addSource(String,String)}.
+   * @param librarySource the source for the compilation unit that defines the library
+   * @param unitSources the sources for the compilation units that are part of the library
+   * @return the element representing the resolved library
+   * @throws AnalysisException if the analysis could not be performed
+   */
+  LibraryElement resolve(Source librarySource, List<Source> unitSources) {
+    LibraryResolver resolver = new LibraryResolver.con2(_analysisContext, _errorListener);
+    return resolver.resolveLibrary(librarySource, true);
+  }
+  /**
+   * Verify that all of the identifiers in the compilation units associated with the given sources
+   * have been resolved.
+   * @param resolvedElementMap a table mapping the AST nodes that have been resolved to the element
+   * to which they were resolved
+   * @param sources the sources identifying the compilation units to be verified
+   * @throws Exception if the contents of the compilation unit cannot be accessed
+   */
+  void verify(List<Source> sources) {
+    ResolutionVerifier verifier = new ResolutionVerifier();
+    for (Source source in sources) {
+      _analysisContext.parse3(source, _errorListener).accept(verifier);
+    }
+    verifier.assertResolved();
+  }
+  static dartSuite() {
+    _ut.group('ResolverTestCase', () {
+    });
+  }
+}
+class TypeProviderImplTest extends EngineTestCase {
+  void test_creation() {
+    InterfaceType objectType = classElement("Object", null, []).type;
+    InterfaceType boolType = classElement("bool", objectType, []).type;
+    InterfaceType numType = classElement("num", objectType, []).type;
+    InterfaceType doubleType = classElement("double", numType, []).type;
+    InterfaceType functionType = classElement("Function", objectType, []).type;
+    InterfaceType intType = classElement("int", numType, []).type;
+    InterfaceType listType = classElement("List", objectType, ["E"]).type;
+    InterfaceType mapType = classElement("Map", objectType, ["K", "V"]).type;
+    InterfaceType stackTraceType = classElement("StackTrace", objectType, []).type;
+    InterfaceType stringType = classElement("String", objectType, []).type;
+    InterfaceType typeType = classElement("Type", objectType, []).type;
+    CompilationUnitElementImpl unit = new CompilationUnitElementImpl("lib.dart");
+    unit.types = <ClassElement> [boolType.element, doubleType.element, functionType.element, intType.element, listType.element, mapType.element, objectType.element, stackTraceType.element, stringType.element, typeType.element];
+    LibraryElementImpl library = new LibraryElementImpl(new AnalysisContextImpl(), ASTFactory.libraryIdentifier2(["lib"]));
+    library.definingCompilationUnit = unit;
+    TypeProviderImpl provider = new TypeProviderImpl(library);
+    JUnitTestCase.assertSame(boolType, provider.boolType);
+    JUnitTestCase.assertNotNull(provider.bottomType);
+    JUnitTestCase.assertSame(doubleType, provider.doubleType);
+    JUnitTestCase.assertNotNull(provider.dynamicType);
+    JUnitTestCase.assertSame(functionType, provider.functionType);
+    JUnitTestCase.assertSame(intType, provider.intType);
+    JUnitTestCase.assertSame(listType, provider.listType);
+    JUnitTestCase.assertSame(mapType, provider.mapType);
+    JUnitTestCase.assertSame(objectType, provider.objectType);
+    JUnitTestCase.assertSame(stackTraceType, provider.stackTraceType);
+    JUnitTestCase.assertSame(stringType, provider.stringType);
+    JUnitTestCase.assertSame(typeType, provider.typeType);
+  }
+  ClassElement classElement(String typeName, InterfaceType superclassType, List<String> parameterNames) {
+    ClassElementImpl element = new ClassElementImpl(ASTFactory.identifier2(typeName));
+    element.supertype = superclassType;
+    InterfaceTypeImpl type = new InterfaceTypeImpl.con1(element);
+    element.type = type;
+    int count = parameterNames.length;
+    if (count > 0) {
+      List<TypeVariableElementImpl> typeVariables = new List<TypeVariableElementImpl>(count);
+      List<TypeVariableTypeImpl> typeArguments = new List<TypeVariableTypeImpl>(count);
+      for (int i = 0; i < count; i++) {
+        TypeVariableElementImpl variable = new TypeVariableElementImpl(ASTFactory.identifier2(parameterNames[i]));
+        typeVariables[i] = variable;
+        typeArguments[i] = new TypeVariableTypeImpl(variable);
+        variable.type = typeArguments[i];
+      }
+      element.typeVariables = typeVariables;
+      type.typeArguments = typeArguments;
+    }
+    return element;
+  }
+  static dartSuite() {
+    _ut.group('TypeProviderImplTest', () {
+      _ut.test('test_creation', () {
+        final __test = new TypeProviderImplTest();
+        runJUnitTest(__test, __test.test_creation);
+      });
+    });
+  }
+}
+class CompileTimeErrorCodeTest extends ResolverTestCase {
+  void fail_ambiguousExport() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["library L;", "export 'lib1.dart';", "export 'lib2.dart';"]));
+    addSource("/lib1.dart", EngineTestCase.createSource(["class N {}"]));
+    addSource("/lib2.dart", EngineTestCase.createSource(["class N {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.AMBIGUOUS_EXPORT]);
+    verify([source]);
+  }
+  void fail_ambiguousImport_function() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["library L;", "import 'lib1.dart';", "import 'lib2.dart';", "g() { return f(); }"]));
+    addSource("/lib1.dart", EngineTestCase.createSource(["f() {}"]));
+    addSource("/lib2.dart", EngineTestCase.createSource(["f() {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.AMBIGUOUS_IMPORT]);
+    verify([source]);
+  }
+  void fail_ambiguousImport_typeAnnotation() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["library L;", "import 'lib1.dart';", "import 'lib2.dart';", "class A extends N {}"]));
+    addSource("/lib1.dart", EngineTestCase.createSource(["class N {}"]));
+    addSource("/lib2.dart", EngineTestCase.createSource(["class N {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.AMBIGUOUS_IMPORT]);
+    verify([source]);
+  }
+  void fail_compileTimeConstantRaisesException() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.COMPILE_TIME_CONSTANT_RAISES_EXCEPTION]);
+    verify([source]);
+  }
+  void fail_constEvalThrowsException() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class C {", "  const C() { throw null; }", "}", "f() { return const C(); }"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
+    verify([source]);
+  }
+  void fail_constWithNonConstantArgument() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class T {", "  T(a) {};", "}", "f(p) { return const T(p); }"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT]);
+    verify([source]);
+  }
+  void fail_constWithNonType() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["int A;", "f() {", "  return const A();", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.CONST_WITH_NON_TYPE]);
+    verify([source]);
+  }
+  void fail_constWithTypeParameters() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS]);
+    verify([source]);
+  }
+  void fail_constWithUndefinedConstructor() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  A(x) {}", "}", "f() {", "  return const A(0);", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR]);
+    verify([source]);
+  }
+  void fail_defaultValueInFunctionTypeAlias() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["typedef F([x = 0]);"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS]);
+    verify([source]);
+  }
+  void fail_duplicateDefinition() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() {", "  int m = 0;", "  m(a) {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    verify([source]);
+  }
+  void fail_duplicateMemberName() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  int x = 0;", "  int x() {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.DUPLICATE_MEMBER_NAME]);
+    verify([source]);
+  }
+  void fail_duplicateMemberNameInstanceStatic() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  int x;", "  static int x;", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.DUPLICATE_MEMBER_NAME_INSTANCE_STATIC]);
+    verify([source]);
+  }
+  void fail_duplicateNamedArgument() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f({a, a}) {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT]);
+    verify([source]);
+  }
+  void fail_exportOfNonLibrary() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["library L;", "export 'lib1.dart';"]));
+    addSource("/lib1.dart", EngineTestCase.createSource(["part of lib;"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY]);
+    verify([source]);
+  }
+  void fail_extendsOrImplementsDisallowedClass_extends_bool() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A extends bool {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.EXTENDS_OR_IMPLEMENTS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+  void fail_extendsOrImplementsDisallowedClass_extends_double() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A extends double {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.EXTENDS_OR_IMPLEMENTS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+  void fail_extendsOrImplementsDisallowedClass_extends_int() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A extends int {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.EXTENDS_OR_IMPLEMENTS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+  void fail_extendsOrImplementsDisallowedClass_extends_null() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A extends Null {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.EXTENDS_OR_IMPLEMENTS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+  void fail_extendsOrImplementsDisallowedClass_extends_num() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A extends num {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.EXTENDS_OR_IMPLEMENTS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+  void fail_extendsOrImplementsDisallowedClass_extends_String() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A extends String {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.EXTENDS_OR_IMPLEMENTS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+  void fail_extendsOrImplementsDisallowedClass_implements_bool() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A implements bool {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.EXTENDS_OR_IMPLEMENTS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+  void fail_extendsOrImplementsDisallowedClass_implements_double() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A implements double {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.EXTENDS_OR_IMPLEMENTS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+  void fail_extendsOrImplementsDisallowedClass_implements_int() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A implements int {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.EXTENDS_OR_IMPLEMENTS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+  void fail_extendsOrImplementsDisallowedClass_implements_null() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A implements Null {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.EXTENDS_OR_IMPLEMENTS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+  void fail_extendsOrImplementsDisallowedClass_implements_num() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A implements num {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.EXTENDS_OR_IMPLEMENTS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+  void fail_extendsOrImplementsDisallowedClass_implements_String() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A implements String {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.EXTENDS_OR_IMPLEMENTS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+  void fail_fieldInitializedByMultipleInitializers() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  int x;", "  A() : x = 0, x = 1 {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS]);
+    verify([source]);
+  }
+  void fail_fieldInitializedInInitializerAndDeclaration() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  final int x = 0;", "  A() : x = 1 {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION]);
+    verify([source]);
+  }
+  void fail_fieldInitializeInParameterAndInitializer() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  int x;", "  A(this.x) : x = 1 {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER]);
+    verify([source]);
+  }
+  void fail_fieldInitializerOutsideConstructor() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  int x;", "  m(this.x) {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]);
+    verify([source]);
+  }
+  void fail_finalInitializedInDeclarationAndConstructor_assignment() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  final x = 0;", "  A() { x = 1; }", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR]);
+    verify([source]);
+  }
+  void fail_finalInitializedInDeclarationAndConstructor_initializingFormal() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  final x = 0;", "  A(this.x) {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR]);
+    verify([source]);
+  }
+  void fail_finalInitializedMultipleTimes() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  final x;", "  A(this.x) { x = 0; }", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES]);
+    verify([source]);
+  }
+  void fail_finalNotInitialized_library() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["final F;"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.FINAL_NOT_INITIALIZED]);
+    verify([source]);
+  }
+  void fail_finalNotInitialized_local() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() {", "  final int x;", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.FINAL_NOT_INITIALIZED]);
+    verify([source]);
+  }
+  void fail_finalNotInitialized_static() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  static final F;", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.FINAL_NOT_INITIALIZED]);
+    verify([source]);
+  }
+  void fail_getterAndMethodWithSameName() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  get x -> 0;", "  x(y) {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.GETTER_AND_METHOD_WITH_SAME_NAME]);
+    verify([source]);
+  }
+  void fail_implementsDynamic() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A implements dynamic {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.IMPLEMENTS_DYNAMIC]);
+    verify([source]);
+  }
+  void fail_implementsRepeated() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {}", "class B implements A, A {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.IMPLEMENTS_REPEATED]);
+    verify([source]);
+  }
+  void fail_implementsSelf() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A implements A {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.IMPLEMENTS_SELF]);
+    verify([source]);
+  }
+  void fail_importDuplicatedLibraryName() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["library test;", "import 'lib1.dart';", "import 'lib2.dart';"]));
+    addSource("/lib1.dart", EngineTestCase.createSource(["library lib;"]));
+    addSource("/lib2.dart", EngineTestCase.createSource(["library lib;"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.IMPORT_DUPLICATED_LIBRARY_NAME]);
+    verify([source]);
+  }
+  void fail_importOfNonLibrary() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["library lib;", "import 'part.dart';"]));
+    addSource("/part.dart", EngineTestCase.createSource(["part of lib;"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY]);
+    verify([source]);
+  }
+  void fail_inconsistentCaseExpressionTypes() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f(var p) {", "  switch (p) {", "    case 3:", "      break;", "    case 'a':", "      break;", "  }", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.INCONSITENT_CASE_EXPRESSION_TYPES]);
+    verify([source]);
+  }
+  void fail_initializerForNonExistantField() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  A(this.x) {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTANT_FIELD]);
+    verify([source]);
+  }
+  void fail_invalidConstructorName() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME]);
+    verify([source]);
+  }
+  void fail_invalidFactoryNameNotAClass() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS]);
+    verify([source]);
+  }
+  void fail_invalidOverrideDefaultValue() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  m([a = 0]) {}", "}", "class B extends A {", "  m([a = 1]) {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.INVALID_OVERRIDE_DEFAULT_VALUE]);
+    verify([source]);
+  }
+  void fail_invalidOverrideNamed() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  m({a, b}) {}", "}", "class B extends A {", "  m({a}) {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.INVALID_OVERRIDE_NAMED]);
+    verify([source]);
+  }
+  void fail_invalidOverridePositional() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  m([a, b]) {}", "}", "class B extends A {", "  m([a]) {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.INVALID_OVERRIDE_POSITIONAL]);
+    verify([source]);
+  }
+  void fail_invalidOverrideRequired() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  m(a) {}", "}", "class B extends A {", "  m(a, b) {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.INVALID_OVERRIDE_REQUIRED]);
+    verify([source]);
+  }
+  void fail_invalidReferenceToThis_staticMethod() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  static m() { return this; }", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
+    verify([source]);
+  }
+  void fail_invalidReferenceToThis_topLevelFunction() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() { return this; }"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
+    verify([source]);
+  }
+  void fail_invalidReferenceToThis_variableInitializer() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["int x = this;"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
+    verify([source]);
+  }
+  void fail_invalidTypeArgumentForKey() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  m() {", "    return const <int, int>{}", "  }", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_FOR_KEY]);
+    verify([source]);
+  }
+  void fail_invalidTypeArgumentInConstList() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A<E> {", "  m() {", "    return const <E>[]", "  }", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST]);
+    verify([source]);
+  }
+  void fail_invalidTypeArgumentInConstMap() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A<E> {", "  m() {", "    return const <String, E>{}", "  }", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP]);
+    verify([source]);
+  }
+  void fail_invalidVariableInInitializer_nonField() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  A(this.x) {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.INVALID_VARIABLE_IN_INITIALIZER]);
+    verify([source]);
+  }
+  void fail_invalidVariableInInitializer_static() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  static x = 0;", "  A(this.x) {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.INVALID_VARIABLE_IN_INITIALIZER]);
+    verify([source]);
+  }
+  void fail_memberWithClassName() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  int A = 0;", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
+    verify([source]);
+  }
+  void fail_mixinDeclaresConstructor() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  A() {}", "}", "class B extends Object mixin A {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]);
+    verify([source]);
+  }
+  void fail_mixinInheritsFromNotObject() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {}", "class B extends A {}", "class C extends Object mixin B {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
+    verify([source]);
+  }
+  void fail_mixinOfNonClass() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["var A;", "class B extends Object mixin A {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.MIXIN_OF_NON_CLASS]);
+    verify([source]);
+  }
+  void fail_mixinOfNonMixin() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.MIXIN_OF_NON_MIXIN]);
+    verify([source]);
+  }
+  void fail_mixinReferencesSuper() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  toString() -> super.toString();", "}", "class B extends Object mixin A {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]);
+    verify([source]);
+  }
+  void fail_mixinWithNonClassSuperclass() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["int A;", "class B extends Object mixin A {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS]);
+    verify([source]);
+  }
+  void fail_multipleSuperInitializers() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {}", "class B extends A {", "  B() : super(), super() {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS]);
+    verify([source]);
+  }
+  void fail_nonConstantDefaultValue_named() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f({x : 2 + 3}) {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
+    verify([source]);
+  }
+  void fail_nonConstantDefaultValue_positional() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f([x = 2 + 3]) {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
+    verify([source]);
+  }
+  void fail_nonConstMapAsExpressionStatement() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() {", "  {'a' : 0, 'b' : 1};", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT]);
+    verify([source]);
+  }
+  void fail_nonConstMapKey() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f(a) {", "  return const {a : 0};", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]);
+    verify([source]);
+  }
+  void fail_nonConstValueInInitializer() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  static C;", "  int a;", "  A() : a = C {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER]);
+    verify([source]);
+  }
+  void fail_objectCannotExtendAnotherClass() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.OBJECT_CANNOT_EXTEND_ANOTHER_CLASS]);
+    verify([source]);
+  }
+  void fail_optionalParameterInOperator() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  operator +([p]) {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR]);
+    verify([source]);
+  }
+  void fail_overrideMissingNamedParameters() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  m(a, {b}) {}", "}", "class B extends A {", "  m(a) {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.OVERRIDE_MISSING_NAMED_PARAMETERS]);
+    verify([source]);
+  }
+  void fail_overrideMissingRequiredParameters() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  m(a) {}", "}", "class B extends A {", "  m(a, b) {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.OVERRIDE_MISSING_REQUIRED_PARAMETERS]);
+    verify([source]);
+  }
+  void fail_partOfNonPart() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["library l1;", "part 'l2.dart';"]));
+    addSource("/l2.dart", EngineTestCase.createSource(["library l2;"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.PART_OF_NON_PART]);
+    verify([source]);
+  }
+  void fail_prefixCollidesWithTopLevelMembers() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["import 'dart:uri' as uri;", "var uri = null;"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER]);
+    verify([source]);
+  }
+  void fail_privateOptionalParameter() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f({_p : 0}) {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER]);
+    verify([source]);
+  }
+  void fail_recursiveCompileTimeConstant() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["const x = y + 1;", "const y = x + 1;"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT]);
+    verify([source]);
+  }
+  void fail_recursiveFactoryRedirect() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT]);
+    verify([source]);
+  }
+  void fail_recursiveFunctionTypeAlias_direct() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["typedef F(F f);"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.RECURSIVE_FUNCTION_TYPE_ALIAS]);
+    verify([source]);
+  }
+  void fail_recursiveFunctionTypeAlias_indirect() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["typedef F(G g);", "typedef G(F f);"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.RECURSIVE_FUNCTION_TYPE_ALIAS]);
+    verify([source]);
+  }
+  void fail_recursiveInterfaceInheritance_direct() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A implements A {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE]);
+    verify([source]);
+  }
+  void fail_recursiveInterfaceInheritance_indirect() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A implements B {}", "class B implements A {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE]);
+    verify([source]);
+  }
+  void fail_redirectToNonConstConstructor() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR]);
+    verify([source]);
+  }
+  void fail_referenceToDeclaredVariableInInitializer_getter() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() {", "  int x = x + 1;", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER]);
+    verify([source]);
+  }
+  void fail_referenceToDeclaredVariableInInitializer_setter() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() {", "  int x = x++;", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER]);
+    verify([source]);
+  }
+  void fail_reservedWordAsIdentifier() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["int class = 2;"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.RESERVED_WORD_AS_IDENTIFIER]);
+    verify([source]);
+  }
+  void fail_returnInGenerativeConstructor() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  A() { return 0; }", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR]);
+    verify([source]);
+  }
+  void fail_staticTopLevelFunction_topLevel() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["static f() {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.STATIC_TOP_LEVEL_FUNCTION]);
+    verify([source]);
+  }
+  void fail_staticTopLevelVariable() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["static int x;"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.STATIC_TOP_LEVEL_VARIABLE]);
+    verify([source]);
+  }
+  void fail_superInInvalidContext_factoryConstructor() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+    verify([source]);
+  }
+  void fail_superInInvalidContext_instanceVariableInitializer() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  var a;", "}", "class B extends A {", " var b = super.a;", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+    verify([source]);
+  }
+  void fail_superInInvalidContext_staticMethod() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  static m() {}", "}", "class B extends A {", "  static n() { return super.m(); }", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+    verify([source]);
+  }
+  void fail_superInInvalidContext_staticVariableInitializer() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  static a = 0;", "}", "class B extends A {", "  static b = super.a;", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+    verify([source]);
+  }
+  void fail_superInInvalidContext_topLevelFunction() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() {", "  super.f();", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+    verify([source]);
+  }
+  void fail_superInInvalidContext_variableInitializer() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["var v = super.v;"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+    verify([source]);
+  }
+  void fail_superInitializerInObject() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.SUPER_INITIALIZER_IN_OBJECT]);
+    verify([source]);
+  }
+  void fail_throwWithoutValueOutsideOn() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() {", "  throw;", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.THROW_WITHOUT_VALUE_OUTSIDE_ON]);
+    verify([source]);
+  }
+  void fail_typeArgumentsForNonGenericClass_creation_const() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {}", "f(p) {", "  return const A<int>();", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.TYPE_ARGUMENTS_FOR_NON_GENERIC_CLASS]);
+    verify([source]);
+  }
+  void fail_typeArgumentsForNonGenericClass_creation_new() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {}", "f(p) {", "  return new A<int>();", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.TYPE_ARGUMENTS_FOR_NON_GENERIC_CLASS]);
+    verify([source]);
+  }
+  void fail_typeArgumentsForNonGenericClass_typeCast() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {}", "f(p) {", "  return p as A<int>;", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.TYPE_ARGUMENTS_FOR_NON_GENERIC_CLASS]);
+    verify([source]);
+  }
+  void fail_undefinedConstructorInInitializer() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER]);
+    verify([source]);
+  }
+  void fail_uninitializedFinalField() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  final int i;", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.UNINITIALIZED_FINAL_FIELD]);
+    verify([source]);
+  }
+  void fail_wrongNumberOfParametersForOperator() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  operator []=(i) {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR]);
+    verify([source]);
+  }
+  void fail_wrongNumberOfParametersForSetter_tooFew() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["set x() {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
+    verify([source]);
+  }
+  void fail_wrongNumberOfParametersForSetter_tooMany() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["set x(a, b) {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
+    verify([source]);
+  }
+  void fail_wrongNumberOfTypeArguments_creation_const_tooFew() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {}", "class C<K, V> {}", "f(p) {", "  return const C<A>();", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+    verify([source]);
+  }
+  void fail_wrongNumberOfTypeArguments_creation_const_tooMany() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {}", "class C<E> {}", "f(p) {", "  return const C<A, A>();", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+    verify([source]);
+  }
+  void fail_wrongNumberOfTypeArguments_creation_new_tooFew() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {}", "class C<K, V> {}", "f(p) {", "  return new C<A>();", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+    verify([source]);
+  }
+  void fail_wrongNumberOfTypeArguments_creation_new_tooMany() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {}", "class C<E> {}", "f(p) {", "  return new C<A, A>();", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+    verify([source]);
+  }
+  void fail_wrongNumberOfTypeArguments_typeTest_tooFew() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {}", "class C<K, V> {}", "f(p) {", "  return p is C<A>;", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+    verify([source]);
+  }
+  void fail_wrongNumberOfTypeArguments_typeTest_tooMany() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {}", "class C<E> {}", "f(p) {", "  return p is C<A, A>;", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+    verify([source]);
+  }
+  void test_argumentDefinitionTestNonParameter() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() {", " var v = 0;", " return ?v;", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.ARGUMENT_DEFINITION_TEST_NON_PARAMETER]);
+    verify([source]);
+  }
+  void test_builtInIdentifierAsType() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() {", "  typedef x;", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE]);
+    verify([source]);
+  }
+  void test_builtInIdentifierAsTypedefName_classTypeAlias() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {}", "class B {}", "typedef as = A with B;"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME]);
+    verify([source]);
+  }
+  void test_builtInIdentifierAsTypedefName_functionTypeAlias() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["typedef bool as();"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME]);
+    verify([source]);
+  }
+  void test_builtInIdentifierAsTypeName() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class as {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME]);
+    verify([source]);
+  }
+  void test_builtInIdentifierAsTypeVariableName() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A<as> {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME]);
+    verify([source]);
+  }
+  void test_caseExpressionTypeImplementsEquals() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class IntWrapper {", "  final int value;", "  const IntWrapper(this.value);", "  bool operator ==(IntWrapper x) {", "    return value == x.value;", "  }", "}", "", "f(IntWrapper a) {", "  switch(a) {", "    case(const IntWrapper(1)) : return 1;", "    default: return 0;", "  }", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS]);
+    verify([source]);
+  }
+  void test_compileTimeConstantRaisesExceptionDivideByZero() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["const int INF = 0 / 0;"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.COMPILE_TIME_CONSTANT_RAISES_EXCEPTION_DIVIDE_BY_ZERO]);
+    verify([source]);
+  }
+  void test_conflictingConstructorNameAndMember_field() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  int x;", "  A.x() {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD]);
+    verify([source]);
+  }
+  void test_conflictingConstructorNameAndMember_method() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  const A.x() {}", "  void x() {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD]);
+    verify([source]);
+  }
+  void test_constConstructorWithNonFinalField() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  int x;", "  const A() {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD]);
+    verify([source]);
+  }
+  void test_constFormalParameter_fieldFormalParameter() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  var x;", "  A(const this.x) {}", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.CONST_FORMAL_PARAMETER]);
+    verify([source]);
+  }
+  void test_constFormalParameter_simpleFormalParameter() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f(const x) {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.CONST_FORMAL_PARAMETER]);
+    verify([source]);
+  }
+  void test_constInitializedWithNonConstValue() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f(p) {", "  const C = p;", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE]);
+    verify([source]);
+  }
+  void test_constWithInvalidTypeParameters() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  const A() {}", "}", "f() { return const A<A>(); }"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS]);
+    verify([source]);
+  }
+  void test_constWithNonConst() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class T {", "  T(a, b, {c, d}) {}", "}", "f() { return const T(0, 1, c: 2, d: 3); }"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.CONST_WITH_NON_CONST]);
+    verify([source]);
+  }
+  void test_duplicateMemberError() {
+    Source librarySource = addSource("/lib.dart", EngineTestCase.createSource(["library lib;", "", "part 'a.dart';", "part 'b.dart';"]));
+    Source sourceA = addSource("/a.dart", EngineTestCase.createSource(["part of lib;", "", "class A {}"]));
+    Source sourceB = addSource("/b.dart", EngineTestCase.createSource(["part of lib;", "", "class A {}"]));
+    resolve(librarySource, [sourceA, sourceB]);
+    assertErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    verify([librarySource, sourceA, sourceB]);
+  }
+  void test_extendsNonClass() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["int A;", "class B extends A {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.EXTENDS_NON_CLASS]);
+    verify([source]);
+  }
+  void test_implementsNonClass() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["int A;", "class B implements A {}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.IMPLEMENTS_NON_CLASS]);
+    verify([source]);
+  }
+  void test_labelInOuterScope() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class int {}", "", "class A {", "  void m(int i) {", "    l: while (i > 0) {", "      void f() {", "        break l;", "      };", "    }", "  }", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE, ResolverErrorCode.CANNOT_BE_RESOLVED]);
+  }
+  void test_labelUndefined_break() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() {", "  x: while (true) {", "    break y;", "  }", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.LABEL_UNDEFINED]);
+  }
+  void test_labelUndefined_continue() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() {", "  x: while (true) {", "    continue y;", "  }", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.LABEL_UNDEFINED]);
+  }
+  void test_newWithInvalidTypeParameters() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {}", "f() { return new A<A>(); }"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.NEW_WITH_INVALID_TYPE_PARAMETERS]);
+    verify([source]);
+  }
+  void test_nonConstCaseExpression() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f(int p, int q) {", "  switch (p) {", "    case 3 + q:", "      break;", "  }", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION]);
+    verify([source]);
+  }
+  void test_nonConstListElement() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f(a) {", "  return const [a];", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
+    verify([source]);
+  }
+  void test_nonConstMapValue() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f(a) {", "  return const {'a' : a};", "}"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]);
+    verify([source]);
+  }
+  void test_uriWithInterpolation_constant() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["import 'stuff_\$platform.dart';"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.URI_WITH_INTERPOLATION]);
+  }
+  void test_uriWithInterpolation_nonConstant() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["library lib;", "part '\${'a'}.dart';"]));
+    resolve(source, []);
+    assertErrors([CompileTimeErrorCode.URI_WITH_INTERPOLATION]);
+  }
+  static dartSuite() {
+    _ut.group('CompileTimeErrorCodeTest', () {
+      _ut.test('test_argumentDefinitionTestNonParameter', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_argumentDefinitionTestNonParameter);
+      });
+      _ut.test('test_builtInIdentifierAsType', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_builtInIdentifierAsType);
+      });
+      _ut.test('test_builtInIdentifierAsTypeName', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_builtInIdentifierAsTypeName);
+      });
+      _ut.test('test_builtInIdentifierAsTypeVariableName', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_builtInIdentifierAsTypeVariableName);
+      });
+      _ut.test('test_builtInIdentifierAsTypedefName_classTypeAlias', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_builtInIdentifierAsTypedefName_classTypeAlias);
+      });
+      _ut.test('test_builtInIdentifierAsTypedefName_functionTypeAlias', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_builtInIdentifierAsTypedefName_functionTypeAlias);
+      });
+      _ut.test('test_caseExpressionTypeImplementsEquals', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_caseExpressionTypeImplementsEquals);
+      });
+      _ut.test('test_compileTimeConstantRaisesExceptionDivideByZero', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_compileTimeConstantRaisesExceptionDivideByZero);
+      });
+      _ut.test('test_conflictingConstructorNameAndMember_field', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_conflictingConstructorNameAndMember_field);
+      });
+      _ut.test('test_conflictingConstructorNameAndMember_method', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_conflictingConstructorNameAndMember_method);
+      });
+      _ut.test('test_constConstructorWithNonFinalField', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_constConstructorWithNonFinalField);
+      });
+      _ut.test('test_constFormalParameter_fieldFormalParameter', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_constFormalParameter_fieldFormalParameter);
+      });
+      _ut.test('test_constFormalParameter_simpleFormalParameter', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_constFormalParameter_simpleFormalParameter);
+      });
+      _ut.test('test_constInitializedWithNonConstValue', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_constInitializedWithNonConstValue);
+      });
+      _ut.test('test_constWithInvalidTypeParameters', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_constWithInvalidTypeParameters);
+      });
+      _ut.test('test_constWithNonConst', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_constWithNonConst);
+      });
+      _ut.test('test_duplicateMemberError', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_duplicateMemberError);
+      });
+      _ut.test('test_extendsNonClass', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_extendsNonClass);
+      });
+      _ut.test('test_implementsNonClass', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_implementsNonClass);
+      });
+      _ut.test('test_labelInOuterScope', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_labelInOuterScope);
+      });
+      _ut.test('test_labelUndefined_break', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_labelUndefined_break);
+      });
+      _ut.test('test_labelUndefined_continue', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_labelUndefined_continue);
+      });
+      _ut.test('test_newWithInvalidTypeParameters', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_newWithInvalidTypeParameters);
+      });
+      _ut.test('test_nonConstCaseExpression', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_nonConstCaseExpression);
+      });
+      _ut.test('test_nonConstListElement', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_nonConstListElement);
+      });
+      _ut.test('test_nonConstMapValue', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_nonConstMapValue);
+      });
+      _ut.test('test_uriWithInterpolation_constant', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_uriWithInterpolation_constant);
+      });
+      _ut.test('test_uriWithInterpolation_nonConstant', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_uriWithInterpolation_nonConstant);
+      });
+    });
+  }
+}
+/**
+ * Instances of the class {@code StaticTypeVerifier} verify that all of the nodes in an AST
+ * structure that should have a static type associated with them do have a static type.
+ */
+class StaticTypeVerifier extends GeneralizingASTVisitor<Object> {
+  /**
+   * A list containing all of the AST Expression nodes that were not resolved.
+   */
+  List<Expression> _unresolvedExpressions = new List<Expression>();
+  /**
+   * A list containing all of the AST TypeName nodes that were not resolved.
+   */
+  List<TypeName> _unresolvedTypes = new List<TypeName>();
+  /**
+   * Counter for the number of Expression nodes visited that are resolved.
+   */
+  int _resolvedExpressionCount = 0;
+  /**
+   * Counter for the number of TypeName nodes visited that are resolved.
+   */
+  int _resolvedTypeCount = 0;
+  /**
+   * Initialize a newly created verifier to verify that all of the nodes in an AST structure that
+   * should have a static type associated with them do have a static type.
+   */
+  StaticTypeVerifier() : super() {
+  }
+  /**
+   * Assert that all of the visited nodes have a static type associated with them.
+   */
+  void assertResolved() {
+    if (!_unresolvedExpressions.isEmpty || !_unresolvedTypes.isEmpty) {
+      int unresolvedExpressionCount = _unresolvedExpressions.length;
+      int unresolvedTypeCount = _unresolvedTypes.length;
+      PrintStringWriter writer = new PrintStringWriter();
+      writer.print("Failed to associate types with nodes: ");
+      writer.print(unresolvedExpressionCount);
+      writer.print("/");
+      writer.print(_resolvedExpressionCount + unresolvedExpressionCount);
+      writer.print(" Expressions and ");
+      writer.print(unresolvedTypeCount);
+      writer.print("/");
+      writer.print(_resolvedTypeCount + unresolvedTypeCount);
+      writer.printlnObject(" TypeNames.");
+      if (unresolvedTypeCount > 0) {
+        writer.printlnObject("TypeNames:");
+        for (TypeName identifier in _unresolvedTypes) {
+          writer.print("  ");
+          writer.print(identifier.toString());
+          writer.print(" (");
+          writer.print(getFileName(identifier));
+          writer.print(" : ");
+          writer.print(identifier.offset);
+          writer.printlnObject(")");
+        }
+      }
+      if (unresolvedExpressionCount > 0) {
+        writer.printlnObject("Expressions:");
+        for (Expression identifier in _unresolvedExpressions) {
+          writer.print("  ");
+          writer.print(identifier.toString());
+          writer.print(" (");
+          writer.print(getFileName(identifier));
+          writer.print(" : ");
+          writer.print(identifier.offset);
+          writer.printlnObject(")");
+        }
+      }
+      JUnitTestCase.fail(writer.toString());
+    }
+  }
+  Object visitCommentReference(CommentReference node) => null;
+  Object visitExpression(Expression node) {
+    node.visitChildren(this);
+    if (node.staticType == null) {
+      _unresolvedExpressions.add(node);
+    } else {
+      _resolvedExpressionCount++;
+    }
+    return null;
+  }
+  Object visitLibraryIdentifier(LibraryIdentifier node) => null;
+  Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+    if (node.staticType == null && identical(node.prefix.staticType, DynamicTypeImpl.instance)) {
+      return null;
+    }
+    return super.visitPrefixedIdentifier(node);
+  }
+  Object visitSimpleIdentifier(SimpleIdentifier node) {
+    ASTNode parent19 = node.parent;
+    if (parent19 is MethodInvocation && identical(node, ((parent19 as MethodInvocation)).methodName)) {
+      return null;
+    } else if (parent19 is RedirectingConstructorInvocation && identical(node, ((parent19 as RedirectingConstructorInvocation)).constructorName)) {
+      return null;
+    } else if (parent19 is SuperConstructorInvocation && identical(node, ((parent19 as SuperConstructorInvocation)).constructorName)) {
+      return null;
+    } else if (parent19 is ConstructorName && identical(node, ((parent19 as ConstructorName)).name)) {
+      return null;
+    } else if (parent19 is Label && identical(node, ((parent19 as Label)).label)) {
+      return null;
+    } else if (parent19 is ImportDirective && identical(node, ((parent19 as ImportDirective)).prefix)) {
+      return null;
+    } else if (node.element is PrefixElement) {
+      return null;
+    }
+    return super.visitSimpleIdentifier(node);
+  }
+  Object visitTypeName(TypeName node) {
+    if (node.type == null) {
+      _unresolvedTypes.add(node);
+    } else {
+      _resolvedTypeCount++;
+    }
+    return null;
+  }
+  String getFileName(ASTNode node) {
+    if (node != null) {
+      ASTNode root3 = node.root;
+      if (root3 is CompilationUnit) {
+        CompilationUnit rootCU = (root3 as CompilationUnit);
+        if (rootCU.element != null) {
+          return rootCU.element.source.fullName;
+        } else {
+          return "<unknown file- CompilationUnit.getElement() returned null>";
+        }
+      } else {
+        return "<unknown file- CompilationUnit.getRoot() is not a CompilationUnit>";
+      }
+    }
+    return "<unknown file- ASTNode is null>";
+  }
+}
+class ElementResolverTest extends EngineTestCase {
+  /**
+   * The error listener to which errors will be reported.
+   */
+  GatheringErrorListener _listener;
+  /**
+   * The type provider used to access the types.
+   */
+  TestTypeProvider _typeProvider;
+  /**
+   * The library containing the code being resolved.
+   */
+  LibraryElementImpl _definingLibrary;
+  /**
+   * The resolver visitor that maintains the state for the resolver.
+   */
+  ResolverVisitor _visitor;
+  /**
+   * The resolver being used to resolve the test cases.
+   */
+  ElementResolver _resolver;
+  void fail_visitExportDirective_combinators() {
+    JUnitTestCase.fail("Not yet tested");
+    ExportDirective directive = ASTFactory.exportDirective2(null, [ASTFactory.hideCombinator2(["A"])]);
+    resolveNode(directive, []);
+    _listener.assertNoErrors();
+  }
+  void fail_visitFunctionExpressionInvocation() {
+    JUnitTestCase.fail("Not yet tested");
+    _listener.assertNoErrors();
+  }
+  void fail_visitImportDirective_combinators_noPrefix() {
+    JUnitTestCase.fail("Not yet tested");
+    ImportDirective directive = ASTFactory.importDirective2(null, null, [ASTFactory.showCombinator2(["A"])]);
+    resolveNode(directive, []);
+    _listener.assertNoErrors();
+  }
+  void fail_visitImportDirective_combinators_prefix() {
+    JUnitTestCase.fail("Not yet tested");
+    String prefixName = "p";
+    _definingLibrary.imports = <ImportElement> [ElementFactory.importFor(null, ElementFactory.prefix(prefixName), [])];
+    ImportDirective directive = ASTFactory.importDirective2(null, prefixName, [ASTFactory.showCombinator2(["A"]), ASTFactory.hideCombinator2(["B"])]);
+    resolveNode(directive, []);
+    _listener.assertNoErrors();
+  }
+  void fail_visitRedirectingConstructorInvocation() {
+    JUnitTestCase.fail("Not yet tested");
+    _listener.assertNoErrors();
+  }
+  void setUp() {
+    _listener = new GatheringErrorListener();
+    _typeProvider = new TestTypeProvider();
+    _resolver = createResolver();
+  }
+  void test_visitAssignmentExpression_compound() {
+    InterfaceType intType2 = _typeProvider.intType;
+    SimpleIdentifier leftHandSide = ASTFactory.identifier2("a");
+    leftHandSide.staticType = intType2;
+    AssignmentExpression assignment = ASTFactory.assignmentExpression(leftHandSide, TokenType.PLUS_EQ, ASTFactory.integer(1));
+    resolveNode(assignment, []);
+    JUnitTestCase.assertSame(getMethod(_typeProvider.numType, "+"), assignment.element);
+    _listener.assertNoErrors();
+  }
+  void test_visitAssignmentExpression_simple() {
+    AssignmentExpression expression = ASTFactory.assignmentExpression(ASTFactory.identifier2("x"), TokenType.EQ, ASTFactory.integer(0));
+    resolveNode(expression, []);
+    JUnitTestCase.assertNull(expression.element);
+    _listener.assertNoErrors();
+  }
+  void test_visitBinaryExpression() {
+    InterfaceType numType2 = _typeProvider.numType;
+    SimpleIdentifier left = ASTFactory.identifier2("i");
+    left.staticType = numType2;
+    BinaryExpression expression = ASTFactory.binaryExpression(left, TokenType.PLUS, ASTFactory.identifier2("j"));
+    resolveNode(expression, []);
+    JUnitTestCase.assertEquals(getMethod(numType2, "+"), expression.element);
+    _listener.assertNoErrors();
+  }
+  void test_visitBreakStatement_withLabel() {
+    String label = "loop";
+    LabelElementImpl labelElement = new LabelElementImpl(ASTFactory.identifier2(label), false, false);
+    BreakStatement statement = ASTFactory.breakStatement2(label);
+    JUnitTestCase.assertSame(labelElement, resolve(statement, labelElement));
+    _listener.assertNoErrors();
+  }
+  void test_visitBreakStatement_withoutLabel() {
+    BreakStatement statement = ASTFactory.breakStatement();
+    resolveStatement(statement, null);
+    _listener.assertNoErrors();
+  }
+  void test_visitConstructorName_named() {
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
+    String constructorName = "a";
+    ConstructorElement constructor = ElementFactory.constructorElement(constructorName);
+    classA.constructors = <ConstructorElement> [constructor];
+    ConstructorName name = ASTFactory.constructorName(ASTFactory.typeName(classA, []), constructorName);
+    resolveNode(name, []);
+    JUnitTestCase.assertSame(constructor, name.element);
+    _listener.assertNoErrors();
+  }
+  void test_visitConstructorName_unnamed() {
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
+    String constructorName = null;
+    ConstructorElement constructor = ElementFactory.constructorElement(constructorName);
+    classA.constructors = <ConstructorElement> [constructor];
+    ConstructorName name = ASTFactory.constructorName(ASTFactory.typeName(classA, []), constructorName);
+    resolveNode(name, []);
+    JUnitTestCase.assertSame(constructor, name.element);
+    _listener.assertNoErrors();
+  }
+  void test_visitContinueStatement_withLabel() {
+    String label = "loop";
+    LabelElementImpl labelElement = new LabelElementImpl(ASTFactory.identifier2(label), false, false);
+    ContinueStatement statement = ASTFactory.continueStatement2(label);
+    JUnitTestCase.assertSame(labelElement, resolve2(statement, labelElement));
+    _listener.assertNoErrors();
+  }
+  void test_visitContinueStatement_withoutLabel() {
+    ContinueStatement statement = ASTFactory.continueStatement();
+    resolveStatement(statement, null);
+    _listener.assertNoErrors();
+  }
+  void test_visitExportDirective_noCombinators() {
+    ExportDirective directive = ASTFactory.exportDirective2(null, []);
+    directive.element = ElementFactory.exportFor(ElementFactory.library(_definingLibrary.context, "lib"), []);
+    resolveNode(directive, []);
+    _listener.assertNoErrors();
+  }
+  void test_visitImportDirective_noCombinators_noPrefix() {
+    ImportDirective directive = ASTFactory.importDirective2(null, null, []);
+    directive.element = ElementFactory.importFor(ElementFactory.library(_definingLibrary.context, "lib"), null, []);
+    resolveNode(directive, []);
+    _listener.assertNoErrors();
+  }
+  void test_visitImportDirective_noCombinators_prefix() {
+    String prefixName = "p";
+    ImportElement importElement = ElementFactory.importFor(ElementFactory.library(_definingLibrary.context, "lib"), ElementFactory.prefix(prefixName), []);
+    _definingLibrary.imports = <ImportElement> [importElement];
+    ImportDirective directive = ASTFactory.importDirective2(null, prefixName, []);
+    directive.element = importElement;
+    resolveNode(directive, []);
+    _listener.assertNoErrors();
+  }
+  void test_visitIndexExpression_get() {
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
+    InterfaceType intType3 = _typeProvider.intType;
+    MethodElement getter = ElementFactory.methodElement("[]", intType3, [intType3]);
+    classA.methods = <MethodElement> [getter];
+    SimpleIdentifier array = ASTFactory.identifier2("a");
+    array.staticType = classA.type;
+    IndexExpression expression = ASTFactory.indexExpression(array, ASTFactory.identifier2("i"));
+    JUnitTestCase.assertSame(getter, resolve4(expression, []));
+    _listener.assertNoErrors();
+  }
+  void test_visitIndexExpression_set() {
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
+    InterfaceType intType4 = _typeProvider.intType;
+    MethodElement setter = ElementFactory.methodElement("[]=", intType4, [intType4]);
+    classA.methods = <MethodElement> [setter];
+    SimpleIdentifier array = ASTFactory.identifier2("a");
+    array.staticType = classA.type;
+    IndexExpression expression = ASTFactory.indexExpression(array, ASTFactory.identifier2("i"));
+    ASTFactory.assignmentExpression(expression, TokenType.EQ, ASTFactory.integer(0));
+    JUnitTestCase.assertSame(setter, resolve4(expression, []));
+    _listener.assertNoErrors();
+  }
+  void test_visitInstanceCreationExpression_named() {
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
+    String constructorName = "a";
+    ConstructorElement constructor = ElementFactory.constructorElement(constructorName);
+    classA.constructors = <ConstructorElement> [constructor];
+    ConstructorName name = ASTFactory.constructorName(ASTFactory.typeName(classA, []), constructorName);
+    name.element = constructor;
+    InstanceCreationExpression creation = ASTFactory.instanceCreationExpression(Keyword.NEW, name, []);
+    resolveNode(creation, []);
+    JUnitTestCase.assertSame(constructor, creation.element);
+    _listener.assertNoErrors();
+  }
+  void test_visitInstanceCreationExpression_unnamed() {
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
+    String constructorName = null;
+    ConstructorElement constructor = ElementFactory.constructorElement(constructorName);
+    classA.constructors = <ConstructorElement> [constructor];
+    ConstructorName name = ASTFactory.constructorName(ASTFactory.typeName(classA, []), constructorName);
+    name.element = constructor;
+    InstanceCreationExpression creation = ASTFactory.instanceCreationExpression(Keyword.NEW, name, []);
+    resolveNode(creation, []);
+    JUnitTestCase.assertSame(constructor, creation.element);
+    _listener.assertNoErrors();
+  }
+  void test_visitInstanceCreationExpression_unnamed_namedParameter() {
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
+    String constructorName = null;
+    ConstructorElementImpl constructor = ElementFactory.constructorElement(constructorName);
+    String parameterName = "a";
+    ParameterElement parameter = ElementFactory.namedParameter(parameterName);
+    constructor.parameters = <ParameterElement> [parameter];
+    classA.constructors = <ConstructorElement> [constructor];
+    ConstructorName name = ASTFactory.constructorName(ASTFactory.typeName(classA, []), constructorName);
+    name.element = constructor;
+    InstanceCreationExpression creation = ASTFactory.instanceCreationExpression(Keyword.NEW, name, [ASTFactory.namedExpression(parameterName, ASTFactory.integer(0))]);
+    resolveNode(creation, []);
+    JUnitTestCase.assertSame(constructor, creation.element);
+    JUnitTestCase.assertSame(parameter, ((creation.argumentList.arguments[0] as NamedExpression)).name.label.element);
+    _listener.assertNoErrors();
+  }
+  void test_visitMethodInvocation() {
+    InterfaceType numType3 = _typeProvider.numType;
+    SimpleIdentifier left = ASTFactory.identifier2("i");
+    left.staticType = numType3;
+    String methodName = "abs";
+    MethodInvocation invocation = ASTFactory.methodInvocation(left, methodName, []);
+    resolveNode(invocation, []);
+    JUnitTestCase.assertSame(getMethod(numType3, methodName), invocation.methodName.element);
+    _listener.assertNoErrors();
+  }
+  void test_visitMethodInvocation_namedParameter() {
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
+    String methodName = "m";
+    String parameterName = "p";
+    MethodElementImpl method = ElementFactory.methodElement(methodName, null, []);
+    ParameterElement parameter = ElementFactory.namedParameter(parameterName);
+    method.parameters = <ParameterElement> [parameter];
+    classA.methods = <MethodElement> [method];
+    SimpleIdentifier left = ASTFactory.identifier2("i");
+    left.staticType = classA.type;
+    MethodInvocation invocation = ASTFactory.methodInvocation(left, methodName, [ASTFactory.namedExpression(parameterName, ASTFactory.integer(0))]);
+    resolveNode(invocation, []);
+    JUnitTestCase.assertSame(method, invocation.methodName.element);
+    JUnitTestCase.assertSame(parameter, ((invocation.argumentList.arguments[0] as NamedExpression)).name.label.element);
+    _listener.assertNoErrors();
+  }
+  void test_visitPostfixExpression() {
+    InterfaceType numType4 = _typeProvider.numType;
+    SimpleIdentifier operand = ASTFactory.identifier2("i");
+    operand.staticType = numType4;
+    PostfixExpression expression = ASTFactory.postfixExpression(operand, TokenType.PLUS_PLUS);
+    resolveNode(expression, []);
+    JUnitTestCase.assertEquals(getMethod(numType4, "+"), expression.element);
+    _listener.assertNoErrors();
+  }
+  void test_visitPrefixedIdentifier_dynamic() {
+    Type2 dynamicType2 = _typeProvider.dynamicType;
+    SimpleIdentifier target = ASTFactory.identifier2("a");
+    VariableElementImpl variable = ElementFactory.localVariableElement(target);
+    variable.type = dynamicType2;
+    target.element = variable;
+    target.staticType = dynamicType2;
+    PrefixedIdentifier identifier5 = ASTFactory.identifier(target, ASTFactory.identifier2("b"));
+    resolveNode(identifier5, []);
+    JUnitTestCase.assertNull(identifier5.element);
+    JUnitTestCase.assertNull(identifier5.identifier.element);
+    _listener.assertNoErrors();
+  }
+  void test_visitPrefixedIdentifier_nonDynamic() {
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
+    String getterName = "b";
+    PropertyAccessorElement getter = ElementFactory.getterElement(getterName, false, _typeProvider.intType);
+    classA.accessors = <PropertyAccessorElement> [getter];
+    SimpleIdentifier target = ASTFactory.identifier2("a");
+    VariableElementImpl variable = ElementFactory.localVariableElement(target);
+    variable.type = classA.type;
+    target.element = variable;
+    target.staticType = classA.type;
+    PrefixedIdentifier identifier6 = ASTFactory.identifier(target, ASTFactory.identifier2(getterName));
+    resolveNode(identifier6, []);
+    JUnitTestCase.assertSame(getter, identifier6.element);
+    JUnitTestCase.assertSame(getter, identifier6.identifier.element);
+    _listener.assertNoErrors();
+  }
+  void test_visitPrefixExpression() {
+    InterfaceType numType5 = _typeProvider.numType;
+    SimpleIdentifier operand = ASTFactory.identifier2("i");
+    operand.staticType = numType5;
+    PrefixExpression expression = ASTFactory.prefixExpression(TokenType.PLUS_PLUS, operand);
+    resolveNode(expression, []);
+    JUnitTestCase.assertEquals(getMethod(numType5, "+"), expression.element);
+    _listener.assertNoErrors();
+  }
+  void test_visitPropertyAccess_getter_identifier() {
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
+    String getterName = "b";
+    PropertyAccessorElement getter = ElementFactory.getterElement(getterName, false, _typeProvider.intType);
+    classA.accessors = <PropertyAccessorElement> [getter];
+    SimpleIdentifier target = ASTFactory.identifier2("a");
+    target.staticType = classA.type;
+    PropertyAccess access = ASTFactory.propertyAccess2(target, getterName);
+    resolveNode(access, []);
+    JUnitTestCase.assertSame(getter, access.propertyName.element);
+    _listener.assertNoErrors();
+  }
+  void test_visitPropertyAccess_getter_super() {
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
+    String getterName = "b";
+    PropertyAccessorElement getter = ElementFactory.getterElement(getterName, false, _typeProvider.intType);
+    classA.accessors = <PropertyAccessorElement> [getter];
+    SuperExpression target = ASTFactory.superExpression();
+    target.staticType = classA.type;
+    PropertyAccess access = ASTFactory.propertyAccess2(target, getterName);
+    resolveNode(access, []);
+    JUnitTestCase.assertSame(getter, access.propertyName.element);
+    _listener.assertNoErrors();
+  }
+  void test_visitPropertyAccess_setter_this() {
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
+    String setterName = "b";
+    PropertyAccessorElement setter = ElementFactory.setterElement(setterName, false, _typeProvider.intType);
+    classA.accessors = <PropertyAccessorElement> [setter];
+    ThisExpression target = ASTFactory.thisExpression();
+    target.staticType = classA.type;
+    PropertyAccess access = ASTFactory.propertyAccess2(target, setterName);
+    ASTFactory.assignmentExpression(access, TokenType.EQ, ASTFactory.integer(0));
+    resolveNode(access, []);
+    JUnitTestCase.assertSame(setter, access.propertyName.element);
+    _listener.assertNoErrors();
+  }
+  void test_visitSimpleIdentifier_classScope() {
+    InterfaceType doubleType2 = _typeProvider.doubleType;
+    String fieldName = "NAN";
+    SimpleIdentifier node = ASTFactory.identifier2(fieldName);
+    resolveInClass(node, doubleType2.element);
+    JUnitTestCase.assertEquals(getGetter(doubleType2, fieldName), node.element);
+    _listener.assertNoErrors();
+  }
+  void test_visitSimpleIdentifier_lexicalScope() {
+    SimpleIdentifier node = ASTFactory.identifier2("i");
+    VariableElementImpl element = ElementFactory.localVariableElement(node);
+    JUnitTestCase.assertSame(element, resolve3(node, [element]));
+    _listener.assertNoErrors();
+  }
+  void test_visitSimpleIdentifier_lexicalScope_field_setter() {
+    InterfaceType intType5 = _typeProvider.intType;
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
+    String fieldName = "a";
+    FieldElement field = ElementFactory.fieldElement(fieldName, false, false, false, intType5);
+    classA.fields = <FieldElement> [field];
+    classA.accessors = <PropertyAccessorElement> [field.getter, field.setter];
+    SimpleIdentifier node = ASTFactory.identifier2(fieldName);
+    ASTFactory.assignmentExpression(node, TokenType.EQ, ASTFactory.integer(0));
+    resolveInClass(node, classA);
+    Element element50 = node.element;
+    EngineTestCase.assertInstanceOf(PropertyAccessorElement, element50);
+    JUnitTestCase.assertTrue(((element50 as PropertyAccessorElement)).isSetter());
+    _listener.assertNoErrors();
+  }
+  void test_visitSuperConstructorInvocation() {
+    ClassElementImpl superclass = ElementFactory.classElement2("A", []);
+    ConstructorElementImpl superConstructor = ElementFactory.constructorElement(null);
+    superclass.constructors = <ConstructorElement> [superConstructor];
+    ClassElementImpl subclass = ElementFactory.classElement("B", superclass.type, []);
+    ConstructorElementImpl subConstructor = ElementFactory.constructorElement(null);
+    subclass.constructors = <ConstructorElement> [subConstructor];
+    SuperConstructorInvocation invocation = ASTFactory.superConstructorInvocation([]);
+    resolveInClass(invocation, subclass);
+    JUnitTestCase.assertEquals(superConstructor, invocation.element);
+    _listener.assertNoErrors();
+  }
+  void test_visitSuperConstructorInvocation_namedParameter() {
+    ClassElementImpl superclass = ElementFactory.classElement2("A", []);
+    ConstructorElementImpl superConstructor = ElementFactory.constructorElement(null);
+    String parameterName = "p";
+    ParameterElement parameter = ElementFactory.namedParameter(parameterName);
+    superConstructor.parameters = <ParameterElement> [parameter];
+    superclass.constructors = <ConstructorElement> [superConstructor];
+    ClassElementImpl subclass = ElementFactory.classElement("B", superclass.type, []);
+    ConstructorElementImpl subConstructor = ElementFactory.constructorElement(null);
+    subclass.constructors = <ConstructorElement> [subConstructor];
+    SuperConstructorInvocation invocation = ASTFactory.superConstructorInvocation([ASTFactory.namedExpression(parameterName, ASTFactory.integer(0))]);
+    resolveInClass(invocation, subclass);
+    JUnitTestCase.assertEquals(superConstructor, invocation.element);
+    JUnitTestCase.assertSame(parameter, ((invocation.argumentList.arguments[0] as NamedExpression)).name.label.element);
+    _listener.assertNoErrors();
+  }
+  /**
+   * Create the resolver used by the tests.
+   * @return the resolver that was created
+   */
+  ElementResolver createResolver() {
+    AnalysisContextImpl context = new AnalysisContextImpl();
+    SourceFactory sourceFactory = new SourceFactory.con2([new DartUriResolver(DartSdk.defaultSdk)]);
+    context.sourceFactory = sourceFactory;
+    CompilationUnitElementImpl definingCompilationUnit = new CompilationUnitElementImpl("test.dart");
+    definingCompilationUnit.source = new FileBasedSource.con1(sourceFactory, FileUtilities2.createFile("/test.dart"));
+    _definingLibrary = ElementFactory.library(context, "test");
+    _definingLibrary.definingCompilationUnit = definingCompilationUnit;
+    Library library = new Library(context, _listener, null);
+    library.libraryElement = _definingLibrary;
+    _visitor = new ResolverVisitor(library, null, _typeProvider);
+    try {
+      return _visitor.elementResolver_J2DAccessor as ElementResolver;
+    } on JavaException catch (exception) {
+      throw new IllegalArgumentException("Could not create resolver", exception);
+    }
+  }
+  /**
+   * Return the element associated with the label of the given statement after the resolver has
+   * resolved the statement.
+   * @param statement the statement to be resolved
+   * @param labelElement the label element to be defined in the statement's label scope
+   * @return the element to which the statement's label was resolved
+   */
+  Element resolve(BreakStatement statement, LabelElementImpl labelElement) {
+    resolveStatement(statement, labelElement);
+    return statement.label.element;
+  }
+  /**
+   * Return the element associated with the label of the given statement after the resolver has
+   * resolved the statement.
+   * @param statement the statement to be resolved
+   * @param labelElement the label element to be defined in the statement's label scope
+   * @return the element to which the statement's label was resolved
+   */
+  Element resolve2(ContinueStatement statement, LabelElementImpl labelElement) {
+    resolveStatement(statement, labelElement);
+    return statement.label.element;
+  }
+  /**
+   * Return the element associated with the given identifier after the resolver has resolved the
+   * identifier.
+   * @param node the expression to be resolved
+   * @param definedElements the elements that are to be defined in the scope in which the element is
+   * being resolved
+   * @return the element to which the expression was resolved
+   */
+  Element resolve3(Identifier node, List<Element> definedElements) {
+    resolveNode(node, definedElements);
+    return node.element;
+  }
+  /**
+   * Return the element associated with the given expression after the resolver has resolved the
+   * expression.
+   * @param node the expression to be resolved
+   * @param definedElements the elements that are to be defined in the scope in which the element is
+   * being resolved
+   * @return the element to which the expression was resolved
+   */
+  Element resolve4(IndexExpression node, List<Element> definedElements) {
+    resolveNode(node, definedElements);
+    return node.element;
+  }
+  /**
+   * Return the element associated with the given identifier after the resolver has resolved the
+   * identifier.
+   * @param node the expression to be resolved
+   * @param enclosingClass the element representing the class enclosing the identifier
+   * @return the element to which the expression was resolved
+   */
+  void resolveInClass(ASTNode node, ClassElement enclosingClass) {
+    try {
+      Scope outerScope = _visitor.nameScope_J2DAccessor as Scope;
+      try {
+        _visitor.enclosingClass_J2DAccessor = enclosingClass;
+        EnclosedScope innerScope = new ClassScope(outerScope, enclosingClass);
+        _visitor.nameScope_J2DAccessor = innerScope;
+        node.accept(_resolver);
+      } finally {
+        _visitor.enclosingClass_J2DAccessor = null;
+        _visitor.nameScope_J2DAccessor = outerScope;
+      }
+    } on JavaException catch (exception) {
+      throw new IllegalArgumentException("Could not resolve node", exception);
+    }
+  }
+  /**
+   * Return the element associated with the given identifier after the resolver has resolved the
+   * identifier.
+   * @param node the expression to be resolved
+   * @param definedElements the elements that are to be defined in the scope in which the element is
+   * being resolved
+   * @return the element to which the expression was resolved
+   */
+  void resolveNode(ASTNode node, List<Element> definedElements) {
+    try {
+      Scope outerScope = _visitor.nameScope_J2DAccessor as Scope;
+      try {
+        EnclosedScope innerScope = new EnclosedScope(outerScope);
+        for (Element element in definedElements) {
+          innerScope.define(element);
+        }
+        _visitor.nameScope_J2DAccessor = innerScope;
+        node.accept(_resolver);
+      } finally {
+        _visitor.nameScope_J2DAccessor = outerScope;
+      }
+    } on JavaException catch (exception) {
+      throw new IllegalArgumentException("Could not resolve node", exception);
+    }
+  }
+  /**
+   * Return the element associated with the label of the given statement after the resolver has
+   * resolved the statement.
+   * @param statement the statement to be resolved
+   * @param labelElement the label element to be defined in the statement's label scope
+   * @return the element to which the statement's label was resolved
+   */
+  void resolveStatement(Statement statement, LabelElementImpl labelElement) {
+    try {
+      LabelScope outerScope = _visitor.labelScope_J2DAccessor as LabelScope;
+      try {
+        LabelScope innerScope;
+        if (labelElement == null) {
+          innerScope = new LabelScope.con1(outerScope, false, false);
+        } else {
+          innerScope = new LabelScope.con2(outerScope, labelElement.name, labelElement);
+        }
+        _visitor.labelScope_J2DAccessor = innerScope;
+        statement.accept(_resolver);
+      } finally {
+        _visitor.labelScope_J2DAccessor = outerScope;
+      }
+    } on JavaException catch (exception) {
+      throw new IllegalArgumentException("Could not resolve node", exception);
+    }
+  }
+  static dartSuite() {
+    _ut.group('ElementResolverTest', () {
+      _ut.test('test_visitAssignmentExpression_compound', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitAssignmentExpression_compound);
+      });
+      _ut.test('test_visitAssignmentExpression_simple', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitAssignmentExpression_simple);
+      });
+      _ut.test('test_visitBinaryExpression', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitBinaryExpression);
+      });
+      _ut.test('test_visitBreakStatement_withLabel', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitBreakStatement_withLabel);
+      });
+      _ut.test('test_visitBreakStatement_withoutLabel', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitBreakStatement_withoutLabel);
+      });
+      _ut.test('test_visitConstructorName_named', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitConstructorName_named);
+      });
+      _ut.test('test_visitConstructorName_unnamed', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitConstructorName_unnamed);
+      });
+      _ut.test('test_visitContinueStatement_withLabel', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitContinueStatement_withLabel);
+      });
+      _ut.test('test_visitContinueStatement_withoutLabel', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitContinueStatement_withoutLabel);
+      });
+      _ut.test('test_visitExportDirective_noCombinators', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitExportDirective_noCombinators);
+      });
+      _ut.test('test_visitImportDirective_noCombinators_noPrefix', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitImportDirective_noCombinators_noPrefix);
+      });
+      _ut.test('test_visitImportDirective_noCombinators_prefix', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitImportDirective_noCombinators_prefix);
+      });
+      _ut.test('test_visitIndexExpression_get', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitIndexExpression_get);
+      });
+      _ut.test('test_visitIndexExpression_set', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitIndexExpression_set);
+      });
+      _ut.test('test_visitInstanceCreationExpression_named', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitInstanceCreationExpression_named);
+      });
+      _ut.test('test_visitInstanceCreationExpression_unnamed', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitInstanceCreationExpression_unnamed);
+      });
+      _ut.test('test_visitInstanceCreationExpression_unnamed_namedParameter', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitInstanceCreationExpression_unnamed_namedParameter);
+      });
+      _ut.test('test_visitMethodInvocation', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitMethodInvocation);
+      });
+      _ut.test('test_visitMethodInvocation_namedParameter', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitMethodInvocation_namedParameter);
+      });
+      _ut.test('test_visitPostfixExpression', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitPostfixExpression);
+      });
+      _ut.test('test_visitPrefixExpression', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitPrefixExpression);
+      });
+      _ut.test('test_visitPrefixedIdentifier_dynamic', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitPrefixedIdentifier_dynamic);
+      });
+      _ut.test('test_visitPrefixedIdentifier_nonDynamic', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitPrefixedIdentifier_nonDynamic);
+      });
+      _ut.test('test_visitPropertyAccess_getter_identifier', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitPropertyAccess_getter_identifier);
+      });
+      _ut.test('test_visitPropertyAccess_getter_super', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitPropertyAccess_getter_super);
+      });
+      _ut.test('test_visitPropertyAccess_setter_this', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitPropertyAccess_setter_this);
+      });
+      _ut.test('test_visitSimpleIdentifier_classScope', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitSimpleIdentifier_classScope);
+      });
+      _ut.test('test_visitSimpleIdentifier_lexicalScope', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitSimpleIdentifier_lexicalScope);
+      });
+      _ut.test('test_visitSimpleIdentifier_lexicalScope_field_setter', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitSimpleIdentifier_lexicalScope_field_setter);
+      });
+      _ut.test('test_visitSuperConstructorInvocation', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitSuperConstructorInvocation);
+      });
+      _ut.test('test_visitSuperConstructorInvocation_namedParameter', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitSuperConstructorInvocation_namedParameter);
+      });
+    });
+  }
+}
+class StaticWarningCodeTest extends ResolverTestCase {
+  void fail_argumentTypeNotAssignable() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+    verify([source]);
+  }
+  void fail_assignmentToFinal() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["final x = 0;", "f() { x = 1; }"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.ASSIGNMENT_TO_FINAL]);
+    verify([source]);
+  }
+  void fail_caseBlockNotTerminated() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f(int p) {", "  switch (p) {", "    case 0:", "      f(p);", "    case 1:", "      break;", "  }", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.CASE_BLOCK_NOT_TERMINATED]);
+    verify([source]);
+  }
+  void fail_castToNonType() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["var A = 0;", "f(String s) { var x = s as A; }"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.CAST_TO_NON_TYPE]);
+    verify([source]);
+  }
+  void fail_commentReferenceConstructorNotVisible() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.COMMENT_REFERENCE_CONSTRUCTOR_NOT_VISIBLE]);
+    verify([source]);
+  }
+  void fail_commentReferenceIdentifierNotVisible() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.COMMENT_REFERENCE_IDENTIFIER_NOT_VISIBLE]);
+    verify([source]);
+  }
+  void fail_commentReferenceUndeclaredConstructor() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.COMMENT_REFERENCE_UNDECLARED_CONSTRUCTOR]);
+    verify([source]);
+  }
+  void fail_commentReferenceUndeclaredIdentifier() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.COMMENT_REFERENCE_UNDECLARED_IDENTIFIER]);
+    verify([source]);
+  }
+  void fail_commentReferenceUriNotLibrary() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.COMMENT_REFERENCE_URI_NOT_LIBRARY]);
+    verify([source]);
+  }
+  void fail_concreteClassWithAbstractMember() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  m();", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER]);
+    verify([source]);
+  }
+  void fail_conflictingInstanceGetterAndSuperclassMember() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER]);
+    verify([source]);
+  }
+  void fail_conflictingInstanceSetterAndSuperclassMember() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER]);
+    verify([source]);
+  }
+  void fail_conflictingStaticGetterAndInstanceSetter() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  static get x -> 0;", "  set x(int p) {}", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER]);
+    verify([source]);
+  }
+  void fail_conflictingStaticSetterAndInstanceGetter() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  get x -> 0;", "  static set x(int p) {}", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_GETTER]);
+    verify([source]);
+  }
+  void fail_fieldInitializerWithInvalidType() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  int x;", "  A(String this.x) {}", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.FIELD_INITIALIZER_WITH_INVALID_TYPE]);
+    verify([source]);
+  }
+  void fail_incorrectNumberOfArguments_tooFew() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f(a, b) -> 0;", "g() {", "  f(2);", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.INCORRECT_NUMBER_OF_ARGUMENTS]);
+    verify([source]);
+  }
+  void fail_incorrectNumberOfArguments_tooMany() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f(a, b) -> 0;", "g() {", "  f(2, 3, 4);", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.INCORRECT_NUMBER_OF_ARGUMENTS]);
+    verify([source]);
+  }
+  void fail_instanceMethodNameCollidesWithSuperclassStatic() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  static n", "}", "class C extends A {", "  void n() {}", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC]);
+    verify([source]);
+  }
+  void fail_invalidFactoryName() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.INVALID_FACTORY_NAME]);
+    verify([source]);
+  }
+  void fail_invalidOverrideGetterType() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  int get g -> 0", "}", "class B extends A {", "  String get g { return 'a'; }", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.INVALID_OVERRIDE_GETTER_TYPE]);
+    verify([source]);
+  }
+  void fail_invalidOverrideReturnType() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  int m() { return 0; }", "}", "class B extends A {", "  String m() { return 'a'; }", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.INVALID_OVERRIDE_RETURN_TYPE]);
+    verify([source]);
+  }
+  void fail_invalidOverrideSetterReturnType() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  void set s(int v) {}", "}", "class B extends A {", "  void set s(String v) {}", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.INVALID_OVERRIDE_SETTER_RETURN_TYPE]);
+    verify([source]);
+  }
+  void fail_invocationOfNonFunction() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.INVOCATION_OF_NON_FUNCTION]);
+    verify([source]);
+  }
+  void fail_mismatchedGetterAndSetterTypes() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  int get g { return 0; }", "  set g(String v) {}", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
+    verify([source]);
+  }
+  void fail_newWithNonType() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["var A = 0;", "void f() {", "  A a = new A();", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.NEW_WITH_NON_TYPE]);
+    verify([source]);
+  }
+  void fail_newWithUndefinedConstructor() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  A(int p) {}", "}", "A f() {", "  return new A();", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR]);
+    verify([source]);
+  }
+  void fail_nonAbstractClassInheritsAbstractMember() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class I {", "  m(p) {}", "}", "class C implements I {", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER]);
+    verify([source]);
+  }
+  void fail_nonAbstractClassInheritsAbstractMethod() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["abstract class A {", "  m(p);", "}", "class C extends A {", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_METHOD]);
+    verify([source]);
+  }
+  void fail_nonType() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["var A = 0;", "f(var p) {", "  if (p is A) {", "  }", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.NON_TYPE]);
+    verify([source]);
+  }
+  void fail_nonTypeInCatchClause() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["var T = 0;", "f(var p) {", "  try {", "  } on T catch e {", "  }", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE]);
+    verify([source]);
+  }
+  void fail_nonVoidReturnForOperator() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  int operator []=() {}", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR]);
+    verify([source]);
+  }
+  void fail_nonVoidReturnForSetter() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["int set x(int v) {", "  var s = x;", "  x = v;", "  return s;", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.NON_VOID_RETURN_FOR_SETTER]);
+    verify([source]);
+  }
+  void fail_overrideNotSubtype() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  int m() {}", "}", "class B extends A {", "  String m() {}", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.OVERRIDE_NOT_SUBTYPE]);
+    verify([source]);
+  }
+  void fail_overrideWithDifferentDefault() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  m([int p = 0]) {}", "}", "class B extends A {", "  m([int p = 1]) {}", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.OVERRIDE_WITH_DIFFERENT_DEFAULT]);
+    verify([source]);
+  }
+  void fail_redirectToInvalidReturnType() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE]);
+    verify([source]);
+  }
+  void fail_redirectToMissingConstructor() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR]);
+    verify([source]);
+  }
+  void fail_redirectToNonClass() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.REDIRECT_TO_NON_CLASS]);
+    verify([source]);
+  }
+  void fail_returnWithoutValue() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["int f() { return; }"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.RETURN_WITHOUT_VALUE]);
+    verify([source]);
+  }
+  void fail_switchExpressionNotAssignable() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f(int p) {", "  switch (p) {", "    case 'a': break;", "  }", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE]);
+    verify([source]);
+  }
+  void fail_undefinedClass() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() { C.m(); }"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.UNDEFINED_CLASS]);
+    verify([source]);
+  }
+  void fail_undefinedGetter() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource([]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.UNDEFINED_GETTER]);
+    verify([source]);
+  }
+  void fail_undefinedIdentifier_function() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["int a() -> b;"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.UNDEFINED_IDENTIFIER]);
+    verify([source]);
+  }
+  void fail_undefinedIdentifier_initializer() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["var a = b;"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.UNDEFINED_IDENTIFIER]);
+    verify([source]);
+  }
+  void fail_undefinedSetter() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class C {}", "f(var p) {", "  C.m = 0;", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.UNDEFINED_SETTER]);
+    verify([source]);
+  }
+  void fail_undefinedStaticMethodOrGetter_getter() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class C {}", "f(var p) {", "  f(C.m);", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.UNDEFINED_STATIC_METHOD_OR_GETTER]);
+    verify([source]);
+  }
+  void fail_undefinedStaticMethodOrGetter_method() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class C {}", "f(var p) {", "  f(C.m());", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.UNDEFINED_STATIC_METHOD_OR_GETTER]);
+    verify([source]);
+  }
+  void test_constWithAbstractClass() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["abstract class A {", "  const A() {}", "}", "void f() {", "  A a = const A();", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.CONST_WITH_ABSTRACT_CLASS]);
+    verify([source]);
+  }
+  void test_equalKeysInMap() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["var m = {'a' : 0, 'b' : 1, 'a' : 2};"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.EQUAL_KEYS_IN_MAP]);
+    verify([source]);
+  }
+  void test_newWithAbstractClass() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["abstract class A {}", "void f() {", "  A a = new A();", "}"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.NEW_WITH_ABSTRACT_CLASS]);
+    verify([source]);
+  }
+  void test_partOfDifferentLibrary() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["library lib;", "part 'part.dart';"]));
+    addSource("/part.dart", EngineTestCase.createSource(["part of lub;"]));
+    resolve(source, []);
+    assertErrors([StaticWarningCode.PART_OF_DIFFERENT_LIBRARY]);
+    verify([source]);
+  }
+  static dartSuite() {
+    _ut.group('StaticWarningCodeTest', () {
+      _ut.test('test_constWithAbstractClass', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_constWithAbstractClass);
+      });
+      _ut.test('test_equalKeysInMap', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_equalKeysInMap);
+      });
+      _ut.test('test_newWithAbstractClass', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_newWithAbstractClass);
+      });
+      _ut.test('test_partOfDifferentLibrary', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_partOfDifferentLibrary);
+      });
+    });
+  }
+}
+class ErrorResolverTest extends ResolverTestCase {
+  void test_breakLabelOnSwitchMember() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  void m(int i) {", "    switch (i) {", "      l: case 0:", "        break;", "      case 1:", "        break l;", "    }", "  }", "}"]));
+    resolve(source, []);
+    assertErrors([ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER]);
+    verify([source]);
+  }
+  void test_continueLabelOnSwitch() {
+    Source source = addSource("/a.dart", EngineTestCase.createSource(["class A {", "  void m(int i) {", "    l: switch (i) {", "      case 0:", "        continue l;", "    }", "  }", "}"]));
+    resolve(source, []);
+    assertErrors([ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH]);
+    verify([source]);
+  }
+  static dartSuite() {
+    _ut.group('ErrorResolverTest', () {
+      _ut.test('test_breakLabelOnSwitchMember', () {
+        final __test = new ErrorResolverTest();
+        runJUnitTest(__test, __test.test_breakLabelOnSwitchMember);
+      });
+      _ut.test('test_continueLabelOnSwitch', () {
+        final __test = new ErrorResolverTest();
+        runJUnitTest(__test, __test.test_continueLabelOnSwitch);
+      });
+    });
+  }
+}
+/**
+ * The class {@code AnalysisContextFactory} defines utility methods used to create analysis contexts
+ * for testing purposes.
+ */
+class AnalysisContextFactory {
+  /**
+   * Create an analysis context that has a fake core library already resolved.
+   * @return the analysis context that was created
+   */
+  static AnalysisContextImpl contextWithCore() {
+    AnalysisContextImpl context = new AnalysisContextImpl();
+    SourceFactory sourceFactory = new SourceFactory.con2([new DartUriResolver(DartSdk.defaultSdk), new FileUriResolver()]);
+    context.sourceFactory = sourceFactory;
+    TestTypeProvider provider = new TestTypeProvider();
+    CompilationUnitElementImpl unit = new CompilationUnitElementImpl("core.dart");
+    unit.types = <ClassElement> [provider.boolType.element, provider.doubleType.element, provider.functionType.element, provider.intType.element, provider.listType.element, provider.mapType.element, provider.numType.element, provider.objectType.element, provider.stackTraceType.element, provider.stringType.element, provider.typeType.element];
+    LibraryElementImpl library = new LibraryElementImpl(context, ASTFactory.libraryIdentifier2(["dart", "core"]));
+    library.definingCompilationUnit = unit;
+    Map<Source, LibraryElement> elementMap = new Map<Source, LibraryElement>();
+    Source coreSource = sourceFactory.forUri(DartSdk.DART_CORE);
+    elementMap[coreSource] = library;
+    context.recordLibraryElements(elementMap);
+    unit.source = coreSource;
+    return context;
+  }
+  /**
+   * Prevent the creation of instances of this class.
+   */
+  AnalysisContextFactory() {
+  }
+}
+/**
+ * Instances of the class {@code TestTypeProvider} implement a type provider that can be used by
+ * tests without creating the element model for the core library.
+ */
+class TestTypeProvider implements TypeProvider {
+  /**
+   * The type representing the built-in type 'bool'.
+   */
+  InterfaceType _boolType;
+  /**
+   * The type representing the type 'bottom'.
+   */
+  Type2 _bottomType;
+  /**
+   * The type representing the built-in type 'double'.
+   */
+  InterfaceType _doubleType;
+  /**
+   * The type representing the built-in type 'dynamic'.
+   */
+  Type2 _dynamicType;
+  /**
+   * The type representing the built-in type 'Function'.
+   */
+  InterfaceType _functionType;
+  /**
+   * The type representing the built-in type 'int'.
+   */
+  InterfaceType _intType;
+  /**
+   * The type representing the built-in type 'List'.
+   */
+  InterfaceType _listType;
+  /**
+   * The type representing the built-in type 'Map'.
+   */
+  InterfaceType _mapType;
+  /**
+   * The type representing the built-in type 'num'.
+   */
+  InterfaceType _numType;
+  /**
+   * The type representing the built-in type 'Object'.
+   */
+  InterfaceType _objectType;
+  /**
+   * The type representing the built-in type 'StackTrace'.
+   */
+  InterfaceType _stackTraceType;
+  /**
+   * The type representing the built-in type 'String'.
+   */
+  InterfaceType _stringType;
+  /**
+   * The type representing the built-in type 'Type'.
+   */
+  InterfaceType _typeType;
+  /**
+   * Initialize a newly created type provider to provide stand-ins for the types defined in the core
+   * library.
+   */
+  TestTypeProvider() : super() {
+  }
+  InterfaceType get boolType {
+    if (_boolType == null) {
+      _boolType = ElementFactory.classElement2("bool", []).type;
+    }
+    return _boolType;
+  }
+  Type2 get bottomType {
+    if (_bottomType == null) {
+      _bottomType = BottomTypeImpl.instance;
+    }
+    return _bottomType;
+  }
+  InterfaceType get doubleType {
+    if (_doubleType == null) {
+      initializeNumericTypes();
+    }
+    return _doubleType;
+  }
+  Type2 get dynamicType {
+    if (_dynamicType == null) {
+      _dynamicType = DynamicTypeImpl.instance;
+    }
+    return _dynamicType;
+  }
+  InterfaceType get functionType {
+    if (_functionType == null) {
+      _functionType = ElementFactory.classElement2("Function", []).type;
+    }
+    return _functionType;
+  }
+  InterfaceType get intType {
+    if (_intType == null) {
+      initializeNumericTypes();
+    }
+    return _intType;
+  }
+  InterfaceType get listType {
+    if (_listType == null) {
+      ClassElementImpl listElement = ElementFactory.classElement2("List", ["E"]);
+      _listType = listElement.type;
+      Type2 eType = listElement.typeVariables[0].type;
+      listElement.accessors = <PropertyAccessorElement> [ElementFactory.getterElement("last", false, eType)];
+      listElement.methods = <MethodElement> [ElementFactory.methodElement("[]", eType, [_intType]), ElementFactory.methodElement("[]=", VoidTypeImpl.instance, [_intType, eType])];
+    }
+    return _listType;
+  }
+  InterfaceType get mapType {
+    if (_mapType == null) {
+      _mapType = ElementFactory.classElement2("Map", ["K", "V"]).type;
+    }
+    return _mapType;
+  }
+  InterfaceType get numType {
+    if (_numType == null) {
+      initializeNumericTypes();
+    }
+    return _numType;
+  }
+  InterfaceType get objectType {
+    if (_objectType == null) {
+      ClassElementImpl objectElement = ElementFactory.object;
+      _objectType = objectElement.type;
+      if (objectElement.methods.length == 0) {
+        objectElement.methods = <MethodElement> [ElementFactory.methodElement("toString", stringType, []), ElementFactory.methodElement("==", _boolType, [_objectType])];
+        objectElement.accessors = <PropertyAccessorElement> [ElementFactory.getterElement("hashCode", false, intType)];
+      }
+    }
+    return _objectType;
+  }
+  InterfaceType get stackTraceType {
+    if (_stackTraceType == null) {
+      _stackTraceType = ElementFactory.classElement2("StackTrace", []).type;
+    }
+    return _stackTraceType;
+  }
+  InterfaceType get stringType {
+    if (_stringType == null) {
+      _stringType = ElementFactory.classElement2("String", []).type;
+      ClassElementImpl stringElement = _stringType.element as ClassElementImpl;
+      stringElement.accessors = <PropertyAccessorElement> [ElementFactory.getterElement("length", false, intType)];
+    }
+    return _stringType;
+  }
+  InterfaceType get typeType {
+    if (_typeType == null) {
+      _typeType = ElementFactory.classElement2("Type", []).type;
+    }
+    return _typeType;
+  }
+  /**
+   * Initialize the numeric types. They are created as a group so that we can (a) create the right
+   * hierarchy and (b) add members to them.
+   */
+  void initializeNumericTypes() {
+    ClassElementImpl numElement = ElementFactory.classElement2("num", []);
+    _numType = numElement.type;
+    ClassElementImpl intElement = ElementFactory.classElement("int", _numType, []);
+    _intType = intElement.type;
+    ClassElementImpl doubleElement = ElementFactory.classElement("double", _numType, []);
+    _doubleType = doubleElement.type;
+    boolType;
+    stringType;
+    numElement.methods = <MethodElement> [ElementFactory.methodElement("+", _numType, [_numType]), ElementFactory.methodElement("-", _numType, [_numType]), ElementFactory.methodElement("*", _numType, [_numType]), ElementFactory.methodElement("%", _numType, [_numType]), ElementFactory.methodElement("/", _doubleType, [_numType]), ElementFactory.methodElement("~/", _numType, [_numType]), ElementFactory.methodElement("-", _numType, []), ElementFactory.methodElement("remainder", _numType, [_numType]), ElementFactory.methodElement("<", _boolType, [_numType]), ElementFactory.methodElement("<=", _boolType, [_numType]), ElementFactory.methodElement(">", _boolType, [_numType]), ElementFactory.methodElement(">=", _boolType, [_numType]), ElementFactory.methodElement("isNaN", _boolType, []), ElementFactory.methodElement("isNegative", _boolType, []), ElementFactory.methodElement("isInfinite", _boolType, []), ElementFactory.methodElement("abs", _numType, []), ElementFactory.methodElement("floor", _numType, []), ElementFactory.methodElement("ceil", _numType, []), ElementFactory.methodElement("round", _numType, []), ElementFactory.methodElement("truncate", _numType, []), ElementFactory.methodElement("toInt", _intType, []), ElementFactory.methodElement("toDouble", _doubleType, []), ElementFactory.methodElement("toStringAsFixed", _stringType, [_intType]), ElementFactory.methodElement("toStringAsExponential", _stringType, [_intType]), ElementFactory.methodElement("toStringAsPrecision", _stringType, [_intType]), ElementFactory.methodElement("toRadixString", _stringType, [_intType])];
+    intElement.methods = <MethodElement> [ElementFactory.methodElement("&", _intType, [_intType]), ElementFactory.methodElement("|", _intType, [_intType]), ElementFactory.methodElement("^", _intType, [_intType]), ElementFactory.methodElement("~", _intType, []), ElementFactory.methodElement("<<", _intType, [_intType]), ElementFactory.methodElement(">>", _intType, [_intType]), ElementFactory.methodElement("-", _intType, []), ElementFactory.methodElement("abs", _intType, []), ElementFactory.methodElement("round", _intType, []), ElementFactory.methodElement("floor", _intType, []), ElementFactory.methodElement("ceil", _intType, []), ElementFactory.methodElement("truncate", _intType, []), ElementFactory.methodElement("toString", _stringType, [])];
+    List<FieldElement> fields = <FieldElement> [ElementFactory.fieldElement("NAN", true, false, true, _doubleType), ElementFactory.fieldElement("INFINITY", true, false, true, _doubleType), ElementFactory.fieldElement("NEGATIVE_INFINITY", true, false, true, _doubleType), ElementFactory.fieldElement("MIN_POSITIVE", true, false, true, _doubleType), ElementFactory.fieldElement("MAX_FINITE", true, false, true, _doubleType)];
+    doubleElement.fields = fields;
+    int fieldCount = fields.length;
+    List<PropertyAccessorElement> accessors = new List<PropertyAccessorElement>(fieldCount);
+    for (int i = 0; i < fieldCount; i++) {
+      accessors[i] = fields[i].getter;
+    }
+    doubleElement.accessors = accessors;
+    doubleElement.methods = <MethodElement> [ElementFactory.methodElement("remainder", _doubleType, [_numType]), ElementFactory.methodElement("+", _doubleType, [_numType]), ElementFactory.methodElement("-", _doubleType, [_numType]), ElementFactory.methodElement("*", _doubleType, [_numType]), ElementFactory.methodElement("%", _doubleType, [_numType]), ElementFactory.methodElement("/", _doubleType, [_numType]), ElementFactory.methodElement("~/", _doubleType, [_numType]), ElementFactory.methodElement("-", _doubleType, []), ElementFactory.methodElement("abs", _doubleType, []), ElementFactory.methodElement("round", _doubleType, []), ElementFactory.methodElement("floor", _doubleType, []), ElementFactory.methodElement("ceil", _doubleType, []), ElementFactory.methodElement("truncate", _doubleType, []), ElementFactory.methodElement("toString", _stringType, [])];
+  }
+}
+class LibraryImportScopeTest extends ResolverTestCase {
+  void test_conflictingImports() {
+    AnalysisContext context = new AnalysisContextImpl();
+    String typeNameA = "A";
+    String typeNameB = "B";
+    String typeNameC = "C";
+    ClassElement typeA = new ClassElementImpl(ASTFactory.identifier2(typeNameA));
+    ClassElement typeB1 = new ClassElementImpl(ASTFactory.identifier2(typeNameB));
+    ClassElement typeB2 = new ClassElementImpl(ASTFactory.identifier2(typeNameB));
+    ClassElement typeC = new ClassElementImpl(ASTFactory.identifier2(typeNameC));
+    LibraryElement importedLibrary1 = createTestLibrary2(context, "imported1", []);
+    ((importedLibrary1.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [typeA, typeB1];
+    ImportElementImpl import1 = new ImportElementImpl();
+    import1.importedLibrary = importedLibrary1;
+    LibraryElement importedLibrary2 = createTestLibrary2(context, "imported2", []);
+    ((importedLibrary2.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [typeB2, typeC];
+    ImportElementImpl import2 = new ImportElementImpl();
+    import2.importedLibrary = importedLibrary2;
+    LibraryElementImpl importingLibrary = createTestLibrary2(context, "importing", []);
+    importingLibrary.imports = <ImportElement> [import1, import2];
+    GatheringErrorListener errorListener = new GatheringErrorListener();
+    Scope scope = new LibraryImportScope(importingLibrary, errorListener);
+    JUnitTestCase.assertEquals(typeA, scope.lookup3(typeNameA, importingLibrary));
+    errorListener.assertNoErrors();
+    JUnitTestCase.assertEquals(typeC, scope.lookup3(typeNameC, importingLibrary));
+    errorListener.assertNoErrors();
+    Element element = scope.lookup3(typeNameB, importingLibrary);
+    errorListener.assertNoErrors();
+    EngineTestCase.assertInstanceOf(MultiplyDefinedElement, element);
+    List<Element> conflictingElements2 = ((element as MultiplyDefinedElement)).conflictingElements;
+    JUnitTestCase.assertEquals(typeB1, conflictingElements2[0]);
+    JUnitTestCase.assertEquals(typeB2, conflictingElements2[1]);
+    JUnitTestCase.assertEquals(2, conflictingElements2.length);
+  }
+  void test_creation_empty() {
+    LibraryElement definingLibrary = createTestLibrary();
+    GatheringErrorListener errorListener = new GatheringErrorListener();
+    new LibraryImportScope(definingLibrary, errorListener);
+  }
+  void test_creation_nonEmpty() {
+    AnalysisContext context = new AnalysisContextImpl();
+    String importedTypeName = "A";
+    ClassElement importedType = new ClassElementImpl(ASTFactory.identifier2(importedTypeName));
+    LibraryElement importedLibrary = createTestLibrary2(context, "imported", []);
+    ((importedLibrary.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [importedType];
+    LibraryElementImpl definingLibrary = createTestLibrary2(context, "importing", []);
+    ImportElementImpl importElement = new ImportElementImpl();
+    importElement.importedLibrary = importedLibrary;
+    definingLibrary.imports = <ImportElement> [importElement];
+    GatheringErrorListener errorListener = new GatheringErrorListener();
+    Scope scope = new LibraryImportScope(definingLibrary, errorListener);
+    JUnitTestCase.assertEquals(importedType, scope.lookup3(importedTypeName, definingLibrary));
+  }
+  void test_getDefiningLibrary() {
+    LibraryElement definingLibrary = createTestLibrary();
+    GatheringErrorListener errorListener = new GatheringErrorListener();
+    Scope scope = new LibraryImportScope(definingLibrary, errorListener);
+    JUnitTestCase.assertEquals(definingLibrary, scope.definingLibrary);
+  }
+  void test_getErrorListener() {
+    LibraryElement definingLibrary = createTestLibrary();
+    GatheringErrorListener errorListener = new GatheringErrorListener();
+    Scope scope = new LibraryImportScope(definingLibrary, errorListener);
+    JUnitTestCase.assertEquals(errorListener, scope.errorListener);
+  }
+  static dartSuite() {
+    _ut.group('LibraryImportScopeTest', () {
+      _ut.test('test_conflictingImports', () {
+        final __test = new LibraryImportScopeTest();
+        runJUnitTest(__test, __test.test_conflictingImports);
+      });
+      _ut.test('test_creation_empty', () {
+        final __test = new LibraryImportScopeTest();
+        runJUnitTest(__test, __test.test_creation_empty);
+      });
+      _ut.test('test_creation_nonEmpty', () {
+        final __test = new LibraryImportScopeTest();
+        runJUnitTest(__test, __test.test_creation_nonEmpty);
+      });
+      _ut.test('test_getDefiningLibrary', () {
+        final __test = new LibraryImportScopeTest();
+        runJUnitTest(__test, __test.test_getDefiningLibrary);
+      });
+      _ut.test('test_getErrorListener', () {
+        final __test = new LibraryImportScopeTest();
+        runJUnitTest(__test, __test.test_getErrorListener);
+      });
+    });
+  }
+}
+/**
+ * Instances of the class {@code ResolutionVerifier} verify that all of the nodes in an AST
+ * structure that should have been resolved were resolved.
+ */
+class ResolutionVerifier extends RecursiveASTVisitor<Object> {
+  /**
+   * A set containing nodes that are known to not be resolvable and should therefore not cause the
+   * test to fail.
+   */
+  Set<ASTNode> _knownExceptions;
+  /**
+   * A list containing all of the AST nodes that were not resolved.
+   */
+  List<ASTNode> _unresolvedNodes = new List<ASTNode>();
+  /**
+   * A list containing all of the AST nodes that were resolved to an element of the wrong type.
+   */
+  List<ASTNode> _wrongTypedNodes = new List<ASTNode>();
+  /**
+   * Initialize a newly created verifier to verify that all of the nodes in the visited AST
+   * structures that are expected to have been resolved have an element associated with them.
+   */
+  ResolutionVerifier() {
+    _jtd_constructor_317_impl();
+  }
+  _jtd_constructor_317_impl() {
+    _jtd_constructor_318_impl(null);
+  }
+  /**
+   * Initialize a newly created verifier to verify that all of the identifiers in the visited AST
+   * structures that are expected to have been resolved have an element associated with them. Nodes
+   * in the set of known exceptions are not expected to have been resolved, even if they normally
+   * would have been expected to have been resolved.
+   * @param knownExceptions a set containing nodes that are known to not be resolvable and should
+   * therefore not cause the test to fail
+   */
+  ResolutionVerifier.con1(Set<ASTNode> knownExceptions2) {
+    _jtd_constructor_318_impl(knownExceptions2);
+  }
+  _jtd_constructor_318_impl(Set<ASTNode> knownExceptions2) {
+    this._knownExceptions = knownExceptions2;
+  }
+  /**
+   * Assert that all of the visited identifiers were resolved.
+   */
+  void assertResolved() {
+    if (!_unresolvedNodes.isEmpty || !_wrongTypedNodes.isEmpty) {
+      PrintStringWriter writer = new PrintStringWriter();
+      if (!_unresolvedNodes.isEmpty) {
+        writer.print("Failed to resolve ");
+        writer.print(_unresolvedNodes.length);
+        writer.printlnObject(" nodes:");
+        printNodes(writer, _unresolvedNodes);
+      }
+      if (!_wrongTypedNodes.isEmpty) {
+        writer.print("Resolved ");
+        writer.print(_wrongTypedNodes.length);
+        writer.printlnObject(" to the wrong type of element:");
+        printNodes(writer, _wrongTypedNodes);
+      }
+      JUnitTestCase.fail(writer.toString());
+    }
+  }
+  Object visitBinaryExpression(BinaryExpression node) {
+    node.visitChildren(this);
+    if (!node.operator.isUserDefinableOperator()) {
+      return null;
+    }
+    return checkResolved2(node, node.element, MethodElement);
+  }
+  Object visitCompilationUnit(CompilationUnit node) {
+    node.visitChildren(this);
+    return checkResolved2(node, node.element, CompilationUnitElement);
+  }
+  Object visitExportDirective(ExportDirective node) => checkResolved2(node, node.element, ExportElement);
+  Object visitFunctionDeclaration(FunctionDeclaration node) {
+    node.visitChildren(this);
+    if (node.element is LibraryElement) {
+      _wrongTypedNodes.add(node);
+    }
+    return null;
+  }
+  Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    node.visitChildren(this);
+    return checkResolved2(node, node.element, FunctionElement);
+  }
+  Object visitImportDirective(ImportDirective node) {
+    checkResolved2(node, node.element, ImportElement);
+    SimpleIdentifier prefix10 = node.prefix;
+    if (prefix10 == null) {
+      return null;
+    }
+    return checkResolved2(prefix10, prefix10.element, PrefixElement);
+  }
+  Object visitIndexExpression(IndexExpression node) {
+    node.visitChildren(this);
+    return checkResolved2(node, node.element, MethodElement);
+  }
+  Object visitLibraryDirective(LibraryDirective node) => checkResolved2(node, node.element, LibraryElement);
+  Object visitPartDirective(PartDirective node) => checkResolved2(node, node.element, CompilationUnitElement);
+  Object visitPartOfDirective(PartOfDirective node) => checkResolved2(node, node.element, LibraryElement);
+  Object visitPostfixExpression(PostfixExpression node) {
+    node.visitChildren(this);
+    if (!node.operator.isUserDefinableOperator()) {
+      return null;
+    }
+    return checkResolved2(node, node.element, MethodElement);
+  }
+  Object visitPrefixExpression(PrefixExpression node) {
+    node.visitChildren(this);
+    if (!node.operator.isUserDefinableOperator()) {
+      return null;
+    }
+    return checkResolved2(node, node.element, MethodElement);
+  }
+  Object visitSimpleIdentifier(SimpleIdentifier node) {
+    if (node.name == "void") {
+      return null;
+    }
+    return checkResolved(node, node.element);
+  }
+  Object checkResolved(ASTNode node, Element element) => checkResolved2(node, element, null);
+  Object checkResolved2(ASTNode node, Element element, Type expectedClass) {
+    if (element == null) {
+      if (node.parent is CommentReference) {
+        return null;
+      }
+      if (_knownExceptions == null || !_knownExceptions.contains(node)) {
+        _unresolvedNodes.add(node);
+      }
+    } else if (expectedClass != null) {
+      if (!isInstanceOf(element, expectedClass)) {
+        _wrongTypedNodes.add(node);
+      }
+    }
+    return null;
+  }
+  String getFileName(ASTNode node) {
+    if (node != null) {
+      ASTNode root2 = node.root;
+      if (root2 is CompilationUnit) {
+        CompilationUnit rootCU = (root2 as CompilationUnit);
+        if (rootCU.element != null) {
+          return rootCU.element.source.fullName;
+        } else {
+          return "<unknown file- CompilationUnit.getElement() returned null>";
+        }
+      } else {
+        return "<unknown file- CompilationUnit.getRoot() is not a CompilationUnit>";
+      }
+    }
+    return "<unknown file- ASTNode is null>";
+  }
+  void printNodes(PrintStringWriter writer, List<ASTNode> nodes) {
+    for (ASTNode identifier in nodes) {
+      writer.print("  ");
+      writer.print(identifier.toString());
+      writer.print(" (");
+      writer.print(getFileName(identifier));
+      writer.print(" : ");
+      writer.print(identifier.offset);
+      writer.printlnObject(")");
+    }
+  }
+}
+class LibraryScopeTest extends ResolverTestCase {
+  void test_creation_empty() {
+    LibraryElement definingLibrary = createTestLibrary();
+    GatheringErrorListener errorListener = new GatheringErrorListener();
+    new LibraryScope(definingLibrary, errorListener);
+  }
+  void test_creation_nonEmpty() {
+    AnalysisContext context = new AnalysisContextImpl();
+    String importedTypeName = "A";
+    ClassElement importedType = new ClassElementImpl(ASTFactory.identifier2(importedTypeName));
+    LibraryElement importedLibrary = createTestLibrary2(context, "imported", []);
+    ((importedLibrary.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [importedType];
+    LibraryElementImpl definingLibrary = createTestLibrary2(context, "importing", []);
+    ImportElementImpl importElement = new ImportElementImpl();
+    importElement.importedLibrary = importedLibrary;
+    definingLibrary.imports = <ImportElement> [importElement];
+    GatheringErrorListener errorListener = new GatheringErrorListener();
+    Scope scope = new LibraryScope(definingLibrary, errorListener);
+    JUnitTestCase.assertEquals(importedType, scope.lookup3(importedTypeName, definingLibrary));
+  }
+  void test_getDefiningLibrary() {
+    LibraryElement definingLibrary = createTestLibrary();
+    GatheringErrorListener errorListener = new GatheringErrorListener();
+    Scope scope = new LibraryScope(definingLibrary, errorListener);
+    JUnitTestCase.assertEquals(definingLibrary, scope.definingLibrary);
+  }
+  void test_getErrorListener() {
+    LibraryElement definingLibrary = createTestLibrary();
+    GatheringErrorListener errorListener = new GatheringErrorListener();
+    Scope scope = new LibraryScope(definingLibrary, errorListener);
+    JUnitTestCase.assertEquals(errorListener, scope.errorListener);
+  }
+  static dartSuite() {
+    _ut.group('LibraryScopeTest', () {
+      _ut.test('test_creation_empty', () {
+        final __test = new LibraryScopeTest();
+        runJUnitTest(__test, __test.test_creation_empty);
+      });
+      _ut.test('test_creation_nonEmpty', () {
+        final __test = new LibraryScopeTest();
+        runJUnitTest(__test, __test.test_creation_nonEmpty);
+      });
+      _ut.test('test_getDefiningLibrary', () {
+        final __test = new LibraryScopeTest();
+        runJUnitTest(__test, __test.test_getDefiningLibrary);
+      });
+      _ut.test('test_getErrorListener', () {
+        final __test = new LibraryScopeTest();
+        runJUnitTest(__test, __test.test_getErrorListener);
+      });
+    });
+  }
+}
+class StaticTypeAnalyzerTest extends EngineTestCase {
+  /**
+   * The error listener to which errors will be reported.
+   */
+  GatheringErrorListener _listener;
+  /**
+   * The analyzer being used to analyze the test cases.
+   */
+  StaticTypeAnalyzer _analyzer;
+  /**
+   * The type provider used to access the types.
+   */
+  TestTypeProvider _typeProvider;
+  void fail_visitFunctionExpressionInvocation() {
+    JUnitTestCase.fail("Not yet tested");
+    _listener.assertNoErrors();
+  }
+  void fail_visitIndexExpression_typeParameters() {
+    InterfaceType intType6 = _typeProvider.intType;
+    InterfaceType listType2 = _typeProvider.listType;
+    MethodElement methodElement = getMethod(listType2, "[]");
+    SimpleIdentifier identifier = ASTFactory.identifier2("list");
+    identifier.staticType = listType2.substitute5(<Type2> [intType6]);
+    IndexExpression indexExpression2 = ASTFactory.indexExpression(identifier, ASTFactory.integer(0));
+    indexExpression2.element = methodElement;
+    JUnitTestCase.assertSame(intType6, analyze(indexExpression2));
+    _listener.assertNoErrors();
+  }
+  void fail_visitMethodInvocation() {
+    JUnitTestCase.fail("Not yet tested");
+    _listener.assertNoErrors();
+  }
+  void fail_visitSimpleIdentifier() {
+    JUnitTestCase.fail("Not yet tested");
+    _listener.assertNoErrors();
+  }
+  void setUp() {
+    _listener = new GatheringErrorListener();
+    _typeProvider = new TestTypeProvider();
+    _analyzer = createAnalyzer();
+  }
+  void test_visitAdjacentStrings() {
+    Expression node = ASTFactory.adjacentStrings([resolvedString("a"), resolvedString("b")]);
+    JUnitTestCase.assertSame(_typeProvider.stringType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitArgumentDefinitionTest() {
+    Expression node = ASTFactory.argumentDefinitionTest("p");
+    JUnitTestCase.assertSame(_typeProvider.boolType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitAsExpression() {
+    ClassElement superclass = ElementFactory.classElement2("A", []);
+    InterfaceType superclassType = superclass.type;
+    ClassElement subclass = ElementFactory.classElement("B", superclassType, []);
+    Expression node = ASTFactory.asExpression(ASTFactory.thisExpression(), ASTFactory.typeName(subclass, []));
+    JUnitTestCase.assertSame(subclass.type, analyze2(node, superclassType));
+    _listener.assertNoErrors();
+  }
+  void test_visitAssignmentExpression_compound() {
+    InterfaceType numType6 = _typeProvider.numType;
+    SimpleIdentifier identifier = resolvedVariable(_typeProvider.intType, "i");
+    AssignmentExpression node = ASTFactory.assignmentExpression(identifier, TokenType.PLUS_EQ, resolvedInteger(1));
+    node.element = getMethod(numType6, "+");
+    JUnitTestCase.assertSame(numType6, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitAssignmentExpression_simple() {
+    InterfaceType intType7 = _typeProvider.intType;
+    Expression node = ASTFactory.assignmentExpression(resolvedVariable(intType7, "i"), TokenType.EQ, resolvedInteger(0));
+    JUnitTestCase.assertSame(intType7, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitBinaryExpression_equals() {
+    Expression node = ASTFactory.binaryExpression(resolvedInteger(2), TokenType.EQ_EQ, resolvedInteger(3));
+    JUnitTestCase.assertSame(_typeProvider.boolType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitBinaryExpression_logicalAnd() {
+    Expression node = ASTFactory.binaryExpression(ASTFactory.booleanLiteral(false), TokenType.AMPERSAND_AMPERSAND, ASTFactory.booleanLiteral(true));
+    JUnitTestCase.assertSame(_typeProvider.boolType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitBinaryExpression_logicalOr() {
+    Expression node = ASTFactory.binaryExpression(ASTFactory.booleanLiteral(false), TokenType.BAR_BAR, ASTFactory.booleanLiteral(true));
+    JUnitTestCase.assertSame(_typeProvider.boolType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitBinaryExpression_notEquals() {
+    Expression node = ASTFactory.binaryExpression(resolvedInteger(2), TokenType.BANG_EQ, resolvedInteger(3));
+    JUnitTestCase.assertSame(_typeProvider.boolType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitBinaryExpression_plus() {
+    BinaryExpression node = ASTFactory.binaryExpression(resolvedInteger(2), TokenType.PLUS, resolvedInteger(2));
+    node.element = getMethod(_typeProvider.numType, "+");
+    JUnitTestCase.assertSame(_typeProvider.numType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitBooleanLiteral_false() {
+    Expression node = ASTFactory.booleanLiteral(false);
+    JUnitTestCase.assertSame(_typeProvider.boolType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitBooleanLiteral_true() {
+    Expression node = ASTFactory.booleanLiteral(true);
+    JUnitTestCase.assertSame(_typeProvider.boolType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitCascadeExpression() {
+    Expression node = ASTFactory.cascadeExpression(resolvedString("a"), [ASTFactory.propertyAccess2(null, "length")]);
+    JUnitTestCase.assertSame(_typeProvider.stringType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitConditionalExpression_differentTypes() {
+    Expression node = ASTFactory.conditionalExpression(ASTFactory.booleanLiteral(true), resolvedDouble(1.0), resolvedInteger(0));
+    JUnitTestCase.assertSame(_typeProvider.numType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitConditionalExpression_sameTypes() {
+    Expression node = ASTFactory.conditionalExpression(ASTFactory.booleanLiteral(true), resolvedInteger(1), resolvedInteger(0));
+    JUnitTestCase.assertSame(_typeProvider.intType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitDoubleLiteral() {
+    Expression node = ASTFactory.doubleLiteral(4.33);
+    JUnitTestCase.assertSame(_typeProvider.doubleType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitFunctionExpression_named_block() {
+    Type2 dynamicType3 = _typeProvider.dynamicType;
+    FormalParameter p1 = ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter3("p1"), resolvedInteger(0));
+    setType(p1, dynamicType3);
+    FormalParameter p2 = ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter3("p2"), resolvedInteger(0));
+    setType(p2, dynamicType3);
+    FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p1, p2]), ASTFactory.blockFunctionBody([]));
+    analyze3(p1);
+    analyze3(p2);
+    Type2 resultType = analyze(node);
+    Map<String, Type2> expectedNamedTypes = new Map<String, Type2>();
+    expectedNamedTypes["p1"] = dynamicType3;
+    expectedNamedTypes["p2"] = dynamicType3;
+    assertFunctionType(dynamicType3, null, null, expectedNamedTypes, resultType);
+    _listener.assertNoErrors();
+  }
+  void test_visitFunctionExpression_named_expression() {
+    Type2 dynamicType4 = _typeProvider.dynamicType;
+    FormalParameter p = ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter3("p"), resolvedInteger(0));
+    setType(p, dynamicType4);
+    FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p]), ASTFactory.expressionFunctionBody(resolvedInteger(0)));
+    analyze3(p);
+    Type2 resultType = analyze(node);
+    Map<String, Type2> expectedNamedTypes = new Map<String, Type2>();
+    expectedNamedTypes["p"] = dynamicType4;
+    assertFunctionType(_typeProvider.intType, null, null, expectedNamedTypes, resultType);
+    _listener.assertNoErrors();
+  }
+  void test_visitFunctionExpression_normal_block() {
+    Type2 dynamicType5 = _typeProvider.dynamicType;
+    FormalParameter p1 = ASTFactory.simpleFormalParameter3("p1");
+    setType(p1, dynamicType5);
+    FormalParameter p2 = ASTFactory.simpleFormalParameter3("p2");
+    setType(p2, dynamicType5);
+    FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p1, p2]), ASTFactory.blockFunctionBody([]));
+    analyze3(p1);
+    analyze3(p2);
+    Type2 resultType = analyze(node);
+    assertFunctionType(dynamicType5, <Type2> [dynamicType5, dynamicType5], null, null, resultType);
+    _listener.assertNoErrors();
+  }
+  void test_visitFunctionExpression_normal_expression() {
+    Type2 dynamicType6 = _typeProvider.dynamicType;
+    FormalParameter p = ASTFactory.simpleFormalParameter3("p");
+    setType(p, dynamicType6);
+    FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p]), ASTFactory.expressionFunctionBody(resolvedInteger(0)));
+    analyze3(p);
+    Type2 resultType = analyze(node);
+    assertFunctionType(_typeProvider.intType, <Type2> [dynamicType6], null, null, resultType);
+    _listener.assertNoErrors();
+  }
+  void test_visitFunctionExpression_normalAndNamed_block() {
+    Type2 dynamicType7 = _typeProvider.dynamicType;
+    FormalParameter p1 = ASTFactory.simpleFormalParameter3("p1");
+    setType(p1, dynamicType7);
+    FormalParameter p2 = ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter3("p2"), resolvedInteger(0));
+    setType(p2, dynamicType7);
+    FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p1, p2]), ASTFactory.blockFunctionBody([]));
+    analyze3(p2);
+    Type2 resultType = analyze(node);
+    Map<String, Type2> expectedNamedTypes = new Map<String, Type2>();
+    expectedNamedTypes["p2"] = dynamicType7;
+    assertFunctionType(dynamicType7, <Type2> [dynamicType7], null, expectedNamedTypes, resultType);
+    _listener.assertNoErrors();
+  }
+  void test_visitFunctionExpression_normalAndNamed_expression() {
+    Type2 dynamicType8 = _typeProvider.dynamicType;
+    FormalParameter p1 = ASTFactory.simpleFormalParameter3("p1");
+    setType(p1, dynamicType8);
+    FormalParameter p2 = ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter3("p2"), resolvedInteger(0));
+    setType(p2, dynamicType8);
+    FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p1, p2]), ASTFactory.expressionFunctionBody(resolvedInteger(0)));
+    analyze3(p2);
+    Type2 resultType = analyze(node);
+    Map<String, Type2> expectedNamedTypes = new Map<String, Type2>();
+    expectedNamedTypes["p2"] = dynamicType8;
+    assertFunctionType(_typeProvider.intType, <Type2> [dynamicType8], null, expectedNamedTypes, resultType);
+    _listener.assertNoErrors();
+  }
+  void test_visitFunctionExpression_normalAndPositional_block() {
+    Type2 dynamicType9 = _typeProvider.dynamicType;
+    FormalParameter p1 = ASTFactory.simpleFormalParameter3("p1");
+    setType(p1, dynamicType9);
+    FormalParameter p2 = ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter3("p2"), resolvedInteger(0));
+    setType(p2, dynamicType9);
+    FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p1, p2]), ASTFactory.blockFunctionBody([]));
+    analyze3(p1);
+    analyze3(p2);
+    Type2 resultType = analyze(node);
+    assertFunctionType(dynamicType9, <Type2> [dynamicType9], <Type2> [dynamicType9], null, resultType);
+    _listener.assertNoErrors();
+  }
+  void test_visitFunctionExpression_normalAndPositional_expression() {
+    Type2 dynamicType10 = _typeProvider.dynamicType;
+    FormalParameter p1 = ASTFactory.simpleFormalParameter3("p1");
+    setType(p1, dynamicType10);
+    FormalParameter p2 = ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter3("p2"), resolvedInteger(0));
+    setType(p2, dynamicType10);
+    FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p1, p2]), ASTFactory.expressionFunctionBody(resolvedInteger(0)));
+    analyze3(p1);
+    analyze3(p2);
+    Type2 resultType = analyze(node);
+    assertFunctionType(_typeProvider.intType, <Type2> [dynamicType10], <Type2> [dynamicType10], null, resultType);
+    _listener.assertNoErrors();
+  }
+  void test_visitFunctionExpression_positional_block() {
+    Type2 dynamicType11 = _typeProvider.dynamicType;
+    FormalParameter p1 = ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter3("p1"), resolvedInteger(0));
+    setType(p1, dynamicType11);
+    FormalParameter p2 = ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter3("p2"), resolvedInteger(0));
+    setType(p2, dynamicType11);
+    FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p1, p2]), ASTFactory.blockFunctionBody([]));
+    analyze3(p1);
+    analyze3(p2);
+    Type2 resultType = analyze(node);
+    assertFunctionType(dynamicType11, null, <Type2> [dynamicType11, dynamicType11], null, resultType);
+    _listener.assertNoErrors();
+  }
+  void test_visitFunctionExpression_positional_expression() {
+    Type2 dynamicType12 = _typeProvider.dynamicType;
+    FormalParameter p = ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter3("p"), resolvedInteger(0));
+    setType(p, dynamicType12);
+    FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p]), ASTFactory.expressionFunctionBody(resolvedInteger(0)));
+    analyze3(p);
+    Type2 resultType = analyze(node);
+    assertFunctionType(_typeProvider.intType, null, <Type2> [dynamicType12], null, resultType);
+    _listener.assertNoErrors();
+  }
+  void test_visitIndexExpression_getter() {
+    InterfaceType listType3 = _typeProvider.listType;
+    SimpleIdentifier identifier = resolvedVariable(listType3, "a");
+    IndexExpression node = ASTFactory.indexExpression(identifier, resolvedInteger(2));
+    node.element = listType3.element.methods[0];
+    JUnitTestCase.assertSame(listType3.typeArguments[0], analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitIndexExpression_setter() {
+    InterfaceType listType4 = _typeProvider.listType;
+    SimpleIdentifier identifier = resolvedVariable(listType4, "a");
+    IndexExpression node = ASTFactory.indexExpression(identifier, resolvedInteger(2));
+    node.element = listType4.element.methods[1];
+    ASTFactory.assignmentExpression(node, TokenType.EQ, ASTFactory.integer(0));
+    JUnitTestCase.assertSame(listType4.typeArguments[0], analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitInstanceCreationExpression_named() {
+    ClassElement classElement = ElementFactory.classElement2("C", []);
+    String constructorName = "m";
+    ConstructorElementImpl constructor = ElementFactory.constructorElement(constructorName);
+    FunctionTypeImpl constructorType = new FunctionTypeImpl.con1(constructor);
+    constructorType.returnType = classElement.type;
+    constructor.type = constructorType;
+    InstanceCreationExpression node = ASTFactory.instanceCreationExpression2(null, ASTFactory.typeName(classElement, []), [ASTFactory.identifier2(constructorName)]);
+    node.element = constructor;
+    JUnitTestCase.assertSame(classElement.type, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitInstanceCreationExpression_typeParameters() {
+    ClassElementImpl elementC = ElementFactory.classElement2("C", ["E"]);
+    ClassElementImpl elementI = ElementFactory.classElement2("I", []);
+    ConstructorElementImpl constructor = ElementFactory.constructorElement(null);
+    elementC.constructors = <ConstructorElement> [constructor];
+    FunctionTypeImpl constructorType = new FunctionTypeImpl.con1(constructor);
+    constructorType.returnType = elementC.type;
+    constructor.type = constructorType;
+    TypeName typeName4 = ASTFactory.typeName(elementC, [ASTFactory.typeName(elementI, [])]);
+    typeName4.type = elementC.type.substitute5(<Type2> [elementI.type]);
+    InstanceCreationExpression node = ASTFactory.instanceCreationExpression2(null, typeName4, []);
+    node.element = constructor;
+    InterfaceType interfaceType = analyze(node) as InterfaceType;
+    List<Type2> typeArgs = interfaceType.typeArguments;
+    JUnitTestCase.assertEquals(1, typeArgs.length);
+    JUnitTestCase.assertEquals(elementI.type, typeArgs[0]);
+    _listener.assertNoErrors();
+  }
+  void test_visitInstanceCreationExpression_unnamed() {
+    ClassElement classElement = ElementFactory.classElement2("C", []);
+    ConstructorElementImpl constructor = ElementFactory.constructorElement(null);
+    FunctionTypeImpl constructorType = new FunctionTypeImpl.con1(constructor);
+    constructorType.returnType = classElement.type;
+    constructor.type = constructorType;
+    InstanceCreationExpression node = ASTFactory.instanceCreationExpression2(null, ASTFactory.typeName(classElement, []), []);
+    node.element = constructor;
+    JUnitTestCase.assertSame(classElement.type, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitIntegerLiteral() {
+    Expression node = resolvedInteger(42);
+    JUnitTestCase.assertSame(_typeProvider.intType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitIsExpression_negated() {
+    Expression node = ASTFactory.isExpression(resolvedString("a"), true, ASTFactory.typeName3("String", []));
+    JUnitTestCase.assertSame(_typeProvider.boolType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitIsExpression_notNegated() {
+    Expression node = ASTFactory.isExpression(resolvedString("a"), false, ASTFactory.typeName3("String", []));
+    JUnitTestCase.assertSame(_typeProvider.boolType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitListLiteral_empty() {
+    Expression node = ASTFactory.listLiteral([]);
+    Type2 resultType = analyze(node);
+    assertType2(_typeProvider.listType.substitute5(<Type2> [_typeProvider.dynamicType]), resultType);
+    _listener.assertNoErrors();
+  }
+  void test_visitListLiteral_nonEmpty() {
+    Expression node = ASTFactory.listLiteral([resolvedInteger(0)]);
+    Type2 resultType = analyze(node);
+    assertType2(_typeProvider.listType.substitute5(<Type2> [_typeProvider.dynamicType]), resultType);
+    _listener.assertNoErrors();
+  }
+  void test_visitMapLiteral_empty() {
+    Expression node = ASTFactory.mapLiteral2([]);
+    Type2 resultType = analyze(node);
+    assertType2(_typeProvider.mapType.substitute5(<Type2> [_typeProvider.stringType, _typeProvider.dynamicType]), resultType);
+    _listener.assertNoErrors();
+  }
+  void test_visitMapLiteral_nonEmpty() {
+    Expression node = ASTFactory.mapLiteral2([ASTFactory.mapLiteralEntry("k", resolvedInteger(0))]);
+    Type2 resultType = analyze(node);
+    assertType2(_typeProvider.mapType.substitute5(<Type2> [_typeProvider.stringType, _typeProvider.dynamicType]), resultType);
+    _listener.assertNoErrors();
+  }
+  void test_visitNamedExpression() {
+    Expression node = ASTFactory.namedExpression("n", resolvedString("a"));
+    JUnitTestCase.assertSame(_typeProvider.stringType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitNullLiteral() {
+    Expression node = ASTFactory.nullLiteral();
+    JUnitTestCase.assertSame(_typeProvider.bottomType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitParenthesizedExpression() {
+    Expression node = ASTFactory.parenthesizedExpression(resolvedInteger(0));
+    JUnitTestCase.assertSame(_typeProvider.intType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitPostfixExpression_minusMinus() {
+    PostfixExpression node = ASTFactory.postfixExpression(resolvedInteger(0), TokenType.MINUS_MINUS);
+    JUnitTestCase.assertSame(_typeProvider.intType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitPostfixExpression_plusPlus() {
+    PostfixExpression node = ASTFactory.postfixExpression(resolvedInteger(0), TokenType.PLUS_PLUS);
+    JUnitTestCase.assertSame(_typeProvider.intType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitPrefixedIdentifier_getter() {
+    Type2 boolType2 = _typeProvider.boolType;
+    PropertyAccessorElementImpl getter = ElementFactory.getterElement("b", false, boolType2);
+    PrefixedIdentifier node = ASTFactory.identifier4("a", "b");
+    node.identifier.element = getter;
+    JUnitTestCase.assertSame(boolType2, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitPrefixedIdentifier_setter() {
+    Type2 boolType3 = _typeProvider.boolType;
+    FieldElementImpl field = ElementFactory.fieldElement("b", false, false, false, boolType3);
+    PropertyAccessorElement setter5 = field.setter;
+    PrefixedIdentifier node = ASTFactory.identifier4("a", "b");
+    node.identifier.element = setter5;
+    JUnitTestCase.assertSame(boolType3, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitPrefixedIdentifier_variable() {
+    VariableElementImpl variable = ElementFactory.localVariableElement2("b");
+    variable.type = _typeProvider.boolType;
+    PrefixedIdentifier node = ASTFactory.identifier4("a", "b");
+    node.identifier.element = variable;
+    JUnitTestCase.assertSame(_typeProvider.boolType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitPrefixExpression_bang() {
+    PrefixExpression node = ASTFactory.prefixExpression(TokenType.BANG, resolvedInteger(0));
+    JUnitTestCase.assertSame(_typeProvider.boolType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitPrefixExpression_minus() {
+    PrefixExpression node = ASTFactory.prefixExpression(TokenType.MINUS, resolvedInteger(0));
+    node.element = getMethod(_typeProvider.numType, "-");
+    JUnitTestCase.assertSame(_typeProvider.numType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitPrefixExpression_minusMinus() {
+    PrefixExpression node = ASTFactory.prefixExpression(TokenType.MINUS_MINUS, resolvedInteger(0));
+    node.element = getMethod(_typeProvider.numType, "-");
+    JUnitTestCase.assertSame(_typeProvider.numType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitPrefixExpression_not() {
+    Expression node = ASTFactory.prefixExpression(TokenType.BANG, ASTFactory.booleanLiteral(true));
+    JUnitTestCase.assertSame(_typeProvider.boolType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitPrefixExpression_plusPlus() {
+    PrefixExpression node = ASTFactory.prefixExpression(TokenType.PLUS_PLUS, resolvedInteger(0));
+    node.element = getMethod(_typeProvider.numType, "+");
+    JUnitTestCase.assertSame(_typeProvider.numType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitPrefixExpression_tilde() {
+    PrefixExpression node = ASTFactory.prefixExpression(TokenType.TILDE, resolvedInteger(0));
+    node.element = getMethod(_typeProvider.intType, "~");
+    JUnitTestCase.assertSame(_typeProvider.intType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitPropertyAccess_getter() {
+    Type2 boolType4 = _typeProvider.boolType;
+    PropertyAccessorElementImpl getter = ElementFactory.getterElement("b", false, boolType4);
+    PropertyAccess node = ASTFactory.propertyAccess2(ASTFactory.identifier2("a"), "b");
+    node.propertyName.element = getter;
+    JUnitTestCase.assertSame(boolType4, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitPropertyAccess_setter() {
+    Type2 boolType5 = _typeProvider.boolType;
+    FieldElementImpl field = ElementFactory.fieldElement("b", false, false, false, boolType5);
+    PropertyAccessorElement setter6 = field.setter;
+    PropertyAccess node = ASTFactory.propertyAccess2(ASTFactory.identifier2("a"), "b");
+    node.propertyName.element = setter6;
+    JUnitTestCase.assertSame(boolType5, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitSimpleStringLiteral() {
+    Expression node = resolvedString("a");
+    JUnitTestCase.assertSame(_typeProvider.stringType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitStringInterpolation() {
+    Expression node = ASTFactory.string([ASTFactory.interpolationString("a", "a"), ASTFactory.interpolationExpression(resolvedString("b")), ASTFactory.interpolationString("c", "c")]);
+    JUnitTestCase.assertSame(_typeProvider.stringType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitSuperExpression() {
+    InterfaceType superType = ElementFactory.classElement2("A", []).type;
+    InterfaceType thisType = ElementFactory.classElement("B", superType, []).type;
+    Expression node = ASTFactory.superExpression();
+    JUnitTestCase.assertSame(superType, analyze2(node, thisType));
+    _listener.assertNoErrors();
+  }
+  void test_visitThisExpression() {
+    InterfaceType thisType = ElementFactory.classElement("B", ElementFactory.classElement2("A", []).type, []).type;
+    Expression node = ASTFactory.thisExpression();
+    JUnitTestCase.assertSame(thisType, analyze2(node, thisType));
+    _listener.assertNoErrors();
+  }
+  void test_visitThrowExpression_withoutValue() {
+    Expression node = ASTFactory.throwExpression();
+    JUnitTestCase.assertSame(_typeProvider.bottomType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  void test_visitThrowExpression_withValue() {
+    Expression node = ASTFactory.throwExpression2(resolvedInteger(0));
+    JUnitTestCase.assertSame(_typeProvider.bottomType, analyze(node));
+    _listener.assertNoErrors();
+  }
+  /**
+   * Return the type associated with the given expression after the static type analyzer has
+   * computed a type for it.
+   * @param node the expression with which the type is associated
+   * @return the type associated with the expression
+   */
+  Type2 analyze(Expression node) => analyze2(node, null);
+  /**
+   * Return the type associated with the given expression after the static type analyzer has
+   * computed a type for it.
+   * @param node the expression with which the type is associated
+   * @param thisType the type of 'this'
+   * @return the type associated with the expression
+   */
+  Type2 analyze2(Expression node, InterfaceType thisType) {
+    try {
+      _analyzer.thisType_J2DAccessor = thisType;
+    } on JavaException catch (exception) {
+      throw new IllegalArgumentException("Could not set type of 'this'", exception);
+    }
+    node.accept(_analyzer);
+    return node.staticType;
+  }
+  /**
+   * Return the type associated with the given parameter after the static type analyzer has computed
+   * a type for it.
+   * @param node the parameter with which the type is associated
+   * @return the type associated with the parameter
+   */
+  Type2 analyze3(FormalParameter node) {
+    node.accept(_analyzer);
+    return ((node.identifier.element as ParameterElement)).type;
+  }
+  /**
+   * Assert that the actual type is a function type with the expected characteristics.
+   * @param expectedReturnType the expected return type of the function
+   * @param expectedNormalTypes the expected types of the normal parameters
+   * @param expectedOptionalTypes the expected types of the optional parameters
+   * @param expectedNamedTypes the expected types of the named parameters
+   * @param actualType the type being tested
+   */
+  void assertFunctionType(Type2 expectedReturnType, List<Type2> expectedNormalTypes, List<Type2> expectedOptionalTypes, Map<String, Type2> expectedNamedTypes, Type2 actualType) {
+    EngineTestCase.assertInstanceOf(FunctionType, actualType);
+    FunctionType functionType = actualType as FunctionType;
+    List<Type2> normalTypes = functionType.normalParameterTypes;
+    if (expectedNormalTypes == null) {
+      EngineTestCase.assertLength(0, normalTypes);
+    } else {
+      int expectedCount = expectedNormalTypes.length;
+      EngineTestCase.assertLength(expectedCount, normalTypes);
+      for (int i = 0; i < expectedCount; i++) {
+        JUnitTestCase.assertSame(expectedNormalTypes[i], normalTypes[i]);
+      }
+    }
+    List<Type2> optionalTypes = functionType.optionalParameterTypes;
+    if (expectedOptionalTypes == null) {
+      EngineTestCase.assertLength(0, optionalTypes);
+    } else {
+      int expectedCount = expectedOptionalTypes.length;
+      EngineTestCase.assertLength(expectedCount, optionalTypes);
+      for (int i = 0; i < expectedCount; i++) {
+        JUnitTestCase.assertSame(expectedOptionalTypes[i], optionalTypes[i]);
+      }
+    }
+    Map<String, Type2> namedTypes = functionType.namedParameterTypes;
+    if (expectedNamedTypes == null) {
+      EngineTestCase.assertSize2(0, namedTypes);
+    } else {
+      EngineTestCase.assertSize2(expectedNamedTypes.length, namedTypes);
+      for (MapEntry<String, Type2> entry in getMapEntrySet(expectedNamedTypes)) {
+        JUnitTestCase.assertSame(entry.getValue(), namedTypes[entry.getKey()]);
+      }
+    }
+    JUnitTestCase.assertSame(expectedReturnType, functionType.returnType);
+  }
+  void assertType(InterfaceTypeImpl expectedType, InterfaceTypeImpl actualType) {
+    JUnitTestCase.assertEquals(expectedType.name, actualType.name);
+    JUnitTestCase.assertEquals(expectedType.element, actualType.element);
+    List<Type2> expectedArguments = expectedType.typeArguments;
+    int length9 = expectedArguments.length;
+    List<Type2> actualArguments = actualType.typeArguments;
+    EngineTestCase.assertLength(length9, actualArguments);
+    for (int i = 0; i < length9; i++) {
+      assertType2(expectedArguments[i], actualArguments[i]);
+    }
+  }
+  void assertType2(Type2 expectedType, Type2 actualType) {
+    if (expectedType is InterfaceTypeImpl) {
+      EngineTestCase.assertInstanceOf(InterfaceTypeImpl, actualType);
+      assertType((expectedType as InterfaceTypeImpl), (actualType as InterfaceTypeImpl));
+    }
+  }
+  /**
+   * Create the analyzer used by the tests.
+   * @return the analyzer to be used by the tests
+   */
+  StaticTypeAnalyzer createAnalyzer() {
+    AnalysisContextImpl context = new AnalysisContextImpl();
+    context.sourceFactory = new SourceFactory.con2([new DartUriResolver(DartSdk.defaultSdk)]);
+    CompilationUnitElementImpl definingCompilationUnit = new CompilationUnitElementImpl("lib.dart");
+    LibraryElementImpl definingLibrary = new LibraryElementImpl(context, null);
+    definingLibrary.definingCompilationUnit = definingCompilationUnit;
+    Library library = new Library(context, _listener, null);
+    library.libraryElement = definingLibrary;
+    ResolverVisitor visitor = new ResolverVisitor(library, null, _typeProvider);
+    try {
+      return visitor.typeAnalyzer_J2DAccessor as StaticTypeAnalyzer;
+    } on JavaException catch (exception) {
+      throw new IllegalArgumentException("Could not create analyzer", exception);
+    }
+  }
+  /**
+   * Return an integer literal that has been resolved to the correct type.
+   * @param value the value of the literal
+   * @return an integer literal that has been resolved to the correct type
+   */
+  DoubleLiteral resolvedDouble(double value) {
+    DoubleLiteral literal = ASTFactory.doubleLiteral(value);
+    literal.staticType = _typeProvider.doubleType;
+    return literal;
+  }
+  /**
+   * Create a function expression that has an element associated with it, where the element has an
+   * incomplete type associated with it (just like the one{@link ElementBuilder#visitFunctionExpression(FunctionExpression)} would have built if we had
+   * run it).
+   * @param parameters the parameters to the function
+   * @param body the body of the function
+   * @return a resolved function expression
+   */
+  FunctionExpression resolvedFunctionExpression(FormalParameterList parameters15, FunctionBody body) {
+    for (FormalParameter parameter in parameters15.parameters) {
+      ParameterElementImpl element = new ParameterElementImpl(parameter.identifier);
+      element.parameterKind = parameter.kind;
+      element.type = _typeProvider.dynamicType;
+      parameter.identifier.element = element;
+    }
+    FunctionExpression node = ASTFactory.functionExpression2(parameters15, body);
+    FunctionElementImpl element = new FunctionElementImpl.con1(null);
+    element.type = new FunctionTypeImpl.con1(element);
+    node.element = element;
+    return node;
+  }
+  /**
+   * Return an integer literal that has been resolved to the correct type.
+   * @param value the value of the literal
+   * @return an integer literal that has been resolved to the correct type
+   */
+  IntegerLiteral resolvedInteger(int value) {
+    IntegerLiteral literal = ASTFactory.integer(value);
+    literal.staticType = _typeProvider.intType;
+    return literal;
+  }
+  /**
+   * Return a string literal that has been resolved to the correct type.
+   * @param value the value of the literal
+   * @return a string literal that has been resolved to the correct type
+   */
+  SimpleStringLiteral resolvedString(String value) {
+    SimpleStringLiteral string = ASTFactory.string2(value);
+    string.staticType = _typeProvider.stringType;
+    return string;
+  }
+  /**
+   * Return a simple identifier that has been resolved to a variable element with the given type.
+   * @param type the type of the variable being represented
+   * @param variableName the name of the variable
+   * @return a simple identifier that has been resolved to a variable element with the given type
+   */
+  SimpleIdentifier resolvedVariable(InterfaceType type37, String variableName) {
+    SimpleIdentifier identifier = ASTFactory.identifier2(variableName);
+    VariableElementImpl element = ElementFactory.localVariableElement(identifier);
+    element.type = type37;
+    identifier.element = element;
+    identifier.staticType = type37;
+    return identifier;
+  }
+  /**
+   * Set the type of the given parameter to the given type.
+   * @param parameter the parameter whose type is to be set
+   * @param type the new type of the given parameter
+   */
+  void setType(FormalParameter parameter, Type2 type38) {
+    SimpleIdentifier identifier17 = parameter.identifier;
+    Element element51 = identifier17.element;
+    if (element51 is! ParameterElement) {
+      element51 = new ParameterElementImpl(identifier17);
+      identifier17.element = element51;
+    }
+    ((element51 as ParameterElementImpl)).type = type38;
+  }
+  static dartSuite() {
+    _ut.group('StaticTypeAnalyzerTest', () {
+      _ut.test('test_visitAdjacentStrings', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitAdjacentStrings);
+      });
+      _ut.test('test_visitArgumentDefinitionTest', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitArgumentDefinitionTest);
+      });
+      _ut.test('test_visitAsExpression', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitAsExpression);
+      });
+      _ut.test('test_visitAssignmentExpression_compound', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitAssignmentExpression_compound);
+      });
+      _ut.test('test_visitAssignmentExpression_simple', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitAssignmentExpression_simple);
+      });
+      _ut.test('test_visitBinaryExpression_equals', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitBinaryExpression_equals);
+      });
+      _ut.test('test_visitBinaryExpression_logicalAnd', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitBinaryExpression_logicalAnd);
+      });
+      _ut.test('test_visitBinaryExpression_logicalOr', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitBinaryExpression_logicalOr);
+      });
+      _ut.test('test_visitBinaryExpression_notEquals', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitBinaryExpression_notEquals);
+      });
+      _ut.test('test_visitBinaryExpression_plus', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitBinaryExpression_plus);
+      });
+      _ut.test('test_visitBooleanLiteral_false', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitBooleanLiteral_false);
+      });
+      _ut.test('test_visitBooleanLiteral_true', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitBooleanLiteral_true);
+      });
+      _ut.test('test_visitCascadeExpression', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitCascadeExpression);
+      });
+      _ut.test('test_visitConditionalExpression_differentTypes', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitConditionalExpression_differentTypes);
+      });
+      _ut.test('test_visitConditionalExpression_sameTypes', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitConditionalExpression_sameTypes);
+      });
+      _ut.test('test_visitDoubleLiteral', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitDoubleLiteral);
+      });
+      _ut.test('test_visitFunctionExpression_named_block', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitFunctionExpression_named_block);
+      });
+      _ut.test('test_visitFunctionExpression_named_expression', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitFunctionExpression_named_expression);
+      });
+      _ut.test('test_visitFunctionExpression_normalAndNamed_block', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitFunctionExpression_normalAndNamed_block);
+      });
+      _ut.test('test_visitFunctionExpression_normalAndNamed_expression', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitFunctionExpression_normalAndNamed_expression);
+      });
+      _ut.test('test_visitFunctionExpression_normalAndPositional_block', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitFunctionExpression_normalAndPositional_block);
+      });
+      _ut.test('test_visitFunctionExpression_normalAndPositional_expression', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitFunctionExpression_normalAndPositional_expression);
+      });
+      _ut.test('test_visitFunctionExpression_normal_block', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitFunctionExpression_normal_block);
+      });
+      _ut.test('test_visitFunctionExpression_normal_expression', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitFunctionExpression_normal_expression);
+      });
+      _ut.test('test_visitFunctionExpression_positional_block', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitFunctionExpression_positional_block);
+      });
+      _ut.test('test_visitFunctionExpression_positional_expression', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitFunctionExpression_positional_expression);
+      });
+      _ut.test('test_visitIndexExpression_getter', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitIndexExpression_getter);
+      });
+      _ut.test('test_visitIndexExpression_setter', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitIndexExpression_setter);
+      });
+      _ut.test('test_visitInstanceCreationExpression_named', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitInstanceCreationExpression_named);
+      });
+      _ut.test('test_visitInstanceCreationExpression_typeParameters', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitInstanceCreationExpression_typeParameters);
+      });
+      _ut.test('test_visitInstanceCreationExpression_unnamed', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitInstanceCreationExpression_unnamed);
+      });
+      _ut.test('test_visitIntegerLiteral', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitIntegerLiteral);
+      });
+      _ut.test('test_visitIsExpression_negated', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitIsExpression_negated);
+      });
+      _ut.test('test_visitIsExpression_notNegated', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitIsExpression_notNegated);
+      });
+      _ut.test('test_visitListLiteral_empty', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitListLiteral_empty);
+      });
+      _ut.test('test_visitListLiteral_nonEmpty', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitListLiteral_nonEmpty);
+      });
+      _ut.test('test_visitMapLiteral_empty', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitMapLiteral_empty);
+      });
+      _ut.test('test_visitMapLiteral_nonEmpty', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitMapLiteral_nonEmpty);
+      });
+      _ut.test('test_visitNamedExpression', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitNamedExpression);
+      });
+      _ut.test('test_visitNullLiteral', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitNullLiteral);
+      });
+      _ut.test('test_visitParenthesizedExpression', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitParenthesizedExpression);
+      });
+      _ut.test('test_visitPostfixExpression_minusMinus', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitPostfixExpression_minusMinus);
+      });
+      _ut.test('test_visitPostfixExpression_plusPlus', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitPostfixExpression_plusPlus);
+      });
+      _ut.test('test_visitPrefixExpression_bang', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitPrefixExpression_bang);
+      });
+      _ut.test('test_visitPrefixExpression_minus', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitPrefixExpression_minus);
+      });
+      _ut.test('test_visitPrefixExpression_minusMinus', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitPrefixExpression_minusMinus);
+      });
+      _ut.test('test_visitPrefixExpression_not', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitPrefixExpression_not);
+      });
+      _ut.test('test_visitPrefixExpression_plusPlus', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitPrefixExpression_plusPlus);
+      });
+      _ut.test('test_visitPrefixExpression_tilde', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitPrefixExpression_tilde);
+      });
+      _ut.test('test_visitPrefixedIdentifier_getter', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitPrefixedIdentifier_getter);
+      });
+      _ut.test('test_visitPrefixedIdentifier_setter', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitPrefixedIdentifier_setter);
+      });
+      _ut.test('test_visitPrefixedIdentifier_variable', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitPrefixedIdentifier_variable);
+      });
+      _ut.test('test_visitPropertyAccess_getter', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitPropertyAccess_getter);
+      });
+      _ut.test('test_visitPropertyAccess_setter', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitPropertyAccess_setter);
+      });
+      _ut.test('test_visitSimpleStringLiteral', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitSimpleStringLiteral);
+      });
+      _ut.test('test_visitStringInterpolation', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitStringInterpolation);
+      });
+      _ut.test('test_visitSuperExpression', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitSuperExpression);
+      });
+      _ut.test('test_visitThisExpression', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitThisExpression);
+      });
+      _ut.test('test_visitThrowExpression_withValue', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitThrowExpression_withValue);
+      });
+      _ut.test('test_visitThrowExpression_withoutValue', () {
+        final __test = new StaticTypeAnalyzerTest();
+        runJUnitTest(__test, __test.test_visitThrowExpression_withoutValue);
+      });
+    });
+  }
+}
+class EnclosedScopeTest extends ResolverTestCase {
+  void test_define_duplicate() {
+    LibraryElement definingLibrary2 = createTestLibrary();
+    GatheringErrorListener errorListener2 = new GatheringErrorListener();
+    Scope rootScope = new Scope_10(definingLibrary2, errorListener2);
+    EnclosedScope scope = new EnclosedScope(rootScope);
+    VariableElement element1 = ElementFactory.localVariableElement(ASTFactory.identifier2("v1"));
+    VariableElement element2 = ElementFactory.localVariableElement(ASTFactory.identifier2("v1"));
+    scope.define(element1);
+    scope.define(element2);
+    errorListener2.assertErrors3([ErrorSeverity.ERROR]);
+  }
+  void test_define_normal() {
+    LibraryElement definingLibrary3 = createTestLibrary();
+    GatheringErrorListener errorListener3 = new GatheringErrorListener();
+    Scope rootScope = new Scope_11(definingLibrary3, errorListener3);
+    EnclosedScope outerScope = new EnclosedScope(rootScope);
+    EnclosedScope innerScope = new EnclosedScope(outerScope);
+    VariableElement element1 = ElementFactory.localVariableElement(ASTFactory.identifier2("v1"));
+    VariableElement element2 = ElementFactory.localVariableElement(ASTFactory.identifier2("v2"));
+    outerScope.define(element1);
+    innerScope.define(element2);
+    errorListener3.assertNoErrors();
+  }
+  static dartSuite() {
+    _ut.group('EnclosedScopeTest', () {
+      _ut.test('test_define_duplicate', () {
+        final __test = new EnclosedScopeTest();
+        runJUnitTest(__test, __test.test_define_duplicate);
+      });
+      _ut.test('test_define_normal', () {
+        final __test = new EnclosedScopeTest();
+        runJUnitTest(__test, __test.test_define_normal);
+      });
+    });
+  }
+}
+class Scope_10 extends Scope {
+  LibraryElement definingLibrary2;
+  GatheringErrorListener errorListener2;
+  Scope_10(this.definingLibrary2, this.errorListener2) : super();
+  LibraryElement get definingLibrary => definingLibrary2;
+  AnalysisErrorListener get errorListener => errorListener2;
+  Element lookup3(String name, LibraryElement referencingLibrary) => null;
+}
+class Scope_11 extends Scope {
+  LibraryElement definingLibrary3;
+  GatheringErrorListener errorListener3;
+  Scope_11(this.definingLibrary3, this.errorListener3) : super();
+  LibraryElement get definingLibrary => definingLibrary3;
+  AnalysisErrorListener get errorListener => errorListener3;
+  Element lookup3(String name, LibraryElement referencingLibrary) => null;
+}
+class LibraryElementBuilderTest extends EngineTestCase {
+  /**
+   * The source factory used to create {@link Source sources}.
+   */
+  SourceFactory _sourceFactory;
+  void setUp() {
+    _sourceFactory = new SourceFactory.con2([new FileUriResolver()]);
+  }
+  void test_empty() {
+    Source librarySource = addSource("/lib.dart", "library lib;");
+    LibraryElement element = buildLibrary(librarySource, []);
+    JUnitTestCase.assertNotNull(element);
+    JUnitTestCase.assertEquals("lib", element.name);
+    JUnitTestCase.assertNull(element.entryPoint);
+    EngineTestCase.assertLength(0, element.importedLibraries);
+    EngineTestCase.assertLength(0, element.imports);
+    JUnitTestCase.assertNull(element.library);
+    EngineTestCase.assertLength(0, element.prefixes);
+    EngineTestCase.assertLength(0, element.parts);
+    CompilationUnitElement unit = element.definingCompilationUnit;
+    JUnitTestCase.assertNotNull(unit);
+    JUnitTestCase.assertEquals("lib.dart", unit.name);
+    JUnitTestCase.assertEquals(element, unit.library);
+    EngineTestCase.assertLength(0, unit.accessors);
+    EngineTestCase.assertLength(0, unit.functions);
+    EngineTestCase.assertLength(0, unit.functionTypeAliases);
+    EngineTestCase.assertLength(0, unit.types);
+    EngineTestCase.assertLength(0, unit.topLevelVariables);
+  }
+  void test_invalidUri_part() {
+    Source librarySource = addSource("/lib.dart", EngineTestCase.createSource(["library lib;", "", "part '\${'a'}.dart';"]));
+    LibraryElement element = buildLibrary(librarySource, [CompileTimeErrorCode.URI_WITH_INTERPOLATION]);
+    JUnitTestCase.assertNotNull(element);
+  }
+  void test_missingLibraryDirectiveWithPart() {
+    addSource("/a.dart", EngineTestCase.createSource(["part of lib;"]));
+    Source librarySource = addSource("/lib.dart", EngineTestCase.createSource(["part 'a.dart';"]));
+    LibraryElement element = buildLibrary(librarySource, [ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART]);
+    JUnitTestCase.assertNotNull(element);
+  }
+  void test_missingPartOfDirective() {
+    addSource("/a.dart", "class A {}");
+    Source librarySource = addSource("/lib.dart", EngineTestCase.createSource(["library lib;", "", "part 'a.dart';"]));
+    LibraryElement element = buildLibrary(librarySource, [ResolverErrorCode.MISSING_PART_OF_DIRECTIVE]);
+    JUnitTestCase.assertNotNull(element);
+  }
+  void test_multipleFiles() {
+    Source librarySource = addSource("/lib.dart", EngineTestCase.createSource(["library lib;", "part 'first.dart';", "part 'second.dart';", "", "class A {}"]));
+    addSource("/first.dart", EngineTestCase.createSource(["part of lib;", "class B {}"]));
+    addSource("/second.dart", EngineTestCase.createSource(["part of lib;", "class C {}"]));
+    LibraryElement element = buildLibrary(librarySource, []);
+    JUnitTestCase.assertNotNull(element);
+    List<CompilationUnitElement> sourcedUnits = element.parts;
+    EngineTestCase.assertLength(2, sourcedUnits);
+    assertTypes(element.definingCompilationUnit, ["A"]);
+    if (sourcedUnits[0].name == "first.dart") {
+      assertTypes(sourcedUnits[0], ["B"]);
+      assertTypes(sourcedUnits[1], ["C"]);
+    } else {
+      assertTypes(sourcedUnits[0], ["C"]);
+      assertTypes(sourcedUnits[1], ["B"]);
+    }
+  }
+  void test_singleFile() {
+    Source librarySource = addSource("/lib.dart", EngineTestCase.createSource(["library lib;", "", "class A {}"]));
+    LibraryElement element = buildLibrary(librarySource, []);
+    JUnitTestCase.assertNotNull(element);
+    assertTypes(element.definingCompilationUnit, ["A"]);
+  }
+  /**
+   * Add a source file to the content provider. The file path should be absolute.
+   * @param filePath the path of the file being added
+   * @param contents the contents to be returned by the content provider for the specified file
+   * @return the source object representing the added file
+   */
+  Source addSource(String filePath, String contents) {
+    Source source = new FileBasedSource.con1(_sourceFactory, FileUtilities2.createFile(filePath));
+    _sourceFactory.setContents(source, contents);
+    return source;
+  }
+  /**
+   * Ensure that there are elements representing all of the types in the given array of type names.
+   * @param unit the compilation unit containing the types
+   * @param typeNames the names of the types that should be found
+   */
+  void assertTypes(CompilationUnitElement unit, List<String> typeNames) {
+    JUnitTestCase.assertNotNull(unit);
+    List<ClassElement> types3 = unit.types;
+    EngineTestCase.assertLength(typeNames.length, types3);
+    for (ClassElement type in types3) {
+      JUnitTestCase.assertNotNull(type);
+      String actualTypeName = type.name;
+      bool wasExpected = false;
+      for (String expectedTypeName in typeNames) {
+        if (expectedTypeName == actualTypeName) {
+          wasExpected = true;
+        }
+      }
+      if (!wasExpected) {
+        JUnitTestCase.fail("Found unexpected type ${actualTypeName}");
+      }
+    }
+  }
+  /**
+   * Build the element model for the library whose defining compilation unit has the given source.
+   * @param librarySource the source of the defining compilation unit for the library
+   * @param expectedErrorCodes the errors that are expected to be found while building the element
+   * model
+   * @return the element model that was built for the library
+   * @throws Exception if the element model could not be built
+   */
+  LibraryElement buildLibrary(Source librarySource, List<ErrorCode> expectedErrorCodes) {
+    AnalysisContextImpl context = new AnalysisContextImpl();
+    context.sourceFactory = new SourceFactory.con2([new DartUriResolver(DartSdk.defaultSdk), new FileUriResolver()]);
+    GatheringErrorListener listener = new GatheringErrorListener();
+    LibraryResolver resolver = new LibraryResolver.con2(context, listener);
+    LibraryElementBuilder builder = new LibraryElementBuilder(resolver);
+    Library library = resolver.createLibrary(librarySource) as Library;
+    LibraryElement element = builder.buildLibrary(library);
+    listener.assertErrors2(expectedErrorCodes);
+    return element;
+  }
+  static dartSuite() {
+    _ut.group('LibraryElementBuilderTest', () {
+      _ut.test('test_empty', () {
+        final __test = new LibraryElementBuilderTest();
+        runJUnitTest(__test, __test.test_empty);
+      });
+      _ut.test('test_invalidUri_part', () {
+        final __test = new LibraryElementBuilderTest();
+        runJUnitTest(__test, __test.test_invalidUri_part);
+      });
+      _ut.test('test_missingLibraryDirectiveWithPart', () {
+        final __test = new LibraryElementBuilderTest();
+        runJUnitTest(__test, __test.test_missingLibraryDirectiveWithPart);
+      });
+      _ut.test('test_missingPartOfDirective', () {
+        final __test = new LibraryElementBuilderTest();
+        runJUnitTest(__test, __test.test_missingPartOfDirective);
+      });
+      _ut.test('test_multipleFiles', () {
+        final __test = new LibraryElementBuilderTest();
+        runJUnitTest(__test, __test.test_multipleFiles);
+      });
+      _ut.test('test_singleFile', () {
+        final __test = new LibraryElementBuilderTest();
+        runJUnitTest(__test, __test.test_singleFile);
+      });
+    });
+  }
+}
+class ScopeTest extends ResolverTestCase {
+  void test_define_duplicate() {
+    LibraryElement definingLibrary = createTestLibrary();
+    GatheringErrorListener errorListener = new GatheringErrorListener();
+    ScopeTest_TestScope scope = new ScopeTest_TestScope(definingLibrary, errorListener);
+    VariableElement element1 = ElementFactory.localVariableElement(ASTFactory.identifier2("v1"));
+    VariableElement element2 = ElementFactory.localVariableElement(ASTFactory.identifier2("v1"));
+    scope.define(element1);
+    scope.define(element2);
+    errorListener.assertErrors3([ErrorSeverity.ERROR]);
+  }
+  void test_define_normal() {
+    LibraryElement definingLibrary = createTestLibrary();
+    GatheringErrorListener errorListener = new GatheringErrorListener();
+    ScopeTest_TestScope scope = new ScopeTest_TestScope(definingLibrary, errorListener);
+    VariableElement element1 = ElementFactory.localVariableElement(ASTFactory.identifier2("v1"));
+    VariableElement element2 = ElementFactory.localVariableElement(ASTFactory.identifier2("v2"));
+    scope.define(element1);
+    scope.define(element2);
+    errorListener.assertNoErrors();
+  }
+  void test_getDefiningLibrary() {
+    LibraryElement definingLibrary = createTestLibrary();
+    Scope scope = new ScopeTest_TestScope(definingLibrary, null);
+    JUnitTestCase.assertEquals(definingLibrary, scope.definingLibrary);
+  }
+  void test_getErrorListener() {
+    LibraryElement definingLibrary = new LibraryElementImpl(new AnalysisContextImpl(), ASTFactory.libraryIdentifier2(["test"]));
+    GatheringErrorListener errorListener = new GatheringErrorListener();
+    Scope scope = new ScopeTest_TestScope(definingLibrary, errorListener);
+    JUnitTestCase.assertEquals(errorListener, scope.errorListener);
+  }
+  void test_isPrivateName_nonPrivate() {
+    JUnitTestCase.assertFalse(Scope.isPrivateName("Public"));
+  }
+  void test_isPrivateName_private() {
+    JUnitTestCase.assertTrue(Scope.isPrivateName("_Private"));
+  }
+  static dartSuite() {
+    _ut.group('ScopeTest', () {
+      _ut.test('test_define_duplicate', () {
+        final __test = new ScopeTest();
+        runJUnitTest(__test, __test.test_define_duplicate);
+      });
+      _ut.test('test_define_normal', () {
+        final __test = new ScopeTest();
+        runJUnitTest(__test, __test.test_define_normal);
+      });
+      _ut.test('test_getDefiningLibrary', () {
+        final __test = new ScopeTest();
+        runJUnitTest(__test, __test.test_getDefiningLibrary);
+      });
+      _ut.test('test_getErrorListener', () {
+        final __test = new ScopeTest();
+        runJUnitTest(__test, __test.test_getErrorListener);
+      });
+      _ut.test('test_isPrivateName_nonPrivate', () {
+        final __test = new ScopeTest();
+        runJUnitTest(__test, __test.test_isPrivateName_nonPrivate);
+      });
+      _ut.test('test_isPrivateName_private', () {
+        final __test = new ScopeTest();
+        runJUnitTest(__test, __test.test_isPrivateName_private);
+      });
+    });
+  }
+}
+/**
+ * A non-abstract subclass that can be used for testing purposes.
+ */
+class ScopeTest_TestScope extends Scope {
+  /**
+   * The element representing the library in which this scope is enclosed.
+   */
+  LibraryElement _definingLibrary;
+  /**
+   * The listener that is to be informed when an error is encountered.
+   */
+  AnalysisErrorListener _errorListener;
+  ScopeTest_TestScope(LibraryElement definingLibrary, AnalysisErrorListener errorListener) {
+    this._definingLibrary = definingLibrary;
+    this._errorListener = errorListener;
+  }
+  LibraryElement get definingLibrary => _definingLibrary;
+  AnalysisErrorListener get errorListener => _errorListener;
+  Element lookup3(String name, LibraryElement referencingLibrary) => localLookup(name, referencingLibrary);
+}
+class SimpleResolverTest extends ResolverTestCase {
+  void fail_staticInvocation() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  static int get g => (a,b) => 0;", "}", "class B {", "  f() {", "    A.g(1,0);", "  }", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_argumentDefinitionTestNonParameter_formalParameter() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f(var v) {", "  return ?v;", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_argumentDefinitionTestNonParameter_namedParameter() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f({var v : 0}) {", "  return ?v;", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_argumentDefinitionTestNonParameter_optionalParameter() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f([var v]) {", "  return ?v;", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_breakWithoutLabelInSwitch() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  void m(int i) {", "    switch (i) {", "      case 0:", "        break;", "    }", "  }", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_builtInIdentifierAsType_dynamic() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() {", "  dynamic x;", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_caseExpressionTypeImplementsEquals_int() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f(int i) {", "  switch(i) {", "    case(1) : return 1;", "    default: return 0;", "  }", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_caseExpressionTypeImplementsEquals_Object() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class IntWrapper {", "  final int value;", "  const IntWrapper(this.value);", "}", "", "f(IntWrapper intWrapper) {", "  switch(intWrapper) {", "    case(const IntWrapper(1)) : return 1;", "    default: return 0;", "  }", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_caseExpressionTypeImplementsEquals_String() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f(String s) {", "  switch(s) {", "    case('1') : return 1;", "    default: return 0;", "  }", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_class_extends_implements() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A extends B implements C {}", "class B {}", "class C {}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_constConstructorWithNonFinalField_const() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  const int x;", "  const A() {}", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_constConstructorWithNonFinalField_final() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  final int x;", "  const A() {}", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_constConstructorWithNonFinalField_syntheticField() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  const A();", "  set x(value) {}", "  get x {return 0;}", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_duplicateDefinition_getter() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["bool get a => true;"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_empty() {
+    Source source = addSource("/test.dart", "");
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_forEachLoops_nonConflicting() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() {", "  List list = [1,2,3];", "  for (int x in list) {}", "  for (int x in list) {}", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_forLoops_nonConflicting() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() {", "  for (int i = 0; i < 3; i++) {", "  }", "  for (int i = 0; i < 3; i++) {", "  }", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_functionTypeAlias() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["typedef bool P(e);", "class A {", "  P p;", "  m(e) {", "    if (p(e)) {}", "  }", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_getterAndSetterWithDifferentTypes() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  int get f => 0;", "  void set f(String s) {}", "}", "g (A a) {", "  a.f = a.f.toString();", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_invalidAssignment() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() {", "  var x;", "  var y;", "  x = y;", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_invalidAssignment_toDynamic() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() {", "  var g;", "  g = () => 0;", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_invocationOfNonFunction_dynamic() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  var f;", "}", "class B extends A {", "  g() {", "    f();", "  }", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_invocationOfNonFunction_getter() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  var g;", "}", "f() {", "  A a;", "  a.g();", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_invocationOfNonFunction_localVariable() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() {", "  var g;", "  g();", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_invoke_dynamicThroughGetter() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  List get X => [() => 0];", "  m(A a) {", "    X.last();", "  }", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_isValidMixin_badSuperclass() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A extends B {}", "class B {}"]));
+    LibraryElement library = resolve(source, []);
+    JUnitTestCase.assertNotNull(library);
+    CompilationUnitElement unit = library.definingCompilationUnit;
+    JUnitTestCase.assertNotNull(unit);
+    List<ClassElement> classes = unit.types;
+    EngineTestCase.assertLength(2, classes);
+    JUnitTestCase.assertFalse(classes[0].isValidMixin());
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_isValidMixin_constructor() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  A() {}", "}"]));
+    LibraryElement library = resolve(source, []);
+    JUnitTestCase.assertNotNull(library);
+    CompilationUnitElement unit = library.definingCompilationUnit;
+    JUnitTestCase.assertNotNull(unit);
+    List<ClassElement> classes = unit.types;
+    EngineTestCase.assertLength(1, classes);
+    JUnitTestCase.assertFalse(classes[0].isValidMixin());
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_isValidMixin_super() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  toString() {", "    return super.toString();", "  }", "}"]));
+    LibraryElement library = resolve(source, []);
+    JUnitTestCase.assertNotNull(library);
+    CompilationUnitElement unit = library.definingCompilationUnit;
+    JUnitTestCase.assertNotNull(unit);
+    List<ClassElement> classes = unit.types;
+    EngineTestCase.assertLength(1, classes);
+    JUnitTestCase.assertFalse(classes[0].isValidMixin());
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_isValidMixin_valid() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {}"]));
+    LibraryElement library = resolve(source, []);
+    JUnitTestCase.assertNotNull(library);
+    CompilationUnitElement unit = library.definingCompilationUnit;
+    JUnitTestCase.assertNotNull(unit);
+    List<ClassElement> classes = unit.types;
+    EngineTestCase.assertLength(1, classes);
+    JUnitTestCase.assertTrue(classes[0].isValidMixin());
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_methodCascades() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  void m1() {}", "  void m2() {}", "  void m() {", "    A a = new A();", "    a..m1()", "     ..m2();", "  }", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_methodCascades_withSetter() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  String name;", "  void m1() {}", "  void m2() {}", "  void m() {", "    A a = new A();", "    a..m1()", "     ..name = 'name'", "     ..m2();", "  }", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_newWithAbstractClass_factory() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["abstract class A {", "  factory A() { return new B(); }", "}", "class B implements A {", "  B() {}", "}", "A f() {", "  return new A();", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_nonBoolExpression_assert_bool() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f() {", "  assert(true);", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_nonBoolExpression_assert_functionType() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["bool makeAssertion() => true;", "f() {", "  assert(makeAssertion);", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_resolveAgainstNull() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["f(var p) {", "  return null == p;", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_returnOfInvalidType_dynamic() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {", "  static void testLogicalOp() {", "    testOr(a, b, onTypeError) {", "      try {", "        return a || b;", "      } on TypeError catch (t) {", "        return onTypeError;", "      }", "    }", "  }", "}"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_returnOfInvalidType_subtype() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {}", "class B extends A {}", "A f(B b) { return b; }"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_returnOfInvalidType_supertype() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {}", "class B extends A {}", "B f(A a) { return a; }"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_typeArgumentNotMatchingBounds_const() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {}", "class B extends A {}", "class G<E extends A> {", "  const G() {}", "}", "f() { return const G<B>(); }"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_typeArgumentNotMatchingBounds_new() {
+    Source source = addSource("/test.dart", EngineTestCase.createSource(["class A {}", "class B extends A {}", "class G<E extends A> {}", "f() { return new G<B>(); }"]));
+    resolve(source, []);
+    assertNoErrors();
+    verify([source]);
+  }
+  static dartSuite() {
+    _ut.group('SimpleResolverTest', () {
+      _ut.test('test_argumentDefinitionTestNonParameter_formalParameter', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_argumentDefinitionTestNonParameter_formalParameter);
+      });
+      _ut.test('test_argumentDefinitionTestNonParameter_namedParameter', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_argumentDefinitionTestNonParameter_namedParameter);
+      });
+      _ut.test('test_argumentDefinitionTestNonParameter_optionalParameter', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_argumentDefinitionTestNonParameter_optionalParameter);
+      });
+      _ut.test('test_breakWithoutLabelInSwitch', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_breakWithoutLabelInSwitch);
+      });
+      _ut.test('test_builtInIdentifierAsType_dynamic', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_builtInIdentifierAsType_dynamic);
+      });
+      _ut.test('test_caseExpressionTypeImplementsEquals_Object', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_caseExpressionTypeImplementsEquals_Object);
+      });
+      _ut.test('test_caseExpressionTypeImplementsEquals_String', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_caseExpressionTypeImplementsEquals_String);
+      });
+      _ut.test('test_caseExpressionTypeImplementsEquals_int', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_caseExpressionTypeImplementsEquals_int);
+      });
+      _ut.test('test_class_extends_implements', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_class_extends_implements);
+      });
+      _ut.test('test_constConstructorWithNonFinalField_const', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_constConstructorWithNonFinalField_const);
+      });
+      _ut.test('test_constConstructorWithNonFinalField_final', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_constConstructorWithNonFinalField_final);
+      });
+      _ut.test('test_constConstructorWithNonFinalField_syntheticField', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_constConstructorWithNonFinalField_syntheticField);
+      });
+      _ut.test('test_duplicateDefinition_getter', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_duplicateDefinition_getter);
+      });
+      _ut.test('test_empty', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_empty);
+      });
+      _ut.test('test_forEachLoops_nonConflicting', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_forEachLoops_nonConflicting);
+      });
+      _ut.test('test_forLoops_nonConflicting', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_forLoops_nonConflicting);
+      });
+      _ut.test('test_functionTypeAlias', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_functionTypeAlias);
+      });
+      _ut.test('test_getterAndSetterWithDifferentTypes', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_getterAndSetterWithDifferentTypes);
+      });
+      _ut.test('test_invalidAssignment', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_invalidAssignment);
+      });
+      _ut.test('test_invalidAssignment_toDynamic', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_invalidAssignment_toDynamic);
+      });
+      _ut.test('test_invocationOfNonFunction_dynamic', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_invocationOfNonFunction_dynamic);
+      });
+      _ut.test('test_invocationOfNonFunction_getter', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_invocationOfNonFunction_getter);
+      });
+      _ut.test('test_invocationOfNonFunction_localVariable', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_invocationOfNonFunction_localVariable);
+      });
+      _ut.test('test_invoke_dynamicThroughGetter', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_invoke_dynamicThroughGetter);
+      });
+      _ut.test('test_isValidMixin_badSuperclass', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_isValidMixin_badSuperclass);
+      });
+      _ut.test('test_isValidMixin_constructor', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_isValidMixin_constructor);
+      });
+      _ut.test('test_isValidMixin_super', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_isValidMixin_super);
+      });
+      _ut.test('test_isValidMixin_valid', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_isValidMixin_valid);
+      });
+      _ut.test('test_methodCascades', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_methodCascades);
+      });
+      _ut.test('test_methodCascades_withSetter', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_methodCascades_withSetter);
+      });
+      _ut.test('test_newWithAbstractClass_factory', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_newWithAbstractClass_factory);
+      });
+      _ut.test('test_nonBoolExpression_assert_bool', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_nonBoolExpression_assert_bool);
+      });
+      _ut.test('test_nonBoolExpression_assert_functionType', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_nonBoolExpression_assert_functionType);
+      });
+      _ut.test('test_resolveAgainstNull', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_resolveAgainstNull);
+      });
+      _ut.test('test_returnOfInvalidType_dynamic', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_returnOfInvalidType_dynamic);
+      });
+      _ut.test('test_returnOfInvalidType_subtype', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_returnOfInvalidType_subtype);
+      });
+      _ut.test('test_returnOfInvalidType_supertype', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_returnOfInvalidType_supertype);
+      });
+      _ut.test('test_typeArgumentNotMatchingBounds_const', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_typeArgumentNotMatchingBounds_const);
+      });
+      _ut.test('test_typeArgumentNotMatchingBounds_new', () {
+        final __test = new SimpleResolverTest();
+        runJUnitTest(__test, __test.test_typeArgumentNotMatchingBounds_new);
+      });
+    });
+  }
+}
+main() {
+//  ElementResolverTest.dartSuite();
+//  LibraryElementBuilderTest.dartSuite();
+//  LibraryTest.dartSuite();
+//  StaticTypeAnalyzerTest.dartSuite();
+//  TypeProviderImplTest.dartSuite();
+//  TypeResolverVisitorTest.dartSuite();
+//  EnclosedScopeTest.dartSuite();
+//  LibraryImportScopeTest.dartSuite();
+//  LibraryScopeTest.dartSuite();
+//  ScopeTest.dartSuite();
+//  CompileTimeErrorCodeTest.dartSuite();
+//  ErrorResolverTest.dartSuite();
+//  SimpleResolverTest.dartSuite();
+//  StaticTypeWarningCodeTest.dartSuite();
+//  StaticWarningCodeTest.dartSuite();
+}
\ No newline at end of file
diff --git a/pkg/analyzer-experimental/test/generated/scanner_test.dart b/pkg/analyzer_experimental/test/generated/scanner_test.dart
similarity index 97%
rename from pkg/analyzer-experimental/test/generated/scanner_test.dart
rename to pkg/analyzer_experimental/test/generated/scanner_test.dart
index 8506de2..994cca8 100644
--- a/pkg/analyzer-experimental/test/generated/scanner_test.dart
+++ b/pkg/analyzer_experimental/test/generated/scanner_test.dart
@@ -4,15 +4,147 @@
 library engine.scanner_test;
 
 import 'dart:collection';
-import 'package:analyzer-experimental/src/generated/java_core.dart';
-import 'package:analyzer-experimental/src/generated/java_engine.dart';
-import 'package:analyzer-experimental/src/generated/java_junit.dart';
-import 'package:analyzer-experimental/src/generated/source.dart';
-import 'package:analyzer-experimental/src/generated/error.dart';
-import 'package:analyzer-experimental/src/generated/scanner.dart';
+import 'package:analyzer_experimental/src/generated/java_core.dart';
+import 'package:analyzer_experimental/src/generated/java_engine.dart';
+import 'package:analyzer_experimental/src/generated/java_junit.dart';
+import 'package:analyzer_experimental/src/generated/source.dart';
+import 'package:analyzer_experimental/src/generated/error.dart';
+import 'package:analyzer_experimental/src/generated/scanner.dart';
 import 'package:unittest/unittest.dart' as _ut;
 import 'test_support.dart';
 
+class KeywordStateTest extends JUnitTestCase {
+  void test_KeywordState() {
+    List<Keyword> keywords = Keyword.values;
+    int keywordCount = keywords.length;
+    List<String> textToTest = new List<String>(keywordCount * 3);
+    for (int i = 0; i < keywordCount; i++) {
+      String syntax3 = keywords[i].syntax;
+      textToTest[i] = syntax3;
+      textToTest[i + keywordCount] = "${syntax3}x";
+      textToTest[i + keywordCount * 2] = syntax3.substring(0, syntax3.length - 1);
+    }
+    KeywordState firstState = KeywordState.KEYWORD_STATE;
+    for (int i = 0; i < textToTest.length; i++) {
+      String text = textToTest[i];
+      int index = 0;
+      int length10 = text.length;
+      KeywordState state = firstState;
+      while (index < length10 && state != null) {
+        state = state.next(text.codeUnitAt(index));
+        index++;
+      }
+      if (i < keywordCount) {
+        JUnitTestCase.assertNotNull(state);
+        JUnitTestCase.assertNotNull(state.keyword());
+        JUnitTestCase.assertEquals(keywords[i], state.keyword());
+      } else if (i < keywordCount * 2) {
+        JUnitTestCase.assertNull(state);
+      } else {
+        JUnitTestCase.assertNotNull(state);
+      }
+    }
+  }
+  static dartSuite() {
+    _ut.group('KeywordStateTest', () {
+      _ut.test('test_KeywordState', () {
+        final __test = new KeywordStateTest();
+        runJUnitTest(__test, __test.test_KeywordState);
+      });
+    });
+  }
+}
+class TokenTypeTest extends EngineTestCase {
+  void test_isOperator() {
+    JUnitTestCase.assertTrue(TokenType.AMPERSAND.isOperator());
+    JUnitTestCase.assertTrue(TokenType.AMPERSAND_AMPERSAND.isOperator());
+    JUnitTestCase.assertTrue(TokenType.AMPERSAND_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.BANG.isOperator());
+    JUnitTestCase.assertTrue(TokenType.BANG_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.BAR.isOperator());
+    JUnitTestCase.assertTrue(TokenType.BAR_BAR.isOperator());
+    JUnitTestCase.assertTrue(TokenType.BAR_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.CARET.isOperator());
+    JUnitTestCase.assertTrue(TokenType.CARET_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.EQ_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.GT.isOperator());
+    JUnitTestCase.assertTrue(TokenType.GT_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.GT_GT.isOperator());
+    JUnitTestCase.assertTrue(TokenType.GT_GT_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.INDEX.isOperator());
+    JUnitTestCase.assertTrue(TokenType.INDEX_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.IS.isOperator());
+    JUnitTestCase.assertTrue(TokenType.LT.isOperator());
+    JUnitTestCase.assertTrue(TokenType.LT_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.LT_LT.isOperator());
+    JUnitTestCase.assertTrue(TokenType.LT_LT_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.MINUS.isOperator());
+    JUnitTestCase.assertTrue(TokenType.MINUS_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.MINUS_MINUS.isOperator());
+    JUnitTestCase.assertTrue(TokenType.PERCENT.isOperator());
+    JUnitTestCase.assertTrue(TokenType.PERCENT_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.PERIOD_PERIOD.isOperator());
+    JUnitTestCase.assertTrue(TokenType.PLUS.isOperator());
+    JUnitTestCase.assertTrue(TokenType.PLUS_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.PLUS_PLUS.isOperator());
+    JUnitTestCase.assertTrue(TokenType.QUESTION.isOperator());
+    JUnitTestCase.assertTrue(TokenType.SLASH.isOperator());
+    JUnitTestCase.assertTrue(TokenType.SLASH_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.STAR.isOperator());
+    JUnitTestCase.assertTrue(TokenType.STAR_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.TILDE.isOperator());
+    JUnitTestCase.assertTrue(TokenType.TILDE_SLASH.isOperator());
+    JUnitTestCase.assertTrue(TokenType.TILDE_SLASH_EQ.isOperator());
+  }
+  void test_isUserDefinableOperator() {
+    JUnitTestCase.assertTrue(TokenType.AMPERSAND.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.BAR.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.CARET.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.EQ_EQ.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.GT.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.GT_EQ.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.GT_GT.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.INDEX.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.INDEX_EQ.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.LT.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.LT_EQ.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.LT_LT.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.MINUS.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.PERCENT.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.PLUS.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.SLASH.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.STAR.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.TILDE.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.TILDE_SLASH.isUserDefinableOperator());
+  }
+  static dartSuite() {
+    _ut.group('TokenTypeTest', () {
+      _ut.test('test_isOperator', () {
+        final __test = new TokenTypeTest();
+        runJUnitTest(__test, __test.test_isOperator);
+      });
+      _ut.test('test_isUserDefinableOperator', () {
+        final __test = new TokenTypeTest();
+        runJUnitTest(__test, __test.test_isUserDefinableOperator);
+      });
+    });
+  }
+}
+/**
+ * The class {@code TokenFactory} defines utility methods that can be used to create tokens.
+ */
+class TokenFactory {
+  static Token token(Keyword keyword) => new KeywordToken(keyword, 0);
+  static Token token2(String lexeme) => new StringToken(TokenType.STRING, lexeme, 0);
+  static Token token3(TokenType type) => new Token(type, 0);
+  static Token token4(TokenType type, String lexeme) => new StringToken(type, lexeme, 0);
+  /**
+   * Prevent the creation of instances of this class.
+   */
+  TokenFactory() {
+  }
+}
 class CharBufferScannerTest extends AbstractScannerTest {
   Token scan(String source, GatheringErrorListener listener) {
     CharBuffer buffer = CharBuffer.wrap(source);
@@ -642,198 +774,6 @@
     });
   }
 }
-/**
- * Instances of the class {@code TokenStreamValidator} are used to validate the correct construction
- * of a stream of tokens.
- */
-class TokenStreamValidator {
-  /**
-   * Validate that the stream of tokens that starts with the given token is correct.
-   * @param token the first token in the stream of tokens to be validated
-   */
-  void validate(Token token) {
-    StringBuffer builder = new StringBuffer();
-    validateStream(builder, token);
-    if (builder.length > 0) {
-      JUnitTestCase.fail(builder.toString());
-    }
-  }
-  void validateStream(StringBuffer builder, Token token) {
-    if (token == null) {
-      return;
-    }
-    Token previousToken = null;
-    int previousEnd = -1;
-    Token currentToken = token;
-    while (currentToken != null && currentToken.type != TokenType.EOF) {
-      validateStream(builder, currentToken.precedingComments);
-      TokenType type23 = currentToken.type;
-      if (identical(type23, TokenType.OPEN_CURLY_BRACKET) || identical(type23, TokenType.OPEN_PAREN) || identical(type23, TokenType.OPEN_SQUARE_BRACKET) || identical(type23, TokenType.STRING_INTERPOLATION_EXPRESSION)) {
-        if (currentToken is! BeginToken) {
-          builder.add("\r\nExpected BeginToken, found ");
-          builder.add(currentToken.runtimeType.toString());
-          builder.add(" ");
-          writeToken(builder, currentToken);
-        }
-      }
-      int currentStart = currentToken.offset;
-      int currentLength = currentToken.length;
-      int currentEnd = currentStart + currentLength - 1;
-      if (currentStart <= previousEnd) {
-        builder.add("\r\nInvalid token sequence: ");
-        writeToken(builder, previousToken);
-        builder.add(" followed by ");
-        writeToken(builder, currentToken);
-      }
-      previousEnd = currentEnd;
-      previousToken = currentToken;
-      currentToken = currentToken.next;
-    }
-  }
-  void writeToken(StringBuffer builder, Token token) {
-    builder.add("[");
-    builder.add(token.type);
-    builder.add(", '");
-    builder.add(token.lexeme);
-    builder.add("', ");
-    builder.add(token.offset);
-    builder.add(", ");
-    builder.add(token.length);
-    builder.add("]");
-  }
-}
-class TokenTypeTest extends EngineTestCase {
-  void test_isOperator() {
-    JUnitTestCase.assertTrue(TokenType.AMPERSAND.isOperator());
-    JUnitTestCase.assertTrue(TokenType.AMPERSAND_AMPERSAND.isOperator());
-    JUnitTestCase.assertTrue(TokenType.AMPERSAND_EQ.isOperator());
-    JUnitTestCase.assertTrue(TokenType.BANG.isOperator());
-    JUnitTestCase.assertTrue(TokenType.BANG_EQ.isOperator());
-    JUnitTestCase.assertTrue(TokenType.BAR.isOperator());
-    JUnitTestCase.assertTrue(TokenType.BAR_BAR.isOperator());
-    JUnitTestCase.assertTrue(TokenType.BAR_EQ.isOperator());
-    JUnitTestCase.assertTrue(TokenType.CARET.isOperator());
-    JUnitTestCase.assertTrue(TokenType.CARET_EQ.isOperator());
-    JUnitTestCase.assertTrue(TokenType.EQ.isOperator());
-    JUnitTestCase.assertTrue(TokenType.EQ_EQ.isOperator());
-    JUnitTestCase.assertTrue(TokenType.GT.isOperator());
-    JUnitTestCase.assertTrue(TokenType.GT_EQ.isOperator());
-    JUnitTestCase.assertTrue(TokenType.GT_GT.isOperator());
-    JUnitTestCase.assertTrue(TokenType.GT_GT_EQ.isOperator());
-    JUnitTestCase.assertTrue(TokenType.INDEX.isOperator());
-    JUnitTestCase.assertTrue(TokenType.INDEX_EQ.isOperator());
-    JUnitTestCase.assertTrue(TokenType.IS.isOperator());
-    JUnitTestCase.assertTrue(TokenType.LT.isOperator());
-    JUnitTestCase.assertTrue(TokenType.LT_EQ.isOperator());
-    JUnitTestCase.assertTrue(TokenType.LT_LT.isOperator());
-    JUnitTestCase.assertTrue(TokenType.LT_LT_EQ.isOperator());
-    JUnitTestCase.assertTrue(TokenType.MINUS.isOperator());
-    JUnitTestCase.assertTrue(TokenType.MINUS_EQ.isOperator());
-    JUnitTestCase.assertTrue(TokenType.MINUS_MINUS.isOperator());
-    JUnitTestCase.assertTrue(TokenType.PERCENT.isOperator());
-    JUnitTestCase.assertTrue(TokenType.PERCENT_EQ.isOperator());
-    JUnitTestCase.assertTrue(TokenType.PERIOD_PERIOD.isOperator());
-    JUnitTestCase.assertTrue(TokenType.PLUS.isOperator());
-    JUnitTestCase.assertTrue(TokenType.PLUS_EQ.isOperator());
-    JUnitTestCase.assertTrue(TokenType.PLUS_PLUS.isOperator());
-    JUnitTestCase.assertTrue(TokenType.QUESTION.isOperator());
-    JUnitTestCase.assertTrue(TokenType.SLASH.isOperator());
-    JUnitTestCase.assertTrue(TokenType.SLASH_EQ.isOperator());
-    JUnitTestCase.assertTrue(TokenType.STAR.isOperator());
-    JUnitTestCase.assertTrue(TokenType.STAR_EQ.isOperator());
-    JUnitTestCase.assertTrue(TokenType.TILDE.isOperator());
-    JUnitTestCase.assertTrue(TokenType.TILDE_SLASH.isOperator());
-    JUnitTestCase.assertTrue(TokenType.TILDE_SLASH_EQ.isOperator());
-  }
-  void test_isUserDefinableOperator() {
-    JUnitTestCase.assertTrue(TokenType.AMPERSAND.isUserDefinableOperator());
-    JUnitTestCase.assertTrue(TokenType.BAR.isUserDefinableOperator());
-    JUnitTestCase.assertTrue(TokenType.CARET.isUserDefinableOperator());
-    JUnitTestCase.assertTrue(TokenType.EQ_EQ.isUserDefinableOperator());
-    JUnitTestCase.assertTrue(TokenType.GT.isUserDefinableOperator());
-    JUnitTestCase.assertTrue(TokenType.GT_EQ.isUserDefinableOperator());
-    JUnitTestCase.assertTrue(TokenType.GT_GT.isUserDefinableOperator());
-    JUnitTestCase.assertTrue(TokenType.INDEX.isUserDefinableOperator());
-    JUnitTestCase.assertTrue(TokenType.INDEX_EQ.isUserDefinableOperator());
-    JUnitTestCase.assertTrue(TokenType.LT.isUserDefinableOperator());
-    JUnitTestCase.assertTrue(TokenType.LT_EQ.isUserDefinableOperator());
-    JUnitTestCase.assertTrue(TokenType.LT_LT.isUserDefinableOperator());
-    JUnitTestCase.assertTrue(TokenType.MINUS.isUserDefinableOperator());
-    JUnitTestCase.assertTrue(TokenType.PERCENT.isUserDefinableOperator());
-    JUnitTestCase.assertTrue(TokenType.PLUS.isUserDefinableOperator());
-    JUnitTestCase.assertTrue(TokenType.SLASH.isUserDefinableOperator());
-    JUnitTestCase.assertTrue(TokenType.STAR.isUserDefinableOperator());
-    JUnitTestCase.assertTrue(TokenType.TILDE.isUserDefinableOperator());
-    JUnitTestCase.assertTrue(TokenType.TILDE_SLASH.isUserDefinableOperator());
-  }
-  static dartSuite() {
-    _ut.group('TokenTypeTest', () {
-      _ut.test('test_isOperator', () {
-        final __test = new TokenTypeTest();
-        runJUnitTest(__test, __test.test_isOperator);
-      });
-      _ut.test('test_isUserDefinableOperator', () {
-        final __test = new TokenTypeTest();
-        runJUnitTest(__test, __test.test_isUserDefinableOperator);
-      });
-    });
-  }
-}
-/**
- * The class {@code TokenFactory} defines utility methods that can be used to create tokens.
- */
-class TokenFactory {
-  static Token token(Keyword keyword) => new KeywordToken(keyword, 0);
-  static Token token2(String lexeme) => new StringToken(TokenType.STRING, lexeme, 0);
-  static Token token3(TokenType type) => new Token(type, 0);
-  static Token token4(TokenType type, String lexeme) => new StringToken(type, lexeme, 0);
-  /**
-   * Prevent the creation of instances of this class.
-   */
-  TokenFactory() {
-  }
-}
-class KeywordStateTest extends JUnitTestCase {
-  void test_KeywordState() {
-    List<Keyword> keywords = Keyword.values;
-    int keywordCount = keywords.length;
-    List<String> textToTest = new List<String>(keywordCount * 3);
-    for (int i = 0; i < keywordCount; i++) {
-      String syntax3 = keywords[i].syntax;
-      textToTest[i] = syntax3;
-      textToTest[i + keywordCount] = "${syntax3}x";
-      textToTest[i + keywordCount * 2] = syntax3.substring(0, syntax3.length - 1);
-    }
-    KeywordState firstState = KeywordState.KEYWORD_STATE;
-    for (int i = 0; i < textToTest.length; i++) {
-      String text = textToTest[i];
-      int index = 0;
-      int length10 = text.length;
-      KeywordState state = firstState;
-      while (index < length10 && state != null) {
-        state = state.next(text.codeUnitAt(index));
-        index++;
-      }
-      if (i < keywordCount) {
-        JUnitTestCase.assertNotNull(state);
-        JUnitTestCase.assertNotNull(state.keyword());
-        JUnitTestCase.assertEquals(keywords[i], state.keyword());
-      } else if (i < keywordCount * 2) {
-        JUnitTestCase.assertNull(state);
-      } else {
-        JUnitTestCase.assertNotNull(state);
-      }
-    }
-  }
-  static dartSuite() {
-    _ut.group('KeywordStateTest', () {
-      _ut.test('test_KeywordState', () {
-        final __test = new KeywordStateTest();
-        runJUnitTest(__test, __test.test_KeywordState);
-      });
-    });
-  }
-}
 class StringScannerTest extends AbstractScannerTest {
   void test_setSourceStart() {
     int offsetDelta = 42;
@@ -841,10 +781,10 @@
     StringScanner scanner = new StringScanner(null, "a", listener);
     scanner.setSourceStart(3, 9, offsetDelta);
     scanner.tokenize();
-    List<int> lineStarts2 = scanner.lineStarts;
-    JUnitTestCase.assertNotNull(lineStarts2);
-    JUnitTestCase.assertEquals(3, lineStarts2.length);
-    JUnitTestCase.assertEquals(33, lineStarts2[2]);
+    List<int> lineStarts3 = scanner.lineStarts;
+    JUnitTestCase.assertNotNull(lineStarts3);
+    JUnitTestCase.assertEquals(3, lineStarts3.length);
+    JUnitTestCase.assertEquals(33, lineStarts3[2]);
   }
   Token scan(String source, GatheringErrorListener listener) {
     StringScanner scanner = new StringScanner(null, source, listener);
@@ -1477,6 +1417,66 @@
     });
   }
 }
+/**
+ * Instances of the class {@code TokenStreamValidator} are used to validate the correct construction
+ * of a stream of tokens.
+ */
+class TokenStreamValidator {
+  /**
+   * Validate that the stream of tokens that starts with the given token is correct.
+   * @param token the first token in the stream of tokens to be validated
+   */
+  void validate(Token token) {
+    JavaStringBuilder builder = new JavaStringBuilder();
+    validateStream(builder, token);
+    if (builder.length > 0) {
+      JUnitTestCase.fail(builder.toString());
+    }
+  }
+  void validateStream(JavaStringBuilder builder, Token token) {
+    if (token == null) {
+      return;
+    }
+    Token previousToken = null;
+    int previousEnd = -1;
+    Token currentToken = token;
+    while (currentToken != null && currentToken.type != TokenType.EOF) {
+      validateStream(builder, currentToken.precedingComments);
+      TokenType type30 = currentToken.type;
+      if (identical(type30, TokenType.OPEN_CURLY_BRACKET) || identical(type30, TokenType.OPEN_PAREN) || identical(type30, TokenType.OPEN_SQUARE_BRACKET) || identical(type30, TokenType.STRING_INTERPOLATION_EXPRESSION)) {
+        if (currentToken is! BeginToken) {
+          builder.append("\r\nExpected BeginToken, found ");
+          builder.append(currentToken.runtimeType.toString());
+          builder.append(" ");
+          writeToken(builder, currentToken);
+        }
+      }
+      int currentStart = currentToken.offset;
+      int currentLength = currentToken.length;
+      int currentEnd = currentStart + currentLength - 1;
+      if (currentStart <= previousEnd) {
+        builder.append("\r\nInvalid token sequence: ");
+        writeToken(builder, previousToken);
+        builder.append(" followed by ");
+        writeToken(builder, currentToken);
+      }
+      previousEnd = currentEnd;
+      previousToken = currentToken;
+      currentToken = currentToken.next;
+    }
+  }
+  void writeToken(JavaStringBuilder builder, Token token) {
+    builder.append("[");
+    builder.append(token.type);
+    builder.append(", '");
+    builder.append(token.lexeme);
+    builder.append("', ");
+    builder.append(token.offset);
+    builder.append(", ");
+    builder.append(token.length);
+    builder.append("]");
+  }
+}
 abstract class AbstractScannerTest extends JUnitTestCase {
   void test_ampersand() {
     assertToken(TokenType.AMPERSAND, "&");
@@ -1864,9 +1864,9 @@
   }
   void test_startAndEnd() {
     Token token = scan2("a");
-    Token previous3 = token.previous;
-    JUnitTestCase.assertEquals(token, previous3.next);
-    JUnitTestCase.assertEquals(previous3, previous3.previous);
+    Token previous5 = token.previous;
+    JUnitTestCase.assertEquals(token, previous5.next);
+    JUnitTestCase.assertEquals(previous5, previous5.previous);
     Token next7 = token.next;
     JUnitTestCase.assertEquals(next7, next7.next);
     JUnitTestCase.assertEquals(token, next7.previous);
diff --git a/pkg/analyzer-experimental/test/generated/test_support.dart b/pkg/analyzer_experimental/test/generated/test_support.dart
similarity index 85%
rename from pkg/analyzer-experimental/test/generated/test_support.dart
rename to pkg/analyzer_experimental/test/generated/test_support.dart
index 987ff38..7312a7c 100644
--- a/pkg/analyzer-experimental/test/generated/test_support.dart
+++ b/pkg/analyzer_experimental/test/generated/test_support.dart
@@ -4,12 +4,14 @@
 library engine.test_support;
 
 import 'dart:collection';
-import 'package:analyzer-experimental/src/generated/java_core.dart';
-import 'package:analyzer-experimental/src/generated/java_engine.dart';
-import 'package:analyzer-experimental/src/generated/java_junit.dart';
-import 'package:analyzer-experimental/src/generated/source.dart';
-import 'package:analyzer-experimental/src/generated/error.dart';
-import 'package:analyzer-experimental/src/generated/scanner.dart';
+import 'dart:uri';
+import 'package:analyzer_experimental/src/generated/java_core.dart';
+import 'package:analyzer_experimental/src/generated/java_engine.dart';
+import 'package:analyzer_experimental/src/generated/java_junit.dart';
+import 'package:analyzer_experimental/src/generated/source.dart';
+import 'package:analyzer_experimental/src/generated/error.dart';
+import 'package:analyzer_experimental/src/generated/scanner.dart';
+import 'package:analyzer_experimental/src/generated/element.dart' show InterfaceType, MethodElement, PropertyAccessorElement;
 import 'package:unittest/unittest.dart' as _ut;
 
 /**
@@ -42,17 +44,17 @@
    * Initialize a newly created error listener to collect errors.
    */
   GatheringErrorListener() : super() {
-    _jtd_constructor_258_impl();
+    _jtd_constructor_315_impl();
   }
-  _jtd_constructor_258_impl() {
+  _jtd_constructor_315_impl() {
   }
   /**
    * Initialize a newly created error listener to collect errors.
    */
   GatheringErrorListener.con1(String rawSource2) {
-    _jtd_constructor_259_impl(rawSource2);
+    _jtd_constructor_316_impl(rawSource2);
   }
-  _jtd_constructor_259_impl(String rawSource2) {
+  _jtd_constructor_316_impl(String rawSource2) {
     this._rawSource = rawSource2;
     this._markedSource = rawSource2;
   }
@@ -87,7 +89,7 @@
    * expected
    */
   void assertErrors2(List<ErrorCode> expectedErrorCodes) {
-    StringBuffer builder = new StringBuffer();
+    JavaStringBuilder builder = new JavaStringBuilder();
     Map<ErrorCode, int> expectedCounts = new Map<ErrorCode, int>();
     for (ErrorCode code in expectedErrorCodes) {
       int count = expectedCounts[code];
@@ -120,15 +122,15 @@
       }
       if (actualCount != expectedCount) {
         if (builder.length == 0) {
-          builder.add("Expected ");
+          builder.append("Expected ");
         } else {
-          builder.add("; ");
+          builder.append("; ");
         }
-        builder.add(expectedCount);
-        builder.add(" errors of type ");
-        builder.add(code);
-        builder.add(", found ");
-        builder.add(actualCount);
+        builder.append(expectedCount);
+        builder.append(" errors of type ");
+        builder.append(code);
+        builder.append(", found ");
+        builder.append(actualCount);
       }
     }
     for (MapEntry<ErrorCode, List<AnalysisError>> entry in getMapEntrySet(errorsByCode)) {
@@ -136,23 +138,23 @@
       List<AnalysisError> actualErrors = entry.getValue();
       int actualCount = actualErrors.length;
       if (builder.length == 0) {
-        builder.add("Expected ");
+        builder.append("Expected ");
       } else {
-        builder.add("; ");
+        builder.append("; ");
       }
-      builder.add("0 errors of type ");
-      builder.add(code);
-      builder.add(", found ");
-      builder.add(actualCount);
-      builder.add(" (");
+      builder.append("0 errors of type ");
+      builder.append(code);
+      builder.append(", found ");
+      builder.append(actualCount);
+      builder.append(" (");
       for (int i = 0; i < actualErrors.length; i++) {
         AnalysisError error = actualErrors[i];
         if (i > 0) {
-          builder.add(", ");
+          builder.append(", ");
         }
-        builder.add(error.offset);
+        builder.append(error.offset);
       }
-      builder.add(")");
+      builder.append(")");
     }
     if (builder.length > 0) {
       JUnitTestCase.fail(builder.toString());
@@ -206,9 +208,9 @@
    * @param errorCode the error code being searched for
    * @return {@code true} if an error with the given error code has been gathered
    */
-  bool hasError(ErrorCode errorCode4) {
+  bool hasError(ErrorCode errorCode5) {
     for (AnalysisError error in _errors) {
-      if (identical(error.errorCode, errorCode4)) {
+      if (identical(error.errorCode, errorCode5)) {
         return true;
       }
     }
@@ -272,15 +274,15 @@
     writer.print(expectedErrors.length);
     writer.print(" errors:");
     for (AnalysisError error in expectedErrors) {
-      Source source9 = error.source;
-      LineInfo lineInfo = _lineInfoMap[source9];
+      Source source11 = error.source;
+      LineInfo lineInfo = _lineInfoMap[source11];
       writer.println();
       if (lineInfo == null) {
-        int offset9 = error.offset;
-        writer.printf("  %s %s (%d..%d)", [source9 == null ? "" : source9.shortName, error.errorCode, offset9, offset9 + error.length]);
+        int offset10 = error.offset;
+        writer.printf("  %s %s (%d..%d)", [source11 == null ? "" : source11.shortName, error.errorCode, offset10, offset10 + error.length]);
       } else {
         LineInfo_Location location = lineInfo.getLocation(error.offset);
-        writer.printf("  %s %s (%d, %d/%d)", [source9 == null ? "" : source9.shortName, error.errorCode, location.lineNumber, location.columnNumber, error.length]);
+        writer.printf("  %s %s (%d, %d/%d)", [source11 == null ? "" : source11.shortName, error.errorCode, location.lineNumber, location.columnNumber, error.length]);
       }
     }
     writer.println();
@@ -288,15 +290,15 @@
     writer.print(_errors.length);
     writer.print(" errors:");
     for (AnalysisError error in _errors) {
-      Source source10 = error.source;
-      LineInfo lineInfo = _lineInfoMap[source10];
+      Source source12 = error.source;
+      LineInfo lineInfo = _lineInfoMap[source12];
       writer.println();
       if (lineInfo == null) {
-        int offset10 = error.offset;
-        writer.printf("  %s %s (%d..%d): %s", [source10 == null ? "" : source10.shortName, error.errorCode, offset10, offset10 + error.length, error.message]);
+        int offset11 = error.offset;
+        writer.printf("  %s %s (%d..%d): %s", [source12 == null ? "" : source12.shortName, error.errorCode, offset11, offset11 + error.length, error.message]);
       } else {
         LineInfo_Location location = lineInfo.getLocation(error.offset);
-        writer.printf("  %s %s (%d, %d/%d): %s", [source10 == null ? "" : source10.shortName, error.errorCode, location.lineNumber, location.columnNumber, error.length, error.message]);
+        writer.printf("  %s %s (%d, %d/%d): %s", [source12 == null ? "" : source12.shortName, error.errorCode, location.lineNumber, location.columnNumber, error.length, error.message]);
       }
     }
     JUnitTestCase.fail(writer.toString());
@@ -351,7 +353,7 @@
     JUnitTestCase.assertNotNull(actualValues);
     int expectedLength = expectedValues.length;
     JUnitTestCase.assertEquals(expectedLength, actualValues.length);
-    List<bool> found = new List<bool>(expectedLength);
+    List<bool> found = new List<bool>.filled(expectedLength, false);
     for (int i = 0; i < expectedLength; i++) {
       found[i] = false;
     }
@@ -471,7 +473,7 @@
     if (!isInstanceOf(object, expectedClass)) {
       JUnitTestCase.fail("Expected instance of ${expectedClass.toString()}, found ${(object == null ? "null" : object.runtimeType.toString())}");
     }
-    return (object as Object);
+    return object as Object;
   }
   /**
    * Assert that the given array is non-{@code null} and has the expected number of elements.
@@ -564,6 +566,36 @@
     }
     return diffPos;
   }
+  /**
+   * Return the getter in the given type with the given name. Inherited getters are ignored.
+   * @param type the type in which the getter is declared
+   * @param getterName the name of the getter to be returned
+   * @return the property accessor element representing the getter with the given name
+   */
+  PropertyAccessorElement getGetter(InterfaceType type, String getterName) {
+    for (PropertyAccessorElement accessor in type.element.accessors) {
+      if (accessor.isGetter() && accessor.name == getterName) {
+        return accessor;
+      }
+    }
+    JUnitTestCase.fail("Could not find getter named ${getterName} in ${type.name}");
+    return null;
+  }
+  /**
+   * Return the method in the given type with the given name. Inherited methods are ignored.
+   * @param type the type in which the method is declared
+   * @param methodName the name of the method to be returned
+   * @return the method element representing the method with the given name
+   */
+  MethodElement getMethod(InterfaceType type, String methodName) {
+    for (MethodElement method in type.element.methods) {
+      if (method.name == methodName) {
+        return method;
+      }
+    }
+    JUnitTestCase.fail("Could not find method named ${methodName} in ${type.name}");
+    return null;
+  }
   static dartSuite() {
     _ut.group('EngineTestCase', () {
     });
@@ -585,12 +617,22 @@
   String get shortName {
     throw new UnsupportedOperationException();
   }
+  String get encoding {
+    throw new UnsupportedOperationException();
+  }
+  int get modificationStamp {
+    throw new UnsupportedOperationException();
+  }
+  bool exists() => true;
   bool isInSystemLibrary() {
     throw new UnsupportedOperationException();
   }
   Source resolve(String uri) {
     throw new UnsupportedOperationException();
   }
+  Source resolveRelative(Uri uri) {
+    throw new UnsupportedOperationException();
+  }
 }
 
 /**
diff --git a/pkg/analyzer-experimental/test/options_test.dart b/pkg/analyzer_experimental/test/options_test.dart
similarity index 95%
rename from pkg/analyzer-experimental/test/options_test.dart
rename to pkg/analyzer_experimental/test/options_test.dart
index 075f60f..02b194c 100644
--- a/pkg/analyzer-experimental/test/options_test.dart
+++ b/pkg/analyzer_experimental/test/options_test.dart
@@ -5,7 +5,7 @@
 library options_test;
 
 import 'package:unittest/unittest.dart';
-import 'package:analyzer-experimental/options.dart';
+import 'package:analyzer_experimental/options.dart';
 
 main() {
 
diff --git a/pkg/args/lib/args.dart b/pkg/args/lib/args.dart
index 6bdcb7e..48cef16 100644
--- a/pkg/args/lib/args.dart
+++ b/pkg/args/lib/args.dart
@@ -285,11 +285,6 @@
 
     // Make sure the abbreviation isn't too long or in use.
     if (abbr != null) {
-      if (abbr.length > 1) {
-        throw new ArgumentError(
-            'Abbreviation "$abbr" is longer than one character.');
-      }
-
       var existing = findByAbbreviation(abbr);
       if (existing != null) {
         throw new ArgumentError(
@@ -331,7 +326,7 @@
    * that abbreviation.
    */
   Option findByAbbreviation(String abbr) {
-    return options.values.firstMatching((option) => option.abbreviation == abbr,
+    return options.values.firstWhere((option) => option.abbreviation == abbr,
         orElse: () => null);
   }
 }
@@ -342,7 +337,7 @@
 class Option {
   final String name;
   final String abbreviation;
-  final List allowed;
+  final List<String> allowed;
   final defaultValue;
   final Function callback;
   final String help;
@@ -353,7 +348,33 @@
 
   Option(this.name, this.abbreviation, this.help, this.allowed,
       this.allowedHelp, this.defaultValue, this.callback, {this.isFlag,
-      this.negatable, this.allowMultiple: false});
+      this.negatable, this.allowMultiple: false}) {
+
+    if (name.isEmpty) {
+      throw new ArgumentError('Name cannot be empty.');
+    } else if (name.startsWith('-')) {
+      throw new ArgumentError('Name $name cannot start with "-".');
+    }
+
+    // Ensure name does not contain any invalid characters.
+    if (_invalidChars.hasMatch(name)) {
+      throw new ArgumentError('Name "$name" contains invalid characters.');
+    }
+
+    if (abbreviation != null) {
+      if (abbreviation.length != 1) {
+        throw new ArgumentError('Abbreviation must be null or have length 1.');
+      } else if(abbreviation == '-') {
+        throw new ArgumentError('Abbreviation cannot be "-".');
+      }
+
+      if (_invalidChars.hasMatch(abbreviation)) {
+        throw new ArgumentError('Abbreviation is an invalid character.');
+      }
+    }
+  }
+
+  static final _invalidChars = new RegExp(r'''[ \t\r\n"'\\/]''');
 }
 
 /**
diff --git a/pkg/args/test/args_test.dart b/pkg/args/test/args_test.dart
index d807291..cf31cc2 100644
--- a/pkg/args/test/args_test.dart
+++ b/pkg/args/test/args_test.dart
@@ -32,6 +32,24 @@
       var parser = new ArgParser();
       throwsIllegalArg(() => parser.addFlag('flummox', abbr: 'flu'));
     });
+
+    test('throws ArgumentError if a flag name is invalid', () {
+      var parser = new ArgParser();
+
+      for(var name in _INVALID_OPTIONS) {
+        var reason = '${Error.safeToString(name)} is not valid';
+        throwsIllegalArg(() => parser.addFlag(name), reason: reason);
+      }
+    });
+
+    test('accepts valid flag names', () {
+      var parser = new ArgParser();
+
+      for(var name in _VALID_OPTIONS) {
+        var reason = '${Error.safeToString(name)} is valid';
+        expect(() => parser.addFlag(name), returnsNormally, reason: reason);
+      }
+    });
   });
 
   group('ArgParser.addOption()', () {
@@ -58,6 +76,46 @@
       var parser = new ArgParser();
       throwsIllegalArg(() => parser.addOption('flummox', abbr: 'flu'));
     });
+
+    test('throws ArgumentError if the abbreviation is empty', () {
+      var parser = new ArgParser();
+      throwsIllegalArg(() => parser.addOption('flummox', abbr: ''));
+    });
+
+    test('throws ArgumentError if the abbreviation is an invalid value', () {
+      var parser = new ArgParser();
+      for(var name in _INVALID_OPTIONS.where((v) => v != null)) {
+        throwsIllegalArg(() => parser.addOption('flummox', abbr: name));
+      }
+    });
+
+    test('throws ArgumentError if the abbreviation is a dash', () {
+      var parser = new ArgParser();
+      throwsIllegalArg(() => parser.addOption('flummox', abbr: '-'));
+    });
+
+    test('allows explict null value for "abbr"', () {
+      var parser = new ArgParser();
+      expect(() => parser.addOption('flummox', abbr: null), returnsNormally);
+    });
+
+    test('throws ArgumentError if an option name is invalid', () {
+      var parser = new ArgParser();
+
+      for(var name in _INVALID_OPTIONS) {
+        var reason = '${Error.safeToString(name)} is not valid';
+        throwsIllegalArg(() => parser.addOption(name), reason: reason);
+      }
+    });
+
+    test('accepts valid option names', () {
+      var parser = new ArgParser();
+
+      for(var name in _VALID_OPTIONS) {
+        var reason = '${Error.safeToString(name)} is valid';
+        expect(() => parser.addOption(name), returnsNormally, reason: reason);
+      }
+    });
   });
 
   group('ArgParser.getDefault()', () {
@@ -155,10 +213,33 @@
   });
 }
 
-throwsIllegalArg(function) {
-  expect(function, throwsArgumentError);
+throwsIllegalArg(function, {String reason: null}) {
+  expect(function, throwsArgumentError, reason: reason);
 }
 
 throwsFormat(ArgParser parser, List<String> args) {
   expect(() => parser.parse(args), throwsFormatException);
 }
+
+const _INVALID_OPTIONS = const [
+ ' ', '', '-', '--', '--foo',
+ ' with space',
+ 'with\ttab',
+ 'with\rcarriage\rreturn',
+ 'with\nline\nfeed',
+ "'singlequotes'",
+ '"doublequotes"',
+ 'back\\slash',
+ 'forward/slash'
+];
+
+const _VALID_OPTIONS = const [
+ 'a' // one char
+ 'contains-dash',
+ 'contains_underscore',
+ 'ends-with-dash-',
+ 'contains--doubledash--',
+ '1starts-with-number',
+ 'contains-a-1number',
+ 'ends-with-a-number8'
+];
diff --git a/pkg/fixnum/test/int_64_vm_test.dart b/pkg/fixnum/test/int_64_vm_test.dart
index ee1fd74..b9b4a9a 100644
--- a/pkg/fixnum/test/int_64_vm_test.dart
+++ b/pkg/fixnum/test/int_64_vm_test.dart
@@ -56,7 +56,7 @@
   for (int i = 0; i < DISCARD; i++) {
     rand = random.nextDouble();
   }
-  return (rand * n).floor().toInt();
+  return (rand * n).floor();
 }
 
 class Op {
diff --git a/pkg/http/lib/src/multipart_file.dart b/pkg/http/lib/src/multipart_file.dart
index aa30fc3..2f1f102 100644
--- a/pkg/http/lib/src/multipart_file.dart
+++ b/pkg/http/lib/src/multipart_file.dart
@@ -67,12 +67,15 @@
   /// the future may be inferred from [filename].
   factory MultipartFile.fromString(String field, String value,
       {String filename, ContentType contentType}) {
-    contentType = contentType == null ? new ContentType("text", "plain") :
-        // Make a copy of the original contentType so we can modify charset.
-        new ContentType.fromString(contentType.toString());
+    contentType = contentType == null ? new ContentType("text", "plain")
+                                      : contentType;
     var charset = contentType.charset;
     var encoding = encodingForCharset(contentType.charset, Encoding.UTF_8);
-    contentType.charset = encoding.name;
+    // Make a new contentType with ensured charset.
+    contentType = new ContentType(contentType.primaryType,
+                                  contentType.subType,
+                                  charset: encoding.name,
+                                  parameters: contentType.parameters);
 
     return new MultipartFile.fromBytes(field, encodeString(value, encoding),
         filename: filename,
diff --git a/pkg/http/lib/src/multipart_request.dart b/pkg/http/lib/src/multipart_request.dart
index 0855063..bc58871 100644
--- a/pkg/http/lib/src/multipart_request.dart
+++ b/pkg/http/lib/src/multipart_request.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -144,7 +144,7 @@
     // URL-encode them so we do the same.
     var header = 'content-disposition: form-data; name="${encodeUri(name)}"';
     if (!isPlainAscii(value)) {
-      header = '$header\r\ncontent-type: text/plain; charset=UTF-8';
+      header = '$header\r\ncontent-type: text/plain; charset=utf-8';
     }
     return '$header\r\n\r\n';
   }
diff --git a/pkg/http/lib/src/request.dart b/pkg/http/lib/src/request.dart
index 670bc48..525f1ae 100644
--- a/pkg/http/lib/src/request.dart
+++ b/pkg/http/lib/src/request.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -57,7 +57,10 @@
     _defaultEncoding = value;
     var contentType = _contentType;
     if (contentType != null) {
-      contentType.charset = value.name;
+      contentType = new ContentType(contentType.primaryType,
+                                    contentType.subType,
+                                    charset: value.name,
+                                    parameters: contentType.parameters);
       _contentType = contentType;
     }
   }
@@ -87,8 +90,14 @@
   set body(String value) {
     bodyBytes = encodeString(value, encoding);
     var contentType = _contentType;
-    if (contentType == null) contentType = new ContentType("text", "plain");
-    if (contentType.charset == null) contentType.charset = encoding.name;
+    if (contentType == null) {
+      contentType = new ContentType("text", "plain", charset: encoding.name);
+    } else if (contentType.charset == null) {
+      contentType = new ContentType(contentType.primaryType,
+                                    contentType.subType,
+                                    charset: encoding.name,
+                                    parameters: contentType.parameters);
+    }
     _contentType = contentType;
   }
 
diff --git a/pkg/http/lib/src/streamed_request.dart b/pkg/http/lib/src/streamed_request.dart
index b313f68..eb20758 100644
--- a/pkg/http/lib/src/streamed_request.dart
+++ b/pkg/http/lib/src/streamed_request.dart
@@ -24,7 +24,7 @@
   /// buffered.
   ///
   /// Closing this signals the end of the request.
-  StreamSink<List<int>> get sink => _controller.sink;
+  EventSink<List<int>> get sink => _controller.sink;
 
   /// The controller for [sink], from which [BaseRequest] will read data for
   /// [finalize].
diff --git a/pkg/http/lib/src/utils.dart b/pkg/http/lib/src/utils.dart
index 65c4799..5a69ee5 100644
--- a/pkg/http/lib/src/utils.dart
+++ b/pkg/http/lib/src/utils.dart
@@ -78,30 +78,20 @@
 Encoding encodingForCharset(
     String charset, [Encoding fallback = Encoding.ISO_8859_1]) {
   if (charset == null) return fallback;
-  var encoding = _encodingForCharset(charset);
+  var encoding = Encoding.fromName(charset);
   return encoding == null ? fallback : encoding;
 }
 
+
 /// Returns the [Encoding] that corresponds to [charset]. Throws a
 /// [FormatException] if no [Encoding] was found that corresponds to [charset].
 /// [charset] may not be null.
 Encoding requiredEncodingForCharset(String charset) {
-  var encoding = _encodingForCharset(charset);
+  var encoding = Encoding.fromName(charset);
   if (encoding != null) return encoding;
   throw new FormatException('Unsupported encoding "$charset".');
 }
 
-/// Returns the [Encoding] that corresponds to [charset]. Returns null if no
-/// [Encoding] was found that corresponds to [charset]. [charset] may not be
-/// null.
-Encoding _encodingForCharset(String charset) {
-  charset = charset.toLowerCase();
-  if (charset == 'ascii' || charset == 'us-ascii') return Encoding.ASCII;
-  if (charset == 'utf-8') return Encoding.UTF_8;
-  if (charset == 'iso-8859-1') return Encoding.ISO_8859_1;
-  return null;
-}
-
 /// Converts [bytes] into a [String] according to [encoding].
 String decodeString(List<int> bytes, Encoding encoding) {
   // TODO(nweiz): implement this once issue 6284 is fixed.
@@ -152,10 +142,10 @@
 // TODO(nweiz): remove this when issue 7786 is fixed.
 /// Pipes all data and errors from [stream] into [sink]. When [stream] is done,
 /// [sink] is closed and the returned [Future] is completed.
-Future store(Stream stream, StreamSink sink) {
+Future store(Stream stream, EventSink sink) {
   var completer = new Completer();
   stream.listen(sink.add,
-      onError: sink.signalError,
+      onError: sink.addError,
       onDone: () {
         sink.close();
         completer.complete();
@@ -166,10 +156,10 @@
 /// Pipes all data and errors from [stream] into [sink]. Completes [Future] once
 /// [stream] is done. Unlike [store], [sink] remains open after [stream] is
 /// done.
-Future writeStreamToSink(Stream stream, StreamSink sink) {
+Future writeStreamToSink(Stream stream, EventSink sink) {
   var completer = new Completer();
   stream.listen(sink.add,
-      onError: sink.signalError,
+      onError: sink.addError,
       onDone: () => completer.complete());
   return completer.future;
 }
@@ -200,8 +190,8 @@
     controller1.add(value);
     controller2.add(value);
   }, onError: (error) {
-    controller1.signalError(error);
-    controller2.signalError(error);
+    controller1.addError(error);
+    controller2.addError(error);
   }, onDone: () {
     controller1.close();
     controller2.close();
diff --git a/pkg/http/test/http_test.dart b/pkg/http/test/http_test.dart
index 1fc7f57..2dd5d3e 100644
--- a/pkg/http/test/http_test.dart
+++ b/pkg/http/test/http_test.dart
@@ -58,7 +58,7 @@
             'path': '/',
             'headers': {
               'content-type': [
-                'application/x-www-form-urlencoded; charset=UTF-8'
+                'application/x-www-form-urlencoded; charset=utf-8'
               ],
               'content-length': ['40'],
               'x-random-header': ['Value'],
@@ -107,7 +107,7 @@
             'path': '/',
             'headers': {
               'content-type': [
-                'application/x-www-form-urlencoded; charset=UTF-8'
+                'application/x-www-form-urlencoded; charset=utf-8'
               ],
               'content-length': ['40'],
               'x-random-header': ['Value'],
diff --git a/pkg/http/test/multipart_test.dart b/pkg/http/test/multipart_test.dart
index c3c3dd9..b8210d2 100644
--- a/pkg/http/test/multipart_test.dart
+++ b/pkg/http/test/multipart_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -76,12 +76,12 @@
 
         value2
         --{{boundary}}
-        content-type: text/plain; charset=UTF-8
+        content-type: text/plain; charset=utf-8
         content-disposition: form-data; name="file1"; filename="filename1.txt"
 
         contents1
         --{{boundary}}
-        content-type: text/plain; charset=UTF-8
+        content-type: text/plain; charset=utf-8
         content-disposition: form-data; name="file2"
 
         contents2
@@ -109,7 +109,7 @@
     expect(request, bodyMatches('''
         --{{boundary}}
         content-disposition: form-data; name="field"
-        content-type: text/plain; charset=UTF-8
+        content-type: text/plain; charset=utf-8
 
         vⱥlūe
         --{{boundary}}--
@@ -123,7 +123,7 @@
 
     expect(request, bodyMatches('''
         --{{boundary}}
-        content-type: text/plain; charset=UTF-8
+        content-type: text/plain; charset=utf-8
         content-disposition: form-data; name="file"; filename="f%C3%AFl%C4%93name.txt"
 
         contents
@@ -139,7 +139,7 @@
 
     expect(request, bodyMatches('''
         --{{boundary}}
-        content-type: application/json; charset=UTF-8
+        content-type: application/json; charset=utf-8
         content-disposition: form-data; name="file"
 
         {"hello": "world"}
diff --git a/pkg/http/test/request_test.dart b/pkg/http/test/request_test.dart
index 551f694..1ef7230 100644
--- a/pkg/http/test/request_test.dart
+++ b/pkg/http/test/request_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -25,7 +25,7 @@
         'method': 'POST',
         'path': '/',
         'headers': {
-          'content-type': ['text/plain; charset=UTF-8'],
+          'content-type': ['text/plain; charset=utf-8'],
           'content-length': ['5']
         },
         'body': 'hello'
@@ -246,7 +246,7 @@
       var request = new http.Request('POST', dummyUrl);
       request.bodyFields = {'hello': 'world'};
       expect(request.headers[HttpHeaders.CONTENT_TYPE],
-          equals('application/x-www-form-urlencoded; charset=UTF-8'));
+          equals('application/x-www-form-urlencoded; charset=utf-8'));
     });
 
     test('is set to application/x-www-form-urlencoded with the given charset '
@@ -255,7 +255,7 @@
       request.encoding = Encoding.ISO_8859_1;
       request.bodyFields = {'hello': 'world'};
       expect(request.headers[HttpHeaders.CONTENT_TYPE],
-          equals('application/x-www-form-urlencoded; charset=ISO-8859-1'));
+          equals('application/x-www-form-urlencoded; charset=iso-8859-1'));
     });
 
     test('is set to text/plain and the given encoding if body and encoding are '
@@ -264,7 +264,7 @@
       request.encoding = Encoding.ISO_8859_1;
       request.body = 'hello, world';
       expect(request.headers[HttpHeaders.CONTENT_TYPE],
-          equals('text/plain; charset=ISO-8859-1'));
+          equals('text/plain; charset=iso-8859-1'));
     });
 
     test('is modified to include utf-8 if body is set', () {
@@ -272,7 +272,7 @@
       request.headers[HttpHeaders.CONTENT_TYPE] = 'application/json';
       request.body = '{"hello": "world"}';
       expect(request.headers[HttpHeaders.CONTENT_TYPE],
-          equals('application/json; charset=UTF-8'));
+          equals('application/json; charset=utf-8'));
     });
 
     test('is modified to include the given encoding if encoding is set', () {
@@ -280,7 +280,7 @@
       request.headers[HttpHeaders.CONTENT_TYPE] = 'application/json';
       request.encoding = Encoding.ISO_8859_1;
       expect(request.headers[HttpHeaders.CONTENT_TYPE],
-          equals('application/json; charset=ISO-8859-1'));
+          equals('application/json; charset=iso-8859-1'));
     });
 
     test('has its charset overridden by an explicit encoding', () {
@@ -289,7 +289,7 @@
           'application/json; charset=utf-8';
       request.encoding = Encoding.ISO_8859_1;
       expect(request.headers[HttpHeaders.CONTENT_TYPE],
-          equals('application/json; charset=ISO-8859-1'));
+          equals('application/json; charset=iso-8859-1'));
     });
 
     test("doen't have its charset overridden by setting bodyFields", () {
diff --git a/pkg/http/test/safe_http_server.dart b/pkg/http/test/safe_http_server.dart
new file mode 100644
index 0000000..64adf5b
--- /dev/null
+++ b/pkg/http/test/safe_http_server.dart
@@ -0,0 +1,144 @@
+// 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 safe_http_server;
+
+import 'dart:async';
+import 'dart:io';
+import 'dart:uri';
+
+// TODO(nweiz): remove this when issue 9140 is fixed.
+/// A wrapper around [HttpServer] that swallows errors caused by requests
+/// behaving badly. This provides the following guarantees:
+///
+/// * The [SafeHttpServer.listen] onError callback will only emit server-wide
+///   errors. It will not emit errors for requests that were unparseable or
+///   where the connection was closed too soon.
+/// * [HttpResponse.done] will emit no errors.
+///
+/// The [HttpRequest] data stream can still emit errors.
+class SafeHttpServer extends StreamView<HttpRequest> implements HttpServer {
+  final HttpServer _inner;
+
+  static Future<SafeHttpServer> bind([String host = "127.0.0.1",
+      int port = 0, int backlog = 0]) {
+    return HttpServer.bind(host, port, backlog)
+        .then((server) => new SafeHttpServer(server));
+  }
+
+  SafeHttpServer(HttpServer server)
+      : super(server),
+        _inner = server;
+
+  void close() => _inner.close();
+
+  int get port => _inner.port;
+
+  set sessionTimeout(int timeout) {
+    _inner.sessionTimeout = timeout;
+  }
+
+  HttpConnectionsInfo connectionsInfo() => _inner.connectionsInfo();
+
+  StreamSubscription<HttpRequest> listen(void onData(HttpRequest value),
+      {void onError(AsyncError error), void onDone(),
+      bool unsubscribeOnError: false}) {
+    var subscription;
+    subscription = super.listen((request) {
+      onData(new _HttpRequestWrapper(request));
+    }, onError: (e) {
+      var error = e.error;
+      // Ignore socket error 104, which is caused by a request being cancelled
+      // before it writes any headers. There's no reason to care about such
+      // requests.
+      if (error is SocketIOException && error.osError.errorCode == 104) return;
+      // Ignore any parsing errors, which come from malformed requests.
+      if (error is HttpParserException) return;
+      // Manually handle unsubscribeOnError so the above (ignored) errors don't
+      // cause unsubscription.
+      if (unsubscribeOnError) subscription.cancel();
+      if (onError != null) onError(e);
+    }, onDone: onDone);
+    return subscription;
+  }
+}
+
+/// A wrapper around [HttpRequest] for the sole purpose of swallowing errors on
+/// [HttpResponse.done].
+class _HttpRequestWrapper extends StreamView<List<int>> implements HttpRequest {
+  final HttpRequest _inner;
+  final HttpResponse response;
+
+  _HttpRequestWrapper(HttpRequest inner)
+      : super(inner),
+        _inner = inner,
+        response = new _HttpResponseWrapper(inner.response);
+
+  int get contentLength => _inner.contentLength;
+  String get method => _inner.method;
+  Uri get uri => _inner.uri;
+  Map<String, String> get queryParameters => _inner.queryParameters;
+  HttpHeaders get headers => _inner.headers;
+  List<Cookie> get cookies => _inner.cookies;
+  bool get persistentConnection => _inner.persistentConnection;
+  X509Certificate get certificate => _inner.certificate;
+  HttpSession get session => _inner.session;
+  String get protocolVersion => _inner.protocolVersion;
+  HttpConnectionInfo get connectionInfo => _inner.connectionInfo;
+}
+
+/// A wrapper around [HttpResponse] for the sole purpose of swallowing errors on
+/// [done].
+class _HttpResponseWrapper implements HttpResponse {
+  final HttpResponse _inner;
+  Future<HttpResponse> _done;
+
+  _HttpResponseWrapper(this._inner);
+
+  /// Swallows all errors from writing to the response.
+  Future<HttpResponse> get done {
+    if (_done == null) _done = _inner.done.catchError((_) {});
+    return _done;
+  }
+
+  int get contentLength => _inner.contentLength;
+  set contentLength(int value) {
+    _inner.contentLength = value;
+  }
+
+  int get statusCode => _inner.statusCode;
+  set statusCode(int value) {
+    _inner.statusCode = value;
+  }
+
+  String get reasonPhrase => _inner.reasonPhrase;
+  set reasonPhrase(String value) {
+    _inner.reasonPhrase = value;
+  }
+
+  bool get persistentConnection => _inner.persistentConnection;
+  set persistentConnection(bool value) {
+    _inner.persistentConnection = value;
+  }
+
+  Encoding get encoding => _inner.encoding;
+  set encoding(Encoding value) {
+    _inner.encoding = value;
+  }
+
+  HttpHeaders get headers => _inner.headers;
+  List<Cookie> get cookies => _inner.cookies;
+  Future<Socket> detachSocket() => _inner.detachSocket();
+  HttpConnectionInfo get connectionInfo => _inner.connectionInfo;
+  void writeBytes(List<int> data) => _inner.writeBytes(data);
+  Future<HttpResponse> consume(Stream<List<int>> stream) =>
+    _inner.consume(stream);
+  Future<HttpResponse> writeStream(Stream<List<int>> stream) =>
+    _inner.writeStream(stream);
+  void close() => _inner.close();
+  void write(Object obj) => _inner.write(obj);
+  void writeAll(Iterable objects) => _inner.writeAll(objects);
+  void writeCharCode(int charCode) => _inner.writeCharCode(charCode);
+  void writeln([Object obj = ""]) => _inner.writeln(obj);
+}
diff --git a/pkg/http/test/utils.dart b/pkg/http/test/utils.dart
index 8b404a5..6bbe139 100644
--- a/pkg/http/test/utils.dart
+++ b/pkg/http/test/utils.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -13,6 +13,7 @@
 import '../lib/src/byte_stream.dart';
 import '../lib/http.dart' as http;
 import '../lib/src/utils.dart';
+import 'safe_http_server.dart';
 
 /// The current server instance.
 HttpServer _server;
@@ -25,7 +26,7 @@
 
 /// Starts a new HTTP server.
 Future startServer() {
-  return HttpServer.bind("127.0.0.1", 0).then((s) {
+  return SafeHttpServer.bind("127.0.0.1", 0).then((s) {
     _server = s;
     s.listen((request) {
       var path = request.uri.path;
@@ -57,9 +58,18 @@
       }
 
       new ByteStream(request).toBytes().then((requestBodyBytes) {
-        response.statusCode = 200;
-        response.headers.contentType = new ContentType("application", "json");
-      response.headers.set('single', 'value');
+        var outputEncoding;
+        var encodingName = request.queryParameters['response-encoding'];
+        if (encodingName != null) {
+          outputEncoding = requiredEncodingForCharset(encodingName);
+        } else {
+          outputEncoding = Encoding.ASCII;
+        }
+
+        response.headers.contentType =
+            new ContentType(
+                "application", "json", charset: outputEncoding.name);
+        response.headers.set('single', 'value');
 
         var requestBody;
         if (requestBodyBytes.isEmpty) {
@@ -86,17 +96,9 @@
           content['headers'][name] = values;
         });
 
-        var outputEncoding;
-        var encodingName = request.queryParameters['response-encoding'];
-        if (encodingName != null) {
-          outputEncoding = requiredEncodingForCharset(encodingName);
-        } else {
-          outputEncoding = Encoding.ASCII;
-        }
-
         var body = json.stringify(content);
         response.contentLength = body.length;
-        response.addString(body, outputEncoding);
+        response.write(body);
         response.close();
       });
     });
diff --git a/pkg/intl/example/basic/basic_example.dart b/pkg/intl/example/basic/basic_example.dart
index 0ac9c20..1ecb2a0 100644
--- a/pkg/intl/example/basic/basic_example.dart
+++ b/pkg/intl/example/basic/basic_example.dart
@@ -5,9 +5,9 @@
 /**
  * This provides a basic example of internationalization usage. It uses the
  * local variant of all the facilities, meaning that libraries with the
- * data for all the locales are directly imported by the program. More realistic
- * examples might read the data from files or over the web, which uses the
- * same APIs but requires different imports.
+ * data for all the locales are directly imported by the program. Once lazy
+ * loading is available, we expect this to be the preferred mode, with
+ * the initialization code actually loading the specific libraries needed.
  *
  * This defines messages for an English locale directly in the program and
  * has separate libraries that define German and Thai messages that say more or
@@ -16,15 +16,18 @@
  */
 
 library intl_basic_example;
-// These can be replaced with package:intl/... references if using this in
-// a separate package.
-// TODO(alanknight): Replace these with package: once pub works in buildbots.
 import 'dart:async';
-import '../../lib/date_symbol_data_local.dart';
-import '../../lib/intl.dart';
-import '../../lib/message_lookup_local.dart';
+import 'package:intl/date_symbol_data_local.dart';
+import 'package:intl/intl.dart';
+import 'package:intl/message_lookup_by_library.dart';
 import 'messages_all.dart';
 
+/**
+ * In order to use this both as an example and as a test case, we pass in
+ * the function for what we're going to do with the output. For a simple
+ * example we just pass in [print] and for tests we pass in a function that
+ * adds it a list to be verified.
+ */
 Function doThisWithTheOutput;
 
 void setup(Function program, Function output) {
@@ -58,8 +61,8 @@
   printForLocale(aDate, de, runAt);
   printForLocale(aDate, th, runAt);
   // Example making use of the return value from withLocale;
-  Intl.withLocale(th.locale, () => runAt('now', 'today'))
-    .then(doThisWithTheOutput);
+  var returnValue = Intl.withLocale(th.locale, () => runAt('now', 'today'));
+  doThisWithTheOutput(returnValue);
 }
 
 printForLocale(aDate, intl, operation) {
@@ -67,7 +70,5 @@
   var dayFormat = intl.date().add_yMMMMEEEEd();
   var time = hmsFormat.format(aDate);
   var day = dayFormat.format(aDate);
-  Intl.withLocale(intl.locale, () {
-    operation(time,day).then(doThisWithTheOutput);
-  });
+  Intl.withLocale(intl.locale, () => doThisWithTheOutput(operation(time,day)));
 }
diff --git a/pkg/intl/example/basic/messages_all.dart b/pkg/intl/example/basic/messages_all.dart
index 43629f2..e722f6c 100644
--- a/pkg/intl/example/basic/messages_all.dart
+++ b/pkg/intl/example/basic/messages_all.dart
@@ -3,12 +3,36 @@
 // BSD-style license that can be found in the LICENSE file.
 
 /**
- * In order to avoid needing to import the libraries for each locale
- * individually in each program file, we make a separate library that imports
- * all of them. In this example there's only one program file, so it doesn't
- * make very much difference.
+ * This imports all of the different message libraries and provides an
+ * [initializeMessages] function that sets up the lookup for a particular
+ * library.
  */
 library messages_all;
 
+import 'dart:async';
+import 'package:intl/message_lookup_by_library.dart';
+import 'package:intl/src/intl_helpers.dart';
 import 'messages_th_th.dart' as th_TH;
 import 'messages_de.dart' as de;
+import 'package:intl/intl.dart';
+
+// TODO(alanknight): Use lazy loading of the requested library.
+MessageLookupByLibrary _findExact(localeName) {
+  switch (localeName) {
+    case 'th_TH' : return th_TH.messages;
+    case 'de' : return de.messages;
+    default: return null;
+  }
+}
+
+initializeMessages(localeName) {
+  initializeInternalMessageLookup(() => new CompositeMessageLookup());
+  messageLookup.addLocale(localeName, _findGeneratedMessagesFor);
+  return new Future.immediate(null);
+}
+
+MessageLookupByLibrary _findGeneratedMessagesFor(locale) {
+  var actualLocale = Intl.verifiedLocale(locale, (x) => _findExact(x) != null);
+  if (actualLocale == null) return null;
+  return _findExact(actualLocale);
+}
\ No newline at end of file
diff --git a/pkg/intl/example/basic/messages_de.dart b/pkg/intl/example/basic/messages_de.dart
index 07e8331..d18c981 100644
--- a/pkg/intl/example/basic/messages_de.dart
+++ b/pkg/intl/example/basic/messages_de.dart
@@ -5,12 +5,20 @@
 /**
  * This is a library that provides messages for a German locale. All the
  * messages from the main program should be duplicated here with the same
- * function name. Note that the library name is significant, as it's looked
- * up based on a naming convention.
+ * function name.
  */
-
 library messages_de;
-import '../../lib/intl.dart';
+import 'package:intl/intl.dart';
+import 'package:intl/message_lookup_by_library.dart';
 
-runAt(time, day) => Intl.message('Ausgedruckt am $time am $day.', name: 'runAt',
-    args: [time, day]);
+final messages = new MessageLookup();
+
+class MessageLookup extends MessageLookupByLibrary {
+
+  get localeName => 'de';
+
+  final messages = {
+    "runAt" : (time, day) => Intl.message("Ausgedruckt am $time am $day.")
+  };
+}
+
diff --git a/pkg/intl/example/basic/messages_th_th.dart b/pkg/intl/example/basic/messages_th_th.dart
index 899399d..59c98dc 100644
--- a/pkg/intl/example/basic/messages_th_th.dart
+++ b/pkg/intl/example/basic/messages_th_th.dart
@@ -5,13 +5,19 @@
 /**
  * This is a library that provides messages for a German locale. All the
  * messages from the main program should be duplicated here with the same
- * function name.  Note that the library name is significant, as it's looked
- * up based on a naming convention.
+ * function name.
  */
-
 library messages_th_TH;
-import '../../lib/intl.dart';
+import 'package:intl/intl.dart';
+import 'package:intl/message_lookup_by_library.dart';
 
-runAt(time, day) =>
-    Intl.message('วิ่ง $time on $day.', name: 'runAt', args: [time, day]);
+final messages = new MessageLookup();
 
+class MessageLookup extends MessageLookupByLibrary {
+
+  get localeName => 'th_TH';
+
+  final messages = {
+    "runAt" : (time, day) => Intl.message('วิ่ง $time on $day.')
+  };
+}
\ No newline at end of file
diff --git a/pkg/intl/example/basic/pubspec.yaml b/pkg/intl/example/basic/pubspec.yaml
index 868adbd..17ceb36 100644
--- a/pkg/intl/example/basic/pubspec.yaml
+++ b/pkg/intl/example/basic/pubspec.yaml
@@ -1,9 +1,4 @@
 name: IntlExample
-description: >
-  An example using internationalization facilities
+description: An example using internationalization facilities
 dependencies:
-  intl:
-    sdk: intl
-  htmlescape:
-    sdk: htmlescape
-
+  intl: any
diff --git a/pkg/intl/lib/bidi_formatter.dart b/pkg/intl/lib/bidi_formatter.dart
index ae7b908..a9655f9 100644
--- a/pkg/intl/lib/bidi_formatter.dart
+++ b/pkg/intl/lib/bidi_formatter.dart
@@ -130,7 +130,7 @@
     } else {
       result = text;
     }
-    return result.concat(resetDir? _resetDir(text, direction, isHtml) : '');
+    return result + (resetDir? _resetDir(text, direction, isHtml) : '');
   }
 
   /**
@@ -161,7 +161,7 @@
       result = "${marker}$text${Bidi.PDF}";
 
     }
-    return result.concat(resetDir? _resetDir(text, direction, isHtml) : '');
+    return result + (resetDir? _resetDir(text, direction, isHtml) : '');
   }
 
   /**
diff --git a/pkg/intl/lib/date_symbol_data_file.dart b/pkg/intl/lib/date_symbol_data_file.dart
index 767e89b..5c599f4 100644
--- a/pkg/intl/lib/date_symbol_data_file.dart
+++ b/pkg/intl/lib/date_symbol_data_file.dart
@@ -14,7 +14,7 @@
 import "src/lazy_locale_data.dart";
 import 'src/date_format_internal.dart';
 import 'src/file_data_reader.dart';
-import 'dart:io';
+import 'package:pathos/path.dart' as path;
 
 part "src/data/dates/localeList.dart";
 
@@ -24,11 +24,11 @@
  * The [path] parameter should end with a directory separator appropriate
  * for the platform.
  */
-Future initializeDateFormatting(String locale, String path) {
-  var reader = new FileDataReader('${path}symbols${Platform.pathSeparator}');
+Future initializeDateFormatting(String locale, String filePath) {
+  var reader = new FileDataReader(path.join(filePath, 'symbols'));
   initializeDateSymbols(() => new LazyLocaleData(
       reader, _createDateSymbol, availableLocalesForDateFormatting));
-  var reader2 = new FileDataReader('${path}patterns${Platform.pathSeparator}');
+  var reader2 = new FileDataReader(path.join(filePath, 'patterns'));
   initializeDatePatterns(() => new LazyLocaleData(
       reader2, (x) => x, availableLocalesForDateFormatting));
   return initializeIndividualLocaleDateFormatting(
diff --git a/pkg/intl/lib/extract_messages.dart b/pkg/intl/lib/extract_messages.dart
new file mode 100755
index 0000000..fb57341
--- /dev/null
+++ b/pkg/intl/lib/extract_messages.dart
@@ -0,0 +1,332 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * This is for use in extracting messages from a Dart program
+ * using the Intl.message() mechanism and writing them to a file for
+ * translation. This provides only the stub of a mechanism, because it
+ * doesn't define how the file should be written. It provides an
+ * [IntlMessage] class that holds the extracted data and [parseString]
+ * and [parseFile] methods which
+ * can extract messages that conform to the expected pattern:
+ *       (parameters) => Intl.message("Message $parameters", desc: ...);
+ * It uses the analyzer_experimental package to do the parsing, so may
+ * break if there are changes to the API that it provides.
+ * An example can be found in test/message_extraction/extract_to_json.dart
+ *
+ * Note that this does not understand how to follow part directives, so it
+ * has to explicitly be given all the files that it needs. A typical use case
+ * is to run it on all .dart files in a directory.
+ */
+library extract_messages;
+
+import 'package:analyzer_experimental/src/generated/ast.dart';
+import 'package:analyzer_experimental/src/generated/error.dart';
+import 'package:analyzer_experimental/src/generated/java_core.dart';
+import 'package:analyzer_experimental/src/generated/parser.dart';
+import 'package:analyzer_experimental/src/generated/scanner.dart';
+import 'package:analyzer_experimental/src/generated/source.dart';
+import 'package:analyzer_experimental/src/generated/utilities_dart.dart';
+import 'dart:io';
+import 'package:intl/src/intl_message.dart';
+
+/**
+ * Parse the dart program represented in [sourceCode] and return a Map from
+ * message names to [IntlMessage] instances. The [origin] is a string
+ * describing where the source came from, and is used in error messages.
+ */
+Map<String, IntlMessage> parseString(String sourceCode, [String origin]) {
+  var errorListener = new _ErrorCollector();
+  var scanner = new StringScanner(null, sourceCode, errorListener);
+  var token = scanner.tokenize();
+  var parser = new Parser(null, errorListener);
+  var unit = parser.parseCompilationUnit(token);
+  unit.lineInfo = new LineInfo(scanner.lineStarts);
+
+  var visitor = new MessageFindingVisitor(unit, origin);
+  unit.accept(visitor);
+  for (var error in errorListener.errors) {
+    print(error);
+  }
+  return visitor.messages;
+}
+
+/**
+ * Parse the source of the Dart program file [file] and return a Map from
+ * message names to [IntlMessage] instances.
+ */
+Map<String, IntlMessage> parseFile(File file) {
+  var sourceCode = file.readAsStringSync();
+  return parseString(sourceCode, file.path);
+}
+
+/**
+ * An error handler for parsing. Error handling is currently very primitive.
+ */
+class _ErrorCollector extends AnalysisErrorListener {
+  List<AnalysisError> errors;
+  _ErrorCollector() : errors = new List<AnalysisError>();
+  onError(error) => errors.add(error);
+}
+
+/**
+ * This visits the program source nodes looking for Intl.message uses
+ * that conform to its pattern and then finding the
+ */
+class MessageFindingVisitor extends GeneralizingASTVisitor {
+
+  /**
+   * The root of the compilation unit, and the first node we visit. We hold
+   * on to this for error reporting, as it can give us line numbers of other
+   * nodes.
+   */
+  final CompilationUnit root;
+
+  /**
+   * An arbitrary string describing where the source code came from. Most
+   * obviously, this could be a file path. We use this when reporting
+   * invalid messages.
+   */
+  final String origin;
+
+  MessageFindingVisitor(this.root, this.origin);
+
+  /**
+   * Accumulates the messages we have found.
+   */
+  final Map<String, IntlMessage> messages = new Map<String, IntlMessage>();
+
+  /**
+   * We keep track of the data from the last MethodDeclaration,
+   * FunctionDeclaration or FunctionExpression that we saw on the way down,
+   * as that will be the nearest parent of the Intl.message invocation.
+   */
+  FormalParameterList parameters;
+  String name;
+
+  /** Return true if [node] matches the pattern we expect for Intl.message() */
+  bool looksLikeIntlMessage(MethodInvocation node) {
+    if (node.methodName.name != "message") return false;
+    if (!(node.target is SimpleIdentifier)) return false;
+    SimpleIdentifier target = node.target;
+    if (target.token.toString() != "Intl") return false;
+    return true;
+  }
+
+  /**
+   * Returns a String describing why the node is invalid, or null if no
+   * reason is found, so it's presumed valid.
+   */
+  String checkValidity(MethodInvocation node) {
+    // The containing function cannot have named parameters.
+    if (parameters.parameters.any((each) => each.kind == ParameterKind.NAMED)) {
+      return "Named parameters on message functions are not supported.";
+    }
+    var arguments = node.argumentList.arguments;
+    if (!(arguments.first is StringLiteral)) {
+      return "Intl.message messages must be string literals";
+    }
+    var namedArguments = arguments.skip(1);
+    // This seems unlikely to happen, but make sure all are NamedExpression
+    // before doing the tests below.
+    if (!namedArguments.every((each) => each is NamedExpression)) {
+      return "Message arguments except the message must be named";
+    }
+    var notArgs = namedArguments.where(
+        (each) => each.name.label.name != 'args');
+    var values = notArgs.map((each) => each.expression).toList();
+    if (!values.every((each) => each is SimpleStringLiteral)) {
+      "Intl.message arguments must be simple string literals";
+    }
+    if (!notArgs.any((each) => each.name.label.name == 'name')) {
+      return "The 'name' argument for Intl.message must be specified";
+    }
+    var hasArgs = namedArguments.any((each) => each.name.label.name == 'args');
+    var hasParameters = !parameters.parameters.isEmpty;
+    if (!hasArgs && hasParameters) {
+      return "The 'args' argument for Intl.message must be specified";
+    }
+    return null;
+  }
+
+  /**
+   * Record the parameters of the function or method declaration we last
+   * encountered before seeing the Intl.message call.
+   */
+  void visitMethodDeclaration(MethodDeclaration node) {
+    parameters = node.parameters;
+    String name = node.name.name;
+    super.visitMethodDeclaration(node);
+  }
+
+  /**
+   * Record the parameters of the function or method declaration we last
+   * encountered before seeing the Intl.message call.
+   */
+  void visitFunctionExpression(FunctionExpression node) {
+    parameters = node.parameters;
+    name = null;
+    super.visitFunctionExpression(node);
+  }
+
+  /**
+   * Record the parameters of the function or method declaration we last
+   * encountered before seeing the Intl.message call.
+   */
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    parameters = node.functionExpression.parameters;
+    name = node.name.name;
+    super.visitFunctionDeclaration(node);
+  }
+
+  /**
+   * Examine method invocations to see if they look like calls to Intl.message.
+   */
+  void visitMethodInvocation(MethodInvocation node) {
+    addIntlMessage(node);
+    return super.visitNode(node);
+  }
+
+  /**
+   * Check that the node looks like an Intl.message invocation, and create
+   * the [IntlMessage] object from it and store it in [messages].
+   */
+  void addIntlMessage(MethodInvocation node) {
+    if (!looksLikeIntlMessage(node)) return;
+    var reason = checkValidity(node);
+    if (!(reason == null)) {
+      print("Skipping invalid Intl.message invocation\n    <$node>");
+      print("  reason: $reason");
+      reportErrorLocation(node);
+      return;
+    }
+    var message = messageFromMethodInvocation(node);
+    if (message != null) messages[message.name] = message;
+  }
+
+  /**
+   * Create an IntlMessage from [node] using the name and
+   * parameters of the last function/method declaration we encountered
+   * and the parameters to the Intl.message call.
+   */
+  IntlMessage messageFromMethodInvocation(MethodInvocation node) {
+    var message = new IntlMessage();
+    message.name = name;
+    message.arguments = parameters.parameters.elements.map(
+        (x) => x.identifier.name).toList();
+    try {
+      node.accept(new MessageVisitor(message));
+    } on IntlMessageExtractionException catch (e) {
+      message = null;
+      print("Error $e");
+      print("Processing <$node>");
+      reportErrorLocation(node);
+    }
+    return message;
+  }
+
+  void reportErrorLocation(ASTNode node) {
+    if (origin != null) print("from $origin");
+    LineInfo info = root.lineInfo;
+    if (info != null) {
+      LineInfo_Location line = info.getLocation(node.offset);
+      print("line: ${line.lineNumber}, column: ${line.columnNumber}");
+    }
+  }
+}
+
+/**
+ * Given a node that looks like an invocation of Intl.message, extract out
+ * the message and the parameters and store them in [target].
+ */
+class MessageVisitor extends GeneralizingASTVisitor {
+  IntlMessage target;
+
+  MessageVisitor(IntlMessage this.target);
+
+  /**
+   * Extract out the message string. If it's an interpolation, turn it into
+   * a single string with interpolation characters.
+   */
+  void visitArgumentList(ArgumentList node) {
+    var interpolation = new InterpolationVisitor(target);
+    node.arguments.elements.first.accept(interpolation);
+    target.messagePieces = interpolation.pieces;
+    super.visitArgumentList(node);
+  }
+
+  /**
+   * Find the values of all the named arguments, remove quotes, and save them
+   * into [target].
+   */
+  void visitNamedExpression(NamedExpression node) {
+    var name = node.name.label.name;
+    var exp = node.expression;
+    var string = exp is SimpleStringLiteral ? exp.value : exp.toString();
+    target[name] = string;
+    super.visitNamedExpression(node);
+  }
+}
+
+/**
+ * Given an interpolation, find all of its chunks, validate that they are only
+ * simple interpolations, and keep track of the chunks so that other parts
+ * of the program can deal with the interpolations and the simple string
+ * sections separately.
+ */
+class InterpolationVisitor extends GeneralizingASTVisitor {
+  IntlMessage message;
+
+  InterpolationVisitor(this.message);
+
+  List pieces = [];
+  String get extractedMessage => pieces.join();
+
+  void visitSimpleStringLiteral(SimpleStringLiteral node) {
+    pieces.add(node.value);
+    super.visitSimpleStringLiteral(node);
+  }
+
+  void visitInterpolationString(InterpolationString node) {
+    pieces.add(node.value);
+    super.visitInterpolationString(node);
+  }
+
+  // TODO(alanknight): The limitation to simple identifiers is important
+  // to avoid letting translators write arbitrary code, but is a problem
+  // for plurals.
+  void visitInterpolationExpression(InterpolationExpression node) {
+    if (node.expression is! SimpleIdentifier) {
+      throw new IntlMessageExtractionException(
+          "Only simple identifiers are allowed in message "
+          "interpolation expressions.\nError at $node");
+    }
+    var index = arguments.indexOf(node.expression.toString());
+    if (index == -1) {
+      throw new IntlMessageExtractionException(
+          "Cannot find argument ${node.expression}");
+    }
+    pieces.add(index);
+    super.visitInterpolationExpression(node);
+  }
+
+  List get arguments => message.arguments;
+}
+
+/**
+ * Exception thrown when we cannot process a message properly.
+ */
+class IntlMessageExtractionException implements Exception {
+  /**
+   * A message describing the error.
+   */
+  final String message;
+
+  /**
+   * Creates a new exception with an optional error [message].
+   */
+  const IntlMessageExtractionException([this.message = ""]);
+
+  String toString() => "IntlMessageExtractionException: $message";
+}
\ No newline at end of file
diff --git a/pkg/intl/lib/generate_localized.dart b/pkg/intl/lib/generate_localized.dart
new file mode 100644
index 0000000..84ba5c9
--- /dev/null
+++ b/pkg/intl/lib/generate_localized.dart
@@ -0,0 +1,170 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * This provides utilities for generating localized versions of
+ * messages. It does not stand alone, but expects to be given
+ * TranslatedMessage objects and generate code for a particular locale
+ * based on them.
+ *
+ * An example of usage can be found
+ * in test/message_extract/generate_from_json.dart
+ */
+library generate_localized;
+
+import 'extract_messages.dart';
+import 'src/intl_message.dart';
+import 'dart:io';
+import 'package:pathos/path.dart' as path;
+
+/**
+ * A list of all the locales for which we have translations. Code that does
+ * the reading of translations should add to this.
+ */
+List<String> allLocales = [];
+
+/**
+ * This represents a message and its translation. We assume that the translation
+ * has some identifier that allows us to figure out the original message it
+ * corresponds to, and that it may want to transform the translated text in
+ * some way, e.g. to turn whatever format the translation uses for variables
+ * into a Dart string interpolation. Specific translation
+ * mechanisms are expected to subclass this.
+ */
+abstract class TranslatedMessage {
+  /** The identifier for this message. In the simplest case, this is the name.*/
+  var id;
+
+  String translatedString;
+  IntlMessage originalMessage;
+  TranslatedMessage(this.id, this.translatedString);
+
+  String get message => translatedString;
+}
+
+/**
+ * We can't use a hyphen in a Dart library name, so convert the locale
+ * separator to an underscore.
+ */
+String asLibraryName(String x) => x.replaceAll('-', '_');
+
+/**
+ * Generate a file messages_<locale>.dart for the [translations] in
+ * [locale].
+ */
+void generateIndividualMessageFile(String locale,
+    Iterable<TranslatedMessage> translations, String targetDir) {
+  var result = new StringBuffer();
+  locale = new IntlMessage().escapeAndValidate(locale, locale);
+  result.write(prologue(locale));
+  for (var each in translations) {
+    var message = each.originalMessage;
+    if (each.message != null) {
+      message.addTranslation(locale, each.message);
+    }
+  }
+  var sorted = translations.where((each) => each.message != null).toList();
+  sorted.sort((a, b) =>
+      a.originalMessage.name.compareTo(b.originalMessage.name));
+  for (var each in sorted) {
+    result.write("  ");
+    result.write(each.originalMessage.toCode(locale));
+    result.write("\n\n");
+  }
+  result.write("\n  final messages = const {\n");
+  var entries = sorted
+      .map((translation) => translation.originalMessage.name)
+      .map((name) => "    \"$name\" : $name");
+  result.write(entries.join(",\n"));
+  result.write("\n  };\n}");
+
+  var output = new File(path.join(targetDir, "messages_$locale.dart"));
+  output.writeAsStringSync(result.toString());
+}
+
+/**
+ * This returns the mostly constant string used in [generated] for the
+ * beginning of the file, parameterized by [locale].
+ */
+String prologue(String locale) => """
+/**
+ * DO NOT EDIT. This is code generated via pkg/intl/generate_localized.dart
+ * This is a library that provides messages for a $locale locale. All the
+ * messages from the main program should be duplicated here with the same
+ * function name.
+ */
+
+library messages_${locale.replaceAll('-','_')};
+import 'package:intl/intl.dart';
+import 'package:intl/message_lookup_by_library.dart';
+
+final messages = new MessageLookup();
+
+class MessageLookup extends MessageLookupByLibrary {
+
+  get localeName => '$locale';
+""";
+
+/**
+ * This section generates the messages_all.dart file based on the list of
+ * [allLocales].
+ */
+String generateMainImportFile() {
+  var output = new StringBuffer();
+  output.write(mainPrologue);
+  for (var each in allLocales) {
+    output.write("import 'messages_$each.dart' as ${asLibraryName(each)};\n");
+  }
+  output.write(
+    "\nMessageLookupByLibrary _findExact(localeName) {\n"
+    "  switch (localeName) {\n");
+  for (var each in allLocales) {
+    output.write(
+        "    case '$each' : return ${asLibraryName(each)}.messages;\n");
+  }
+  output.write(closing);
+  return output.toString();
+}
+
+/**
+ * Constant string used in [generateMainImportFile] for the beginning of the
+ * file.
+ */
+const mainPrologue = """
+/**
+ * DO NOT EDIT. This is code generated via pkg/intl/generate_localized.dart
+ * This is a library that looks up messages for specific locales by
+ * delegating to the appropriate library.
+ */
+
+library messages_all;
+
+import 'dart:async';
+import 'package:intl/message_lookup_by_library.dart';
+import 'package:intl/src/intl_helpers.dart';
+import 'package:intl/intl.dart';
+
+""";
+
+/**
+ * Constant string used in [generateMainImportfile] as the end of the file.
+ */
+const closing = """
+    default: return null;
+  }
+}
+
+/** User programs should call this before using [localeName] for messages.*/
+initializeMessages(localeName) {
+  initializeInternalMessageLookup(() => new CompositeMessageLookup());
+  messageLookup.addLocale(localeName, _findGeneratedMessagesFor);
+  return new Future.immediate(null);
+}
+
+MessageLookupByLibrary _findGeneratedMessagesFor(locale) {
+  var actualLocale = Intl.verifiedLocale(locale, (x) => _findExact(x) != null);
+  if (actualLocale == null) return null;
+  return _findExact(actualLocale);
+}
+""";
diff --git a/pkg/intl/lib/intl.dart b/pkg/intl/lib/intl.dart
index 18af6a7..c3cbdd5 100644
--- a/pkg/intl/lib/intl.dart
+++ b/pkg/intl/lib/intl.dart
@@ -43,19 +43,23 @@
  * Usage examples:
  *      today(date) => Intl.message(
  *          "Today's date is $date",
+ *          name: 'today',
+ *          args: [date],
  *          desc: 'Indicate the current date',
  *          examples: {'date' : 'June 8, 2012'});
  *      print(today(new DateTime.now());
  *
- *      msg({num_people, place}) => Intl.message(
+ *      msg(num_people, place) => Intl.message(
  *           '''I see ${Intl.plural(num_people,
  *             {'0': 'no one at all',
  *              '1': 'one other person',
  *              'other': '$num_people other people'})} in $place.'''',
+ *          name: 'msg',
+ *          args: [num_people, place],
  *          desc: 'Description of how many people are seen as program start.',
  *          examples: {'num_people': 3, 'place': 'London'});
  *
- * Calling `msg({'num_people': 2, 'place': 'Athens'});` would
+ * Calling `msg(2, 'Athens');` would
  * produce "I see 2 other people in Athens." as output in the default locale.
  *
  * To use a locale other than the default, use the `withLocale` function.
@@ -128,7 +132,7 @@
    * will be extracted automatically but for the time being it must be passed
    * explicitly in the [name] and [args] arguments.
    */
-  static Future<String> message(String message_str, {final String desc: '',
+  static String message(String message_str, {final String desc: '',
       final Map examples: const {}, String locale, String name,
       List<String> args}) {
     return messageLookup.lookupMessage(
@@ -271,4 +275,6 @@
     if (_defaultLocale == null) _defaultLocale = systemLocale;
     return _defaultLocale;
   }
+
+  toString() => "Intl($locale)";
 }
diff --git a/pkg/intl/lib/message_lookup_by_library.dart b/pkg/intl/lib/message_lookup_by_library.dart
new file mode 100644
index 0000000..27b9699
--- /dev/null
+++ b/pkg/intl/lib/message_lookup_by_library.dart
@@ -0,0 +1,140 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Message/plural format library with locale support. This can have different
+ * implementations based on the mechanism for finding the localized versions
+ * of messages. This version expects them to be in a library named e.g.
+ * 'messages_en_US'. The prefix is set in the [initializeMessages] call, which
+ * must be made for a locale before any lookups can be done.
+ *
+ * See Intl class comment or `tests/message_format_test.dart` for more examples.
+ */
+library message_lookup_by_library;
+
+import 'dart:async';
+import 'intl.dart';
+import 'src/intl_helpers.dart';
+
+/**
+ * This is a message lookup mechanism that delegates to one of a collection
+ * of individual [MessageLookupByLibrary] instances.
+ */
+class CompositeMessageLookup {
+  /** A map from locale names to the corresponding lookups. */
+  Map<String, MessageLookupByLibrary> availableMessages = new Map();
+
+  /** Return true if we have a message lookup for [localeName]. */
+  bool localeExists(localeName) => availableMessages.containsKey(localeName);
+
+  /**
+   * Look up the message with the given [name] and [locale] and return
+   * the translated version with the values in [args] interpolated.
+   * If nothing is found, return [message_str]. The [desc] and [examples]
+   * parameters are ignored
+   */
+  String lookupMessage(String message_str, [final String desc='',
+      final Map examples=const {}, String locale,
+      String name, List<String> args]) {
+    var actualLocale = (locale == null) ? Intl.getCurrentLocale() : locale;
+      // For this usage, if the locale doesn't exist for messages, just return
+      // it and we'll fall back to the original version.
+    var verifiedLocale =
+        Intl.verifiedLocale(
+            actualLocale,
+            localeExists,
+            onFailure: (locale)=>locale);
+    var messages = availableMessages[verifiedLocale];
+    if (messages == null) return message_str;
+    return messages.
+        lookupMessage(message_str, desc, examples, locale, name, args);
+  }
+
+  /**
+   * If we do not already have a locale for [localeName] then
+   * [findLocale] will be called and the result stored as the lookup
+   * mechanism for that locale.
+   */
+  addLocale(String localeName, Function findLocale) {
+    if (localeExists(localeName)) return;
+    var newLocale = findLocale(localeName);
+    if (newLocale != null) {
+      availableMessages[localeName] = newLocale;
+    }
+  }
+}
+
+/**
+ * This provides an abstract class for messages looked up in generated code.
+ * Each locale will have a separate subclass of this class with its set of
+ * messages. See generate_localized.dart.
+ */
+abstract class MessageLookupByLibrary {
+  /** Prevent infinite recursion when looking up the message. */
+  bool _lookupInProgress = false;
+
+  /**
+   * Return true if the locale exists, or if it is null. Null is treated
+   * as meaning that we use the default locale.
+   */
+  bool localeExists(localeName);
+
+  /**
+   * Return the localized version of a message. We are passed the original
+   * version of the message, which consists of a
+   * [message_str] that will be translated, and which may be interpolated
+   * based on one or more variables, a [desc] providing a description of usage
+   * for the [message_str], and a map of [examples] for each data element to be
+   * substituted into the message.
+   *
+   * For example, if message="Hello, $name", then
+   * examples = {'name': 'Sparky'}. If not using the user's default locale, or
+   * if the locale is not easily detectable, explicitly pass [locale].
+   *
+   * The values of [desc] and [examples] are not used at run-time but are only
+   * made available to the translators, so they MUST be simple Strings available
+   * at compile time: no String interpolation or concatenation.
+   * The expected usage of this is inside a function that takes as parameters
+   * the variables used in the interpolated string.
+   *
+   * Ultimately, the information about the enclosing function and its arguments
+   * will be extracted automatically but for the time being it must be passed
+   * explicitly in the [name] and [args] arguments.
+   */
+  String lookupMessage(String message_str, [final String desc='',
+      final Map examples=const {}, String locale,
+      String name, List<String> args]) {
+    // If we don't have a name, return the original, and if we have
+    // been recursively invoked, also just return message_str. This
+    // happens because the replacement functions also call Intl.message,
+    // so we assume that when _lookupInProgress is true that we're
+    // already translated.
+    if (name == null || _lookupInProgress) return message_str;
+    _lookupInProgress = true;
+    // Try to apply the function holding the translated version. If there
+    // is an exception, use the original [message_str] as the result.
+    var result = message_str;
+    try {
+      var function = this[name];
+      if (function != null) result = Function.apply(function, args);
+    } finally {
+      _lookupInProgress = false;
+    }
+    return result;
+  }
+
+  /** Return our message with the given name */
+  operator [](String messageName) => messages[messageName];
+
+  /**
+   * Subclasses should override this to return a list of their message
+   * functions.
+   */
+  Map<String, Function> get messages;
+
+  /** Subclasses should override this to return their locale, e.g. 'en_US' */
+  String get localeName;
+
+  toString() => localeName;
+}
\ No newline at end of file
diff --git a/pkg/intl/lib/message_lookup_local.dart b/pkg/intl/lib/message_lookup_local.dart
deleted file mode 100644
index e8a0e97..0000000
--- a/pkg/intl/lib/message_lookup_local.dart
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/**
- * Message/plural format library with locale support. This can have different
- * implementations based on the mechanism for finding the localized versions
- * of messages. This version expects them to be in a library named e.g.
- * 'messages_en_US'. The prefix is set in the [initializeMessages] call, which
- * must be made for a locale before any lookups can be done.
- *
- * See Intl class comment or `tests/message_format_test.dart` for more examples.
- */
- //TODO(efortuna): documentation example involving the offset parameter?
-
-library message_lookup_local;
-
-import 'dart:async';
-import 'intl.dart';
-import 'src/intl_helpers.dart';
-import 'dart:mirrors';
-
-/**
- * Initialize the user messages for [localeName]. Note that this is an ASYNC
- * operation. This must be called before attempting to use messages in
- * [localeName].
- */
-Future initializeMessages(localeName, [String source = 'messages_']) {
-  initializeInternalMessageLookup(
-      () => new MessageLookupLocal(localeName, source));
-  _initializeMessagesForLocale(localeName);
-  return new Future.immediate(null);
-}
-
-void _initializeMessagesForLocale(String localeName) {}
-
-class MessageLookupLocal {
-  /** Prevent infinite recursion when looking up the message. */
-  bool _lookupInProgress = false;
-
-  /** The libraries we can look in for internationalization messages. */
-  Map<String, LibraryMirror> _libraries;
-
-  /** The prefix used to find libraries that contain localized messages.
-   * So, if this is 'messages_' we would look for messages for the locale
-   * 'pt_BR' in a library named 'messages_pt_BR'.
-   */
-  String _sourcePrefix;
-
-  /**
-   * Constructor. The [localeName] is of the form 'en' or 'en_US'.
-   *The [source] parameter defines the prefix that is used to find
-   * libraries that contain localized messages. So with the default value of
-   * 'messages_', we would look for messages for the locale 'pt_BR' in a library
-   * named 'messages_pt_BR'.
-   */
-  MessageLookupLocal(String localeName, this._sourcePrefix) {
-    _libraries = currentMirrorSystem().libraries;
-  }
-
-  /**
-   * Return true if the locale exists, or if it is null. The null case
-   * is interpreted to mean that we use the default locale.
-   */
-  bool localeExists(localeName) {
-    if (localeName == null) return false;
-    return _libraries['$_sourcePrefix$localeName'] != null;
-  }
-
-  /**
-   * Return the localized version of a message. We are passed the original
-   * version of the message, which consists of a
-   * [message_str] that will be translated, and which may be interpolated
-   * based on one or more variables, a [desc] providing a description of usage
-   * for the [message_str], and a map of [examples] for each data element to be
-   * substituted into the message.
-   *
-   * For example, if message="Hello, $name", then
-   * examples = {'name': 'Sparky'}. If not using the user's default locale, or
-   * if the locale is not easily detectable, explicitly pass [locale].
-   *
-   * The values of [desc] and [examples] are not used at run-time but are only
-   * made available to the translators, so they MUST be simple Strings available
-   * at compile time: no String interpolation or concatenation.
-   * The expected usage of this is inside a function that takes as parameters
-   * the variables used in the interpolated string.
-   *
-   * Ultimately, the information about the enclosing function and its arguments
-   * will be extracted automatically but for the time being it must be passed
-   * explicitly in the [name] and [args] arguments.
-   */
-  Future<String> lookupMessage(String message_str, [final String desc='',
-      final Map examples=const {}, String locale,
-      String name, List<String> args]) {
-    if (name == null) return new Future.immediate(message_str);
-    // The translations also make use of Intl.message, so we need to not
-    // recurse and just stop when we find the first substitution.
-    if (_lookupInProgress) return new Future.immediate(message_str);
-    _lookupInProgress = true;
-    var result;
-    try {
-      var actualLocale = (locale == null) ? Intl.getCurrentLocale() : locale;
-      // For this usage, if the locale doesn't exist for messages, just return
-      // it and we'll fall back to the original version.
-      var verifiedLocale =
-          Intl.verifiedLocale(
-              actualLocale,
-              localeExists,
-              onFailure: (locale)=>locale);
-      LibraryMirror messagesForThisLocale =
-          _libraries['$_sourcePrefix$verifiedLocale'];
-      if (messagesForThisLocale == null) {
-        return new Future.immediate(message_str);
-      }
-      MethodMirror localized = messagesForThisLocale.functions[name];
-      if (localized == null) return new Future.immediate(message_str);
-      result = messagesForThisLocale.invoke(localized.simpleName, args);
-    } finally {
-      _lookupInProgress = false;
-    }
-    return result.then((value) => value.reflectee);
-  }
-}
diff --git a/pkg/intl/lib/number_format.dart b/pkg/intl/lib/number_format.dart
index 567fb99..ed5cf2b 100644
--- a/pkg/intl/lib/number_format.dart
+++ b/pkg/intl/lib/number_format.dart
@@ -156,9 +156,9 @@
   void _formatFixed(num number) {
     // Round the number.
     var power = pow(10, _maximumFractionDigits);
-    var intValue = number.truncate().toInt();
+    var intValue = number.truncate();
     var multiplied = (number * power).round();
-    var fracValue = (multiplied - intValue * power).floor().toInt();
+    var fracValue = (multiplied - intValue * power).floor();
     var fractionPresent = _minimumFractionDigits > 0 || fracValue > 0;
 
     // On dartj2s the integer part may be large enough to be a floating
diff --git a/pkg/intl/lib/src/date_format_field.dart b/pkg/intl/lib/src/date_format_field.dart
index 843b6dc..08afc04 100644
--- a/pkg/intl/lib/src/date_format_field.dart
+++ b/pkg/intl/lib/src/date_format_field.dart
@@ -259,7 +259,7 @@
     var basic = padTo(3, date.millisecond);
     if (width - 3 > 0) {
       var extra = padTo(width - 3, 0);
-      return basic.concat(extra);
+      return basic + extra;
     } else {
       return basic;
     }
@@ -345,7 +345,7 @@
   }
 
   String formatQuarter(DateTime date) {
-    var quarter = (date.month / 3).truncate().toInt();
+    var quarter = (date.month / 3).truncate();
     if (width < 4) {
       return symbols.SHORTQUARTERS[quarter];
     } else {
diff --git a/pkg/intl/lib/src/date_format_helpers.dart b/pkg/intl/lib/src/date_format_helpers.dart
index a10b274..253a4e6 100644
--- a/pkg/intl/lib/src/date_format_helpers.dart
+++ b/pkg/intl/lib/src/date_format_helpers.dart
@@ -98,7 +98,7 @@
           min(index + howMany, contents.length));
     } else {
       // Assume List
-      result = contents.getRange(index, howMany);
+      result = contents.sublist(index, index + howMany);
     }
     return result;
   }
diff --git a/pkg/intl/lib/src/file_data_reader.dart b/pkg/intl/lib/src/file_data_reader.dart
index 1c0b4ad..4e6c2ae 100644
--- a/pkg/intl/lib/src/file_data_reader.dart
+++ b/pkg/intl/lib/src/file_data_reader.dart
@@ -10,6 +10,7 @@
 library file_data_reader;
 
 import 'dart:async';
+import 'package:pathos/path.dart';
 import 'dart:io';
 import 'intl_helpers.dart';
 
@@ -22,7 +23,7 @@
 
   /// Read the locale data found for [locale] on our [path].
   Future read(String locale) {
-    var file = new File('$path$locale.json');
+    var file = new File(join(path, '$locale.json'));
     return file.readAsString();
   }
 }
diff --git a/pkg/intl/lib/src/intl_helpers.dart b/pkg/intl/lib/src/intl_helpers.dart
index d431584..ee9fdb2 100644
--- a/pkg/intl/lib/src/intl_helpers.dart
+++ b/pkg/intl/lib/src/intl_helpers.dart
@@ -24,7 +24,13 @@
 
   operator [](String key) =>
       (key == 'en_US') ? fallbackData : _throwException();
+
+  String lookupMessage(String message_str, [final String desc='',
+      final Map examples=const {}, String locale,
+      String name, List<String> args]) => _throwException();
+
   List get keys => _throwException();
+
   bool containsKey(String key) => (key == 'en_US') ? true : _throwException();
 
   _throwException() {
@@ -56,7 +62,7 @@
 
 /**
  * Initialize the message lookup mechanism. This is for internal use only.
- * User applications should import `message_lookup_local.dart` and call
+ * User applications should import `message_lookup_by_library.dart` and call
  * `initializeMessages`
  */
 void initializeInternalMessageLookup(Function lookupFunction) {
diff --git a/pkg/intl/lib/src/intl_message.dart b/pkg/intl/lib/src/intl_message.dart
new file mode 100644
index 0000000..4a1f6cd
--- /dev/null
+++ b/pkg/intl/lib/src/intl_message.dart
@@ -0,0 +1,169 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * This provides the class IntlMessage to represent an occurence of
+ * [Intl.message] in a program. It is used when parsing sources to extract
+ * messages or to generate code for message substitution.
+ */
+library intl_message;
+
+/**
+ * Represents an occurence of Intl.message in the program's source text. We
+ * assemble it into an object that can be used to write out some translation
+ * format and can also print itself into code.
+ */
+class IntlMessage {
+
+  /**
+   * This holds either Strings or ints representing the message. Literal
+   * parts of the message are stored as strings. Interpolations are represented
+   * by the index of the function parameter that they represent. When writing
+   * out to a translation file format the interpolations must be turned
+   * into the appropriate syntax, and the non-interpolated sections
+   * may be modified. See [fullMessage].
+   */
+  // TODO(alanknight): This will need to be changed for plural support.
+  List messagePieces;
+
+  String description;
+
+  /** The examples from the Intl.message call */
+  String examples;
+
+  /**
+   * The name, which may come from the function name, from the arguments
+   * to Intl.message, or we may just re-use the message.
+   */
+  String _name;
+
+  /** The arguments parameter from the Intl.message call. */
+  List<String> arguments;
+
+  /**
+   * A placeholder for any other identifier that the translation format
+   * may want to use.
+   */
+  String id;
+
+  /**
+   * When generating code, we store translations for each locale
+   * associated with the original message.
+   */
+  Map<String, String> translations = new Map();
+
+  IntlMessage();
+
+  /**
+   * If the message was not given a name, we use the entire message string as
+   * the name.
+   */
+  String get name => _name == null ? computeName() : _name;
+  void set name(x) {_name = x;}
+  String computeName() => name = fullMessage((msg, chunk) => "");
+
+  /**
+   * Return the full message, with any interpolation expressions transformed
+   * by [f] and all the results concatenated. The argument to [f] may be
+   * either a String or an int representing the index of a function parameter
+   * that's being interpolated. See [messagePieces].
+   */
+  String fullMessage([Function f]) {
+    var transform = f == null ? (msg, chunk) => chunk : f;
+    var out = new StringBuffer();
+    messagePieces.map((chunk) => transform(this, chunk)).forEach(out.write);
+    return out.toString();
+  }
+
+  /**
+   * The node will have the attribute names as strings, so we translate
+   * between those and the fields of the class.
+   */
+  void operator []=(attributeName, value) {
+    switch (attributeName) {
+      case "desc" : description = value; return;
+      case "examples" : examples = value; return;
+      case "name" : name = value; return;
+      // We use the actual args from the parser rather than what's given in the
+      // arguments to Intl.message.
+      case "args" : return;
+      default: return;
+    }
+  }
+
+  /**
+   * Record the translation for this message in the given locale, after
+   * suitably escaping it.
+   */
+  String addTranslation(locale, value) =>
+      translations[locale] = escapeAndValidate(locale, value);
+
+  /**
+   * Escape the string and validate that it doesn't contain any interpolations
+   * more complex than including a simple variable value.
+   */
+  String escapeAndValidate(String locale, String s) {
+    const escapes = const {
+      r"\" : r"\\",
+      '"' : r'\"',
+      "\b" : r"\b",
+      "\f" : r"\f",
+      "\n" : r"\n",
+      "\r" : r"\r",
+      "\t" : r"\t",
+      "\v" : r"\v"
+    };
+
+    _escape(String s) => (escapes[s] == null) ? s : escapes[s];
+
+    // We know that we'll be enclosing the string in double-quotes, so we need
+    // to escape those, but not single-quotes. In addition we must escape
+    // backslashes, newlines, and other formatting characters.
+    var escaped = s.splitMapJoin("", onNonMatch: _escape);
+
+    // We don't allow any ${} expressions, only $variable to avoid malicious
+    // code. Disallow any usage of "${". If that makes a false positive
+    // on a translation that legitimate contains "\\${" or other variations,
+    // we'll live with that rather than risk a false negative.
+    var validInterpolations = new RegExp(r"(\$\w+)|(\${\w+})");
+    var validMatches = validInterpolations.allMatches(escaped);
+    escapeInvalidMatches(Match m) {
+      var valid = validMatches.any((x) => x.start == m.start);
+      if (valid) {
+        return m.group(0);
+      } else {
+        return "\\${m.group(0)}";
+      }
+    }
+    return escaped.replaceAllMapped("\$", escapeInvalidMatches);
+  }
+
+  /**
+   * Generate code for this message, expecting it to be part of a map
+   * keyed by name with values the function that calls Intl.message.
+   */
+  String toCode(String locale) {
+    var out = new StringBuffer();
+    // These are statics because we want to closurize them into a map and
+    // that doesn't work for instance methods.
+    out.write('static $name(');
+    out.write(arguments.join(", "));
+    out.write(') => Intl.message("${translations[locale]}");');
+    return out.toString();
+  }
+
+  /**
+   * Escape the string to be used in the name, as a map key. So no double quotes
+   * and no interpolation. Assumes that the string has no existing escaping.
+   */
+  String escapeForName(String s) {
+    var escaped1 = s.replaceAll('"', r'\"');
+    var escaped2 = escaped1.replaceAll('\$', r'\$');
+    return escaped2;
+  }
+
+  String toString() =>
+      "Intl.message(${fullMessage()}, $name, $description, $examples, "
+          "$arguments)";
+}
\ No newline at end of file
diff --git a/pkg/intl/pubspec.yaml b/pkg/intl/pubspec.yaml
index 0a870a0..a568a3a 100644
--- a/pkg/intl/pubspec.yaml
+++ b/pkg/intl/pubspec.yaml
@@ -1,11 +1,9 @@
 name: intl
-author: "Dart Team <misc@dartlang.org>"
+author: Dart Team <misc@dartlang.org>
+description: Contains code to deal with internationalized/localized messages, date and number formatting and parsing, bi-directional text, and other internationalization issues.
 homepage: http://www.dartlang.org
 documentation: http://api.dartlang.org/docs/pkg/intl
-description: >
-  Contains code to deal with internationalized/localized
-  messages, date and number formatting and parsing,
-  bi-directional text, and other internationalization issues.
 dependencies:
-  unittest:
-    sdk: unittest
+  unittest: any
+  analyzer_experimental: any
+  pathos: any
diff --git a/pkg/intl/test/data_directory.dart b/pkg/intl/test/data_directory.dart
index 96fa450..9cf6253 100644
--- a/pkg/intl/test/data_directory.dart
+++ b/pkg/intl/test/data_directory.dart
@@ -5,21 +5,43 @@
 /**
  * A utility function for test and tools that compensates (at least for very
  * simple cases) for file-dependent programs being run from different
- * directories.
+ * directories. The important cases are
+ *   -running in the directory that contains the test itself, i.e.
+ *    pkg/intl/test or a sub-directory.
+ *   -running in pkg/intl, which is where the editor will run things by default
+ *   -running in the top-level dart directory, where the build tests run
  */
 library data_directory;
 
-import 'dart:io';
+import "package:pathos/path.dart" as path;
 
-String get _sep => Platform.pathSeparator;
-
-get dataDirectory {
-  var current = new Directory.current().path;
-  if (new RegExp('.*${_sep}test').hasMatch(current)) {
-    return '..${_sep}lib${_sep}src${_sep}data${_sep}dates${_sep}';
-  }
-  if (new RegExp('.*${_sep}intl').hasMatch(current)) {
-    return 'lib${_sep}src${_sep}data${_sep}dates${_sep}';
-  }
-  return 'pkg${_sep}intl${_sep}lib${_sep}src${_sep}data${_sep}dates${_sep}';
+String get dataDirectory {
+  return path.join(intlDirectory, datesRelativeToIntl);
 }
+
+String get intlDirectory {
+  var components = path.split(path.current);
+  var foundIntlDir = false;
+
+  /**
+   * A helper function that returns false (indicating we should stop iterating)
+   * if the argument to the previous call was 'intl' and also sets
+   * the outer scope [foundIntl].
+   */
+  bool checkForIntlDir(String each) {
+    if (foundIntlDir) return false;
+    foundIntlDir = (each == 'intl') ? true : false;
+    return true;
+  }
+
+  var pathUpToIntl = components.takeWhile(checkForIntlDir).toList();
+  // We assume that if we're not somewhere underneath the intl hierarchy
+  // that we are in the dart root.
+  if (foundIntlDir) {
+    return path.joinAll(pathUpToIntl);
+  } else {
+    return path.join(path.current, 'pkg', 'intl');
+  }
+}
+
+String get datesRelativeToIntl => path.join('lib', 'src', 'data', 'dates');
\ No newline at end of file
diff --git a/pkg/intl/test/date_time_format_test_core.dart b/pkg/intl/test/date_time_format_test_core.dart
index fce9e6e..ff880f8 100644
--- a/pkg/intl/test/date_time_format_test_core.dart
+++ b/pkg/intl/test/date_time_format_test_core.dart
@@ -184,7 +184,7 @@
  * Return a set of a few locales to run just the tests on a small sample.
  */
 List smallSetOfLocales() {
-  return allLocales().getRange(0,10);
+  return allLocales().sublist(0,10);
 }
 
 /**
diff --git a/pkg/intl/test/intl_message_basic_example_test.dart b/pkg/intl/test/intl_message_basic_example_test.dart
index 0015964..d89ccd8 100644
--- a/pkg/intl/test/intl_message_basic_example_test.dart
+++ b/pkg/intl/test/intl_message_basic_example_test.dart
@@ -7,9 +7,7 @@
  */
 library intl_message_test_2;
 
-import 'package:intl/date_symbol_data_local.dart';
 import 'package:intl/intl.dart';
-import 'package:intl//message_lookup_local.dart';
 import '../example/basic/basic_example.dart';
 import 'package:unittest/unittest.dart';
 import 'dart:async';
diff --git a/pkg/intl/test/intl_message_test.dart b/pkg/intl/test/intl_message_test.dart
deleted file mode 100644
index f8bcd5e..0000000
--- a/pkg/intl/test/intl_message_test.dart
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library intl_message_test;
-
-import '../lib/intl.dart';
-import '../../../pkg/unittest/lib/unittest.dart';
-import '../lib/message_lookup_local.dart';
-
-/** Tests the MessageFormat library in dart. */
-
-class Person {
-  String firstName, lastName;
-  Person(this.firstName, this.lastName);
-}
-
-main() {
-  test('Run all tests', () {
-    initializeMessages('en_US').then(expectAsync1(runTests));
-  });
-}
-
-runTests(_) {
-  test('Trivial Message', () {
-    hello() => Intl.message('Hello, world!',
-        desc: 'hello world string');
-    expect(hello(), completion(equals('Hello, world!')));
-  });
-
-  test('Message with one parameter', () {
-    lucky(number) => Intl.message('Your lucky number is $number',
-        desc: 'number str', examples: {'number': 2});
-    expect(lucky(3), completion(equals('Your lucky number is 3')));
-  });
-
-  test('Message with multiple plural cases (whole message)', () {
-    emails(number) => Intl.message(
-        Intl.plural(number,
-          {'0': 'There are no emails left.',
-           '1': 'There is one email left.',
-           'other': 'There are $number emails left.'}),
-          desc: 'Message telling user how many emails will be sent.',
-          examples: {'number': 32});
-    expect(emails(5), completion(equals('There are 5 emails left.')));
-    expect(emails(0), completion(equals('There are no emails left.')));
-    expect(emails(1), completion(equals('There is one email left.')));
-  });
-
-  test('Message with multiple plural cases (partial message)', () {
-    emails(number) => Intl.message(
-      "There ${Intl.plural(number,
-        {'0': 'are',
-         '1': 'is',
-         'other': 'are'})} $number messages left.",
-          desc: 'Message telling user how many emails will be sent.',
-          examples: {'number': 32});
-    expect(emails(5), completion(equals('There are 5 messages left.')));
-    expect(emails(0), completion(equals('There are 0 messages left.')));
-    expect(emails(1), completion(equals('There is 1 messages left.')));
-  });
-
-  test('Message with dictionary parameter', () {
-    hello(dict) => Intl.message(
-        "Hello, my name is ${dict['first']} ${dict['last']}",
-        desc: "States a person's name.",
-        examples: {'first': 'Ford', 'last': 'Prefect'});
-    expect(hello({'first' : 'Ford', 'last' : 'Prefect'}),
-      completion(equals('Hello, my name is Ford Prefect')));
-  });
-
-  test('Message with object parameter', () {
-    hello(person) => Intl.message(
-        "Hello, my name is ${person.firstName} ${person.lastName}.",
-        desc: "States a person's name.",
-        examples: {'first': 'Ford', 'last' : 'Prefect'});
-    var ford = new Person('Ford', 'Prefect');
-    expect(hello(ford), completion(equals('Hello, my name is Ford Prefect.')));
-  });
-
-  test('WithLocale test', () {
-    hello() => Intl.message('locale=${Intl.getCurrentLocale()}',
-        desc: 'explains the locale');
-    expect(Intl.withLocale('en-US', () => hello()),
-           completion(equals('locale=en-US')));
-  });
-
-  test('Test passing locale', () {
-    hello(a_locale) => Intl.message('locale=${Intl.getCurrentLocale()}',
-        desc: 'explains the locale', locale: a_locale);
-    expect(hello('en-US'), completion(equals('locale=en_US')));
-  });
-}
diff --git a/pkg/intl/test/message_extraction/extract_to_json.dart b/pkg/intl/test/message_extraction/extract_to_json.dart
new file mode 100644
index 0000000..7d719ee
--- /dev/null
+++ b/pkg/intl/test/message_extraction/extract_to_json.dart
@@ -0,0 +1,67 @@
+#!/usr/bin/env dart
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * This script uses the extract_messages.dart library to find the Intl.message
+ * calls in the target dart files and produces intl_messages.json containing the
+ * information on those messages. It uses the analyzer-experimental parser
+ * to find the information.
+ *
+ * This is intended to test the basic functioning of extracting messages and
+ * serve as an example for how a program to extract them to a translation
+ * file format could work. In the tests, this file is then run through a
+ * simulated translation and the results of that are used to generate code. See
+ * message_extraction_test.dart
+ *
+ * If the environment variable INTL_MESSAGE_OUTPUT is set then it will use
+ * that as the output directory, otherwise it will use the working directory.
+ */
+library extract_to_json;
+
+import 'dart:io';
+import 'package:intl/extract_messages.dart';
+import 'dart:json' as json;
+import 'package:pathos/path.dart' as path;
+import 'package:intl/src/intl_message.dart';
+import 'find_output_directory.dart';
+
+main() {
+  var args = new Options().arguments;
+  if (args.length == 0) {
+    print('Usage: extract_to_json [--output-dir=<dir>] [files.dart]');
+    print('Accepts Dart files and produces intl_messages.json');
+    exit(0);
+  }
+  var allMessages = [];
+  for (var arg in args.where((x) => x.contains(".dart"))) {
+    var messages = parseFile(new File(arg));
+    messages.forEach((k, v) => allMessages.add(toJson(v)));
+  }
+  var targetDir = findOutputDirectory(args);
+  var file = new File(path.join(targetDir, 'intl_messages.json'));
+  file.writeAsStringSync(json.stringify(allMessages));
+}
+
+/**
+ * This is a placeholder for transforming a parameter substitution from
+ * the translation file format into a Dart interpolation. In our case we
+ * store it to the file in Dart interpolation syntax, so the transformation
+ * is trivial.
+ */
+String leaveTheInterpolationsInDartForm(IntlMessage msg, chunk) =>
+    (chunk is String) ? chunk : "\$${msg.arguments[chunk]}";
+
+/**
+ * Convert the [IntlMessage] to a trivial JSON format.
+ */
+Map toJson(IntlMessage message) {
+  return {
+    "name" : message.name,
+    "description" : message.description,
+    "message" : message.fullMessage(leaveTheInterpolationsInDartForm),
+    "examples" : message.examples,
+    "arguments" : message.arguments
+  };
+}
\ No newline at end of file
diff --git a/pkg/intl/test/message_extraction/find_output_directory.dart b/pkg/intl/test/message_extraction/find_output_directory.dart
new file mode 100644
index 0000000..bb62389
--- /dev/null
+++ b/pkg/intl/test/message_extraction/find_output_directory.dart
@@ -0,0 +1,19 @@
+/**
+ * A shared library for finding the valu eof the --output-dir parameter
+ * which all of these programs use.
+ */
+library find_output_directory;
+
+const directiveName = '--output-dir=';
+
+_asString(list) => new String.fromCharCodes(list);
+
+findOutputDirectory(List<String> args) {
+  var directive = args.firstWhere(
+      (x) => x.contains(directiveName),
+      orElse: () => null);
+  if (directive == null) return '.';
+  var file = directive.codeUnits.skip(directiveName.length);
+  return _asString(file);
+}
+
diff --git a/pkg/intl/test/message_extraction/generate_from_json.dart b/pkg/intl/test/message_extraction/generate_from_json.dart
new file mode 100644
index 0000000..7bbb878
--- /dev/null
+++ b/pkg/intl/test/message_extraction/generate_from_json.dart
@@ -0,0 +1,97 @@
+#!/usr/bin/env dart
+// 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.
+
+/**
+ * A main program that takes as input a source Dart file and a number
+ * of JSON files representing translations of messages from the corresponding
+ * Dart file. See extract_to_json.dart and make_hardcoded_translation.dart.
+ *
+ * This produces a series of files named
+ * "messages_<locale>.dart" containing messages for a particular locale
+ * and a main import file named "messages_all.dart" which has imports all of
+ * them and provides an initializeMessages function.
+ */
+library generate_from_json;
+
+import 'dart:io';
+import 'package:intl/extract_messages.dart';
+import 'package:intl/src/intl_message.dart';
+import 'extract_to_json.dart';
+import 'package:intl/generate_localized.dart';
+import 'dart:json' as json;
+import 'package:pathos/path.dart' as path;
+import 'find_output_directory.dart';
+
+/**
+ * Keeps track of all the messages we have processed so far, keyed by message
+ * name.
+ */
+Map<String, IntlMessage> messages;
+
+main() {
+  var args = new Options().arguments;
+  if (args.length == 0) {
+    print('Usage: generate_from_json [--output-dir=<dir>] [originalFiles.dart]'
+        ' [translationFiles.json]');
+    exit(0);
+  }
+
+  var targetDir = findOutputDirectory(args);
+  var isDart = new RegExp(r'\.dart');
+  var isJson = new RegExp(r'\.json');
+  var dartFiles = args.where(isDart.hasMatch).toList();
+  var jsonFiles = args.where(isJson.hasMatch).toList();
+
+  var allMessages = dartFiles.map((each) => parseFile(new File(each)));
+
+  messages = new Map();
+  for (var eachMap in allMessages) {
+    eachMap.forEach((key, value) => messages[key] = value);
+  }
+  for (var arg in jsonFiles) {
+    var file = new File(path.join(targetDir, arg));
+    var translations = generateLocaleFile(file, targetDir);
+  }
+
+  var mainImportFile = new File(path.join(targetDir, 'messages_all.dart'));
+  mainImportFile.writeAsStringSync(generateMainImportFile());
+}
+
+/**
+ * Create the file of generated code for a particular locale. We read the json
+ * data and create [BasicTranslatedMessage] instances from everything,
+ * excluding only the special _locale attribute that we use to indicate the
+ * locale.
+ */
+void generateLocaleFile(File file, String targetDir) {
+  var src = file.readAsStringSync();
+  var data = json.parse(src);
+  var locale = data["_locale"];
+  allLocales.add(locale);
+
+  var translations = [];
+  data.forEach((key, value) {
+    if (key[0] != "_") {
+      translations.add(new BasicTranslatedMessage(key, value));
+    }
+  });
+  generateIndividualMessageFile(locale, translations, targetDir);
+}
+
+/**
+ * A TranslatedMessage that just uses the name as the id and knows how to look
+ * up its original message in our [messages].
+ */
+class BasicTranslatedMessage extends TranslatedMessage {
+  BasicTranslatedMessage(String name, String translated) :
+      super(name, translated);
+
+  IntlMessage get originalMessage =>
+      (super.originalMessage == null) ? _findOriginal() : super.originalMessage;
+
+  // We know that our [id] is the name of the message, which is used as the
+  //key in [messages].
+  IntlMessage _findOriginal() => originalMessage = messages[id];
+}
\ No newline at end of file
diff --git a/pkg/intl/test/message_extraction/make_hardcoded_translation.dart b/pkg/intl/test/message_extraction/make_hardcoded_translation.dart
new file mode 100644
index 0000000..3f7977c
--- /dev/null
+++ b/pkg/intl/test/message_extraction/make_hardcoded_translation.dart
@@ -0,0 +1,105 @@
+#!/usr/bin/env dart
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * This simulates a translation process, reading the messages generated
+ * from extract_message.dart for the files sample_with_messages.dart and
+ * part_of_sample_with_messages.dart and writing out hard-coded translations for
+ * German and French locales.
+ */
+
+import 'dart:io';
+import 'dart:json' as json;
+import 'package:pathos/path.dart' as path;
+import 'find_output_directory.dart';
+
+/** A list of the French translations that we will produce. */
+var french = {
+  "types" : r"$a, $b, $c",
+  "multiLine" : "Cette message prend plusiers lignes.",
+  "message2" : r"Un autre message avec un seul paramètre $x",
+  "alwaysTranslated" : "Cette chaîne est toujours traduit",
+  "message1" : "Il s'agit d'un message",
+  "leadingQuotes" : "\"Soi-disant\"",
+  "trickyInterpolation" : r"L'interpolation est délicate "
+    r"quand elle se termine une phrase comme ${s}.",
+  "message3" : "Caractères qui doivent être échapper, par exemple barres \\ "
+    "dollars \${ (les accolades sont ok), et xml/html réservés <& et "
+    "des citations \" "
+    "avec quelques paramètres ainsi \$a, \$b, et \$c",
+  "method" : "Cela vient d'une méthode",
+  "nonLambda" : "Cette méthode n'est pas un lambda",
+  "staticMessage" : "Cela vient d'une méthode statique",
+  "notAlwaysTranslated" : "Ce manque certaines traductions",
+  "thisNameIsNotInTheOriginal" : "Could this lead to something malicious?",
+  "originalNotInBMP" : "Anciens caractères grecs jeux du pendu: 𐅆𐅇.",
+  "plural" : """Une des choses difficiles est \${Intl.plural(num,
+      {
+        '0' : 'la forme plurielle',
+        '1' : 'la forme plurielle',
+        'other' : 'des formes plurielles'})}""",
+   "namedArgs" : "La chose est, \$thing",
+   "escapable" : "Escapes: \n\r\f\b\t\v."
+};
+
+/** A list of the German translations that we will produce. */
+var german = {
+  "types" : r"$a, $b, $c",
+  "multiLine" : "Dieser String erstreckt sich über mehrere Zeilen erstrecken.",
+  "message2" : r"Eine weitere Meldung mit dem Parameter $x",
+  "alwaysTranslated" : "Diese Zeichenkette wird immer übersetzt",
+  "message1" : "Dies ist eine Nachricht",
+  "leadingQuotes" : "\"Sogenannt\"",
+  "trickyInterpolation" :
+    r"Interpolation ist schwierig, wenn es einen Satz wie dieser endet ${s}.",
+  "message3" : "Zeichen, die Flucht benötigen, zB Schrägstriche \\ Dollar "
+    "\${ (geschweiften Klammern sind ok) und xml reservierte Zeichen <& und "
+    "Zitate \" Parameter \$a, \$b und \$c",
+  "method" : "Dies ergibt sich aus einer Methode",
+  "nonLambda" : "Diese Methode ist nicht eine Lambda",
+  "staticMessage" : "Dies ergibt sich aus einer statischen Methode",
+  "originalNotInBMP" : "Antike griechische Galgenmännchen Zeichen: 𐅆𐅇",
+  "plurals" : """\${Intl.plural(num,
+      {
+        '0' : 'Einer der knifflige Dinge ist der Plural',
+        '1' : 'Einer der knifflige Dinge ist der Plural',
+        'other' : 'Zu den kniffligen Dinge Pluralformen'
+      })}""",
+   "namedArgs" : "Die Sache ist, \$thing",
+   "escapable" : "Escapes: \n\r\f\b\t\v."
+};
+
+/** The output directory for translated files. */
+String targetDir;
+
+/**
+ * Generate a translated json version from [originals] in [locale] looking
+ * up the translations in [translations].
+ */
+void translate(List originals, String locale, Map translations) {
+  var translated = {"_locale" : locale};
+  for (var each in originals) {
+    var name = each["name"];
+    translated[name] = translations[name];
+  }
+  var file = new File(path.join(targetDir, 'translation_$locale.json'));
+  file.writeAsStringSync(json.stringify(translated));
+}
+
+main() {
+  var args = new Options().arguments;
+  if (args.length == 0) {
+    print('Usage: generate_hardcoded_translation [--output-dir=<dir>] '
+        '[originalFile.dart]');
+    exit(0);
+  }
+
+  targetDir = findOutputDirectory(args);
+  var fileArgs = args.where((x) => x.contains('.json'));
+
+  var messages = json.parse(new File(fileArgs.first).readAsStringSync());
+  translate(messages, "fr", french);
+  translate(messages, "de_DE", german);
+}
\ No newline at end of file
diff --git a/pkg/intl/test/message_extraction/message_extraction_test.dart b/pkg/intl/test/message_extraction/message_extraction_test.dart
new file mode 100644
index 0000000..0b00fdb
--- /dev/null
+++ b/pkg/intl/test/message_extraction/message_extraction_test.dart
@@ -0,0 +1,222 @@
+// 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 message_extraction_test;
+
+import 'package:unittest/unittest.dart';
+import 'dart:io';
+import 'dart:async';
+import 'package:pathos/path.dart' as path;
+import '../data_directory.dart';
+
+final dart = new Options().executable;
+
+// TODO(alanknight): We have no way of knowing what the package-root is,
+// so when we're running under the test framework, which sets the
+// package-root, we use a horrible hack and infer it from the executable.
+final packageDir = _findPackageDir(dart);
+
+/**
+ * Find our package directory from the executable. If we seem to be running
+ * from out/Release<arch>/dart or the equivalent Debug, then use the packages
+ * directory under Release<arch>. Otherwise return null, indicating to use
+ * the normal pub packages directory.
+ */
+String _findPackageDir(executable) {
+  var oneUp = path.dirname(executable);
+  var tail = path.basename(oneUp);
+  // If we're running from test.dart, we want e.g. out/ReleaseIA32/packages
+  if (tail.contains('Release') || tail.contains('Debug')) {
+      return path.join(oneUp, 'packages/');
+  }
+  // Check for the case where we're running Release<arch>/dart-sdk/bin/dart
+  // (pub bots)
+  var threeUp = path.dirname(path.dirname(oneUp));
+  tail = path.basename(threeUp);
+  if (tail.contains('Release') || tail.contains('Debug')) {
+      return path.join(threeUp, 'packages/');
+  }
+  // Otherwise we will rely on the normal packages directory.
+  return null;
+}
+
+/** If our package root directory is set, return it as a VM argument. */
+final vmArgs = (packageDir == null) ? [] : ['--package-root=$packageDir'];
+
+/**
+ * Translate a file path into this test directory, regardless of the
+ * working directory.
+ */
+String dir([String s]) =>
+    path.join(intlDirectory, 'test', 'message_extraction', s);
+
+main() {
+  test("Test round trip message extraction, translation, code generation, "
+      "and printing", () {
+    deleteGeneratedFiles();
+    extractMessages(null).then((result) {
+      return generateTranslationFiles(result);
+    }).then((result) {
+      return generateCodeFromTranslation(result);
+    }).then((result) {
+      return runGeneratedCode(result);
+    }).then(verifyResult);
+  });
+}
+
+void deleteGeneratedFiles() {
+  var files = [dir('intl_messages.json'), dir('translation_fr.json'),
+      dir('messages_fr.dart'), dir('message_de_DE.dart'),
+      dir('messages_all.dart')];
+  files.map((name) => new File(name)).forEach((x) {
+    if (x.existsSync()) x.deleteSync();});
+}
+
+/**
+ * Run the process with the given list of filenames, which we assume
+ * are in dir() and need to be qualified in case that's not our working
+ * directory.
+ */
+Future<ProcessResult> run(ProcessResult previousResult, List<String> filenames)
+{
+  // If there's a failure in one of the sub-programs, print its output.
+  if (previousResult != null) {
+    if (previousResult.exitCode != 0) {
+      print("Error running sub-program:");
+    }
+    print(previousResult.stdout);
+    print(previousResult.stderr);
+    print("exitCode=${previousResult.exitCode}");
+  }
+  var filesInTheRightDirectory = filenames.map((x) => dir(x)).toList();
+  // Inject the script argument --output-dir in between the script and its
+  // arguments.
+  var args = []
+      ..addAll(vmArgs)
+      ..add(filesInTheRightDirectory.first)
+      ..addAll(["--output-dir=${dir()}"])
+      ..addAll(filesInTheRightDirectory.skip(1));
+  var options = new ProcessOptions()
+      ..stdoutEncoding=Encoding.UTF_8
+      ..stderrEncoding=Encoding.UTF_8;
+  var result = Process.run(dart, args);
+  return result;
+}
+
+Future<ProcessResult> extractMessages(ProcessResult previousResult) => run(
+    previousResult,
+    ['extract_to_json.dart', 'sample_with_messages.dart',
+        'part_of_sample_with_messages.dart']);
+
+Future<ProcessResult> generateTranslationFiles(ProcessResult previousResult) =>
+    run(
+        previousResult,
+        ['make_hardcoded_translation.dart', 'intl_messages.json']);
+
+Future<ProcessResult> generateCodeFromTranslation(ProcessResult previousResult)
+    => run(
+        previousResult,
+        ['generate_from_json.dart', 'sample_with_messages.dart',
+             'part_of_sample_with_messages.dart', 'translation_fr.json',
+             'translation_de_DE.json' ]);
+
+Future<ProcessResult> runGeneratedCode(ProcessResult previousResult) =>
+    run(previousResult, ['sample_with_messages.dart']);
+
+void verifyResult(results) {
+  var lineIterator;
+  verify(String s) {
+    lineIterator.moveNext();
+    var value = lineIterator.current;
+    expect(value, s);
+  }
+
+  var output = results.stdout;
+  var lines = output.split("\n");
+  // If it looks like these are CRLF delimited, then use that. Wish strings
+  // just implemented last.
+  if (lines.first.codeUnits.last == "\r".codeUnits.first) {
+    lines = output.split("\r\n");
+  }
+  lineIterator = lines.iterator..moveNext();
+  verify("Printing messages for en_US");
+  verify("This is a message");
+  verify("Another message with parameter hello");
+  verify("Characters that need escaping, e.g slashes \\ dollars \${ "
+      "(curly braces are ok) and xml reserved characters <& and "
+      "quotes \" parameters 1, 2, and 3");
+  verify("This string extends across multiple lines.");
+  verify("1, b, [c, d]");
+  verify('"So-called"');
+  verify("Cette chaîne est toujours traduit");
+  verify("Interpolation is tricky when it ends a sentence like this.");
+  verify("This comes from a method");
+  verify("This method is not a lambda");
+  verify("This comes from a static method");
+  verify("This is missing some translations");
+  verify("Ancient Greek hangman characters: 𐅆𐅇.");
+//  verify("The thing is, well");
+//  verify("One of the tricky things is the plural form");
+//  verify("One of the tricky things is plural forms");
+  verify("Escapable characters here: ");
+
+  var fr_lines = lines.skip(1).skipWhile(
+      (line) => !line.contains('----')).toList();
+  lineIterator = fr_lines.iterator..moveNext();
+  verify("Printing messages for fr");
+  verify("Il s'agit d'un message");
+  verify("Un autre message avec un seul paramètre hello");
+  verify(
+      "Caractères qui doivent être échapper, par exemple barres \\ "
+      "dollars \${ (les accolades sont ok), et xml/html réservés <& et "
+      "des citations \" "
+      "avec quelques paramètres ainsi 1, 2, et 3");
+  verify("Cette message prend plusiers lignes.");
+  verify("1, b, [c, d]");
+  verify('"Soi-disant"');
+  verify("Cette chaîne est toujours traduit");
+  verify(
+      "L'interpolation est délicate quand elle se termine une "
+          "phrase comme this.");
+  verify("Cela vient d'une méthode");
+  verify("Cette méthode n'est pas un lambda");
+  verify("Cela vient d'une méthode statique");
+  verify("Ce manque certaines traductions");
+  verify("Anciens caractères grecs jeux du pendu: 𐅆𐅇.");
+//  verify("La chose est, well");
+//  verify("Une des choses difficiles est la forme plurielle");
+//  verify("Une des choses difficiles est les formes plurielles");
+  verify("Escapes: ");
+  verify("\r\f\b\t\v.");
+
+
+  var de_lines = fr_lines.skip(1).skipWhile(
+      (line) => !line.contains('----')).toList();
+  lineIterator = de_lines.iterator..moveNext();
+  verify("Printing messages for de_DE");
+  verify("Dies ist eine Nachricht");
+  verify("Eine weitere Meldung mit dem Parameter hello");
+  verify(
+      "Zeichen, die Flucht benötigen, zB Schrägstriche \\ Dollar "
+      "\${ (geschweiften Klammern sind ok) und xml reservierte Zeichen <& und "
+      "Zitate \" Parameter 1, 2 und 3");
+  verify("Dieser String erstreckt sich über mehrere "
+      "Zeilen erstrecken.");
+  verify("1, b, [c, d]");
+  verify('"Sogenannt"');
+  // This is correct, the message is forced to French, even in a German locale.
+  verify("Cette chaîne est toujours traduit");
+  verify(
+      "Interpolation ist schwierig, wenn es einen Satz wie dieser endet this.");
+  verify("Dies ergibt sich aus einer Methode");
+  verify("Diese Methode ist nicht eine Lambda");
+  verify("Dies ergibt sich aus einer statischen Methode");
+  verify("This is missing some translations");
+  verify("Antike griechische Galgenmännchen Zeichen: 𐅆𐅇");
+//  verify("Die Sache ist, well");
+//  expect("Einer der knifflige Dinge ist der Plural");
+//  expect("Zu den kniffligen Dinge Pluralformen");
+  verify("Escapes: ");
+  verify("\r\f\b\t\v.");
+}
\ No newline at end of file
diff --git a/pkg/intl/test/message_extraction/part_of_sample_with_messages.dart b/pkg/intl/test/message_extraction/part_of_sample_with_messages.dart
new file mode 100644
index 0000000..49cee07
--- /dev/null
+++ b/pkg/intl/test/message_extraction/part_of_sample_with_messages.dart
@@ -0,0 +1,34 @@
+// 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.part of sample;
+
+part of sample;
+
+class YouveGotMessages {
+
+  // A static message, rather than a standalone function.
+  static staticMessage() => Intl.message("This comes from a static method",
+      name: 'staticMessage');
+
+  // An instance method, rather than a standalone function.
+  method() => Intl.message("This comes from a method", name: 'method');
+
+  // A non-lambda, i.e. not using => syntax, and with an additional statement
+  // before the Intl.message call.
+  nonLambda() {
+    // TODO(alanknight): I'm really not sure that this shouldn't be disallowed.
+    var x = 'something';
+    return Intl.message("This method is not a lambda", name: 'nonLambda');
+  }
+
+// TODO(alanknight): Support plurals and named arguments.
+//  plurals(num) => Intl.message("""
+//One of the tricky things is ${Intl.plural(num,
+//      {
+//        '0' : 'the plural form',
+//        '1' : 'the plural form',
+//        'other' : 'plural forms'})}""",
+//    name: "plurals");
+//
+//namedArgs({thing}) => Intl.message("The thing is, $thing", name: "namedArgs");
+}
diff --git a/pkg/intl/test/message_extraction/sample_with_messages.dart b/pkg/intl/test/message_extraction/sample_with_messages.dart
new file mode 100644
index 0000000..ada1d79
--- /dev/null
+++ b/pkg/intl/test/message_extraction/sample_with_messages.dart
@@ -0,0 +1,132 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * This is a program with various [Intl.message] messages. It just prints
+ * all of them, and is used for testing of message extraction, translation,
+ * and code generation.
+ */
+library sample;
+
+import "package:intl/intl.dart";
+import "package:intl/message_lookup_by_library.dart";
+import "dart:async";
+import "package:intl/src/intl_helpers.dart";
+import "messages_all.dart";
+
+part 'part_of_sample_with_messages.dart';
+
+message1() => Intl.message("This is a message", name: 'message1', desc: 'foo' );
+
+message2(x) => Intl.message("Another message with parameter $x",
+    name: 'message2', desc: 'Description 2', args: [x]);
+
+// A string with multiple adjacent strings concatenated together, verify
+// that the parser handles this properly.
+multiLine() => Intl.message("This "
+    "string "
+    "extends "
+    "across "
+    "multiple "
+    "lines.",
+    name: "multiLine");
+
+// Have types on the enclosing function's arguments.
+types(int a, String b, List c) => Intl.message("$a, $b, $c", name: 'types',
+    args: [a, b, c]);
+
+// This string will be printed with a French locale, so it will always show
+// up in the French version, regardless of the current locale.
+alwaysAccented() =>
+    Intl.message("This string is always translated", locale: 'fr',
+        name: 'alwaysTranslated');
+
+// Test interpolation with curly braces around the expression, but it must
+// still be just a variable reference.
+trickyInterpolation(s) =>
+    Intl.message("Interpolation is tricky when it ends a sentence like ${s}.",
+        name: 'trickyInterpolation', args: [s]);
+
+leadingQuotes() => Intl.message("\"So-called\"", name: 'leadingQuotes');
+
+// A message with characters not in the basic multilingual plane.
+originalNotInBMP() => Intl.message("Ancient Greek hangman characters: 𐅆𐅇.",
+    name: "originalNotInBMP");
+
+// A string for which we don't provide all translations.
+notAlwaysTranslated() => Intl.message("This is missing some translations",
+    name: "notAlwaysTranslated");
+
+// This is invalid and should be recognized as such, because the message has
+// to be a literal. Otherwise, interpolations would be outside of the function
+// scope.
+var someString = "No, it has to be a literal string";
+noVariables() => Intl.message(someString, name: "noVariables");
+
+// This is unremarkable in English, but the translated versions will contain
+// characters that ought to be escaped during code generation.
+escapable() => Intl.message("Escapable characters here: ", name: "escapable");
+
+printStuff(Intl locale) {
+
+  // Use a name that's not a literal so this will get skipped. Then we have
+  // a name that's not in the original but we include it in the French
+  // translation. Because it's not in the original it shouldn't get included
+  // in the generated catalog and shouldn't get translated.
+  if (locale.locale == 'fr') {
+    var badName = "thisNameIsNotInTheOriginal";
+    var notInOriginal = Intl.message("foo", name: badName);
+    if (notInOriginal != "foo") {
+      throw "You shouldn't be able to introduce a new message in a translation";
+    }
+  }
+
+  // A function that is unnamed and assigned to a variable. It's also nested
+  // within another function definition.
+  var messageVariable = (a, b, c) => Intl.message(
+      "Characters that need escaping, e.g slashes \\ dollars \${ (curly braces "
+      "are ok) and xml reserved characters <& and quotes \" "
+      "parameters $a, $b, and $c",
+      name: 'message3',
+      args: [a, b, c]);
+
+  print("-------------------------------------------");
+  print("Printing messages for ${locale.locale}");
+  Intl.withLocale(locale.locale, () {
+    print(message1());
+    print(message2("hello"));
+    print(messageVariable(1,2,3));
+    print(multiLine());
+    print(types(1, "b", ["c", "d"]));
+    print(leadingQuotes());
+    print(alwaysAccented());
+    print(trickyInterpolation("this"));
+    var thing = new YouveGotMessages();
+    print(thing.method());
+    print(thing.nonLambda());
+    var x = YouveGotMessages.staticMessage();
+    print(YouveGotMessages.staticMessage());
+    print(notAlwaysTranslated());
+    print(originalNotInBMP());
+    // TODO(alanknight): Support named arguments.
+//    print(thing.namedArgs(thing: 'well...'));
+    // TODO(alanknight): Support plurals. Do we need to consider changing
+    // the form so as not to have a difficult to validate interpolation
+    // in our translation output?
+//    print(thing.plurals(1));
+//    print(thing.plurals(2));
+    print(escapable());
+  });
+}
+
+var localeToUse = 'en_US';
+
+main() {
+  var fr = new Intl("fr");
+  var english = new Intl("en_US");
+  var de = new Intl("de_DE");
+  initializeMessages(fr.locale).then((_) => printStuff(fr));
+  initializeMessages(de.locale).then((_) => printStuff(de));
+  printStuff(english);
+}
\ No newline at end of file
diff --git a/pkg/oauth2/lib/src/authorization_code_grant.dart b/pkg/oauth2/lib/src/authorization_code_grant.dart
index b199579..342c726 100644
--- a/pkg/oauth2/lib/src/authorization_code_grant.dart
+++ b/pkg/oauth2/lib/src/authorization_code_grant.dart
@@ -8,7 +8,7 @@
 import 'dart:uri';
 
 // TODO(nweiz): This should be a "package:" import. See issue 6745.
-import '../../../http/lib/http.dart' as http;
+import '../../../../pkg/http/lib/http.dart' as http;
 
 import 'client.dart';
 import 'authorization_exception.dart';
diff --git a/pkg/oauth2/lib/src/client.dart b/pkg/oauth2/lib/src/client.dart
index fd315bb..6d4d042 100644
--- a/pkg/oauth2/lib/src/client.dart
+++ b/pkg/oauth2/lib/src/client.dart
@@ -7,7 +7,7 @@
 import 'dart:async';
 import 'dart:uri';
 
-import '../../../http/lib/http.dart' as http;
+import '../../../../pkg/http/lib/http.dart' as http;
 
 import 'authorization_exception.dart';
 import 'credentials.dart';
diff --git a/pkg/oauth2/lib/src/credentials.dart b/pkg/oauth2/lib/src/credentials.dart
index acc5690..bd9ab04 100644
--- a/pkg/oauth2/lib/src/credentials.dart
+++ b/pkg/oauth2/lib/src/credentials.dart
@@ -8,7 +8,7 @@
 import 'dart:json' as JSON;
 import 'dart:uri';
 
-import '../../../http/lib/http.dart' as http;
+import '../../../../pkg/http/lib/http.dart' as http;
 import 'handle_access_token_response.dart';
 import 'utils.dart';
 
diff --git a/pkg/oauth2/lib/src/handle_access_token_response.dart b/pkg/oauth2/lib/src/handle_access_token_response.dart
index 6443247..9f9e867 100644
--- a/pkg/oauth2/lib/src/handle_access_token_response.dart
+++ b/pkg/oauth2/lib/src/handle_access_token_response.dart
@@ -8,7 +8,7 @@
 import 'dart:json' as JSON;
 import 'dart:uri';
 
-import '../../../http/lib/http.dart' as http;
+import '../../../../pkg/http/lib/http.dart' as http;
 
 import 'credentials.dart';
 import 'authorization_exception.dart';
diff --git a/pkg/oauth2/test/authorization_code_grant_test.dart b/pkg/oauth2/test/authorization_code_grant_test.dart
index 0bc3433..ad784a5 100644
--- a/pkg/oauth2/test/authorization_code_grant_test.dart
+++ b/pkg/oauth2/test/authorization_code_grant_test.dart
@@ -9,9 +9,9 @@
 import 'dart:json' as JSON;
 import 'dart:uri';
 
-import '../../unittest/lib/unittest.dart';
-import '../../http/lib/http.dart' as http;
-import '../../http/lib/testing.dart';
+import '../../../pkg/unittest/lib/unittest.dart';
+import '../../../pkg/http/lib/http.dart' as http;
+import '../../../pkg/http/lib/testing.dart';
 import '../lib/oauth2.dart' as oauth2;
 import 'utils.dart';
 
diff --git a/pkg/oauth2/test/client_test.dart b/pkg/oauth2/test/client_test.dart
index b875de9..a815a22 100644
--- a/pkg/oauth2/test/client_test.dart
+++ b/pkg/oauth2/test/client_test.dart
@@ -9,8 +9,8 @@
 import 'dart:json' as JSON;
 import 'dart:uri';
 
-import '../../unittest/lib/unittest.dart';
-import '../../http/lib/http.dart' as http;
+import '../../../pkg/unittest/lib/unittest.dart';
+import '../../../pkg/http/lib/http.dart' as http;
 import '../lib/oauth2.dart' as oauth2;
 import 'utils.dart';
 
diff --git a/pkg/oauth2/test/credentials_test.dart b/pkg/oauth2/test/credentials_test.dart
index e6ad2a9..e21b301 100644
--- a/pkg/oauth2/test/credentials_test.dart
+++ b/pkg/oauth2/test/credentials_test.dart
@@ -9,8 +9,8 @@
 import 'dart:json' as JSON;
 import 'dart:uri';
 
-import '../../unittest/lib/unittest.dart';
-import '../../http/lib/http.dart' as http;
+import '../../../pkg/unittest/lib/unittest.dart';
+import '../../../pkg/http/lib/http.dart' as http;
 import '../lib/oauth2.dart' as oauth2;
 import 'utils.dart';
 
diff --git a/pkg/oauth2/test/handle_access_token_response_test.dart b/pkg/oauth2/test/handle_access_token_response_test.dart
index 3e95ddc..e39ee56 100644
--- a/pkg/oauth2/test/handle_access_token_response_test.dart
+++ b/pkg/oauth2/test/handle_access_token_response_test.dart
@@ -8,8 +8,8 @@
 import 'dart:json' as JSON;
 import 'dart:uri';
 
-import '../../unittest/lib/unittest.dart';
-import '../../http/lib/http.dart' as http;
+import '../../../pkg/unittest/lib/unittest.dart';
+import '../../../pkg/http/lib/http.dart' as http;
 import '../lib/oauth2.dart' as oauth2;
 import '../lib/src/handle_access_token_response.dart';
 import 'utils.dart';
diff --git a/pkg/oauth2/test/utils.dart b/pkg/oauth2/test/utils.dart
index 0935658..04b194e 100644
--- a/pkg/oauth2/test/utils.dart
+++ b/pkg/oauth2/test/utils.dart
@@ -7,9 +7,9 @@
 import 'dart:async';
 import 'dart:collection' show Queue;
 
-import '../../unittest/lib/unittest.dart';
-import '../../http/lib/http.dart' as http;
-import '../../http/lib/testing.dart';
+import '../../../pkg/unittest/lib/unittest.dart';
+import '../../../pkg/http/lib/http.dart' as http;
+import '../../../pkg/http/lib/testing.dart';
 import '../lib/oauth2.dart' as oauth2;
 
 class ExpectClient extends MockClient {
diff --git a/pkg/oauth2/test/utils_test.dart b/pkg/oauth2/test/utils_test.dart
index d76e2b0..2fa4b73 100644
--- a/pkg/oauth2/test/utils_test.dart
+++ b/pkg/oauth2/test/utils_test.dart
@@ -4,7 +4,7 @@
 
 library utils_test;
 
-import '../../unittest/lib/unittest.dart';
+import '../../../pkg/unittest/lib/unittest.dart';
 import '../lib/src/utils.dart';
 
 
diff --git a/pkg/pkg.status b/pkg/pkg.status
index d139d96..e919f3d 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -12,6 +12,11 @@
 # Skip non-test files ending with "_test".
 scheduled_test/lib/*: Skip
 
+# WebDriver tests have 3rd party dependencies (we need to run
+# selenium_standalone.jar), so we skip these in our automated
+# testing.
+webdriver/test/webdriver_test: Skip
+
 [$compiler == dart2dart]
 *: Skip
 
@@ -33,11 +38,13 @@
 intl/test/date_time_format_file_even_test: Skip
 intl/test/date_time_format_file_odd_test: Skip
 intl/test/find_default_locale_standalone_test: Skip
-analyzer-experimental/test/options_test: Skip # Imports dart:io.
-analyzer-experimental/test/generated/parser_test: Skip # Imports dart:io.
-analyzer-experimental/test/generated/scanner_test: Skip # Imports dart:io.
-analyzer-experimental/test/generated/element_test: Skip # Imports dart:io.
-analyzer-experimental/test/generated/ast_test: Skip # Imports dart:io.
+intl/test/message_extraction/message_extraction_test: Skip
+analyzer_experimental/test/options_test: Skip # Imports dart:io.
+analyzer_experimental/test/generated/ast_test: Skip # Imports dart:io.
+analyzer_experimental/test/generated/element_test: Skip # Imports dart:io.
+analyzer_experimental/test/generated/parser_test: Skip # Imports dart:io.
+analyzer_experimental/test/generated/resolver_test: Skip # Imports dart:io.
+analyzer_experimental/test/generated/scanner_test: Skip # Imports dart:io.
 
 # Issue 8440 forces us to use pathos in the scheduled_test tests, which would
 # otherwise be dart2js-compatible.
@@ -47,16 +54,17 @@
 intl/test/find_default_locale_browser_test: Fail
 intl/test/date_time_format_http_request_test: Skip # Timeout.
 
+[ $runtime == ie9 ]
+intl/test/date_time_format_http_request_test: Fail # Issue 8983
+
 # Skip browser-specific Intl tests on VM
 [ $runtime == vm ]
 intl/test/find_default_locale_browser_test: Skip
 intl/test/date_time_format_http_request_test: Skip
 
-# Fails to recognize HashMap as an instance of Map.
-analyzer-experimental/test/generated/ast_test: Fail
-
 [ $runtime == vm && $system == windows ]
 intl/test/find_default_locale_standalone_test: Fail # Issue 8110
+intl/test/message_extraction/message_extraction_test: Fail # Issue 9167
 
 # Skip http request tests on Dartium while resolving an odd
 # error there that causes the tests to timeout.
@@ -66,13 +74,12 @@
 [ $compiler == dart2js ]
 # Skip intl_message tests that use mirrors on dart2js until it's been
 # implemented there.
-intl/test/intl_message_test: Skip
-intl/test/intl_message_basic_example_test: Skip
 serialization/test/serialization_test: Skip
-analyzer-experimental/test/generated/parser_test: Skip
-analyzer-experimental/test/generated/scanner_test: Skip
-analyzer-experimental/test/generated/element_test: Skip
-analyzer-experimental/test/generated/ast_test: Skip
+analyzer_experimental/test/generated/ast_test: Skip
+analyzer_experimental/test/generated/element_test: Skip
+analyzer_experimental/test/generated/parser_test: Skip
+analyzer_experimental/test/generated/resolver_test: Skip
+analyzer_experimental/test/generated/scanner_test: Skip
 
 [ $compiler == dartc ]
 unittest/test/mock_regexp_negative_test: Fail
@@ -82,6 +89,15 @@
 [ $compiler == dart2js ]
 unittest/test/instance_test: Skip
 
+[ $compiler == dart2js && $runtime == drt ]
+intl/test/date_time_format_uninitialized_test: Pass, Fail # http://dartbug.com/9000
+
+[ $compiler == dart2js && $minified ]
+# The unittest package relies on getting the original (non-minified) method
+# names in InvocationMirrors.  You can't get that when minifying.
+unittest/test/mock_test: Fail
+unittest/test/mock_regexp_negative_test: Fail
+
 [ $compiler == none && $runtime == drt ]
 dartdoc/test/dartdoc_test: Skip # See dartbug.com/4541.
 
diff --git a/pkg/scheduled_test/lib/descriptor.dart b/pkg/scheduled_test/lib/descriptor.dart
index 60210f6..b8baeca 100644
--- a/pkg/scheduled_test/lib/descriptor.dart
+++ b/pkg/scheduled_test/lib/descriptor.dart
@@ -64,7 +64,7 @@
 
 import 'dart:async';
 
-import 'package:pathos/path.dart' as path;
+import '../../../pkg/pathos/lib/path.dart' as path;
 
 import 'scheduled_test.dart';
 import 'src/descriptor/async.dart';
diff --git a/pkg/scheduled_test/lib/scheduled_process.dart b/pkg/scheduled_test/lib/scheduled_process.dart
new file mode 100644
index 0000000..0e277da
--- /dev/null
+++ b/pkg/scheduled_test/lib/scheduled_process.dart
@@ -0,0 +1,308 @@
+// 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 scheduled_process;
+
+import 'dart:async';
+import 'dart:io';
+
+import 'scheduled_test.dart';
+import 'src/utils.dart';
+import 'src/value_future.dart';
+
+/// A class representing a [Process] that is scheduled to run in the course of
+/// the test. This class allows actions on the process to be scheduled
+/// synchronously. All operations on this class are scheduled.
+///
+/// Before running the test, either [shouldExit] or [kill] must be called on
+/// this to ensure that the process terminates when expected.
+///
+/// If the test fails, this will automatically print out any stdout and stderr
+/// from the process to aid debugging.
+class ScheduledProcess {
+  // A description of the process. Used for error reporting.
+  String get description => _description;
+  String _description;
+
+  /// The encoding used for the process's input and output streams.
+  final Encoding _encoding;
+
+  /// The process that's scheduled to run.
+  ValueFuture<Process> _process;
+
+  /// A fork of [_stdout] that records the standard output of the process. Used
+  /// for debugging information.
+  Stream<String> _stdoutLog;
+
+  /// A line-by-line view of the standard output stream of the process.
+  Stream<String> _stdout;
+
+  /// A canceller that controls both [_stdout] and [_stdoutLog].
+  StreamCanceller _stdoutCanceller;
+
+  /// A fork of [_stderr] that records the standard error of the process. Used
+  /// for debugging information.
+  Stream<String> _stderrLog;
+
+  /// A line-by-line view of the standard error stream of the process.
+  Stream<String> _stderr;
+
+  /// A canceller that controls both [_stderr] and [_stderrLog].
+  StreamCanceller _stderrCanceller;
+
+  /// The exit code of the process that's scheduled to run. This will naturally
+  /// only complete once the process has terminated.
+  ValueFuture<int> _exitCode;
+
+  /// Whether the user has scheduled the end of this process by calling either
+  /// [shouldExit] or [kill].
+  var _endScheduled = false;
+
+  /// The task that runs immediately before this process is scheduled to end. If
+  /// the process ends during this task, we treat that as expected.
+  Task _taskBeforeEnd;
+
+  /// Whether the process is expected to terminate at this point.
+  var _endExpected = false;
+
+  /// Schedules a process to start. [executable], [arguments], and [options]
+  /// have the same meaning as for [Process.start]. [description] is a string
+  /// description of this process; it defaults to the command-line invocation.
+  /// [encoding] is the [Encoding] that will be used for the process's input and
+  /// output.
+  ///
+  /// [executable], [arguments], and [options] may be either a [Future] or a
+  /// concrete value. If any are [Future]s, the process won't start until the
+  /// [Future]s have completed. In addition, [arguments] may be a [List]
+  /// containing a mix of strings and [Future]s.
+  ScheduledProcess.start(executable, arguments,
+      {options, String description, Encoding encoding: Encoding.UTF_8})
+      : _encoding = encoding {
+    assert(currentSchedule.state == ScheduleState.SET_UP);
+
+    _updateDescription(executable, arguments);
+
+    _scheduleStartProcess(executable, arguments, options);
+
+    _scheduleExceptionCleanup();
+
+    var stdoutWithCanceller = _lineStreamWithCanceller(
+        _process.then((p) => p.stdout));
+    _stdoutCanceller = stdoutWithCanceller.last;
+    var stdoutTee = tee(stdoutWithCanceller.first);
+    _stdout = stdoutTee.first;
+    _stdoutLog = stdoutTee.last;
+
+    var stderrWithCanceller = _lineStreamWithCanceller(
+        _process.then((p) => p.stderr));
+    _stderrCanceller = stderrWithCanceller.last;
+    var stderrTee = tee(stderrWithCanceller.first);
+    _stderr = stderrTee.first;
+    _stderrLog = stderrTee.last;
+  }
+
+  /// Updates [_description] to reflect [executable] and [arguments], which are
+  /// the same values as in [start].
+  void _updateDescription(executable, arguments) {
+    if (executable is Future) {
+      _description = "future process";
+    } else if (arguments is Future || arguments.any((e) => e is Future)) {
+      _description = executable;
+    } else {
+      _description = "$executable ${arguments.map((a) => '"$a"').join(' ')}";
+    }
+  }
+
+  /// Schedules the process to start and sets [_process].
+  void _scheduleStartProcess(executable, arguments, options) {
+    var exitCodeCompleter = new Completer();
+    _exitCode = new ValueFuture(exitCodeCompleter.future);
+
+    _process = new ValueFuture(schedule(() {
+      if (!_endScheduled) {
+        throw new StateError("Scheduled process '$description' must "
+            "have shouldExit() or kill() called before the test is run.");
+      }
+
+      _handleExit(exitCodeCompleter);
+
+      return Future.wait([
+        new Future.of(() => executable),
+        awaitObject(arguments),
+        new Future.of(() => options)
+      ]).then((results) {
+        executable = results[0];
+        arguments = results[1];
+        options = results[2];
+        _updateDescription(executable, arguments);
+        return Process.start(executable, arguments, options).then((process) {
+          // TODO(nweiz): enable this when issue 9020 is fixed.
+          // process.stdin.encoding = Encoding.UTF_8;
+          return process;
+        });
+      });
+    }, "starting process '$description'"));
+  }
+
+  /// Listens for [_process] to exit and passes the exit code to
+  /// [exitCodeCompleter]. If the process completes earlier than expected, an
+  /// exception will be signaled to the schedule.
+  void _handleExit(Completer exitCodeCompleter) {
+    // We purposefully avoid using wrapFuture here. If an error occurs while a
+    // process is running, we want the schedule to move to the onException
+    // queue where the process will be killed, rather than blocking the tasks
+    // queue waiting for the process to exit.
+    _process.then((p) => p.exitCode).then((exitCode) {
+      if (_endExpected) {
+        exitCodeCompleter.complete(exitCode);
+        return;
+      }
+
+      wrapFuture(pumpEventQueue().then((_) {
+        if (currentSchedule.currentTask != _taskBeforeEnd) return;
+        // If we're one task before the end was scheduled, wait for that task
+        // to complete and pump the event queue so that _endExpected will be
+        // set.
+        return _taskBeforeEnd.result.then((_) => pumpEventQueue());
+      }).then((_) {
+        exitCodeCompleter.complete(exitCode);
+
+        if (!_endExpected) {
+          throw "Process '$description' ended earlier than scheduled "
+            "with exit code $exitCode.";
+        }
+      }), "waiting to reach shouldExit() or kill() for process "
+          "'$description'");
+    });
+  }
+
+  /// Converts a stream of bytes to a stream of lines and returns that along
+  /// with a [StreamCanceller] controlling it.
+  Pair<Stream<String>, StreamCanceller> _lineStreamWithCanceller(
+      Future<Stream<int>> streamFuture) {
+    return streamWithCanceller(futureStream(streamFuture)
+        .handleError((e) => currentSchedule.signalError(e))
+        .transform(new StringDecoder(_encoding))
+        .transform(new LineTransformer()));
+  }
+
+  /// Schedule an exception handler that will clean up the process and provide
+  /// debug information if an error occurs.
+  void _scheduleExceptionCleanup() {
+    currentSchedule.onException.schedule(() {
+      _stdoutCanceller();
+      _stderrCanceller();
+
+      if (!_process.hasValue) return;
+
+      var killedPrematurely = false;
+      if (!_exitCode.hasValue) {
+        killedPrematurely = true;
+        _endExpected = true;
+        _process.value.kill();
+        // Ensure that the onException queue waits for the process to actually
+        // exit after being killed.
+        wrapFuture(_process.value.exitCode, "waiting for process "
+            "'$description' to die");
+      }
+
+      return Future.wait([
+        _stdoutLog.toList(),
+        _stderrLog.toList()
+      ]).then((results) {
+        var stdout = results[0].join("\n");
+        var stderr = results[1].join("\n");
+
+        var exitDescription = killedPrematurely
+            ? "Process was killed prematurely."
+            : "Process exited with exit code ${_exitCode.value}.";
+        currentSchedule.addDebugInfo(
+            "Results of running '$description':\n"
+            "$exitDescription\n"
+            "Standard output:\n"
+            "${prefixLines(stdout)}\n"
+            "Standard error:\n"
+            "${prefixLines(stderr)}");
+      });
+    }, "cleaning up process '$description'");
+  }
+
+  /// Reads the next line of stdout from the process.
+  Future<String> nextLine() => schedule(() => streamFirst(_stdout),
+      "reading the next stdout line from process '$description'");
+
+  /// Reads the next line of stderr from the process.
+  Future<String> nextErrLine() => schedule(() => streamFirst(_stderr),
+      "reading the next stderr line from process '$description'");
+
+  /// Reads the remaining stdout from the process. This should only be called
+  /// after kill() or shouldExit().
+  Future<String> remainingStdout() {
+    if (!_endScheduled) {
+      throw new StateError("remainingStdout() should only be called after "
+          "kill() or shouldExit().");
+    }
+
+    return schedule(() => _stdout.toList().then((lines) => lines.join("\n")),
+        "reading the remaining stdout from process '$description'");
+  }
+
+  /// Reads the remaining stderr from the process. This should only be called
+  /// after kill() or shouldExit().
+  Future<String> remainingStderr() {
+    if (!_endScheduled) {
+      throw new StateError("remainingStderr() should only be called after "
+          "kill() or shouldExit().");
+    }
+
+    return schedule(() => _stderr.toList().then((lines) => lines.join("\n")),
+        "reading the remaining stderr from process '$description'");
+  }
+
+  /// Writes [line] to the process as stdin.
+  void writeLine(String line) {
+    schedule(() {
+      return _process.then((p) => p.stdin.writeln('$line'));
+    }, "writing '$line' to stdin for process '$description'");
+  }
+
+  /// Closes the process's stdin stream.
+  void closeStdin() {
+    schedule(() => _process.then((p) => p.stdin.close()),
+        "closing stdin for process '$description'");
+  }
+
+  /// Kills the process, and waits until it's dead.
+  void kill() {
+    if (_endScheduled) {
+      throw new StateError("shouldExit() or kill() already called.");
+    }
+
+    _endScheduled = true;
+    _taskBeforeEnd = currentSchedule.tasks.contents.last;
+    schedule(() {
+      _endExpected = true;
+      return _process.then((p) => p.kill()).then((_) => _exitCode);
+    }, "waiting for process '$description' to die");
+  }
+
+  /// Waits for the process to exit, and verifies that the exit code matches
+  /// [expectedExitCode] (if given).
+  void shouldExit([int expectedExitCode]) {
+    if (_endScheduled) {
+      throw new StateError("shouldExit() or kill() already called.");
+    }
+
+    _endScheduled = true;
+    _taskBeforeEnd = currentSchedule.tasks.contents.last;
+    schedule(() {
+      _endExpected = true;
+      return _exitCode.then((exitCode) {
+        if (expectedExitCode != null) {
+          expect(exitCode, equals(expectedExitCode));
+        }
+      });
+    }, "waiting for process '$description' to exit");
+  }
+}
diff --git a/pkg/scheduled_test/lib/scheduled_server.dart b/pkg/scheduled_test/lib/scheduled_server.dart
new file mode 100644
index 0000000..88d9807
--- /dev/null
+++ b/pkg/scheduled_test/lib/scheduled_server.dart
@@ -0,0 +1,106 @@
+// 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 scheduled_server;
+
+import 'dart:async';
+import 'dart:collection';
+import 'dart:io';
+import 'dart:uri';
+
+import 'scheduled_test.dart';
+import 'src/utils.dart';
+import 'src/scheduled_server/handler.dart';
+import 'src/scheduled_server/safe_http_server.dart';
+
+typedef Future ScheduledHandler(HttpRequest request);
+
+/// A class representing an [HttpServer] that's scheduled to run in the course
+/// of the test. This class allows the server's request handling to be scheduled
+/// synchronously.
+///
+/// The server expects requests to be received in the order [handle] is called,
+/// and expects that no additional requests will be received.
+class ScheduledServer {
+  /// The description of the server.
+  final String description;
+
+  /// The wrapped server.
+  final Future<HttpServer> _server;
+
+  /// The queue of handlers to run for upcoming requests. Each [Future] will
+  /// complete once the schedule reaches the point where that handler was
+  /// scheduled.
+  final _handlers = new Queue<Handler>();
+
+  /// The number of servers created. Used for auto-generating descriptions;
+  static var _count = 0;
+
+  ScheduledServer._(this._server, this.description);
+
+  /// Creates a new server listening on an automatically-allocated port on
+  /// localhost. [description] is used to refer to the server in debugging
+  /// messages.
+  factory ScheduledServer([String description]) {
+    var id = _count++;
+    if (description == null) description = 'scheduled server $id';
+
+    var scheduledServer;
+    scheduledServer = new ScheduledServer._(schedule(() {
+      return SafeHttpServer.bind("127.0.0.1", 0).then((server) {
+        server.listen(scheduledServer._handleRequest,
+            onError: (e) => currentSchedule.signalError(e));
+        currentSchedule.onComplete.schedule(server.close);
+        return server;
+      });
+    }, "starting '$description'"), description);
+    return scheduledServer;
+  }
+
+  /// The port on which the server is listening.
+  Future<int> get port => _server.then((s) => s.port);
+
+  /// The base URL of the server, including its port.
+  Future<Uri> get url => port.then((p) => Uri.parse("http://localhost:$p"));
+
+  /// Schedules [handler] to handle a request to the server with [method] and
+  /// [path]. The schedule will wait until an HTTP request is received. If that
+  /// request doesn't have the expected [method] and [path], it will fail.
+  /// Otherwise, it will run [fn]. If [fn] returns a [Future], the schedule will
+  /// wait until that [Future] completes.
+  ///
+  /// The request must be received at the point in the schedule at which
+  /// [handle] was called, or in the task immediately prior (to allow for
+  /// non-deterministic asynchronicity). Otherwise, an error will be thrown.
+  void handle(String method, String path, ScheduledHandler fn) {
+    var handler = new Handler(this, method, path, fn);
+    _handlers.add(handler);
+    schedule(() {
+      handler.ready = true;
+      return handler.result.catchError((e) {
+        // Close the server so that we don't leave a dangling request.
+        _server.then((s) => s.close());
+        throw e;
+      });
+    }, "'$description' waiting for $method $path");
+  }
+
+  /// The handler for incoming [HttpRequest]s to this server. This dispatches
+  /// the request to the first handler in the queue. It's that handler's
+  /// responsibility to check that the method/path are correct and that it's
+  /// being run at the correct time.
+  void _handleRequest(HttpRequest request) {
+    wrapFuture(new Future.of(() {
+      if (_handlers.isEmpty) {
+        throw "'$description' received ${request.method} ${request.uri.path} "
+            "when no more requests were expected.";
+      }
+      return _handlers.removeFirst().fn(request);
+    }).catchError((e) {
+      // Close the server so that we don't leave a dangling request.
+      _server.then((s) => s.close());
+      throw e;
+    }), 'receiving ${request.method} ${request.uri}');
+  }
+}
diff --git a/pkg/scheduled_test/lib/scheduled_test.dart b/pkg/scheduled_test/lib/scheduled_test.dart
index 587abb7..8451e18 100644
--- a/pkg/scheduled_test/lib/scheduled_test.dart
+++ b/pkg/scheduled_test/lib/scheduled_test.dart
@@ -175,18 +175,19 @@
 
 import 'dart:async';
 
-import 'package:unittest/unittest.dart' as unittest;
+import '../../../pkg/unittest/lib/unittest.dart' as unittest;
 
 import 'src/schedule.dart';
 import 'src/schedule_error.dart';
 import 'src/utils.dart';
 
-export 'package:unittest/matcher.dart';
-export 'package:unittest/unittest.dart' show
+export '../../../pkg/unittest/lib/matcher.dart' hide completes, completion;
+export '../../../pkg/unittest/lib/unittest.dart' show
     config, configure, Configuration, logMessage, expectThrow;
 
 export 'src/schedule.dart';
 export 'src/schedule_error.dart';
+export 'src/scheduled_future_matchers.dart';
 export 'src/task.dart';
 
 /// The [Schedule] for the current test. This is used to add new tasks and
@@ -316,13 +317,13 @@
 /// initialized.
 void _ensureInitialized() {
   unittest.ensureInitialized();
-  unittest.wrapAsync = (f, [id = '']) {
+  unittest.wrapAsync = (f, [description]) {
     if (currentSchedule == null) {
       throw new StateError("Unexpected call to wrapAsync with no current "
           "schedule.");
     }
 
-    return currentSchedule.wrapAsync(f);
+    return currentSchedule.wrapAsync(f, description);
   };
 }
 
@@ -332,11 +333,14 @@
 /// a single callback.
 ///
 /// The returned [Future] completes to the same value or error as [future].
-Future wrapFuture(Future future) {
+///
+/// [description] provides an optional description of the future, which is
+/// used when generating error messages.
+Future wrapFuture(Future future, [String description]) {
   if (currentSchedule == null) {
     throw new StateError("Unexpected call to wrapFuture with no current "
         "schedule.");
   }
 
-  return currentSchedule.wrapFuture(future);
+  return currentSchedule.wrapFuture(future, description);
 }
diff --git a/pkg/scheduled_test/lib/src/descriptor/directory.dart b/pkg/scheduled_test/lib/src/descriptor/directory.dart
index 978daef..594fb56 100644
--- a/pkg/scheduled_test/lib/src/descriptor/directory.dart
+++ b/pkg/scheduled_test/lib/src/descriptor/directory.dart
@@ -7,7 +7,7 @@
 import 'dart:async';
 import 'dart:io' as io;
 
-import 'package:pathos/path.dart' as path;
+import '../../../../../pkg/pathos/lib/path.dart' as path;
 
 import '../../descriptor.dart' as descriptor;
 import '../../scheduled_test.dart';
@@ -62,7 +62,7 @@
         throw "Found multiple entries named '${split.first}' within "
             "$nameDescription.";
       } else {
-        var remainingPath = split.getRange(1, split.length - 1);
+        var remainingPath = split.sublist(1);
         if (remainingPath.isEmpty) {
           return matchingEntries.first.read();
         } else {
@@ -90,7 +90,7 @@
 
     var lastEntryString = prefixLines(contents.last.describe(), prefix: '    ')
         .replaceFirst('    ', "'-- ");
-    buffer.add(lastEntryString);
+    buffer.write(lastEntryString);
     return buffer.toString();
   }
 }
diff --git a/pkg/scheduled_test/lib/src/descriptor/file.dart b/pkg/scheduled_test/lib/src/descriptor/file.dart
index 2fefb89..15b9ef4 100644
--- a/pkg/scheduled_test/lib/src/descriptor/file.dart
+++ b/pkg/scheduled_test/lib/src/descriptor/file.dart
@@ -9,7 +9,7 @@
 import 'dart:math' as math;
 import 'dart:utf';
 
-import 'package:pathos/path.dart' as path;
+import '../../../../../pkg/pathos/lib/path.dart' as path;
 
 import '../../descriptor.dart' as descriptor;
 import '../../scheduled_test.dart';
diff --git a/pkg/scheduled_test/lib/src/descriptor/nothing.dart b/pkg/scheduled_test/lib/src/descriptor/nothing.dart
index 048297e..9a1f1b4 100644
--- a/pkg/scheduled_test/lib/src/descriptor/nothing.dart
+++ b/pkg/scheduled_test/lib/src/descriptor/nothing.dart
@@ -7,7 +7,7 @@
 import 'dart:async';
 import 'dart:io';
 
-import 'package:pathos/path.dart' as path;
+import '../../../../../pkg/pathos/lib/path.dart' as path;
 
 import '../../descriptor.dart' as descriptor;
 import '../../scheduled_test.dart';
diff --git a/pkg/scheduled_test/lib/src/descriptor/utils.dart b/pkg/scheduled_test/lib/src/descriptor/utils.dart
index c649019..c53b429 100644
--- a/pkg/scheduled_test/lib/src/descriptor/utils.dart
+++ b/pkg/scheduled_test/lib/src/descriptor/utils.dart
@@ -6,7 +6,7 @@
 
 import 'dart:io';
 
-import 'package:pathos/path.dart' as path;
+import '../../../../../pkg/pathos/lib/path.dart' as path;
 
 /// Returns a single filesystem entry within [parent] whose name matches
 /// [pattern]. If [pattern] is a string, looks for an exact match; otherwise,
@@ -48,7 +48,7 @@
   if (pattern is! RegExp) return '$pattern';
 
   var flags = new StringBuffer();
-  if (!pattern.isCaseSensitive) flags.add('i');
-  if (pattern.isMultiLine) flags.add('m');
+  if (!pattern.isCaseSensitive) flags.write('i');
+  if (pattern.isMultiLine) flags.write('m');
   return '/${pattern.pattern}/$flags';
 }
diff --git a/pkg/scheduled_test/lib/src/mock_clock.dart b/pkg/scheduled_test/lib/src/mock_clock.dart
index bda216f..d60e418 100644
--- a/pkg/scheduled_test/lib/src/mock_clock.dart
+++ b/pkg/scheduled_test/lib/src/mock_clock.dart
@@ -86,20 +86,14 @@
   /// The subscription to the [Clock.onTick] stream.
   StreamSubscription _subscription;
 
-  // TODO(nweiz): Remove this when issue 8512 is fixed.
-  var _cancelled = false;
-
   _MockTimer(Duration duration, this._callback)
       : _time = _clock.time + duration.inMilliseconds {
     _subscription = _clock.onTick.listen((time) {
-      if (_cancelled || time < _time) return;
+      if (time < _time) return;
       _subscription.cancel();
       _callback();
     });
   }
 
-  void cancel() {
-    _cancelled = true;
-    _subscription.cancel();
-  }
+  void cancel() => _subscription.cancel();
 }
diff --git a/pkg/scheduled_test/lib/src/schedule.dart b/pkg/scheduled_test/lib/src/schedule.dart
index 17ab86a..1e97ecc 100644
--- a/pkg/scheduled_test/lib/src/schedule.dart
+++ b/pkg/scheduled_test/lib/src/schedule.dart
@@ -7,12 +7,13 @@
 import 'dart:async';
 import 'dart:collection';
 
-import 'package:unittest/unittest.dart' as unittest;
+import '../../../../pkg/unittest/lib/unittest.dart' as unittest;
 
 import 'mock_clock.dart' as mock_clock;
 import 'schedule_error.dart';
 import 'substitute_future.dart';
 import 'task.dart';
+import 'value_future.dart';
 
 /// The schedule of tasks to run for a single test. This has three separate task
 /// queues: [tasks], [onComplete], and [onException]. It also provides
@@ -60,7 +61,6 @@
   ScheduleState _state = ScheduleState.SET_UP;
 
   // TODO(nweiz): make this a read-only view once issue 8321 is fixed.
-
   /// Errors thrown by the task queues.
   ///
   /// When running tasks in [tasks], this will always be empty. If an error
@@ -74,6 +74,10 @@
   /// added to this list.
   final errors = <ScheduleError>[];
 
+  // TODO(nweiz): make this a read-only view once issue 8321 is fixed.
+  /// Additional debugging info registered via [addDebugInfo].
+  final debugInfo = <String>[];
+
   /// The task queue that's currently being run. One of [tasks], [onException],
   /// or [onComplete]. This starts as [tasks], and can only be `null` after the
   /// schedule is done.
@@ -98,15 +102,6 @@
     heartbeat();
   }
 
-  /// The number of out-of-band callbacks that have been registered with
-  /// [wrapAsync] but have yet to be called.
-  int _pendingCallbacks = 0;
-
-  /// A completer that will be completed once [_pendingCallbacks] reaches zero.
-  /// This will only be non-`null` if [_awaitPendingCallbacks] has been called
-  /// while [_pendingCallbacks] is non-zero.
-  Completer _noPendingCallbacks;
-
   /// The timer for keeping track of task timeouts. This may be null.
   Timer _timeoutTimer;
 
@@ -162,6 +157,21 @@
     });
   }
 
+  /// Stop the current [TaskQueue] after the current task and any out-of-band
+  /// tasks stop executing. If this is called before [this] has started running,
+  /// no tasks in the [tasks] queue will be run.
+  ///
+  /// This won't cause an error, but any errors that are otherwise signaled will
+  /// still cause the test to fail.
+  void abort() {
+    if (_state == ScheduleState.DONE) {
+      throw new StateError("Called abort() after the schedule has finished "
+          "running.");
+    }
+
+    currentQueue._abort();
+  }
+
   /// Signals that an out-of-band error has occurred. Using [wrapAsync] along
   /// with `throw` is usually preferable to calling this directly.
   ///
@@ -185,6 +195,12 @@
     }
   }
 
+  /// Adds [info] to the debugging output that will be printed if the test
+  /// fails. Unlike [signalError], this won't cause the test to fail, nor will
+  /// it short-circuit the current [TaskQueue]; it's just useful for providing
+  /// additional information that may not fit cleanly into an existing error.
+  void addDebugInfo(String info) => debugInfo.add(info);
+
   /// Notifies the schedule of an error that occurred in a task or out-of-band
   /// callback after the appropriate queue has timed out. If this schedule is
   /// still running, the error will be added to the errors list to be shown
@@ -205,39 +221,19 @@
   /// the returned function has been called. It's used to ensure that
   /// out-of-band callbacks are properly handled by the scheduled test.
   ///
+  /// [description] provides an optional description of the callback, which is
+  /// used when generating error messages.
+  ///
   /// The top-level `wrapAsync` function should usually be used in preference to
   /// this in test code.
-  Function wrapAsync(fn(arg)) {
+  Function wrapAsync(fn(arg), [String description]) {
     if (_state == ScheduleState.DONE) {
       throw new StateError("wrapAsync called after the schedule has finished "
           "running.");
     }
     heartbeat();
 
-    var queue = currentQueue;
-    // It's possible that the queue timed out before this.
-    bool _timedOut() => queue != currentQueue || _pendingCallbacks == 0;
-
-    _pendingCallbacks++;
-    return (arg) {
-      try {
-        return fn(arg);
-      } catch (e, stackTrace) {
-        if (_timedOut()) {
-          _signalPostTimeoutError(e, stackTrace);
-        } else {
-          signalError(e, stackTrace);
-        }
-      } finally {
-        if (_timedOut()) return;
-
-        _pendingCallbacks--;
-        if (_pendingCallbacks == 0 && _noPendingCallbacks != null) {
-          _noPendingCallbacks.complete();
-          _noPendingCallbacks = null;
-        }
-      }
-    };
+    return currentQueue._wrapAsync(fn, description);
   }
 
   /// Like [wrapAsync], this ensures that the current task queue waits for
@@ -247,18 +243,20 @@
   ///
   /// The returned [Future] completes to the same value or error as [future].
   ///
+  /// [description] provides an optional description of the future, which is
+  /// used when generating error messages.
+  ///
   /// The top-level `wrapFuture` function should usually be used in preference
   /// to this in test code.
-  Future wrapFuture(Future future) {
-    var doneCallback = wrapAsync((_) => null);
-    done() => new Future.immediate(null).then(doneCallback);
+  Future wrapFuture(Future future, [String description]) {
+    var done = wrapAsync((fn) => fn(), description);
 
-    future = future.then((result) {
-      done();
-      return result;
-    }).catchError((e) {
-      signalError(e);
-      done();
+    future = future.then((result) => done(() => result)).catchError((e) {
+      done(() {
+        throw e;
+      });
+      // wrapAsync will catch the first throw, so we throw [e] again so it
+      // propagates through the Future chain.
       throw e;
     });
 
@@ -272,10 +270,18 @@
   /// Returns a string representation of all errors registered on this schedule.
   String errorString() {
     if (errors.isEmpty) return "The schedule had no errors.";
-    if (errors.length == 1) return errors.first.toString();
-    var errorStrings = errors.map((e) => e.toString()).join("\n================"
-        "================================================================\n");
-    return "The schedule had ${errors.length} errors:\n$errorStrings";
+    if (errors.length == 1 && debugInfo.isEmpty) return errors.first.toString();
+
+    var border = "\n==========================================================="
+      "=====================\n";
+    var errorStrings = errors.map((e) => e.toString()).join(border);
+    var message = "The schedule had ${errors.length} errors:\n$errorStrings";
+
+    if (!debugInfo.isEmpty) {
+      message = "$message$border\nDebug info:\n${debugInfo.join(border)}";
+    }
+
+    return message;
   }
 
   /// Notifies the schedule that progress is being made on an asynchronous task.
@@ -286,38 +292,14 @@
     if (_timeout == null) {
       _timeoutTimer = null;
     } else {
-      _timeoutTimer = mock_clock.newTimer(_timeout, _signalTimeout);
+      _timeoutTimer = mock_clock.newTimer(_timeout, () {
+        _timeoutTimer = null;
+        currentQueue._signalTimeout(new ScheduleError.from(this, "The schedule "
+            "timed out after $_timeout of inactivity."));
+      });
     }
   }
 
-  /// The callback to run when the timeout timer fires. Notifies the current
-  /// queue that a timeout has occurred.
-  void _signalTimeout() {
-    // Reset the timer so that we can detect timeouts in the onException and
-    // onComplete queues.
-    _timeoutTimer = null;
-
-    var error = new ScheduleError.from(this, "The schedule timed out after "
-        "$_timeout of inactivity.");
-
-    _pendingCallbacks = 0;
-    if (_noPendingCallbacks != null) {
-      var noPendingCallbacks = _noPendingCallbacks;
-      _noPendingCallbacks = null;
-      noPendingCallbacks.completeError(error);
-    } else {
-      currentQueue._signalTimeout(error);
-    }
-  }
-
-  /// Returns a [Future] that will complete once there are no pending
-  /// out-of-band callbacks.
-  Future _awaitNoPendingCallbacks() {
-    if (_pendingCallbacks == 0) return new Future.immediate(null);
-    if (_noPendingCallbacks == null) _noPendingCallbacks = new Completer();
-    return _noPendingCallbacks.future;
-  }
-
   /// Register an error in the schedule's error list. This ensures that there
   /// are no duplicate errors, and that all errors are wrapped in
   /// [ScheduleError].
@@ -371,12 +353,47 @@
   /// null if no task is currently running.
   SubstituteFuture _taskFuture;
 
-  TaskQueue._(this.name, this._schedule);
+  /// The toal number of out-of-band callbacks that have been registered on
+  /// [this].
+  int _totalCallbacks = 0;
+
+  /// Whether to stop running after the current task.
+  bool _aborted = false;
+
+  // TODO(nweiz): make this a read-only view when issue 8321 is fixed.
+  /// The descriptions of all callbacks that are blocking the completion of
+  /// [this].
+  Collection<String> get pendingCallbacks => _pendingCallbacks;
+  final _pendingCallbacks = new Queue<String>();
+
+  /// A completer that will be completed once [_pendingCallbacks] becomes empty
+  /// after the queue finishes running its tasks.
+  Future get _noPendingCallbacks => _noPendingCallbacksCompleter.future;
+  final Completer _noPendingCallbacksCompleter = new Completer();
+
+  /// A [Future] that completes when the tasks in [this] are all complete. If an
+  /// error occurs while running this queue, the returned [Future] will complete
+  /// with that error.
+  ///
+  /// The returned [Future] can complete before outstanding out-of-band
+  /// callbacks have finished running.
+  Future get onTasksComplete => _onTasksCompleteCompleter.future;
+  final _onTasksCompleteCompleter = new Completer();
+
+  TaskQueue._(this.name, this._schedule) {
+    // Avoid top-leveling errors that are passed to onTasksComplete if there are
+    // no listeners.
+    onTasksComplete.catchError((_) {});
+  }
 
   /// Whether this queue is currently running.
   bool get isRunning => _schedule.state == ScheduleState.RUNNING &&
       _schedule.currentQueue == this;
 
+  /// Whether this queue is running its tasks (as opposed to waiting for
+  /// out-of-band callbacks or not running at all).
+  bool get isRunningTasks => isRunning && _schedule.currentTask != null;
+
   /// Schedules a task, [fn], to run asynchronously as part of this queue. Tasks
   /// will be run in the order they're scheduled. In [fn] returns a [Future],
   /// tasks after it won't be run until that [Future] completes.
@@ -403,7 +420,11 @@
       return task.runChild(wrappedFn, description);
     }
 
-    var task = new Task(fn, description, this);
+    var task = new Task(() {
+      return new Future.of(fn).catchError((e) {
+        throw new ScheduleError.from(_schedule, e);
+      });
+    }, description, this);
     _contents.add(task);
     return task.result;
   }
@@ -415,24 +436,86 @@
     return Future.forEach(_contents, (task) {
       _schedule._currentTask = task;
       if (_error != null) throw _error;
+      if (_aborted) return;
 
       _taskFuture = new SubstituteFuture(task.fn());
       return _taskFuture.whenComplete(() {
         _taskFuture = null;
         _schedule.heartbeat();
       }).catchError((e) {
-        if (_error != null) _schedule._addError(_error);
-        throw new ScheduleError.from(_schedule, e);
+        var error = new ScheduleError.from(_schedule, e);
+        _signalError(error);
+        throw _error;
       });
     }).whenComplete(() {
       _schedule._currentTask = null;
-      return _schedule._awaitNoPendingCallbacks();
     }).then((_) {
+      _onTasksCompleteCompleter.complete();
+    }).catchError((e) {
+      _onTasksCompleteCompleter.completeError(e);
+      throw e;
+    }).whenComplete(() {
+      if (pendingCallbacks.isEmpty) return;
+      return _noPendingCallbacks.catchError((e) {
+        // Signal the error rather than passing it through directly so that if a
+        // timeout happens after an in-task error, both are reported.
+        _signalError(new ScheduleError.from(_schedule, e));
+      });
+    }).whenComplete(() {
       _schedule.heartbeat();
+      // If the tasks were otherwise successful, make sure we throw any
+      // out-of-band errors. If a task failed, make sure we throw the most
+      // recent error.
       if (_error != null) throw _error;
     });
   }
 
+  /// Stops this queue after the current task and any out-of-band callbacks
+  /// finish running.
+  void _abort() {
+    assert(_schedule.state == ScheduleState.SET_UP || isRunning);
+    _aborted = true;
+  }
+
+  /// Returns a function wrapping [fn] that pipes any errors into the schedule
+  /// chain. This will also block [this] from completing until the returned
+  /// function has been called. It's used to ensure that out-of-band callbacks
+  /// are properly handled by the scheduled test.
+  Function _wrapAsync(fn(arg), String description) {
+    assert(_schedule.state == ScheduleState.SET_UP || isRunning);
+
+    // It's possible that the queue timed out before [fn] finished.
+    bool _timedOut() =>
+      _schedule.currentQueue != this || pendingCallbacks.isEmpty;
+
+    if (description == null) {
+      description = "Out-of-band operation #${_totalCallbacks}";
+    }
+    _totalCallbacks++;
+
+    _pendingCallbacks.add(description);
+    return (arg) {
+      try {
+        return fn(arg);
+      } catch (e, stackTrace) {
+        var error = new ScheduleError.from(
+            _schedule, e, stackTrace: stackTrace);
+        if (_timedOut()) {
+          _schedule._signalPostTimeoutError(error);
+        } else {
+          _schedule.signalError(error);
+        }
+      } finally {
+        if (_timedOut()) return;
+
+        _pendingCallbacks.remove(description);
+        if (_pendingCallbacks.isEmpty && !isRunningTasks) {
+          _noPendingCallbacksCompleter.complete();
+        }
+      }
+    };
+  }
+
   /// Signals that an out-of-band error has been detected and the queue should
   /// stop running as soon as possible.
   void _signalError(ScheduleError error) {
@@ -445,7 +528,10 @@
   /// Notifies the queue that it has timed out and it needs to terminate
   /// immediately with a timeout error.
   void _signalTimeout(ScheduleError error) {
-    if (_taskFuture != null) {
+    _pendingCallbacks.clear();
+    if (!isRunningTasks) {
+      _noPendingCallbacksCompleter.completeError(error);
+    } else if (_taskFuture != null) {
       // Catch errors coming off the old task future, in case it completes after
       // timing out.
       _taskFuture.substitute(new Future.immediateError(error)).catchError((e) {
@@ -454,7 +540,7 @@
     } else {
       // This branch probably won't be reached, but it's conceivable that the
       // event loop might get pumped when _taskFuture is null but we haven't yet
-      // called _awaitNoPendingCallbacks.
+      // finished running all the tasks.
       _signalError(error);
     }
   }
@@ -473,6 +559,22 @@
           "> ${lines.first}" : "* ${lines.first}";
       lines = new List.from(lines.skip(1).map((line) => "| $line"));
       lines.insertRange(0, 1, firstLine);
+
+      if (task == highlight && !task.children.isEmpty) {
+        for (var child in task.children) {
+          var prefix = ">";
+          if (child.state == TaskState.ERROR) {
+            prefix = "X";
+          } else if (child.state == TaskState.SUCCESS) {
+            prefix = "*";
+          }
+
+          var childLines = child.toString().split("\n");
+          lines.add("  $prefix ${childLines.first}");
+          lines.addAll(childLines.skip(1).map((line) => "  | $line"));
+        }
+      }
+
       return lines.join("\n");
     }).join("\n");
   }
diff --git a/pkg/scheduled_test/lib/src/schedule_error.dart b/pkg/scheduled_test/lib/src/schedule_error.dart
index d36be02..7f1856b 100644
--- a/pkg/scheduled_test/lib/src/schedule_error.dart
+++ b/pkg/scheduled_test/lib/src/schedule_error.dart
@@ -23,6 +23,10 @@
   /// `null` if there was no such queue.
   final TaskQueue queue;
 
+  /// The descriptions of out-of-band callbacks that were pending when this
+  /// error occurred.
+  final Collection<String> pendingCallbacks;
+
   /// The state of the schedule at the time the error was detected.
   final ScheduleState _stateWhenDetected;
 
@@ -49,10 +53,12 @@
 
   ScheduleError(Schedule schedule, error, stackTrace, AsyncError cause)
       : super.withCause(error, stackTrace, cause),
-        this.schedule = schedule,
-        this.task = schedule.currentTask,
-        this.queue = schedule.currentQueue,
-        this._stateWhenDetected = schedule.state;
+        schedule = schedule,
+        task = schedule.currentTask,
+        queue = schedule.currentQueue,
+        pendingCallbacks = schedule.currentQueue == null ? <String>[]
+            : schedule.currentQueue.pendingCallbacks.toList(),
+        _stateWhenDetected = schedule.state;
 
   bool operator ==(other) => other is ScheduleError && task == other.task &&
       queue == other.queue && _stateWhenDetected == other._stateWhenDetected &&
@@ -64,30 +70,38 @@
 
     var errorString = error.toString();
     if (errorString.contains("\n")) {
-      result.add('ScheduleError:\n');
-      result.add(prefixLines(errorString.trim()));
-      result.add("\n\n");
+      result.write('ScheduleError:\n');
+      result.write(prefixLines(errorString.trim()));
+      result.write("\n\n");
     } else {
-      result.add('ScheduleError: "$errorString"\n');
+      result.write('ScheduleError: "$errorString"\n');
     }
 
-    result.add('Stack trace:\n');
-    result.add(prefixLines(stackTrace.toString().trim()));
-    result.add("\n\n");
+    result.write('Stack trace:\n');
+    result.write(prefixLines(stackTrace.toString().trim()));
+    result.write("\n\n");
 
     if (task != null) {
-      result.add('Error detected during task in queue "$queue":\n');
-      result.add(task.generateTree());
+      result.write('Error detected during task in queue "$queue":\n');
+      result.write(task.generateTree());
     } else if (_stateWhenDetected == ScheduleState.DONE) {
-      result.add('Error detected after all tasks in the schedule had '
+      result.write('Error detected after all tasks in the schedule had '
           'finished.');
     } else if (_stateWhenDetected == ScheduleState.RUNNING) {
-      result.add('Error detected when waiting for out-of-band callbacks in '
+      result.write('Error detected when waiting for out-of-band callbacks in '
           'queue "$queue".');
     } else { // _stateWhenDetected == ScheduleState.SET_UP
-      result.add('Error detected before the schedule started running.');
+      result.write('Error detected before the schedule started running.');
     }
 
-    return result.toString();
+    if (!pendingCallbacks.isEmpty) {
+      result.write("\n\n");
+      result.writeln("Pending out-of-band callbacks:");
+      for (var callback in pendingCallbacks) {
+        result.writeln("* $callback");
+      }
+    }
+
+    return result.toString().trim();
   }
 }
diff --git a/pkg/scheduled_test/lib/src/scheduled_future_matchers.dart b/pkg/scheduled_test/lib/src/scheduled_future_matchers.dart
new file mode 100644
index 0000000..4e1d0ff
--- /dev/null
+++ b/pkg/scheduled_test/lib/src/scheduled_future_matchers.dart
@@ -0,0 +1,78 @@
+// 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 scheduled_future_matchers;
+
+import 'dart:async';
+
+import '../scheduled_test.dart';
+
+/// Matches a [Future] that completes successfully with a value. Note that this
+/// creates an asynchronous expectation. The call to `expect()` that includes
+/// this will return immediately and execution will continue. Later, when the
+/// future completes, the actual expectation will run.
+///
+/// To test that a Future completes with an exception, you can use [throws] and
+/// [throwsA].
+///
+/// This differs from the `completes` matcher in `unittest` in that it pipes any
+/// errors in the Future to [currentSchedule], rather than reporting them in the
+/// [expect]'s error message.
+Matcher completes = const _ScheduledCompletes(null, null);
+
+/// Matches a [Future] that completes succesfully with a value that matches
+/// [matcher]. Note that this creates an asynchronous expectation. The call to
+/// `expect()` that includes this will return immediately and execution will
+/// continue. Later, when the future completes, the actual expectation will run.
+///
+/// To test that a Future completes with an exception, you can use [throws] and
+/// [throwsA].
+///
+/// [description] is an optional tag that can be used to identify the completion
+/// matcher in error messages.
+///
+/// This differs from the `completion` matcher in `unittest` in that it pipes
+/// any errors in the Future to [currentSchedule], rather than reporting them in
+/// the [expect]'s error message.
+Matcher completion(matcher, [String description]) =>
+    new _ScheduledCompletes(wrapMatcher(matcher), description);
+
+class _ScheduledCompletes extends BaseMatcher {
+  final Matcher _matcher;
+  final String _description;
+
+  const _ScheduledCompletes(this._matcher, this._description);
+
+  bool matches(item, MatchState matchState) {
+    if (item is! Future) return false;
+
+    // TODO(nweiz): parse the stack, figure out on what line these were called,
+    // and include that in their descriptions
+    var description = _description;
+    if (description == null) {
+      if (_matcher == null) {
+        description = 'expect(..., completes)';
+      } else {
+        var matcherDescription = new StringDescription();
+        _matcher.describe(matcherDescription);
+        description = 'expect(..., completion($matcherDescription))';
+      }
+    }
+
+    currentSchedule.wrapFuture(item.then((value) {
+      if (_matcher != null) expect(value, _matcher);
+    }), description);
+
+    return true;
+  }
+
+  Description describe(Description description) {
+    if (_matcher == null) {
+      description.add('completes successfully');
+    } else {
+      description.add('completes to a value that ').addDescriptionOf(_matcher);
+    }
+    return description;
+  }
+}
diff --git a/pkg/scheduled_test/lib/src/scheduled_server/handler.dart b/pkg/scheduled_test/lib/src/scheduled_server/handler.dart
new file mode 100644
index 0000000..6be6b1c
--- /dev/null
+++ b/pkg/scheduled_test/lib/src/scheduled_server/handler.dart
@@ -0,0 +1,82 @@
+// 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 scheduled_server.handler;
+
+import 'dart:async';
+import 'dart:io';
+
+import '../../scheduled_server.dart';
+import '../../scheduled_test.dart';
+import '../utils.dart';
+
+/// A handler for a single request to a [ScheduledServer].
+class Handler {
+  /// The server for which this handler will handle a request.
+  final ScheduledServer server;
+
+  /// The expected method of the request to be handled.
+  final String method;
+
+  /// The expected path of the request to be handled.
+  final String path;
+
+  /// The function to run to handle the request.
+  ScheduledHandler get fn => _fn;
+  ScheduledHandler _fn;
+
+  /// The scheduled task immediately prior to this handler. If this task is
+  /// running when this handler receives a request, it should wait until the
+  /// task has completed.
+  ///
+  /// The last task in the queue will be the prior task because a Handler is
+  /// created before its associated [schedule] call.
+  final Task _taskBefore = currentSchedule.tasks.contents.last;
+
+  /// The result of running this handler. If an error occurs while running the
+  /// handler, that will be piped through this [Future].
+  Future get result => _resultCompleter.future;
+  final _resultCompleter = new Completer();
+
+  /// Whether it's time for the handler to receive its request.
+  var ready = false;
+
+  Handler(this.server, this.method, this.path, ScheduledHandler fn) {
+    _fn = (request) {
+      return _waitForTask().then((_) {
+        if (!ready) {
+          throw "'${server.description}' received $method $path earlier than "
+              "expected.";
+        }
+
+        // Use a nested call to [schedule] to help the user tell the difference
+        // between a test failing while waiting for a handler and a test failing
+        // while executing a handler.
+        chainToCompleter(schedule(() {
+          return new Future.of(() {
+            if (request.method != method || request.uri.path != path) {
+              throw "'${server.description}' expected $method $path, "
+                  "but got ${request.method} ${request.uri.path}.";
+            }
+
+            return fn(request);
+          });
+        }, "'${server.description}' handling ${request.method} ${request.uri}"),
+            _resultCompleter);
+      });
+    };
+  }
+
+  /// If the current task is [_taskBefore], waits for it to finish before
+  /// completing. Otherwise, completes immediately.
+  Future _waitForTask() {
+    return pumpEventQueue().then((_) {
+      if (currentSchedule.currentTask != _taskBefore) return;
+      // If we're one task before the handler was scheduled, wait for that
+      // task to complete and pump the event queue so that [ready] will be
+      // set.
+      return _taskBefore.result.then((_) => pumpEventQueue());
+    });
+  }
+}
diff --git a/pkg/scheduled_test/lib/src/scheduled_server/safe_http_server.dart b/pkg/scheduled_test/lib/src/scheduled_server/safe_http_server.dart
new file mode 100644
index 0000000..64adf5b
--- /dev/null
+++ b/pkg/scheduled_test/lib/src/scheduled_server/safe_http_server.dart
@@ -0,0 +1,144 @@
+// 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 safe_http_server;
+
+import 'dart:async';
+import 'dart:io';
+import 'dart:uri';
+
+// TODO(nweiz): remove this when issue 9140 is fixed.
+/// A wrapper around [HttpServer] that swallows errors caused by requests
+/// behaving badly. This provides the following guarantees:
+///
+/// * The [SafeHttpServer.listen] onError callback will only emit server-wide
+///   errors. It will not emit errors for requests that were unparseable or
+///   where the connection was closed too soon.
+/// * [HttpResponse.done] will emit no errors.
+///
+/// The [HttpRequest] data stream can still emit errors.
+class SafeHttpServer extends StreamView<HttpRequest> implements HttpServer {
+  final HttpServer _inner;
+
+  static Future<SafeHttpServer> bind([String host = "127.0.0.1",
+      int port = 0, int backlog = 0]) {
+    return HttpServer.bind(host, port, backlog)
+        .then((server) => new SafeHttpServer(server));
+  }
+
+  SafeHttpServer(HttpServer server)
+      : super(server),
+        _inner = server;
+
+  void close() => _inner.close();
+
+  int get port => _inner.port;
+
+  set sessionTimeout(int timeout) {
+    _inner.sessionTimeout = timeout;
+  }
+
+  HttpConnectionsInfo connectionsInfo() => _inner.connectionsInfo();
+
+  StreamSubscription<HttpRequest> listen(void onData(HttpRequest value),
+      {void onError(AsyncError error), void onDone(),
+      bool unsubscribeOnError: false}) {
+    var subscription;
+    subscription = super.listen((request) {
+      onData(new _HttpRequestWrapper(request));
+    }, onError: (e) {
+      var error = e.error;
+      // Ignore socket error 104, which is caused by a request being cancelled
+      // before it writes any headers. There's no reason to care about such
+      // requests.
+      if (error is SocketIOException && error.osError.errorCode == 104) return;
+      // Ignore any parsing errors, which come from malformed requests.
+      if (error is HttpParserException) return;
+      // Manually handle unsubscribeOnError so the above (ignored) errors don't
+      // cause unsubscription.
+      if (unsubscribeOnError) subscription.cancel();
+      if (onError != null) onError(e);
+    }, onDone: onDone);
+    return subscription;
+  }
+}
+
+/// A wrapper around [HttpRequest] for the sole purpose of swallowing errors on
+/// [HttpResponse.done].
+class _HttpRequestWrapper extends StreamView<List<int>> implements HttpRequest {
+  final HttpRequest _inner;
+  final HttpResponse response;
+
+  _HttpRequestWrapper(HttpRequest inner)
+      : super(inner),
+        _inner = inner,
+        response = new _HttpResponseWrapper(inner.response);
+
+  int get contentLength => _inner.contentLength;
+  String get method => _inner.method;
+  Uri get uri => _inner.uri;
+  Map<String, String> get queryParameters => _inner.queryParameters;
+  HttpHeaders get headers => _inner.headers;
+  List<Cookie> get cookies => _inner.cookies;
+  bool get persistentConnection => _inner.persistentConnection;
+  X509Certificate get certificate => _inner.certificate;
+  HttpSession get session => _inner.session;
+  String get protocolVersion => _inner.protocolVersion;
+  HttpConnectionInfo get connectionInfo => _inner.connectionInfo;
+}
+
+/// A wrapper around [HttpResponse] for the sole purpose of swallowing errors on
+/// [done].
+class _HttpResponseWrapper implements HttpResponse {
+  final HttpResponse _inner;
+  Future<HttpResponse> _done;
+
+  _HttpResponseWrapper(this._inner);
+
+  /// Swallows all errors from writing to the response.
+  Future<HttpResponse> get done {
+    if (_done == null) _done = _inner.done.catchError((_) {});
+    return _done;
+  }
+
+  int get contentLength => _inner.contentLength;
+  set contentLength(int value) {
+    _inner.contentLength = value;
+  }
+
+  int get statusCode => _inner.statusCode;
+  set statusCode(int value) {
+    _inner.statusCode = value;
+  }
+
+  String get reasonPhrase => _inner.reasonPhrase;
+  set reasonPhrase(String value) {
+    _inner.reasonPhrase = value;
+  }
+
+  bool get persistentConnection => _inner.persistentConnection;
+  set persistentConnection(bool value) {
+    _inner.persistentConnection = value;
+  }
+
+  Encoding get encoding => _inner.encoding;
+  set encoding(Encoding value) {
+    _inner.encoding = value;
+  }
+
+  HttpHeaders get headers => _inner.headers;
+  List<Cookie> get cookies => _inner.cookies;
+  Future<Socket> detachSocket() => _inner.detachSocket();
+  HttpConnectionInfo get connectionInfo => _inner.connectionInfo;
+  void writeBytes(List<int> data) => _inner.writeBytes(data);
+  Future<HttpResponse> consume(Stream<List<int>> stream) =>
+    _inner.consume(stream);
+  Future<HttpResponse> writeStream(Stream<List<int>> stream) =>
+    _inner.writeStream(stream);
+  void close() => _inner.close();
+  void write(Object obj) => _inner.write(obj);
+  void writeAll(Iterable objects) => _inner.writeAll(objects);
+  void writeCharCode(int charCode) => _inner.writeCharCode(charCode);
+  void writeln([Object obj = ""]) => _inner.writeln(obj);
+}
diff --git a/pkg/scheduled_test/lib/src/task.dart b/pkg/scheduled_test/lib/src/task.dart
index 0819bd0..2ce3905 100644
--- a/pkg/scheduled_test/lib/src/task.dart
+++ b/pkg/scheduled_test/lib/src/task.dart
@@ -44,6 +44,10 @@
   /// The body of the task.
   TaskBody fn;
 
+  /// The current state of [this].
+  TaskState get state => _state;
+  var _state = TaskState.WAITING;
+
   /// The identifier of the task. For top-level tasks, this is the index of the
   /// task within [queue]; for nested tasks, this is the index within
   /// [parent.children]. It's used for debugging when [description] isn't
@@ -63,6 +67,11 @@
 
   Task._(fn(), this.description, this.queue, this.parent, this._id) {
     this.fn = () {
+      if (state != TaskState.WAITING) {
+        throw new StateError("Can't run $state task '$this'.");
+      }
+
+      _state = TaskState.RUNNING;
       var future = new Future.immediate(null).then((_) => fn())
           .whenComplete(() {
         if (_childGroup == null || _childGroup.completed) return;
@@ -72,9 +81,21 @@
       return future;
     };
 
-    // Make sure any error thrown by fn isn't top-leveled by virtue of being
-    // passed to the result future.
-    result.catchError((_) {});
+    // If the parent queue experiences an error before this task has started
+    // running, pipe that error out through [result]. This ensures that we don't
+    // get deadlocked by something like `expect(schedule(...), completes)`.
+    queue.onTasksComplete.catchError((e) {
+      if (state == TaskState.WAITING) _resultCompleter.completeError(e);
+    });
+
+    // catchError makes sure any error thrown by fn isn't top-leveled by virtue
+    // of being passed to the result future.
+    result.then((_) {
+      _state = TaskState.SUCCESS;
+    }).catchError((e) {
+      _state = TaskState.ERROR;
+      throw e;
+    }).catchError((_) {});
   }
 
   /// Run [fn] as a child of this task. Returns a Future that will complete with
@@ -98,3 +119,29 @@
   /// Returns a detailed representation of [queue] with this task highlighted.
   String generateTree() => queue.generateTree(this);
 }
+
+/// An enum of states for a [Task].
+class TaskState {
+  /// The task is waiting to be run.
+  static const WAITING = const TaskState._("WAITING");
+
+  /// The task is currently running.
+  static const RUNNING = const TaskState._("RUNNING");
+
+  /// The task has finished running successfully.
+  static const SUCCESS = const TaskState._("SUCCESS");
+
+  /// The task has finished running with an error.
+  static const ERROR = const TaskState._("ERROR");
+
+  /// The name of the state.
+  final String name;
+
+  /// Whether the state indicates that the task has finished running. This is
+  /// true for both the [SUCCESS] and [ERROR] states.
+  bool get isDone => this == SUCCESS || this == ERROR;
+
+  const TaskState._(this.name);
+
+  String toString() => name;
+}
diff --git a/pkg/scheduled_test/lib/src/utils.dart b/pkg/scheduled_test/lib/src/utils.dart
index b880a2d..898b72e 100644
--- a/pkg/scheduled_test/lib/src/utils.dart
+++ b/pkg/scheduled_test/lib/src/utils.dart
@@ -6,11 +6,28 @@
 
 import 'dart:async';
 
+/// A pair of values.
+class Pair<E, F> {
+  E first;
+  F last;
+
+  Pair(this.first, this.last);
+
+  String toString() => '($first, $last)';
+
+  bool operator==(other) {
+    if (other is! Pair) return false;
+    return other.first == first && other.last == last;
+  }
+
+  int get hashCode => first.hashCode ^ last.hashCode;
+}
+
 /// Configures [future] so that its result (success or exception) is passed on
 /// to [completer].
 void chainToCompleter(Future future, Completer completer) {
   future.then((value) => completer.complete(value),
-      onError: (e) => completer.completeError(e.error, e.stackTrace));
+      onError: (e) => completer.completeError(e));
 }
 
 /// Prepends each line in [text] with [prefix].
@@ -52,11 +69,101 @@
   future.then((stream) {
     stream.listen(
         controller.add,
-        onError: (error) => controller.signalError(error),
+        onError: (error) => controller.addError(error),
         onDone: controller.close);
   }).catchError((e) {
-    controller.signalError(e);
+    controller.addError(e);
     controller.close();
   });
   return controller.stream;
 }
+
+// TODO(nweiz): remove this when issue 7964 is fixed.
+/// Returns a [Future] that will complete to the first element of [stream].
+/// Unlike [Stream.first], this is safe to use with single-subscription streams.
+Future streamFirst(Stream stream) {
+  // TODO(nweiz): remove this when issue 8512 is fixed.
+  var cancelled = false;
+  var completer = new Completer();
+  var subscription;
+  subscription = stream.listen((value) {
+    if (!cancelled) {
+      cancelled = true;
+      subscription.cancel();
+      completer.complete(value);
+    }
+  }, onError: (e) {
+    if (!cancelled) {
+      completer.completeError(e.error, e.stackTrace);
+    }
+  }, onDone: () {
+    if (!cancelled) {
+      completer.completeError(new StateError("No elements"));
+    }
+  }, unsubscribeOnError: true);
+  return completer.future;
+}
+
+/// A function that can be called to cancel a [Stream] and send a done message.
+typedef void StreamCanceller();
+
+// TODO(nweiz): use a StreamSubscription when issue 9026 is fixed.
+/// Returns a wrapped version of [stream] along with a function that will cancel
+/// the wrapped stream. Unlike [StreamSubscription], this canceller will send a
+/// "done" message to the wrapped stream.
+Pair<Stream, StreamCanceller> streamWithCanceller(Stream stream) {
+  var controller = stream.isBroadcast ?
+      new StreamController.broadcast() :
+      new StreamController();
+  var subscription = stream.listen((value) {
+    if (!controller.isClosed) controller.add(value);
+  }, onError: (error) {
+    if (!controller.isClosed) controller.signalError(error);
+  }, onDone: controller.close);
+  return new Pair<Stream, StreamCanceller>(controller.stream, controller.close);
+}
+
+// TODO(nweiz): remove this when issue 7787 is fixed.
+/// Creates two single-subscription [Stream]s that each emit all values and
+/// errors from [stream]. This is useful if [stream] is single-subscription but
+/// multiple subscribers are necessary.
+Pair<Stream, Stream> tee(Stream stream) {
+  var controller1 = new StreamController();
+  var controller2 = new StreamController();
+  stream.listen((value) {
+    controller1.add(value);
+    controller2.add(value);
+  }, onError: (error) {
+    controller1.signalError(error);
+    controller2.signalError(error);
+  }, onDone: () {
+    controller1.close();
+    controller2.close();
+  });
+  return new Pair<Stream, Stream>(controller1.stream, controller2.stream);
+}
+
+/// Takes a simple data structure (composed of [Map]s, [Iterable]s, scalar
+/// objects, and [Future]s) and recursively resolves all the [Future]s contained
+/// within. Completes with the fully resolved structure.
+Future awaitObject(object) {
+  // Unroll nested futures.
+  if (object is Future) return object.then(awaitObject);
+  if (object is Iterable) {
+    return Future.wait(object.map(awaitObject).toList());
+  }
+  if (object is! Map) return new Future.immediate(object);
+
+  var pairs = <Future<Pair>>[];
+  object.forEach((key, value) {
+    pairs.add(awaitObject(value)
+        .then((resolved) => new Pair(key, resolved)));
+  });
+  return Future.wait(pairs).then((resolvedPairs) {
+    var map = {};
+    for (var pair in resolvedPairs) {
+      map[pair.first] = pair.last;
+    }
+    return map;
+  });
+}
diff --git a/pkg/scheduled_test/lib/src/value_future.dart b/pkg/scheduled_test/lib/src/value_future.dart
new file mode 100644
index 0000000..41ffcc0
--- /dev/null
+++ b/pkg/scheduled_test/lib/src/value_future.dart
@@ -0,0 +1,38 @@
+// 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 value_future;
+
+import 'dart:async';
+
+/// A [Future] wrapper that provides synchronous access to the value of the
+/// wrapped [Future] once it's completed.
+class ValueFuture<T> implements Future<T> {
+  /// The wrapped [Future].
+  Future<T> _future;
+
+  /// The [value] of the wrapped [Future], if it's completed succesfully. If it
+  /// hasn't completed yet or has completed with an error, this will be `null`.
+  T get value => _value;
+  T _value;
+
+  /// Whether the wrapped [Future] has completed successfully.
+  bool get hasValue => _hasValue;
+  var _hasValue = false;
+
+  ValueFuture(Future<T> future) {
+    _future = future.then((value) {
+      _value = value;
+      _hasValue = true;
+      return value;
+    });
+  }
+
+  Stream<T> asStream() => _future.asStream();
+  Future catchError(onError(AsyncError asyncError), {bool test(error)}) =>
+    _future.catchError(onError, test: test);
+  Future then(onValue(T value), {onError(AsyncError asyncError)}) =>
+    _future.then(onValue, onError: onError);
+  Future<T> whenComplete(action()) => _future.whenComplete(action);
+}
diff --git a/pkg/scheduled_test/pubspec.yaml b/pkg/scheduled_test/pubspec.yaml
index 10db576..8cccf1b 100644
--- a/pkg/scheduled_test/pubspec.yaml
+++ b/pkg/scheduled_test/pubspec.yaml
@@ -10,4 +10,5 @@
 
 dependencies:
   unittest: any
+  http: ">=0.4.1 <1.0.0"
   pathos: ">=0.3.2 <1.0.0"
diff --git a/pkg/scheduled_test/test/descriptor_test.dart b/pkg/scheduled_test/test/descriptor_test.dart
index 1f5b42a..d203bbe 100644
--- a/pkg/scheduled_test/test/descriptor_test.dart
+++ b/pkg/scheduled_test/test/descriptor_test.dart
@@ -7,9 +7,9 @@
 import 'dart:async';
 import 'dart:io';
 
-import 'package:pathos/path.dart' as path;
-import 'package:scheduled_test/descriptor.dart' as d;
-import 'package:scheduled_test/scheduled_test.dart';
+import '../../../pkg/pathos/lib/path.dart' as path;
+import '../lib/descriptor.dart' as d;
+import '../lib/scheduled_test.dart';
 
 import 'metatest.dart';
 import 'utils.dart';
diff --git a/pkg/scheduled_test/test/metatest.dart b/pkg/scheduled_test/test/metatest.dart
index 9850fff..657e93e 100644
--- a/pkg/scheduled_test/test/metatest.dart
+++ b/pkg/scheduled_test/test/metatest.dart
@@ -9,14 +9,20 @@
 /// isolate, then reporting the results back to the parent isolate.
 library metatest;
 
+import 'dart:io';
 import 'dart:async';
 import 'dart:isolate';
 
-import 'package:pathos/path.dart' as path;
-import 'package:unittest/unittest.dart';
+import '../../../pkg/pathos/lib/path.dart' as path;
+import '../../../pkg/unittest/lib/unittest.dart';
 
 import 'utils.dart';
 
+// TODO(nweiz): get rid of this once issue 8863 is fixed.
+/// The path to the Dart executable. This is only set in a child isolate.
+String get dartExecutable => _executable;
+String _executable;
+
 /// 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. By
 /// default, this expects that all tests defined in [body] pass, but if
@@ -99,7 +105,8 @@
 
   var completer = new Completer();
   port.receive((message, replyTo) {
-    _testToRun = message;
+    _testToRun = message['testToRun'];
+    _executable = message['executable'];
     _replyTo = replyTo;
     port.close();
     completer.complete(true);
@@ -117,8 +124,10 @@
 /// describing the results of that test run.
 Future<Map> _runInIsolate(String description) {
   // TODO(nweiz): Don't use path here once issue 8440 is fixed.
-  var future = spawnUri(path.join(path.current, new Options().script))
-      .call(description);
+  var future = spawnUri(path.join(path.current, new Options().script)).call({
+    'testToRun': description,
+    'executable': new Options().executable
+  });
   // TODO(nweiz): Remove this timeout once issue 8417 is fixed and we can
   // capture top-level exceptions.
   return timeout(future, 30 * 1000, () {
@@ -137,29 +146,29 @@
 String _summarizeTests(Map results) {
   var buffer = new StringBuffer();
   for (var t in results["results"]) {
-    buffer.add("${t['result'].toUpperCase()}: ${t['description']}\n");
-    if (t['message'] != '') buffer.add("${_indent(t['message'])}\n");
+    buffer.writeln("${t['result'].toUpperCase()}: ${t['description']}");
+    if (t['message'] != '') buffer.writeln("${_indent(t['message'])}");
     if (t['stackTrace'] != null && t['stackTrace'] != '') {
-      buffer.add("${_indent(t['stackTrace'])}\n");
+      buffer.writeln("${_indent(t['stackTrace'])}");
     }
   }
 
-  buffer.add("\n");
+  buffer.writeln();
 
   var success = false;
   if (results['passed'] == 0 && results['failed'] == 0 &&
       results['errors'] == 0 && results['uncaughtError'] == null) {
-    buffer.add('No tests found.');
+    buffer.write('No tests found.');
     // This is considered a failure too.
   } else if (results['failed'] == 0 && results['errors'] == 0 &&
       results['uncaughtError'] == null) {
-    buffer.add('All ${results['passed']} tests passed.');
+    buffer.write('All ${results['passed']} tests passed.');
     success = true;
   } else {
     if (results['uncaughtError'] != null) {
-      buffer.add('Top-level uncaught error: ${results['uncaughtError']}');
+      buffer.write('Top-level uncaught error: ${results['uncaughtError']}');
     }
-    buffer.add('${results['passed']} PASSED, ${results['failed']} FAILED, '
+    buffer.write('${results['passed']} PASSED, ${results['failed']} FAILED, '
         '${results['errors']} ERRORS');
   }
   return prefixLines(buffer.toString());
diff --git a/pkg/scheduled_test/test/scheduled_process_test.dart b/pkg/scheduled_test/test/scheduled_process_test.dart
new file mode 100644
index 0000000..66b288f
--- /dev/null
+++ b/pkg/scheduled_test/test/scheduled_process_test.dart
@@ -0,0 +1,391 @@
+// 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 scheduled_process_test;
+
+import 'dart:async';
+import 'dart:io';
+
+import '../../../pkg/pathos/lib/path.dart' as path;
+import '../lib/scheduled_process.dart';
+import '../lib/scheduled_test.dart';
+import '../lib/src/mock_clock.dart' as mock_clock;
+
+import 'metatest.dart';
+import 'utils.dart';
+
+void main() {
+  expectTestsPass("a process must have kill() or shouldExit() called", () {
+    var errors;
+    test('test 1', () {
+      currentSchedule.onException.schedule(() {
+        errors = currentSchedule.errors;
+      });
+
+      startDartProcess('print("hello!");');
+    });
+
+    test('test 2', () {
+      expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
+      expect(errors.length, equals(1));
+      expect(errors.first.error, isStateError);
+      expect(errors.first.error.message, matches(r"^Scheduled process "
+          r"'[^']+[\\/]dart(\.exe)?' must have shouldExit\(\) or kill\(\) "
+          r"called before the test is run\.$"));
+    });
+  }, passing: ['test 2']);
+
+  expectTestsPass("a process exits with the expected exit code", () {
+    test('exit code 0', () {
+      var process = startDartProcess('exitCode = 0;');
+      process.shouldExit(0);
+    });
+
+    test('exit code 42', () {
+      var process = startDartProcess('exitCode = 42;');
+      process.shouldExit(42);
+    });
+  });
+
+  expectTestsPass("a process exiting with an unexpected exit code should cause "
+      "an error", () {
+    var errors;
+    test('test 1', () {
+      currentSchedule.onException.schedule(() {
+        errors = currentSchedule.errors;
+      });
+
+      var process = startDartProcess('exitCode = 1;');
+      process.shouldExit(0);
+    });
+
+    test('test 2', () {
+      expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
+      expect(errors.length, equals(1));
+      expect(errors.first.error, new isInstanceOf<TestFailure>());
+    });
+  }, passing: ['test 2']);
+
+  expectTestsPass("a killed process doesn't care about its exit code", () {
+    test('exit code 0', () {
+      var process = startDartProcess('exitCode = 0;');
+      process.kill();
+    });
+
+    test('exit code 1', () {
+      var process = startDartProcess('exitCode = 1;');
+      process.kill();
+    });
+  });
+
+  expectTestsPass("a killed process stops running", () {
+    test('test', () {
+      var process = startDartProcess('while (true);');
+      process.kill();
+    });
+  });
+
+  expectTestsPass("kill can't be called twice", () {
+    test('test', () {
+      var process = startDartProcess('');
+      process.kill();
+      expect(process.kill, throwsA(isStateError));
+    });
+  });
+
+  expectTestsPass("kill can't be called after shouldExit", () {
+    test('test', () {
+      var process = startDartProcess('');
+      process.shouldExit(0);
+      expect(process.kill, throwsA(isStateError));
+    });
+  });
+
+  expectTestsPass("shouldExit can't be called twice", () {
+    test('test', () {
+      var process = startDartProcess('');
+      process.shouldExit(0);
+      expect(() => process.shouldExit(0), throwsA(isStateError));
+    });
+  });
+
+  expectTestsPass("shouldExit can't be called after kill", () {
+    test('test', () {
+      var process = startDartProcess('');
+      process.kill();
+      expect(() => process.shouldExit(0), throwsA(isStateError));
+    });
+  });
+
+  expectTestsPass("a process that ends while waiting for stdout shouldn't "
+      "block the test", () {
+    var errors;
+    test('test 1', () {
+      currentSchedule.onException.schedule(() {
+        errors = currentSchedule.errors;
+      });
+  
+      var process = startDartProcess('');
+      expect(process.nextLine(), completion(equals('hello')));
+      expect(process.nextLine(), completion(equals('world')));
+      process.shouldExit(0);
+    });
+  
+    test('test 2', () {
+      expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
+      expect(errors.length, anyOf(1, 2));
+      expect(errors[0].error, isStateError);
+      expect(errors[0].error.message, equals("No elements"));
+
+      // Whether or not this error appears depends on how quickly the "no
+      // elements" error is handled.
+      if (errors.length == 2) {
+        expect(errors[1].error, matches(r"^Process "
+            r"'[^']+[\\/]dart(\.exe)? [^']+' ended earlier than scheduled with "
+            r"exit code 0\."));
+      }
+    });
+  }, passing: ['test 2']);
+
+  expectTestsPass("a process that ends during the task immediately before it's "
+      "scheduled to end shouldn't cause an error", () {
+    test('test', () {
+      var process = startDartProcess('stdin.toList();');
+      process.closeStdin();
+      // Unfortunately, sleeping for a second seems like the best way of
+      // guaranteeing that the process ends during this task.
+      schedule(() => new Future.delayed(new Duration(seconds: 1)));
+      process.shouldExit(0);
+    });
+  });
+
+  expectTestsPass("nextLine returns the next line of stdout from the process",
+      () {
+    test('test', () {
+      var process = startDartProcess(r'print("hello\n\nworld"); print("hi");');
+      expect(process.nextLine(), completion(equals('hello')));
+      expect(process.nextLine(), completion(equals('')));
+      expect(process.nextLine(), completion(equals('world')));
+      expect(process.nextLine(), completion(equals('hi')));
+      process.shouldExit(0);
+    });
+  });
+
+  expectTestsPass("nextLine throws an error if there's no more stdout", () {
+    var errors;
+    test('test 1', () {
+      currentSchedule.onException.schedule(() {
+        errors = currentSchedule.errors;
+      });
+  
+      var process = startDartProcess('print("hello");');
+      expect(process.nextLine(), completion(equals('hello')));
+      expect(process.nextLine(), completion(equals('world')));
+      process.shouldExit(0);
+    });
+  
+    test('test 2', () {
+      expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
+      expect(errors.length, anyOf(1, 2));
+      expect(errors[0].error, isStateError);
+      expect(errors[0].error.message, equals("No elements"));
+
+      // Whether or not this error appears depends on how quickly the "no
+      // elements" error is handled.
+      if (errors.length == 2) {
+        expect(errors[1].error, matches(r"^Process "
+            r"'[^']+[\\/]dart(\.exe)? [^']+' ended earlier than scheduled with "
+            r"exit code 0\."));
+      }
+    });
+  }, passing: ['test 2']);
+
+  expectTestsPass("nextErrLine returns the next line of stderr from the "
+      "process", () {
+    test('test', () {
+      var process = startDartProcess(r'''
+          stderr.write("hello\n\nworld\n");
+          stderr.write("hi");
+          ''');
+      expect(process.nextErrLine(), completion(equals('hello')));
+      expect(process.nextErrLine(), completion(equals('')));
+      expect(process.nextErrLine(), completion(equals('world')));
+      expect(process.nextErrLine(), completion(equals('hi')));
+      process.shouldExit(0);
+    });
+  });
+
+  expectTestsPass("nextErrLine throws an error if there's no more stderr", () {
+    var errors;
+    test('test 1', () {
+      currentSchedule.onException.schedule(() {
+        errors = currentSchedule.errors;
+      });
+  
+      var process = startDartProcess(r'stderr.write("hello\n");');
+      expect(process.nextErrLine(), completion(equals('hello')));
+      expect(process.nextErrLine(), completion(equals('world')));
+      process.shouldExit(0);
+    });
+  
+    test('test 2', () {
+      expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
+      expect(errors.length, anyOf(1, 2));
+      expect(errors[0].error, isStateError);
+      expect(errors[0].error.message, equals("No elements"));
+
+      // Whether or not this error appears depends on how quickly the "no
+      // elements" error is handled.
+      if (errors.length == 2) {
+        expect(errors[1].error, matches(r"^Process "
+            r"'[^']+[\\/]dart(\.exe)? [^']+' ended earlier than scheduled with "
+            r"exit code 0\."));
+      }
+    });
+  }, passing: ['test 2']);
+
+  expectTestsPass("remainingStdout returns all the stdout if it's not consumed "
+      "any other way", () {
+    test('test', () {
+      var process = startDartProcess(r'print("hello\n\nworld"); print("hi");');
+      process.shouldExit(0);
+      expect(process.remainingStdout(),
+          completion(equals("hello\n\nworld\nhi")));
+    });
+  });
+
+  expectTestsPass("remainingStdout returns the empty string if there's no "
+      "stdout", () {
+    test('test', () {
+      var process = startDartProcess(r'');
+      process.shouldExit(0);
+      expect(process.remainingStdout(), completion(isEmpty));
+    });
+  });
+
+  expectTestsPass("remainingStdout returns the remaining stdout after the "
+      "lines consumed by nextLine", () {
+    test('test', () {
+      var process = startDartProcess(r'print("hello\n\nworld"); print("hi");');
+      expect(process.nextLine(), completion(equals("hello")));
+      expect(process.nextLine(), completion(equals("")));
+      process.shouldExit(0);
+      expect(process.remainingStdout(), completion(equals("world\nhi")));
+    });
+  });
+
+  expectTestsPass("remainingStdout can't be called before the process is "
+      "scheduled to end", () {
+    test('test', () {
+      var process = startDartProcess(r'');
+      expect(process.remainingStdout, throwsA(isStateError));
+      process.shouldExit(0);
+    });
+  });
+
+  expectTestsPass("remainingStderr returns all the stderr if it's not consumed "
+      "any other way", () {
+    test('test', () {
+      var process = startDartProcess(r'''
+          stderr.write("hello\n\nworld\n");
+          stderr.write("hi\n");
+          ''');
+      process.shouldExit(0);
+      expect(process.remainingStderr(),
+          completion(equals("hello\n\nworld\nhi")));
+    });
+  });
+
+  expectTestsPass("remainingStderr returns the empty string if there's no "
+      "stderr", () {
+    test('test', () {
+      var process = startDartProcess(r'');
+      process.shouldExit(0);
+      expect(process.remainingStderr(), completion(isEmpty));
+    });
+  });
+
+  expectTestsPass("remainingStderr returns the remaining stderr after the "
+      "lines consumed by nextLine", () {
+    test('test', () {
+      var process = startDartProcess(r'''
+          stderr.write("hello\n\nworld\n");
+          stderr.write("hi\n");
+          ''');
+      expect(process.nextErrLine(), completion(equals("hello")));
+      expect(process.nextErrLine(), completion(equals("")));
+      process.shouldExit(0);
+      expect(process.remainingStderr(), completion(equals("world\nhi")));
+    });
+  });
+
+  expectTestsPass("remainingStderr can't be called before the process is "
+      "scheduled to end", () {
+    test('test', () {
+      var process = startDartProcess(r'');
+      expect(process.remainingStderr, throwsA(isStateError));
+      process.shouldExit(0);
+    });
+  });
+
+  expectTestsPass("writeLine schedules a line to be written to the process",
+      () {
+    test('test', () {
+      var process = startDartProcess(r'''
+          stdinLines.listen((line) => print("> $line"));
+          ''');
+      process.writeLine("hello");
+      expect(process.nextLine(), completion(equals("> hello")));
+      process.writeLine("world");
+      expect(process.nextLine(), completion(equals("> world")));
+      process.kill();
+    });
+  });
+
+  expectTestsPass("closeStdin closes the process's stdin stream", () {
+    test('test', () {
+      var process = startDartProcess(r'''
+          stdin.listen((line) => print("> $line"),
+              onDone: () => print("stdin closed"));
+          ''');
+      process.closeStdin();
+      process.shouldExit(0);
+      expect(process.nextLine(), completion(equals('stdin closed')));
+    });
+  });
+}
+
+ScheduledProcess startDartProcess(String script) {
+  var tempDir = schedule(() {
+    return new Directory('').createTemp().then((dir) => dir.path);
+  }, 'create temp dir');
+
+  var dartPath = schedule(() {
+    return tempDir.then((dir) {
+      var utilsPath = path.absolute(path.join(
+          new Options().script, 'utils.dart'));
+      return new File(path.join(dir, 'test.dart')).writeAsString('''
+          import 'dart:async';
+          import 'dart:io';
+
+          var stdinLines = stdin
+              .transform(new StringDecoder())
+              .transform(new LineTransformer());
+
+          void main() {
+            $script
+          }
+          ''').then((file) => file.path);
+    });
+  }, 'write script file');
+
+  currentSchedule.onComplete.schedule(() {
+    return tempDir.catchError((_) => null).then((dir) {
+      if (dir == null) return;
+      return new Directory(dir).delete(recursive: true);
+    });
+  }, 'clean up temp dir');
+
+  return new ScheduledProcess.start(dartExecutable, ['--checked', dartPath]);
+}
diff --git a/pkg/scheduled_test/test/scheduled_server_test.dart b/pkg/scheduled_test/test/scheduled_server_test.dart
new file mode 100644
index 0000000..5fc7812
--- /dev/null
+++ b/pkg/scheduled_test/test/scheduled_server_test.dart
@@ -0,0 +1,305 @@
+// 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 scheduled_server_test;
+
+import 'dart:async';
+import 'dart:io';
+
+import '../../../pkg/http/lib/http.dart' as http;
+import '../lib/scheduled_server.dart';
+import '../lib/scheduled_test.dart';
+import '../lib/src/mock_clock.dart' as mock_clock;
+
+import 'metatest.dart';
+import 'utils.dart';
+
+void main() {
+  expectTestsPass("a server with no handlers does nothing", () {
+    test('test', () => new ScheduledServer());
+  });
+
+  expectTestsPass("a server with no handlers that receives a request throws an "
+      "error", () {
+    var errors;
+    test('test 1', () {
+      currentSchedule.onException.schedule(() {
+        errors = currentSchedule.errors;
+      });
+
+      var server = new ScheduledServer();
+      expect(server.url.then((url) => http.read(url.resolve('/hello'))),
+          completion(equals('Hello, test!')));
+    });
+
+    test('test 2', () {
+      expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
+      expect(errors.length, equals(2));
+      expect(errors[0].error, equals("'scheduled server 0' received GET /hello "
+          "when no more requests were expected."));
+      expect(errors[1].error, new isInstanceOf<HttpParserException>());
+    });
+  }, passing: ['test 2']);
+
+  expectTestsPass("a handler runs when it's hit", () {
+    test('test', () {
+      var server = new ScheduledServer();
+      expect(server.url.then((url) => http.read(url.resolve('/hello'))),
+          completion(equals('Hello, test!')));
+
+      server.handle('GET', '/hello', (request) {
+        request.response.write('Hello, test!');
+        request.response.close();
+      });
+    });
+  });
+
+  expectTestsPass("a handler blocks the schedule on the returned future", () {
+    test('test', () {
+      var blockedOnFuture = false;
+      var server = new ScheduledServer();
+      expect(server.url.then((url) => http.read(url.resolve('/hello'))),
+          completion(equals('Hello, test!')));
+
+      server.handle('GET', '/hello', (request) {
+        request.response.write('Hello, test!');
+        request.response.close();
+        return pumpEventQueue().then((_) {
+          blockedOnFuture = true;
+        });
+      });
+
+      schedule(() => expect(blockedOnFuture, isTrue));
+    });
+  });
+
+  expectTestsPass("a handler fails if it's hit too early", () {
+    var errors;
+    test('test 1', () {
+      currentSchedule.onException.schedule(() {
+        errors = currentSchedule.errors;
+      });
+
+      var server = new ScheduledServer();
+      var response = server.url.then((url) => http.read(url.resolve('/hello')));
+      expect(response, completion(equals('Hello, test!')));
+
+      // Block the schedule until we're sure the request has hit the server.
+      schedule(() => response);
+
+      // Add a task's worth of space to avoid hitting the heuristic of waiting
+      // for the immediately-preceding task.
+      schedule(() => null);
+
+      server.handle('GET', '/hello', (request) {
+        request.response.write('Hello, test!');
+        request.response.close();
+      });
+    });
+
+    test('test 2', () {
+      expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
+      expect(errors.length, equals(2));
+      expect(errors[0].error, equals("'scheduled server 0' received GET /hello "
+          "earlier than expected."));
+      expect(errors[1].error, new isInstanceOf<HttpParserException>());
+    });
+  }, passing: ['test 2']);
+
+  expectTestsPass("a handler waits for the immediately prior task to complete "
+      "before checking if it's too early", () {
+    test('test', () {
+      var server = new ScheduledServer();
+      expect(server.url.then((url) => http.read(url.resolve('/hello'))),
+          completion(equals('Hello, test!')));
+
+      // Sleeping here is unfortunate, but we want to be sure that the HTTP
+      // request hits the server during this test without actually blocking the
+      // task on the request completing.
+      //
+      // This is also a potential race condition, but hopefully a local HTTP
+      // request won't take 1s.
+      schedule(() => new Future.delayed(new Duration(seconds: 1)));
+
+      server.handle('GET', '/hello', (request) {
+        request.response.write('Hello, test!');
+        request.response.close();
+      });
+    });
+  });
+
+  expectTestsPass("a handler fails if the url is wrong", () {
+    var errors;
+    test('test 1', () {
+      currentSchedule.onException.schedule(() {
+        errors = currentSchedule.errors;
+      });
+
+      var server = new ScheduledServer();
+      expect(server.url.then((url) => http.read(url.resolve('/hello'))),
+          completion(equals('Hello, test!')));
+
+      server.handle('GET', '/goodbye', (request) {
+        request.response.write('Goodbye, test!');
+        request.response.close();
+      });
+    });
+
+    test('test 2', () {
+      expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
+      expect(errors.length, equals(2));
+      expect(errors[0].error, equals("'scheduled server 0' expected GET "
+          "/goodbye, but got GET /hello."));
+      expect(errors[1].error, new isInstanceOf<HttpParserException>());
+    });
+  }, passing: ['test 2']);
+
+  expectTestsPass("a handler fails if the method is wrong", () {
+    var errors;
+    test('test 1', () {
+      currentSchedule.onException.schedule(() {
+        errors = currentSchedule.errors;
+      });
+
+      var server = new ScheduledServer();
+      expect(server.url.then((url) => http.head(url.resolve('/hello'))),
+          completes);
+
+      server.handle('GET', '/hello', (request) {
+        request.response.write('Hello, test!');
+        request.response.close();
+      });
+    });
+
+    test('test 2', () {
+      expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
+      expect(errors.length, equals(2));
+      expect(errors[0].error, equals("'scheduled server 0' expected GET "
+          "/hello, but got HEAD /hello."));
+      expect(errors[1].error, new isInstanceOf<HttpParserException>());
+    });
+  }, passing: ['test 2']);
+
+  expectTestsPass("a handler times out waiting to be hit", () {
+    var clock = mock_clock.mock()..run();
+    var timeOfException;
+    var errors;
+    test('test 1', () {
+      currentSchedule.timeout = new Duration(milliseconds: 2);
+      currentSchedule.onException.schedule(() {
+        timeOfException = clock.time;
+        errors = currentSchedule.errors;
+      });
+
+      var server = new ScheduledServer();
+
+      server.handle('GET', '/hello', (request) {
+        request.response.write('Hello, test!');
+        request.response.close();
+      });
+    });
+
+    test('test 2', () {
+      expect(clock.time, equals(2));
+
+      expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
+      expect(errors.map((e) => e.error), equals(["The schedule timed out after "
+        "0:00:00.002000 of inactivity."]));
+    });
+  }, passing: ['test 2']);
+
+  expectTestsPass("multiple handlers in series respond to requests in series",
+      () {
+    test('test', () {
+      var server = new ScheduledServer();
+      expect(server.url.then((url) {
+        return http.read(url.resolve('/hello/1')).then((response) {
+          expect(response, equals('Hello, request 1!'));
+          return http.read(url.resolve('/hello/2'));
+        }).then((response) {
+          expect(response, equals('Hello, request 2!'));
+          return http.read(url.resolve('/hello/3'));
+        }).then((response) => expect(response, equals('Hello, request 3!')));
+      }), completes);
+
+      server.handle('GET', '/hello/1', (request) {
+        request.response.write('Hello, request 1!');
+        request.response.close();
+      });
+
+      server.handle('GET', '/hello/2', (request) {
+        request.response.write('Hello, request 2!');
+        request.response.close();
+      });
+
+      server.handle('GET', '/hello/3', (request) {
+        request.response.write('Hello, request 3!');
+        request.response.close();
+      });
+    });
+  });
+
+  expectTestsPass("a server that receives a request after all its handlers "
+      "have run throws an error", () {
+    var errors;
+    test('test 1', () {
+      currentSchedule.onException.schedule(() {
+        errors = currentSchedule.errors;
+      });
+
+      var server = new ScheduledServer();
+      expect(server.url.then((url) {
+        return http.read(url.resolve('/hello/1')).then((response) {
+          expect(response, equals('Hello, request 1!'));
+          return http.read(url.resolve('/hello/2'));
+        }).then((response) {
+          expect(response, equals('Hello, request 2!'));
+          return http.read(url.resolve('/hello/3'));
+        }).then((response) => expect(response, equals('Hello, request 3!')));
+      }), completes);
+
+      server.handle('GET', '/hello/1', (request) {
+        request.response.write('Hello, request 1!');
+        request.response.close();
+      });
+
+      server.handle('GET', '/hello/2', (request) {
+        request.response.write('Hello, request 2!');
+        request.response.close();
+      });
+    });
+
+    test('test 2', () {
+      expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
+      expect(errors.length, equals(2));
+      expect(errors[0].error, equals("'scheduled server 0' received GET "
+          "/hello/3 when no more requests were expected."));
+      expect(errors[1].error, new isInstanceOf<HttpParserException>());
+    });
+  }, passing: ['test 2']);
+
+  expectTestsPass("an error in a handler doesn't cause a timeout", () {
+    var errors;
+    test('test 1', () {
+      currentSchedule.onException.schedule(() {
+        errors = currentSchedule.errors;
+      });
+
+      var server = new ScheduledServer();
+      expect(server.url.then((url) => http.read(url.resolve('/hello'))),
+          completion(equals('Hello, test!')));
+
+      server.handle('GET', '/hello', (request) {
+        throw 'oh no';
+      });
+    });
+
+    test('test 2', () {
+      expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
+      expect(errors.length, equals(2));
+      expect(errors[0].error, equals('oh no'));
+      expect(errors[1].error, new isInstanceOf<HttpParserException>());
+    });
+  }, passing: ['test 2']);
+}
diff --git a/pkg/scheduled_test/test/scheduled_test_test.dart b/pkg/scheduled_test/test/scheduled_test_test.dart
index 79d2e37..e42f810 100644
--- a/pkg/scheduled_test/test/scheduled_test_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test_test.dart
@@ -6,8 +6,8 @@
 
 import 'dart:async';
 
-import 'package:scheduled_test/scheduled_test.dart';
-import 'package:scheduled_test/src/mock_clock.dart' as mock_clock;
+import '../lib/scheduled_test.dart';
+import '../lib/src/mock_clock.dart' as mock_clock;
 
 import 'metatest.dart';
 import 'utils.dart';
@@ -650,6 +650,30 @@
     });
   }, passing: ['test 2']);
 
+  expectTestsPass('currentSchedule.errors contains both an error raised in a '
+      'task and an error raised afterwards out-of-band', () {
+    mock_clock.mock().run();
+    var errors;
+    test('test 1', () {
+      currentSchedule.onComplete.schedule(() {
+        errors = currentSchedule.errors;
+      });
+
+      sleep(2).then(wrapAsync((_) {
+        throw 'out-of-band';
+      }));
+
+      schedule(() => sleep(1).then((_) {
+        throw 'in-band';
+      }));
+    });
+
+    test('test 2', () {
+      expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
+      expect(errors.map((e) => e.error), equals(['in-band', 'out-of-band']));
+    });
+  }, passing: ['test 2']);
+
   expectTestsPass('currentSchedule.currentTask returns the current task while '
       'executing a task', () {
     test('test', () {
@@ -1003,6 +1027,32 @@
     });
   }, passing: ['test 2']);
 
+  expectTestsPass("a task that has an error then times out waiting for an "
+      "out-of-band callback records both", () {
+    mock_clock.mock().run();
+    var errors;
+    test('test 1', () {
+      currentSchedule.timeout = new Duration(milliseconds: 2);
+
+      currentSchedule.onException.schedule(() {
+        errors = currentSchedule.errors;
+      });
+
+      schedule(() {
+        throw 'error';
+      });
+      wrapFuture(sleep(3));
+    });
+
+    test('test 2', () {
+      expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
+      expect(errors.map((e) => e.error), equals([
+        "error",
+        "The schedule timed out after 0:00:00.002000 of inactivity."
+      ]));
+    });
+  }, passing: ['test 2']);
+
   expectTestsPass("currentSchedule.heartbeat resets the timeout timer", () {
     mock_clock.mock().run();
     test('test', () {
@@ -1173,4 +1223,219 @@
       expect(parentTaskFinishedBeforeOnComplete, isTrue);
     });
   }, passing: ['test 2']);
+
+  expectTestsPass("an error thrown in a scheduled task should be piped to that "
+      "task's return value", () {
+    var error;
+    test('test 1', () {
+      schedule(() {
+        throw 'error';
+      }).catchError((e) {
+        error = e;
+      });
+    });
+
+    test('test 2', () {
+      expect(error, new isInstanceOf<ScheduleError>());
+      expect(error.error, equals('error'));
+    });
+  }, passing: ['test 2']);
+
+  expectTestsPass("an error thrown in a scheduled task should be piped to "
+      "future tasks' return values", () {
+    var error;
+    test('test 1', () {
+      schedule(() {
+        throw 'error';
+      });
+
+      schedule(() => null).catchError((e) {
+        error = e;
+      });
+    });
+
+    test('test 2', () {
+      expect(error, new isInstanceOf<ScheduleError>());
+      expect(error.error, equals('error'));
+    });
+  }, passing: ['test 2']);
+
+  expectTestsPass("an out-of-band error should be piped to future tasks' "
+      "return values, but not the current task's", () {
+    mock_clock.mock().run();
+    var error;
+    var firstTaskError = false;
+    var secondTaskRun = false;
+    test('test 1', () {
+      schedule(() => sleep(2)).catchError((_) {
+        firstTaskError = true;
+      });
+
+      sleep(1).then(wrapAsync((_) {
+        throw 'error';
+      }));
+
+      schedule(() {
+        secondTaskRun = true;
+      }).catchError((e) {
+        error = e;
+      });
+    });
+
+    test('test 2', () {
+      expect(firstTaskError, isFalse);
+      expect(secondTaskRun, isFalse);
+      expect(error, new isInstanceOf<ScheduleError>());
+      expect(error.error, equals('error'));
+    });
+  }, passing: ['test 2']);
+
+  expectTestsPass("expect(..., completes) with a completing future should pass",
+      () {
+    test('test', () {
+      expect(pumpEventQueue(), completes);
+    });
+  });
+
+  expectTestsPass("expect(..., completes) with a failing future should signal "
+      "an out-of-band error", () {
+    var errors;
+    test('test 1', () {
+      currentSchedule.onException.schedule(() {
+        errors = currentSchedule.errors;
+      });
+
+      expect(pumpEventQueue().then((_) {
+        throw 'error';
+      }), completes);
+    });
+
+    test('test 2', () {
+      expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
+      expect(errors.map((e) => e.error), equals(['error']));
+    });
+  }, passing: ['test 2']);
+
+  expectTestsPass("expect(..., completion(...)) with a matching future should "
+      "pass", () {
+    test('test', () {
+      expect(pumpEventQueue().then((_) => 'foo'), completion(equals('foo')));
+    });
+  });
+
+  expectTestsPass("expect(..., completion(...)) with a non-matching future "
+      "should signal an out-of-band error", () {
+    var errors;
+    test('test 1', () {
+      currentSchedule.onException.schedule(() {
+        errors = currentSchedule.errors;
+      });
+
+      expect(pumpEventQueue().then((_) => 'foo'), completion(equals('bar')));
+    });
+
+    test('test 2', () {
+      expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
+      expect(errors.length, equals(1));
+      expect(errors.first.error, new isInstanceOf<TestFailure>());
+    });
+  }, passing: ['test 2']);
+
+  expectTestsPass("expect(..., completion(...)) with a failing future should "
+      "signal an out-of-band error", () {
+    var errors;
+    test('test 1', () {
+      currentSchedule.onException.schedule(() {
+        errors = currentSchedule.errors;
+      });
+
+      expect(pumpEventQueue().then((_) {
+        throw 'error';
+      }), completion(equals('bar')));
+    });
+
+    test('test 2', () {
+      expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
+      expect(errors.map((e) => e.error), equals(['error']));
+    });
+  }, passing: ['test 2']);
+
+  expectTestsPass("aborting the schedule before it's started running should "
+      "cause no tasks to be run", () {
+    test('test', () {
+      schedule(() {
+        throw 'error';
+      });
+
+      currentSchedule.abort();
+    });
+  });
+
+  expectTestsPass("aborting the schedule while it's running should stop future "
+      "tasks from running", () {
+    test('test', () {
+      schedule(currentSchedule.abort);
+
+      schedule(() {
+        throw 'error';
+      });
+    });
+  });
+
+  expectTestsPass("aborting the schedule while it's running shouldn't stop "
+      "tasks in other queues from running", () {
+    var onCompleteRun = false;
+    test('test 1', () {
+      schedule(currentSchedule.abort);
+
+      currentSchedule.onComplete.schedule(() {
+        onCompleteRun = true;
+      });
+    });
+
+    test('test 2', () {
+      expect(onCompleteRun, isTrue);
+    });
+  });
+
+  expectTestsPass("aborting the schedule while it's running shouldn't stop "
+      "out-of-band callbacks", () {
+    test('test', () {
+      var outOfBandFinished = false;
+      schedule(() {
+        wrapFuture(pumpEventQueue().then((_) {
+          outOfBandFinished = true;
+        }));
+
+        currentSchedule.abort();
+      });
+
+      currentSchedule.onComplete.schedule(() {
+        expect(outOfBandFinished, isTrue);
+      });
+    });
+  });
+
+  expectTestsPass("aborting the schedule in a non-tasks queue should stop "
+      "future tasks from running", () {
+    test('test', () {
+      currentSchedule.onComplete.schedule(() {
+        currentSchedule.abort();
+      });
+
+      currentSchedule.onComplete.schedule(() {
+        throw 'error';
+      });
+    });
+  });
+
+  expectTestsFail("aborting the schedule after an out-of-band error should "
+      "still surface the error", () {
+    test('test', () {
+      schedule(() {
+        currentSchedule.signalError('error');
+        currentSchedule.abort();
+      });
+    });
+  });
 }
diff --git a/pkg/scheduled_test/test/substitute_future_test.dart b/pkg/scheduled_test/test/substitute_future_test.dart
index f9c8b32..be42ccc 100644
--- a/pkg/scheduled_test/test/substitute_future_test.dart
+++ b/pkg/scheduled_test/test/substitute_future_test.dart
@@ -6,8 +6,8 @@
 
 import 'dart:async';
 
-import 'package:scheduled_test/src/substitute_future.dart';
-import 'package:unittest/unittest.dart';
+import '../lib/src/substitute_future.dart';
+import '../../../pkg/unittest/lib/unittest.dart';
 
 void main() {
   group('with no substitution, works like a normal Future for', () {
diff --git a/pkg/scheduled_test/test/utils.dart b/pkg/scheduled_test/test/utils.dart
index 3d59e66..8f0bd23 100644
--- a/pkg/scheduled_test/test/utils.dart
+++ b/pkg/scheduled_test/test/utils.dart
@@ -6,10 +6,10 @@
 
 import 'dart:async';
 
-import 'package:scheduled_test/src/utils.dart';
-import 'package:scheduled_test/src/mock_clock.dart' as mock_clock;
+import '../lib/src/utils.dart';
+import '../lib/src/mock_clock.dart' as mock_clock;
 
-export 'package:scheduled_test/src/utils.dart';
+export '../lib/src/utils.dart';
 
 /// Wraps [input] to provide a timeout. If [input] completes before
 /// [milliseconds] have passed, then the return value completes in the same way.
diff --git a/pkg/scheduled_test/test/value_future_test.dart b/pkg/scheduled_test/test/value_future_test.dart
new file mode 100644
index 0000000..ebbcf17
--- /dev/null
+++ b/pkg/scheduled_test/test/value_future_test.dart
@@ -0,0 +1,127 @@
+// 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 value_future_test;
+
+import 'dart:async';
+
+import '../lib/src/value_future.dart';
+import '../../../pkg/unittest/lib/unittest.dart';
+
+void main() {
+  group('works like a normal Future for', () {
+    var completer;
+    var future;
+
+    setUp(() {
+      completer = new Completer();
+      future = new ValueFuture(completer.future);
+    });
+
+    test('.asStream on success', () {
+      expect(future.asStream().toList(), completion(equals(['success'])));
+      completer.complete('success');
+    });
+
+    test('.asStream on error', () {
+      expect(future.asStream().toList(), throwsA(equals('error')));
+      completer.completeError('error');
+    });
+
+    test('.then and .catchError on success', () {
+      expect(future.then((v) => "transformed $v")
+              .catchError((e) => "caught ${e.error}"),
+          completion(equals('transformed success')));
+      completer.complete('success');
+    });
+
+    test('.then and .catchError on error', () {
+      expect(future.then((v) => "transformed $v")
+              .catchError((e) => "caught ${e.error}"),
+          completion(equals('caught error')));
+      completer.completeError('error');
+    });
+
+    test('.then with onError on success', () {
+      expect(future.then((v) => "transformed $v",
+              onError: (e) => "caught ${e.error}"),
+          completion(equals('transformed success')));
+      completer.complete('success');
+    });
+
+    test('.then with onError on error', () {
+      expect(future.then((v) => "transformed $v",
+              onError: (e) => "caught ${e.error}"),
+          completion(equals('caught error')));
+      completer.completeError('error');
+    });
+
+    test('.whenComplete on success', () {
+      expect(future.whenComplete(() {
+        throw 'whenComplete';
+      }), throwsA(equals('whenComplete')));
+      completer.complete('success');
+    });
+
+    test('.whenComplete on error', () {
+      expect(future.whenComplete(() {
+        throw 'whenComplete';
+      }), throwsA(equals('whenComplete')));
+      completer.completeError('error');
+    });
+  });
+
+  group('before completion', () {
+    var future;
+
+    setUp(() {
+      future = new ValueFuture(new Completer().future);
+    });
+
+    test('.value is null', () {
+      expect(future.value, isNull);
+    });
+
+    test('.hasValue is false', () {
+      expect(future.hasValue, isFalse);
+    });
+  });
+
+  group('after successful completion', () {
+    var future;
+
+    setUp(() {
+      var completer = new Completer();
+      future = new ValueFuture(completer.future);
+      completer.complete(12);
+    });
+
+    test('.value is the result of the future', () {
+      expect(future.value, equals(12));
+    });
+
+    test('.hasValue is true', () {
+      expect(future.hasValue, isTrue);
+    });
+  });
+
+  group('after an error completion', () {
+    var future;
+
+    setUp(() {
+      var completer = new Completer();
+      future = new ValueFuture(completer.future);
+      future.catchError((e) {});
+      completer.completeError('bad');
+    });
+
+    test('.value is null', () {
+      expect(future.value, isNull);
+    });
+
+    test('.hasValue is false', () {
+      expect(future.hasValue, isFalse);
+    });
+  });
+}
diff --git a/pkg/serialization/lib/src/serialization_rule.dart b/pkg/serialization/lib/src/serialization_rule.dart
index de5113c..408d40b 100644
--- a/pkg/serialization/lib/src/serialization_rule.dart
+++ b/pkg/serialization/lib/src/serialization_rule.dart
@@ -554,13 +554,14 @@
   addAll(x) => _throw();
   sort([f]) => _throw();
   clear() => _throw();
+  insert(x, y) => _throw();
   removeAt(x) => _throw();
   remove(x) => _throw();
   removeLast() => _throw();
   removeAll(x) => _throw();
   retainAll(x) => _throw();
-  removeMatching(x) => _throw();
-  retainMatching(x) => _throw();
+  removeWhere(x) => _throw();
+  retainWhere(x) => _throw();
   getRange(x, y) => _throw();
   setRange(x, y, z, [a]) => _throw();
   removeRange(x, y) => _throw();
diff --git a/pkg/serialization/test/serialization_test.dart b/pkg/serialization/test/serialization_test.dart
index 7b43793..2987fe0 100644
--- a/pkg/serialization/test/serialization_test.dart
+++ b/pkg/serialization/test/serialization_test.dart
@@ -48,7 +48,7 @@
     // actually writing.
     var w = new Writer(s);
     w.write(p1);
-    var personRule = s.rules.firstMatching(
+    var personRule = s.rules.firstWhere(
         (x) => x is BasicRule && x.type == reflect(p1).type);
     var flatPerson = w.states[personRule.number].first;
     var primStates = w.states.first;
@@ -56,7 +56,7 @@
     expect(flatPerson["name"], "Alice");
     var ref = flatPerson["address"];
     expect(ref is Reference, true);
-    var addressRule = s.rules.firstMatching(
+    var addressRule = s.rules.firstWhere(
         (x) => x is BasicRule && x.type == reflect(a1).type);
     expect(ref.ruleNumber, addressRule.number);
     expect(ref.objectNumber, 0);
@@ -213,7 +213,7 @@
     w.write(n1);
     expect(w.states.length, 5); // prims, lists, essential lists, basic
     var children = 0, name = 1, parent = 2;
-    var nodeRule = s.rules.firstMatching((x) => x is BasicRule);
+    var nodeRule = s.rules.firstWhere((x) => x is BasicRule);
     List rootNode = w.states[nodeRule.number].where(
         (x) => x[name] == "1").toList();
     rootNode = rootNode.first;
@@ -476,8 +476,8 @@
       var reader = s.newReader(eachFormat);
       var input = reader.read(output);
       expect(input["simple data"], data["simple data"]);
-      var p2 = input.keys.firstMatching((x) => x is Person);
-      var a2 = input.keys.firstMatching((x) => x is Address);
+      var p2 = input.keys.firstWhere((x) => x is Person);
+      var a2 = input.keys.firstWhere((x) => x is Address);
       if (eachFormat is SimpleJsonFormat) {
         // JSON doesn't handle cycles, so these won't be identical.
         expect(input[p2] is Address, isTrue);
@@ -502,7 +502,7 @@
     var data = {"abc" : 1, "def" : "ghi"};
     data["person"] = new Person()..name = "Foo";
     var output = s.write(data, new SimpleMapFormat());
-    var mapRule = s.rules.firstMatching((x) => x is MapRule);
+    var mapRule = s.rules.firstWhere((x) => x is MapRule);
     var map = output["data"][mapRule.number][0];
     expect(map is Map, isTrue);
     expect(map["abc"], 1);
diff --git a/pkg/unittest/lib/compact_vm_config.dart b/pkg/unittest/lib/compact_vm_config.dart
index ae8ec97..080824a 100644
--- a/pkg/unittest/lib/compact_vm_config.dart
+++ b/pkg/unittest/lib/compact_vm_config.dart
@@ -88,7 +88,7 @@
       [String color = _NONE]) {
     var duration = (new DateTime.now()).difference(startTime);
     var buffer = new StringBuffer();
-    // \r moves back to the beginnig of the current line.
+    // \r moves back to the beginning of the current line.
     buffer.write('\r${_timeString(duration)} ');
     buffer.write(_GREEN);
     buffer.write('+');
@@ -121,7 +121,7 @@
         _lastLength--;
       }
     }
-    stdout.addString(buffer.toString());
+    stdout.write(buffer.toString());
   }
 
   String _padTime(int time) =>
diff --git a/pkg/unittest/lib/html_config.dart b/pkg/unittest/lib/html_config.dart
index 2246bf3..1b9d12a 100644
--- a/pkg/unittest/lib/html_config.dart
+++ b/pkg/unittest/lib/html_config.dart
@@ -51,6 +51,14 @@
     }
     newBody.write("</tbody></table>");
     document.body.innerHtml = newBody.toString();
+
+    window.onHashChange.listen((_) {
+      // Location may change from individual tests setting the hash tag.
+      if (window.location.hash != null &&
+          window.location.hash.contains('testFilter')) {
+        window.location.reload();
+      }
+    });
   }
 }
 
@@ -68,7 +76,7 @@
       <tr>
         <td>${test_.id}</td>
         <td class="unittest-${test_.result}">${test_.result.toUpperCase()}</td>
-        <td>Expectation: ${test_.description}. ${_htmlEscape(test_.message)}</td>
+        <td>Expectation: <a href="#testFilter=${test_.description}">${test_.description}</a>. ${_htmlEscape(test_.message)}</td>
       </tr>''';
 
   if (test_.stackTrace != null) {
@@ -126,6 +134,23 @@
     window.postMessage('unittest-suite-wait-for-done', '*');
   }
 
+  void onStart() {
+    // If the URL has a #testFilter=testName then filter tests to that.
+    // This is used to make it easy to run a single test- but is only intended
+    // for interactive debugging scenarios.
+    var hash = window.location.hash;
+    if (hash != null && hash.length > 1) {
+      var params = hash.substring(1).split('&');
+      for (var param in params) {
+        var parts = param.split('=');
+        if (parts.length == 2 && parts[0] == 'testFilter') {
+          filterTests('^${parts[1]}');
+        }
+      }
+    }
+    super.onStart();
+  }
+
   void onSummary(int passed, int failed, int errors, List<TestCase> results,
       String uncaughtError) {
     _showResultsInPage(passed, failed, errors, results, _isLayoutTest,
diff --git a/pkg/unittest/lib/html_individual_config.dart b/pkg/unittest/lib/html_individual_config.dart
index f722a6d..2432a55 100644
--- a/pkg/unittest/lib/html_individual_config.dart
+++ b/pkg/unittest/lib/html_individual_config.dart
@@ -24,15 +24,15 @@
   HtmlIndividualConfiguration(isLayoutTest): super(isLayoutTest);
 
   void onStart() {
-    var testGroupName = window.location.search;
-    if (testGroupName != '') {
+    var search = window.location.search;
+    if (search != '') {
       try {
-        for (var parameter in testGroupName.substring(1).split('&')) {
+        for (var parameter in search.substring(1).split('&')) {
           if (parameter.startsWith('group=')) {
-            testGroupName = parameter.split('=')[1];
+            var testGroupName = parameter.split('=')[1];
+            unittest.filterTests('^$testGroupName${unittest.groupSep}');
           }
         }
-        unittest.filterTests('^$testGroupName${unittest.groupSep}');
       } catch (e) {
         print('tried to match "$testGroupName"');
         print('NO_SUCH_TEST');
diff --git a/pkg/unittest/lib/html_layout_config.dart b/pkg/unittest/lib/html_layout_config.dart
index 8a2e1bd..ddb0415 100644
--- a/pkg/unittest/lib/html_layout_config.dart
+++ b/pkg/unittest/lib/html_layout_config.dart
@@ -1,9 +1,9 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
 /**
- * A configuration for running layoutr tests with testrunner.
+ * A configuration for running layout tests with testrunner.
  * This configuration is similar to the interactive_html_config
  * as it runs each test in its own IFrame. However, where the former
  * recreated the IFrame for each test, here the IFrames are preserved.
@@ -11,6 +11,7 @@
  */
 library html_layout_config;
 
+import 'dart:async';
 import 'dart:html';
 import 'dart:math';
 import 'unittest.dart';
@@ -64,8 +65,8 @@
  */
 class ChildHtmlConfiguration extends Configuration {
   get name => 'ChildHtmlConfiguration';
-  // TODO(rnystrom): Get rid of this if we get canonical closures for methods.
-  EventListener _onErrorClosure;
+
+  StreamSubscription _errorSubscription;
 
   /** The window to which results must be posted. */
   Window parentWindow;
@@ -80,16 +81,13 @@
   get autoStart => false;
 
   void onInit() {
-    _onErrorClosure =
-        (e) => handleExternalError(e, '(DOM callback has errors)');
-
     /**
      *  The parent posts a 'start' message to kick things off,
      *  which is handled by this handler. It saves the parent
      *  window, gets the test ID from the query parameter in the
      *  IFrame URL, sets that as a solo test and starts test execution.
      */
-    window.on.message.add((MessageEvent e) {
+    window.onMessage.listen((MessageEvent e) {
       var m = new _Message.fromString(e.data);
       if (m.messageType == _Message.START) {
         parentWindow = e.source;
@@ -104,8 +102,9 @@
   }
 
   void onStart() {
-    // Listen for uncaught errors.
-    window.on.error.add(_onErrorClosure);
+    _errorSubscription = window.onError.listen((e) {
+      handleExternalError(e, '(DOM callback has errors)');
+    });
   }
 
   /** Record the start time of the test. */
@@ -153,7 +152,9 @@
   }
 
   void onDone(bool success) {
-    window.on.error.remove(_onErrorClosure);
+    assert(_errorSubscription != null);
+    _errorSubscription.cancel();
+    _errorSubscription = null;
   }
 }
 
@@ -165,8 +166,6 @@
   get autoStart => false;
   get name => 'ParentHtmlConfiguration';
   Map<int,DateTime> _testStarts;
-  // TODO(rnystrom): Get rid of this if we get canonical closures for methods.
-  EventListener _onErrorClosure;
 
   /** The stack that was posted back from the child, if any. */
   String _stack;
@@ -179,11 +178,7 @@
    */
   bool _doneWrap = false;
 
-  /**
-   * We use this to make a single closure from _handleMessage so we
-   * can remove the handler later.
-   */
-  Function _messageHandler;
+  StreamSubscription _messageSubscription, _errorSubscription;
 
   ParentHtmlConfiguration() :
       _testStarts = new Map<int,DateTime>();
@@ -207,7 +202,7 @@
       childDiv.nodes.add(child);
       completeTest = expectAsync0((){ });
       // Kick off the test when the IFrame is loaded.
-      child.on.load.add((e) {
+      child.onLoad.listen((e) {
         child.contentWindow.postMessage(_Message.text(_Message.START), '*');
       });
     };
@@ -234,23 +229,25 @@
   }
 
   void onInit() {
-    _messageHandler = _handleMessage; // We need to make just one closure.
-    _onErrorClosure =
-        (e) => handleExternalError(e, '(DOM callback has errors)');
   }
 
   void onStart() {
     // Listen for uncaught errors.
-    window.on.error.add(_onErrorClosure);
+    assert(_errorSubscription == null);
+    _errorSubscription = window.onError.listen((e) {
+      handleExternalError(e, '(DOM callback has errors)');
+    });
+
     if (!_doneWrap) {
       _doneWrap = true;
       for (int i = 0; i < testCases.length; i++) {
-        testCases[i].test = wrapTest(testCases[i]);
+        testCases[i].testFunction = wrapTest(testCases[i]);
         testCases[i].setUp = null;
         testCases[i].tearDown = null;
       }
     }
-    window.on.message.add(_messageHandler);
+
+    _messageSubscription = window.onMessage.listen(_handleMessage);
   }
 
   void onTestStart(TestCase testCase) {
@@ -281,8 +278,12 @@
       String uncaughtError) {
   }
   void onDone(bool success) {
-    window.on.message.remove(_messageHandler);
-    window.on.error.remove(_onErrorClosure);
+    _messageSubscription.cancel();
+    _messageSubscription = null;
+
+    _errorSubscription.cancel();
+    _errorSubscription = null;
+
     window.postMessage('done', '*'); // Unblock DRT
   }
 }
diff --git a/pkg/unittest/lib/interactive_html_config.dart b/pkg/unittest/lib/interactive_html_config.dart
index 3971a9f..2475d53 100644
--- a/pkg/unittest/lib/interactive_html_config.dart
+++ b/pkg/unittest/lib/interactive_html_config.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -15,6 +15,7 @@
 // IFrame for failed tests/keep IFrame for all tests.
 
 import 'dart:html';
+import 'dart:async';
 import 'dart:math';
 import 'unittest.dart';
 
@@ -53,22 +54,20 @@
 
 
 class HtmlConfiguration extends Configuration {
-  // TODO(rnystrom): Get rid of this if we get canonical closures for methods.
-  EventListener _onErrorClosure;
+  StreamSubscription _errorSubscription;
 
   void _installErrorHandler() {
-    if (_onErrorClosure == null) {
-      _onErrorClosure =
-          (e) => handleExternalError(e, '(DOM callback has errors)');
-      // Listen for uncaught errors.
-      window.on.error.add(_onErrorClosure);
+    if (_errorSubscription == null) {
+      _errorSubscription = window.onError.listen((e) {
+        handleExternalError(e, '(DOM callback has errors)');
+      });
     }
   }
 
   void _uninstallErrorHandler() {
-    if (_onErrorClosure != null) {
-      window.on.error.remove(_onErrorClosure);
-      _onErrorClosure = null;
+    if (_errorSubscription != null) {
+      _errorSubscription.cancel();
+      _errorSubscription = null;
     }
   }
 }
@@ -82,7 +81,7 @@
 class ChildInteractiveHtmlConfiguration extends HtmlConfiguration {
 
   /** The window to which results must be posted. */
-  Window parentWindow;
+  WindowBase parentWindow;
 
   /** The time at which tests start. */
   Map<int,DateTime> _testStarts;
@@ -102,7 +101,7 @@
      *  window, gets the test ID from the query parameter in the
      *  IFrame URL, sets that as a solo test and starts test execution.
      */
-    window.on.message.add((MessageEvent e) {
+    window.onMessage.listen((MessageEvent e) {
       // Get the result, do any logging, then do a pass/fail.
       var m = new _Message.fromString(e.data);
       if (m.messageType == _Message.START) {
@@ -188,11 +187,7 @@
    */
   bool _doneWrap = false;
 
-  /**
-   * We use this to make a single closure from _handleMessage so we
-   * can remove the handler later.
-   */
-  Function _messageHandler;
+  StreamSubscription _messageSubscription;
 
   ParentInteractiveHtmlConfiguration() :
       _testStarts = new Map<int,DateTime>();
@@ -214,7 +209,7 @@
       childDiv.nodes.add(child);
       completeTest = expectAsync0((){ });
       // Kick off the test when the IFrame is loaded.
-      child.on.load.add((e) {
+      child.onLoad.listen((e) {
         child.contentWindow.postMessage(_Message.text(_Message.START), '*');
       });
     };
@@ -243,7 +238,6 @@
 
   void onInit() {
     _installErrorHandler();
-    _messageHandler = _handleMessage; // We need to make just one closure.
     document.query('#group-divs').innerHtml = "";
   }
 
@@ -252,12 +246,13 @@
     if (!_doneWrap) {
       _doneWrap = true;
       for (int i = 0; i < testCases.length; i++) {
-        testCases[i].test = wrapTest(testCases[i]);
+        testCases[i].testFunction = wrapTest(testCases[i]);
         testCases[i].setUp = null;
         testCases[i].tearDown = null;
       }
     }
-    window.on.message.add(_messageHandler);
+    assert(_messageSubscription == null);
+    _messageSubscription = window.onMessage.listen(_handleMessage);
   }
 
   static final _notAlphaNumeric = new RegExp('[^a-z0-9A-Z]');
@@ -297,12 +292,12 @@
             </ul>
           </div>""");
       document.query('#group-divs').nodes.add(groupDiv);
-      groupDiv.query('.groupselect').on.click.add((e) {
+      groupDiv.query('.groupselect').onClick.listen((e) {
         var parent = document.query('#$groupId');
         InputElement cb = parent.query('.groupselect');
         var state = cb.checked;
         var tests = parent.query('.tests');
-        for (Element t in tests.elements) {
+        for (Element t in tests.children) {
           cb = t.query('.testselect') as InputElement;
           cb.checked = state;
           var testId = int.parse(t.id.substring(_testIdPrefix.length));
@@ -335,11 +330,11 @@
             </div>
           </li>""");
       list.nodes.add(testItem);
-      testItem.query('#$_selectedIdPrefix$id').on.change.add((e) {
+      testItem.query('#$_selectedIdPrefix$id').onChange.listen((e) {
         InputElement cb = testItem.query('#$_selectedIdPrefix$id');
         testCase.enabled = cb.checked;
       });
-      testItem.query('.test-label').on.click.add((e) {
+      testItem.query('.test-label').onClick.listen((e) {
         var _testItem = document.query('#$_testIdPrefix$id');
         var _actions = _testItem.query('#$_actionIdPrefix$id');
         var _label = _testItem.query('.test-name');
@@ -414,7 +409,9 @@
   }
 
   void onDone(bool success) {
-    window.on.message.remove(_messageHandler);
+    assert(_messageSubscription != null);
+    _messageSubscription.cancel();
+    _messageSubscription = null;
     _uninstallErrorHandler();
     document.query('#busy').style.display = 'none';
     InputElement startButton = document.query('#start');
@@ -440,7 +437,7 @@
         "<div id='control'>"
             "<input id='start' disabled='true' type='button' value='Run'>"
         "</div>"));
-    document.query('#start').on.click.add((e) {
+    document.query('#start').onClick.listen((e) {
       InputElement startButton = document.query('#start');
       startButton.disabled = true;
       rerunTests();
@@ -466,7 +463,7 @@
 
 /**
  * Allocate a Configuration. We allocate either a parent or
- * child, depedning on whether the URL has a search part.
+ * child, depending on whether the URL has a search part.
  */
 void useInteractiveHtmlConfiguration() {
   if (config != null) return;
diff --git a/pkg/unittest/lib/matcher.dart b/pkg/unittest/lib/matcher.dart
index 65583af..29c5504 100644
--- a/pkg/unittest/lib/matcher.dart
+++ b/pkg/unittest/lib/matcher.dart
@@ -1,14 +1,9 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 /**
  * The matcher library provides a 3rd generation assertion mechanism, drawing
- * inspiration from [Hamcrest] and Ladislav Thon's [dart-matchers]
- * library.
- *
- * See [Hamcrest] http://en.wikipedia.org/wiki/Hamcrest
- *     [Hamcrest] http://code.google.com/p/hamcrest/
- *     [dart-matchers] https://github.com/Ladicek/dart-matchers
+ * inspiration from [Hamcrest](http://code.google.com/p/hamcrest/).
  */
 library matcher;
 
diff --git a/pkg/unittest/lib/src/collection_matchers.dart b/pkg/unittest/lib/src/collection_matchers.dart
index 30e38f6..7f3a64c 100644
--- a/pkg/unittest/lib/src/collection_matchers.dart
+++ b/pkg/unittest/lib/src/collection_matchers.dart
@@ -189,10 +189,10 @@
   const _CollectionMatcher();
   Description describeMismatch(item, Description mismatchDescription,
                                MatchState matchState, bool verbose) {
-    if (item is !Collection) {
+    if (item is! Iterable) {
       return mismatchDescription.
           addDescriptionOf(item).
-          add(' not a collection');
+          add(' not an Iterable');
     } else {
       return super.describeMismatch(item, mismatchDescription, matchState,
         verbose);
diff --git a/pkg/unittest/lib/src/config.dart b/pkg/unittest/lib/src/config.dart
index 29adfc8..9b00394 100644
--- a/pkg/unittest/lib/src/config.dart
+++ b/pkg/unittest/lib/src/config.dart
@@ -158,8 +158,8 @@
   /** Handle errors that happen outside the tests. */
   // TODO(vsm): figure out how to expose the stack trace here
   // Currently e.message works in dartium, but not in dartc.
-  void handleExternalError(e, String message) =>
-      _reportTestError('$message\nCaught $e', '');
+  void handleExternalError(e, String message, [String stack = '']) =>
+      _reportTestError('$message\nCaught $e', stack);
 
   _postMessage(String message) {
     // In dart2js browser tests, the JavaScript-based test controller
diff --git a/pkg/unittest/lib/src/string_matchers.dart b/pkg/unittest/lib/src/string_matchers.dart
index 933d0a0..ae79cce 100644
--- a/pkg/unittest/lib/src/string_matchers.dart
+++ b/pkg/unittest/lib/src/string_matchers.dart
@@ -178,8 +178,8 @@
     }
   }
 
-  bool matches(String item, MatchState matchState) =>
-        _regexp.hasMatch(item);
+  bool matches(item, MatchState matchState) =>
+    item is String ? _regexp.hasMatch(item) : false;
 
   Description describe(Description description) =>
       description.add("match '${_regexp.pattern}'");
diff --git a/pkg/unittest/lib/src/test_case.dart b/pkg/unittest/lib/src/test_case.dart
index da85f80..7eb835f 100644
--- a/pkg/unittest/lib/src/test_case.dart
+++ b/pkg/unittest/lib/src/test_case.dart
@@ -1,15 +1,14 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
 part of unittest;
 
 /**
- * testcase.dart: this file is sourced by unittest.dart. It defines [TestCase]
- * and assumes unittest defines the type [TestFunction].
+ * Represents the state for an individual unit test.
+ *
+ * Create by calling [test] or [solo_test].
  */
-
-/** Summarizes information about a single test case. */
 class TestCase {
   /** Identifier for this test. */
   final int id;
@@ -18,43 +17,42 @@
   final String description;
 
   /** The setup function to call before the test, if any. */
-  Function _setUp;
-
-  Function get setUp => _setUp;
-  set setUp(Function value) => _setUp = value;
+  Function setUp;
 
   /** The teardown function to call after the test, if any. */
-  Function _tearDown;
-
-  Function get tearDown => _tearDown;
-  set tearDown(Function value) => _tearDown = value;
+  Function tearDown;
 
   /** The body of the test case. */
-  TestFunction test;
+  TestFunction testFunction;
 
   /**
    * Remaining number of callbacks functions that must reach a 'done' state
    * to wait for before the test completes.
    */
-  int callbackFunctionsOutstanding;
+  int _callbackFunctionsOutstanding = 0;
 
+  String _message = '';
   /** Error or failure message. */
-  String message = '';
+  String get message => _message;
 
+  String _result;
   /**
    * One of [PASS], [FAIL], [ERROR], or [null] if the test hasn't run yet.
    */
-  String result;
+  String get result => _result;
 
-  /** Stack trace associated with this test, or null if it succeeded. */
-  String stackTrace;
+  String _stackTrace;
+  /** Stack trace associated with this test, or [null] if it succeeded. */
+  String get stackTrace => _stackTrace;
 
   /** The group (or groups) under which this test is running. */
   final String currentGroup;
 
-  DateTime startTime;
+  DateTime _startTime;
+  DateTime get startTime => _startTime;
 
-  Duration runningTime;
+  Duration _runningTime;
+  Duration get runningTime => _runningTime;
 
   bool enabled = true;
 
@@ -62,18 +60,17 @@
 
   Completer _testComplete;
 
-  TestCase(this.id, this.description, this.test,
-           this.callbackFunctionsOutstanding)
+  TestCase._internal(this.id, this.description, this.testFunction)
   : currentGroup = _currentGroup,
-    _setUp = _testSetup,
-    _tearDown = _testTeardown;
+    setUp = _testSetup,
+    tearDown = _testTeardown;
 
   bool get isComplete => !enabled || result != null;
 
   void _prepTest() {
     _config.onTestStart(this);
-    startTime = new DateTime.now();
-    runningTime = null;
+    _startTime = new DateTime.now();
+    _runningTime = null;
   }
 
   Future _runTest() {
@@ -81,9 +78,9 @@
     // Increment/decrement callbackFunctionsOutstanding to prevent
     // synchronous 'async' callbacks from causing the  test to be
     // marked as complete before the body is completely executed.
-    ++callbackFunctionsOutstanding;
-    var f = test();
-    --callbackFunctionsOutstanding;
+    ++_callbackFunctionsOutstanding;
+    var f = testFunction();
+    --_callbackFunctionsOutstanding;
     if (f is Future) {
       f.then((_) => _finishTest())
        .catchError((e) => fail("${e.error}"));
@@ -95,24 +92,24 @@
   }
 
   void _finishTest() {
-    if (result == null && callbackFunctionsOutstanding == 0) {
+    if (result == null && _callbackFunctionsOutstanding == 0) {
       pass();
     }
   }
 
   /**
-   * Perform any associated [setUp] function and run the test. Returns
+   * Perform any associated [_setUp] function and run the test. Returns
    * a [Future] that can be used to schedule the next test. If the test runs
-   * to completion synchronously, or is disabled, we return null, to
+   * to completion synchronously, or is disabled, null is returned, to
    * tell unittest to schedule the next test immediately.
    */
-  Future run() {
+  Future _run() {
     if (!enabled) return null;
 
-    result = stackTrace = null;
-    message = '';
+    _result = _stackTrace = null;
+    _message = '';
     _doneTeardown = false;
-    var rtn = _setUp == null ? null : _setUp();
+    var rtn = setUp == null ? null : setUp();
     if (rtn is Future) {
       rtn.then((_) => _runTest())
          .catchError((e) {
@@ -120,7 +117,7 @@
           // Calling error() will result in the tearDown being done.
           // One could debate whether tearDown should be done after
           // a failed setUp. There is no right answer, but doing it
-          // seems to be the more conservative approach, because 
+          // seems to be the more conservative approach, because
           // unittest will not stop at a test failure.
           error("$description: Test setup failed: ${e.error}");
         });
@@ -147,13 +144,13 @@
   // Set the results, notify the config, and return true if this
   // is the first time the result is being set.
   void _setResult(String testResult, String messageText, String stack) {
-    message = messageText;
-    stackTrace = stack;
+    _message = messageText;
+    _stackTrace = stack;
     if (result == null) {
-      result = testResult;
+      _result = testResult;
       _config.onTestResult(this);
     } else {
-      result = testResult;
+      _result = testResult;
       _config.onTestResultChanged(this);
     }
   }
@@ -162,16 +159,13 @@
                 [String messageText = '',
                  String stack = '']) {
     if (runningTime == null) {
-      // TODO(gram): currently the duration measurement code is blocked
-      // by issue 4437. When that is fixed replace the line below with:
-      //    runningTime = new DateTime.now().difference(startTime);
-      runningTime = new Duration(milliseconds: 0);
+      _runningTime = new DateTime.now().difference(startTime);
     }
     _setResult(testResult, messageText, stack);
     if (!_doneTeardown) {
       _doneTeardown = true;
-      if (_tearDown != null) {
-        var rtn = _tearDown();
+      if (tearDown != null) {
+        var rtn = tearDown();
         if (rtn is Future) {
           rtn.then((_) {
             _notifyComplete();
@@ -210,8 +204,8 @@
     _complete(ERROR, messageText, stack);
   }
 
-  void markCallbackComplete() {
-    if (--callbackFunctionsOutstanding == 0 && !isComplete) {
+  void _markCallbackComplete() {
+    if (--_callbackFunctionsOutstanding == 0 && !isComplete) {
       pass();
     }
   }
diff --git a/pkg/unittest/lib/unittest.dart b/pkg/unittest/lib/unittest.dart
index 1177de5..2132a3e 100644
--- a/pkg/unittest/lib/unittest.dart
+++ b/pkg/unittest/lib/unittest.dart
@@ -1,33 +1,27 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
 /**
  * A library for writing dart unit tests.
  *
- * To import this library, use the pub package manager.
- * Create a pubspec.yaml file in your project and add
- * a dependency on unittest with the following lines:
- *     dependencies:
- *       unittest: any
- *
- * Then run 'pub install' from your project directory or using
- * the DartEditor.
- *
- * Please see [Pub Getting Started](http://pub.dartlang.org/doc)
- * for more details about the pub package manager.
+ * To import this library, install the
+ * [unittest package](http://pub.dartlang.org/packages/unittest) via the pub
+ * package manager. See the [Getting Started](http://pub.dartlang.org/doc)
+ * guide for more details.
  *
  * ##Concepts##
  *
- *  * Tests: Tests are specified via the top-level function [test], they can be
+ *  * __Tests__: Tests are specified via the top-level function [test], they can be
  *    organized together using [group].
- *  * Checks: Test expectations can be specified via [expect]
- *  * Matchers: [expect] assertions are written declaratively using [Matcher]s
- *  * Configuration: The framework can be adapted by calling [configure] with a
- *    [Configuration].  Common configurations can be found in this package
- *    under: 'dom\_config.dart' (deprecated), 'html\_config.dart' (for running
- *    tests compiled to Javascript in a browser), and 'vm\_config.dart' (for
- *    running native Dart tests on the VM).
+ *  * __Checks__: Test expectations can be specified via [expect]
+ *  * __Matchers__: [expect] assertions are written declaratively using the
+ *    [Matcher] class.
+ *  * __Configuration__: The framework can be adapted by calling [configure] with a
+ *    [Configuration]. See the other libraries in the `unittest` package for
+ *    alternative implementations of [Configuration] including
+ *    `compact_vm_config.dart`, `html_config.dart` and
+ *    `html_enhanced_config.dart`.
  *
  * ##Examples##
  *
@@ -258,7 +252,7 @@
  */
 void test(String spec, TestFunction body) {
   ensureInitialized();
-  _tests.add(new TestCase(_tests.length + 1, _fullSpec(spec), body, 0));
+  _tests.add(new TestCase._internal(_tests.length + 1, _fullSpec(spec), body));
 }
 
 /**
@@ -280,7 +274,7 @@
 
   ensureInitialized();
 
-  _soloTest = new TestCase(_tests.length + 1, _fullSpec(spec), body, 0);
+  _soloTest = new TestCase._internal(_tests.length + 1, _fullSpec(spec), body);
   _tests.add(_soloTest);
 }
 
@@ -326,7 +320,7 @@
            _tests[_currentTest] != null);
     testCase = _tests[_currentTest];
     if (isDone != null || minExpected > 0) {
-      testCase.callbackFunctionsOutstanding++;
+      testCase._callbackFunctionsOutstanding++;
       complete = false;
     } else {
       complete = true;
@@ -382,7 +376,7 @@
       // Mark this callback as complete and remove it from the testcase
       // oustanding callback count; if that hits zero the testcase is done.
       complete = true;
-      testCase.markCallbackComplete();
+      testCase._markCallbackComplete();
     }
   }
 
@@ -695,7 +689,7 @@
   } else if (testFilter is Function) {
     filterFunction = testFilter;
   }
-  _tests.retainMatching(filterFunction);
+  _tests.retainWhere(filterFunction);
 }
 
 /** Runs all queued tests, one at a time. */
@@ -768,7 +762,7 @@
       break;
     }
     final testCase = _tests[_currentTest];
-    var f = _guardAsync(testCase.run, null, _currentTest);
+    var f = _guardAsync(testCase._run, null, _currentTest);
     if (f != null) {
       f.whenComplete(() {
         _nextTestCase(); // Schedule the next test.
diff --git a/pkg/unittest/lib/vm_config.dart b/pkg/unittest/lib/vm_config.dart
index d75cb2a..1f4ce0d 100644
--- a/pkg/unittest/lib/vm_config.dart
+++ b/pkg/unittest/lib/vm_config.dart
@@ -15,6 +15,7 @@
   void onDone(bool success) {
     try {
       super.onDone(success);
+      exit(0);
     } catch (ex) {
       // A non-zero exit code is used by the test infrastructure to detect
       // failure.
diff --git a/pkg/webdriver/lib/webdriver.dart b/pkg/webdriver/lib/webdriver.dart
index 41d0cbc..9fed8d7 100644
--- a/pkg/webdriver/lib/webdriver.dart
+++ b/pkg/webdriver/lib/webdriver.dart
@@ -4,9 +4,10 @@
 
 library webdriver;
 
+import 'dart:async';
+import 'dart:io';
 import 'dart:json' as json;
 import 'dart:uri';
-import 'dart:io';
 
 part 'src/base64decoder.dart';
 
@@ -33,18 +34,18 @@
  *     String id;
  *     WebDriverSession session;
  *     Future f = web_driver.newSession('chrome');
- *     f.chain((_session) {
+ *     f.then((_session) {
  *       session = _session;
  *       return session.setUrl('http://my.web.site.com');
- *    }).chain((_) {
+ *    }).then((_) {
  *      return session.findElement('id', 'username');
- *    }).chain((element) {
+ *    }).then((element) {
  *      id = element['ELEMENT'];
  *      return session.sendKeyStrokesToElement(id,
  *          [ 'j', 'o', 'e', ' ', 'u', 's', 'e', 'r' ]);
- *    }).chain((_) {
+ *    }).then((_) {
  *      return session.submit(id);
- *    }).chain((_) {
+ *    }).then((_) {
  *      return session.close();
  *    }).then((_) {
  *      session = null;
@@ -214,6 +215,12 @@
     _url = 'http://$_host:$_port$_path';
   }
 
+  void _failRequest(Completer completer, error, StackTrace stackTrace) {
+    if (completer != null) {
+      completer.completeError(new WebDriverError(-1, error), stackTrace);
+    }
+  }
+
   /**
    * Execute a request to the WebDriver server. [http_method] should be
    * one of 'GET', 'POST', or 'DELETE'. [command] is the text to append
@@ -222,7 +229,7 @@
    * If a number or string, "/params" is appended to the URL.
    */
   void _serverRequest(String http_method, String command, Completer completer,
-                      [List successCodes, Map params, Function customHandler]) {
+                      {List successCodes, params, Function customHandler}) {
     var status = 0;
     var results = null;
     var message = null;
@@ -230,110 +237,106 @@
       successCodes = [ 200, 204 ];
     }
     try {
-      if (params != null && params is List && http_method != 'POST') {
-        throw new Exception(
-          'The http method called for ${command} is ${http_method} but it has '
-          'to be POST if you want to pass the JSON params '
-          '${json.stringify(params)}');
-      }
-
       var path = command;
-      if (params != null && (params is num || params is String)) {
-        path = '$path/$params';
+      if (params != null) {
+        if (params is num || params is String) {
+          path = '$path/$params';
+          params = null;
+        } else if (http_method != 'POST') {
+          throw new Exception(
+            'The http method called for ${command} is ${http_method} but it '
+            'must be POST if you want to pass the JSON params '
+            '${json.stringify(params)}');
+        }
       }
 
       var client = new HttpClient();
-      var connection = client.open(http_method, _host, _port, path);
-
-      connection.onRequest = (r) {
-        r.headers.add(HttpHeaders.ACCEPT, "application/json");
-        r.headers.add(
+      client.open(http_method, _host, _port, path).then((req) {
+        req.followRedirects = false;
+        req.headers.add(HttpHeaders.ACCEPT, "application/json");
+        req.headers.add(
             HttpHeaders.CONTENT_TYPE, 'application/json;charset=UTF-8');
-        OutputStream s = r.outputStream;
-        if (params != null && params is Map) {
-          s.writeString(json.stringify(params));
+        if (params != null) {
+          var body = json.stringify(params);
+          req.write(body);
         }
-        s.close();
-      };
-      connection.onError = (e) {
-        if (completer != null) {
-          completer.completeError(new WebDriverError(-1, e));
+        req.close().then((rsp) {
+          List<int> body = new List<int>();
+          rsp.listen(body.addAll, onDone: () {
+            var value = null;
+            // For some reason we get a bunch of NULs on the end
+            // of the text and the json.parse blows up on these, so
+            // strip them with trim().
+            // These NULs can be seen in the TCP packet, so it is not
+            // an issue with character encoding; it seems to be a bug
+            // in WebDriver stack.
+            results = new String.fromCharCodes(body).trim();
+            if (!successCodes.contains(rsp.statusCode)) {
+              _failRequest(completer, 
+                  'Unexpected response ${rsp.statusCode}; $results', null);
+              completer = null;
+              return;
+            }
+            if (status == 0 && results.length > 0) {
+              // 4xx responses send plain text; others send JSON.
+              if (rsp.statusCode < 400) {
+                results = json.parse(results);
+                status = results['status'];
+              }
+              if (results is Map && (results as Map).containsKey('value')) {
+                value = results['value'];
+              }
+              if (value is Map && value.containsKey('message')) {
+                message = value['message'];
+              }
+            }
+            if (status == 0) {
+              if (customHandler != null) {
+                customHandler(rsp, value);
+              } else if (completer != null) {
+                completer.complete(value);
+              }
+            }
+          }, onError: (e) {
+            _failRequest(completer, e.error, e.stackTrace);
+            completer = null;
+          });
+        })
+        .catchError((e) {
+          _failRequest(completer, e.error, e.stackTrace);
           completer = null;
-        }
-      };
-      connection.followRedirects = false;
-      connection.onResponse = (r) {
-        StringInputStream s = new StringInputStream(r.inputStream);
-        StringBuffer sbuf = new StringBuffer();
-        s.onData = () {
-          var data = s.read();
-          if (data != null) {
-            sbuf.add(data);
-          }
-        };
-        s.onClosed = () {
-          var value = null;
-          results  = sbuf.toString().trim();
-          // For some reason we get a bunch of NULs on the end
-          // of the text and the json.parse blows up on these, so
-          // strip them.
-          // These NULs can be seen in the TCP packet, so it is not
-          // an issue with character encoding; it seems to be a bug
-          // in WebDriver stack.
-          for (var i = results.length; --i >= 0;) {
-            var code = results.codeUnitAt(i);
-            if (code != 0) {
-              results = results.substring(0, i + 1);
-              break;
-            }
-          }
-          if (successCodes.indexOf(r.statusCode) < 0) {
-            throw 'Unexpected response ${r.statusCode}';
-          }
-          if (status == 0 && results.length > 0) {
-            // 4xx responses send plain text; others send JSON.
-            if (r.statusCode < 400) {
-              results = json.parse(results);
-              status = results['status'];
-            }
-            if (results is Map && (results as Map).containsKey('value')) {
-              value = results['value'];
-            }
-            if (value is Map && value.containsKey('message')) {
-              message = value['message'];
-            }
-          }
-          if (status == 0) {
-            if (customHandler != null) {
-              customHandler(r, value);
-            } else if (completer != null) {
-              completer.complete(value);
-            }
-          }
-        };
-      };
+        });
+      })
+      .catchError((e) {
+        _failRequest(completer, e.error, e.stackTrace);
+        completer = null;
+      });
     } catch (e, s) {
-      completer.completeError(
-          new WebDriverError(-1, e), s);
+      _failRequest(completer, e, s);
       completer = null;
     }
   }
 
-  Future _simpleCommand(method, extraPath, [successCodes, params]) {
-    var completer = new Completer();
-    _serverRequest(method, '${_path}/$extraPath', completer,
-          successCodes, params: params);
+  Future _get(String extraPath,
+      [Completer completer, Function customHandler]) {
+    if (completer == null) completer = new Completer();
+    _serverRequest('GET', '${_path}/$extraPath', completer,
+        customHandler: customHandler);
     return completer.future;
   }
 
-  Future _get(extraPath, [successCodes]) =>
-      _simpleCommand('GET', extraPath, successCodes);
+  Future _post(String extraPath, [params]) {
+    var completer = new Completer();
+    _serverRequest('POST', '${_path}/$extraPath', completer,
+        params: params);
+    return completer.future;
+  }
 
-  Future _post(extraPath, [successCodes, params]) =>
-      _simpleCommand('POST', extraPath, successCodes, params);
-
-  Future _delete(extraPath, [successCodes]) =>
-      _simpleCommand('DELETE', extraPath, successCodes);
+  Future _delete(String extraPath) {
+    var completer = new Completer();
+    _serverRequest('DELETE', '${_path}/$extraPath', completer);
+    return completer.future;
+  }
 }
 
 class WebDriver extends WebDriverBase {
@@ -432,27 +435,29 @@
 
     additional_capabilities['browserName'] = browser;
 
-    _serverRequest('POST', '${_path}/session', null, [ 302 ],
+    _serverRequest('POST', '${_path}/session', completer,
+        successCodes: [ 302 ],
         customHandler: (r, v) {
           var url = r.headers.value(HttpHeaders.LOCATION);
           var session = new WebDriverSession.fromUrl(url);
           completer.complete(session);
-        }, params: { 'desiredCapabilities': additional_capabilities });
+        },
+        params: { 'desiredCapabilities': additional_capabilities });
     return completer.future;
   }
 
   /** Get the set of currently active sessions. */
   Future<List<WebDriverSession>> getSessions() {
     var completer = new Completer();
-    _get('sessions', (result) {
+    return _get('sessions', completer, (r, v) {
       var _sessions = [];
-      for (var session in result) {
-        _sessions.add(new WebDriverSession.fromUrl(
-          '${this._path}/session/${session["id"]}'));
+      for (var session in v) {
+        var url = 'http://${this._host}:${this._port}${this._path}/'
+            'session/${session["id"]}';
+        _sessions.add(new WebDriverSession.fromUrl(url));
       }
       completer.complete(_sessions);
     });
-    return completer.future;
   }
 
   /** Query the server's current status. */
@@ -466,24 +471,26 @@
   Future<Map> getSize() => _get('size');
 
   /**
-   * Set the window size.
+   * Set the window size. Note that this is flaky and often
+   * has no effect.
    *
    * Potential Errors:
    *   NoSuchWindow - If the specified window cannot be found.
    */
   Future<String> setSize(int width, int height) =>
-      _post('size', params: { 'width': width, 'height': height });
+      _post('size', { 'width': width, 'height': height });
 
   /** Get the window position. */
   Future<Map> getPosition() => _get('position');
 
   /**
-   * Set the window position.
+   * Set the window position. Note that this is flaky and often
+   * has no effect.
    *
    * Potential Errors: NoSuchWindow.
    */
   Future setPosition(int x, int y) =>
-      _post('position', params: { 'x': x, 'y': y });
+      _post('position', { 'x': x, 'y': y });
 
   /** Maximize the specified window if not already maximized. */
   Future maximize() => _post('maximize');
@@ -503,7 +510,7 @@
    * for before it is aborted and a Timeout error is returned to the client.
    */
   Future setScriptTimeout(t) =>
-      _post('timeouts', params: { 'type': 'script', 'ms': t });
+      _post('timeouts', { 'type': 'script', 'ms': t });
 
   /*Future<String> setImplicitWaitTimeout(t) =>
       simplePost('timeouts', { 'type': 'implicit', 'ms': t });*/
@@ -513,7 +520,7 @@
    * before it is aborted and a Timeout error is returned to the client.
    */
   Future setPageLoadTimeout(t) =>
-      _post('timeouts', params: { 'type': 'page load', 'ms': t });
+      _post('timeouts', { 'type': 'page load', 'ms': t });
 
   /**
    * Set the amount of time, in milliseconds, that asynchronous scripts
@@ -521,7 +528,7 @@
    * before they are aborted and a Timeout error is returned to the client.
    */
   Future setAsyncScriptTimeout(t) =>
-      _post('timeouts/async_script', params: { 'ms': t });
+      _post('timeouts/async_script', { 'ms': t });
 
   /**
    * Set the amount of time the driver should wait when searching for elements.
@@ -535,7 +542,7 @@
    * wait of 0ms.
    */
   Future setImplicitWaitTimeout(t) =>
-      _post('timeouts/implicit_wait', params: { 'ms': t });
+      _post('timeouts/implicit_wait', { 'ms': t });
 
   /**
    * Retrieve the current window handle.
@@ -569,7 +576,7 @@
    *
    * Potential Errors: NoSuchWindow.
    */
-  Future setUrl(String url) => _post('url', params: { 'url': url });
+  Future setUrl(String url) => _post('url', { 'url': url });
 
   /**
    * Navigate forwards in the browser history, if possible.
@@ -611,8 +618,10 @@
    *
    * Potential Errors: NoSuchWindow, StaleElementReference, JavaScriptError.
    */
-  Future execute(String script, [List args]) =>
-      _post('execute', params: { 'script': script, 'args': args });
+  Future execute(String script, [List args]) {
+    if (args == null) args = [];
+    return _post('execute', { 'script': script, 'args': args });
+  }
 
   /**
    * Inject a snippet of JavaScript into the page for execution in the context
@@ -640,8 +649,10 @@
    * by the [setAsyncScriptTimeout] command), JavaScriptError (if the script
    * callback is not invoked before the timout expires).
    */
-  Future executeAsync(String script, [List args]) =>
-      _post('execute_async', params: { 'script': script, 'args': args });
+  Future executeAsync(String script, [List args]) {
+    if (args == null) args = [];
+    return _post('execute_async', { 'script': script, 'args': args });
+  }
 
   /**
    * Take a screenshot of the current page (PNG).
@@ -650,15 +661,13 @@
    */
   Future<List<int>> getScreenshot([fname]) {
     var completer = new Completer();
-    var result = _serverRequest('GET', '$_path/screenshot', completer,
-        customHandler: (r, v) {
+    return _get('screenshot', completer, (r, v) {
       var image = Base64Decoder.decode(v);
       if (fname != null) {
         writeBytesToFile(fname, image);
       }
       completer.complete(image);
     });
-    return completer.future;
   }
 
   /**
@@ -704,7 +713,7 @@
    * Potential Errors: ImeActivationFailedException, ImeNotAvailableException.
    */
   Future activateIme(String engine) =>
-      _post('ime/activate', params: { 'engine': engine });
+      _post('ime/activate', { 'engine': engine });
 
   /**
    * Change focus to another frame on the page. If the frame id is null,
@@ -714,7 +723,7 @@
    *
    * Potential Errors: NoSuchWindow, NoSuchFrame.
    */
-  Future setFrameFocus(id) => _post('frame', params: { 'id': id });
+  Future setFrameFocus(id) => _post('frame', { 'id': id });
 
   /**
    * Change focus to another window. The window to change focus to may be
@@ -723,8 +732,7 @@
    *
    * Potential Errors: NoSuchWindow.
    */
-  Future setWindowFocus(name) =>
-      _post('window', params: { 'name': name });
+  Future setWindowFocus(name) => _post('window', { 'name': name });
 
   /**
    * Close the current window.
@@ -762,8 +770,7 @@
    * current page's domain. See [getCookies] for the structure of a cookie
    * Map.
    */
-  Future setCookie(Map cookie) =>
-      _post('cookie', params: { 'cookie': cookie });
+  Future setCookie(Map cookie) => _post('cookie', { 'cookie': cookie });
 
   /**
    * Delete all cookies visible to the current page.
@@ -827,7 +834,7 @@
    * using XPath and the input expression is invalid).
    */
   Future<String> findElement(String strategy, String searchValue) =>
-      _post('element', params: { 'using': strategy, 'value' : searchValue });
+      _post('element', { 'using': strategy, 'value' : searchValue });
 
   /**
    * Search for multiple elements on the page, starting from the document root.
@@ -838,7 +845,7 @@
    * Potential Errors: NoSuchWindow, XPathLookupError.
    */
   Future<List<String>> findElements(String strategy, String searchValue) =>
-      _post('elements', params: { 'using': strategy, 'value' : searchValue });
+      _post('elements', { 'using': strategy, 'value' : searchValue });
 
   /**
    * Get the element on the page that currently has focus. The element will
@@ -857,8 +864,7 @@
    */
   Future<String>
       findElementFromId(String id, String strategy, String searchValue) {
-    _post('element/$id/element',
-              params: { 'using': strategy, 'value' : searchValue });
+    _post('element/$id/element', { 'using': strategy, 'value' : searchValue });
   }
 
   /**
@@ -1002,7 +1008,7 @@
    * Potential Errors: NoSuchWindow, StaleElementReference, ElementNotVisible.
    */
   Future sendKeyStrokesToElement(String id, List<String> keys) =>
-      _post('element/$id/value', params: { 'value': keys });
+      _post('element/$id/value', { 'value': keys });
 
   /**
    * Send a sequence of key strokes to the active element. This command is
@@ -1013,8 +1019,7 @@
    *
    * Potential Errors: NoSuchWindow.
    */
-  Future sendKeyStrokes(List<String> keys) =>
-      _post('keys', params: { 'value': keys });
+  Future sendKeyStrokes(List<String> keys) => _post('keys', { 'value': keys });
 
   /**
    * Query for an element's tag name, as a lower-case string.
@@ -1119,7 +1124,7 @@
    * Potential Errors: NoAlertPresent.
    */
   Future sendKeyStrokesToPrompt(String text) =>
-      _post('alert_text', params: { 'text': text });
+      _post('alert_text', { 'text': text });
 
   /**
    * Accepts the currently displayed alert dialog. Usually, this is equivalent
@@ -1146,7 +1151,7 @@
    * into view.
    */
   Future moveTo(String id, int x, int y) =>
-      _post('moveto', params: { 'element': id, 'xoffset': x, 'yoffset' : y});
+      _post('moveto', { 'element': id, 'xoffset': x, 'yoffset' : y});
 
   /**
    * Click a mouse button (at the coordinates set by the last [moveTo] command).
@@ -1156,8 +1161,7 @@
    *
    * [button] should be 0 for left, 1 for middle, or 2 for right.
    */
-  Future clickMouse([button = 0]) =>
-      _post('click', params: { 'button' : button });
+  Future clickMouse([button = 0]) => _post('click', { 'button' : button });
 
   /**
    * Click and hold the left mouse button (at the coordinates set by the last
@@ -1167,8 +1171,7 @@
    *
    * [button] should be 0 for left, 1 for middle, or 2 for right.
    */
-  Future buttonDown([button = 0]) =>
-      _post('click', params: { 'button' : button });
+  Future buttonDown([button = 0]) => _post('click', { 'button' : button });
 
   /**
    * Releases the mouse button previously held (where the mouse is currently
@@ -1178,27 +1181,22 @@
    *
    * [button] should be 0 for left, 1 for middle, or 2 for right.
    */
-  Future buttonUp([button = 0]) =>
-      _post('click', params: { 'button' : button });
+  Future buttonUp([button = 0]) => _post('click', { 'button' : button });
 
   /** Double-clicks at the current mouse coordinates (set by [moveTo]). */
   Future doubleClick() => _post('doubleclick');
 
   /** Single tap on the touch enabled device on the element with id [id]. */
-  Future touchClick(String id) =>
-      _post('touch/click', params: { 'element': id });
+  Future touchClick(String id) => _post('touch/click', { 'element': id });
 
   /** Finger down on the screen. */
-  Future touchDown(int x, int y) =>
-      _post('touch/down', params: { 'x': x, 'y': y });
+  Future touchDown(int x, int y) => _post('touch/down', { 'x': x, 'y': y });
 
   /** Finger up on the screen. */
-  Future touchUp(int x, int y) =>
-      _post('touch/up', params: { 'x': x, 'y': y });
+  Future touchUp(int x, int y) => _post('touch/up', { 'x': x, 'y': y }); 
 
   /** Finger move on the screen. */
-  Future touchMove(int x, int y) =>
-      _post('touch/move', params: { 'x': x, 'y': y });
+  Future touchMove(int x, int y) => _post('touch/move', { 'x': x, 'y': y });
 
   /**
    * Scroll on the touch screen using finger based motion events. If [id] is
@@ -1206,21 +1204,20 @@
    */
   Future touchScroll(int xOffset, int yOffset, [String id = null]) {
     if (id == null) {
-      return _post('touch/scroll',
-          params: { 'xoffset': xOffset, 'yoffset': yOffset });
+      return _post('touch/scroll', { 'xoffset': xOffset, 'yoffset': yOffset });
     } else {
       return _post('touch/scroll',
-          params: { 'element': id, 'xoffset': xOffset, 'yoffset': yOffset });
+          { 'element': id, 'xoffset': xOffset, 'yoffset': yOffset });
     }
   }
 
   /** Double tap on the touch screen using finger motion events. */
   Future touchDoubleClick(String id) =>
-      _post('touch/doubleclick', params: { 'element': id });
+      _post('touch/doubleclick', { 'element': id });
 
   /** Long press on the touch screen using finger motion events. */
   Future touchLongClick(String id) =>
-      _post('touch/longclick', params: { 'element': id });
+      _post('touch/longclick', { 'element': id });
 
   /**
    * Flick on the touch screen using finger based motion events, starting
@@ -1228,7 +1225,7 @@
    */
   Future touchFlickFrom(String id, int xOffset, int yOffset, int speed) =>
           _post('touch/flick',
-              params: { 'element': id, 'xoffset': xOffset, 'yoffset': yOffset,
+              { 'element': id, 'xoffset': xOffset, 'yoffset': yOffset,
                         'speed': speed });
 
   /**
@@ -1236,7 +1233,7 @@
    * instead of [touchFlickFrom] if you don'tr care where the flick starts.
    */
   Future touchFlick(int xSpeed, int ySpeed) =>
-      _post('touch/flick', params: { 'xSpeed': xSpeed, 'ySpeed': ySpeed });
+      _post('touch/flick', { 'xSpeed': xSpeed, 'ySpeed': ySpeed });
 
   /**
    * Get the current geo location. Returns a [Map] with latitude,
@@ -1246,103 +1243,196 @@
 
   /** Set the current geo location. */
   Future setLocation(double latitude, double longitude, double altitude) =>
-          _post('location', params:
+          _post('location',
               { 'latitude': latitude,
                 'longitude': longitude,
                 'altitude': altitude });
 
   /**
+   * Only a few drivers actually support the JSON storage commands.
+   * Currently it looks like this is the Android and iPhone drivers only.
+   * For the rest, we can achieve a similar effect with Javascript
+   * execution. The flag below is used to control whether to do this.
+   */
+  bool useJavascriptForStorageAPIs = true;
+
+  /**
    * Get all keys of the local storage. Completes with [null] if there
    * are no keys or the keys could not be retrieved.
    *
    * Potential Errors: NoSuchWindow.
    */
-  Future<List<String>> getLocalStorageKeys() => _get('local_storage');
+  Future<List<String>> getLocalStorageKeys() {
+    if (useJavascriptForStorageAPIs) {
+      return execute(
+          'var rtn = [];'
+          'for (var i = 0; i < window.localStorage.length; i++)'
+          '  rtn.push(window.localStorage.key(i));'
+          'return rtn;'); 
+    } else {
+      return _get('local_storage');
+    }
+  }
 
   /**
    * Set the local storage item for the given key.
    *
    * Potential Errors: NoSuchWindow.
    */
-  Future setLocalStorageItem(String key, String value) =>
-      _post('local_storage', params: { 'key': key, 'value': value });
+  Future setLocalStorageItem(String key, String value) {
+    if (useJavascriptForStorageAPIs) {
+      return execute('window.localStorage.setItem(arguments[0], arguments[1]);',
+          [key, value]); 
+    } else {
+      return _post('local_storage', { 'key': key, 'value': value });
+    }
+  }
 
   /**
    * Clear the local storage.
    *
    * Potential Errors: NoSuchWindow.
    */
-  Future clearLocalStorage() => _delete('local_storage');
+  Future clearLocalStorage() {
+    if (useJavascriptForStorageAPIs) {
+      return execute('return window.localStorage.clear();');
+    } else {
+      return _delete('local_storage');
+    }
+  }
 
   /**
    * Get the local storage item for the given key.
    *
    * Potential Errors: NoSuchWindow.
    */
-  Future<String> getLocalStorageValue(String key) =>
-      _get('local_storage/key/$key');
+  Future<String> getLocalStorageValue(String key) {
+    if (useJavascriptForStorageAPIs) {
+      return execute('return window.localStorage.getItem(arguments[0]);',
+          [key]); 
+    } else {
+      return _get('local_storage/key/$key');
+    }
+  }
 
   /**
    * Delete the local storage item for the given key.
    *
    * Potential Errors: NoSuchWindow.
    */
-  Future deleteLocalStorageValue(String key) =>
-      _delete('local_storage/key/$key');
+  Future deleteLocalStorageValue(String key) {
+    if (useJavascriptForStorageAPIs) {
+      return execute('return window.localStorage.removeItem(arguments[0]);',
+          [key]); 
+    } else {
+      return _delete('local_storage/key/$key');
+    }
+  }
 
   /**
    * Get the number of items in the local storage.
    *
    * Potential Errors: NoSuchWindow.
    */
-  Future<int> getLocalStorageCount() => _get('local_storage/size');
+  Future<int> getLocalStorageCount() {
+    if (useJavascriptForStorageAPIs) {
+      return execute('return window.localStorage.length;'); 
+    } else {
+      return _get('local_storage/size');
+    }
+  }
 
   /**
    * Get all keys of the session storage.
    *
    * Potential Errors: NoSuchWindow.
    */
-  Future<List<String>> getSessionStorageKeys() => _get('session_storage');
+  Future<List<String>> getSessionStorageKeys() {
+    if (useJavascriptForStorageAPIs) {
+      return execute(
+          'var rtn = [];'
+          'for (var i = 0; i < window.sessionStorage.length; i++)'
+          '  rtn.push(window.sessionStorage.key(i));'
+          'return rtn;'); 
+    } else {
+      return _get('session_storage');
+    }
+  }
 
   /**
    * Set the sessionstorage item for the given key.
    *
    * Potential Errors: NoSuchWindow.
    */
-  Future setSessionStorageItem(String key, String value) =>
-      _post('session_storage', params: { 'key': key, 'value': value });
+  Future setSessionStorageItem(String key, String value) {
+    if (useJavascriptForStorageAPIs) {
+      return execute(
+          'window.sessionStorage.setItem(arguments[0], arguments[1]);',
+              [key, value]); 
+    } else {
+      return _post('session_storage', { 'key': key, 'value': value });
+    }
+  }
 
   /**
    * Clear the session storage.
    *
    * Potential Errors: NoSuchWindow.
    */
-  Future clearSessionStorage() => _delete('session_storage');
+  Future clearSessionStorage() {
+    if (useJavascriptForStorageAPIs) {
+      return execute('window.sessionStorage.clear();');
+    } else {
+      return _delete('session_storage');
+    }
+  }
 
   /**
    * Get the session storage item for the given key.
    *
    * Potential Errors: NoSuchWindow.
    */
-  Future<String> getSessionStorageValue(String key) =>
-      _get('session_storage/key/$key');
+  Future<String> getSessionStorageValue(String key) {
+    if (useJavascriptForStorageAPIs) {
+      return execute('return window.sessionStorage.getItem(arguments[0]);',
+          [key]); 
+    } else {
+      return _get('session_storage/key/$key');
+    }
+  }
 
   /**
    * Delete the session storage item for the given key.
    *
    * Potential Errors: NoSuchWindow.
    */
-  Future deleteSessionStorageValue(String key) =>
-      _delete('session_storage/key/$key');
+  Future deleteSessionStorageValue(String key) {
+    if (useJavascriptForStorageAPIs) {
+      return execute('return window.sessionStorage.removeItem(arguments[0]);',
+          [key]); 
+    } else {
+      return _delete('session_storage/key/$key');
+    }
+  }
 
   /**
    * Get the number of items in the session storage.
    *
    * Potential Errors: NoSuchWindow.
    */
-  Future<String> getSessionStorageCount() => _get('session_storage/size');
+  Future<String> getSessionStorageCount() {
+    if (useJavascriptForStorageAPIs) {
+      return execute('return window.sessionStorage.length;');
+    } else {
+      return _get('session_storage/size');
+    }
+  }
 
-  /** Get available log types ('client', 'driver', 'browser', 'server'). */
+  /**
+   * Get available log types ('client', 'driver', 'browser', 'server').
+   * This works with Firefox but Chrome returns a 500 response due to a 
+   * bad cast.
+   */
   Future<List<String>> getLogTypes() => _get('log/types');
 
   /**
@@ -1352,7 +1442,9 @@
    * 'timestamp' (int) - The timestamp of the entry.
    * 'level' (String) - The log level of the entry, for example, "INFO".
    * 'message' (String) - The log message.
+   *
+   * This works with Firefox but Chrome returns a 500 response due to a 
+   * bad cast.
    */
-  Future<List<Map>> getLogs(String type) =>
-      _post('log', params: { 'type': type });
+  Future<List<Map>> getLogs(String type) => _post('log', { 'type': type });
 }
diff --git a/pkg/webdriver/test/webdriver_test.dart b/pkg/webdriver/test/webdriver_test.dart
new file mode 100644
index 0000000..213917f
--- /dev/null
+++ b/pkg/webdriver/test/webdriver_test.dart
@@ -0,0 +1,464 @@
+library webdriver_test;
+import 'package:webdriver/webdriver.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/vm_config.dart';
+
+WebDriver web_driver;
+
+/**
+ * These tests are not expected to be run as part of normal automated testing,
+ * as they are slow and they have external dependencies.
+ */
+main() {
+  useVMConfiguration();
+
+  var web_driver = new WebDriver('localhost', 4444, '/wd/hub');
+  var session = null;
+
+  var exceptionHandler = (e) {
+    if (e.error is TestFailure) {
+      currentTestCase.fail(e.error.message, e.stackTrace.toString());
+    } else {
+      currentTestCase.error("Unexpected error: ${e.error}",
+          e.stackTrace.toString());
+    }
+    if (session != null) {
+      var s = session;
+      session = null;
+      s.close();
+    }
+  };
+
+  group('Sessionless tests', () {
+    test('Get status', () {
+      return web_driver.getStatus()
+          .then((status) {
+            expect(status['sessionId'], isNull);
+          })
+          .catchError(exceptionHandler);
+    });
+  });
+
+  group('Basic session tests', () {
+    test('Create session/get capabilities', () {
+      return web_driver.newSession('chrome')
+          .then((_session) {
+            expect(_session, isNotNull);
+            session = _session;
+            return session.getCapabilities();
+          })
+          .then((capabilities) {
+            expect(capabilities, isNotNull);
+            expect(capabilities['browserName'], equals('chrome'));
+            return session.close();
+          })
+          .then((_) {
+            session = null;
+          })
+          .catchError(exceptionHandler);
+    });
+
+    test('Create and get multiple sessions', () {
+      var session2 = null;
+      return web_driver.newSession('chrome')
+          .then((_session) {
+            session = _session;
+            return web_driver.newSession('chrome');
+          })
+          .then((_session) {
+            session2 = _session;
+            return web_driver.getSessions();
+          })
+          .then((sessions) {
+            expect(sessions.length, greaterThanOrEqualTo(2));
+            return session2.close();
+          })
+          .then((_) {
+            return session.close();
+          })
+          .then((_) {
+            session = null;
+          })
+          .catchError(exceptionHandler);
+    });
+
+    test('Set/get url', () {
+      return web_driver.newSession('chrome')
+          .then((_session) {
+            session = _session;
+            return session.setUrl('http://translate.google.com');
+          })
+          .then((_) {
+            return session.getUrl();
+          })
+          .then((u) {
+            expect(u, equals('http://translate.google.com/'));
+            return session.close();
+          })
+          .then((_) {
+            session = null;
+          })
+          .catchError(exceptionHandler);
+    });
+
+    test('Navigation', () {
+      return web_driver.newSession('chrome')
+          .then((_session) {
+            session = _session;
+            return session.setUrl('http://translate.google.com');
+          })
+          .then((_) {
+            return session.setUrl('http://www.google.com');
+          })
+          .then((_) {
+            return session.navigateBack();
+          })
+          .then((_) {
+            return session.getUrl();
+          })
+          .then((u) {
+            expect(u, equals('http://translate.google.com/'));
+            return session.navigateForward();
+          })
+          .then((_) {
+            return session.getUrl();
+          })
+          .then((url) {
+            expect(url, equals('http://www.google.com/'));
+            return session.close();
+          })
+          .then((_) {
+            session = null;
+          })
+          .catchError(exceptionHandler);
+    });
+
+    test('Take a Screen shot', () {
+      return web_driver.newSession('chrome')
+          .then((_session) {
+            session = _session;
+            return session.setUrl('http://translate.google.com');
+          })
+          .then((_) {
+            return session.getScreenshot();
+          })
+          .then((image) {
+            expect(image.length, greaterThan(10000));
+            return session.close();
+          })
+          .then((_) {
+            session = null;
+          })
+          .catchError(exceptionHandler);
+    });
+  });
+
+  group('Window tests', () {
+    test('Window position and size', () {
+      // We don't validate the results. Setting size and position is flaky.
+      // I tried with the Selenium python client code and found it had the
+      // same issue, so this is not a bug in the Dart code.
+      var window;
+      return web_driver.newSession('chrome')
+          .then((_session) {
+            session = _session;
+            return session.getWindow();
+          })
+          .then((_window) {
+            window = _window;
+            return window.setSize(220, 400);
+          })
+          .then((_) {
+            return window.getSize();
+          })
+          .then((ws) {
+            return window.setPosition(100, 80);
+          })
+          .then((_) {
+            return window.getPosition();
+          })
+          .then((wp) {
+            return session.close();
+          })
+          .then((_) {
+            session = null;
+          })
+          .catchError(exceptionHandler);
+    });
+  });
+
+  group('Cookie tests', () {
+    test('Create/query/delete', () {
+      var window;
+      var numcookies;
+      return web_driver.newSession('chrome')
+          .then((_session) {
+            session = _session;
+            // Must go to a web page first to set a cookie.
+            return session.setUrl('http://translate.google.com');
+          })
+          .then((_) {
+            return session.getCookies();
+          })
+          .then((cookies) {
+            numcookies = cookies.length;
+            return session.setCookie({ 'name': 'foo', 'value': 'bar'});
+          })
+          .then((_) {
+            return session.getCookies();
+          })
+          .then((cookies) {
+            expect(cookies.length, equals(numcookies + 1));
+            expect(cookies, someElement(allOf(
+                containsPair('name', 'foo'),
+                containsPair('value', 'bar'))));
+            return session.deleteCookie('foo');
+          })
+          .then((_) {
+            return session.getCookies();
+          })
+          .then((cookies) {
+            expect(cookies.length, numcookies);
+            expect(cookies, everyElement(isNot(containsPair('name', 'foo'))));
+            return session.deleteCookie('foo');
+          })
+          .then((_) {
+            return session.getCookies();
+          })
+          .then((cookies) {
+            expect(cookies.length, numcookies);
+            return session.close();
+          })
+          .then((_) {
+            session = null;
+          })
+          .catchError(exceptionHandler);
+    });
+  });
+
+  group('Storage tests', () {
+    test('Local Storage Create/query/delete', () {
+      var window;
+      var numkeys;
+      return web_driver.newSession('firefox', { 'webStorageEnabled': true })
+          .then((_session) {
+            session = _session;
+            return session.getCapabilities();
+          })
+          .then((capabilities) {
+            expect(capabilities, isNotNull);
+            expect(capabilities['webStorageEnabled'], isTrue);
+            // Must go to a web page first.
+            return session.setUrl('http://translate.google.com');
+          })
+          .then((_) {
+            return session.getLocalStorageKeys();
+          })
+          .then((keys) {
+            numkeys = keys.length;
+            return session.setLocalStorageItem('foo', 'bar');
+          })
+          .then((_) {
+            return session.getLocalStorageKeys();
+          })
+          .then((keys) {
+            expect(keys.length, equals(numkeys + 1));
+            expect(keys, someElement(equals('foo')));
+            return session.getLocalStorageCount();
+          })
+          .then((count) {
+            expect(count, equals(numkeys + 1));
+            return session.getLocalStorageValue('foo');
+          })
+          .then((value) {
+            expect(value, equals('bar'));
+            return session.setLocalStorageItem('bar', 'foo');
+          })
+          .then((_) {
+            return session.getLocalStorageKeys();
+          })
+          .then((keys) {
+            expect(keys.length, equals(numkeys + 2));
+            expect(keys, someElement(equals('bar')));
+            expect(keys, someElement(equals('foo')));
+            return session.deleteLocalStorageValue('foo');
+          })
+          .then((_) {
+            return session.getLocalStorageKeys();
+          })
+          .then((keys) {
+            expect(keys.length, equals(numkeys + 1));
+            expect(keys, everyElement(isNot(equals('foo'))));
+            return session.setLocalStorageItem('foo', 'bar');
+          })
+          .then((_) {
+            return session.clearLocalStorage();
+          })
+          .then((_) {
+            return session.getLocalStorageKeys();
+          })
+          .then((keys) {
+            expect(keys.length, isZero);
+            return session.close();
+          })
+          .then((_) {
+            session = null;
+          })
+          .catchError(exceptionHandler);
+    });
+
+    test('Session Storage Create/query/delete', () {
+      var window;
+      var numkeys;
+      return web_driver.newSession('chrome', { 'webStorageEnabled': true })
+          .then((_session) {
+            session = _session;
+            // Must go to a web page first.
+            return session.setUrl('http://translate.google.com');
+          })
+          .then((_) {
+            return session.getSessionStorageKeys();
+          })
+          .then((keys) {
+            numkeys = keys.length;
+            return session.setSessionStorageItem('foo', 'bar');
+          })
+          .then((_) {
+            return session.getSessionStorageKeys();
+          })
+          .then((keys) {
+            expect(keys.length, equals(numkeys + 1));
+            expect(keys, someElement(equals('foo')));
+            return session.getSessionStorageCount();
+          })
+          .then((count) {
+            expect(count, equals(numkeys + 1));
+            return session.getSessionStorageValue('foo');
+          })
+          .then((value) {
+            expect(value, equals('bar'));
+            return session.deleteSessionStorageValue('foo');
+          })
+          .then((_) {
+            return session.getSessionStorageKeys();
+          })
+          .then((keys) {
+            expect(keys.length, equals(numkeys));
+            expect(keys, everyElement(isNot(equals('foo'))));
+            return session.setSessionStorageItem('foo', 'bar');
+          })
+          .then((_) {
+            return session.clearSessionStorage();
+          })
+          .then((_) {
+            return session.getSessionStorageKeys();
+          })
+          .then((keys) {
+            expect(keys.length, isZero);
+            return session.close();
+          })
+          .then((_) {
+            session = null;
+          })
+          .catchError(exceptionHandler);
+        });
+
+  });
+
+  group('Script tests', () {
+    // This test is just timing out eventually with a 500 response.
+
+    test('Sync script', () {
+      return web_driver.newSession('chrome')
+          .then((_session) {
+            session = _session;
+            return session.setUrl('http://translate.google.com');
+          })
+          .then((_) {
+            return session.execute('return arguments[0] * arguments[1];',
+                [2, 3]);
+          })
+          .then((value) {
+            expect(value, equals(6));
+            return session.close();
+          })
+          .then((_) {
+            session = null;
+          })
+          .catchError(exceptionHandler);
+    });
+  });
+
+  group('Element tests', () {
+    test('Elements', () {
+      var w;
+      return web_driver.newSession('chrome')
+          .then((_session) {
+            session = _session;
+            return session.setUrl('http://duckduckgo.com');
+          })
+          .then((_) {
+            return session.findElement('id', 'search_form_input_homepage');
+          })
+          .then((_w) {
+            w = _w['ELEMENT'];
+            return session.sendKeyStrokesToElement(w,
+                [ 'g', 'o', 'o', 'g', 'l', 'e' ]);
+          })
+          .then((_) {
+            return session.submit(w);
+          })
+          .then((_) {
+            return session.findElements('class name',
+                'links_zero_click_disambig');
+          })
+          .then((divs) {
+            expect(divs.length, greaterThan(0));
+            return session.close();
+          })
+          .then((_) {
+            session = null;
+          })
+          .catchError(exceptionHandler);
+    });
+  });
+
+  group('Log tests', () {
+    // Currently, getLogTypes returns a 404, and attempts to get the
+    // logs either return 500 with 'Unknown log type' or 500 with
+    // 'Unable to convert logEntries'.
+
+    test('Log retrieval', () {
+      return web_driver.newSession('firefox')
+          .then((_session) {
+            session = _session;
+            return session.getLogTypes();
+          })
+          .then((logTypes) {
+            expect(logTypes, someElement(equals('client')));
+            expect(logTypes, someElement(equals('server')));
+            return session.getLogs('driver');
+          })
+          .then((logs) {
+            expect(logs.length, greaterThan(0));
+            return session.close();
+          })
+          .then((_) {
+            session = null;
+          })
+          .catchError(exceptionHandler);
+        });
+  });
+
+  group('Cleanup', () {
+    test('Cleanup', () {
+      web_driver = null;
+      if (session != null) {
+        var s = session;
+        session = null;
+        s.close();
+      }
+    });
+  });
+}
+
diff --git a/pkg/webdriver/test/webdrivertest.dart b/pkg/webdriver/test/webdrivertest.dart
deleted file mode 100644
index 8d9c0ac..0000000
--- a/pkg/webdriver/test/webdrivertest.dart
+++ /dev/null
@@ -1,421 +0,0 @@
-library webdriver_test;
-import 'package:webdriver/webdriver.dart';
-import 'package:unittest/unittest.dart';
-
-WebDriver web_driver;
-
-/**
- * These tests are not expected to be run as part of normal automated testing,
- * as they are slow, many of them do not yet work due to WebDriver limitations,
- * and they have external dependencies. Nontheless it is useful to keep them
- * here for manual testing.
- */
-main() {
-  var web_driver = new WebDriver('localhost', 4444, '/wd/hub');
-  var session = null;
-  var completionCallback;
-
-  var exceptionHandler = (e) {
-    print('Handled: ${e.toString()}');
-    if (session != null) {
-      session.close().then((_){
-        session = null;
-        config.handleExternalError(e, 'Unexpected failure');
-      });
-    }
-    return true;
-  };
-
-  group('Sessionless tests', () {
-    setUp(() {
-      completionCallback = expectAsync0((){
-      });
-    });
-
-    test('Get status', () {
-      Future f = web_driver.getStatus();
-      f.handleException(exceptionHandler);
-      f.then((status) {
-        expect(status['sessionId'], isNull);
-        completionCallback();
-      });
-    });
-  });
-
-  group('Basic session tests', () {
-    setUp(() {
-      completionCallback = expectAsync0((){
-      });
-    });
-
-    test('Create session/get capabilities', () {
-      Future f = web_driver.newSession('chrome');
-      f.handleException(exceptionHandler);
-      f.chain((_session) {
-        session = _session;
-        return session.getCapabilities();
-      }).chain((capabilities) {
-        expect(capabilities['browserName'], equals('chrome'));
-        return session.close();
-      }).then((_) {
-        session = null;
-        completionCallback();
-      });
-    });
-
-    test('Create and get multiple sessions', () {
-      Future f = web_driver.newSession('chrome');
-      var session2 = null;
-      f.handleException(exceptionHandler);
-      f.chain((_session) {
-        session = _session;
-        return web_driver.newSession('firefox');
-      }).chain((_session) {
-        session2 = _session;
-        return web_driver.getSessions();
-      }).chain((sessions) {
-        expect(sessions.length, greaterThanOrEqualTo(2));
-        return session2.close();
-      }).chain((_) {
-        return session.close();
-      }).then((_) {
-        session = null;
-        completionCallback();
-      });
-    });
-
-    test('Set/get url', () {
-      Future f = web_driver.newSession('chrome');
-      f.handleException(exceptionHandler);
-      f.chain((_session) {
-        session = _session;
-        return session.setUrl('http://translate.google.com');
-      }).chain((_) {
-        return session.getUrl();
-      }).chain((u) {
-        expect(u, equals('http://translate.google.com/'));
-        return session.close();
-      }).then((_) {
-        session = null;
-        completionCallback();
-      });
-    });
-
-    test('Navigation', () {
-      Future f = web_driver.newSession('chrome');
-      f.handleException(exceptionHandler);
-      f.chain((_session) {
-        session = _session;
-        return session.setUrl('http://translate.google.com');
-      }).chain((_) {
-        return session.setUrl('http://www.google.com');
-      }).chain((_) {
-        return session.navigateBack();
-      }).chain((_) {
-        return session.getUrl();
-      }).chain((u) {
-        expect(u, equals('http://translate.google.com/'));
-        return session.navigateForward();
-      }).chain((_) {
-        return session.getUrl();
-      }).chain((url) {
-        expect(url, equals('http://www.google.com/'));
-        return session.close();
-      }).then((_) {
-        session = null;
-        completionCallback();
-      });
-    });
-
-    test('Take a Screen shot', () {
-      Future f = web_driver.newSession('chrome');
-      f.handleException(exceptionHandler);
-      f.chain((_session) {
-        session = _session;
-        return session.setUrl('http://translate.google.com');
-      }).chain((_) {
-        return session.getScreenshot();
-      }).chain((image) {
-        expect(image.length, greaterThan(10000));
-        return session.close();
-      }).then((_) {
-        session = null;
-        completionCallback();
-      });
-    });
-  });
-
-  group('Window tests', () {
-    setUp(() {
-      completionCallback = expectAsync0((){
-      });
-    });
-
-    test('Window position and size', () {
-      var window;
-      Future f = web_driver.newSession('chrome');
-      f.handleException(exceptionHandler);
-      f.chain((_session) {
-        session = _session;
-        return session.getWindow();
-      }).chain((_window) {
-        window = _window;
-        return window.setSize(200, 100);
-      }).chain((_) {
-        return window.getSize();
-      }).chain((ws) {
-        expect(ws['width'], equals(200));
-        expect(ws['height'], equals(100));
-        return window.setPosition(100, 80);
-      }).chain((_) {
-        return window.getPosition();
-      }).chain((wp) {
-        expect(wp['x'], equals(100));
-        expect(wp['y'], equals(80));
-        return session.close();
-      }).then((_) {
-        session = null;
-        completionCallback();
-      });
-    });
-  });
-
-  group('Cookie tests', () {
-    setUp(() {
-      completionCallback = expectAsync0((){
-      });
-    });
-
-    test('Create/query/delete', () {
-      var window;
-      var numcookies;
-      Future f = web_driver.newSession('chrome');
-      f.handleException(exceptionHandler);
-      f.chain((_session) {
-        session = _session;
-        // Must go to a web page first to set a cookie.
-        return session.setUrl('http://translate.google.com');
-      }).chain((_) {
-        return session.getCookies();
-      }).chain((cookies) {
-        numcookies = cookies.length;
-        return session.setCookie({ 'name': 'foo', 'value': 'bar'});
-      }).chain((_) {
-        return session.getCookies();
-      }).chain((cookies) {
-        expect(cookies.length, equals(numcookies + 1));
-        expect(cookies, someElement(allOf(
-            containsPair('name', 'foo'),
-            containsPair('value', 'bar'))));
-        return session.deleteCookie('foo');
-      }).chain((_) {
-        return session.getCookies();
-      }).chain((cookies) {
-        expect(cookies.length, numcookies);
-        expect(cookies, everyElement(isNot(containsPair('name', 'foo'))));
-        return session.deleteCookie('foo');
-      }).chain((_) {
-        return session.getCookies();
-      }).chain((cookies) {
-        expect(cookies.length, numcookies);
-        return session.close();
-      }).then((_) {
-        session = null;
-        completionCallback();
-      });
-    });
-  });
-
-  group('Storage tests', () {
-    setUp(() {
-      completionCallback = expectAsync0((){
-      });
-    });
-
-    // Storage tests are return 500 errors. This seems to be a bug in
-    // the remote driver.
-
-    test('Local Storage Create/query/delete', () {
-      var window;
-      var numkeys;
-      Future f = web_driver.newSession('htmlunit', { 'webStorageEnabled': true });
-      f.handleException(exceptionHandler);
-      f.chain((_session) {
-        session = _session;
-        // Must go to a web page first.
-        return session.setUrl('http://translate.google.com');
-      }).chain((_) {
-        return session.getLocalStorageKeys();
-      }).chain((keys) {
-        print(keys);
-        numkeys = keys.length;
-        return session.setLocalStorageItem('foo', 'bar');
-      }).chain((_) {
-        return session.getLocalStorageKeys();
-      }).chain((keys) {
-        expect(keys.length, equals(numkeys + 1));
-        expect(keys, someElement(equals('foo')));
-        return session.getLocalStorageCount();
-      }).chain((count) {
-        expect(count, equals(numkeys + 1));
-        return session.getLocalStorageValue('foo');
-      }).chain((value) {
-        expect(value, equals('bar'));
-        return session.deleteLocalStorageValue('foo');
-      }).chain((_) {
-        return session.getLocalStorageKeys();
-      }).chain((keys) {
-        expect(keys.length, equals(numkeys));
-        expect(keys, everyElement(isNot(equals('foo'))));
-        return session.setLocalStorageItem('foo', 'bar');
-      }).chain((_) {
-        return session.clearLocalStorage();
-      }).chain((_) {
-        return session.getLocalStorageKeys();
-      }).chain((keys) {
-        expect(keys.length, isZero);
-        return session.close();
-      }).then((_) {
-        session = null;
-        completionCallback();
-      });
-    });
-
-    test('Session Storage Create/query/delete', () {
-      var window;
-      var numkeys;
-      Future f = web_driver.newSession('chrome', { 'webStorageEnabled': true });
-      f.handleException(exceptionHandler);
-      f.chain((_session) {
-        session = _session;
-        // Must go to a web page first.
-        return session.setUrl('http://translate.google.com');
-      }).chain((_) {
-        return session.getSessionStorageKeys();
-      }).chain((keys) {
-        print(keys);
-        numkeys = keys.length;
-        return session.setSessionStorageItem('foo', 'bar');
-      }).chain((_) {
-        return session.getSessionStorageKeys();
-      }).chain((keys) {
-        expect(keys.length, equals(numkeys + 1));
-        expect(keys, someElement(equals('foo')));
-        return session.getSessionStorageCount();
-      }).chain((count) {
-        expect(count, equals(numkeys + 1));
-        return session.getSessionStorageValue('foo');
-      }).chain((value) {
-        expect(value, equals('bar'));
-        return session.deleteSessionStorageValue('foo');
-      }).chain((_) {
-        return session.getSessionStorageKeys();
-      }).chain((keys) {
-        expect(keys.length, equals(numkeys));
-        expect(keys, everyElement(isNot(equals('foo'))));
-        return session.setSessionStorageItem('foo', 'bar');
-      }).chain((_) {
-        return session.clearSessionStorage();
-      }).chain((_) {
-        return session.getSessionStorageKeys();
-      }).chain((keys) {
-        expect(keys.length, isZero);
-        return session.close();
-      }).then((_) {
-        session = null;
-        completionCallback();
-      });
-    });
-
-  });
-
-  group('Script tests', () {
-    setUp(() {
-      completionCallback = expectAsync0((){
-      });
-    });
-
-    // This test is just timing out eventually with a 500 response.
-
-    test('Sync script', () {
-      Future f = web_driver.newSession('chrome');
-      f.handleException(exceptionHandler);
-      f.chain((_session) {
-        session = _session;
-        return session.setUrl('http://translate.google.com');
-      }).chain((_) {
-        return session.execute('function(x, y) { return x * y; }', [2, 3]);
-      }).chain((value) {
-        expect(value, equals(6));
-        return session.close();
-      }).then((_) {
-        session = null;
-        completionCallback();
-      });
-    });
-  });
-
-  group('Element tests', () {
-    setUp(() {
-      completionCallback = expectAsync0((){
-      });
-    });
-
-    test('Elements', () {
-      var w;
-      Future f = web_driver.newSession('chrome');
-      f.handleException(exceptionHandler);
-      f.chain((_session) {
-        session = _session;
-        return session.setUrl('http://duckduckgo.com');
-      }).chain((_) {
-        return session.findElement('id', 'search_form_input_homepage');
-      }).chain((_w) {
-        print(_w);
-        w = _w['ELEMENT'];
-        return session.sendKeyStrokesToElement(w,
-            [ 'g', 'o', 'o', 'g', 'l', 'e' ]);
-      }).chain((_) {
-        return session.submit(w);
-      }).chain((_) {
-        return session.findElements('class name', 'links_zero_click_disambig');
-      }).chain((divs) {
-        expect(divs.length, greaterThan(0));
-        return session.close();
-      }).then((_) {
-        session = null;
-        completionCallback();
-      });
-    });
-  });
-
-  group('Log tests', () {
-    setUp(() {
-      completionCallback = expectAsync0((){
-      });
-    });
-
-    // Currently, getLogTypes returns a 404, and attempts to get the
-    // logs either return 500 with 'Unknown log type' or 500 with
-    // 'Unable to convert logEntries'.
-
-    test('Log retrieval', () {
-      Future f = web_driver.newSession('chrome');
-      f.handleException(exceptionHandler);
-      f.chain((_session) {
-        session = _session;
-          return session.getLogTypes();
-      }).chain((logTypes) {
-        //print(logTypes);
-        return session.getLogs('driver');
-      }).chain((logs) {
-        //print(logs);
-        return session.close();
-      }).then((_) {
-        session = null;
-        completionCallback();
-      });
-    });
-  });
-}
-
diff --git a/pkg/yaml/lib/composer.dart b/pkg/yaml/lib/composer.dart
index e22159f..90ed330 100644
--- a/pkg/yaml/lib/composer.dart
+++ b/pkg/yaml/lib/composer.dart
@@ -98,13 +98,13 @@
 
   /// Parses a null scalar.
   _ScalarNode parseNull(String content) {
-    if (!new RegExp("^(null|Null|NULL|~|)\$").hasMatch(content)) return null;
+    if (!new RegExp(r"^(null|Null|NULL|~|)$").hasMatch(content)) return null;
     return new _ScalarNode(_Tag.yaml("null"), value: null);
   }
 
   /// Parses a boolean scalar.
   _ScalarNode parseBool(String content) {
-    var match = new RegExp("^(?:(true|True|TRUE)|(false|False|FALSE))\$").
+    var match = new RegExp(r"^(?:(true|True|TRUE)|(false|False|FALSE))$").
       firstMatch(content);
     if (match == null) return null;
     return new _ScalarNode(_Tag.yaml("bool"), value: match.group(1) != null);
@@ -112,19 +112,19 @@
 
   /// Parses an integer scalar.
   _ScalarNode parseInt(String content) {
-    var match = new RegExp("^[-+]?[0-9]+\$").firstMatch(content);
+    var match = new RegExp(r"^[-+]?[0-9]+$").firstMatch(content);
     if (match != null) {
       return new _ScalarNode(_Tag.yaml("int"),
           value: int.parse(match.group(0)));
     }
 
-    match = new RegExp("^0o([0-7]+)\$").firstMatch(content);
+    match = new RegExp(r"^0o([0-7]+)$").firstMatch(content);
     if (match != null) {
       int n = int.parse(match.group(1), radix: 8);
       return new _ScalarNode(_Tag.yaml("int"), value: n);
     }
 
-    match = new RegExp("^0x[0-9a-fA-F]+\$").firstMatch(content);
+    match = new RegExp(r"^0x[0-9a-fA-F]+$").firstMatch(content);
     if (match != null) {
       return new _ScalarNode(_Tag.yaml("int"),
           value: int.parse(match.group(0)));
@@ -136,7 +136,7 @@
   /// Parses a floating-point scalar.
   _ScalarNode parseFloat(String content) {
     var match = new RegExp(
-        "^[-+]?(\.[0-9]+|[0-9]+(\.[0-9]*)?)([eE][-+]?[0-9]+)?\$").
+        r"^[-+]?(\.[0-9]+|[0-9]+(\.[0-9]*)?)([eE][-+]?[0-9]+)?$").
       firstMatch(content);
     if (match != null) {
       // YAML allows floats of the form "0.", but Dart does not. Fix up those
@@ -146,13 +146,13 @@
           value: double.parse(matchStr));
     }
 
-    match = new RegExp("^([+-]?)\.(inf|Inf|INF)\$").firstMatch(content);
+    match = new RegExp(r"^([+-]?)\.(inf|Inf|INF)$").firstMatch(content);
     if (match != null) {
       var value = match.group(1) == "-" ? -double.INFINITY : double.INFINITY;
       return new _ScalarNode(_Tag.yaml("float"), value: value);
     }
 
-    match = new RegExp("^\.(nan|NaN|NAN)\$").firstMatch(content);
+    match = new RegExp(r"^\.(nan|NaN|NAN)$").firstMatch(content);
     if (match != null) {
       return new _ScalarNode(_Tag.yaml("float"), value: double.NAN);
     }
diff --git a/pkg/yaml/lib/parser.dart b/pkg/yaml/lib/parser.dart
index 386bb59..c84f374 100644
--- a/pkg/yaml/lib/parser.dart
+++ b/pkg/yaml/lib/parser.dart
@@ -347,13 +347,13 @@
     capturingAs = false;
     if (!truth(res)) return res;
 
-    capturedString.add(transformation(s.substring(captureStart, pos)));
+    capturedString.write(transformation(s.substring(captureStart, pos)));
     captureStart = pos;
     return res;
   }
 
   void flushCapture() {
-    capturedString.add(s.substring(captureStart, pos));
+    capturedString.write(s.substring(captureStart, pos));
     captureStart = pos;
   }
 
diff --git a/runtime/bin/bin.gypi b/runtime/bin/bin.gypi
index 8f41e50..2e360e0 100644
--- a/runtime/bin/bin.gypi
+++ b/runtime/bin/bin.gypi
@@ -11,6 +11,7 @@
     'snapshot_in_cc_file': 'snapshot_in.cc',
     'snapshot_bin_file': '<(SHARED_INTERMEDIATE_DIR)/snapshot_gen.bin',
     'snapshot_cc_file': '<(SHARED_INTERMEDIATE_DIR)/snapshot_gen.cc',
+    'resources_cc_file': '<(SHARED_INTERMEDIATE_DIR)/resources_gen.cc',
   },
   'targets': [
     {
@@ -330,6 +331,33 @@
       ]
     },
     {
+      'target_name': 'generate_resources_cc_file',
+      'type': 'none',
+      'includes': [
+        'vmstats_sources.gypi',
+      ],
+      'actions': [
+        {
+          'action_name': 'generate_resources_cc',
+          'inputs': [
+            '../tools/create_resources.py',
+            '<@(_sources)',
+          ],
+          'outputs': [
+            '<(resources_cc_file)',
+          ],
+          'action': [
+            'python',
+            'tools/create_resources.py',
+            '--output', '<(resources_cc_file)',
+            '--root_prefix', 'bin/vmstats/',
+            '<@(_sources)',
+          ],
+          'message': 'Generating ''<(resources_cc_file)'' file.'
+        },
+      ]
+    },
+    {
       # dart binary with a snapshot of corelibs built in.
       'target_name': 'dart',
       'type': 'executable',
@@ -338,6 +366,7 @@
         'libdart_builtin',
         'libdart_io',
         'generate_snapshot_file',
+        'generate_resources_cc_file',
       ],
       'include_dirs': [
         '..',
@@ -345,10 +374,12 @@
       'sources': [
         'main.cc',
         'builtin_nolib.cc',
+        'resources.h',
         'vmstats.h',
         'vmstats_impl.cc',
         'vmstats_impl.h',
         '<(snapshot_cc_file)',
+        '<(resources_cc_file)',
       ],
       'conditions': [
         ['OS=="win"', {
@@ -380,6 +411,7 @@
         'libdart_withcore',
         'libdart_builtin',
         'libdart_io',
+        'generate_resources_cc_file',
       ],
       'include_dirs': [
         '..',
@@ -387,6 +419,7 @@
       'sources': [
         'main.cc',
         'builtin.cc',
+        'resources.h',
         'vmstats.h',
         'vmstats_impl.cc',
         'vmstats_impl.h',
@@ -394,6 +427,7 @@
         '<(builtin_cc_file)',
         '<(io_cc_file)',
         '<(io_patch_cc_file)',
+        '<(resources_cc_file)',
         'snapshot_empty.cc',
       ],
       'conditions': [
diff --git a/runtime/bin/builtin_natives.cc b/runtime/bin/builtin_natives.cc
index 75b4edf..0dbc958 100644
--- a/runtime/bin/builtin_natives.cc
+++ b/runtime/bin/builtin_natives.cc
@@ -41,11 +41,13 @@
   V(File_LastModified, 1)                                                      \
   V(File_Flush, 1)                                                             \
   V(File_Create, 1)                                                            \
+  V(File_CreateLink, 2)                                                        \
   V(File_Delete, 1)                                                            \
   V(File_Directory, 1)                                                         \
   V(File_FullPath, 1)                                                          \
   V(File_OpenStdio, 1)                                                         \
   V(File_GetStdioHandleType, 1)                                                \
+  V(File_GetType, 2)                                                           \
   V(File_NewServicePort, 0)                                                    \
   V(Logger_PrintString, 1)
 
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index a780780..9d2ac70 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -530,6 +530,11 @@
 }
 
 
+Dart_Handle DartUtils::NewInternalError(const char* message) {
+  return NewDartExceptionWithMessage(kCoreLibURL, "InternalError", message);
+}
+
+
 void DartUtils::SetOriginalWorkingDirectory() {
   original_working_directory = Directory::Current();
 }
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index 7f539de..35b7866 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -139,6 +139,9 @@
                                   strlen(str));
   }
 
+  // Create a new Dart InternalError object with the provided message.
+  static Dart_Handle NewInternalError(const char* message);
+
   static void SetOriginalWorkingDirectory();
 
   static const char* MapLibraryUrl(CommandLineOptions* url_mapping,
diff --git a/runtime/bin/eventhandler.h b/runtime/bin/eventhandler.h
index 530cc8f..c487c52 100644
--- a/runtime/bin/eventhandler.h
+++ b/runtime/bin/eventhandler.h
@@ -50,7 +50,7 @@
 
   static EventHandler* Start() {
     EventHandler* handler = new EventHandler();
-    handler->delegate_.Start();
+    handler->delegate_.Start(handler);
     IsolateData* isolate_data =
         reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData());
     isolate_data->event_handler = handler;
@@ -58,6 +58,7 @@
   }
 
  private:
+  friend class EventHandlerImplementation;
   EventHandlerImplementation delegate_;
 };
 
diff --git a/runtime/bin/eventhandler_linux.cc b/runtime/bin/eventhandler_linux.cc
index ce99057..8cda7927 100644
--- a/runtime/bin/eventhandler_linux.cc
+++ b/runtime/bin/eventhandler_linux.cc
@@ -84,7 +84,14 @@
       sd->set_tracked_by_epoll(true);
     }
     if (status == -1) {
-      FATAL1("Failed updating epoll instance: %s", strerror(errno));
+      // Epoll does not accept the file descriptor. It could be due to
+      // already closed file descriptor, or unuspported devices, such
+      // as /dev/null. In such case, mark the file descriptor as closed,
+      // so dart will handle it accordingly.
+      sd->set_tracked_by_epoll(false);
+      sd->ShutdownRead();
+      sd->ShutdownWrite();
+      DartUtils::PostInt32(sd->port(), 1 << kCloseEvent);
     }
   }
 }
@@ -126,6 +133,7 @@
 
 
 EventHandlerImplementation::~EventHandlerImplementation() {
+  TEMP_FAILURE_RETRY(close(epoll_fd_));
   TEMP_FAILURE_RETRY(close(interrupt_fds_[0]));
   TEMP_FAILURE_RETRY(close(interrupt_fds_[1]));
 }
@@ -368,12 +376,12 @@
 void EventHandlerImplementation::Poll(uword args) {
   static const intptr_t kMaxEvents = 16;
   struct epoll_event events[kMaxEvents];
-  EventHandlerImplementation* handler =
-      reinterpret_cast<EventHandlerImplementation*>(args);
-  ASSERT(handler != NULL);
-  while (!handler->shutdown_) {
-    intptr_t millis = handler->GetTimeout();
-    intptr_t result = TEMP_FAILURE_RETRY(epoll_wait(handler->epoll_fd_,
+  EventHandler* handler = reinterpret_cast<EventHandler*>(args);
+  EventHandlerImplementation* handler_impl = &handler->delegate_;
+  ASSERT(handler_impl != NULL);
+  while (!handler_impl->shutdown_) {
+    intptr_t millis = handler_impl->GetTimeout();
+    intptr_t result = TEMP_FAILURE_RETRY(epoll_wait(handler_impl->epoll_fd_,
                                                     events,
                                                     kMaxEvents,
                                                     millis));
@@ -383,16 +391,17 @@
         perror("Poll failed");
       }
     } else {
-      handler->HandleTimeout();
-      handler->HandleEvents(events, result);
+      handler_impl->HandleTimeout();
+      handler_impl->HandleEvents(events, result);
     }
   }
+  delete handler;
 }
 
 
-void EventHandlerImplementation::Start() {
+void EventHandlerImplementation::Start(EventHandler* handler) {
   int result = dart::Thread::Start(&EventHandlerImplementation::Poll,
-                                   reinterpret_cast<uword>(this));
+                                   reinterpret_cast<uword>(handler));
   if (result != 0) {
     FATAL1("Failed to start event handler thread %d", result);
   }
diff --git a/runtime/bin/eventhandler_linux.h b/runtime/bin/eventhandler_linux.h
index ebdcf7b..e44e283 100644
--- a/runtime/bin/eventhandler_linux.h
+++ b/runtime/bin/eventhandler_linux.h
@@ -93,7 +93,7 @@
   // descriptor. Creates a new one if one is not found.
   SocketData* GetSocketData(intptr_t fd);
   void SendData(intptr_t id, Dart_Port dart_port, int64_t data);
-  void Start();
+  void Start(EventHandler* handler);
   void Shutdown();
 
  private:
diff --git a/runtime/bin/eventhandler_macos.cc b/runtime/bin/eventhandler_macos.cc
index fbced64..5972cfb 100644
--- a/runtime/bin/eventhandler_macos.cc
+++ b/runtime/bin/eventhandler_macos.cc
@@ -102,7 +102,15 @@
     int status =
       TEMP_FAILURE_RETRY(kevent(kqueue_fd_, events, changes, NULL, 0, NULL));
     if (status == -1) {
-      FATAL1("Failed updating kqueue: %s\n", strerror(errno));
+      // kQueue does not accept the file descriptor. It could be due to
+      // already closed file descriptor, or unuspported devices, such
+      // as /dev/null. In such case, mark the file descriptor as closed,
+      // so dart will handle it accordingly.
+      sd->set_write_tracked_by_kqueue(false);
+      sd->set_read_tracked_by_kqueue(false);
+      sd->ShutdownRead();
+      sd->ShutdownWrite();
+      DartUtils::PostInt32(sd->port(), 1 << kCloseEvent);
     }
   }
 }
@@ -138,6 +146,7 @@
 
 
 EventHandlerImplementation::~EventHandlerImplementation() {
+  VOID_TEMP_FAILURE_RETRY(close(kqueue_fd_));
   VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0]));
   VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1]));
 }
@@ -362,11 +371,11 @@
 void EventHandlerImplementation::EventHandlerEntry(uword args) {
   static const intptr_t kMaxEvents = 16;
   struct kevent events[kMaxEvents];
-  EventHandlerImplementation* handler =
-      reinterpret_cast<EventHandlerImplementation*>(args);
-  ASSERT(handler != NULL);
-  while (!handler->shutdown_) {
-    intptr_t millis = handler->GetTimeout();
+  EventHandler* handler = reinterpret_cast<EventHandler*>(args);
+  EventHandlerImplementation* handler_impl = &handler->delegate_;
+  ASSERT(handler_impl != NULL);
+  while (!handler_impl->shutdown_) {
+    intptr_t millis = handler_impl->GetTimeout();
     // NULL pointer timespec for infinite timeout.
     ASSERT(kInfinityTimeout < 0);
     struct timespec* timeout = NULL;
@@ -376,7 +385,7 @@
       ts.tv_nsec = (millis - (ts.tv_sec * 1000)) * 1000000;
       timeout = &ts;
     }
-    intptr_t result = TEMP_FAILURE_RETRY(kevent(handler->kqueue_fd_,
+    intptr_t result = TEMP_FAILURE_RETRY(kevent(handler_impl->kqueue_fd_,
                                                 NULL,
                                                 0,
                                                 events,
@@ -385,17 +394,18 @@
     if (result == -1) {
       FATAL1("kevent failed %s\n", strerror(errno));
     } else {
-      handler->HandleTimeout();
-      handler->HandleEvents(events, result);
+      handler_impl->HandleTimeout();
+      handler_impl->HandleEvents(events, result);
     }
   }
+  delete handler;
 }
 
 
-void EventHandlerImplementation::Start() {
+void EventHandlerImplementation::Start(EventHandler* handler) {
   int result =
       dart::Thread::Start(&EventHandlerImplementation::EventHandlerEntry,
-                          reinterpret_cast<uword>(this));
+                          reinterpret_cast<uword>(handler));
   if (result != 0) {
     FATAL1("Failed to start event handler thread %d", result);
   }
diff --git a/runtime/bin/eventhandler_macos.h b/runtime/bin/eventhandler_macos.h
index e113082..cbc6040 100644
--- a/runtime/bin/eventhandler_macos.h
+++ b/runtime/bin/eventhandler_macos.h
@@ -106,7 +106,7 @@
   // descriptor. Creates a new one if one is not found.
   SocketData* GetSocketData(intptr_t fd);
   void SendData(intptr_t id, Dart_Port dart_port, int64_t data);
-  void Start();
+  void Start(EventHandler* handler);
   void Shutdown();
 
  private:
diff --git a/runtime/bin/eventhandler_win.cc b/runtime/bin/eventhandler_win.cc
index a10dd04..cb193a6 100644
--- a/runtime/bin/eventhandler_win.cc
+++ b/runtime/bin/eventhandler_win.cc
@@ -889,6 +889,11 @@
 }
 
 
+EventHandlerImplementation::~EventHandlerImplementation() {
+  CloseHandle(completion_port_);
+}
+
+
 DWORD EventHandlerImplementation::GetTimeout() {
   if (timeout_ == kInfinityTimeout) {
     return kInfinityTimeout;
@@ -914,15 +919,15 @@
 
 
 void EventHandlerImplementation::EventHandlerEntry(uword args) {
-  EventHandlerImplementation* handler =
-      reinterpret_cast<EventHandlerImplementation*>(args);
-  ASSERT(handler != NULL);
-  while (!handler->shutdown_) {
+  EventHandler* handler = reinterpret_cast<EventHandler*>(args);
+  EventHandlerImplementation* handler_impl = &handler->delegate_;
+  ASSERT(handler_impl != NULL);
+  while (!handler_impl->shutdown_) {
     DWORD bytes;
     ULONG_PTR key;
     OVERLAPPED* overlapped;
-    intptr_t millis = handler->GetTimeout();
-    BOOL ok = GetQueuedCompletionStatus(handler->completion_port(),
+    intptr_t millis = handler_impl->GetTimeout();
+    BOOL ok = GetQueuedCompletionStatus(handler_impl->completion_port(),
                                         &bytes,
                                         &key,
                                         &overlapped,
@@ -934,7 +939,7 @@
         UNREACHABLE();
       } else {
         // Timeout is signalled by false result and NULL in overlapped.
-        handler->HandleTimeout();
+        handler_impl->HandleTimeout();
       }
     } else if (!ok) {
       // Treat ERROR_CONNECTION_ABORTED as connection closed.
@@ -948,26 +953,27 @@
           last_error == ERROR_NETNAME_DELETED ||
           last_error == ERROR_BROKEN_PIPE) {
         ASSERT(bytes == 0);
-        handler->HandleIOCompletion(bytes, key, overlapped);
+        handler_impl->HandleIOCompletion(bytes, key, overlapped);
       } else {
         ASSERT(bytes == 0);
-        handler->HandleIOCompletion(-1, key, overlapped);
+        handler_impl->HandleIOCompletion(-1, key, overlapped);
       }
     } else if (key == NULL) {
       // A key of NULL signals an interrupt message.
       InterruptMessage* msg = reinterpret_cast<InterruptMessage*>(overlapped);
-      handler->HandleInterrupt(msg);
+      handler_impl->HandleInterrupt(msg);
       delete msg;
     } else {
-      handler->HandleIOCompletion(bytes, key, overlapped);
+      handler_impl->HandleIOCompletion(bytes, key, overlapped);
     }
   }
+  delete handler;
 }
 
 
-void EventHandlerImplementation::Start() {
+void EventHandlerImplementation::Start(EventHandler* handler) {
   int result = dart::Thread::Start(EventHandlerEntry,
-                                   reinterpret_cast<uword>(this));
+                                   reinterpret_cast<uword>(handler));
   if (result != 0) {
     FATAL1("Failed to start event handler thread %d", result);
   }
diff --git a/runtime/bin/eventhandler_win.h b/runtime/bin/eventhandler_win.h
index 44d710c..09044e0 100644
--- a/runtime/bin/eventhandler_win.h
+++ b/runtime/bin/eventhandler_win.h
@@ -360,10 +360,10 @@
 class EventHandlerImplementation {
  public:
   EventHandlerImplementation();
-  virtual ~EventHandlerImplementation() {}
+  virtual ~EventHandlerImplementation();
 
   void SendData(intptr_t id, Dart_Port dart_port, int64_t data);
-  void Start();
+  void Start(EventHandler* handler);
   void Shutdown();
 
   static void EventHandlerEntry(uword args);
diff --git a/runtime/bin/file.cc b/runtime/bin/file.cc
index 3a2c455..f457dd9 100644
--- a/runtime/bin/file.cc
+++ b/runtime/bin/file.cc
@@ -425,6 +425,29 @@
 }
 
 
+void FUNCTION_NAME(File_CreateLink)(Dart_NativeArguments args) {
+  Dart_EnterScope();
+  if (Dart_IsString(Dart_GetNativeArgument(args, 0)) &&
+      Dart_IsString(Dart_GetNativeArgument(args, 1))) {
+    const char* name =
+        DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
+    const char* target =
+        DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
+    if (!File::CreateLink(name, target)) {
+      Dart_Handle err = DartUtils::NewDartOSError();
+      if (Dart_IsError(err)) Dart_PropagateError(err);
+      Dart_SetReturnValue(args, err);
+    }
+  } else  {
+    OSError os_error(-1, "Invalid argument", OSError::kUnknown);
+    Dart_Handle err = DartUtils::NewDartOSError(&os_error);
+    if (Dart_IsError(err)) Dart_PropagateError(err);
+    Dart_SetReturnValue(args, err);
+  }
+  Dart_ExitScope();
+}
+
+
 void FUNCTION_NAME(File_Delete)(Dart_NativeArguments args) {
   Dart_EnterScope();
   const char* str =
@@ -497,6 +520,26 @@
 }
 
 
+void FUNCTION_NAME(File_GetType)(Dart_NativeArguments args) {
+  Dart_EnterScope();
+  if (Dart_IsString(Dart_GetNativeArgument(args, 0)) &&
+      Dart_IsBoolean(Dart_GetNativeArgument(args, 1))) {
+    const char* str =
+        DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
+    bool follow_links =
+        DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 1));
+    File::Type type = File::GetType(str, follow_links);
+    Dart_SetReturnValue(args, Dart_NewInteger(static_cast<int>(type)));
+  } else  {
+    OSError os_error(-1, "Invalid argument", OSError::kUnknown);
+    Dart_Handle err = DartUtils::NewDartOSError(&os_error);
+    if (Dart_IsError(err)) Dart_PropagateError(err);
+    Dart_SetReturnValue(args, err);
+  }
+  Dart_ExitScope();
+}
+
+
 static int64_t CObjectInt32OrInt64ToInt64(CObject* cobject) {
   ASSERT(cobject->IsInt32OrInt64());
   int64_t result;
diff --git a/runtime/bin/file.h b/runtime/bin/file.h
index 05be61c..dab7a9c 100644
--- a/runtime/bin/file.h
+++ b/runtime/bin/file.h
@@ -36,6 +36,13 @@
     kDartAppend = 2
   };
 
+  enum Type {
+    kIsFile = 0,
+    kIsDirectory = 1,
+    kIsLink = 2,
+    kDoesNotExist = 3
+  };
+
   enum StdioHandleType {
     kTerminal = 0,
     kPipe = 1,
@@ -116,6 +123,7 @@
 
   static bool Exists(const char* path);
   static bool Create(const char* path);
+  static bool CreateLink(const char* path, const char* target);
   static bool Delete(const char* path);
   static off_t LengthFromPath(const char* path);
   static time_t LastModified(const char* path);
@@ -124,6 +132,7 @@
   static char* GetContainingDirectory(char* path);
   static const char* PathSeparator();
   static const char* StringEscapedPathSeparator();
+  static Type GetType(const char* path, bool follow_links);
   static StdioHandleType GetStdioHandleType(int fd);
 
   static FileOpenMode DartModeToFileMode(DartFileOpenMode mode);
diff --git a/runtime/bin/file_android.cc b/runtime/bin/file_android.cc
index 390ef4d..bdb8ac1 100644
--- a/runtime/bin/file_android.cc
+++ b/runtime/bin/file_android.cc
@@ -159,6 +159,12 @@
 }
 
 
+bool File::CreateLink(const char* name, const char* target) {
+  int status = TEMP_FAILURE_RETRY(symlink(target, name));
+  return (status == 0);
+}
+
+
 bool File::Delete(const char* name) {
   int status = TEMP_FAILURE_RETRY(remove(name));
   if (status == -1) {
@@ -246,4 +252,20 @@
   return kOther;
 }
 
+
+File::Type File::GetType(const char* pathname, bool follow_links) {
+  struct stat entry_info;
+  int stat_success;
+  if (follow_links) {
+    stat_success = TEMP_FAILURE_RETRY(stat(pathname, &entry_info));
+  } else {
+    stat_success = TEMP_FAILURE_RETRY(lstat(pathname, &entry_info));
+  }
+  if (stat_success == -1) return File::kDoesNotExist;
+  if (S_ISDIR(entry_info.st_mode)) return File::kIsDirectory;
+  if (S_ISREG(entry_info.st_mode)) return File::kIsFile;
+  if (S_ISLNK(entry_info.st_mode)) return File::kIsLink;
+  return File::kDoesNotExist;
+}
+
 #endif  // defined(TARGET_OS_ANDROID)
diff --git a/runtime/bin/file_linux.cc b/runtime/bin/file_linux.cc
index 459a692..abbe9cc 100644
--- a/runtime/bin/file_linux.cc
+++ b/runtime/bin/file_linux.cc
@@ -107,7 +107,8 @@
   // Report errors for non-regular files.
   struct stat st;
   if (TEMP_FAILURE_RETRY(stat(name, &st)) == 0) {
-    if (!S_ISREG(st.st_mode)) {
+    // Only accept regular files and character devices.
+    if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode)) {
       errno = (S_ISDIR(st.st_mode)) ? EISDIR : ENOENT;
       return NULL;
     }
@@ -159,6 +160,12 @@
 }
 
 
+bool File::CreateLink(const char* name, const char* target) {
+  int status = TEMP_FAILURE_RETRY(symlink(target, name));
+  return (status == 0);
+}
+
+
 bool File::Delete(const char* name) {
   int status = TEMP_FAILURE_RETRY(remove(name));
   if (status == -1) {
@@ -246,4 +253,20 @@
   return kOther;
 }
 
+
+File::Type File::GetType(const char* pathname, bool follow_links) {
+  struct stat entry_info;
+  int stat_success;
+  if (follow_links) {
+    stat_success = TEMP_FAILURE_RETRY(stat(pathname, &entry_info));
+  } else {
+    stat_success = TEMP_FAILURE_RETRY(lstat(pathname, &entry_info));
+  }
+  if (stat_success == -1) return File::kDoesNotExist;
+  if (S_ISDIR(entry_info.st_mode)) return File::kIsDirectory;
+  if (S_ISREG(entry_info.st_mode)) return File::kIsFile;
+  if (S_ISLNK(entry_info.st_mode)) return File::kIsLink;
+  return File::kDoesNotExist;
+}
+
 #endif  // defined(TARGET_OS_LINUX)
diff --git a/runtime/bin/file_macos.cc b/runtime/bin/file_macos.cc
index 37b5328..9d32457 100644
--- a/runtime/bin/file_macos.cc
+++ b/runtime/bin/file_macos.cc
@@ -109,7 +109,8 @@
   // Report errors for non-regular files.
   struct stat st;
   if (TEMP_FAILURE_RETRY(stat(name, &st)) == 0) {
-    if (!S_ISREG(st.st_mode)) {
+    // Only accept regular files and character devices.
+    if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode)) {
       errno = (S_ISDIR(st.st_mode)) ? EISDIR : ENOENT;
       return NULL;
     }
@@ -161,6 +162,12 @@
 }
 
 
+bool File::CreateLink(const char* name, const char* target) {
+  int status = TEMP_FAILURE_RETRY(symlink(target, name));
+  return (status == 0);
+}
+
+
 bool File::Delete(const char* name) {
   int status = TEMP_FAILURE_RETRY(remove(name));
   if (status == -1) {
@@ -254,4 +261,20 @@
   return kOther;
 }
 
+
+File::Type File::GetType(const char* pathname, bool follow_links) {
+  struct stat entry_info;
+  int stat_success;
+  if (follow_links) {
+    stat_success = TEMP_FAILURE_RETRY(stat(pathname, &entry_info));
+  } else {
+    stat_success = TEMP_FAILURE_RETRY(lstat(pathname, &entry_info));
+  }
+  if (stat_success == -1) return File::kDoesNotExist;
+  if (S_ISDIR(entry_info.st_mode)) return File::kIsDirectory;
+  if (S_ISREG(entry_info.st_mode)) return File::kIsFile;
+  if (S_ISLNK(entry_info.st_mode)) return File::kIsLink;
+  return File::kDoesNotExist;
+}
+
 #endif  // defined(TARGET_OS_MACOS)
diff --git a/runtime/bin/file_patch.dart b/runtime/bin/file_patch.dart
index 2355f9d..194813b 100644
--- a/runtime/bin/file_patch.dart
+++ b/runtime/bin/file_patch.dart
@@ -9,6 +9,8 @@
 patch class _File {
   /* patch */ static _exists(String path) native "File_Exists";
   /* patch */ static _create(String path) native "File_Create";
+  /* patch */ static _createLink(String path, String target)
+      native "File_CreateLink";
   /* patch */ static _delete(String path) native "File_Delete";
   /* patch */ static _directory(String path) native "File_Directory";
   /* patch */ static _lengthFromPath(String path) native "File_LengthFromPath";
@@ -35,6 +37,6 @@
   /* patch */ static _flush(int id) native "File_Flush";
 }
 
-List<int> _makeUint8ListView(List<int> source, int from, int to) {
-  return new Uint8List.view(source.asByteArray(), from, to);
+Uint8List _makeUint8ListView(Uint8List source, int offsetInBytes, int length) {
+  return new Uint8List.view(source.buffer, offsetInBytes, length);
 }
diff --git a/runtime/bin/file_system_entity_patch.dart b/runtime/bin/file_system_entity_patch.dart
new file mode 100644
index 0000000..267ab1b
--- /dev/null
+++ b/runtime/bin/file_system_entity_patch.dart
@@ -0,0 +1,8 @@
+// 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.
+
+patch class FileSystemEntity {
+  /* patch */ static int _getType(String path, bool followLinks)
+      native "File_GetType";
+}
diff --git a/runtime/bin/file_win.cc b/runtime/bin/file_win.cc
index e18071a..b23049d 100644
--- a/runtime/bin/file_win.cc
+++ b/runtime/bin/file_win.cc
@@ -12,6 +12,7 @@
 #include <stdio.h>  // NOLINT
 #include <string.h>  // NOLINT
 #include <sys/stat.h>  // NOLINT
+#include <WinIoCtl.h>  // NOLINT
 
 #include "bin/builtin.h"
 #include "bin/log.h"
@@ -154,6 +155,107 @@
 }
 
 
+// This structure is needed for creating and reading Junctions.
+typedef struct _REPARSE_DATA_BUFFER {
+    ULONG  ReparseTag;
+    USHORT ReparseDataLength;
+    USHORT Reserved;
+
+    union {
+        struct {
+            USHORT  SubstituteNameOffset;
+            USHORT  SubstituteNameLength;
+            USHORT  PrintNameOffset;
+            USHORT  PrintNameLength;
+            WCHAR   PathBuffer[1];
+        } SymbolicLinkReparseBuffer;
+
+        struct {
+            USHORT  SubstituteNameOffset;
+            USHORT  SubstituteNameLength;
+            USHORT  PrintNameOffset;
+            USHORT  PrintNameLength;
+            WCHAR   PathBuffer[1];
+        } MountPointReparseBuffer;
+
+        struct {
+            UCHAR   DataBuffer[1];
+        } GenericReparseBuffer;
+    };
+} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
+
+
+static const int kReparseDataHeaderSize = sizeof ULONG + 2 * sizeof USHORT;
+static const int kMountPointHeaderSize = 4 * sizeof USHORT;
+
+
+bool File::CreateLink(const char* utf8_name, const char* utf8_target) {
+  const wchar_t* name = StringUtils::Utf8ToWide(utf8_name);
+  int create_status = CreateDirectoryW(name, NULL);
+  // If the directory already existed, treat it as a success.
+  if (create_status == 0 &&
+      (GetLastError() != ERROR_ALREADY_EXISTS ||
+       (GetFileAttributesW(name) & FILE_ATTRIBUTE_DIRECTORY) != 0)) {
+    free(const_cast<wchar_t*>(name));
+    return false;
+  }
+
+  HANDLE dir_handle = CreateFileW(
+      name,
+      GENERIC_READ | GENERIC_WRITE,
+      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+      NULL,
+      OPEN_EXISTING,
+      FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
+      NULL);
+  free(const_cast<wchar_t*>(name));
+  if (dir_handle == INVALID_HANDLE_VALUE) {
+    return false;
+  }
+
+  const wchar_t* target = StringUtils::Utf8ToWide(utf8_target);
+  int target_len = wcslen(target);
+  if (target_len > MAX_PATH - 1) {
+    free(const_cast<wchar_t*>(target));
+    CloseHandle(dir_handle);
+    return false;
+  }
+
+  int reparse_data_buffer_size =
+      sizeof REPARSE_DATA_BUFFER + 2 * MAX_PATH * sizeof WCHAR;
+  REPARSE_DATA_BUFFER* reparse_data_buffer =
+      static_cast<REPARSE_DATA_BUFFER*>(calloc(reparse_data_buffer_size, 1));
+  reparse_data_buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
+  wcscpy(reparse_data_buffer->MountPointReparseBuffer.PathBuffer, target);
+  wcscpy(
+      reparse_data_buffer->MountPointReparseBuffer.PathBuffer + target_len + 1,
+      target);
+  reparse_data_buffer->MountPointReparseBuffer.SubstituteNameOffset = 0;
+  reparse_data_buffer->MountPointReparseBuffer.SubstituteNameLength =
+      target_len * sizeof WCHAR;
+  reparse_data_buffer->MountPointReparseBuffer.PrintNameOffset =
+      (target_len + 1) * sizeof WCHAR;
+  reparse_data_buffer->MountPointReparseBuffer.PrintNameLength =
+      target_len * sizeof WCHAR;
+  reparse_data_buffer->ReparseDataLength =
+      (target_len + 1) * 2 * sizeof WCHAR + kMountPointHeaderSize;
+  DWORD dummy_received_bytes;
+  int result = DeviceIoControl(
+      dir_handle,
+      FSCTL_SET_REPARSE_POINT,
+      reparse_data_buffer,
+      reparse_data_buffer->ReparseDataLength + kReparseDataHeaderSize,
+      NULL,
+      0,
+      &dummy_received_bytes,
+      NULL);
+  if (CloseHandle(dir_handle) == 0) return false;
+  free(const_cast<wchar_t*>(target));
+  free(reparse_data_buffer);
+  return (result != 0);
+}
+
+
 bool File::Delete(const char* name) {
   const wchar_t* system_name = StringUtils::Utf8ToWide(name);
   int status = _wremove(system_name);
@@ -270,4 +372,48 @@
   return kPipe;
 }
 
+
+File::Type File::GetType(const char* pathname, bool follow_links) {
+  const wchar_t* name = StringUtils::Utf8ToWide(pathname);
+  WIN32_FIND_DATAW file_data;
+  HANDLE find_handle = FindFirstFileW(name, &file_data);
+  if (find_handle == INVALID_HANDLE_VALUE) {
+    // TODO(whesse): Distinguish other errors from does not exist.
+    return File::kDoesNotExist;
+  }
+  FindClose(find_handle);
+  DWORD attributes = file_data.dwFileAttributes;
+  if ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
+    if (follow_links) {
+      HANDLE dir_handle = CreateFileW(
+          name,
+          0,
+          FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+          NULL,
+          OPEN_EXISTING,
+          FILE_FLAG_BACKUP_SEMANTICS,
+          NULL);
+      if (dir_handle == INVALID_HANDLE_VALUE) {
+        // TODO(whesse): Distinguish other errors from does not exist.
+        return File::kDoesNotExist;
+      } else {
+        CloseHandle(dir_handle);
+        return File::kIsDirectory;
+      }
+    } else {
+      DWORD reparse_tag = file_data.dwReserved0;
+      if (reparse_tag == IO_REPARSE_TAG_SYMLINK ||
+          reparse_tag == IO_REPARSE_TAG_MOUNT_POINT) {
+        return File::kIsLink;
+      } else {
+        return File::kDoesNotExist;
+      }
+    }
+  } else if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
+    return File::kIsDirectory;
+  } else {
+    return File::kIsFile;
+  }
+}
+
 #endif  // defined(TARGET_OS_WINDOWS)
diff --git a/runtime/bin/filter.cc b/runtime/bin/filter.cc
new file mode 100644
index 0000000..61a499c
--- /dev/null
+++ b/runtime/bin/filter.cc
@@ -0,0 +1,311 @@
+// 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.
+
+#include "bin/dartutils.h"
+#include "bin/filter.h"
+#include "bin/io_buffer.h"
+
+#include "include/dart_api.h"
+
+const int kZlibFlagMemUsage = 8;
+const int kZLibFlagWindowBits = 15;
+const int kZLibFlagUseGZipHeader = 16;
+const int kZLibFlagAcceptAnyHeader = 32;
+
+static const int kFilterPointerNativeField = 0;
+
+Filter* GetFilter(Dart_Handle filter_obj) {
+  Filter* filter;
+  Dart_Handle result = Filter::GetFilterPointerNativeField(filter_obj, &filter);
+  if (Dart_IsError(result)) {
+    Dart_PropagateError(result);
+  }
+  if (filter == NULL) {
+    Dart_ThrowException(DartUtils::NewInternalError("Filter destroyed"));
+  }
+  return filter;
+}
+
+void EndFilter(Dart_Handle filter_obj, Filter* filter) {
+  Filter::SetFilterPointerNativeField(filter_obj, NULL);
+  delete filter;
+}
+
+void FUNCTION_NAME(Filter_CreateZLibInflate)(Dart_NativeArguments args) {
+  Dart_EnterScope();
+  Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0);
+  Filter* filter = new ZLibInflateFilter();
+  if (filter == NULL || !filter->Init()) {
+    delete filter;
+    Dart_ThrowException(DartUtils::NewInternalError(
+        "Failed to create ZLibInflateFilter"));
+  }
+  Dart_Handle result = Filter::SetFilterPointerNativeField(filter_obj, filter);
+  if (Dart_IsError(result)) {
+    delete filter;
+    Dart_PropagateError(result);
+  }
+  Dart_ExitScope();
+}
+
+void FUNCTION_NAME(Filter_CreateZLibDeflate)(Dart_NativeArguments args) {
+  Dart_EnterScope();
+  Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0);
+  Dart_Handle gzip_obj = Dart_GetNativeArgument(args, 1);
+  Dart_Handle level_obj = Dart_GetNativeArgument(args, 2);
+  bool gzip;
+  if (Dart_IsError(Dart_BooleanValue(gzip_obj, &gzip))) {
+    Dart_ThrowException(DartUtils::NewInternalError(
+        "Failed to get 'gzip' parameter"));
+  }
+  int64_t level;
+  if (Dart_IsError(Dart_IntegerToInt64(level_obj, &level))) {
+    Dart_ThrowException(DartUtils::NewInternalError(
+        "Failed to get 'level' parameter"));
+  }
+  Filter* filter = new ZLibDeflateFilter(gzip, level);
+  if (filter == NULL || !filter->Init()) {
+    delete filter;
+    Dart_ThrowException(DartUtils::NewInternalError(
+        "Failed to create ZLibDeflateFilter"));
+  }
+  Dart_Handle result = Filter::SetFilterPointerNativeField(filter_obj, filter);
+  if (Dart_IsError(result)) {
+    delete filter;
+    Dart_PropagateError(result);
+  }
+  Dart_ExitScope();
+}
+
+void FUNCTION_NAME(Filter_Process)(Dart_NativeArguments args) {
+  Dart_EnterScope();
+  Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0);
+  Filter* filter = GetFilter(filter_obj);
+  Dart_Handle data_obj = Dart_GetNativeArgument(args, 1);
+  intptr_t length;
+  Dart_TypedData_Type type;
+  uint8_t* buffer = NULL;
+  Dart_Handle result = Dart_TypedDataAcquireData(
+      data_obj, &type, reinterpret_cast<void**>(&buffer), &length);
+  if (!Dart_IsError(result)) {
+    uint8_t* zlib_buffer = new uint8_t[length];
+    if (zlib_buffer == NULL) {
+      Dart_TypedDataReleaseData(data_obj);
+      Dart_ThrowException(DartUtils::NewInternalError(
+          "Failed to allocate buffer for zlib"));
+    }
+    memmove(zlib_buffer, buffer, length);
+    Dart_TypedDataReleaseData(data_obj);
+    buffer = zlib_buffer;
+  } else {
+    if (Dart_IsError(Dart_ListLength(data_obj, &length))) {
+      Dart_ThrowException(DartUtils::NewInternalError(
+          "Failed to get list length"));
+    }
+    buffer = new uint8_t[length];
+    if (Dart_IsError(Dart_ListGetAsBytes(data_obj, 0, buffer, length))) {
+      delete[] buffer;
+      Dart_ThrowException(DartUtils::NewInternalError(
+          "Failed to get list bytes"));
+    }
+  }
+  // Process will take ownership of buffer, if successful.
+  if (!filter->Process(buffer, length)) {
+    delete[] buffer;
+    EndFilter(filter_obj, filter);
+    Dart_ThrowException(DartUtils::NewInternalError(
+        "Call to Process while still processing data"));
+  }
+  Dart_ExitScope();
+}
+
+
+void FUNCTION_NAME(Filter_Processed)(Dart_NativeArguments args) {
+  Dart_EnterScope();
+  Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0);
+  Filter* filter = GetFilter(filter_obj);
+  Dart_Handle flush_obj = Dart_GetNativeArgument(args, 1);
+  bool flush;
+  if (Dart_IsError(Dart_BooleanValue(flush_obj, &flush))) {
+    Dart_ThrowException(DartUtils::NewInternalError(
+        "Failed to get 'flush' parameter"));
+  }
+  intptr_t read = filter->Processed(filter->processed_buffer(),
+                                    filter->processed_buffer_size(),
+                                    flush);
+  if (read < 0) {
+    // Error, end filter.
+    EndFilter(filter_obj, filter);
+    Dart_ThrowException(DartUtils::NewInternalError(
+        "Filter error, bad data"));
+  } else if (read == 0) {
+    Dart_SetReturnValue(args, Dart_Null());
+  } else {
+    uint8_t* io_buffer;
+    Dart_Handle result = IOBuffer::Allocate(read, &io_buffer);
+    memmove(io_buffer, filter->processed_buffer(), read);
+    Dart_SetReturnValue(args, result);
+  }
+  Dart_ExitScope();
+}
+
+
+void FUNCTION_NAME(Filter_End)(Dart_NativeArguments args) {
+  Dart_EnterScope();
+  Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0);
+  Filter* filter = GetFilter(filter_obj);
+  EndFilter(filter_obj, filter);
+  Dart_ExitScope();
+}
+
+
+Dart_Handle Filter::SetFilterPointerNativeField(Dart_Handle filter,
+                                                Filter* filter_pointer) {
+  return Dart_SetNativeInstanceField(filter,
+                                     kFilterPointerNativeField,
+                                     (intptr_t)filter_pointer);
+}
+
+
+Dart_Handle Filter::GetFilterPointerNativeField(Dart_Handle filter,
+                                                Filter** filter_pointer) {
+  return Dart_GetNativeInstanceField(
+      filter,
+      kFilterPointerNativeField,
+      reinterpret_cast<intptr_t*>(filter_pointer));
+}
+
+
+ZLibDeflateFilter::~ZLibDeflateFilter() {
+  delete[] current_buffer_;
+  if (initialized()) deflateEnd(&stream_);
+}
+
+
+bool ZLibDeflateFilter::Init() {
+  stream_.zalloc = Z_NULL;
+  stream_.zfree = Z_NULL;
+  stream_.opaque = Z_NULL;
+  int result = deflateInit2(
+      &stream_,
+      level_,
+      Z_DEFLATED,
+      kZLibFlagWindowBits | (gzip_ ? kZLibFlagUseGZipHeader : 0),
+      kZlibFlagMemUsage,
+      Z_DEFAULT_STRATEGY);
+  if (result == Z_OK) {
+    set_initialized(true);
+    return true;
+  }
+  return false;
+}
+
+
+bool ZLibDeflateFilter::Process(uint8_t* data, intptr_t length) {
+  if (current_buffer_ != NULL) return false;
+  stream_.avail_in = length;
+  stream_.next_in = current_buffer_ = data;
+  return true;
+}
+
+intptr_t ZLibDeflateFilter::Processed(uint8_t* buffer,
+                                      intptr_t length,
+                                      bool flush) {
+  stream_.avail_out = length;
+  stream_.next_out = buffer;
+  switch (deflate(&stream_, flush ? Z_SYNC_FLUSH : Z_NO_FLUSH)) {
+    case Z_OK: {
+      intptr_t processed = length - stream_.avail_out;
+      if (processed == 0) {
+        delete[] current_buffer_;
+        current_buffer_ = NULL;
+        return 0;
+      } else {
+        // We processed data, should be called again.
+        return processed;
+      }
+    }
+
+    case Z_STREAM_END:
+    case Z_BUF_ERROR:
+      // We processed all available input data.
+      delete[] current_buffer_;
+      current_buffer_ = NULL;
+      return 0;
+
+    default:
+    case Z_STREAM_ERROR:
+      // An error occoured.
+      delete[] current_buffer_;
+      current_buffer_ = NULL;
+      return -1;
+  }
+}
+
+
+ZLibInflateFilter::~ZLibInflateFilter() {
+  delete[] current_buffer_;
+  if (initialized()) inflateEnd(&stream_);
+}
+
+
+bool ZLibInflateFilter::Init() {
+  stream_.zalloc = Z_NULL;
+  stream_.zfree = Z_NULL;
+  stream_.opaque = Z_NULL;
+  int result = inflateInit2(&stream_,
+                            kZLibFlagWindowBits | kZLibFlagAcceptAnyHeader);
+  if (result == Z_OK) {
+    set_initialized(true);
+    return true;
+  }
+  return false;
+}
+
+
+bool ZLibInflateFilter::Process(uint8_t* data, intptr_t length) {
+  if (current_buffer_ != NULL) return false;
+  stream_.avail_in = length;
+  stream_.next_in = current_buffer_ = data;
+  return true;
+}
+
+
+intptr_t ZLibInflateFilter::Processed(uint8_t* buffer,
+                                      intptr_t length,
+                                      bool flush) {
+  stream_.avail_out = length;
+  stream_.next_out = buffer;
+  switch (inflate(&stream_, flush ? Z_SYNC_FLUSH : Z_NO_FLUSH)) {
+    case Z_OK: {
+      intptr_t processed = length - stream_.avail_out;
+      if (processed == 0) {
+        delete[] current_buffer_;
+        current_buffer_ = NULL;
+        return 0;
+      } else {
+        // We processed data, should be called again.
+        return processed;
+      }
+    }
+
+    case Z_STREAM_END:
+    case Z_BUF_ERROR:
+      // We processed all available input data.
+      delete[] current_buffer_;
+      current_buffer_ = NULL;
+      return 0;
+
+    default:
+    case Z_MEM_ERROR:
+    case Z_NEED_DICT:
+    case Z_DATA_ERROR:
+    case Z_STREAM_ERROR:
+      // An error occoured.
+      delete[] current_buffer_;
+      current_buffer_ = NULL;
+      return -1;
+  }
+}
+
diff --git a/runtime/bin/filter.h b/runtime/bin/filter.h
new file mode 100644
index 0000000..cc3a0a9
--- /dev/null
+++ b/runtime/bin/filter.h
@@ -0,0 +1,84 @@
+// 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.
+
+#ifndef BIN_FILTER_H_
+#define BIN_FILTER_H_
+
+#include "bin/builtin.h"
+#include "bin/utils.h"
+
+#include "../third_party/zlib/zlib.h"
+
+class Filter {
+ public:
+  virtual ~Filter() {}
+
+  virtual bool Init() = 0;
+
+  /**
+   * On a succesfull call to Process, Process will take ownership of data. On
+   * successive calls to either Processed or ~Filter, data will be freed with
+   * a delete[] call.
+   */
+  virtual bool Process(uint8_t* data, intptr_t length) = 0;
+  virtual intptr_t Processed(uint8_t* buffer, intptr_t length, bool finish) = 0;
+
+  static Dart_Handle SetFilterPointerNativeField(Dart_Handle filter,
+                                                 Filter* filter_pointer);
+  static Dart_Handle GetFilterPointerNativeField(Dart_Handle filter,
+                                                 Filter** filter_pointer);
+
+  bool initialized() const { return initialized_; }
+  void set_initialized(bool value) { initialized_ = value; }
+  uint8_t* processed_buffer() { return processed_buffer_; }
+  intptr_t processed_buffer_size() const { return kFilterBufferSize; }
+
+ protected:
+  Filter() : initialized_(false) {}
+
+ private:
+  static const intptr_t kFilterBufferSize = 64 * KB;
+  uint8_t processed_buffer_[kFilterBufferSize];
+  bool initialized_;
+
+  DISALLOW_COPY_AND_ASSIGN(Filter);
+};
+
+class ZLibDeflateFilter : public Filter {
+ public:
+  ZLibDeflateFilter(bool gzip = false, int level = 6)
+    : gzip_(gzip), level_(level), current_buffer_(NULL) {}
+  virtual ~ZLibDeflateFilter();
+
+  virtual bool Init();
+  virtual bool Process(uint8_t* data, intptr_t length);
+  virtual intptr_t Processed(uint8_t* buffer, intptr_t length, bool finish);
+
+ private:
+  const bool gzip_;
+  const int level_;
+  uint8_t* current_buffer_;
+  z_stream stream_;
+
+  DISALLOW_COPY_AND_ASSIGN(ZLibDeflateFilter);
+};
+
+class ZLibInflateFilter : public Filter {
+ public:
+  ZLibInflateFilter() : current_buffer_(NULL) {}
+  virtual ~ZLibInflateFilter();
+
+  virtual bool Init();
+  virtual bool Process(uint8_t* data, intptr_t length);
+  virtual intptr_t Processed(uint8_t* buffer, intptr_t length, bool finish);
+
+ private:
+  uint8_t* current_buffer_;
+  z_stream stream_;
+
+  DISALLOW_COPY_AND_ASSIGN(ZLibInflateFilter);
+};
+
+#endif  // BIN_FILTER_H_
+
diff --git a/runtime/bin/filter_patch.dart b/runtime/bin/filter_patch.dart
new file mode 100644
index 0000000..5a04241
--- /dev/null
+++ b/runtime/bin/filter_patch.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+class _FilterImpl extends NativeFieldWrapperClass1 implements _Filter {
+  void process(List<int> data) native "Filter_Process";
+
+  List<int> processed({bool flush: true}) native "Filter_Processed";
+
+  void end() native "Filter_End";
+}
+
+class _ZLibInflateFilter extends _FilterImpl {
+  _ZLibInflateFilter() {
+    _init();
+  }
+  void _init() native "Filter_CreateZLibInflate";
+}
+
+class _ZLibDeflateFilter extends _FilterImpl {
+  _ZLibDeflateFilter(bool gzip, int level) {
+    _init(gzip, level);
+  }
+  void _init(bool gzip, int level) native "Filter_CreateZLibDeflate";
+}
+
+patch class _Filter {
+  /* patch */ static _Filter newZLibDeflateFilter(bool gzip, int level)
+      => new _ZLibDeflateFilter(gzip, level);
+  /* patch */ static _Filter newZLibInflateFilter() => new _ZLibInflateFilter();
+}
+
diff --git a/runtime/bin/io.dart b/runtime/bin/io.dart
index 9faff4e..5e47d9f 100644
--- a/runtime/bin/io.dart
+++ b/runtime/bin/io.dart
@@ -13,6 +13,6 @@
 #import("dart:isolate");
 #import("dart:math");
 #import("dart:nativewrappers");
-#import("dart:scalarlist");
+#import("dart:typeddata");
 #import("dart:uri");
 #import("dart:utf");
diff --git a/runtime/bin/io_impl_sources.gypi b/runtime/bin/io_impl_sources.gypi
index 552ac3d..0eeaf5d 100644
--- a/runtime/bin/io_impl_sources.gypi
+++ b/runtime/bin/io_impl_sources.gypi
@@ -21,6 +21,8 @@
     'eventhandler_macos.h',
     'eventhandler_win.cc',
     'eventhandler_win.h',
+    'filter.cc',
+    'filter.h',
     'net/nss_memio.cc',
     'net/nss_memio.h',
     'platform.cc',
diff --git a/runtime/bin/io_natives.cc b/runtime/bin/io_natives.cc
index 9c647a3..660005e 100644
--- a/runtime/bin/io_natives.cc
+++ b/runtime/bin/io_natives.cc
@@ -21,6 +21,11 @@
   V(Crypto_GetRandomBytes, 1)                                                  \
   V(EventHandler_Start, 1)                                                     \
   V(EventHandler_SendData, 4)                                                  \
+  V(Filter_CreateZLibDeflate, 3)                                               \
+  V(Filter_CreateZLibInflate, 1)                                               \
+  V(Filter_End, 1)                                                             \
+  V(Filter_Process, 2)                                                         \
+  V(Filter_Processed, 2)                                                       \
   V(Platform_NumberOfProcessors, 0)                                            \
   V(Platform_OperatingSystem, 0)                                               \
   V(Platform_PathSeparator, 0)                                                 \
@@ -43,6 +48,7 @@
   V(Socket_GetStdioHandle, 2)                                                  \
   V(Socket_NewServicePort, 0)                                                  \
   V(Socket_GetType, 1)                                                         \
+  V(Socket_SetOption, 3)                                                       \
   V(SecureSocket_Connect, 8)                                                   \
   V(SecureSocket_Destroy, 1)                                                   \
   V(SecureSocket_Handshake, 1)                                                 \
@@ -52,8 +58,8 @@
   V(SecureSocket_RegisterBadCertificateCallback, 2)                            \
   V(SecureSocket_RegisterHandshakeCompleteCallback, 2)                         \
   V(SecureSocket_InitializeLibrary, 3)                                         \
-  V(SystemEncodingToString, 1)                                                 \
-  V(StringToSystemEncoding, 1)
+  V(StringToSystemEncoding, 1)                                                 \
+  V(SystemEncodingToString, 1)
 
 
 IO_NATIVE_LIST(DECLARE_FUNCTION);
diff --git a/runtime/bin/io_sources.gypi b/runtime/bin/io_sources.gypi
index 69100f0..52ec37c 100644
--- a/runtime/bin/io_sources.gypi
+++ b/runtime/bin/io_sources.gypi
@@ -9,6 +9,8 @@
     'directory_patch.dart',
     'eventhandler_patch.dart',
     'file_patch.dart',
+    'file_system_entity_patch.dart',
+    'filter_patch.dart',
     'http_patch.dart',
     'platform_patch.dart',
     'process_patch.dart',
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 4ccc87a..6f29afa 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -63,6 +63,11 @@
 static bool has_compile_all = false;
 
 
+// Global flag that is used to indicate that we want to print the source code
+// for script that is being run.
+static bool has_print_script = false;
+
+
 static bool IsValidFlag(const char* name,
                         const char* prefix,
                         intptr_t prefix_length) {
@@ -186,6 +191,16 @@
 }
 
 
+static bool ProcessPrintScriptOption(const char* arg) {
+  ASSERT(arg != NULL);
+  if (*arg != '\0') {
+    return false;
+  }
+  has_print_script = true;
+  return true;
+}
+
+
 static bool ProcessVmStatsRootOption(const char* arg) {
   ASSERT(arg != NULL);
   vmstats_root = arg;
@@ -238,6 +253,7 @@
   { "--generate-script-snapshot=", ProcessGenScriptSnapshotOption },
   { "--stats-root=", ProcessVmStatsRootOption },
   { "--stats", ProcessVmStatsOption },
+  { "--print-script", ProcessPrintScriptOption },
   { NULL, NULL }
 };
 
@@ -379,13 +395,13 @@
       return result;
     }
   }
-  Dart_Handle core_lib_url = DartUtils::NewString("dart:core");
-  if (Dart_IsError(core_lib_url)) {
-    return core_lib_url;
+  Dart_Handle io_lib_url = DartUtils::NewString("dart:io");
+  if (Dart_IsError(io_lib_url)) {
+    return io_lib_url;
   }
-  Dart_Handle core_lib = Dart_LookupLibrary(core_lib_url);
-  if (Dart_IsError(core_lib)) {
-    return core_lib;
+  Dart_Handle io_lib = Dart_LookupLibrary(io_lib_url);
+  if (Dart_IsError(io_lib)) {
+    return io_lib;
   }
   Dart_Handle runtime_options_class_name =
       DartUtils::NewString("_OptionsImpl");
@@ -393,7 +409,7 @@
     return runtime_options_class_name;
   }
   Dart_Handle runtime_options_class = Dart_GetClass(
-      core_lib, runtime_options_class_name);
+      io_lib, runtime_options_class_name);
   if (Dart_IsError(runtime_options_class)) {
     return runtime_options_class;
   }
@@ -583,6 +599,9 @@
 "--generate-script-snapshot=<file_name>\n"
 "  loads Dart script and generates a snapshot in the specified file\n"
 "\n"
+"--print-source\n"
+"  generates Dart source code back and prints it after parsing a Dart script\n"
+"\n"
 "--stats[:<port number>]\n"
 "  enables VM stats service and listens on specified port for HTTP requests\n"
 "  (default port number is dynamically assigned)\n"
@@ -675,6 +694,40 @@
 }
 
 
+static Dart_Handle GenerateScriptSource() {
+  Dart_Handle library_url = Dart_LibraryUrl(Dart_RootLibrary());
+  if (Dart_IsError(library_url)) {
+    return library_url;
+  }
+  Dart_Handle script_urls = Dart_GetScriptURLs(library_url);
+  if (Dart_IsError(script_urls)) {
+    return script_urls;
+  }
+  intptr_t length;
+  Dart_Handle result = Dart_ListLength(script_urls, &length);
+  if (Dart_IsError(result)) {
+    return result;
+  }
+  for (intptr_t i = 0; i < length; i++) {
+    Dart_Handle script_url = Dart_ListGetAt(script_urls, i);
+    if (Dart_IsError(script_url)) {
+      return script_url;
+    }
+    result = Dart_GenerateScriptSource(library_url, script_url);
+    if (Dart_IsError(result)) {
+      return result;
+    }
+    const char* script_source = NULL;
+    result = Dart_StringToCString(result, &script_source);
+    if (Dart_IsError(result)) {
+      return result;
+    }
+    Log::Print("%s\n", script_source);
+  }
+  return Dart_True();
+}
+
+
 int main(int argc, char** argv) {
   char* executable_name;
   char* script_name;
@@ -805,16 +858,22 @@
                          Dart_GetError(result));
       }
     }
-
-    // Lookup and invoke the top level main function.
-    result = Dart_Invoke(library, DartUtils::NewString("main"), 0, NULL);
-    if (Dart_IsError(result)) {
-      return ErrorExit("%s\n", Dart_GetError(result));
-    }
-    // Keep handling messages until the last active receive port is closed.
-    result = Dart_RunLoop();
-    if (Dart_IsError(result)) {
-      return ErrorExit("%s\n", Dart_GetError(result));
+    if (has_print_script) {
+      result = GenerateScriptSource();
+      if (Dart_IsError(result)) {
+        return ErrorExit("%s\n", Dart_GetError(result));
+      }
+    } else {
+      // Lookup and invoke the top level main function.
+      result = Dart_Invoke(library, DartUtils::NewString("main"), 0, NULL);
+      if (Dart_IsError(result)) {
+        return ErrorExit("%s\n", Dart_GetError(result));
+      }
+      // Keep handling messages until the last active receive port is closed.
+      result = Dart_RunLoop();
+      if (Dart_IsError(result)) {
+        return ErrorExit("%s\n", Dart_GetError(result));
+      }
     }
   }
 
diff --git a/runtime/bin/process_android.cc b/runtime/bin/process_android.cc
index 066539a..f0bbb83 100644
--- a/runtime/bin/process_android.cc
+++ b/runtime/bin/process_android.cc
@@ -334,6 +334,7 @@
     Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
     return errno;
   }
+  FDUtils::SetCloseOnExec(read_in[0]);
 
   result = TEMP_FAILURE_RETRY(pipe(read_err));
   if (result < 0) {
@@ -343,6 +344,7 @@
     Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
     return errno;
   }
+  FDUtils::SetCloseOnExec(read_err[0]);
 
   result = TEMP_FAILURE_RETRY(pipe(write_out));
   if (result < 0) {
@@ -354,6 +356,7 @@
     Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
     return errno;
   }
+  FDUtils::SetCloseOnExec(write_out[1]);
 
   result = TEMP_FAILURE_RETRY(pipe(exec_control));
   if (result < 0) {
@@ -367,12 +370,9 @@
     Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
     return errno;
   }
+  FDUtils::SetCloseOnExec(exec_control[0]);
+  FDUtils::SetCloseOnExec(exec_control[1]);
 
-  // Set close on exec on the write file descriptor of the exec control pipe.
-  result = TEMP_FAILURE_RETRY(
-      fcntl(exec_control[1],
-            F_SETFD,
-            TEMP_FAILURE_RETRY(fcntl(exec_control[1], F_GETFD)) | FD_CLOEXEC));
   if (result < 0) {
     SetChildOsErrorMessage(os_error_message);
     TEMP_FAILURE_RETRY(close(read_in[0]));
diff --git a/runtime/bin/process_linux.cc b/runtime/bin/process_linux.cc
index 3522385..9ff0ce7 100644
--- a/runtime/bin/process_linux.cc
+++ b/runtime/bin/process_linux.cc
@@ -336,6 +336,7 @@
     Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
     return errno;
   }
+  FDUtils::SetCloseOnExec(read_in[0]);
 
   result = TEMP_FAILURE_RETRY(pipe(read_err));
   if (result < 0) {
@@ -345,6 +346,7 @@
     Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
     return errno;
   }
+  FDUtils::SetCloseOnExec(read_err[0]);
 
   result = TEMP_FAILURE_RETRY(pipe(write_out));
   if (result < 0) {
@@ -356,6 +358,7 @@
     Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
     return errno;
   }
+  FDUtils::SetCloseOnExec(write_out[1]);
 
   result = TEMP_FAILURE_RETRY(pipe(exec_control));
   if (result < 0) {
@@ -369,12 +372,9 @@
     Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
     return errno;
   }
+  FDUtils::SetCloseOnExec(exec_control[0]);
+  FDUtils::SetCloseOnExec(exec_control[1]);
 
-  // Set close on exec on the write file descriptor of the exec control pipe.
-  result = TEMP_FAILURE_RETRY(
-      fcntl(exec_control[1],
-            F_SETFD,
-            TEMP_FAILURE_RETRY(fcntl(exec_control[1], F_GETFD)) | FD_CLOEXEC));
   if (result < 0) {
     SetChildOsErrorMessage(os_error_message);
     TEMP_FAILURE_RETRY(close(read_in[0]));
diff --git a/runtime/bin/process_macos.cc b/runtime/bin/process_macos.cc
index 67a7102..fb60ecd 100644
--- a/runtime/bin/process_macos.cc
+++ b/runtime/bin/process_macos.cc
@@ -334,6 +334,7 @@
     Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
     return errno;
   }
+  FDUtils::SetCloseOnExec(read_in[0]);
 
   result = TEMP_FAILURE_RETRY(pipe(read_err));
   if (result < 0) {
@@ -343,6 +344,7 @@
     Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
     return errno;
   }
+  FDUtils::SetCloseOnExec(read_err[0]);
 
   result = TEMP_FAILURE_RETRY(pipe(write_out));
   if (result < 0) {
@@ -354,6 +356,7 @@
     Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
     return errno;
   }
+  FDUtils::SetCloseOnExec(write_out[1]);
 
   result = TEMP_FAILURE_RETRY(pipe(exec_control));
   if (result < 0) {
@@ -367,12 +370,9 @@
     Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
     return errno;
   }
+  FDUtils::SetCloseOnExec(exec_control[0]);
+  FDUtils::SetCloseOnExec(exec_control[1]);
 
-  // Set close on exec on the write file descriptor of the exec control pipe.
-  result = TEMP_FAILURE_RETRY(
-      fcntl(exec_control[1],
-            F_SETFD,
-            TEMP_FAILURE_RETRY(fcntl(exec_control[1], F_GETFD)) | FD_CLOEXEC));
   if (result < 0) {
     SetChildOsErrorMessage(os_error_message);
     VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
diff --git a/runtime/bin/process_patch.dart b/runtime/bin/process_patch.dart
index 4468ec0..4893cee 100644
--- a/runtime/bin/process_patch.dart
+++ b/runtime/bin/process_patch.dart
@@ -118,27 +118,27 @@
           numBackslash++;
           pos--;
         }
-        sb.add(argument.substring(nextPos, quotePos - numBackslash));
+        sb.write(argument.substring(nextPos, quotePos - numBackslash));
         for (var i = 0; i < numBackslash; i++) {
-          sb.add(r'\\');
+          sb.write(r'\\');
         }
-        sb.add(r'\"');
+        sb.write(r'\"');
         nextPos = quotePos + 1;
         quotePos = argument.indexOf('"', nextPos);
       }
-      sb.add(argument.substring(nextPos, argument.length));
+      sb.write(argument.substring(nextPos, argument.length));
       result = sb.toString();
 
       // Add '"' at the beginning and end and replace all '\' at
       // the end with two '\'.
       sb = new StringBuffer('"');
-      sb.add(result);
+      sb.write(result);
       nextPos = argument.length - 1;
       while (argument.codeUnitAt(nextPos) == backslash) {
-        sb.add('\\');
+        sb.write('\\');
         nextPos--;
       }
-      sb.add('"');
+      sb.write('"');
       result = sb.toString();
     }
 
@@ -302,7 +302,7 @@
         .reduce(
             new StringBuffer(),
             (buf, data) {
-              buf.add(data);
+              buf.write(data);
               return buf;
             });
 
@@ -311,7 +311,7 @@
         .reduce(
             new StringBuffer(),
             (buf, data) {
-              buf.add(data);
+              buf.write(data);
               return buf;
             });
 
diff --git a/runtime/bin/resources.h b/runtime/bin/resources.h
new file mode 100644
index 0000000..6279bba
--- /dev/null
+++ b/runtime/bin/resources.h
@@ -0,0 +1,53 @@
+// 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.
+
+#ifndef BIN_RESOURCES_H_
+#define BIN_RESOURCES_H_
+
+#include <stddef.h>
+#include <string.h>
+
+#include "platform/assert.h"
+
+
+class Resources {
+ public:
+  static const int kNoSuchInstance = -1;
+
+  static int ResourceLookup(const char* path, const char** resource) {
+    for (int i = 0; i < get_resource_count(); i++) {
+      resource_map_entry* entry = get_resource(i);
+      if (strcmp(path, entry->path_) == 0) {
+        *resource = entry->resource_;
+        ASSERT(entry->length_ > 0);
+        return entry->length_;
+      }
+    }
+    return kNoSuchInstance;
+  }
+
+ private:
+  struct resource_map_entry {
+    const char* path_;
+    const char* resource_;
+    intptr_t length_;
+  };
+
+  // These fields are generated by resources_gen.cc.
+  static resource_map_entry builtin_resources_[];
+  static const intptr_t builtin_resources_count_;
+
+  static resource_map_entry* get_resource(int i) {
+    ASSERT(i >= 0 && i < builtin_resources_count_);
+    return &builtin_resources_[i];
+  }
+
+  static intptr_t get_resource_count() {
+    return builtin_resources_count_; }
+
+  DISALLOW_ALLOCATION();
+  DISALLOW_IMPLICIT_CONSTRUCTORS(Resources);
+};
+
+#endif  // BIN_RESOURCES_H_
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index d9c20e7..3a35ea2 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -445,6 +445,33 @@
 }
 
 
+void FUNCTION_NAME(Socket_SetOption)(Dart_NativeArguments args) {
+  Dart_EnterScope();
+  Dart_Handle socket_obj = Dart_GetNativeArgument(args, 0);
+  intptr_t socket = 0;
+  bool result = false;
+  Dart_Handle err = Socket::GetSocketIdNativeField(socket_obj, &socket);
+  if (Dart_IsError(err)) Dart_PropagateError(err);
+  Dart_Handle option_obj = Dart_GetNativeArgument(args, 1);
+  int64_t option;
+  err = Dart_IntegerToInt64(option_obj, &option);
+  if (Dart_IsError(err)) Dart_PropagateError(err);
+  Dart_Handle enabled_obj = Dart_GetNativeArgument(args, 2);
+  bool enabled;
+  err = Dart_BooleanValue(enabled_obj, &enabled);
+  if (Dart_IsError(err)) Dart_PropagateError(err);
+  switch (option) {
+    case 0:  // TCP_NODELAY.
+      result = Socket::SetNoDelay(socket, enabled);
+      break;
+    default:
+      break;
+  }
+  Dart_SetReturnValue(args, Dart_NewBoolean(result));
+  Dart_ExitScope();
+}
+
+
 Dart_Handle Socket::SetSocketIdNativeField(Dart_Handle socket, intptr_t id) {
   return Dart_SetNativeInstanceField(socket, kSocketIdNativeField, id);
 }
diff --git a/runtime/bin/socket.h b/runtime/bin/socket.h
index db68c32..b68b782 100644
--- a/runtime/bin/socket.h
+++ b/runtime/bin/socket.h
@@ -43,6 +43,7 @@
   static void Close(intptr_t fd);
   static bool SetNonBlocking(intptr_t fd);
   static bool SetBlocking(intptr_t fd);
+  static bool SetNoDelay(intptr_t fd, bool enabled);
 
   // Perform a IPv4 hostname lookup. Returns the hostname string in
   // IPv4 dotted-decimal format.
diff --git a/runtime/bin/socket_android.cc b/runtime/bin/socket_android.cc
index 07a7a10..7e3871d 100644
--- a/runtime/bin/socket_android.cc
+++ b/runtime/bin/socket_android.cc
@@ -10,6 +10,7 @@
 #include <stdlib.h>  // NOLINT
 #include <string.h>  // NOLINT
 #include <unistd.h>  // NOLINT
+#include <netinet/tcp.h>  // NOLINT
 
 #include "bin/socket.h"
 #include "bin/fdutils.h"
@@ -274,4 +275,14 @@
   return FDUtils::SetBlocking(fd);
 }
 
+
+bool Socket::SetNoDelay(intptr_t fd, bool enabled) {
+  int on = enabled ? 1 : 0;
+  return TEMP_FAILURE_RETRY(setsockopt(fd,
+                                       SOL_TCP,
+                                       TCP_NODELAY,
+                                       reinterpret_cast<char *>(&on),
+                                       sizeof(on))) == 0;
+}
+
 #endif  // defined(TARGET_OS_ANDROID)
diff --git a/runtime/bin/socket_linux.cc b/runtime/bin/socket_linux.cc
index cdaab92..33e632d 100644
--- a/runtime/bin/socket_linux.cc
+++ b/runtime/bin/socket_linux.cc
@@ -11,6 +11,7 @@
 #include <string.h>  // NOLINT
 #include <sys/stat.h>  // NOLINT
 #include <unistd.h>  // NOLINT
+#include <netinet/tcp.h>  // NOLINT
 
 #include "bin/fdutils.h"
 #include "bin/file.h"
@@ -286,4 +287,14 @@
   return FDUtils::SetBlocking(fd);
 }
 
+
+bool Socket::SetNoDelay(intptr_t fd, bool enabled) {
+  int on = enabled ? 1 : 0;
+  return TEMP_FAILURE_RETRY(setsockopt(fd,
+                                       SOL_TCP,
+                                       TCP_NODELAY,
+                                       reinterpret_cast<char *>(&on),
+                                       sizeof(on))) == 0;
+}
+
 #endif  // defined(TARGET_OS_LINUX)
diff --git a/runtime/bin/socket_macos.cc b/runtime/bin/socket_macos.cc
index 849e1fa..b11da00 100644
--- a/runtime/bin/socket_macos.cc
+++ b/runtime/bin/socket_macos.cc
@@ -11,6 +11,7 @@
 #include <string.h>  // NOLINT
 #include <sys/stat.h>  // NOLINT
 #include <unistd.h>  // NOLINT
+#include <netinet/tcp.h>  // NOLINT
 
 #include "bin/fdutils.h"
 #include "bin/file.h"
@@ -272,4 +273,14 @@
   return FDUtils::SetBlocking(fd);
 }
 
+
+bool Socket::SetNoDelay(intptr_t fd, bool enabled) {
+  int on = enabled ? 1 : 0;
+  return TEMP_FAILURE_RETRY(setsockopt(fd,
+                                       IPPROTO_TCP,
+                                       TCP_NODELAY,
+                                       reinterpret_cast<char *>(&on),
+                                       sizeof(on))) == 0;
+}
+
 #endif  // defined(TARGET_OS_MACOS)
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index 3b9aaae..0e9c25f 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -392,6 +392,12 @@
     close();
   }
 
+  bool setOption(SocketOption option, bool enabled) {
+    if (option is! SocketOption) throw new ArgumentError(options);
+    if (enabled is! bool) throw new ArgumentError(enabled);
+    return nativeSetOption(option._value, enabled);
+  }
+
   nativeAvailable() native "Socket_Available";
   nativeRead(int len) native "Socket_Read";
   nativeWrite(List<int> buffer, int offset, int bytes)
@@ -403,6 +409,7 @@
   int nativeGetPort() native "Socket_GetPort";
   List nativeGetRemotePeer() native "Socket_GetRemotePeer";
   OSError nativeGetError() native "Socket_GetError";
+  bool nativeSetOption(int option, bool enabled) native "Socket_SetOption";
 
   static SendPort newServicePort() native "Socket_NewServicePort";
 }
@@ -434,7 +441,7 @@
         if (socket != null) _controller.add(new _RawSocket(socket));
       },
       error: (e) {
-        _controller.signalError(new AsyncError(e));
+        _controller.addError(new AsyncError(e));
         _controller.close();
       }
     );
@@ -507,7 +514,7 @@
       },
       closed: () => _controller.add(RawSocketEvent.READ_CLOSED),
       error: (e) {
-        _controller.signalError(new AsyncError(e));
+        _controller.addError(new AsyncError(e));
         close();
       }
     );
@@ -571,6 +578,9 @@
     }
   }
 
+  bool setOption(SocketOption option, bool enabled) =>
+      _socket.setOption(option, enabled);
+
   _pause() {
     _socket.setListening(read: false, write: false);
   }
@@ -763,20 +773,28 @@
         unsubscribeOnError: unsubscribeOnError);
   }
 
+  Encoding get encoding => _sink.encoding;
+
+  void set encoding(Encoding value) {
+    _sink.encoding = value;
+  }
+
+  void write(Object obj) => _sink.write(obj);
+
+  void writeln([Object obj = ""]) => _sink.writeln(obj);
+
+  void writeCharCode(int charCode) => _sink.writeCharCode(charCode);
+
+  void writeAll(Iterable objects) => _sink.writeAll(objects);
+
+  void writeBytes(List<int> bytes) => _sink.writeBytes(bytes);
+
   Future<Socket> consume(Stream<List<int>> stream) {
     return _sink.consume(stream);
   }
 
-  Future<Socket> addStream(Stream<List<int>> stream) {
-    return _sink.addStream(stream);
-  }
-
-  void add(List<int> data) {
-    return _sink.add(data);
-  }
-
-  void addString(String string, [Encoding encoding = Encoding.UTF_8]) {
-    return _sink.addString(string, encoding);
+  Future<Socket> writeStream(Stream<List<int>> stream) {
+    return _sink.writeStream(stream);
   }
 
   close() => _sink.close();
@@ -792,6 +810,11 @@
     _controller.close();
   }
 
+  bool setOption(SocketOption option, bool enabled) {
+    if (_raw == null) return false;
+    return _raw.setOption(option, enabled);
+  }
+
   int get port => _raw.port;
   String get remoteHost => _raw.remoteHost;
   int get remotePort => _raw.remotePort;
@@ -863,7 +886,7 @@
   void _onError(error) {
     if (!_controllerClosed) {
       _controllerClosed = true;
-      _controller.signalError(error);
+      _controller.addError(error);
       _controller.close();
     }
     _done(error);
diff --git a/runtime/bin/socket_win.cc b/runtime/bin/socket_win.cc
index 4fcf156..54f6639 100644
--- a/runtime/bin/socket_win.cc
+++ b/runtime/bin/socket_win.cc
@@ -310,4 +310,15 @@
   return SetBlockingHelper(fd, true);
 }
 
+
+bool Socket::SetNoDelay(intptr_t fd, bool enabled) {
+  SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
+  int on = enabled ? 1 : 0;
+  return setsockopt(fd,
+                    IPPROTO_TCP,
+                    TCP_NODELAY,
+                    reinterpret_cast<char *>(&on),
+                    sizeof(on)) == 0;
+}
+
 #endif  // defined(TARGET_OS_WINDOWS)
diff --git a/runtime/bin/vmstats/bargraph.dart b/runtime/bin/vmstats/bargraph.dart
new file mode 100644
index 0000000..502ff8e
--- /dev/null
+++ b/runtime/bin/vmstats/bargraph.dart
@@ -0,0 +1,223 @@
+// 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.
+
+part of dart.vmstats;
+
+class BarGraph {
+  CanvasElement _canvas;
+  GraphModel _model;
+  List<Element> _elements;
+  double scaleHeight = 0;
+
+  static const int SAMPLE_WIDTH = 5;
+  static const int LEFT_MARGIN = 50;
+  static const int RIGHT_MARGIN = 150;
+  static const int LEGEND_WIDTH = 130;
+  static const int LEGEND_Y = 20;
+  static const int INSIDE_MARGIN = 2;
+
+  static const int NUM_DIVIDERS = 5;
+  static const String FONT = "14px sans-serif";
+
+  BarGraph(this._canvas, this._elements) {
+    var maxElements =
+        (_canvas.width - LEFT_MARGIN - RIGHT_MARGIN) ~/ SAMPLE_WIDTH;
+    _model = new GraphModel(maxElements);
+    _model.addListener(drawGraph, null);
+    drawBarGraph();
+ }
+
+  void addSample(List<int> segments) {
+    if (segments.length != _elements.length) {
+      throw new RuntimeError('invalid sample size for graph');
+    }
+    _model.addSample(segments);
+  }
+
+  void drawBarGraph() {
+    // Draw chart's outer box.
+    var context = _canvas.context2d;
+    context.beginPath();
+    context.strokeStyle = 'black';
+    // The '2's are the width of the line, even though 1 is specified.
+    context.strokeRect(
+        LEFT_MARGIN - 2, 1, _canvas.width - LEFT_MARGIN - RIGHT_MARGIN + 2,
+        _canvas.height - 2, 1);
+
+    // Draw legend.
+    var x = _canvas.width - LEGEND_WIDTH;
+    var y = LEGEND_Y;
+    context.font = FONT;
+    for (var i = 0; i < _elements.length; i++) {
+      context.fillStyle = _elements[i].color;
+      context.fillRect(x, y, 20, 20);
+      context.fillStyle = 'black';
+      context.fillText(_elements[i].name, x + 30, y + 15);
+      y += 30;
+    }
+  }
+
+  void drawGraph(GraphModel model) {
+    var graphHeight = model.maxTotal;
+    var width = _canvas.clientWidth;
+    var height = _canvas.clientHeight;
+    if (graphHeight >= scaleHeight) {
+      // Make scale height a bit higher to allow for growth, and
+      // round to nearest 100.
+      scaleHeight = graphHeight * 1.2;
+      scaleHeight = ((scaleHeight / 100).ceil() * 100);
+    }
+    var scale = height / scaleHeight;
+    drawValues(scaleHeight, scale);
+    drawChart(scaleHeight, scale);
+  }
+
+  void drawChart(int maxHeight, double scale) {
+    var dividerHeight = maxHeight ~/ NUM_DIVIDERS;
+    var context = _canvas.context2d;
+    context.beginPath();
+    var height = maxHeight.toInt();
+    var scaledY = dividerHeight * scale;
+
+    // Draw the vertical axis values and lines.
+    for (var i = 1; i < NUM_DIVIDERS; i++) {
+      height -= (dividerHeight ~/ 100) * 100;
+      context.font = FONT;
+      context.fillStyle = 'black';
+      context.textAlign = 'right';
+      context.textBaseline = 'middle';
+      context.fillText(height.toString(), LEFT_MARGIN - 10, scaledY);
+      context.moveTo(LEFT_MARGIN - 2, scaledY);
+      context.strokeStyle = 'grey';
+      context.lineWidth = 0.5;
+      context.lineTo(_canvas.width - RIGHT_MARGIN, scaledY);
+      context.stroke();
+      scaledY += dividerHeight * scale;
+    }
+  }
+
+  void drawValues(int maxHeight, num scale) {
+    Iterator<Sample> iterator = _model.iterator;
+    var x = LEFT_MARGIN + INSIDE_MARGIN;
+
+    while (iterator.moveNext()) {
+      Sample s = iterator.current;
+      var y = INSIDE_MARGIN;
+      if (s != null) {
+        var blankHeight = scaleHeight - s.total();
+        drawVerticalSegment(x, y, SAMPLE_WIDTH, blankHeight, 'white', scale);
+        y += blankHeight;
+        for (int i = s.length - 1; i >= 0; i--) {
+          var h = s[i];
+          drawVerticalSegment(x, y, SAMPLE_WIDTH, h, _elements[i].color, scale);
+          y += s[i];
+        }
+      } else {
+        drawVerticalSegment(x, INSIDE_MARGIN, SAMPLE_WIDTH,
+            maxHeight, 'white', scale);
+      }
+      x += SAMPLE_WIDTH ;
+    }
+  }
+
+  void drawVerticalSegment(int x, int y, int w, int h, String color,
+                           num scale) {
+    var context = _canvas.context2d;
+    y = (y * scale).floor();
+    h = (h * scale).ceil();
+    context.beginPath();
+    context.lineWidth = w;
+    context.fillStyle = color;
+    context.strokeStyle = color;
+    if (x < INSIDE_MARGIN) {
+      x = INSIDE_MARGIN;
+    }
+    if (y < INSIDE_MARGIN) {
+      y = INSIDE_MARGIN;
+    }
+    var max = _canvas.width - INSIDE_MARGIN;
+    if ((x + w) > max) {
+      w = max - x;
+    }
+    max = _canvas.height - INSIDE_MARGIN;
+    if ((y + h) > max) {
+      h = max - y;
+    }
+    context.moveTo(x, y);
+    context.lineTo(x, y + h);
+    context.stroke();
+  }
+}
+
+class GraphModel extends ObservableModel {
+  List<Sample> _samples = new List<Sample>();
+  int _maxSize;
+
+  static const int _LARGE_LENGTH = 999999999;
+
+  GraphModel(this._maxSize) {}
+
+  void addSample(List<int> segments) {
+    var len = _samples.length;
+    if (_samples.length >= _maxSize) {
+      _samples.remove(_samples.first);
+    }
+    _samples.add(new Sample(segments));
+    notifySuccess();
+  }
+
+  int get maxSize => _maxSize;
+
+  Iterator<Sample> get iterator => _samples.iterator;
+
+  Sample operator[](int i) => _samples[i];
+
+  /**
+   * Returns the minimum total from all the samples.
+   */
+  int get minTotal {
+    var min = _LARGE_LENGTH;
+    _samples.forEach((Sample s) => min = (s.total() < min ? s.total() : min));
+    return min;
+  }
+
+  /**
+   * Returns the maximum total from all the samples.
+   */
+  int get maxTotal {
+    var max = 0;
+    _samples.forEach((Sample s) => max = (s.total() > max ? s.total() : max));
+    return max;
+  }
+}
+
+/**
+ * An element is a data type that gets charted. Each element has a name for
+ * the legend, and a color for the bar graph. The number of elements in a
+ * graph should match the number of segments in each sample.
+ */
+class Element {
+  final String name;
+  final String color;  // Any description the DOM will accept, like "red".
+
+  Element(this.name, this.color) {}
+}
+
+/**
+ * A sample is a list of segment lengths.
+ */
+class Sample {
+  List<int> _segments;
+
+  Sample(this._segments) {}
+
+  int get length => _segments.length;
+  int operator[](int i) => _segments[i];
+
+  Iterator<int> get iterator => _segments.iterator;
+
+  int total() {
+    return _segments.reduce(0, (int prev, int element) => prev + element);
+  }
+}
diff --git a/runtime/bin/vmstats/favicon.ico b/runtime/bin/vmstats/favicon.ico
new file mode 100644
index 0000000..50ea5b0
--- /dev/null
+++ b/runtime/bin/vmstats/favicon.ico
Binary files differ
diff --git a/runtime/bin/vmstats/isolate_list.dart b/runtime/bin/vmstats/isolate_list.dart
new file mode 100644
index 0000000..835e7b8
--- /dev/null
+++ b/runtime/bin/vmstats/isolate_list.dart
@@ -0,0 +1,62 @@
+// 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.
+
+part of dart.vmstats;
+
+class IsolateList {
+  UListElement _listArea;
+
+  static const String CSS_VISIBLE = 'isolate_details';
+  static const String CSS_HIDDEN  = 'isolate_details_hidden';
+
+  IsolateList(this._listArea) {}
+
+  void updateList(IsolateListModel model) {
+    var detailsClass = CSS_HIDDEN;
+    if (_listArea.children.length > 0) {
+      // Preserve visibility state.
+      var listItem = _listArea.children.first;
+      var item = listItem.children.first;
+      if (item.classes.length > 0 && item.classes.first == CSS_VISIBLE) {
+        detailsClass = CSS_VISIBLE;
+      }
+      _listArea.children.clear();
+    }
+    var iterator = model.iterator;
+    while (iterator.moveNext()) {
+      var isolate = iterator.current;
+      var listItem = new LIElement();
+      listItem.classes.add('isolate_list');
+      listItem.text = isolate.name
+          .replaceAll('\$', ': ')  // Split script from isolate, and ...
+          .replaceAll('-', ' ');   // ... split name from port number.
+
+      // Add isolate details as hidden children.
+      var details = new DivElement();
+      isolateDetails(isolate, details);
+      details.classes.add(detailsClass);
+      listItem.children.add(details);
+      listItem.onClick.listen((e) => toggle(details));
+
+      _listArea.children.add(listItem);
+    }
+  }
+
+  void isolateDetails(Isolate isolate, DivElement parent) {
+    var newSpace = new DivElement();
+    newSpace.text = 'New space: ${isolate.newSpace.used}K';
+    parent.children.add(newSpace);
+    var oldSpace = new DivElement();
+    oldSpace.text = 'Old space: ${isolate.oldSpace.used}K';
+    parent.children.add(oldSpace);
+    var stack = new DivElement();
+    stack.text = 'Stack limit: ${(isolate.stackLimit / 1000000).round()}M';
+    parent.children.add(stack);
+  }
+
+  void toggle(DivElement e) {
+    e.classes.toggle(CSS_VISIBLE);
+    e.classes.toggle(CSS_HIDDEN);
+  }
+}
diff --git a/runtime/bin/vmstats/models.dart b/runtime/bin/vmstats/models.dart
new file mode 100644
index 0000000..ae07fbc
--- /dev/null
+++ b/runtime/bin/vmstats/models.dart
@@ -0,0 +1,117 @@
+// 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.
+
+part of dart.vmstats;
+
+// Base class of model that reports changes to registered listeners.
+abstract class ObservableModel {
+  List<ModelListener> _listeners = [];
+
+  void addListener(Function onUpdate, Function onFailure) {
+    _listeners.add(new ModelListener(onUpdate, onFailure));
+  }
+
+  void removeListener(Function onUpdate) {
+    Iterator<ModelListener> iterator = _listeners.iterator;
+    while (iterator.moveNext()) {
+      if (iterator.current._onUpdate == onUpdate) {
+        _listeners.remove(iterator.current);
+        return;
+      }
+    }
+  }
+
+  void notifySuccess() {
+   _listeners.forEach((listener) => listener.changed(this));
+  }
+
+  void notifyFailure() {
+    _listeners.forEach((listener) => listener.failed());
+  }
+}
+
+// Model of a set of listener functions to call when a model changes.
+class ModelListener {
+  Function _onUpdate;
+  Function _onFailure;
+
+  ModelListener(this._onUpdate, this._onFailure) {}
+
+  void changed(IsolateListModel model) => Function.apply(_onUpdate, [model]);
+  void failed() => Function.apply(_onFailure, []);
+}
+
+
+// Model of the current running isolates.
+class IsolateListModel extends ObservableModel {
+  List<Isolate> _isolates = [];
+
+  void update() {
+    HttpRequest.getString('/isolates').then(
+        (Map response) => _onUpdate(JSON.parse(response)),
+        onError: (e) => notifyFailure());
+  }
+
+  void _onUpdate(Map isolateMap) {
+    _isolates = [];
+    List list = isolateMap['isolates'];
+    for (int i = 0; i < list.length; i++) {
+      _isolates.add(new Isolate(list[i]));
+    }
+    notifySuccess();
+  }
+
+  String toString() {
+    return _isolates.join(', ');
+  }
+
+  // List delegate method subset.
+  Isolate elementAt(int index) => _isolates[index];
+
+  void forEach(void f(Isolate element)) => _isolates.forEach(f);
+
+  bool isEmpty() => _isolates.isEmpty;
+
+  Iterator<Isolate> get iterator => _isolates.iterator;
+
+  int get length => _isolates.length;
+
+  Isolate operator[](int index) => _isolates[index];
+}
+
+
+// Model of a single isolate.
+class Isolate {
+  final String name;
+  final int port;
+  final int startTime;
+  final int stackLimit;
+  final Space newSpace;
+  final Space oldSpace;
+
+  // Create an isolate from a map describing an isolate in the observed VM.
+  Isolate(Map raw):
+      name = raw['name'],
+      port = raw['port'],
+      startTime = raw['starttime'],
+      stackLimit = raw['stacklimit'],
+      newSpace = new Space(raw['newspace']),
+      oldSpace = new Space(raw['oldspace']) {}
+
+  String toString() {
+    return '$name: ${newSpace.used + oldSpace.used}K';
+  }
+}
+
+// Model of a memory space.
+class Space {
+  final int used;
+  final int capacity;
+
+  Space(Map raw): used = raw['used'], capacity = raw['capacity'] {}
+
+  String toString() {
+    return 'used: $used capacity: $capacity';
+  }
+}
diff --git a/runtime/bin/vmstats/packages/browser/dart.js b/runtime/bin/vmstats/packages/browser/dart.js
new file mode 100644
index 0000000..bf60f52
--- /dev/null
+++ b/runtime/bin/vmstats/packages/browser/dart.js
@@ -0,0 +1,249 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Bootstrap support for Dart scripts on the page as this script.
+if (navigator.webkitStartDart) {
+  if (!navigator.webkitStartDart()) {
+    document.body.innerHTML = 'This build has expired.  Please download a new Dartium at http://www.dartlang.org/dartium/index.html';
+  }
+} else {
+  // TODO:
+  // - Support in-browser compilation.
+  // - Handle inline Dart scripts.
+  window.addEventListener("DOMContentLoaded", function (e) {
+    // Fall back to compiled JS. Run through all the scripts and
+    // replace them if they have a type that indicate that they source
+    // in Dart code.
+    //
+    //   <script type="application/dart" src="..."></script>
+    //
+    var scripts = document.getElementsByTagName("script");
+    var length = scripts.length;
+    for (var i = 0; i < length; ++i) {
+      if (scripts[i].type == "application/dart") {
+        // Remap foo.dart to foo.dart.js.
+        if (scripts[i].src && scripts[i].src != '') {
+          var script = document.createElement('script');
+          script.src = scripts[i].src + '.js';
+          var parent = scripts[i].parentNode;
+          parent.replaceChild(script, scripts[i]);
+        }
+      }
+    }
+  }, false);
+}
+
+// ---------------------------------------------------------------------------
+// Experimental support for JS interoperability
+// ---------------------------------------------------------------------------
+function SendPortSync() {
+}
+
+function ReceivePortSync() {
+  this.id = ReceivePortSync.id++;
+  ReceivePortSync.map[this.id] = this;
+}
+
+(function() {
+  // Serialize the following types as follows:
+  //  - primitives / null: unchanged
+  //  - lists: [ 'list', internal id, list of recursively serialized elements ]
+  //  - maps: [ 'map', internal id, map of keys and recursively serialized values ]
+  //  - send ports: [ 'sendport', type, isolate id, port id ]
+  //
+  // Note, internal id's are for cycle detection.
+  function serialize(message) {
+    var visited = [];
+    function checkedSerialization(obj, serializer) {
+      // Implementation detail: for now use linear search.
+      // Another option is expando, but it may prohibit
+      // VM optimizations (like putting object into slow mode
+      // on property deletion.)
+      var id = visited.indexOf(obj);
+      if (id != -1) return [ 'ref', id ];
+      var id = visited.length;
+      visited.push(obj);
+      return serializer(id);
+    }
+
+    function doSerialize(message) {
+      if (message == null) {
+        return null;  // Convert undefined to null.
+      } else if (typeof(message) == 'string' ||
+                 typeof(message) == 'number' ||
+                 typeof(message) == 'boolean') {
+        return message;
+      } else if (message instanceof Array) {
+        return checkedSerialization(message, function(id) {
+          var values = new Array(message.length);
+          for (var i = 0; i < message.length; i++) {
+            values[i] = doSerialize(message[i]);
+          }
+          return [ 'list', id, values ];
+        });
+      } else if (message instanceof LocalSendPortSync) {
+        return [ 'sendport', 'nativejs', message.receivePort.id ];
+      } else if (message instanceof DartSendPortSync) {
+        return [ 'sendport', 'dart', message.isolateId, message.portId ];
+      } else {
+        return checkedSerialization(message, function(id) {
+          var keys = Object.getOwnPropertyNames(message);
+          var values = new Array(keys.length);
+          for (var i = 0; i < keys.length; i++) {
+            values[i] = doSerialize(message[keys[i]]);
+          }
+          return [ 'map', id, keys, values ];
+        });
+      }
+    }
+    return doSerialize(message);
+  }
+
+  function deserialize(message) {
+    return deserializeHelper(message);
+  }
+
+  function deserializeHelper(message) {
+    if (message == null ||
+        typeof(message) == 'string' ||
+        typeof(message) == 'number' ||
+        typeof(message) == 'boolean') {
+      return message;
+    }
+    switch (message[0]) {
+      case 'map': return deserializeMap(message);
+      case 'sendport': return deserializeSendPort(message);
+      case 'list': return deserializeList(message);
+      default: throw 'unimplemented';
+    }
+  }
+
+  function deserializeMap(message) {
+    var result = { };
+    var id = message[1];
+    var keys = message[2];
+    var values = message[3];
+    for (var i = 0, length = keys.length; i < length; i++) {
+      var key = deserializeHelper(keys[i]);
+      var value = deserializeHelper(values[i]);
+      result[key] = value;
+    }
+    return result;
+  }
+
+  function deserializeSendPort(message) {
+    var tag = message[1];
+    switch (tag) {
+      case 'nativejs':
+        var id = message[2];
+        return new LocalSendPortSync(ReceivePortSync.map[id]);
+      case 'dart':
+        var isolateId = message[2];
+        var portId = message[3];
+        return new DartSendPortSync(isolateId, portId);
+      default:
+        throw 'Illegal SendPortSync type: $tag';
+    }
+  }
+
+  function deserializeList(message) {
+    var values = message[2];
+    var length = values.length;
+    var result = new Array(length);
+    for (var i = 0; i < length; i++) {
+      result[i] = deserializeHelper(values[i]);
+    }
+    return result;
+  }
+
+  window.registerPort = function(name, port) {
+    var stringified = JSON.stringify(serialize(port));
+    var attrName = 'dart-port:' + name;
+    document.documentElement.setAttribute(attrName, stringified);
+  };
+
+  window.lookupPort = function(name) {
+    var attrName = 'dart-port:' + name;
+    var stringified = document.documentElement.getAttribute(attrName);
+    return deserialize(JSON.parse(stringified));
+  };
+
+  ReceivePortSync.id = 0;
+  ReceivePortSync.map = {};
+
+  ReceivePortSync.dispatchCall = function(id, message) {
+    // TODO(vsm): Handle and propagate exceptions.
+    var deserialized = deserialize(message);
+    var result = ReceivePortSync.map[id].callback(deserialized);
+    return serialize(result);
+  };
+
+  ReceivePortSync.prototype.receive = function(callback) {
+    this.callback = callback;
+  };
+
+  ReceivePortSync.prototype.toSendPort = function() {
+    return new LocalSendPortSync(this);
+  };
+
+  ReceivePortSync.prototype.close = function() {
+    delete ReceivePortSync.map[this.id];
+  };
+
+  if (navigator.webkitStartDart) {
+    window.addEventListener('js-sync-message', function(event) {
+      var data = JSON.parse(getPortSyncEventData(event));
+      var deserialized = deserialize(data.message);
+      var result = ReceivePortSync.map[data.id].callback(deserialized);
+      // TODO(vsm): Handle and propagate exceptions.
+      dispatchEvent('js-result', serialize(result));
+    }, false);
+  }
+
+  function LocalSendPortSync(receivePort) {
+    this.receivePort = receivePort;
+  }
+
+  LocalSendPortSync.prototype = new SendPortSync();
+
+  LocalSendPortSync.prototype.callSync = function(message) {
+    // TODO(vsm): Do a direct deepcopy.
+    message = deserialize(serialize(message));
+    return this.receivePort.callback(message);
+  }
+
+  function DartSendPortSync(isolateId, portId) {
+    this.isolateId = isolateId;
+    this.portId = portId;
+  }
+
+  DartSendPortSync.prototype = new SendPortSync();
+
+  function dispatchEvent(receiver, message) {
+    var string = JSON.stringify(message);
+    var event = document.createEvent('CustomEvent');
+    event.initCustomEvent(receiver, false, false, string);
+    window.dispatchEvent(event);
+  }
+
+  function getPortSyncEventData(event) {
+    return event.detail;
+  }
+
+  DartSendPortSync.prototype.callSync = function(message) {
+    var serialized = serialize(message);
+    var target = 'dart-port-' + this.isolateId + '-' + this.portId;
+    // TODO(vsm): Make this re-entrant.
+    // TODO(vsm): Set this up set once, on the first call.
+    var source = target + '-result';
+    var result = null;
+    var listener = function (e) {
+      result = JSON.parse(getPortSyncEventData(e));
+    };
+    window.addEventListener(source, listener, false);
+    dispatchEvent(target, [source, serialized]);
+    window.removeEventListener(source, listener, false);
+    return deserialize(result);
+  }
+})();
diff --git a/runtime/bin/vmstats/vmstats.css b/runtime/bin/vmstats/vmstats.css
new file mode 100644
index 0000000..3757344
--- /dev/null
+++ b/runtime/bin/vmstats/vmstats.css
@@ -0,0 +1,46 @@
+
+body {
+  background-color: #F8F8F8;
+  font-family: 'Open Sans', sans-serif;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 1.2em;
+  margin: 15px;
+}
+
+h1, p {
+  color: #333;
+}
+
+#vmstats {
+  width: 100%;
+  height: 500px;
+  position: relative;
+  border: 1px solid #ccc;
+  background-color: #fff;
+  padding: 10px;
+}
+
+#dashboard {
+  font-size: 12pt;
+  text-align: left;
+  margin: 20px;
+}
+
+#graph {
+  font-size: 12pt;
+  text-align: left;
+}
+
+.isolate_list {
+  font-family: 'Open Sans', sans-serif;
+  font-size: 14px;
+}
+
+.isolate_details {
+  visibility:visible;
+}
+
+.isolate_details_hidden {
+  visibility:hidden;
+}
diff --git a/runtime/bin/vmstats/vmstats.dart b/runtime/bin/vmstats/vmstats.dart
new file mode 100644
index 0000000..3c2f6c3
--- /dev/null
+++ b/runtime/bin/vmstats/vmstats.dart
@@ -0,0 +1,59 @@
+// 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 dart.vmstats;
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:json' as JSON;
+
+part 'bargraph.dart';
+part 'isolate_list.dart';
+part 'models.dart';
+
+BarGraph _graph;
+IsolateList _isolateList;
+DivElement _statusText;
+IsolateListModel _isolates;
+Timer _updater;
+
+final int _POLL_INTERVAL = const Duration(seconds: 1);
+
+void main() {
+  DivElement dashBoard = query('#dashboard');
+  CanvasElement canvas = query('#graph');
+  var elements = [ new Element("Old Space", "#97FFFF"),
+                   new Element("New Space", "#00EE76")];
+  _graph = new BarGraph(canvas, elements);
+  UListElement isolateListElement = query('#isolateList');
+  _isolateList = new IsolateList(isolateListElement);
+  _statusText = query('#statusText');
+
+  _isolates = new IsolateListModel();
+  _isolates.addListener(onUpdateStatus, onRequestFailed);
+  _isolates.update();
+  _updater = new Timer.periodic(_POLL_INTERVAL, (timer) => _isolates.update());
+}
+
+void onUpdateStatus(IsolateListModel model) {
+  int oldSpace = 0;
+  int newSpace = 0;
+  model.forEach((Isolate element) {
+    oldSpace += element.oldSpace.used;
+    newSpace += element.newSpace.used;
+  });
+  _graph.addSample([oldSpace, newSpace]);
+  _isolateList.updateList(model);
+  showStatus('Running ...');
+}
+
+void onRequestFailed() {
+  _updater.cancel();
+  _isolates.removeListener(onUpdateStatus);
+  showStatus('Server closed');
+}
+
+void showStatus(status) {
+  _statusText.text = status;
+}
diff --git a/runtime/bin/vmstats/vmstats.html b/runtime/bin/vmstats/vmstats.html
new file mode 100644
index 0000000..5ad19aa
--- /dev/null
+++ b/runtime/bin/vmstats/vmstats.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- 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.
+-->
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>VM Stats</title>
+    <link rel="stylesheet" href="vmstats.css">
+    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
+  </head>
+  <body>
+    <h1>VM Stats</h1>
+    <div id="vmstats">
+      <p id="dashboard">
+        <h3>Allocated Memory</h3>
+        <canvas id="graph" width="480px" height="240px"></canvas>
+        <h3>Isolates</h3>
+        <ul id="isolateList"></ul>
+      </p>
+    </div>
+    <div id="statusSection">
+      <p id="statusText"></p>
+    </div>
+
+    <script type="application/dart" src="vmstats.dart"></script>
+    <script src="packages/browser/dart.js"></script>
+  </body>
+</html>
diff --git a/runtime/bin/vmstats_impl.cc b/runtime/bin/vmstats_impl.cc
index e7e2812..90e3d53 100644
--- a/runtime/bin/vmstats_impl.cc
+++ b/runtime/bin/vmstats_impl.cc
@@ -9,6 +9,7 @@
 #include "bin/file.h"
 #include "bin/log.h"
 #include "bin/platform.h"
+#include "bin/resources.h"
 #include "bin/socket.h"
 #include "bin/thread.h"
 #include "bin/utils.h"
@@ -132,6 +133,59 @@
 }
 
 
+// Return a malloc'd string from a format string and arguments.
+intptr_t alloc_printf(char** result, const char* format, ...) {
+  va_list args;
+  va_start(args, format);
+  intptr_t len = vsnprintf(NULL, 0, format, args) + 1;
+  *result = reinterpret_cast<char*>(malloc(len));
+  return vsnprintf(*result, len, format, args);
+}
+
+
+void writeResponse(intptr_t socket, const char* content_type,
+                   const char* data, size_t length) {
+  char* header;
+  intptr_t len = alloc_printf(&header,
+      "HTTP/1.1 200 OK\nContent-Type: %s\nContent-Length: %"Pu"\n\n",
+      content_type, length);
+  Socket::Write(socket, header, len);
+  Socket::Write(socket, data, length);
+  Socket::Write(socket, "\n", 1);
+  free(header);
+}
+
+
+void writeErrorResponse(intptr_t socket, intptr_t error_num, const char* error,
+                        const char* description) {
+  if (description != NULL) {
+    // Create body first, so its length is known when creating the header.
+    char* body;
+    intptr_t body_len = alloc_printf(&body,
+        "<html><head><title>%d %s</title></head>\n"
+        "<body>\n<h1>%s</h1>\n%s\n</body></html>\n",
+        error_num, error, error, description);
+    char* header;
+    intptr_t header_len = alloc_printf(&header,
+        "HTTP/1.1 %d %s\n"
+        "Content-Length: %d\n"
+        "Connection: close\n"
+        "Content-Type: text/html\n\n",
+        error_num, error, body_len);
+    Socket::Write(socket, header, header_len);
+    Socket::Write(socket, body, body_len);
+    free(header);
+    free(body);
+  } else {
+    char* response;
+    intptr_t len =
+        alloc_printf(&response, "HTTP/1.1 %d %s\n\n", error_num, error);
+    Socket::Write(socket, response, len);
+    free(response);
+  }
+}
+
+
 void VmStats::WebServer(uword bind_address) {
   while (true) {
     intptr_t socket = ServerSocket::Accept(bind_address);
@@ -167,14 +221,8 @@
     // TODO(tball): support POST requests.
     if (strncmp("GET ", buffer, 4) != 0 && strncmp("get ", buffer, 4) != 0) {
       Log::PrintErr("Unsupported HTTP request type");
-      const char* response = "HTTP/1.1 403 Forbidden\n"
-          "Content-Length: 120\n"
-          "Connection: close\n"
-          "Content-Type: text/html\n\n"
-          "<html><head>\n<title>403 Forbidden</title>\n</head>"
-          "<body>\n<h1>Forbidden</h1>\nUnsupported HTTP request type\n</body>"
-          "</html>\n";
-      Socket::Write(socket, response, strlen(response));
+      writeErrorResponse(socket, 403, "Forbidden",
+                         "Unsupported HTTP request type");
       Socket::Close(socket);
       continue;
     }
@@ -186,7 +234,7 @@
         buffer[i] = '\0';
       }
     }
-    char* url = &buffer[4];
+    char* url = strdup(&buffer[4]);
 
     Log::Print("vmstats: %s requested\n", url);
     char* content = NULL;
@@ -200,15 +248,7 @@
     }
 
     if (content != NULL) {
-      size_t content_len = strlen(content);
-      len = snprintf(buffer, BUFSIZE,
-          "HTTP/1.1 200 OK\nContent-Type: application/json; charset=UTF-8\n"
-          "Content-Length: %"Pu"\n\n",
-          content_len);
-      Socket::Write(socket, buffer, strlen(buffer));
-      Socket::Write(socket, content, content_len);
-      Socket::Write(socket, "\n", 1);
-      Socket::Write(socket, buffer, strlen(buffer));
+      writeResponse(socket, "application/json", content, strlen(content));
       free(content);
     } else {
       // No status content with this URL, return file or resource content.
@@ -223,34 +263,39 @@
       }
 
       bool success = false;
+      char* text_buffer = NULL;
+      const char* content_type = ContentType(path.c_str());
       if (File::Exists(path.c_str())) {
         File* f = File::Open(path.c_str(), File::kRead);
         if (f != NULL) {
           intptr_t len = f->Length();
-          char* text_buffer = reinterpret_cast<char*>(malloc(len));
+          text_buffer = reinterpret_cast<char*>(malloc(len));
           if (f->ReadFully(text_buffer, len)) {
-            const char* content_type = ContentType(path.c_str());
-            snprintf(buffer, BUFSIZE,
-                "HTTP/1.1 200 OK\nContent-Type: %s\n"
-                "Content-Length: %"Pu"\n\n",
-                content_type, len);
-            Socket::Write(socket, buffer, strlen(buffer));
-            Socket::Write(socket, text_buffer, len);
-            Socket::Write(socket, "\n", 1);
+            writeResponse(socket, content_type, text_buffer, len);
             success = true;
           }
           free(text_buffer);
           delete f;
         }
       } else {
-        // TODO(tball): look up linked in resource.
+        const char* resource;
+        intptr_t len = Resources::ResourceLookup(path.c_str(), &resource);
+        if (len != Resources::kNoSuchInstance) {
+          ASSERT(len >= 0);
+          writeResponse(socket, content_type, resource, len);
+          success = true;
+        }
       }
       if (!success) {
-        const char* response = "HTTP/1.1 404 Not Found\n\n";
-        Socket::Write(socket, response, strlen(response));
+        char* description;
+        alloc_printf(
+            &description, "URL <a href=\"%s\">%s</a> not found.", url, url);
+        writeErrorResponse(socket, 404, "Not Found", description);
+        free(description);
       }
     }
     Socket::Close(socket);
+    free(url);
   }
 
   Shutdown();
diff --git a/runtime/bin/vmstats_sources.gypi b/runtime/bin/vmstats_sources.gypi
new file mode 100644
index 0000000..5344f5e
--- /dev/null
+++ b/runtime/bin/vmstats_sources.gypi
@@ -0,0 +1,17 @@
+# Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# This file contains all sources for the vmstats application.
+{
+  'sources': [
+    'vmstats/bargraph.dart',
+    'vmstats/favicon.ico',
+    'vmstats/isolate_list.dart',
+    'vmstats/models.dart',
+    'vmstats/packages/browser/dart.js',
+    'vmstats/vmstats.css',
+    'vmstats/vmstats.dart',
+    'vmstats/vmstats.html',
+  ],
+}
diff --git a/runtime/embedders/openglui/android/eventloop.cc b/runtime/embedders/openglui/android/eventloop.cc
index ea536fe..b247008 100644
--- a/runtime/embedders/openglui/android/eventloop.cc
+++ b/runtime/embedders/openglui/android/eventloop.cc
@@ -335,10 +335,15 @@
   /* Get the time this event occurred, in the
    * java.lang.System.nanoTime() time base. */
   int64_t when = AKeyEvent_getEventTime(event);
+  bool isAltKeyDown = (meta_state & AMETA_ALT_ON) != 0;
+  bool isShiftKeyDown = (meta_state & AMETA_SHIFT_ON) != 0;
+  bool isCtrlKeyDown = key_code < 32;
 
   LOGI("Got key event %d %d", type, key_code);
-  if (input_handler_->OnKeyEvent(key_event, when, flags, key_code,
-                             meta_state, repeat) != 0) {
+
+  if (input_handler_->OnKeyEvent(key_event, when, key_code,
+                                 isAltKeyDown, isCtrlKeyDown, isShiftKeyDown,
+                                 repeat) != 0) {
     return false;
   }
   return true;
diff --git a/runtime/embedders/openglui/common/canvas_state.cc b/runtime/embedders/openglui/common/canvas_state.cc
index beef8b5..16232b9 100644
--- a/runtime/embedders/openglui/common/canvas_state.cc
+++ b/runtime/embedders/openglui/common/canvas_state.cc
@@ -97,7 +97,6 @@
   SkTypeface *pTypeface = SkTypeface::CreateFromName(name, SkTypeface::kNormal);
   paint_.setTypeface(pTypeface);
   paint_.setTextSize(size);
-  pTypeface->unref();
   // TODO(gram): Must return a normalized font name incorporating size, so
   // callers can set the Dart canvas font name to an appropriate value.
   // Actually this may not be necessary in which case we can change this
diff --git a/runtime/embedders/openglui/common/gl.dart b/runtime/embedders/openglui/common/gl.dart
index 1cb506d..8b0dc60 100644
--- a/runtime/embedders/openglui/common/gl.dart
+++ b/runtime/embedders/openglui/common/gl.dart
@@ -3,8 +3,305 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library android_extension;
+import 'dart:async';
 
-class CanvasElement {
+// A VERY simplified DOM.
+
+class BodyElement {
+  List _nodes;
+  get nodes => _nodes;
+  BodyElement() : _nodes = new List();
+}
+
+// The OpenGLUI "equivalent" of Window.
+
+typedef void RequestAnimationFrameCallback(num highResTime);
+
+class Window {
+  static int _nextId = 0;
+  Map<int, RequestAnimationFrameCallback> _callbacks;
+
+  Window._internal() : _callbacks = new Map();
+
+  int requestAnimationFrame(RequestAnimationFrameCallback callback) {
+    _callbacks[_nextId++] = callback;
+  }
+  void cancelAnimationFrame(id) {
+    if (_callbacks.containsKey(id)) {
+      _callbacks.remove(id);
+    }
+  }
+  get animationFrame {
+    // TODO(gram)
+    return null;
+  }
+
+  void _dispatch() {
+    var when = (new DateTime.now()).millisecondsSinceEpoch;
+    // We clear out the callbacks map before calling any callbacks,
+    // as they may schedule new callbacks.
+    var oldcallbacks = _callbacks;
+    _callbacks = new Map();
+    for (var c in oldcallbacks.values) {
+      c(when);
+    }
+  }
+}
+
+Window window = new Window._internal();
+
+// The OpenGLUI "equivalent" of HtmlDocument.
+class Document {
+  BodyElement _body;
+  get body => _body;
+  Document._internal() : _body = new BodyElement();
+}
+
+Document document = new Document._internal();
+
+// TODO(gram): make private and call from within library context.
+update_() {
+  window._dispatch();
+}
+
+// Event handling. This is very kludgy for now, especially the
+// bare-bones Stream stuff!
+
+typedef void EventListener(Event event);
+
+class EventTarget {
+  static Map<EventTarget, Map<String, List<EventListener>>>
+      _listeners = new Map();
+
+  static get listeners => _listeners;
+
+  bool dispatchEvent(Event event) {
+    if (!_listeners.containsKey(this)) return false;
+    var listeners = _listeners[this];
+    if (!listeners.containsKey(event.type)) return false;
+    var eventListeners = listeners[event.type];
+    for (var eventListener in eventListeners) {
+      if (eventListener != null) {
+        eventListener(event);
+      }
+    }
+    return true;
+  }
+
+  void addListener(String eventType, EventListener handler) {
+    if (!_listeners.containsKey(this)) {
+      _listeners[this] = new Map();
+    }
+    var listeners = _listeners[this];
+    if (!listeners.containsKey(eventType)) {
+      listeners[eventType] = new List();
+    }
+    var event_listeners = listeners[eventType];
+    for (var i = 0; i < event_listeners.length; i++) {
+      if (event_listeners[i] == null) {
+        event_listeners[i] = handler;
+        return;
+      }
+    }
+    event_listeners.add(handler);
+  }
+
+  void removeListener(String eventType, EventListener handler) {
+    if (_listeners.containsKey(this)) {
+      var listeners = _listeners[this];
+      if (listeners.containsKey(eventType)) {
+        var event_listeners = listeners[eventType];
+        for (var i = 0; i < event_listeners.length; i++) {
+          if (event_listeners[i] == handler) {
+            event_listeners[i] = null;
+            break;
+          }
+        }
+      }
+    }
+  }
+}
+
+class Event {
+  final String type;
+  EventTarget target;
+  Event(String type) : this.type = type;
+}
+
+class KeyEvent extends Event {
+  final bool altKey;
+  final bool ctrlKey;
+  final bool shiftKey;
+  final int keyCode;
+
+  KeyEvent(String type, int keycode, bool alt, bool ctrl, bool shift) 
+    : super(type),
+      keyCode = keycode,
+      altKey = alt,
+      ctrlKey = ctrl,
+      shiftKey = shift {
+  }
+}
+
+class MouseEvent extends Event {
+  final int screenX, screenY;
+  final int clientX, clientY;
+
+  MouseEvent(String type, int x, int y)
+    : super(type),
+      screenX = x,
+      screenY = y,
+      clientX = x,
+      clientY = y {
+  }
+}
+
+
+class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
+  int _pauseCount = 0;
+  EventTarget _target;
+  final String _eventType;
+  var _onData;
+
+  _EventStreamSubscription(this._target, this._eventType, this._onData) {
+    _tryResume();
+  }
+
+  void cancel() {
+    if (_canceled) {
+      throw new StateError("Subscription has been canceled.");
+    }
+
+    _unlisten();
+    // Clear out the target to indicate this is complete.
+    _target = null;
+    _onData = null;
+  }
+
+  bool get _canceled => _target == null;
+
+  void onData(void handleData(T event)) {
+    if (_canceled) {
+      throw new StateError("Subscription has been canceled.");
+    }
+    // Remove current event listener.
+    _unlisten();
+
+    _onData = handleData
+    _tryResume();
+  }
+
+  /// Has no effect.
+  void onError(void handleError(AsyncError error)) {}
+
+  /// Has no effect.
+  void onDone(void handleDone()) {}
+
+  void pause([Future resumeSignal]) {
+    if (_canceled) {
+      throw new StateError("Subscription has been canceled.");
+    }
+    ++_pauseCount;
+    _unlisten();
+
+    if (resumeSignal != null) {
+      resumeSignal.whenComplete(resume);
+    }
+  }
+
+  bool get _paused => _pauseCount > 0;
+
+  void resume() {
+    if (_canceled) {
+      throw new StateError("Subscription has been canceled.");
+    }
+    if (!_paused) {
+      throw new StateError("Subscription is not paused.");
+    }
+    --_pauseCount;
+    _tryResume();
+  }
+
+  void _tryResume() {
+    if (_onData != null && !_paused) {
+      _target.addListener(_eventType, _onData);
+    }
+  }
+
+  void _unlisten() {
+    if (_onData != null) {
+      _target.removeListener(_eventType, _onData);
+    }
+  }
+}
+
+class _EventStream<T extends Event> extends Stream<T> {
+  final Object _target;
+  final String _eventType;
+
+  _EventStream(this._target, this._eventType);
+
+  // DOM events are inherently multi-subscribers.
+  Stream<T> asBroadcastStream() => this;
+  bool get isBroadcast => true;
+
+  StreamSubscription<T> listen(void onData(T event),
+      { void onError(AsyncError error),
+      void onDone(),
+      bool unsubscribeOnError}) {
+
+    return new _EventStreamSubscription<T>(
+        this._target, this._eventType, onData);
+  }
+}
+
+class Node extends EventTarget {
+  Stream<KeyEvent> get onKeyDown => new _EventStream(this, 'keydown');
+  Stream<KeyEvent> get onKeyUp => new _EventStream(this, 'keyup');
+  Stream<MouseEvent> get onMouseDown => new _EventStream(this, 'mousedown');
+  Stream<MouseEvent> get onMouseMove => new _EventStream(this, 'mousemove');
+  Stream<MouseEvent> get onMouseUp => new _EventStream(this, 'mouseup');
+}
+
+// TODO(gram): If we support more than one on-screen canvas, we will
+// need to filter dispatched mouse and key events by the target Node
+// with more granularity; right now we just iterate through DOM nodes
+// until we find one that handles the event.
+_dispatchEvent(Event event) {
+  assert(document.body.nodes.length <= 1);
+  for (var target in document.body.nodes) {
+    event.target = target;
+    if (target.dispatchEvent(event)) {
+      break;
+    }
+  }
+}
+
+_dispatchKeyEvent(String type, int keyCode, bool alt, bool ctrl, bool shift) {
+  _dispatchEvent(new KeyEvent(type, keyCode, alt, ctrl, shift));
+}
+
+_dispatchMouseEvent(String type, double x, double y) {
+  _dispatchEvent(new MouseEvent(type, x.toInt(), y.toInt()));
+}
+
+// These next few are called by vmglue.cc.
+onKeyDown_(int when, int keyCode, bool alt, bool ctrl, bool shift, int repeat)
+    =>  _dispatchKeyEvent('keydown', keyCode, alt, ctrl, shift);
+
+onKeyUp_(int when, int keyCode, bool alt, bool ctrl, bool shift, int repeat) =>
+    _dispatchKeyEvent('keyup', keyCode, alt, ctrl, shift);
+
+onMouseDown_(int when, double x, double y) =>
+    _dispatchMouseEvent('mousedown', x, y);
+
+onMouseMove_(int when, double x, double y) =>
+    _dispatchMouseEvent('mousemove', x, y);
+
+onMouseUp_(int when, double x, double y) =>
+    _dispatchMouseEvent('mouseup', x, y);
+
+class CanvasElement extends Node {
   int _height;
   int _width;
 
@@ -19,7 +316,8 @@
   // code.
   get src => "context2d://${_context2d.handle}";
 
-  CanvasElement({int width, int height}) {
+  CanvasElement({int width, int height})
+    : super() {
     _width = (width == null) ? getDeviceScreenWidth() : width;
     _height = (height == null) ? getDeviceScreenHeight() : height;
   }
@@ -348,15 +646,9 @@
 void C2DCreateNativeContext(int handle, int width, int height)
     native "C2DCreateNativeContext";
 
-class ElementEvents {
-  final List load;
-  ElementEvents()
-    : load =new List() {
-  }
-}
+class ImageElement extends Node {
+  Stream<Event> get onLoad => new _EventStream(this, 'load');
 
-class ImageElement {
-  ElementEvents on;
   String _src;
   int _width;
   int _height;
@@ -364,9 +656,9 @@
   get src => _src;
   set src(String v) {
     _src = v;
-    for (var e in on.load) {
-      e(this);
-    }
+    var e = new Event('load');
+    e.target = this;
+    dispatchEvent(e);
   }
 
   get width => _width;
@@ -376,8 +668,7 @@
   set height(int heightp) => _height = heightp;
 
   ImageElement({String srcp, int widthp, int heightp})
-    : on = new ElementEvents(),
-      _src = srcp,
+    : _src = srcp,
       _width = widthp,
       _height = heightp {
   }
diff --git a/runtime/embedders/openglui/common/input_handler.cc b/runtime/embedders/openglui/common/input_handler.cc
index 6213de7..7ffef44 100644
--- a/runtime/embedders/openglui/common/input_handler.cc
+++ b/runtime/embedders/openglui/common/input_handler.cc
@@ -14,55 +14,59 @@
                                 float x,
                                 float y) {
   const char *function = NULL;
+  // For now we just keep this simple. There are
+  // no click events or mouseover events.
   switch (event) {
     case kMotionDown:
-      function = "onMotionDown";
+      function = "onMouseDown_";
       break;
     case kMotionUp:
-      function = "onMotionUp";
+      function = "onMouseUp_";
       break;
     case kMotionMove:
-      function = "onMotionMove";
+      function = "onMouseMove_";
       break;
     case kMotionCancel:
-      function = "onMotionCancel";
       break;
     case kMotionOutside:
-      function = "onMotionOutside";
       break;
     case kMotionPointerDown:
-      function = "onMotionPointerDown";
       break;
     case kMotionPointerUp:
-      function = "onMotionPointerUp";
       break;
     default:
       return -1;
   }
-  return vm_glue_->OnMotionEvent(function, when, x, y);
+  if (function == NULL) {
+    return 0;
+  } else {
+    return vm_glue_->OnMotionEvent(function, when, x, y);
+  }
 }
 
 int InputHandler::OnKeyEvent(KeyEvent event,
                              int64_t when,
-                             int32_t flags,
                              int32_t key_code,
-                             int32_t meta_state,
+                             bool isAltKeyDown,
+                             bool isCtrlKeyDown,
+                             bool isShiftKeyDown,
                              int32_t repeat) {
   const char *function = NULL;
   switch (event) {
     case kKeyDown:
-      function = "onKeyDown";
+      function = "onKeyDown_";
       break;
     case kKeyUp:
-      function = "onKeyUp";
+      function = "onKeyUp_";
       break;
     case kKeyMultiple:
-      function = "onKeyMultiple";
+      return -1;  // TODO(gram): handle this.
       break;
     default:
       return -1;
   }
-  return vm_glue_->OnKeyEvent(function, when, flags, key_code,
-                              meta_state, repeat);
+  return vm_glue_->OnKeyEvent(function, when, key_code,
+                              isAltKeyDown, isCtrlKeyDown, isShiftKeyDown,
+                              repeat);
 }
 
diff --git a/runtime/embedders/openglui/common/input_handler.h b/runtime/embedders/openglui/common/input_handler.h
index 2750d39..521fe65 100644
--- a/runtime/embedders/openglui/common/input_handler.h
+++ b/runtime/embedders/openglui/common/input_handler.h
@@ -15,8 +15,9 @@
     virtual void Stop() { }
     virtual int OnMotionEvent(MotionEvent event, int64_t when,
                     float move_x, float move_y);
-    virtual int OnKeyEvent(KeyEvent event, int64_t when, int32_t flags,
-             int32_t key_code, int32_t meta_state, int32_t repeat);
+    virtual int OnKeyEvent(KeyEvent event, int64_t when, int32_t key_code,
+                           bool isAltKeyDown, bool isCtrlKeyDown,
+                           bool isShiftKeyDown, int32_t repeat);
     virtual ~InputHandler() {}
 
   protected:
diff --git a/runtime/embedders/openglui/common/opengl.h b/runtime/embedders/openglui/common/opengl.h
index fb844fe..1daaa86 100644
--- a/runtime/embedders/openglui/common/opengl.h
+++ b/runtime/embedders/openglui/common/opengl.h
@@ -42,6 +42,7 @@
 #include "core/SkCanvas.h"
 #include "core/SkGraphics.h"
 #include "core/SkPaint.h"
+#include "core/SkTypeface.h"
 #include "effects/SkBlurDrawLooper.h"
 #include "effects/SkDashPathEffect.h"
 #include "gpu/SkGpuDevice.h"
diff --git a/runtime/embedders/openglui/common/vm_glue.cc b/runtime/embedders/openglui/common/vm_glue.cc
index 39ee799..b014d1d 100644
--- a/runtime/embedders/openglui/common/vm_glue.cc
+++ b/runtime/embedders/openglui/common/vm_glue.cc
@@ -16,6 +16,7 @@
 #include "include/dart_api.h"
 
 char* VMGlue::extension_script_ = NULL;
+bool VMGlue::initialized_vm_ = false;
 
 // snapshot_buffer points to a snapshot if we link in a snapshot otherwise
 // it is initialized to NULL.
@@ -26,7 +27,6 @@
                const char* main_script)
     : surface_(surface),
       isolate_(NULL),
-      initialized_vm_(false),
       initialized_script_(false) {
   LOGI("Creating VMGlue");
   if (main_script == NULL) {
@@ -237,7 +237,7 @@
   if (initialized_script_) {
     Dart_EnterIsolate(isolate_);
     Dart_EnterScope();
-    int rtn = Invoke("update", 0, 0);
+    int rtn = Invoke("update_", 0, 0);
     Dart_ExitScope();
     Dart_ExitIsolate();
     return rtn;
@@ -276,19 +276,21 @@
   return -1;
 }
 
-int VMGlue::OnKeyEvent(const char* function, int64_t when, int32_t flags,
-       int32_t key_code, int32_t meta_state, int32_t repeat) {
+int VMGlue::OnKeyEvent(const char* function, int64_t when, int32_t key_code,
+                       bool isAltKeyDown, bool isCtrlKeyDown,
+                       bool isShiftKeyDown, int32_t repeat) {
   if (initialized_script_) {
     LOGI("Invoking %s", function);
     Dart_EnterIsolate(isolate_);
     Dart_EnterScope();
-    Dart_Handle args[5];
+    Dart_Handle args[6];
     args[0] = CheckError(Dart_NewInteger(when));
-    args[1] = CheckError(Dart_NewInteger(flags));
-    args[2] = CheckError(Dart_NewInteger(key_code));
-    args[3] = CheckError(Dart_NewInteger(meta_state));
-    args[4] = CheckError(Dart_NewInteger(repeat));
-    int rtn = Invoke(function, 5, args, false);
+    args[1] = CheckError(Dart_NewInteger(key_code));
+    args[2] = CheckError(Dart_NewBoolean(isAltKeyDown));
+    args[3] = CheckError(Dart_NewBoolean(isCtrlKeyDown));
+    args[4] = CheckError(Dart_NewBoolean(isShiftKeyDown));
+    args[5] = CheckError(Dart_NewInteger(repeat));
+    int rtn = Invoke(function, 6, args, false);
     Dart_ExitScope();
     Dart_ExitIsolate();
     LOGI("Done %s", function);
diff --git a/runtime/embedders/openglui/common/vm_glue.h b/runtime/embedders/openglui/common/vm_glue.h
index 72db660..76e2270 100644
--- a/runtime/embedders/openglui/common/vm_glue.h
+++ b/runtime/embedders/openglui/common/vm_glue.h
@@ -29,8 +29,9 @@
   int CallShutdown();
   int OnMotionEvent(const char* funtion, int64_t when,
                     float move_x, float move_y);
-  int OnKeyEvent(const char* funtion, int64_t when, int32_t flags,
-             int32_t key_code, int32_t meta_state, int32_t repeat);
+  int OnKeyEvent(const char* funtion, int64_t when, int32_t key_code,
+                 bool isAltKeyDown, bool isCtrlKeyDown, bool isShiftKeyDown,
+                 int32_t repeat);
   void FinishMainIsolate();
 
  private:
@@ -52,9 +53,9 @@
   static Dart_Handle LoadSourceFromFile(const char* url);
   static void ShutdownIsolate(void* callback_data);
 
+  static bool initialized_vm_;
   ISized* surface_;
   Dart_Isolate isolate_;
-  bool initialized_vm_;
   bool initialized_script_;
   char* main_script_;
   static char* extension_script_;
diff --git a/runtime/embedders/openglui/emulator/emulator_embedder.cc b/runtime/embedders/openglui/emulator/emulator_embedder.cc
index 01c5188..831f1e8 100644
--- a/runtime/embedders/openglui/emulator/emulator_embedder.cc
+++ b/runtime/embedders/openglui/emulator/emulator_embedder.cc
@@ -53,8 +53,8 @@
 }
 
 void keyboard(unsigned char key, int x, int y) {
-  input_handler_ptr->OnKeyEvent(kKeyDown, time(0), 0, key, 0, 0);
-  input_handler_ptr->OnKeyEvent(kKeyUp, time(0), 0, key, 0, 0);
+  input_handler_ptr->OnKeyEvent(kKeyDown, time(0), key, false, false, false, 0);
+  input_handler_ptr->OnKeyEvent(kKeyUp, time(0), key, false, false, false, 0);
   if (key == 27) {
     lifecycle_handler_ptr->Pause();
     lifecycle_handler_ptr->Deactivate();
@@ -77,6 +77,18 @@
   }
 }
 
+void mouse(int button, int state, int x, int y) {
+  if (state == GLUT_UP) {
+    input_handler_ptr->OnMotionEvent(kMotionUp, time(0), x, y);
+  } else if (state == GLUT_DOWN) {
+    input_handler_ptr->OnMotionEvent(kMotionDown, time(0), x, y);
+  }
+}
+
+void motion(int x, int y) {
+  input_handler_ptr->OnMotionEvent(kMotionMove, time(0), x, y);
+}
+
 DART_EXPORT void emulator_main(int argc, char** argv, const char* script) {
   EmulatorGraphicsHandler graphics_handler(argc, argv);
   if (argc > 0) {
@@ -102,6 +114,8 @@
   glutReshapeFunc(reshape);
   glutDisplayFunc(display);
   glutKeyboardFunc(keyboard);
+  glutMouseFunc(mouse);
+  glutMotionFunc(motion);
   lifecycle_handler_ptr->OnStart();
   lifecycle_handler_ptr->Activate();
   lifecycle_handler_ptr->Resume();
diff --git a/runtime/include/dart_debugger_api.h b/runtime/include/dart_debugger_api.h
index 5d71e4d..319b773 100755
--- a/runtime/include/dart_debugger_api.h
+++ b/runtime/include/dart_debugger_api.h
@@ -128,22 +128,6 @@
 
 
 /**
- * DEPRECATED --- use Dart_ScriptGetSource
- *
- * Returns a string containing the source code of the given script
- * in the given library.
- *
- * Requires there to be a current isolate.
- *
- * \return A handle to string containing the source text if no error
- * occurs.
- */
-DART_EXPORT Dart_Handle Dart_GetScriptSource(
-                            Dart_Handle library_url_in,
-                            Dart_Handle script_url_in);
-
-
-/**
  * Returns a string containing the source code of the given script
  * in the given library.
  *
@@ -158,6 +142,20 @@
 
 
 /**
+ * Returns a string containing a generated source code of the given script
+ * in the given library. This is essentially used to pretty print dart code
+ * generated from any tool (e.g: dart2dart).
+ *
+ * Requires there to be a current isolate.
+ *
+ * \return A handle to string containing the source text if no error
+ * occurs.
+ */
+DART_EXPORT Dart_Handle Dart_GenerateScriptSource(Dart_Handle library_url_in,
+                                                  Dart_Handle script_url_in);
+
+
+/**
  * Sets a breakpoint at line \line_number in \script_url, or the closest
  * following line (within the same function) where a breakpoint can be set.
  *
diff --git a/runtime/lib/array.dart b/runtime/lib/array.dart
index eb7bc70..1a8977e 100644
--- a/runtime/lib/array.dart
+++ b/runtime/lib/array.dart
@@ -24,6 +24,11 @@
                             int count)
       native "ObjectArray_copyFromObjectArray";
 
+  void insert(int index, E element) {
+    throw new UnsupportedError(
+        "Cannot add to a non-extendable array");
+  }
+
   E removeAt(int index) {
     throw new UnsupportedError(
         "Cannot remove element of a non-extendable array");
@@ -45,12 +50,12 @@
         "Cannot remove element of a non-extendable array");
   }
 
-  void removeMatching(bool test(E element)) {
+  void removeWhere(bool test(E element)) {
     throw new UnsupportedError(
         "Cannot remove element of a non-extendable array");
   }
 
-  void retainMatching(bool test(E element)) {
+  void retainWhere(bool test(E element)) {
     throw new UnsupportedError(
         "Cannot remove element of a non-extendable array");
   }
@@ -77,15 +82,20 @@
         "Cannot insert range in a non-extendable array");
   }
 
-  List<E> getRange(int start, int length) {
-    if (length == 0) return [];
-    Arrays.rangeCheck(this, start, length);
+
+  List<E> sublist(int start, [int end]) {
+    Arrays.indicesCheck(this, start, end);
+    if (end == null) end = this.length;
+    int length = end - start;
+    if (start == end) return [];
     List list = new _GrowableObjectArray<E>.withCapacity(length);
     list.length = length;
     Arrays.copy(this, start, list, 0, length);
     return list;
   }
 
+  List<E> getRange(int start, int length) => sublist(start, start + length);
+
   // Iterable interface.
 
   bool contains(E element) {
@@ -140,16 +150,16 @@
     return IterableMixinWorkaround.any(this, f);
   }
 
-  E firstMatching(bool test(E value), {E orElse()}) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  E firstWhere(bool test(E value), {E orElse()}) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  E lastMatching(bool test(E value), {E orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  E lastWhere(bool test(E value), {E orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  E singleMatching(bool test(E value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  E singleWhere(bool test(E value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   E elementAt(int index) {
@@ -265,6 +275,11 @@
 
   int get length native "ObjectArray_getLength";
 
+  void insert(int index, E element) {
+    throw new UnsupportedError(
+        "Cannot add to an immutable array");
+  }
+
   E removeAt(int index) {
     throw new UnsupportedError(
         "Cannot modify an immutable array");
@@ -285,12 +300,12 @@
         "Cannot modify an immutable array");
   }
 
-  void removeMatching(bool test(E element)) {
+  void removeWhere(bool test(E element)) {
     throw new UnsupportedError(
         "Cannot modify an immutable array");
   }
 
-  void retainMatching(bool test(E element)) {
+  void retainWhere(bool test(E element)) {
     throw new UnsupportedError(
         "Cannot modify an immutable array");
   }
@@ -315,15 +330,19 @@
         "Cannot insert range in an immutable array");
   }
 
-  List<E> getRange(int start, int length) {
-    if (length == 0) return [];
-    Arrays.rangeCheck(this, start, length);
+  List<E> sublist(int start, [int end]) {
+    Arrays.indicesCheck(this, start, end);
+    if (end == null) end = this.length;
+    int length = end - start;
+    if (start == end) return [];
     List list = new List<E>();
     list.length = length;
     Arrays.copy(this, start, list, 0, length);
     return list;
   }
 
+  List<E> getRange(int start, int length) => sublist(start, start + length);
+
   // Collection interface.
 
   bool contains(E element) {
@@ -378,16 +397,16 @@
     return IterableMixinWorkaround.any(this, f);
   }
 
-  E firstMatching(bool test(E value), {E orElse()}) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  E firstWhere(bool test(E value), {E orElse()}) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  E lastMatching(bool test(E value), {E orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  E lastWhere(bool test(E value), {E orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  E singleMatching(bool test(E value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  E singleWhere(bool test(E value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   E elementAt(int index) {
diff --git a/runtime/lib/async_sources.gypi b/runtime/lib/async_sources.gypi
index a64243d..9b39688 100644
--- a/runtime/lib/async_sources.gypi
+++ b/runtime/lib/async_sources.gypi
@@ -2,9 +2,10 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-# This file contains all sources for the dart:isolate library.
+# This file contains all sources for the dart:async library.
 {
   'sources': [
+    'event_loop_patch.dart',
     'timer_patch.dart',
     'deferred_load_patch.dart',
   ],
diff --git a/runtime/lib/byte_array.dart b/runtime/lib/byte_array.dart
index 2323fdf..d2e1ec0 100644
--- a/runtime/lib/byte_array.dart
+++ b/runtime/lib/byte_array.dart
@@ -274,16 +274,16 @@
     return IterableMixinWorkaround.any(this, f);
   }
 
-  int firstMatching(bool test(int value), {int orElse()}) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  int firstWhere(bool test(int value), {int orElse()}) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  int lastMatching(bool test(int value), {int orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  int lastWhere(bool test(int value), {int orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  int singleMatching(bool test(int value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  int singleWhere(bool test(int value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   int elementAt(int index) {
@@ -357,12 +357,12 @@
         "Cannot remove from a non-extendable array");
   }
 
-  void removeMatching(bool test(int element)) {
+  void removeWhere(bool test(int element)) {
     throw new UnsupportedError(
         "Cannot remove from a non-extendable array");
   }
 
-  void retainMatching(bool test(int element)) {
+  void retainWhere(bool test(int element)) {
     throw new UnsupportedError(
         "Cannot remove from a non-extendable array");
   }
@@ -556,13 +556,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = _new(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     if (from is _Int8Array) {
       _setRange(start * _BYTES_PER_ELEMENT,
@@ -620,13 +624,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = _new(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     if (from is _Uint8Array || from is _ExternalUint8Array ||
         from is _Uint8ClampedArray || from is _ExternalUint8ClampedArray) {
@@ -686,13 +694,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = _new(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     if (from is _Uint8Array || from is _ExternalUint8Array ||
         from is _Uint8ClampedArray || from is _ExternalUint8ClampedArray) {
@@ -751,13 +763,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = _new(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     if (from is _Int16Array) {
       _setRange(start * _BYTES_PER_ELEMENT,
@@ -815,13 +831,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = _new(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     if (from is _Uint16Array) {
       _setRange(start * _BYTES_PER_ELEMENT,
@@ -879,13 +899,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = _new(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     if (from is _Int32Array) {
       _setRange(start * _BYTES_PER_ELEMENT,
@@ -944,13 +968,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = _new(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     if (from is _Uint32Array) {
       _setRange(start * _BYTES_PER_ELEMENT,
@@ -1008,13 +1036,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = _new(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     if (from is _Int64Array) {
       _setRange(start * _BYTES_PER_ELEMENT,
@@ -1072,13 +1104,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = _new(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     if (from is _Uint64Array) {
       _setRange(start * _BYTES_PER_ELEMENT,
@@ -1136,13 +1172,18 @@
     return new _ByteArrayIterator<double>(this);
   }
 
-  List<double> getRange(int start, int length) {
+  List<double> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<double> result = _new(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<double> getRange(int start, int length) =>
+      sublist(start, start + length);
+
   void setRange(int start, int length, List<double> from, [int startFrom = 0]) {
     if (from is _Float32Array) {
       _setRange(start * _BYTES_PER_ELEMENT,
@@ -1200,13 +1241,18 @@
     return new _ByteArrayIterator<double>(this);
   }
 
-  List<double> getRange(int start, int length) {
+  List<double> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<double> result = _new(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<double> getRange(int start, int length) =>
+      sublist(start, start + length);
+
   void setRange(int start, int length, List<double> from, [int startFrom = 0]) {
     if (from is _Float64Array) {
       _setRange(start * _BYTES_PER_ELEMENT,
@@ -1253,13 +1299,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = new Int8List(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     if (from is _ExternalInt8Array) {
       _setRange(start * _BYTES_PER_ELEMENT,
@@ -1304,13 +1354,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = new Uint8List(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     if (from is _ExternalUint8Array || from is _Uint8Array) {
       _setRange(start * _BYTES_PER_ELEMENT,
@@ -1356,13 +1410,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = new Uint8ClampedList(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     if (from is _ExternalUint8ClampedArray || from is _Uint8ClampedArray) {
       _setRange(start * _BYTES_PER_ELEMENT,
@@ -1407,13 +1465,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = new Int16List(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     if (from is _ExternalInt16Array) {
       _setRange(start * _BYTES_PER_ELEMENT,
@@ -1458,13 +1520,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = new Uint16List(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     if (from is _ExternalUint16Array) {
       _setRange(start * _BYTES_PER_ELEMENT,
@@ -1511,13 +1577,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = new Int32List(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     if (from is _ExternalInt32Array) {
       _setRange(start * _BYTES_PER_ELEMENT,
@@ -1564,13 +1634,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = new Uint32List(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     if (from is _ExternalUint32Array) {
       _setRange(start * _BYTES_PER_ELEMENT,
@@ -1617,13 +1691,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = new Int64List(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     if (from is _ExternalInt64Array) {
       _setRange(start * _BYTES_PER_ELEMENT,
@@ -1670,13 +1748,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = new Uint64List(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     if (from is _ExternalUint64Array) {
       _setRange(start * _BYTES_PER_ELEMENT,
@@ -1723,13 +1805,18 @@
     return new _ByteArrayIterator<double>(this);
   }
 
-  List<double> getRange(int start, int length) {
+  List<double> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<double> result = new Float32List(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<double> getRange(int start, int length) =>
+      sublist(start, start + length);
+
   void setRange(int start, int length, List<double> from, [int startFrom = 0]) {
     if (from is _ExternalFloat32Array) {
       _setRange(start * _BYTES_PER_ELEMENT,
@@ -1776,13 +1863,18 @@
     return new _ByteArrayIterator<double>(this);
   }
 
-  List<double> getRange(int start, int length) {
+  List<double> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<double> result = new Float64List(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<double> getRange(int start, int length) =>
+      sublist(start, start + length);
+
   void setRange(int start, int length, List<double> from, [int startFrom = 0]) {
     if (from is _ExternalFloat64Array) {
       _setRange(start * _BYTES_PER_ELEMENT,
@@ -2010,6 +2102,11 @@
         "Cannot remove from a non-extendable array");
   }
 
+  void insert(int index, int element) {
+    throw new UnsupportedError(
+        "Cannot add to a non-extendable array");
+  }
+
   int removeAt(int index) {
     throw new UnsupportedError(
         "Cannot remove from a non-extendable array");
@@ -2030,12 +2127,12 @@
         "Cannot remove from a non-extendable array");
   }
 
-  void removeMatching(bool test(int element)) {
+  void removeWhere(bool test(int element)) {
     throw new UnsupportedError(
         "Cannot remove from a non-extendable array");
   }
 
-  void retainMatching(bool test(int element)) {
+  void retainWhere(bool test(int element)) {
     throw new UnsupportedError(
         "Cannot remove from a non-extendable array");
   }
@@ -2105,13 +2202,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = new Int8List(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     IterableMixinWorkaround.setRangeList(this, start, length, from, startFrom);
   }
@@ -2169,13 +2270,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = new Uint8List(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     IterableMixinWorkaround.setRangeList(this, start, length, from, startFrom);
   }
@@ -2233,13 +2338,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = new Int16List(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     IterableMixinWorkaround.setRangeList(this, start, length, from, startFrom);
   }
@@ -2297,13 +2406,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = new Uint16List(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     IterableMixinWorkaround.setRangeList(this, start, length, from, startFrom);
   }
@@ -2361,13 +2474,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = new Int32List(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     IterableMixinWorkaround.setRangeList(this, start, length, from, startFrom);
   }
@@ -2425,13 +2542,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = new Uint32List(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     IterableMixinWorkaround.setRangeList(this, start, length, from, startFrom);
   }
@@ -2489,13 +2610,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = new Int64List(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     IterableMixinWorkaround.setRangeList(this, start, length, from, startFrom);
   }
@@ -2553,13 +2678,17 @@
     return new _ByteArrayIterator<int>(this);
   }
 
-  List<int> getRange(int start, int length) {
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<int> result = new Uint64List(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<int> getRange(int start, int length) => sublist(start, start + length);
+
   void setRange(int start, int length, List<int> from, [int startFrom = 0]) {
     IterableMixinWorkaround.setRangeList(this, start, length, from, startFrom);
   }
@@ -2617,13 +2746,18 @@
     return new _ByteArrayIterator<double>(this);
   }
 
-  List<double> getRange(int start, int length) {
+  List<double> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<double> result = new Float32List(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<double> getRange(int start, int length) =>
+      sublist(start, start + length);
+
   void setRange(int start, int length, List<double> from, [int startFrom = 0]) {
     IterableMixinWorkaround.setRangeList(this, start, length, from, startFrom);
   }
@@ -2681,13 +2815,18 @@
     return new _ByteArrayIterator<double>(this);
   }
 
-  List<double> getRange(int start, int length) {
+  List<double> sublist(int start, [int end]) {
+    if (end == null) end = this.length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<double> result = new Float64List(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<double> getRange(int start, int length) =>
+      sublist(start, start + length);
+
   void setRange(int start, int length, List<double> from, [int startFrom = 0]) {
     IterableMixinWorkaround.setRangeList(this, start, length, from, startFrom);
   }
diff --git a/runtime/lib/core_patch.dart b/runtime/lib/core_patch.dart
index abaaea2..081ba83 100644
--- a/runtime/lib/core_patch.dart
+++ b/runtime/lib/core_patch.dart
@@ -3,3 +3,4 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "dart:math";
+import "dart:scalarlist";
diff --git a/runtime/lib/date_patch.dart b/runtime/lib/date_patch.dart
index 750b60d..b83e96b 100644
--- a/runtime/lib/date_patch.dart
+++ b/runtime/lib/date_patch.dart
@@ -183,7 +183,7 @@
     // Simplify calculations by working with zero-based month.
     --month;
     // Deal with under and overflow.
-    year += (month / 12).floor().toInt();
+    year += (month / 12).floor();
     month = month % 12;
 
     // First compute the seconds in UTC, independent of the [isUtc] flag. If
diff --git a/runtime/lib/double.dart b/runtime/lib/double.dart
index decfb57..29247ad 100644
--- a/runtime/lib/double.dart
+++ b/runtime/lib/double.dart
@@ -100,10 +100,15 @@
     return this < 0.0 ? -this : this;
   }
 
-  double round() native "Double_round";
-  double floor() native "Double_floor";
-  double ceil () native "Double_ceil";
-  double truncate() native "Double_truncate";
+  int round() => roundToDouble().toInt();
+  int floor() => floorToDouble().toInt();
+  int ceil () => ceilToDouble().toInt();
+  int truncate() => truncateToDouble().toInt();
+
+  double roundToDouble() native "Double_round";
+  double floorToDouble() native "Double_floor";
+  double ceilToDouble() native "Double_ceil";
+  double truncateToDouble() native "Double_truncate";
 
   num clamp(num lowerLimit, num upperLimit) {
     if (lowerLimit is! num) throw new ArgumentError(lowerLimit);
diff --git a/runtime/lib/errors_patch.dart b/runtime/lib/errors_patch.dart
index 783a17d..37ab065 100644
--- a/runtime/lib/errors_patch.dart
+++ b/runtime/lib/errors_patch.dart
@@ -25,7 +25,7 @@
     if (numPositionalArguments == 0) {
       positionalArguments = [];
     } else {
-      positionalArguments = arguments.getRange(0, numPositionalArguments);
+      positionalArguments = arguments.sublist(0, numPositionalArguments);
     }
     Map<String, dynamic> namedArguments = new Map<String, dynamic>();
     for (int i = 0; i < numNamedArguments; i++) {
@@ -107,26 +107,26 @@
     if (_arguments != null) {
       for (; i < _arguments.length; i++) {
         if (i > 0) {
-          actual_buf.add(", ");
+          actual_buf.write(", ");
         }
-        actual_buf.add(Error.safeToString(_arguments[i]));
+        actual_buf.write(Error.safeToString(_arguments[i]));
       }
     }
     if (_namedArguments != null) {
       _namedArguments.forEach((String key, var value) {
         if (i > 0) {
-          actual_buf.add(", ");
+          actual_buf.write(", ");
         }
-        actual_buf.add(key);
-        actual_buf.add(": ");
-        actual_buf.add(Error.safeToString(value));
+        actual_buf.write(key);
+        actual_buf.write(": ");
+        actual_buf.write(Error.safeToString(value));
         i++;
       });
     }
     var args_mismatch = _existingArgumentNames != null;
     StringBuffer msg_buf = new StringBuffer(_developerMessage(args_mismatch));
     if (!args_mismatch) {
-      msg_buf.add(
+      msg_buf.write(
           "NoSuchMethodError : method not found: '$_memberName'\n"
           "Receiver: ${Error.safeToString(_receiver)}\n"
           "Arguments: [$actual_buf]");
@@ -135,12 +135,12 @@
       StringBuffer formal_buf = new StringBuffer();
       for (int i = 0; i < _existingArgumentNames.length; i++) {
         if (i > 0) {
-          formal_buf.add(", ");
+          formal_buf.write(", ");
         }
-        formal_buf.add(_existingArgumentNames[i]);
+        formal_buf.write(_existingArgumentNames[i]);
       }
       String formalParameters = formal_buf.toString();
-      msg_buf.add( 
+      msg_buf.write(
           "NoSuchMethodError: incorrect number of arguments passed to "
           "method named '$_memberName'\n"
           "Receiver: ${Error.safeToString(_receiver)}\n"
diff --git a/runtime/lib/event_loop_patch.dart b/runtime/lib/event_loop_patch.dart
new file mode 100644
index 0000000..c4b25b7
--- /dev/null
+++ b/runtime/lib/event_loop_patch.dart
@@ -0,0 +1,10 @@
+// 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.
+
+patch class _AsyncRun {
+  /* patch */ static void _enqueueImmediate(void callback()) {
+    // TODO(9001): don't use the Timer to enqueue the immediate callback.
+    Timer.run(callback);
+  }
+}
diff --git a/runtime/lib/growable_array.dart b/runtime/lib/growable_array.dart
index 5759178..db020ad 100644
--- a/runtime/lib/growable_array.dart
+++ b/runtime/lib/growable_array.dart
@@ -8,6 +8,28 @@
         "GrowableObjectArray can only be allocated by the VM");
   }
 
+  void insert(int index, T element) {
+    if (index < 0 || index > length) {
+      throw new RangeError.range(index, 0, length);
+    }
+    if (index == this.length) {
+      add(element);
+      return;
+    }
+    int oldLength = this.length;
+    // We are modifying the length just below the is-check. Without the check
+    // Array.copy could throw an exception, leaving the list in a bad state
+    // (with a length that has been increased, but without a new element).
+    if (index is! int) throw new ArgumentError(index);
+    this.length++;
+    Arrays.copy(this,
+                index,
+                this,
+                index + 1,
+                oldLength - index);
+    this[index] = element;
+  }
+
   T removeAt(int index) {
     if (index is! int) throw new ArgumentError(index);
     T result = this[index];
@@ -38,13 +60,13 @@
     IterableMixinWorkaround.retainAll(this, elements);
   }
 
-  void removeMatching(bool test(T element)) {
-    IterableMixinWorkaround.removeMatchingList(this, test);
+  void removeWhere(bool test(T element)) {
+    IterableMixinWorkaround.removeWhereList(this, test);
   }
 
-  void retainMatching(bool test(T element)) {
-    IterableMixinWorkaround.removeMatchingList(this,
-                                               (T element) => !test(element));
+  void retainWhere(bool test(T element)) {
+    IterableMixinWorkaround.removeWhereList(this,
+                                            (T element) => !test(element));
   }
 
   void setRange(int start, int length, List<T> from, [int startFrom = 0]) {
@@ -86,15 +108,19 @@
     }
   }
 
-  List<T> getRange(int start, int length) {
-    if (length == 0) return [];
-    Arrays.rangeCheck(this, start, length);
+  List<T> sublist(int start, [int end]) {
+    Arrays.indicesCheck(this, start, end);
+    if (end == null) end = length;
+    int length = end - start;
+    if (start == end) return <T>[];
     List list = new _GrowableObjectArray<T>.withCapacity(length);
     list.length = length;
     Arrays.copy(this, start, list, 0, length);
     return list;
   }
 
+  List<T> getRange(int start, int length) => sublist(start, start + length);
+
   factory _GrowableObjectArray(int length) {
     var data = new _ObjectArray((length == 0) ? 4 : length);
     var result = new _GrowableObjectArray<T>.withData(data);
@@ -226,13 +252,13 @@
     StringBuffer buffer = new StringBuffer();
     if (separator == null || separator == "") {
       for (int i = 0; i < this.length; i++) {
-        buffer.add("${this[i]}");
+        buffer.write("${this[i]}");
       }
     } else {
-      buffer.add("${this[0]}");
+      buffer.write("${this[0]}");
       for (int i = 1; i < this.length; i++) {
-        buffer.add(separator);
-        buffer.add("${this[i]}");
+        buffer.write(separator);
+        buffer.write("${this[i]}");
       }
     }
     return buffer.toString();
@@ -278,16 +304,16 @@
     return IterableMixinWorkaround.any(this, f);
   }
 
-  T firstMatching(bool test(T value), {T orElse()}) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  T firstWhere(bool test(T value), {T orElse()}) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  T lastMatching(bool test(T value), {T orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  T lastWhere(bool test(T value), {T orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  T singleMatching(bool test(T value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  T singleWhere(bool test(T value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   T elementAt(int index) {
diff --git a/runtime/lib/integers.dart b/runtime/lib/integers.dart
index 2b3a1ee..8ee9dd3 100644
--- a/runtime/lib/integers.dart
+++ b/runtime/lib/integers.dart
@@ -131,6 +131,11 @@
   int ceil() { return this; }
   int truncate() { return this; }
 
+  double roundToDouble() { return this.toDouble(); }
+  double floorToDouble() { return this.toDouble(); }
+  double ceilToDouble() { return this.toDouble(); }
+  double truncateToDouble() { return this.toDouble(); }
+
   num clamp(num lowerLimit, num upperLimit) {
     if (lowerLimit is! num) throw new ArgumentError(lowerLimit);
     if (upperLimit is! num) throw new ArgumentError(upperLimit);
@@ -197,9 +202,9 @@
       return "0";
     }
     StringBuffer buffer = new StringBuffer();
-    if (isNegative) buffer.add("-");
+    if (isNegative) buffer.write("-");
     for (int i = temp.length - 1; i >= 0; i--) {
-      buffer.add(table[temp[i]]);
+      buffer.write(table[temp[i]]);
     }
     return buffer.toString();
   }
diff --git a/runtime/lib/invocation_mirror_patch.dart b/runtime/lib/invocation_mirror_patch.dart
index 3f53feb..c498eac 100644
--- a/runtime/lib/invocation_mirror_patch.dart
+++ b/runtime/lib/invocation_mirror_patch.dart
@@ -40,7 +40,7 @@
       _memberName = _functionName.substring(4);
     } else if (_functionName.startsWith("set:")) {
       _type = _SETTER;
-      _memberName = _functionName.substring(4).concat("=");
+      _memberName = _functionName.substring(4) + "=";
     } else {
       _type = _METHOD;
       _memberName = _functionName;
@@ -56,9 +56,9 @@
 
   List get positionalArguments {
     if (_positionalArguments == null) {
+      int numPositionalArguments = _argumentsDescriptor[1];
       // Exclude receiver.
-      int numPositionalArguments = _argumentsDescriptor[1] - 1;
-      _positionalArguments = _arguments.getRange(1, numPositionalArguments);
+      _positionalArguments = _arguments.sublist(1, numPositionalArguments);
     }
     return _positionalArguments;
   }
diff --git a/runtime/lib/math_patch.dart b/runtime/lib/math_patch.dart
index 0be4213..c01084b 100644
--- a/runtime/lib/math_patch.dart
+++ b/runtime/lib/math_patch.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import "dart:scalarlist";
+
 // A VM patch of the dart:math library.
 patch num pow(num x, num exponent) {
   if (exponent is int) {
@@ -51,7 +53,7 @@
 
 class _Random implements Random {
   // Internal state of the random number generator.
-  final _state = new List(2);
+  final _state = new Uint32List(2);
   static const kSTATE_LO = 0;
   static const kSTATE_HI = 1;
 
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index d8c78e1..43f511c 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -22,24 +22,24 @@
 String _makeSignatureString(TypeMirror returnType,
                             List<ParameterMirror> parameters) {
   StringBuffer buf = new StringBuffer();
-  buf.add(returnType.qualifiedName);
-  buf.add(' (');
+  buf.write(returnType.qualifiedName);
+  buf.write(' (');
   bool found_optional_param = false;
   for (int i = 0; i < parameters.length; i++) {
     var param = parameters[i];
     if (param.isOptional && !found_optional_param) {
-      buf.add('[');
+      buf.write('[');
       found_optional_param = true;
     }
-    buf.add(param.type.qualifiedName);
+    buf.write(param.type.qualifiedName);
     if (i < (parameters.length - 1)) {
-      buf.add(', ');
+      buf.write(', ');
     }
   }
   if (found_optional_param) {
-    buf.add(']');
+    buf.write(']');
   }
-  buf.add(')');
+  buf.write(')');
   return buf.toString();
 }
 
@@ -56,7 +56,7 @@
     if (_dynamicType == null) {
       _dynamicType =
           new _LocalClassMirrorImpl(
-              null, 'Dynamic', false, null, null, [], null,
+              null, 'dynamic', false, null, null, [], null,
               const {}, const {}, const {});
     }
     return _dynamicType;
@@ -253,7 +253,7 @@
         }
         break;
     }
-    buf.add(output);
+    buf.write(output);
   }
   return buf.toString();
 }
@@ -340,8 +340,7 @@
 
   TypeMirror resolve(MirrorSystem mirrors) {
     if (libraryName == null) {
-      // TODO(turnidge): Remove support for 'Dynamic'.
-      if ((typeName == 'dynamic') || (typeName == 'Dynamic')) {
+      if (typeName == 'dynamic') {
         return mirrors.dynamicType;
       } else if (typeName == 'void') {
         return mirrors.voidType;
@@ -385,7 +384,7 @@
       }
     } else {
       // The owner of a ClassMirror is null in certain odd cases, like
-      // 'void', 'Dynamic' and function type mirrors.
+      // 'void', 'dynamic' and function type mirrors.
       _qualifiedName = simpleName;
     }
     return _qualifiedName;
diff --git a/runtime/lib/simd128.dart b/runtime/lib/simd128.dart
index 5052773..ca3f587 100644
--- a/runtime/lib/simd128.dart
+++ b/runtime/lib/simd128.dart
@@ -583,6 +583,7 @@
   factory _Float32x4Array(int length) {
     return _new(length);
   }
+
   factory _Float32x4Array.view(ByteArray array,
                                     [int start = 0, int length]) {
     if (length == null) {
@@ -590,21 +591,32 @@
     }
     return new _Float32x4ArrayView(array, start, length);
   }
+
   Float32x4 operator [](int index) {
     return _getIndexed(index);
   }
+
   int operator []=(int index, Float32x4 value) {
     _setIndexed(index, value);
   }
+
   Iterator<Float32x4> get iterator {
     return new _ByteArrayIterator<Float32x4>(this);
   }
-  List<Float32x4> getRange(int start, int length) {
+
+  List<Float32x4> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<Float32x4> result = _new(length);
     result.setRange(0, length, this, start);
     return result;
   }
+
+  List<Float32x4> getRange(int start, int length) {
+    return sublist(start, start + length);
+  }
+
   void setRange(int start, int length, List<Float32x4> from,
                 [int startFrom = 0]) {
     if (from is _Float32x4Array) {
@@ -667,13 +679,19 @@
     return new _ByteArrayIterator<Float32x4>(this);
   }
 
-  List<Float32x4> getRange(int start, int length) {
+  List<Float32x4> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<Float32x4> result = new Float32List(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<Float32x4> getRange(int start, int length) {
+    return sublist(start, start + length);
+  }
+
   void setRange(int start, int length, List<Float32x4> from,
                [int startFrom = 0]) {
     IterableMixinWorkaround.setRangeList(this, start, length, from, startFrom);
@@ -717,13 +735,19 @@
     return new _ByteArrayIterator<Float32x4>(this);
   }
 
-  List<Float32x4> getRange(int start, int length) {
+  List<Float32x4> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    int length = end - start;
     _rangeCheck(this.length, start, length);
     List<Float32x4> result = new Float32x4List(length);
     result.setRange(0, length, this, start);
     return result;
   }
 
+  List<Float32x4> getRange(int start, int length) {
+    return sublist(start, start + length);
+  }
+
   void setRange(int start, int length, List<Float32x4> from,
                 [int startFrom = 0]) {
     if (from is _ExternalFloat32x4Array) {
diff --git a/runtime/lib/string.cc b/runtime/lib/string.cc
index 3b5b633..c282b7a 100644
--- a/runtime/lib/string.cc
+++ b/runtime/lib/string.cc
@@ -13,10 +13,26 @@
 namespace dart {
 
 DEFINE_NATIVE_ENTRY(StringBase_createFromCodePoints, 1) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Array, a, arguments->NativeArgAt(0));
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance, list, arguments->NativeArgAt(0));
+  if (!list.IsGrowableObjectArray() && !list.IsArray()) {
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, list);
+    Exceptions::ThrowByType(Exceptions::kArgument, args);
+  }
   // TODO(srdjan): Check that parameterized type is an int.
+
+  Array& a = Array::Handle();
+  intptr_t array_len;
+  if (list.IsGrowableObjectArray()) {
+    const GrowableObjectArray& growableArray = GrowableObjectArray::Cast(list);
+    a ^= growableArray.data();
+    array_len = growableArray.Length();
+  } else {
+    a ^= Array::Cast(list).raw();
+    array_len = a.Length();
+  }
+
   Zone* zone = isolate->current_zone();
-  intptr_t array_len = a.Length();
 
   // Unbox the array and determine the maximum element width.
   bool is_one_byte_string = true;
@@ -197,4 +213,27 @@
   return String::ConcatAll(strings);
 }
 
+
+DEFINE_NATIVE_ENTRY(StringBuffer_createStringFromUint16Array, 3) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Uint16Array, codeUnits,
+                               arguments->NativeArgAt(0));
+  GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(1));
+  GET_NON_NULL_NATIVE_ARGUMENT(Bool, isLatin1, arguments->NativeArgAt(2));
+  intptr_t array_length = codeUnits.Length();
+  intptr_t length_value = length.Value();
+  if (length_value < 0 || length_value > array_length) {
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, length);
+    Exceptions::ThrowByType(Exceptions::kRange, args);
+  }
+  const String& result = isLatin1.value()
+      ? String::Handle(OneByteString::New(length_value, Heap::kNew))
+      : String::Handle(TwoByteString::New(length_value, Heap::kNew));
+  NoGCScope no_gc;
+
+  uint16_t* data_position = reinterpret_cast<uint16_t*>(codeUnits.ByteAddr(0));
+  String::Copy(result, 0, data_position, length_value);
+  return result.raw();
+}
+
 }  // namespace dart
diff --git a/runtime/lib/string_base.dart b/runtime/lib/string_base.dart
index 8ed74b6..b2d126b 100644
--- a/runtime/lib/string_base.dart
+++ b/runtime/lib/string_base.dart
@@ -19,18 +19,11 @@
    *  Create the most efficient string representation for specified
    *  [codePoints].
    */
-  static String createFromCharCodes(List<int> charCodes) {
-    _ObjectArray objectArray;
-    if (charCodes is _ObjectArray) {
-      objectArray = charCodes;
-    } else {
-      int len = charCodes.length;
-      objectArray = new _ObjectArray(len);
-      for (int i = 0; i < len; i++) {
-        objectArray[i] = charCodes[i];
-      }
+  static String createFromCharCodes(Iterable<int> charCodes) {
+    if (charCodes is! _ObjectArray && charCodes is! _GrowableObjectArray) {
+      charCodes = new List<int>.from(charCodes, growable: false);
     }
-    return _createFromCodePoints(objectArray);
+    return _createFromCodePoints(charCodes);
   }
 
   static String _createFromCodePoints(List<int> codePoints)
@@ -46,7 +39,9 @@
     return this.length == 0;
   }
 
-  String concat(String other) native "String_concat";
+  String operator +(String other) native "String_concat";
+
+  String concat(String other) => this + other;
 
   String toString() {
     return this;
@@ -254,11 +249,11 @@
     Iterator iterator = pattern.allMatches(this).iterator;
     if (iterator.moveNext()) {
       Match match = iterator.current;
-      buffer..add(this.substring(startIndex, match.start))
-            ..add(replacement);
+      buffer..write(this.substring(startIndex, match.start))
+            ..write(replacement);
       startIndex = match.end;
     }
-    return (buffer..add(this.substring(startIndex))).toString();
+    return (buffer..write(this.substring(startIndex))).toString();
   }
 
   String replaceAll(Pattern pattern, String replacement) {
@@ -272,11 +267,11 @@
     StringBuffer buffer = new StringBuffer();
     int startIndex = 0;
     for (Match match in pattern.allMatches(this)) {
-      buffer..add(this.substring(startIndex, match.start))
-            ..add(replacement);
+      buffer..write(this.substring(startIndex, match.start))
+            ..write(replacement);
       startIndex = match.end;
     }
-    return (buffer..add(this.substring(startIndex))).toString();
+    return (buffer..write(this.substring(startIndex))).toString();
   }
 
   String replaceAllMapped(Pattern pattern, String replace(Match match)) {
@@ -292,9 +287,9 @@
     StringBuffer buffer = new StringBuffer();
     int length = this.length;
     int i = 0;
-    buffer.add(onNonMatch(""));
+    buffer.write(onNonMatch(""));
     while (i < length) {
-      buffer.add(onMatch(new _StringMatch(i, this, "")));
+      buffer.write(onMatch(new _StringMatch(i, this, "")));
       // Special case to avoid splitting a surrogate pair.
       int code = this.codeUnitAt(i);
       if ((code & ~0x3FF) == 0xD800 && length > i + 1) {
@@ -302,16 +297,16 @@
         code = this.codeUnitAt(i + 1);
         if ((code & ~0x3FF) == 0xDC00) {
           // Matching trailing surrogate.
-          buffer.add(onNonMatch(this.substring(i, i + 2)));
+          buffer.write(onNonMatch(this.substring(i, i + 2)));
           i += 2;
           continue;
         }
       }
-      buffer.add(onNonMatch(this[i]));
+      buffer.write(onNonMatch(this[i]));
       i++;
     }
-    buffer.add(onMatch(new _StringMatch(i, this, "")));
-    buffer.add(onNonMatch(""));
+    buffer.write(onMatch(new _StringMatch(i, this, "")));
+    buffer.write(onNonMatch(""));
     return buffer.toString();
   }
 
@@ -332,11 +327,11 @@
     StringBuffer buffer = new StringBuffer();
     int startIndex = 0;
     for (Match match in pattern.allMatches(this)) {
-      buffer.add(onNonMatch(this.substring(startIndex, match.start)));
-      buffer.add(onMatch(match).toString());
+      buffer.write(onNonMatch(this.substring(startIndex, match.start)));
+      buffer.write(onMatch(match).toString());
       startIndex = match.end;
     }
-    buffer.add(onNonMatch(this.substring(startIndex)));
+    buffer.write(onNonMatch(this.substring(startIndex)));
     return buffer.toString();
   }
 
diff --git a/runtime/lib/string_buffer_patch.dart b/runtime/lib/string_buffer_patch.dart
index 8fadafa..2d1eb50 100644
--- a/runtime/lib/string_buffer_patch.dart
+++ b/runtime/lib/string_buffer_patch.dart
@@ -3,13 +3,22 @@
 // BSD-style license that can be found in the LICENSE file.
 
 patch class StringBuffer {
-  List<String> _buffer;
-  int _length;
+  /** Backing store for collected UTF-16 code units. */
+  Uint16List _buffer;
+  /** Number of code units collected. */
+  int _length = 0;
+  /**
+   * Collects the approximate maximal magnitude of the added code units.
+   *
+   * The value of each added code unit is or'ed with this variable, so the
+   * most significant bit set in any code unit is also set in this value.
+   * If below 256, the string is a Latin-1 string.
+   */
+  int _codeUnitMagnitude = 0;
 
   /// Creates the string buffer with an initial content.
-  /* patch */ StringBuffer([Object content = ""]) {
-    _buffer = new List<String>();
-    _length = 0;
+  /* patch */ StringBuffer([Object content = ""])
+      : _buffer = new Uint16List(16) {
     write(content);
   }
 
@@ -17,37 +26,82 @@
 
   /// Adds [obj] to the buffer.
   /* patch */ void write(Object obj) {
-    // TODO(srdjan): The following four lines could be replaced by
-    // '$obj', but apparently this is too slow on the Dart VM.
     String str;
     if (obj is String) {
       str = obj;
     } else {
+      // TODO(srdjan): The following four lines could be replaced by
+      // '$obj', but apparently this is too slow on the Dart VM.
       str = obj.toString();
       if (str is! String) {
         throw new ArgumentError('toString() did not return a string');
       }
     }
     if (str.isEmpty) return;
-    _buffer.add(str);
+    _ensureCapacity(str.length);
+    for (int i = 0; i < str.length; i++) {
+      int unit = str.codeUnitAt(i);
+      _buffer[_length + i] = unit;
+      _codeUnitMagnitude |= unit;
+    }
     _length += str.length;
   }
 
-  /// Clears the string buffer.
-  /* patch */ void clear() {
-    _buffer = new List<String>();
-    _length = 0;
+  /* patch */ writeCharCode(int charCode) {
+    if (charCode <= 0xFFFF) {
+      if (charCode < 0) {
+        throw new RangeError.range(charCode, 0, 0x10FFFF);
+      }
+      _ensureCapacity(1);
+      _buffer[_length++] = charCode;
+      _codeUnitMagnitude |= charCode;
+    } else {
+      if (charCode > 0x10FFFF) {
+        throw new RangeError.range(charCode, 0, 0x10FFFF);
+      }
+      _ensureCapacity(2);
+      int bits = charCode - 0x10000;
+      _buffer[_length++] = 0xD800 | (bits >> 10);
+      _buffer[_length++] = 0xDC00 | (bits & 0x3FF);
+      _codeUnitMagnitude |= 0xFFFF;
+    }
   }
 
-  /// Returns the contents of buffer as a concatenated string.
-  /* patch */ String toString() {
-    if (_buffer.length == 0) return "";
-    if (_buffer.length == 1) return _buffer[0];
-    String result = _StringBase.concatAll(_buffer);
-    _buffer.clear();
-    _buffer.add(result);
-    // Since we track the length at each add operation, there is no
-    // need to update it in this function.
-    return result;
+  /** Makes the buffer empty. */
+  /* patch */ void clear() {
+    _length = 0;
+    _codeUnitMagnitude = 0;
   }
+
+  /** Returns the contents of buffer as a string. */
+  /* patch */ String toString() {
+    if (_length == 0) return "";
+    bool isLatin1 = _codeUnitMagnitude <= 0xFF;
+    return _create(_buffer, _length, isLatin1);
+  }
+
+  /** Ensures that the buffer has enough capacity to add n code units. */
+  void _ensureCapacity(int n) {
+    int requiredCapacity = _length + n;
+    if (requiredCapacity > _buffer.length) {
+      _grow(requiredCapacity);
+    }
+  }
+
+  /** Grows the buffer until it can contain [requiredCapacity] entries. */
+  void _grow(int requiredCapacity) {
+    int newCapacity = _buffer.length;
+    do {
+      newCapacity *= 2;
+    } while (newCapacity < requiredCapacity);
+    List<int> newBuffer = new Uint16List(newCapacity);
+    newBuffer.setRange(0, _length, _buffer);
+    _buffer = newBuffer;
+  }
+
+  /**
+   * Create a [String] from the UFT-16 code units in buffer.
+   */
+  static String _create(Uint16List buffer, int length, bool isLatin1)
+      native "StringBuffer_createStringFromUint16Array";
 }
diff --git a/runtime/lib/string_patch.dart b/runtime/lib/string_patch.dart
index 6a9cf54..48035d4 100644
--- a/runtime/lib/string_patch.dart
+++ b/runtime/lib/string_patch.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 patch class String {
-  /* patch */ factory String.fromCharCodes(List<int> charCodes) {
+  /* patch */ factory String.fromCharCodes(Iterable<int> charCodes) {
     return _StringBase.createFromCharCodes(charCodes);
   }
 }
diff --git a/runtime/lib/timer_patch.dart b/runtime/lib/timer_patch.dart
index fd3efbd..2db2343 100644
--- a/runtime/lib/timer_patch.dart
+++ b/runtime/lib/timer_patch.dart
@@ -12,8 +12,8 @@
     return _TimerFactory._factory(milliseconds, (_) { callback(); }, false);
   }
 
-  /* patch */ factory Timer.repeating(Duration duration,
-                                      void callback(Timer timer)) {
+  /* patch */ factory Timer.periodic(Duration duration,
+                                     void callback(Timer timer)) {
     if (_TimerFactory._factory == null) {
       throw new UnsupportedError("Timer interface not supported.");
     }
diff --git a/runtime/lib/typeddata.cc b/runtime/lib/typeddata.cc
new file mode 100644
index 0000000..bf61ba8
--- /dev/null
+++ b/runtime/lib/typeddata.cc
@@ -0,0 +1,310 @@
+// 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.
+
+#include "vm/bootstrap_natives.h"
+
+#include "include/dart_api.h"
+
+#include "vm/bigint_operations.h"
+#include "vm/exceptions.h"
+#include "vm/native_entry.h"
+#include "vm/object.h"
+
+namespace dart {
+
+// TypedData.
+
+// Checks to see if offset_in_bytes is in the range.
+static bool RangeCheck(intptr_t offset_in_bytes, intptr_t length_in_bytes) {
+  return ((offset_in_bytes >= 0) &&
+          (length_in_bytes > 0) &&
+          (offset_in_bytes < length_in_bytes));
+}
+
+
+// Checks to see if offsetInBytes + num_bytes is in the range.
+static void SetRangeCheck(intptr_t offset_in_bytes,
+                          intptr_t num_bytes,
+                          intptr_t length_in_bytes,
+                          intptr_t element_size_in_bytes) {
+  if (!Utils::RangeCheck(offset_in_bytes, num_bytes, length_in_bytes)) {
+    const String& error = String::Handle(String::NewFormatted(
+        "index (%"Pd") must be in the range [0..%"Pd")",
+        (offset_in_bytes / element_size_in_bytes),
+        (length_in_bytes / element_size_in_bytes)));
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, error);
+    Exceptions::ThrowByType(Exceptions::kRange, args);
+  }
+}
+
+
+// Checks to see if a length will not result in an OOM error.
+static void LengthCheck(intptr_t len, intptr_t max) {
+  ASSERT(len >= 0);
+  if (len > max) {
+    const String& error = String::Handle(String::NewFormatted(
+        "insufficient memory to allocate a TypedData object of length (%"Pd")",
+        len));
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, error);
+    Exceptions::ThrowByType(Exceptions::kOutOfMemory, args);
+  }
+}
+
+
+static void PeerFinalizer(Dart_Handle handle, void* peer) {
+  Dart_DeletePersistentHandle(handle);
+  OS::AlignedFree(peer);
+}
+
+
+DEFINE_NATIVE_ENTRY(TypedData_length, 1) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0));
+  if (instance.IsTypedData()) {
+     const TypedData& array = TypedData::Cast(instance);
+     return Smi::New(array.Length());
+  }
+  if (instance.IsExternalTypedData()) {
+    const ExternalTypedData& array = ExternalTypedData::Cast(instance);
+    return Smi::New(array.Length());
+  }
+  const String& error = String::Handle(String::NewFormatted(
+      "Expected a TypedData object but found %s", instance.ToCString()));
+  const Array& args = Array::Handle(Array::New(1));
+  args.SetAt(0, error);
+  Exceptions::ThrowByType(Exceptions::kArgument, args);
+  return Integer::null();
+}
+
+
+#define COPY_DATA(type, dst, src)                                              \
+  const type& dst_array = type::Cast(dst);                                     \
+  const type& src_array = type::Cast(src);                                     \
+  intptr_t element_size_in_bytes = dst_array.ElementSizeInBytes();             \
+  intptr_t length_in_bytes = length.Value() * element_size_in_bytes;           \
+  intptr_t src_offset_in_bytes = src_start.Value() * element_size_in_bytes;    \
+  intptr_t dst_offset_in_bytes = dst_start.Value() * element_size_in_bytes;    \
+  SetRangeCheck(src_offset_in_bytes,                                           \
+                length_in_bytes,                                               \
+                src_array.LengthInBytes(),                                     \
+                element_size_in_bytes);                                        \
+  SetRangeCheck(dst_offset_in_bytes,                                           \
+                length_in_bytes,                                               \
+                dst_array.LengthInBytes(),                                     \
+                element_size_in_bytes);                                        \
+  type::Copy(dst_array, dst_offset_in_bytes,                                   \
+             src_array, src_offset_in_bytes,                                   \
+             length_in_bytes);
+
+DEFINE_NATIVE_ENTRY(TypedData_setRange, 5) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance, dst, arguments->NativeArgAt(0));
+  GET_NON_NULL_NATIVE_ARGUMENT(Smi, dst_start, arguments->NativeArgAt(1));
+  GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(2));
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance, src, arguments->NativeArgAt(3));
+  GET_NON_NULL_NATIVE_ARGUMENT(Smi, src_start, arguments->NativeArgAt(4));
+
+  if (length.Value() < 0) {
+    const String& error = String::Handle(String::NewFormatted(
+        "length (%"Pd") must be non-negative", length.Value()));
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, error);
+    Exceptions::ThrowByType(Exceptions::kArgument, args);
+  }
+  if ((dst.IsTypedData() || dst.IsExternalTypedData()) &&
+      (dst.clazz() == src.clazz())) {
+    if (dst.IsTypedData()) {
+      ASSERT(src.IsTypedData());
+      COPY_DATA(TypedData, dst, src);
+    } else {
+      ASSERT(src.IsExternalTypedData());
+      ASSERT(dst.IsExternalTypedData());
+      COPY_DATA(ExternalTypedData, dst, src);
+    }
+    return Bool::True().raw();
+  }
+  return Bool::False().raw();
+}
+
+
+// We check the length parameter against a possible maximum length for the
+// array based on available physical addressable memory on the system. The
+// maximum possible length is a scaled value of kSmiMax which is set up based
+// on whether the underlying architecture is 32-bit or 64-bit.
+#define TYPED_DATA_NEW(name)                                                   \
+DEFINE_NATIVE_ENTRY(TypedData_##name##_new, 1) {                               \
+  GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));        \
+  intptr_t cid = kTypedData##name##Cid;                                        \
+  intptr_t len = length.Value();                                               \
+  intptr_t max = TypedData::MaxElements(cid);                                  \
+  LengthCheck(len, max);                                                       \
+  return TypedData::New(cid, len);                                             \
+}                                                                              \
+
+
+// We check the length parameter against a possible maximum length for the
+// array based on available physical addressable memory on the system. The
+// maximum possible length is a scaled value of kSmiMax which is set up based
+// on whether the underlying architecture is 32-bit or 64-bit.
+#define EXT_TYPED_DATA_NEW(name)                                               \
+DEFINE_NATIVE_ENTRY(ExternalTypedData_##name##_new, 1) {                       \
+  const int kAlignment = 16;                                                   \
+  GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));        \
+  intptr_t cid = kExternalTypedData##name##Cid;                                \
+  intptr_t len = length.Value();                                               \
+  intptr_t max = ExternalTypedData::MaxElements(cid);                          \
+  LengthCheck(len, max);                                                       \
+  intptr_t len_bytes = len * ExternalTypedData::ElementSizeInBytes(cid);       \
+  uint8_t* data = OS::AllocateAlignedArray<uint8_t>(len_bytes, kAlignment);    \
+  const ExternalTypedData& obj =                                               \
+      ExternalTypedData::Handle(ExternalTypedData::New(cid, data, len));       \
+  obj.AddFinalizer(data, PeerFinalizer);                                       \
+  return obj.raw();                                                            \
+}                                                                              \
+
+
+#define TYPED_DATA_NEW_NATIVE(name)                                            \
+  TYPED_DATA_NEW(name)                                                         \
+  EXT_TYPED_DATA_NEW(name)                                                     \
+
+
+CLASS_LIST_TYPED_DATA(TYPED_DATA_NEW_NATIVE)
+
+
+#define TYPED_DATA_GETTER(getter, object)                                      \
+DEFINE_NATIVE_ENTRY(TypedData_##getter, 2) {                                   \
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0)); \
+  GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes, arguments->NativeArgAt(1)); \
+  if (instance.IsTypedData()) {                                                \
+    const TypedData& array = TypedData::Cast(instance);                        \
+    ASSERT(RangeCheck(offsetInBytes.Value(), array.LengthInBytes()));          \
+    return object::New(array.getter(offsetInBytes.Value()));                   \
+  }                                                                            \
+  if (instance.IsExternalTypedData()) {                                        \
+    const ExternalTypedData& array = ExternalTypedData::Cast(instance);        \
+    ASSERT(RangeCheck(offsetInBytes.Value(), array.LengthInBytes()));          \
+    return object::New(array.getter(offsetInBytes.Value()));                   \
+  }                                                                            \
+  const String& error = String::Handle(String::NewFormatted(                   \
+      "Expected a TypedData object but found %s", instance.ToCString()));      \
+  const Array& args = Array::Handle(Array::New(1));                            \
+  args.SetAt(0, error);                                                        \
+  Exceptions::ThrowByType(Exceptions::kArgument, args);                        \
+  return object::null();                                                       \
+}                                                                              \
+
+
+#define TYPED_DATA_SETTER(setter, object, get_object_value)                    \
+DEFINE_NATIVE_ENTRY(TypedData_##setter, 3) {                                   \
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0)); \
+  GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes, arguments->NativeArgAt(1)); \
+  GET_NON_NULL_NATIVE_ARGUMENT(object, value, arguments->NativeArgAt(2));      \
+  if (instance.IsTypedData()) {                                                \
+    const TypedData& array = TypedData::Cast(instance);                        \
+    ASSERT(RangeCheck(offsetInBytes.Value(), array.LengthInBytes()));          \
+    array.setter(offsetInBytes.Value(), value.get_object_value());             \
+  } else if (instance.IsExternalTypedData()) {                                 \
+    const ExternalTypedData& array = ExternalTypedData::Cast(instance);        \
+    ASSERT(RangeCheck(offsetInBytes.Value(), array.LengthInBytes()));          \
+    array.setter(offsetInBytes.Value(), value.get_object_value());             \
+  } else {                                                                     \
+    const String& error = String::Handle(String::NewFormatted(                 \
+        "Expected a TypedData object but found %s", instance.ToCString()));    \
+    const Array& args = Array::Handle(Array::New(1));                          \
+    args.SetAt(0, error);                                                      \
+    Exceptions::ThrowByType(Exceptions::kArgument, args);                      \
+  }                                                                            \
+  return Object::null();                                                       \
+}
+
+
+#define TYPED_DATA_UINT64_GETTER(getter, object)                               \
+DEFINE_NATIVE_ENTRY(TypedData_##getter, 2) {                                   \
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0)); \
+  GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes, arguments->NativeArgAt(1)); \
+  uint64_t value = 0;                                                          \
+  if (instance.IsTypedData()) {                                                \
+    const TypedData& array = TypedData::Cast(instance);                        \
+    ASSERT(RangeCheck(offsetInBytes.Value(), array.LengthInBytes()));          \
+    value = array.getter(offsetInBytes.Value());                               \
+  } else if (instance.IsExternalTypedData()) {                                 \
+    const ExternalTypedData& array = ExternalTypedData::Cast(instance);        \
+    ASSERT(RangeCheck(offsetInBytes.Value(), array.LengthInBytes()));          \
+    value = array.getter(offsetInBytes.Value());                               \
+  } else {                                                                     \
+    const String& error = String::Handle(String::NewFormatted(                 \
+        "Expected a TypedData object but found %s", instance.ToCString()));    \
+    const Array& args = Array::Handle(Array::New(1));                          \
+    args.SetAt(0, error);                                                      \
+    Exceptions::ThrowByType(Exceptions::kArgument, args);                      \
+  }                                                                            \
+  Integer& result = Integer::Handle();                                         \
+  if (value > static_cast<uint64_t>(Mint::kMaxValue)) {                        \
+    result = BigintOperations::NewFromUint64(value);                           \
+  } else if (value > static_cast<uint64_t>(Smi::kMaxValue)) {                  \
+    result = Mint::New(value);                                                 \
+  } else {                                                                     \
+    result = Smi::New(value);                                                  \
+  }                                                                            \
+  return result.raw();                                                         \
+}                                                                              \
+
+
+// TODO(asiva): Consider truncating the bigint value if it does not fit into
+// a uint64_t value (see ASSERT(BigintOperations::FitsIntoUint64(bigint))).
+#define TYPED_DATA_UINT64_SETTER(setter, object)                               \
+DEFINE_NATIVE_ENTRY(TypedData_##setter, 3) {                                   \
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0)); \
+  GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes, arguments->NativeArgAt(1)); \
+  GET_NON_NULL_NATIVE_ARGUMENT(object, value, arguments->NativeArgAt(2));      \
+  uint64_t object_value;                                                       \
+  if (value.IsBigint()) {                                                      \
+    const Bigint& bigint = Bigint::Cast(value);                                \
+    ASSERT(BigintOperations::FitsIntoUint64(bigint));                          \
+    object_value = BigintOperations::AbsToUint64(bigint);                      \
+  } else {                                                                     \
+    ASSERT(value.IsMint() || value.IsSmi());                                   \
+    object_value = value.AsInt64Value();                                       \
+  }                                                                            \
+  if (instance.IsTypedData()) {                                                \
+    const TypedData& array = TypedData::Cast(instance);                        \
+    ASSERT(RangeCheck(offsetInBytes.Value(), array.LengthInBytes()));          \
+    array.setter(offsetInBytes.Value(), object_value);                         \
+  } else if (instance.IsExternalTypedData()) {                                 \
+    const ExternalTypedData& array = ExternalTypedData::Cast(instance);        \
+    ASSERT(RangeCheck(offsetInBytes.Value(), array.LengthInBytes()));          \
+    array.setter(offsetInBytes.Value(), object_value);                         \
+  } else {                                                                     \
+    const String& error = String::Handle(String::NewFormatted(                 \
+        "Expected a TypedData object but found %s", instance.ToCString()));    \
+    const Array& args = Array::Handle(Array::New(1));                          \
+    args.SetAt(0, error);                                                      \
+    Exceptions::ThrowByType(Exceptions::kArgument, args);                      \
+  }                                                                            \
+  return Object::null();                                                       \
+}
+
+
+#define TYPED_DATA_NATIVES(name, getter, setter, object, get_object_value)     \
+  TYPED_DATA_GETTER(getter, object)                                            \
+  TYPED_DATA_SETTER(setter, object, get_object_value)                          \
+
+
+#define TYPED_DATA_UINT64_NATIVES(name, getter, setter, object)                \
+  TYPED_DATA_UINT64_GETTER(getter, object)                                     \
+  TYPED_DATA_UINT64_SETTER(setter, object)                                     \
+
+
+TYPED_DATA_NATIVES(Int8Array, GetInt8, SetInt8, Smi, Value)
+TYPED_DATA_NATIVES(Uint8Array, GetUint8, SetUint8, Smi, Value)
+TYPED_DATA_NATIVES(Int16Array, GetInt16, SetInt16, Smi, Value)
+TYPED_DATA_NATIVES(Uint16Array, GetUint16, SetUint16, Smi, Value)
+TYPED_DATA_NATIVES(Int32Array, GetInt32, SetInt32, Integer, AsInt64Value)
+TYPED_DATA_NATIVES(Uint32Array, GetUint32, SetUint32, Integer, AsInt64Value)
+TYPED_DATA_NATIVES(Int64Array, GetInt64, SetInt64, Integer, AsInt64Value)
+TYPED_DATA_UINT64_NATIVES(Uint64Array, GetUint64, SetUint64, Integer)
+TYPED_DATA_NATIVES(Float32Array, GetFloat32, SetFloat32, Double, value)
+TYPED_DATA_NATIVES(Float64Array, GetFloat64, SetFloat64, Double, value)
+
+}  // namespace dart
diff --git a/runtime/lib/typeddata.dart b/runtime/lib/typeddata.dart
new file mode 100644
index 0000000..cf049d7
--- /dev/null
+++ b/runtime/lib/typeddata.dart
@@ -0,0 +1,2637 @@
+// 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.
+
+// patch classes for Int8List ..... Float64List and ByteData implementations.
+
+patch class Int8List {
+  /* patch */ factory Int8List(int length) {
+    return new _Int8Array(length);
+  }
+
+  /* patch */ factory Int8List.transferable(int length) {
+    return _newTransferable(length);
+  }
+
+  /* patch */ factory Int8List.view(ByteBuffer buffer,
+                                    [int offsetInBytes = 0, int length]) {
+    return new _Int8ArrayView(buffer, offsetInBytes, length);
+  }
+
+  static _ExternalInt8Array _newTransferable(int length) {
+    return new _ExternalInt8Array(length);
+  }
+}
+
+
+patch class Uint8List {
+  /* patch */ factory Uint8List(int length) {
+    return new _Uint8Array(length);
+  }
+
+  /* patch */ factory Uint8List.transferable(int length) {
+    return _newTransferable(length);
+  }
+
+  /* patch */ factory Uint8List.view(ByteBuffer buffer,
+                                     [int offsetInBytes = 0, int length]) {
+    return new _Uint8ArrayView(buffer, offsetInBytes, length);
+  }
+
+  static _ExternalUint8Array _newTransferable(int length) {
+    return new _ExternalUint8Array(length);
+  }
+}
+
+
+patch class Uint8ClampedList {
+  /* patch */ factory Uint8ClampedList(int length) {
+    return new _Uint8ClampedArray(length);
+  }
+
+  /* patch */ factory Uint8ClampedList.transferable(int length) {
+    return _newTransferable(length);
+  }
+
+  /* patch */ factory Uint8ClampedList.view(ByteBuffer buffer,
+                                            [int offsetInBytes = 0,
+                                             int length]) {
+    return new _Uint8ClampedArrayView(buffer, offsetInBytes, length);
+  }
+
+  static _ExternalUint8ClampedArray _newTransferable(int length) {
+    return new _ExternalUint8ClampedArray(length);
+  }
+}
+
+
+patch class Int16List {
+  /* patch */ factory Int16List(int length) {
+    return new _Int16Array(length);
+  }
+
+  /* patch */ factory Int16List.transferable(int length) {
+    return _newTransferable(length);
+  }
+
+  /* patch */ factory Int16List.view(ByteBuffer buffer,
+                                     [int offsetInBytes = 0, int length]) {
+    return new _Int16ArrayView(buffer, offsetInBytes, length);
+  }
+
+  static _ExternalInt16Array _newTransferable(int length) {
+    return new _ExternalInt16Array(length);
+  }
+}
+
+
+patch class Uint16List {
+  /* patch */ factory Uint16List(int length) {
+    return new _Uint16Array(length);
+  }
+
+  /* patch */ factory Uint16List.transferable(int length) {
+    return _newTransferable(length);
+  }
+
+  /* patch */ factory Uint16List.view(ByteBuffer buffer,
+                                      [int offsetInBytes = 0, int length]) {
+    return new _Uint16ArrayView(buffer, offsetInBytes, length);
+  }
+
+  static _ExternalUint16Array _newTransferable(int length) {
+    return new _ExternalUint16Array(length);
+  }
+}
+
+
+patch class Int32List {
+  /* patch */ factory Int32List(int length) {
+    return new _Int32Array(length);
+  }
+
+  /* patch */ factory Int32List.transferable(int length) {
+    return _newTransferable(length);
+  }
+
+  /* patch */ factory Int32List.view(ByteBuffer buffer,
+                                     [int offsetInBytes = 0, int length]) {
+    return new _Int32ArrayView(buffer, offsetInBytes, length);
+  }
+
+  static _ExternalInt32Array _newTransferable(int length) {
+    return new _ExternalInt32Array(length);
+  }
+}
+
+
+patch class Uint32List {
+  /* patch */ factory Uint32List(int length) {
+    return new _Uint32Array(length);
+  }
+
+  /* patch */ factory Uint32List.transferable(int length) {
+    return _newTransferable(length);
+  }
+
+  /* patch */ factory Uint32List.view(ByteBuffer buffer,
+                                      [int offsetInBytes = 0, int length]) {
+    return new _Uint32ArrayView(buffer, offsetInBytes, length);
+  }
+
+  static _ExternalUint32Array _newTransferable(int length) {
+    return new _ExternalUint32Array(length);
+  }
+}
+
+
+patch class Int64List {
+  /* patch */ factory Int64List(int length) {
+    return new _Int64Array(length);
+  }
+
+  /* patch */ factory Int64List.transferable(int length) {
+    return _newTransferable(length);
+  }
+
+  /* patch */ factory Int64List.view(ByteBuffer buffer,
+                                     [int offsetInBytes = 0, int length]) {
+    return new _Int64ArrayView(buffer, offsetInBytes, length);
+  }
+
+  static _ExternalInt64Array _newTransferable(int length) {
+    return new _ExternalInt64Array(length);
+  }
+}
+
+
+patch class Uint64List {
+  /* patch */ factory Uint64List(int length) {
+    return new _Uint64Array(length);
+  }
+
+  /* patch */ factory Uint64List.transferable(int length) {
+    return _newTransferable(length);
+  }
+
+  /* patch */ factory Uint64List.view(ByteBuffer buffer,
+                                      [int offsetInBytes = 0, int length]) {
+    return new _Uint64ArrayView(buffer, offsetInBytes, length);
+  }
+
+  static _ExternalUint64Array _newTransferable(int length) {
+    return new _ExternalUint64Array(length);
+  }
+}
+
+
+patch class Float32List {
+  /* patch */ factory Float32List(int length) {
+    return new _Float32Array(length);
+  }
+
+  /* patch */ factory Float32List.transferable(int length) {
+    return _newTransferable(length);
+  }
+
+  /* patch */ factory Float32List.view(ByteBuffer buffer,
+                                       [int offsetInBytes = 0, int length]) {
+    return new _Float32ArrayView(buffer, offsetInBytes, length);
+  }
+
+  static _ExternalFloat32Array _newTransferable(int length) {
+    return new _ExternalFloat32Array(length);
+  }
+}
+
+
+patch class Float64List {
+  /* patch */ factory Float64List(int length) {
+    return new _Float64Array(length);
+  }
+
+  /* patch */ factory Float64List.transferable(int length) {
+    return _newTransferable(length);
+  }
+
+  /* patch */ factory Float64List.view(ByteBuffer buffer,
+                                       [int offsetInBytes = 0, int length]) {
+    return new _Float64ArrayView(buffer, offsetInBytes, length);
+  }
+
+  static _ExternalFloat64Array _newTransferable(int length) {
+    return new _ExternalFloat64Array(length);
+  }
+}
+
+
+patch class ByteData {
+  /* patch */ factory ByteData(int length) {
+    var list = new _Uint8Array(length);
+    return new _ByteDataView(list.buffer);
+  }
+
+  /* patch */ factory ByteData.transferable(int length) {
+    var list = new _Uint8Array.transferable(length);
+    return new _ByteDataView(list.buffer);
+  }
+
+  /* patch */ factory ByteData.view(ByteBuffer buffer,
+                                    [int offsetInBytes = 0, int length]) {
+    if (length == null) {
+      length = buffer.lengthInBytes;
+    }
+    return new _ByteDataView(buffer, offsetInBytes, length);
+  }
+}
+
+
+// Based class for _TypedList that provides common methods for implementing
+// the collection and list interfaces.
+
+abstract class _TypedListBase {
+  // Method(s) implementing the Collection interface.
+  bool contains(element) => IterableMixinWorkaround.contains(this, element);
+
+  void forEach(void f(element)) {
+    var len = this.length;
+    for (var i = 0; i < len; i++) {
+      f(this[i]);
+    }
+  }
+
+  Iterable map(f(int element)) {
+    return IterableMixinWorkaround.mapList(this, f);
+  }
+
+  String join([String separator]) {
+    return IterableMixinWorkaround.join(this, separator);
+  }
+
+  dynamic reduce(dynamic initialValue,
+                 dynamic combine(dynamic initialValue, element)) {
+    return IterableMixinWorkaround.reduce(this, initialValue, combine);
+  }
+
+  Collection where(bool f(int element)) {
+    return IterableMixinWorkaround.where(this, f);
+  }
+
+  Iterable expand(Iterable f(int element)) {
+    return IterableMixinWorkaround.expand(this, f);
+  }
+
+  Iterable take(int n) {
+    return IterableMixinWorkaround.takeList(this, n);
+  }
+
+  Iterable takeWhile(bool test(int value)) {
+    return IterableMixinWorkaround.takeWhile(this, test);
+  }
+
+  Iterable skip(int n) {
+    return IterableMixinWorkaround.skipList(this, n);
+  }
+
+  Iterable skipWhile(bool test(int value)) {
+    return IterableMixinWorkaround.skipWhile(this, test);
+  }
+
+  bool every(bool f(element)) {
+    return IterableMixinWorkaround.every(this, f);
+  }
+
+  bool any(bool f(element)) {
+    return IterableMixinWorkaround.any(this, f);
+  }
+
+  int firstWhere(bool test(int value), {int orElse()}) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
+  }
+
+  int lastWhere(bool test(int value), {int orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
+  }
+
+  int singleWhere(bool test(int value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
+  }
+
+  int elementAt(int index) {
+    return this[index];
+  }
+
+  bool get isEmpty {
+    return this.length == 0;
+  }
+
+
+  // Method(s) implementing the List interface.
+
+  set length(newLength) {
+    throw new UnsupportedError(
+        "Cannot resize a non-extendable array");
+  }
+
+  void add(value) {
+    throw new UnsupportedError(
+        "Cannot add to a non-extendable array");
+  }
+
+  void addLast(value) {
+    throw new UnsupportedError(
+        "Cannot add to a non-extendable array");
+  }
+
+  void addAll(Iterable value) {
+    throw new UnsupportedError(
+        "Cannot add to a non-extendable array");
+  }
+
+  void sort([int compare(var a, var b)]) {
+    return IterableMixinWorkaround.sortList(this, compare);
+  }
+
+  int indexOf(element, [int start = 0]) {
+    return IterableMixinWorkaround.indexOfList(this, element, start);
+  }
+
+  int lastIndexOf(element, [int start = null]) {
+    return IterableMixinWorkaround.lastIndexOfList(this, element, start);
+  }
+
+  void clear() {
+    throw new UnsupportedError(
+        "Cannot remove from a non-extendable array");
+  }
+
+  int removeLast() {
+    throw new UnsupportedError(
+        "Cannot remove from a non-extendable array");
+  }
+
+  void remove(Object element) {
+    throw new UnsupportedError(
+        "Cannot remove from a non-extendable array");
+  }
+
+  void removeAll(Iterable elements) {
+    throw new UnsupportedError(
+        "Cannot remove from a non-extendable array");
+  }
+
+  void retainAll(Iterable elements) {
+    throw new UnsupportedError(
+        "Cannot remove from a non-extendable array");
+  }
+
+  void removeWhere(bool test(int element)) {
+    throw new UnsupportedError(
+        "Cannot remove from a non-extendable array");
+  }
+
+  void retainWhere(bool test(int element)) {
+    throw new UnsupportedError(
+        "Cannot remove from a non-extendable array");
+  }
+
+  int get first {
+    if (length > 0) return this[0];
+    throw new StateError("No elements");
+  }
+
+  int get last {
+    if (length > 0) return this[length - 1];
+    throw new StateError("No elements");
+  }
+
+  int get single {
+    if (length == 1) return this[0];
+    if (length == 0) throw new StateError("No elements");
+    throw new StateError("More than one element");
+  }
+
+  int min([int compare(int a, int b)]) =>
+    IterableMixinWorkaround.min(this, compare);
+
+  int max([int compare(int a, int b)]) =>
+    IterableMixinWorkaround.max(this, compare);
+
+  void removeRange(int start, int length) {
+    throw new UnsupportedError(
+        "Cannot remove from a non-extendable array");
+  }
+
+  void insertRange(int start, int length, [initialValue]) {
+    throw new UnsupportedError(
+        "Cannot add to a non-extendable array");
+  }
+
+  List toList() {
+    return new List.from(this);
+  }
+
+  Set toSet() {
+    return new Set.from(this);
+  }
+
+  List sublist(int start, [int end]) {
+    if (end == null) end = length;
+    int length = end - start;
+    _rangeCheck(this.length, start, length);
+    List result = _createList(length);
+    result.setRange(0, length, this, start);
+    return result;
+  }
+
+  List getRange(int start, int length) {
+    return sublist(start, start + length);
+  }
+
+  void setRange(int start, int length, List from, [int startFrom = 0]) {
+    if (!_setRange(start, length, from, startFrom)) {
+      IterableMixinWorkaround.setRangeList(this, start,
+                                           length, from, startFrom);
+    }
+  }
+
+
+  // Method(s) implementing Object interface.
+
+  String toString() {
+    return Collections.collectionToString(this);
+  }
+
+
+  // Internal utility methods.
+
+  bool _setRange(int start, int length, List from, startFrom)
+      native "TypedData_setRange";
+}
+
+
+abstract class _TypedList extends _TypedListBase implements ByteBuffer {
+  // Default method implementing parts of the TypedData interface.
+  int get offsetInBytes {
+    return 0;
+  }
+
+  int get lengthInBytes {
+    return length * elementSizeInBytes;
+  }
+
+  ByteBuffer get buffer {
+    return this;
+  }
+
+
+  // Methods implementing the collection interface.
+
+  int get length native "TypedData_length";
+
+
+  // Internal utility methods.
+
+  int _getInt8(int offsetInBytes) native "TypedData_GetInt8";
+  void _setInt8(int offsetInBytes, int value) native "TypedData_SetInt8";
+
+  int _getUint8(int offsetInBytes) native "TypedData_GetUint8";
+  void _setUint8(int offsetInBytes, int value) native "TypedData_SetUint8";
+
+  int _getInt16(int offsetInBytes) native "TypedData_GetInt16";
+  void _setInt16(int offsetInBytes, int value) native "TypedData_SetInt16";
+
+  int _getUint16(int offsetInBytes) native "TypedData_GetUint16";
+  void _setUint16(int offsetInBytes, int value) native "TypedData_SetUint16";
+
+  int _getInt32(int offsetInBytes) native "TypedData_GetInt32";
+  void _setInt32(int offsetInBytes, int value) native "TypedData_SetInt32";
+
+  int _getUint32(int offsetInBytes) native "TypedData_GetUint32";
+  void _setUint32(int offsetInBytes, int value) native "TypedData_SetUint32";
+
+  int _getInt64(int offsetInBytes) native "TypedData_GetInt64";
+  void _setInt64(int offsetInBytes, int value) native "TypedData_SetInt64";
+
+  int _getUint64(int offsetInBytes) native "TypedData_GetUint64";
+  void _setUint64(int offsetInBytes, int value) native "TypedData_SetUint64";
+
+  double _getFloat32(int offsetInBytes) native "TypedData_GetFloat32";
+  void _setFloat32(int offsetInBytes, double value)
+      native "TypedData_SetFloat32";
+
+  double _getFloat64(int offsetInBytes) native "TypedData_GetFloat64";
+  void _setFloat64(int offsetInBytes, double value)
+      native "TypedData_SetFloat64";
+}
+
+
+class _Int8Array extends _TypedList implements Int8List {
+  // Factory constructors.
+
+  factory _Int8Array(int length) {
+    if (length < 0) {
+      String message = "$length must be greater than 0";
+      throw new ArgumentError(message);
+    }
+    return _new(length);
+  }
+
+  factory _Int8Array.view(ByteBuffer buffer,
+                          [int offsetInBytes = 0, int length]) {
+    if (length == null) {
+      length = buffer.lengthInBytes;
+    }
+    return new _Int8ArrayView(buffer, offsetInBytes, length);
+  }
+
+
+  // Method(s) implementing List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _getInt8(index);
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _setInt8(index, _toInt8(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing TypedData interface.
+
+  int get elementSizeInBytes {
+    return Int8List.BYTES_PER_ELEMENT;
+  }
+
+
+  // Internal utility methods.
+
+  _Int8Array _createList(int length) {
+    return _new(length);
+  }
+
+  static _Int8Array _new(int length) native "TypedData_Int8Array_new";
+}
+
+
+class _Uint8Array extends _TypedList implements Uint8List {
+  // Factory constructors.
+
+  factory _Uint8Array(int length) {
+    if (length < 0) {
+      String message = "$length must be greater than 0";
+      throw new ArgumentError(message);
+    }
+    return _new(length);
+  }
+
+  factory _Uint8Array.view(ByteBuffer buffer,
+                           [int offsetInBytes = 0, int length]) {
+    if (length == null) {
+      length = buffer.lengthInBytes;
+    }
+    return new _Uint8ArrayView(buffer, offsetInBytes, length);
+  }
+
+
+  // Methods implementing List interface.
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _getUint8(index);
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _setUint8(index, _toUint8(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Methods implementing TypedData interface.
+  int get elementSizeInBytes {
+    return Uint8List.BYTES_PER_ELEMENT;
+  }
+
+
+  // Internal utility methods.
+
+  _Uint8Array _createList(int length) {
+    return _new(length);
+  }
+
+  static _Uint8Array _new(int length) native "TypedData_Uint8Array_new";
+}
+
+
+class _Uint8ClampedArray extends _TypedList implements Uint8ClampedList {
+  // Factory constructors.
+
+  factory _Uint8ClampedArray(int length) {
+    if (length < 0) {
+      String message = "$length must be greater than 0";
+      throw new ArgumentError(message);
+    }
+    return _new(length);
+  }
+
+  factory _Uint8ClampedArray.view(ByteBuffer buffer,
+                                  [int offsetInBytes = 0, int length]) {
+    if (length == null) {
+      length = buffer.lengthInBytes;
+    }
+    return new _Uint8ClampedArrayView(buffer, offsetInBytes, length);
+  }
+
+
+  // Methods implementing List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _getUint8(index);
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _setUint8(index, _toClampedUint8(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Methods implementing TypedData interface.
+  int get elementSizeInBytes {
+    return Uint8List.BYTES_PER_ELEMENT;
+  }
+
+
+  // Internal utility methods.
+
+  _Uint8ClampedArray _createList(int length) {
+    return _new(length);
+  }
+
+  static _Uint8ClampedArray _new(int length)
+      native "TypedData_Uint8ClampedArray_new";
+}
+
+
+class _Int16Array extends _TypedList implements Int16List {
+  // Factory constructors.
+
+  factory _Int16Array(int length) {
+    if (length < 0) {
+      String message = "$length must be greater than 0";
+      throw new ArgumentError(message);
+    }
+    return _new(length);
+  }
+
+  factory _Int16Array.view(ByteBuffer buffer,
+                           [int offsetInBytes = 0, int length]) {
+    if (length == null) {
+      length = (buffer.lengthInBytes - offsetInBytes) ~/
+               Int16List.BYTES_PER_ELEMENT;
+    }
+    return new _Int16ArrayView(buffer, offsetInBytes, length);
+  }
+
+
+  // Method(s) implementing List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _getIndexedInt16(index);
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _setIndexedInt16(index, _toInt16(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing TypedData interface.
+
+  int get elementSizeInBytes {
+    return Int16List.BYTES_PER_ELEMENT;
+  }
+
+
+  // Internal utility methods.
+
+  _Int16Array _createList(int length) {
+    return _new(length);
+  }
+
+  int _getIndexedInt16(int index) {
+    return _getInt16(index * Int16List.BYTES_PER_ELEMENT);
+  }
+
+  void _setIndexedInt16(int index, int value) {
+    _setInt16(index * Int16List.BYTES_PER_ELEMENT, value);
+  }
+
+  static _Int16Array _new(int length) native "TypedData_Int16Array_new";
+}
+
+
+class _Uint16Array extends _TypedList implements Uint16List {
+  // Factory constructors.
+
+  factory _Uint16Array(int length) {
+    if (length < 0) {
+      String message = "$length must be greater than 0";
+      throw new ArgumentError(message);
+    }
+    return _new(length);
+  }
+
+  factory _Uint16Array.view(ByteBuffer buffer,
+                            [int offsetInBytes = 0, int length]) {
+    if (length == null) {
+      length = (buffer.lengthInBytes - offsetInBytes) ~/
+                Uint16List.BYTES_PER_ELEMENT;
+    }
+    return new _Uint16ArrayView(buffer, offsetInBytes, length);
+  }
+
+
+  // Method(s) implementing the List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _getIndexedUint16(index);
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _setIndexedUint16(index, _toUint16(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing the TypedData interface.
+
+  int get elementSizeInBytes {
+    return Uint16List.BYTES_PER_ELEMENT;
+  }
+
+
+  // Internal utility methods.
+
+  _Uint16Array _createList(int length) {
+    return _new(length);
+  }
+
+  int _getIndexedUint16(int index) {
+    return _getUint16(index * Uint16List.BYTES_PER_ELEMENT);
+  }
+
+  void _setIndexedUint16(int index, int value) {
+    _setUint16(index * Uint16List.BYTES_PER_ELEMENT, value);
+  }
+
+  static _Uint16Array _new(int length) native "TypedData_Uint16Array_new";
+}
+
+
+class _Int32Array extends _TypedList implements Int32List {
+  // Factory constructors.
+
+  factory _Int32Array(int length) {
+    if (length < 0) {
+      String message = "$length must be greater than 0";
+      throw new ArgumentError(message);
+    }
+    return _new(length);
+  }
+
+  factory _Int32Array.view(ByteBuffer buffer,
+                           [int offsetInBytes = 0, int length]) {
+    if (length == null) {
+      length = (buffer.lengthInBytes - offsetInBytes) ~/
+                Int32List.BYTES_PER_ELEMENT;
+    }
+    return new _Int32ArrayView(buffer, offsetInBytes, length);
+  }
+
+
+  // Method(s) implementing the List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _getIndexedInt32(index);
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _setIndexedInt32(index, _toInt32(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing TypedData interface.
+
+  int get elementSizeInBytes {
+    return Int32List.BYTES_PER_ELEMENT;
+  }
+
+
+  // Internal utility methods.
+
+  _Int32Array _createList(int length) {
+    return _new(length);
+  }
+
+  int _getIndexedInt32(int index) {
+    return _getInt32(index * Int32List.BYTES_PER_ELEMENT);
+  }
+
+  void _setIndexedInt32(int index, int value) {
+    _setInt32(index * Int32List.BYTES_PER_ELEMENT, value);
+  }
+
+  static _Int32Array _new(int length) native "TypedData_Int32Array_new";
+}
+
+
+class _Uint32Array extends _TypedList implements Uint32List {
+  // Factory constructors.
+
+  factory _Uint32Array(int length) {
+    if (length < 0) {
+      String message = "$length must be greater than 0";
+      throw new ArgumentError(message);
+    }
+    return _new(length);
+  }
+
+  factory _Uint32Array.view(ByteBuffer buffer,
+                            [int offsetInBytes = 0, int length]) {
+    if (length == null) {
+      length = (buffer.lengthInBytes - offsetInBytes) ~/
+                Uint32List.BYTES_PER_ELEMENT;
+    }
+    return new _Uint32ArrayView(buffer, offsetInBytes, length);
+  }
+
+
+  // Method(s) implementing the List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _getIndexedUint32(index);
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _setIndexedUint32(index, _toUint32(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing the TypedData interface.
+
+  int get elementSizeInBytes {
+    return Uint32List.BYTES_PER_ELEMENT;
+  }
+
+
+  // Internal utility methods.
+
+  _Uint32Array _createList(int length) {
+    return _new(length);
+  }
+
+  int _getIndexedUint32(int index) {
+    return _getUint32(index * Uint32List.BYTES_PER_ELEMENT);
+  }
+
+  void _setIndexedUint32(int index, int value) {
+    _setInt32(index * Uint32List.BYTES_PER_ELEMENT, value);
+  }
+
+  static _Uint32Array _new(int length) native "TypedData_Uint32Array_new";
+}
+
+
+class _Int64Array extends _TypedList implements Int64List {
+  // Factory constructors.
+
+  factory _Int64Array(int length) {
+    if (length < 0) {
+      String message = "$length must be greater than 0";
+      throw new ArgumentError(message);
+    }
+    return _new(length);
+  }
+
+  factory _Int64Array.view(ByteBuffer buffer,
+                           [int offsetInBytes = 0, int length]) {
+    if (length == null) {
+      length = (buffer.lengthInBytes - offsetInBytes) ~/
+                Int32List.BYTES_PER_ELEMENT;
+    }
+    return new _Int64ArrayView(buffer, offsetInBytes, length);
+  }
+
+
+  // Method(s) implementing the List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _getIndexedInt64(index);
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _setIndexedInt64(index, _toInt64(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing the TypedData interface.
+
+  int get elementSizeInBytes {
+    return Int64List.BYTES_PER_ELEMENT;
+  }
+
+
+  // Internal utility methods.
+
+  _Int64Array _createList(int length) {
+    return _new(length);
+  }
+
+  int _getIndexedInt64(int index) {
+    return _getInt64(index * Int64List.BYTES_PER_ELEMENT);
+  }
+
+  void _setIndexedInt64(int index, int value) {
+    _setInt64(index * Int64List.BYTES_PER_ELEMENT, value);
+  }
+
+  static _Int64Array _new(int length) native "TypedData_Int64Array_new";
+}
+
+
+class _Uint64Array extends _TypedList implements Uint64List {
+  // Factory constructors.
+
+  factory _Uint64Array(int length) {
+    if (length < 0) {
+      String message = "$length must be greater than 0";
+      throw new ArgumentError(message);
+    }
+    return _new(length);
+  }
+
+  factory _Uint64Array.view(ByteBuffer buffer,
+                            [int offsetInBytes = 0, int length]) {
+    if (length == null) {
+      length = (buffer.lengthInBytes - offsetInBytes) ~/
+               Uint64List.BYTES_PER_ELEMENT;
+    }
+    return new _Uint64ArrayView(buffer, offsetInBytes, length);
+  }
+
+
+  // Method(s) implementing the List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _getIndexedUint64(index);
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _setIndexedUint64(index, _toUint64(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing the TypedData interface.
+
+  int get elementSizeInBytes {
+    return Uint64List.BYTES_PER_ELEMENT;
+  }
+
+
+  // Internal utility methods.
+
+  _Uint64Array _createList(int length) {
+    return _new(length);
+  }
+
+  int _getIndexedUint64(int index) {
+    return _getUint64(index * Uint64List.BYTES_PER_ELEMENT);
+  }
+
+  void _setIndexedUint64(int index, int value) {
+    _setUint64(index * Uint64List.BYTES_PER_ELEMENT, value);
+  }
+
+  static _Uint64Array _new(int length) native "TypedData_Uint64Array_new";
+}
+
+
+class _Float32Array extends _TypedList implements Float32List {
+  // Factory constructors.
+
+  factory _Float32Array(int length) {
+    if (length < 0) {
+      String message = "$length must be greater than 0";
+      throw new ArgumentError(message);
+    }
+    return _new(length);
+  }
+
+  factory _Float32Array.view(ByteBuffer buffer,
+                             [int offsetInBytes = 0, int length]) {
+    if (length == null) {
+      length = (buffer.lengthInBytes - offsetInBytes) ~/
+               Float32List.BYTES_PER_ELEMENT;
+    }
+    return new _Float32ArrayView(buffer, offsetInBytes, length);
+  }
+
+
+  // Method(s) implementing the List interface.
+
+  double operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _getIndexedFloat32(index);
+  }
+
+  void operator[]=(int index, double value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _setIndexedFloat32(index, value);
+  }
+
+  Iterator<double> get iterator {
+    return new _TypedListIterator<double>(this);
+  }
+
+
+  // Method(s) implementing the TypedData interface.
+
+  int get elementSizeInBytes {
+    return Float32List.BYTES_PER_ELEMENT;
+  }
+
+
+  // Internal utility methods.
+
+  _Float32Array _createList(int length) {
+    return _new(length);
+  }
+
+  double _getIndexedFloat32(int index) {
+    return _getFloat32(index * Float32List.BYTES_PER_ELEMENT);
+  }
+
+  void _setIndexedFloat32(int index, double value) {
+    _setFloat32(index * Float32List.BYTES_PER_ELEMENT, value);
+  }
+
+  static _Float32Array _new(int length) native "TypedData_Float32Array_new";
+}
+
+
+class _Float64Array extends _TypedList implements Float64List {
+  // Factory constructors.
+
+  factory _Float64Array(int length) {
+    if (length < 0) {
+      String message = "$length must be greater than 0";
+      throw new ArgumentError(message);
+    }
+    return _new(length);
+  }
+
+  factory _Float64Array.view(ByteBuffer buffer,
+                             [int offsetInBytes = 0, int length]) {
+    if (length == null) {
+      length = (buffer.lengthInBytes - offsetInBytes) ~/
+               Float64List.BYTES_PER_ELEMENT;
+    }
+    return new _Float64ArrayView(buffer, offsetInBytes, length);
+  }
+
+
+  // Method(s) implementing the List interface.
+
+  double operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _getIndexedFloat64(index);
+  }
+
+  void operator[]=(int index, double value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _setIndexedFloat64(index, value);
+  }
+
+  Iterator<double> get iterator {
+    return new _TypedListIterator<double>(this);
+  }
+
+
+  // Method(s) implementing the TypedData interface.
+
+  int get elementSizeInBytes {
+    return Float64List.BYTES_PER_ELEMENT;
+  }
+
+
+  // Internal utility methods.
+
+  _Float64Array _createList(int length) {
+    return _new(length);
+  }
+
+  double _getIndexedFloat64(int index) {
+    return _getFloat64(index * Float64List.BYTES_PER_ELEMENT);
+  }
+
+  void _setIndexedFloat64(int index, double value) {
+    _setFloat64(index * Float64List.BYTES_PER_ELEMENT, value);
+  }
+
+  static _Float64Array _new(int length) native "TypedData_Float64Array_new";
+}
+
+
+class _ExternalInt8Array extends _TypedList implements Int8List {
+  // Factory constructors.
+
+  factory _ExternalInt8Array(int length) {
+    if (length < 0) {
+      String message = "$length must be greater than 0";
+      throw new ArgumentError(message);
+    }
+    return _new(length);
+  }
+
+
+  // Method(s) implementing the List interface.
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _getInt8(index);
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _setInt8(index, value);
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing the TypedData interface.
+
+  int get elementSizeInBytes {
+    return Int8List.BYTES_PER_ELEMENT;
+  }
+
+
+  // Internal utility methods.
+
+  Int8List _createList(int length) {
+    return new Int8List(length);
+  }
+
+  static _ExternalInt8Array _new(int length) native
+      "ExternalTypedData_Int8Array_new";
+}
+
+
+class _ExternalUint8Array extends _TypedList implements Uint8List {
+  // Factory constructors.
+
+  factory _ExternalUint8Array(int length) {
+    if (length < 0) {
+      String message = "$length must be greater than 0";
+      throw new ArgumentError(message);
+    }
+    return _new(length);
+  }
+
+
+  // Method(s) implementing the List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _getUint8(index);
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _setUint8(index, _toUint8(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing the TypedData interface.
+
+  int get elementSizeInBytes {
+    return Uint8List.BYTES_PER_ELEMENT;
+  }
+
+
+  // Internal utility methods.
+
+  Uint8List _createList(int length) {
+    return new Uint8List(length);
+  }
+
+  static _ExternalUint8Array _new(int length) native
+      "ExternalTypedData_Uint8Array_new";
+}
+
+
+class _ExternalUint8ClampedArray extends _TypedList implements Uint8ClampedList {
+  // Factory constructors.
+
+  factory _ExternalUint8ClampedArray(int length) {
+    if (length < 0) {
+      String message = "$length must be greater than 0";
+      throw new ArgumentError(message);
+    }
+    return _new(length);
+  }
+
+
+  // Method(s) implementing the List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _getUint8(index);
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _setUint8(index, _toClampedUint8(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing the TypedData interface.
+
+  int get elementSizeInBytes {
+    return Uint8List.BYTES_PER_ELEMENT;
+  }
+
+
+  // Internal utility methods.
+
+  Uint8ClampedList _createList(int length) {
+    return new Uint8ClampedList(length);
+  }
+
+  static _ExternalUint8ClampedArray _new(int length) native
+      "ExternalTypedData_Uint8ClampedArray_new";
+}
+
+
+class _ExternalInt16Array extends _TypedList implements Int16List {
+  // Factory constructors.
+
+  factory _ExternalInt16Array(int length) {
+    if (length < 0) {
+      String message = "$length must be greater than 0";
+      throw new ArgumentError(message);
+    }
+    return _new(length);
+  }
+
+
+  // Method(s) implementing the List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _getIndexedInt16(index);
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _setIndexedInt16(index, _toInt16(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing the TypedData interface.
+
+  int get elementSizeInBytes {
+    return Int16List.BYTES_PER_ELEMENT;
+  }
+
+
+  // Internal utility methods.
+
+  Int16List _createList(int length) {
+    return new Int16List(length);
+  }
+
+  int _getIndexedInt16(int index) {
+    return _getInt16(index * Int16List.BYTES_PER_ELEMENT);
+  }
+
+  void _setIndexedInt16(int index, int value) {
+    _setInt16(index * Int16List.BYTES_PER_ELEMENT, value);
+  }
+
+  static _ExternalInt16Array _new(int length) native
+      "ExternalTypedData_Int16Array_new";
+}
+
+
+class _ExternalUint16Array extends _TypedList implements Uint16List {
+  // Factory constructors.
+
+  factory _ExternalUint16Array(int length) {
+    if (length < 0) {
+      String message = "$length must be greater than 0";
+      throw new ArgumentError(message);
+    }
+    return _new(length);
+  }
+
+
+  // Method(s) implementing the List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _getIndexedUint16(index);
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _setIndexedUint16(index, _toUint16(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing the TypedData interface.
+
+  int get elementSizeInBytes {
+    return Uint16List.BYTES_PER_ELEMENT;
+  }
+
+
+  // Internal utility methods.
+
+  Uint16List _createList(int length) {
+    return new Uint16List(length);
+  }
+
+  int _getIndexedUint16(int index) {
+    return _getUint16(index * Uint16List.BYTES_PER_ELEMENT);
+  }
+
+  void _setIndexedUint16(int index, int value) {
+    _setUint16(index * Uint16List.BYTES_PER_ELEMENT, value);
+  }
+
+  static _ExternalUint16Array _new(int length) native
+      "ExternalTypedData_Uint16Array_new";
+}
+
+
+class _ExternalInt32Array extends _TypedList implements Int32List {
+  // Factory constructors.
+
+  factory _ExternalInt32Array(int length) {
+    if (length < 0) {
+      String message = "$length must be greater than 0";
+      throw new ArgumentError(message);
+    }
+    return _new(length);
+  }
+
+
+  // Method(s) implementing the List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _getIndexedInt32(index);
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _setIndexedInt32(index, _toInt32(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing the TypedData interface.
+
+  int get elementSizeInBytes {
+    return Int32List.BYTES_PER_ELEMENT;
+  }
+
+
+  // Internal utility methods.
+
+  Int32List _createList(int length) {
+    return new Int32List(length);
+  }
+
+  int _getIndexedInt32(int index) {
+    return _getInt32(index * Int32List.BYTES_PER_ELEMENT);
+  }
+
+  void _setIndexedInt32(int index, int value) {
+    _setInt32(index * Int32List.BYTES_PER_ELEMENT, value);
+  }
+
+  static _ExternalInt32Array _new(int length) native
+      "ExternalTypedData_Int32Array_new";
+}
+
+
+class _ExternalUint32Array extends _TypedList implements Uint32List {
+  // Factory constructors.
+
+  factory _ExternalUint32Array(int length) {
+    if (length < 0) {
+      String message = "$length must be greater than 0";
+      throw new ArgumentError(message);
+    }
+    return _new(length);
+  }
+
+
+  // Method(s) implementing the List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _getIndexedUint32(index);
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _setIndexedUint32(index, _toUint32(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing the TypedData interface.
+
+  int get elementSizeInBytes {
+    return Uint32List.BYTES_PER_ELEMENT;
+  }
+
+
+  // Internal utility methods.
+
+  Uint32List _createList(int length) {
+    return new Uint32List(length);
+  }
+
+  int _getIndexedUint32(int index) {
+    return _getUint32(index * Uint32List.BYTES_PER_ELEMENT);
+  }
+
+  void _setIndexedUint32(int index, int value) {
+    _setInt32(index * Uint32List.BYTES_PER_ELEMENT, value);
+  }
+
+  static _ExternalUint32Array _new(int length) native
+      "ExternalTypedData_Uint32Array_new";
+}
+
+
+class _ExternalInt64Array extends _TypedList implements Int64List {
+  // Factory constructors.
+
+  factory _ExternalInt64Array(int length) {
+    if (length < 0) {
+      String message = "$length must be greater than 0";
+      throw new ArgumentError(message);
+    }
+    return _new(length);
+  }
+
+
+  // Method(s) implementing the List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _getIndexedInt64(index);
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _setIndexedInt64(index, _toInt64(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing the TypedData interface.
+
+  int get elementSizeInBytes {
+    return Int64List.BYTES_PER_ELEMENT;
+  }
+
+
+  // Internal utility methods.
+
+  Int64List _createList(int length) {
+    return new Int64List(length);
+  }
+
+  int _getIndexedInt64(int index) {
+    return _getInt64(index * Int64List.BYTES_PER_ELEMENT);
+  }
+
+  void _setIndexedInt64(int index, int value) {
+    _setInt64(index * Int64List.BYTES_PER_ELEMENT, value);
+  }
+
+  static _ExternalInt64Array _new(int length) native
+      "ExternalTypedData_Int64Array_new";
+}
+
+
+class _ExternalUint64Array extends _TypedList implements Uint64List {
+  // Factory constructors.
+
+  factory _ExternalUint64Array(int length) {
+    if (length < 0) {
+      String message = "$length must be greater than 0";
+      throw new ArgumentError(message);
+    }
+    return _new(length);
+  }
+
+
+  // Method(s) implementing the List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _getIndexedUint64(index);
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _setIndexedUint64(index, _toUint64(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing the TypedData interface.
+
+  int get elementSizeInBytes {
+    return Uint64List.BYTES_PER_ELEMENT;
+  }
+
+
+  // Internal utility methods.
+
+  Uint64List _createList(int length) {
+    return new Uint64List(length);
+  }
+
+  int _getIndexedUint64(int index) {
+    return _getUint64(index * Uint64List.BYTES_PER_ELEMENT);
+  }
+
+  void _setIndexedUint64(int index, int value) {
+    _setUint64(index * Uint64List.BYTES_PER_ELEMENT, value);
+  }
+
+  static _ExternalUint64Array _new(int length) native
+      "ExternalTypedData_Uint64Array_new";
+}
+
+
+class _ExternalFloat32Array extends _TypedList implements Float32List {
+  // Factory constructors.
+
+  factory _ExternalFloat32Array(int length) {
+    if (length < 0) {
+      String message = "$length must be greater than 0";
+      throw new ArgumentError(message);
+    }
+    return _new(length);
+  }
+
+
+  // Method(s) implementing the List interface.
+
+  double operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _getIndexedFloat32(index);
+  }
+
+  void operator[]=(int index, double value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _setIndexedFloat32(index, value);
+  }
+
+  Iterator<double> get iterator {
+    return new _TypedListIterator<double>(this);
+  }
+
+
+  // Method(s) implementing the TypedData interface.
+
+  int get elementSizeInBytes {
+    return Float32List.BYTES_PER_ELEMENT;
+  }
+
+
+  // Internal utility methods.
+
+  Float32List _createList(int length) {
+    return new Float32List(length);
+  }
+
+  double _getIndexedFloat32(int index) {
+    return _getFloat32(index * Float32List.BYTES_PER_ELEMENT);
+  }
+
+  void _setIndexedFloat32(int index, double value) {
+    _setFloat32(index * Float32List.BYTES_PER_ELEMENT, value);
+  }
+
+  static _ExternalFloat32Array _new(int length) native
+      "ExternalTypedData_Float32Array_new";
+}
+
+
+class _ExternalFloat64Array extends _TypedList implements Float64List {
+  // Factory constructors.
+
+  factory _ExternalFloat64Array(int length) {
+    if (length < 0) {
+      String message = "$length must be greater than 0";
+      throw new ArgumentError(message);
+    }
+    return _new(length);
+  }
+
+
+  // Method(s) implementing the List interface.
+
+  double operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _getIndexedFloat64(index);
+  }
+
+  void operator[]=(int index, double value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _setIndexedFloat64(index, value);
+  }
+
+  Iterator<double> get iterator {
+    return new _TypedListIterator<double>(this);
+  }
+
+
+  // Method(s) implementing the TypedData interface.
+
+  int get elementSizeInBytes {
+    return Float64List.BYTES_PER_ELEMENT;
+  }
+
+
+  // Internal utility methods.
+
+  Float64List _createList(int length) {
+    return new Float64List(length);
+  }
+
+  double _getIndexedFloat64(int index) {
+    return _getFloat64(index * Float64List.BYTES_PER_ELEMENT);
+  }
+
+  void _setIndexedFloat64(int index, double value) {
+    _setFloat64(index * Float64List.BYTES_PER_ELEMENT, value);
+  }
+
+  static _ExternalFloat64Array _new(int length) native
+      "ExternalTypedData_Float64Array_new";
+}
+
+
+class _TypedListIterator<E> implements Iterator<E> {
+  final List<E> _array;
+  final int _length;
+  int _position;
+  E _current;
+
+  _TypedListIterator(List array)
+      : _array = array, _length = array.length, _position = -1 {
+    assert(array is _TypedList || array is _TypedListView);
+  }
+
+  bool moveNext() {
+    int nextPosition = _position + 1;
+    if (nextPosition < _length) {
+      _current = _array[nextPosition];
+      _position = nextPosition;
+      return true;
+    }
+    _position = _length;
+    _current = null;
+    return false;
+  }
+
+  E get current => _current;
+}
+
+
+class _TypedListView extends _TypedListBase implements TypedData {
+  _TypedListView(ByteBuffer _buffer, int _offset, int _length)
+    : _typeddata = _buffer,  // This assignment is type safe.
+      offsetInBytes = _offset,
+      length = _length {
+  }
+
+
+  // Method(s) implementing the TypedData interface.
+
+  int get lengthInBytes {
+    return length * elementSizeInBytes;
+  }
+
+  ByteBuffer get buffer {
+    return _typeddata.buffer;
+  }
+
+  final TypedData _typeddata;
+  final int offsetInBytes;
+  final int length;
+}
+
+
+class _Int8ArrayView extends _TypedListView implements Int8List {
+  // Constructor.
+  _Int8ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length])
+    : super(buffer, _offsetInBytes,
+            _defaultIfNull(_length,
+                           ((buffer.lengthInBytes - _offsetInBytes) ~/
+                            Int8List.BYTES_PER_ELEMENT))) {
+    _rangeCheck(buffer.lengthInBytes,
+                _offsetInBytes,
+                _length * Int8List.BYTES_PER_ELEMENT);
+  }
+
+
+  // Method(s) implementing List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _typeddata._getInt8(offsetInBytes +
+                               (index * Int8List.BYTES_PER_ELEMENT));
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _typeddata. setInt8(offsetInBytes + (index * Int8List.BYTES_PER_ELEMENT),
+                        _toInt8(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing TypedData interface.
+
+  int get elementSizeInBytes {
+    return Int8List.BYTES_PER_ELEMENT;
+  }
+}
+
+
+class _Uint8ArrayView extends _TypedListView implements Uint8List {
+  // Constructor.
+  _Uint8ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length])
+    : super(buffer, _offsetInBytes,
+            _defaultIfNull(_length,
+                           ((buffer.lengthInBytes - _offsetInBytes) ~/
+                            Uint8List.BYTES_PER_ELEMENT))) {
+    _rangeCheck(buffer.lengthInBytes,
+                _offsetInBytes,
+                _length * Uint8List.BYTES_PER_ELEMENT);
+  }
+
+
+  // Method(s) implementing List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _typeddata._getUint8(offsetInBytes +
+                                (index * Uint8List.BYTES_PER_ELEMENT));
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _typeddata._setUint8(offsetInBytes + (index * Uint8List.BYTES_PER_ELEMENT),
+                         _toUint8(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing TypedData interface.
+
+  int get elementSizeInBytes {
+    return Uint8List.BYTES_PER_ELEMENT;
+  }
+}
+
+
+class _Uint8ClampedArrayView extends _TypedListView implements Uint8List {
+  // Constructor.
+  _Uint8ClampedArrayView(ByteBuffer buffer,
+                         [int _offsetInBytes = 0, int _length])
+    : super(buffer, _offsetInBytes,
+            _defaultIfNull(_length,
+                           ((buffer.lengthInBytes - _offsetInBytes) ~/
+                            Uint8List.BYTES_PER_ELEMENT))) {
+    _rangeCheck(buffer.lengthInBytes,
+                offsetInBytes,
+                length * Uint8List.BYTES_PER_ELEMENT);
+  }
+
+
+  // Method(s) implementing List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _typeddata._getUint8(offsetInBytes +
+                                (index * Uint8List.BYTES_PER_ELEMENT));
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _typeddata._setUint8(offsetInBytes + (index * Uint8List.BYTES_PER_ELEMENT),
+                         _toClampedUint8(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing TypedData interface.
+
+  int get elementSizeInBytes {
+    return Uint8List.BYTES_PER_ELEMENT;
+  }
+}
+
+
+class _Int16ArrayView extends _TypedListView implements Int16List {
+  // Constructor.
+  _Int16ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length])
+    : super(buffer, _offsetInBytes,
+            _defaultIfNull(_length,
+                           ((buffer.lengthInBytes - _offsetInBytes) ~/
+                            Int16List.BYTES_PER_ELEMENT))) {
+    _rangeCheck(buffer.lengthInBytes,
+                offsetInBytes,
+                length * Int16List.BYTES_PER_ELEMENT);
+  }
+
+
+  // Method(s) implementing List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _typeddata._getInt16(offsetInBytes +
+                                (index * Int16List.BYTES_PER_ELEMENT));
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _typeddata._setInt16(offsetInBytes + (index * Int16List.BYTES_PER_ELEMENT),
+                         _toInt16(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing TypedData interface.
+
+  int get elementSizeInBytes {
+    return Int16List.BYTES_PER_ELEMENT;
+  }
+}
+
+
+class _Uint16ArrayView extends _TypedListView implements Uint16List {
+  // Constructor.
+  _Uint16ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length])
+    : super(buffer, _offsetInBytes,
+            _defaultIfNull(_length,
+                           ((buffer.lengthInBytes - _offsetInBytes) ~/
+                            Uint16List.BYTES_PER_ELEMENT))) {
+    _rangeCheck(buffer.lengthInBytes,
+                offsetInBytes,
+                length * Uint16List.BYTES_PER_ELEMENT);
+  }
+
+
+  // Method(s) implementing List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _typeddata._getUint16(offsetInBytes +
+                                 (index * Uint16List.BYTES_PER_ELEMENT));
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _typeddata._setUint16(offsetInBytes + (index * Uint16List.BYTES_PER_ELEMENT),
+                          _toUint16(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing TypedData interface.
+
+  int get elementSizeInBytes {
+    return Uint16List.BYTES_PER_ELEMENT;
+  }
+}
+
+
+class _Int32ArrayView extends _TypedListView implements Int32List {
+  // Constructor.
+  _Int32ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length])
+    : super(buffer, _offsetInBytes,
+            _defaultIfNull(_length,
+                           ((buffer.lengthInBytes - _offsetInBytes) ~/
+                            Int32List.BYTES_PER_ELEMENT))) {
+    _rangeCheck(buffer.lengthInBytes,
+                offsetInBytes,
+                length * Int32List.BYTES_PER_ELEMENT);
+  }
+
+
+  // Method(s) implementing List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _typeddata._getInt32(offsetInBytes +
+                                (index * Int32List.BYTES_PER_ELEMENT));
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _typeddata._setInt32(offsetInBytes + (index * Int32List.BYTES_PER_ELEMENT),
+                         _toInt32(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing TypedData interface.
+
+  int get elementSizeInBytes {
+    return Int32List.BYTES_PER_ELEMENT;
+  }
+}
+
+
+class _Uint32ArrayView extends _TypedListView implements Uint32List {
+  // Constructor.
+  _Uint32ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length])
+    : super(buffer, _offsetInBytes,
+            _defaultIfNull(_length,
+                           ((buffer.lengthInBytes - _offsetInBytes) ~/
+                            Uint32List.BYTES_PER_ELEMENT))) {
+    _rangeCheck(buffer.lengthInBytes,
+                offsetInBytes,
+                length * Uint32List.BYTES_PER_ELEMENT);
+  }
+
+
+  // Method(s) implementing List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _typeddata._getUint32(offsetInBytes +
+                                 (index * Uint32List.BYTES_PER_ELEMENT));
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _typeddata._setUint32(offsetInBytes + (index * Uint32List.BYTES_PER_ELEMENT),
+                          _toUint32(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing TypedData interface.
+
+  int get elementSizeInBytes {
+    return Uint32List.BYTES_PER_ELEMENT;
+  }
+}
+
+
+class _Int64ArrayView extends _TypedListView implements Int64List {
+  // Constructor.
+  _Int64ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length])
+    : super(buffer, _offsetInBytes,
+            _defaultIfNull(_length,
+                           ((buffer.lengthInBytes - _offsetInBytes) ~/
+                            Int64List.BYTES_PER_ELEMENT))) {
+    _rangeCheck(buffer.lengthInBytes,
+                offsetInBytes,
+                length * Int64List.BYTES_PER_ELEMENT);
+  }
+
+
+  // Method(s) implementing List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _typeddata._getInt64(offsetInBytes +
+                                (index * Int64List.BYTES_PER_ELEMENT));
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _typeddata._setInt64(offsetInBytes + (index * Int64List.BYTES_PER_ELEMENT),
+                         _toInt64(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing TypedData interface.
+
+  int get elementSizeInBytes {
+    return Int64List.BYTES_PER_ELEMENT;
+  }
+}
+
+
+class _Uint64ArrayView extends _TypedListView implements Uint64List {
+  // Constructor.
+  _Uint64ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length])
+    : super(buffer, _offsetInBytes,
+            _defaultIfNull(_length,
+                           ((buffer.lengthInBytes - _offsetInBytes) ~/
+                            Uint64List.BYTES_PER_ELEMENT))) {
+    _rangeCheck(buffer.lengthInBytes,
+                offsetInBytes,
+                length * Uint64List.BYTES_PER_ELEMENT);
+  }
+
+
+  // Method(s) implementing List interface.
+
+  int operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _typeddata._getUint64(offsetInBytes +
+                                 (index * Uint64List.BYTES_PER_ELEMENT));
+  }
+
+  void operator[]=(int index, int value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _typeddata._setUint64(offsetInBytes + (index * Uint64List.BYTES_PER_ELEMENT),
+                          _toUint64(value));
+  }
+
+  Iterator<int> get iterator {
+    return new _TypedListIterator<int>(this);
+  }
+
+
+  // Method(s) implementing TypedData interface.
+
+  int get elementSizeInBytes {
+    return Uint64List.BYTES_PER_ELEMENT;
+  }
+}
+
+
+class _Float32ArrayView extends _TypedListView implements Float32List {
+  // Constructor.
+  _Float32ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length])
+    : super(buffer, _offsetInBytes,
+            _defaultIfNull(_length,
+                           ((buffer.lengthInBytes - _offsetInBytes) ~/
+                            Float32List.BYTES_PER_ELEMENT))) {
+    _rangeCheck(buffer.lengthInBytes,
+                offsetInBytes,
+                length * Float32List.BYTES_PER_ELEMENT);
+  }
+
+
+  // Method(s) implementing List interface.
+
+  double operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _typeddata._getFloat32(offsetInBytes +
+                                  (index * Float32List.BYTES_PER_ELEMENT));
+  }
+
+  void operator[]=(int index, double value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _typeddata._setFloat32(offsetInBytes +
+                           (index * Float32List.BYTES_PER_ELEMENT), value);
+  }
+
+  Iterator<double> get iterator {
+    return new _TypedListIterator<double>(this);
+  }
+
+
+  // Method(s) implementing TypedData interface.
+
+  int get elementSizeInBytes {
+    return Float32List.BYTES_PER_ELEMENT;
+  }
+}
+
+
+class _Float64ArrayView extends _TypedListView implements Float64List {
+  // Constructor.
+  _Float64ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length])
+    : super(buffer, _offsetInBytes,
+            _defaultIfNull(_length,
+                           ((buffer.lengthInBytes - _offsetInBytes) ~/
+                            Float64List.BYTES_PER_ELEMENT))) {
+    _rangeCheck(buffer.lengthInBytes,
+                offsetInBytes,
+                length * Float64List.BYTES_PER_ELEMENT);
+  }
+
+
+  // Method(s) implementing List interface.
+
+  double operator[](int index) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    return _typeddata._getFloat64(offsetInBytes +
+                                  (index * Float64List.BYTES_PER_ELEMENT));
+  }
+
+  void operator[]=(int index, double value) {
+    if (index < 0 || index >= length) {
+      String message = "$index must be in the range [0..$length)";
+      throw new RangeError(message);
+    }
+    _typeddata._setFloat64(offsetInBytes +
+                          (index * Float64List.BYTES_PER_ELEMENT), value);
+  }
+
+  Iterator<double> get iterator {
+    return new _TypedListIterator<double>(this);
+  }
+
+
+  // Method(s) implementing TypedData interface.
+
+  int get elementSizeInBytes {
+    return Float64List.BYTES_PER_ELEMENT;
+  }
+}
+
+
+class _ByteDataView implements ByteData {
+  _ByteDataView(ByteBuffer _buffer, int _offsetInBytes, int _lengthInBytes)
+    : _typeddata = _buffer as TypedData,
+      _offset = _offsetInBytes,
+      _length = _lengthInBytes {
+    _rangeCheck(_buffer.lengthInBytes, _offset, _length);
+  }
+
+
+  // Method(s) implementing TypedData interface.
+
+  ByteBuffer get buffer {
+    return _typeddata.buffer;
+  }
+
+  int get lengthInBytes {
+    return _length;
+  }
+
+  int offsetInBytes() {
+    return _offset;
+  }
+
+  // Method(s) implementing ByteData interface.
+
+  int getInt8(int byteOffset) {
+    return _typeddata._getInt8(_offset + byteOffset);
+  }
+  void setInt8(int byteOffset, int value) {
+    _typeddata._setInt8(_offset + byteOffset, value);
+  }
+
+  int getUint8(int byteOffset) {
+    return _typeddata._getUint8(_offset + byteOffset);
+  }
+  void setUint8(int byteOffset, int value) {
+    _typeddata._setUint8(_offset + byteOffset, value);
+  }
+
+  int getInt16(int byteOffset) {
+    return _typeddata._getInt16(_offset + byteOffset);
+  }
+  void setInt16(int byteOffset, int value) {
+    _typeddata._setInt16(_offset + byteOffset, value);
+  }
+
+  int getUint16(int byteOffset) {
+    return _typeddata._getUint16(_offset + byteOffset);
+  }
+  void setUint16(int byteOffset, int value) {
+    _typeddata._setUint16(_offset + byteOffset, value);
+  }
+
+  int getInt32(int byteOffset) {
+    return _typeddata._getInt32(_offset + byteOffset);
+  }
+  void setInt32(int byteOffset, int value) {
+    _typeddata._setInt32(_offset + byteOffset, value);
+  }
+
+  int getUint32(int byteOffset) {
+    return _typeddata._getUint32(_offset + byteOffset);
+  }
+  void setUint32(int byteOffset, int value) {
+    _typeddata._setUint32(_offset + byteOffset, value);
+  }
+
+  int getInt64(int byteOffset) {
+    return _typeddata._getInt64(_offset + byteOffset);
+  }
+  void setInt64(int byteOffset, int value) {
+    _typeddata._setInt64(_offset + byteOffset, value);
+  }
+
+  int getUint64(int byteOffset) {
+    return _typeddata._getUint64(_offset + byteOffset);
+  }
+  void setUint64(int byteOffset, int value) {
+    _typeddata._setUint64(_offset + byteOffset, value);
+  }
+
+  double getFloat32(int byteOffset) {
+    return _typeddata._getFloat32(_offset + byteOffset);
+  }
+  void setFloat32(int byteOffset, double value) {
+    _typeddata._setFloat32(_offset + byteOffset, value);
+  }
+
+  double getFloat64(int byteOffset) {
+    return _typeddata._getFloat64(_offset + byteOffset);
+  }
+  void setFloat64(int byteOffset, double value) {
+    _typeddata._setFloat64(_offset + byteOffset, value);
+  }
+
+  final TypedData _typeddata;
+  final int _offset;
+  final int _length;
+}
+
+
+// Top level utility methods.
+int _toInt(int value, int mask) {
+  value &= mask;
+  if (value > (mask >> 1)) value -= mask + 1;
+  return value;
+}
+
+
+int _toInt8(int value) {
+  return _toInt(value, 0xFF);
+}
+
+
+int _toUint8(int value) {
+  return value & 0xFF;
+}
+
+
+int _toClampedUint8(int value) {
+  if (value < 0) return 0;
+  if (value > 0xFF) return 0xFF;
+  return value;
+}
+
+
+int _toInt16(int value) {
+  return _toInt(value, 0xFFFF);
+}
+
+
+int _toUint16(int value) {
+  return value & 0xFFFF;
+}
+
+
+int _toInt32(int value) {
+  return _toInt(value, 0xFFFFFFFF);
+}
+
+
+int _toUint32(int value) {
+  return value & 0xFFFFFFFF;
+}
+
+
+int _toInt64(int value) {
+  return _toInt(value, 0xFFFFFFFFFFFFFFFF);
+}
+
+
+int _toUint64(int value) {
+  return value & 0xFFFFFFFFFFFFFFFF;
+}
+
+
+void _rangeCheck(int listLength, int start, int length) {
+  if (length < 0) {
+    throw new RangeError.value(length);
+  }
+  if (start < 0) {
+    throw new RangeError.value(start);
+  }
+  if (start + length > listLength) {
+    throw new RangeError.value(start + length);
+  }
+}
+
+
+int _defaultIfNull(object, value) {
+  if (object == null) {
+    return value;
+  }
+  return object;
+}
diff --git a/runtime/lib/typeddata_sources.gypi b/runtime/lib/typeddata_sources.gypi
new file mode 100644
index 0000000..05be7c3
--- /dev/null
+++ b/runtime/lib/typeddata_sources.gypi
@@ -0,0 +1,13 @@
+# 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.
+
+# Sources visible via dart:typeddata library.
+
+{
+  'sources': [
+    'typeddata.cc',
+    'typeddata.dart',
+  ],
+}
+
diff --git a/runtime/platform/thread_win.cc b/runtime/platform/thread_win.cc
index 18ec6d0..662b3766 100644
--- a/runtime/platform/thread_win.cc
+++ b/runtime/platform/thread_win.cc
@@ -42,8 +42,8 @@
   // Call the supplied thread start function handing it its parameters.
   function(parameter);
 
-  // When the function returns here close the handle.
-  CloseHandle(GetCurrentThread());
+  // Clean up the monitor wait data for this thread.
+  MonitorWaitData::ThreadExit();
 
   return 0;
 }
@@ -173,6 +173,17 @@
 }
 
 
+void MonitorWaitData::ThreadExit() {
+  uword raw_wait_data =
+    Thread::GetThreadLocal(MonitorWaitData::monitor_wait_data_key_);
+  if (raw_wait_data != 0) {
+    MonitorWaitData* wait_data =
+        reinterpret_cast<MonitorWaitData*>(raw_wait_data);
+    delete wait_data;
+  }
+}
+
+
 void MonitorData::AddWaiter(MonitorWaitData* wait_data) {
   // Add the MonitorWaitData object to the list of objects waiting for
   // this monitor.
diff --git a/runtime/platform/thread_win.h b/runtime/platform/thread_win.h
index b481cec..b67b254 100644
--- a/runtime/platform/thread_win.h
+++ b/runtime/platform/thread_win.h
@@ -49,8 +49,15 @@
 
 
 class MonitorWaitData {
+ public:
+  static void ThreadExit();
+
  private:
   explicit MonitorWaitData(HANDLE event) : event_(event), next_(NULL) {}
+  ~MonitorWaitData() {
+    CloseHandle(event_);
+    ASSERT(next_ == NULL);
+  }
 
   // ThreadLocalKey used to fetch and store the MonitorWaitData object
   // for a given thread.
diff --git a/runtime/tests/vm/dart/byte_array_optimized_test.dart b/runtime/tests/vm/dart/byte_array_optimized_test.dart
index 803944d..e645c733 100644
--- a/runtime/tests/vm/dart/byte_array_optimized_test.dart
+++ b/runtime/tests/vm/dart/byte_array_optimized_test.dart
@@ -75,14 +75,14 @@
     for (int i = 0; i < array.length; ++i) {
       array[i] = i;
     }
-    var copy = array.getRange(0, array.length);
+    var copy = array.sublist(0, array.length);
     Expect.isFalse(copy === array);
     Expect.isTrue(copy is Int8List);
     Expect.equals(10, copy.length);
     Expect.listEquals(array, copy);
-    var empty = array.getRange(array.length, 0);
+    var empty = array.sublist(array.length, array.length);
     Expect.equals(0, empty.length);
-    var region = array.getRange(3, array.length - 6);
+    var region = array.sublist(3, array.length - 3);
     Expect.isTrue(copy is Int8List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -150,14 +150,14 @@
     for (int i = 0; i < array.length; ++i) {
       array[i] = i;
     }
-    var copy = array.getRange(0, array.length);
+    var copy = array.sublist(0, array.length);
     Expect.isFalse(copy === array);
     Expect.isTrue(copy is Uint8List);
     Expect.equals(10, copy.length);
     Expect.listEquals(array, copy);
-    var empty = array.getRange(array.length, 0);
+    var empty = array.sublist(array.length, array.length);
     Expect.equals(0, empty.length);
-    var region = array.getRange(3, array.length - 6);
+    var region = array.sublist(3, array.length - 3);
     Expect.isTrue(copy is Uint8List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -238,14 +238,14 @@
     for (int i = 0; i < array.length; ++i) {
       array[i] = i;
     }
-    var copy = array.getRange(0, array.length);
+    var copy = array.sublist(0, array.length);
     Expect.isFalse(copy === array);
     Expect.isTrue(copy is Int16List);
     Expect.equals(10, copy.length);
     Expect.listEquals(array, copy);
-    var empty = array.getRange(array.length, 0);
+    var empty = array.sublist(array.length, array.length);
     Expect.equals(0, empty.length);
-    var region = array.getRange(3, array.length - 6);
+    var region = array.sublist(3, array.length - 3);
     Expect.isTrue(copy is Int16List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -314,14 +314,14 @@
     for (int i = 0; i < array.length; ++i) {
       array[i] = i;
     }
-    var copy = array.getRange(0, array.length);
+    var copy = array.sublist(0, array.length);
     Expect.isFalse(copy === array);
     Expect.isTrue(copy is Uint16List);
     Expect.equals(10, copy.length);
     Expect.listEquals(array, copy);
-    var empty = array.getRange(array.length, 0);
+    var empty = array.sublist(array.length, array.length);
     Expect.equals(0, empty.length);
-    var region = array.getRange(3, array.length - 6);
+    var region = array.sublist(3, array.length - 3);
     Expect.isTrue(copy is Uint16List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -408,14 +408,14 @@
     for (int i = 0; i < array.length; ++i) {
       array[i] = i;
     }
-    var copy = array.getRange(0, array.length);
+    var copy = array.sublist(0, array.length);
     Expect.isFalse(copy === array);
     Expect.isTrue(copy is Int32List);
     Expect.equals(10, copy.length);
     Expect.listEquals(array, copy);
-    var empty = array.getRange(array.length, 0);
+    var empty = array.sublist(array.length, array.length);
     Expect.equals(0, empty.length);
-    var region = array.getRange(3, array.length - 6);
+    var region = array.sublist(3, array.length - 3);
     Expect.isTrue(copy is Int32List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -487,14 +487,14 @@
     for (int i = 0; i < array.length; ++i) {
       array[i] = i;
     }
-    var copy = array.getRange(0, array.length);
+    var copy = array.sublist(0, array.length);
     Expect.isFalse(copy === array);
     Expect.isTrue(copy is Uint32List);
     Expect.equals(10, copy.length);
     Expect.listEquals(array, copy);
-    var empty = array.getRange(array.length, 0);
+    var empty = array.sublist(array.length, array.length);
     Expect.equals(0, empty.length);
-    var region = array.getRange(3, array.length - 6);
+    var region = array.sublist(3, array.length - 3);
     Expect.isTrue(copy is Uint32List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -510,7 +510,7 @@
                   (e) { return e is ArgumentError; });
     var array = new Uint32List(10);
     testUint32ListImpl(array);
-    
+
   }
 
   static testInt64ListImpl(Int64List array) {
@@ -584,14 +584,14 @@
     for (int i = 0; i < array.length; ++i) {
       array[i] = i;
     }
-    var copy = array.getRange(0, array.length);
+    var copy = array.sublist(0, array.length);
     Expect.isFalse(copy === array);
     Expect.isTrue(copy is Int64List);
     Expect.equals(10, copy.length);
     Expect.listEquals(array, copy);
-    var empty = array.getRange(array.length, 0);
+    var empty = array.sublist(array.length, array.length);
     Expect.equals(0, empty.length);
-    var region = array.getRange(3, array.length - 6);
+    var region = array.sublist(3, array.length - 3);
     Expect.isTrue(copy is Int64List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -664,14 +664,14 @@
     for (int i = 0; i < array.length; ++i) {
       array[i] = i;
     }
-    var copy = array.getRange(0, array.length);
+    var copy = array.sublist(0, array.length);
     Expect.isFalse(copy === array);
     Expect.isTrue(copy is Uint64List);
     Expect.equals(10, copy.length);
     Expect.listEquals(array, copy);
-    var empty = array.getRange(array.length, 0);
+    var empty = array.sublist(array.length, array.length);
     Expect.equals(0, empty.length);
-    var region = array.getRange(3, array.length - 6);
+    var region = array.sublist(3, array.length - 3);
     Expect.isTrue(copy is Uint64List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -729,14 +729,14 @@
     for (int i = 0; i < array.length; ++i) {
       array[i] = i * 1.0;
     }
-    var copy = array.getRange(0, array.length);
+    var copy = array.sublist(0, array.length);
     Expect.isFalse(copy === array);
     Expect.isTrue(copy is Float32List);
     Expect.equals(10, copy.length);
     Expect.listEquals(array, copy);
-    var empty = array.getRange(array.length, 0);
+    var empty = array.sublist(array.length, array.length);
     Expect.equals(0, empty.length);
-    var region = array.getRange(3, array.length - 6);
+    var region = array.sublist(3, array.length - 3);
     Expect.isTrue(copy is Float32List);
     Expect.equals(4, region.length);
     Expect.listEquals([3.0, 4.0, 5.0, 6.0], region);
@@ -795,14 +795,14 @@
     for (int i = 0; i < array.length; ++i) {
       array[i] = i * 1.0;
     }
-    var copy = array.getRange(0, array.length);
+    var copy = array.sublist(0, array.length);
     Expect.isFalse(copy === array);
     Expect.isTrue(copy is Float64List);
     Expect.equals(10, copy.length);
     Expect.listEquals(array, copy);
-    var empty = array.getRange(array.length, 0);
+    var empty = array.sublist(array.length, array.length);
     Expect.equals(0, empty.length);
-    var region = array.getRange(3, array.length - 6);
+    var region = array.sublist(3, array.length - 3);
     Expect.isTrue(copy is Float64List);
     Expect.equals(4, region.length);
     Expect.listEquals([3.0, 4.0, 5.0, 6.0], region);
@@ -929,12 +929,12 @@
     for (int i = 0; i < view.length; ++i) {
       view[i] = i;
     }
-    var copy = view.getRange(0, view.length);
+    var copy = view.sublist(0, view.length);
     Expect.isFalse(copy === view);
     Expect.isTrue(copy is Int8List);
     Expect.equals(10, copy.length);
     Expect.listEquals(view, copy);
-    var region = view.getRange(3, view.length - 6);
+    var region = view.sublist(3, view.length - 3);
     Expect.isTrue(copy is Int8List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -1042,12 +1042,12 @@
     for (int i = 0; i < view.length; ++i) {
       view[i] = i;
     }
-    var copy = view.getRange(0, view.length);
+    var copy = view.sublist(0, view.length);
     Expect.isFalse(copy === view);
     Expect.isTrue(copy is Uint8List);
     Expect.equals(10, copy.length);
     Expect.listEquals(view, copy);
-    var region = view.getRange(3, view.length - 6);
+    var region = view.sublist(3, view.length - 3);
     Expect.isTrue(copy is Uint8List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -1176,12 +1176,12 @@
     for (int i = 0; i < view.length; ++i) {
       view[i] = i;
     }
-    var copy = view.getRange(0, view.length);
+    var copy = view.sublist(0, view.length);
     Expect.isFalse(copy === view);
     Expect.isTrue(copy is Int16List);
     Expect.equals(10, copy.length);
     Expect.listEquals(view, copy);
-    var region = view.getRange(3, view.length - 6);
+    var region = view.sublist(3, view.length - 3);
     Expect.isTrue(copy is Int16List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -1293,12 +1293,12 @@
     for (int i = 0; i < view.length; ++i) {
       view[i] = i;
     }
-    var copy = view.getRange(0, view.length);
+    var copy = view.sublist(0, view.length);
     Expect.isFalse(copy === view);
     Expect.isTrue(copy is Uint16List);
     Expect.equals(10, copy.length);
     Expect.listEquals(view, copy);
-    var region = view.getRange(3, view.length - 6);
+    var region = view.sublist(3, view.length - 3);
     Expect.isTrue(copy is Uint16List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -1453,12 +1453,12 @@
     for (int i = 0; i < view.length; ++i) {
       view[i] = i;
     }
-    var copy = view.getRange(0, view.length);
+    var copy = view.sublist(0, view.length);
     Expect.isFalse(copy === view);
     Expect.isTrue(copy is Int32List);
     Expect.equals(10, copy.length);
     Expect.listEquals(view, copy);
-    var region = view.getRange(3, view.length - 6);
+    var region = view.sublist(3, view.length - 3);
     Expect.isTrue(copy is Int32List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -1582,12 +1582,12 @@
     for (int i = 0; i < view.length; ++i) {
       view[i] = i;
     }
-    var copy = view.getRange(0, view.length);
+    var copy = view.sublist(0, view.length);
     Expect.isFalse(copy === view);
     Expect.isTrue(copy is Uint32List);
     Expect.equals(10, copy.length);
     Expect.listEquals(view, copy);
-    var region = view.getRange(3, view.length - 6);
+    var region = view.sublist(3, view.length - 3);
     Expect.isTrue(copy is Uint32List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -1774,12 +1774,12 @@
     for (int i = 0; i < view.length; ++i) {
       view[i] = i;
     }
-    var copy = view.getRange(0, view.length);
+    var copy = view.sublist(0, view.length);
     Expect.isFalse(copy === view);
     Expect.isTrue(copy is Int64List);
     Expect.equals(10, copy.length);
     Expect.listEquals(view, copy);
-    var region = view.getRange(3, view.length - 6);
+    var region = view.sublist(3, view.length - 3);
     Expect.isTrue(copy is Int64List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -1936,12 +1936,12 @@
     for (int i = 0; i < view.length; ++i) {
       view[i] = i;
     }
-    var copy = view.getRange(0, view.length);
+    var copy = view.sublist(0, view.length);
     Expect.isFalse(copy === view);
     Expect.isTrue(copy is Uint64List);
     Expect.equals(10, copy.length);
     Expect.listEquals(view, copy);
-    var region = view.getRange(3, view.length - 6);
+    var region = view.sublist(3, view.length - 3);
     Expect.isTrue(copy is Uint64List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -2048,12 +2048,12 @@
     for (int i = 0; i < view.length; ++i) {
       view[i] = i * 1.0;
     }
-    var copy = view.getRange(0, view.length);
+    var copy = view.sublist(0, view.length);
     Expect.isFalse(copy === view);
     Expect.isTrue(copy is Float32List);
     Expect.equals(10, copy.length);
     Expect.listEquals(view, copy);
-    var region = view.getRange(3, view.length - 6);
+    var region = view.sublist(3, view.length - 3);
     Expect.isTrue(copy is Float32List);
     Expect.equals(4, region.length);
     Expect.listEquals([3.0, 4.0, 5.0, 6.0], region);
@@ -2155,12 +2155,12 @@
     for (int i = 0; i < view.length; ++i) {
       view[i] = i * 1.0;
     }
-    var copy = view.getRange(0, view.length);
+    var copy = view.sublist(0, view.length);
     Expect.isFalse(copy === view);
     Expect.isTrue(copy is Float64List);
     Expect.equals(10, copy.length);
     Expect.listEquals(view, copy);
-    var region = view.getRange(3, view.length - 6);
+    var region = view.sublist(3, view.length - 3);
     Expect.isTrue(copy is Float64List);
     Expect.equals(4, region.length);
     Expect.listEquals([3.0, 4.0, 5.0, 6.0], region);
diff --git a/runtime/tests/vm/dart/byte_array_test.dart b/runtime/tests/vm/dart/byte_array_test.dart
index 0eab243..9770cad 100644
--- a/runtime/tests/vm/dart/byte_array_test.dart
+++ b/runtime/tests/vm/dart/byte_array_test.dart
@@ -73,14 +73,17 @@
     for (int i = 0; i < array.length; ++i) {
       array[i] = i;
     }
-    var copy = array.getRange(0, array.length);
+    var copy = array.sublist(0, array.length);
     Expect.isFalse(copy === array);
     Expect.isTrue(copy is Int8List);
     Expect.equals(10, copy.length);
     Expect.listEquals(array, copy);
-    var empty = array.getRange(array.length, 0);
+    var empty = array.sublist(array.length, array.length);
     Expect.equals(0, empty.length);
-    var region = array.getRange(3, array.length - 6);
+    empty = array.sublist(array.length);
+    Expect.equals(0, empty.length);
+
+    var region = array.sublist(3, array.length - 3);
     Expect.isTrue(copy is Int8List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -92,7 +95,7 @@
     Expect.throws(() { new Int8List(-1); },
                   (e) { return e is ArgumentError; });
     Expect.throws(() { new Int8List.transferable(-1); },
-                  (e) { return e is ArgumentError; });                  
+                  (e) { return e is ArgumentError; });
     var array = new Int8List(10);
     testInt8ListImpl(array);
     array = new Int8List.transferable(10);
@@ -152,14 +155,17 @@
     for (int i = 0; i < array.length; ++i) {
       array[i] = i;
     }
-    var copy = array.getRange(0, array.length);
+    var copy = array.sublist(0, array.length);
     Expect.isFalse(copy === array);
     Expect.isTrue(copy is Uint8List);
     Expect.equals(10, copy.length);
     Expect.listEquals(array, copy);
-    var empty = array.getRange(array.length, 0);
+    var empty = array.sublist(array.length, array.length);
     Expect.equals(0, empty.length);
-    var region = array.getRange(3, array.length - 6);
+    empty = array.sublist(array.length);
+    Expect.equals(0, empty.length);
+
+    var region = array.sublist(3, array.length - 3);
     Expect.isTrue(copy is Uint8List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -229,14 +235,17 @@
     for (int i = 0; i < array.length; ++i) {
       array[i] = i;
     }
-    var copy = array.getRange(0, array.length);
+    var copy = array.sublist(0, array.length);
     Expect.isFalse(copy === array);
     Expect.isTrue(copy is Uint8ClampedList);
     Expect.equals(10, copy.length);
     Expect.listEquals(array, copy);
-    var empty = array.getRange(array.length, 0);
+    var empty = array.sublist(array.length, array.length);
     Expect.equals(0, empty.length);
-    var region = array.getRange(3, array.length - 6);
+    empty = array.sublist(array.length);
+    Expect.equals(0, empty.length);
+
+    var region = array.sublist(3, array.length - 3);
     Expect.isTrue(copy is Uint8ClampedList);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -320,14 +329,17 @@
     for (int i = 0; i < array.length; ++i) {
       array[i] = i;
     }
-    var copy = array.getRange(0, array.length);
+    var copy = array.sublist(0, array.length);
     Expect.isFalse(copy === array);
     Expect.isTrue(copy is Int16List);
     Expect.equals(10, copy.length);
     Expect.listEquals(array, copy);
-    var empty = array.getRange(array.length, 0);
+    var empty = array.sublist(array.length, array.length);
     Expect.equals(0, empty.length);
-    var region = array.getRange(3, array.length - 6);
+    empty = array.sublist(array.length);
+    Expect.equals(0, empty.length);
+
+    var region = array.sublist(3, array.length - 3);
     Expect.isTrue(copy is Int16List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -340,7 +352,7 @@
     Expect.throws(() { new Int16List(-1); },
                   (e) { return e is ArgumentError; });
     Expect.throws(() { new Int16List.transferable(-1); },
-                  (e) { return e is ArgumentError; });                  
+                  (e) { return e is ArgumentError; });
     var array = new Int16List(10);
     testInt16ListImpl(array);
     array = new Int16List.transferable(10);
@@ -400,14 +412,17 @@
     for (int i = 0; i < array.length; ++i) {
       array[i] = i;
     }
-    var copy = array.getRange(0, array.length);
+    var copy = array.sublist(0, array.length);
     Expect.isFalse(copy === array);
     Expect.isTrue(copy is Uint16List);
     Expect.equals(10, copy.length);
     Expect.listEquals(array, copy);
-    var empty = array.getRange(array.length, 0);
+    var empty = array.sublist(array.length, array.length);
     Expect.equals(0, empty.length);
-    var region = array.getRange(3, array.length - 6);
+    empty = array.sublist(array.length);
+    Expect.equals(0, empty.length);
+
+    var region = array.sublist(3, array.length - 3);
     Expect.isTrue(copy is Uint16List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -498,14 +513,17 @@
     for (int i = 0; i < array.length; ++i) {
       array[i] = i;
     }
-    var copy = array.getRange(0, array.length);
+    var copy = array.sublist(0, array.length);
     Expect.isFalse(copy === array);
     Expect.isTrue(copy is Int32List);
     Expect.equals(10, copy.length);
     Expect.listEquals(array, copy);
-    var empty = array.getRange(array.length, 0);
+    var empty = array.sublist(array.length, array.length);
     Expect.equals(0, empty.length);
-    var region = array.getRange(3, array.length - 6);
+    empty = array.sublist(array.length);
+    Expect.equals(0, empty.length);
+
+    var region = array.sublist(3, array.length - 3);
     Expect.isTrue(copy is Int32List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -581,14 +599,17 @@
     for (int i = 0; i < array.length; ++i) {
       array[i] = i;
     }
-    var copy = array.getRange(0, array.length);
+    var copy = array.sublist(0, array.length);
     Expect.isFalse(copy === array);
     Expect.isTrue(copy is Uint32List);
     Expect.equals(10, copy.length);
     Expect.listEquals(array, copy);
-    var empty = array.getRange(array.length, 0);
+    var empty = array.sublist(array.length, array.length);
     Expect.equals(0, empty.length);
-    var region = array.getRange(3, array.length - 6);
+    empty = array.sublist(array.length);
+    Expect.equals(0, empty.length);
+
+    var region = array.sublist(3, array.length - 3);
     Expect.isTrue(copy is Uint32List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -606,7 +627,7 @@
     testUint32ListImpl(array);
     array = new Uint32List.transferable(10);
     testUint32ListImpl(array);
-    
+
   }
 
   static testInt64ListImpl(Int64List array) {
@@ -680,14 +701,17 @@
     for (int i = 0; i < array.length; ++i) {
       array[i] = i;
     }
-    var copy = array.getRange(0, array.length);
+    var copy = array.sublist(0, array.length);
     Expect.isFalse(copy === array);
     Expect.isTrue(copy is Int64List);
     Expect.equals(10, copy.length);
     Expect.listEquals(array, copy);
-    var empty = array.getRange(array.length, 0);
+    var empty = array.sublist(array.length, array.length);
     Expect.equals(0, empty.length);
-    var region = array.getRange(3, array.length - 6);
+    empty = array.sublist(array.length);
+    Expect.equals(0, empty.length);
+
+    var region = array.sublist(3, array.length - 3);
     Expect.isTrue(copy is Int64List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -764,14 +788,17 @@
     for (int i = 0; i < array.length; ++i) {
       array[i] = i;
     }
-    var copy = array.getRange(0, array.length);
+    var copy = array.sublist(0, array.length);
     Expect.isFalse(copy === array);
     Expect.isTrue(copy is Uint64List);
     Expect.equals(10, copy.length);
     Expect.listEquals(array, copy);
-    var empty = array.getRange(array.length, 0);
+    var empty = array.sublist(array.length, array.length);
     Expect.equals(0, empty.length);
-    var region = array.getRange(3, array.length - 6);
+    empty = array.sublist(array.length);
+    Expect.equals(0, empty.length);
+
+    var region = array.sublist(3, array.length - 3);
     Expect.isTrue(copy is Uint64List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -833,14 +860,17 @@
     for (int i = 0; i < array.length; ++i) {
       array[i] = i * 1.0;
     }
-    var copy = array.getRange(0, array.length);
+    var copy = array.sublist(0, array.length);
     Expect.isFalse(copy === array);
     Expect.isTrue(copy is Float32List);
     Expect.equals(10, copy.length);
     Expect.listEquals(array, copy);
-    var empty = array.getRange(array.length, 0);
+    var empty = array.sublist(array.length, array.length);
     Expect.equals(0, empty.length);
-    var region = array.getRange(3, array.length - 6);
+    empty = array.sublist(array.length);
+    Expect.equals(0, empty.length);
+
+    var region = array.sublist(3, array.length - 3);
     Expect.isTrue(copy is Float32List);
     Expect.equals(4, region.length);
     Expect.listEquals([3.0, 4.0, 5.0, 6.0], region);
@@ -903,14 +933,17 @@
     for (int i = 0; i < array.length; ++i) {
       array[i] = i * 1.0;
     }
-    var copy = array.getRange(0, array.length);
+    var copy = array.sublist(0, array.length);
     Expect.isFalse(copy === array);
     Expect.isTrue(copy is Float64List);
     Expect.equals(10, copy.length);
     Expect.listEquals(array, copy);
-    var empty = array.getRange(array.length, 0);
+    var empty = array.sublist(array.length, array.length);
     Expect.equals(0, empty.length);
-    var region = array.getRange(3, array.length - 6);
+    empty = array.sublist(array.length);
+    Expect.equals(0, empty.length);
+
+    var region = array.sublist(3, array.length - 3);
     Expect.isTrue(copy is Float64List);
     Expect.equals(4, region.length);
     Expect.listEquals([3.0, 4.0, 5.0, 6.0], region);
@@ -1184,12 +1217,12 @@
     for (int i = 0; i < view.length; ++i) {
       view[i] = i;
     }
-    var copy = view.getRange(0, view.length);
+    var copy = view.sublist(0, view.length);
     Expect.isFalse(copy === view);
     Expect.isTrue(copy is Int8List);
     Expect.equals(10, copy.length);
     Expect.listEquals(view, copy);
-    var region = view.getRange(3, view.length - 6);
+    var region = view.sublist(3, view.length - 3);
     Expect.isTrue(copy is Int8List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -1299,12 +1332,12 @@
     for (int i = 0; i < view.length; ++i) {
       view[i] = i;
     }
-    var copy = view.getRange(0, view.length);
+    var copy = view.sublist(0, view.length);
     Expect.isFalse(copy === view);
     Expect.isTrue(copy is Uint8List);
     Expect.equals(10, copy.length);
     Expect.listEquals(view, copy);
-    var region = view.getRange(3, view.length - 6);
+    var region = view.sublist(3, view.length - 3);
     Expect.isTrue(copy is Uint8List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -1435,12 +1468,12 @@
     for (int i = 0; i < view.length; ++i) {
       view[i] = i;
     }
-    var copy = view.getRange(0, view.length);
+    var copy = view.sublist(0, view.length);
     Expect.isFalse(copy === view);
     Expect.isTrue(copy is Int16List);
     Expect.equals(10, copy.length);
     Expect.listEquals(view, copy);
-    var region = view.getRange(3, view.length - 6);
+    var region = view.sublist(3, view.length - 3);
     Expect.isTrue(copy is Int16List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -1554,12 +1587,12 @@
     for (int i = 0; i < view.length; ++i) {
       view[i] = i;
     }
-    var copy = view.getRange(0, view.length);
+    var copy = view.sublist(0, view.length);
     Expect.isFalse(copy === view);
     Expect.isTrue(copy is Uint16List);
     Expect.equals(10, copy.length);
     Expect.listEquals(view, copy);
-    var region = view.getRange(3, view.length - 6);
+    var region = view.sublist(3, view.length - 3);
     Expect.isTrue(copy is Uint16List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -1716,12 +1749,12 @@
     for (int i = 0; i < view.length; ++i) {
       view[i] = i;
     }
-    var copy = view.getRange(0, view.length);
+    var copy = view.sublist(0, view.length);
     Expect.isFalse(copy === view);
     Expect.isTrue(copy is Int32List);
     Expect.equals(10, copy.length);
     Expect.listEquals(view, copy);
-    var region = view.getRange(3, view.length - 6);
+    var region = view.sublist(3, view.length - 3);
     Expect.isTrue(copy is Int32List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -1845,12 +1878,12 @@
     for (int i = 0; i < view.length; ++i) {
       view[i] = i;
     }
-    var copy = view.getRange(0, view.length);
+    var copy = view.sublist(0, view.length);
     Expect.isFalse(copy === view);
     Expect.isTrue(copy is Uint32List);
     Expect.equals(10, copy.length);
     Expect.listEquals(view, copy);
-    var region = view.getRange(3, view.length - 6);
+    var region = view.sublist(3, view.length - 3);
     Expect.isTrue(copy is Uint32List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -2039,12 +2072,12 @@
     for (int i = 0; i < view.length; ++i) {
       view[i] = i;
     }
-    var copy = view.getRange(0, view.length);
+    var copy = view.sublist(0, view.length);
     Expect.isFalse(copy === view);
     Expect.isTrue(copy is Int64List);
     Expect.equals(10, copy.length);
     Expect.listEquals(view, copy);
-    var region = view.getRange(3, view.length - 6);
+    var region = view.sublist(3, view.length - 3);
     Expect.isTrue(copy is Int64List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -2203,12 +2236,12 @@
     for (int i = 0; i < view.length; ++i) {
       view[i] = i;
     }
-    var copy = view.getRange(0, view.length);
+    var copy = view.sublist(0, view.length);
     Expect.isFalse(copy === view);
     Expect.isTrue(copy is Uint64List);
     Expect.equals(10, copy.length);
     Expect.listEquals(view, copy);
-    var region = view.getRange(3, view.length - 6);
+    var region = view.sublist(3, view.length - 3);
     Expect.isTrue(copy is Uint64List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
@@ -2317,12 +2350,12 @@
     for (int i = 0; i < view.length; ++i) {
       view[i] = i * 1.0;
     }
-    var copy = view.getRange(0, view.length);
+    var copy = view.sublist(0, view.length);
     Expect.isFalse(copy === view);
     Expect.isTrue(copy is Float32List);
     Expect.equals(10, copy.length);
     Expect.listEquals(view, copy);
-    var region = view.getRange(3, view.length - 6);
+    var region = view.sublist(3, view.length - 3);
     Expect.isTrue(copy is Float32List);
     Expect.equals(4, region.length);
     Expect.listEquals([3.0, 4.0, 5.0, 6.0], region);
@@ -2426,12 +2459,12 @@
     for (int i = 0; i < view.length; ++i) {
       view[i] = i * 1.0;
     }
-    var copy = view.getRange(0, view.length);
+    var copy = view.sublist(0, view.length);
     Expect.isFalse(copy === view);
     Expect.isTrue(copy is Float64List);
     Expect.equals(10, copy.length);
     Expect.listEquals(view, copy);
-    var region = view.getRange(3, view.length - 6);
+    var region = view.sublist(3, view.length - 3);
     Expect.isTrue(copy is Float64List);
     Expect.equals(4, region.length);
     Expect.listEquals([3.0, 4.0, 5.0, 6.0], region);
diff --git a/runtime/tests/vm/dart/inline_stack_frame_test.dart b/runtime/tests/vm/dart/inline_stack_frame_test.dart
index 5012982..64e24c7 100644
--- a/runtime/tests/vm/dart/inline_stack_frame_test.dart
+++ b/runtime/tests/vm/dart/inline_stack_frame_test.dart
@@ -22,7 +22,7 @@
       }
       return "";
     } catch (e, stacktrace) {
-      var result = e.concat(stacktrace.toString());
+      var result = e + stacktrace.toString();
       return result;
     }
   }
diff --git a/runtime/tests/vm/dart/isolate_mirror_local_test.dart b/runtime/tests/vm/dart/isolate_mirror_local_test.dart
index 94eaa3f..5d2e687 100644
--- a/runtime/tests/vm/dart/isolate_mirror_local_test.dart
+++ b/runtime/tests/vm/dart/isolate_mirror_local_test.dart
@@ -270,7 +270,7 @@
 
   variable = cls_mirror.members['value'];
   Expect.isTrue(variable is VariableMirror);
-  Expect.equals('value type(Dynamic) final', buildVariableString(variable));
+  Expect.equals('value type(dynamic) final', buildVariableString(variable));
 
   // Test type variable mirrors.
   var type_var = generic_cls_mirror.members['method'].returnType;
@@ -331,7 +331,7 @@
   testRootLibraryMirror(mirrors.isolate.rootLibrary);
   testLibrariesMap(mirrors.libraries);
   Expect.equals('void', mirrors.voidType.simpleName);
-  Expect.equals('Dynamic', mirrors.dynamicType.simpleName);
+  Expect.equals('dynamic', mirrors.dynamicType.simpleName);
   testDone('testMirrorSystem');
 }
 
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 86c53f32..acd74eb 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -63,18 +63,18 @@
 *: Skip
 
 [ $arch == simarm ]
-# Tests needing an assembler.
-cc/CallLeafRuntimeStubCode: Skip
-cc/CallRuntimeStubCode: Skip
+# Tests missing code generation support.
 cc/Dart2JSCompileAll: Skip
 cc/FrameLookup: Skip
-cc/IcDataAccess: Skip
-cc/Jump: Skip
-cc/PatchStaticCall: Skip
 cc/UseDartApi: Skip
 # Tests needing Dart execution.
 dart/*: Skip
 
+[ $arch == simarm && $checked]
+# Tests needing type check support.
+cc/DartStaticResolve: Crash
+cc/DartDynamicResolve: Crash
+
 [ $arch == mips ]
 *: Skip
 
diff --git a/runtime/tools/create_resources.py b/runtime/tools/create_resources.py
new file mode 100644
index 0000000..f657ea1
--- /dev/null
+++ b/runtime/tools/create_resources.py
@@ -0,0 +1,104 @@
+# Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+#
+# This python script creates string literals in a C++ source file from a C++
+# source template and one or more resource files.
+
+import os
+import sys
+from os.path import join
+import time
+from optparse import OptionParser
+import re
+from datetime import date
+
+def makeResources(root_dir, input_files):
+  result = ''
+  resources = []
+
+  # Write each file's contents as a byte string constant.
+  for resource_file in input_files:
+    if root_dir and resource_file.startswith(root_dir):
+      resource_file_name = resource_file[ len(root_dir) : ]
+    else:
+      resource_file_name = resource_file
+    resource_url = '/%s' % resource_file_name
+    result += '// %s\n' % resource_file
+    result += 'const char '
+    resource_name = re.sub(r'(/|\.)', '_', resource_file_name) + '_'
+    result += resource_name
+    result += '[] = {\n   '
+    fileHandle = open(resource_file, 'rb')
+    lineCounter = 0
+    for byte in fileHandle.read():
+      result += ' %d,' % ord(byte)
+      lineCounter += 1
+      if lineCounter == 10:
+        result += '\n   '
+        lineCounter = 0
+    if lineCounter != 0:
+      result += '\n   '
+    result += ' 0\n};\n\n'
+    resources.append(
+        (resource_url, resource_name, os.stat(resource_file).st_size) );
+
+  # Write the resource table.
+  result += 'Resources::resource_map_entry Resources::builtin_resources_[] = '
+  result += '{\n'
+  for res in resources:
+    result += '   { "%s", %s, %d },\n' % res
+  result += '};\n\n'
+  result += 'const intptr_t Resources::builtin_resources_count_ '
+  result += '= %d;\n' % len(resources)
+  return result
+
+
+def makeFile(output_file, root_dir, input_files):
+  cc_text = '''
+// Copyright (c) %d, 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.
+
+''' % date.today().year
+  cc_text += '#include "bin/resources.h"\n\n'
+  cc_text += makeResources(root_dir, input_files)
+  open(output_file, 'w').write(cc_text)
+  return True
+
+
+def main(args):
+  try:
+    # Parse input.
+    parser = OptionParser()
+    parser.add_option("--output",
+                      action="store", type="string",
+                      help="output file name")
+    parser.add_option("--root_prefix",
+                      action="store", type="string",
+                      help="root directory for resources")
+
+    (options, args) = parser.parse_args()
+    if not options.output:
+      sys.stderr.write('--output not specified\n')
+      return -1
+    if len(args) == 0:
+      sys.stderr.write('No input files specified\n')
+      return -1
+
+    files = [ ]
+    for arg in args:
+      files.append(arg)
+
+    if not makeFile(options.output, options.root_prefix, files):
+      return -1
+
+    return 0
+  except Exception, inst:
+    sys.stderr.write('create_resources.py exception\n')
+    sys.stderr.write(str(inst))
+    sys.stderr.write('\n')
+    return -1
+
+if __name__ == '__main__':
+  sys.exit(main(sys.argv))
diff --git a/runtime/vm/assembler.h b/runtime/vm/assembler.h
index 1d24788..200716a 100644
--- a/runtime/vm/assembler.h
+++ b/runtime/vm/assembler.h
@@ -80,6 +80,11 @@
     cursor_ += sizeof(T);
   }
 
+  template<typename T> void Remit() {
+    ASSERT(Size() >= static_cast<intptr_t>(sizeof(T)));
+    cursor_ -= sizeof(T);
+  }
+
   template<typename T> T Load(int position) {
     ASSERT(position >= 0 && position <= (Size() - static_cast<int>(sizeof(T))));
     return *reinterpret_cast<T*>(contents_ + position);
diff --git a/runtime/vm/assembler_arm.cc b/runtime/vm/assembler_arm.cc
index 3331a6f..af41d08 100644
--- a/runtime/vm/assembler_arm.cc
+++ b/runtime/vm/assembler_arm.cc
@@ -6,14 +6,60 @@
 #if defined(TARGET_ARCH_ARM)
 
 #include "vm/assembler.h"
-
+#include "vm/simulator.h"
 #include "vm/runtime_entry.h"
 #include "vm/stub_code.h"
 
 namespace dart {
 
-// TODO(regis): Enable this flag after PrintStopMessage stub is implemented.
-DEFINE_FLAG(bool, print_stop_message, false, "Print stop message.");
+DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
+
+
+bool CPUFeatures::integer_division_supported_ = false;
+#if defined(DEBUG)
+bool CPUFeatures::initialized_ = false;
+#endif
+
+
+bool CPUFeatures::integer_division_supported() {
+  DEBUG_ASSERT(initialized_);
+  return integer_division_supported_;
+}
+
+
+#if defined(USING_SIMULATOR)
+void CPUFeatures::set_integer_division_supported(bool supported) {
+  integer_division_supported_ = supported;
+}
+#endif
+
+
+#define __ assembler.
+
+void CPUFeatures::InitOnce() {
+#if defined(USING_SIMULATOR)
+  integer_division_supported_ = true;
+#else
+  Assembler assembler;
+  __ mrc(R0, 15, 0, 0, 2, 0);
+  __ Lsr(R0, R0, 24);
+  __ and_(R0, R0, ShifterOperand(0xf));
+  __ Ret();
+
+  const Code& code =
+      Code::Handle(Code::FinalizeCode("DetectCPUFeatures", &assembler));
+  Instructions& instructions = Instructions::Handle(code.instructions());
+  typedef int32_t (*DetectCPUFeatures)();
+  int32_t features =
+      reinterpret_cast<DetectCPUFeatures>(instructions.EntryPoint())();
+  integer_division_supported_ = features != 0;
+#endif  // defined(USING_SIMULATOR)
+#if defined(DEBUG)
+  initialized_ = true;
+#endif
+}
+
+#undef __
 
 
 // Instruction encoding bits.
@@ -67,17 +113,15 @@
 
 uint32_t Address::encoding3() const {
   ASSERT(kind_ == Immediate);
-  const uint32_t offset_mask = (1 << 12) - 1;
-  uint32_t offset = encoding_ & offset_mask;
+  uint32_t offset = encoding_ & kOffset12Mask;
   ASSERT(offset < 256);
-  return (encoding_ & ~offset_mask) | ((offset & 0xf0) << 4) | (offset & 0xf);
+  return (encoding_ & ~kOffset12Mask) | ((offset & 0xf0) << 4) | (offset & 0xf);
 }
 
 
 uint32_t Address::vencoding() const {
   ASSERT(kind_ == Immediate);
-  const uint32_t offset_mask = (1 << 12) - 1;
-  uint32_t offset = encoding_ & offset_mask;
+  uint32_t offset = encoding_ & kOffset12Mask;
   ASSERT(offset < (1 << 10));  // In the range 0 to +1020.
   ASSERT(Utils::IsAligned(offset, 4));  // Multiple of 4.
   int mode = encoding_ & ((8|4|1) << 21);
@@ -127,7 +171,7 @@
 }
 
 
-void Assembler::EmitType5(Condition cond, int offset, bool link) {
+void Assembler::EmitType5(Condition cond, int32_t offset, bool link) {
   ASSERT(cond != kNoCondition);
   int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
                      5 << kTypeShift |
@@ -412,6 +456,13 @@
 }
 
 
+// Like mul, but sets condition flags.
+void Assembler::muls(Register rd, Register rn,
+                     Register rm, Condition cond) {
+  EmitMulOp(cond, B20, R0, rd, rn, rm);
+}
+
+
 void Assembler::mla(Register rd, Register rn,
                     Register rm, Register ra, Condition cond) {
   // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
@@ -433,6 +484,33 @@
 }
 
 
+void Assembler::EmitDivOp(Condition cond, int32_t opcode,
+                          Register rd, Register rn, Register rm) {
+  ASSERT(CPUFeatures::integer_division_supported());
+  ASSERT(rd != kNoRegister);
+  ASSERT(rn != kNoRegister);
+  ASSERT(rm != kNoRegister);
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = opcode |
+    (static_cast<int32_t>(cond) << kConditionShift) |
+    (static_cast<int32_t>(rn) << kRnShift) |
+    (static_cast<int32_t>(rd) << kRdShift) |
+    B26 | B25 | B24 | B20 | B4 |
+    (static_cast<int32_t>(rm) << kRmShift);
+  Emit(encoding);
+}
+
+
+void Assembler::sdiv(Register rd, Register rn, Register rm, Condition cond) {
+  EmitDivOp(cond, 0, rd, rn, rm);
+}
+
+
+void Assembler::udiv(Register rd, Register rn, Register rm, Condition cond) {
+  EmitDivOp(cond, B21 , rd, rn, rm);
+}
+
+
 void Assembler::ldr(Register rd, Address ad, Condition cond) {
   EmitMemOp(cond, true, false, rd, ad);
 }
@@ -1117,6 +1195,29 @@
 }
 
 
+void Assembler::mrc(Register rd, int32_t coproc, int32_t opc1,
+                    int32_t crn, int32_t crm, int32_t opc2, Condition cond) {
+  ASSERT(rd != kNoRegister);
+  ASSERT(cond != kNoCondition);
+
+  // This is all the simulator and disassembler know about.
+  ASSERT(coproc == 15);
+  ASSERT(opc1 == 0);
+  ASSERT(crn == 0);
+  ASSERT(crm == 2);
+  ASSERT(opc2 == 0);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+                     B27 | B26 | B25 | B20 | B4 |
+                     ((opc1 & 0x7) << kOpc1Shift) |
+                     ((crn & 0xf) << kCRnShift) |
+                     ((coproc & 0xf) << kCoprocShift) |
+                     ((opc2 & 0x7) << kOpc2Shift) |
+                     ((crm & 0xf) << kCRmShift) |
+                     (static_cast<int32_t>(rd) << kRdShift);
+  Emit(encoding);
+}
+
+
 void Assembler::MarkExceptionHandler(Label* label) {
   EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0));
   Label l;
@@ -1134,6 +1235,32 @@
 }
 
 
+// Uses a code sequence that can easily be decoded.
+void Assembler::LoadWordFromPoolOffset(Register rd, int32_t offset) {
+  ASSERT(rd != PP);
+  int32_t offset_mask = 0;
+  if (Address::CanHoldLoadOffset(kLoadWord, offset, &offset_mask)) {
+    ldr(rd, Address(PP, offset));
+  } else {
+    int32_t offset_hi = offset & ~offset_mask;  // signed
+    uint32_t offset_lo = offset & offset_mask;  // unsigned
+    // Inline a simplified version of AddImmediate(rd, PP, offset_hi).
+    ShifterOperand shifter_op;
+    if (ShifterOperand::CanHold(offset_hi, &shifter_op)) {
+      add(rd, PP, shifter_op);
+    } else {
+      movw(rd, Utils::Low16Bits(offset_hi));
+      const uint16_t value_high = Utils::High16Bits(offset_hi);
+      if (value_high != 0) {
+        movt(rd, value_high);
+      }
+      add(rd, PP, ShifterOperand(LR));
+    }
+    ldr(rd, Address(rd, offset_lo));
+  }
+}
+
+
 void Assembler::LoadObject(Register rd, const Object& object) {
   if (object.IsNull() ||
       object.IsSmi() ||
@@ -1145,14 +1272,13 @@
   }
   const int32_t offset =
       Array::data_offset() + 4*AddObject(object) - kHeapObjectTag;
-  if (Address::CanHoldLoadOffset(kLoadWord, offset)) {
-    ldr(rd, Address(PP, offset));
-  } else {
-    int32_t offset12_hi = offset & ~kOffset12Mask;  // signed
-    uint32_t offset12_lo = offset & kOffset12Mask;  // unsigned
-    AddImmediate(rd, PP, offset12_hi);
-    ldr(rd, Address(rd, offset12_lo));
-  }
+  LoadWordFromPoolOffset(rd, offset);
+}
+
+
+void Assembler::PushObject(const Object& object) {
+  LoadObject(IP, object);
+  Push(IP);
 }
 
 
@@ -1170,40 +1296,58 @@
 }
 
 
-bool Address::CanHoldLoadOffset(LoadOperandType type, int offset) {
+bool Address::CanHoldLoadOffset(LoadOperandType type,
+                                int32_t offset,
+                                int32_t* offset_mask) {
   switch (type) {
     case kLoadSignedByte:
     case kLoadSignedHalfword:
     case kLoadUnsignedHalfword:
-    case kLoadWordPair:
+    case kLoadWordPair: {
+      *offset_mask = 0xff;
       return Utils::IsAbsoluteUint(8, offset);  // Addressing mode 3.
+    }
     case kLoadUnsignedByte:
-    case kLoadWord:
+    case kLoadWord: {
+      *offset_mask = 0xfff;
       return Utils::IsAbsoluteUint(12, offset);  // Addressing mode 2.
+    }
     case kLoadSWord:
-    case kLoadDWord:
+    case kLoadDWord: {
+      *offset_mask = 0x3ff;
       return Utils::IsAbsoluteUint(10, offset);  // VFP addressing mode.
-    default:
+    }
+    default: {
       UNREACHABLE();
       return false;
+    }
   }
 }
 
 
-bool Address::CanHoldStoreOffset(StoreOperandType type, int offset) {
+bool Address::CanHoldStoreOffset(StoreOperandType type,
+                                 int32_t offset,
+                                 int32_t* offset_mask) {
   switch (type) {
     case kStoreHalfword:
-    case kStoreWordPair:
+    case kStoreWordPair: {
+      *offset_mask = 0xff;
       return Utils::IsAbsoluteUint(8, offset);  // Addressing mode 3.
+    }
     case kStoreByte:
-    case kStoreWord:
+    case kStoreWord: {
+      *offset_mask = 0xfff;
       return Utils::IsAbsoluteUint(12, offset);  // Addressing mode 2.
+    }
     case kStoreSWord:
-    case kStoreDWord:
+    case kStoreDWord: {
+      *offset_mask = 0x3ff;
       return Utils::IsAbsoluteUint(10, offset);  // VFP addressing mode.
-    default:
+    }
+    default: {
       UNREACHABLE();
       return false;
+    }
   }
 }
 
@@ -1272,7 +1416,18 @@
 
 void Assembler::Branch(const ExternalLabel* label, Condition cond) {
   LoadImmediate(IP, label->address(), cond);  // Address is never patched.
-  mov(PC, ShifterOperand(IP), cond);
+  bx(IP, cond);
+}
+
+
+void Assembler::BranchPatchable(const ExternalLabel* label) {
+  // Use a fixed size code sequence, since a function prologue may be patched
+  // with this branch sequence.
+  // Contrarily to BranchLinkPatchable, BranchPatchable requires an instruction
+  // cache flush upon patching.
+  movw(IP, Utils::Low16Bits(label->address()));
+  movt(IP, Utils::High16Bits(label->address()));
+  bx(IP);
 }
 
 
@@ -1289,25 +1444,7 @@
   // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors).
   const int32_t offset =
       Array::data_offset() + 4*AddExternalLabel(label) - kHeapObjectTag;
-  if (Address::CanHoldLoadOffset(kLoadWord, offset)) {
-    ldr(LR, Address(PP, offset));
-  } else {
-    int32_t offset12_hi = offset & ~kOffset12Mask;  // signed
-    uint32_t offset12_lo = offset & kOffset12Mask;  // unsigned
-    // Inline a simplified version of AddImmediate(LR, CP, offset12_hi).
-    ShifterOperand shifter_op;
-    if (ShifterOperand::CanHold(offset12_hi, &shifter_op)) {
-      add(LR, PP, shifter_op);
-    } else {
-      movw(LR, Utils::Low16Bits(offset12_hi));
-      const uint16_t value_high = Utils::High16Bits(offset12_hi);
-      if (value_high != 0) {
-        movt(LR, value_high);
-      }
-      add(LR, PP, ShifterOperand(LR));
-    }
-    ldr(LR, Address(LR, offset12_lo));
-  }
+  LoadWordFromPoolOffset(LR, offset);
   blx(LR);  // Use blx instruction so that the return branch prediction works.
 }
 
@@ -1320,24 +1457,10 @@
 }
 
 
-void Assembler::BranchLinkOffset(Register base, int offset) {
+void Assembler::BranchLinkOffset(Register base, int32_t offset) {
   ASSERT(base != PC);
   ASSERT(base != IP);
-  if (Address::CanHoldLoadOffset(kLoadWord, offset)) {
-    ldr(IP, Address(base, offset));
-  } else {
-    int offset_hi = offset & ~kOffset12Mask;
-    int offset_lo = offset & kOffset12Mask;
-    ShifterOperand offset_hi_op;
-    if (ShifterOperand::CanHold(offset_hi, &offset_hi_op)) {
-      add(IP, base, offset_hi_op);
-      ldr(IP, Address(IP, offset_lo));
-    } else {
-      LoadImmediate(IP, offset_hi);
-      add(IP, IP, ShifterOperand(base));
-      ldr(IP, Address(IP, offset_lo));
-    }
-  }
+  LoadFromOffset(kLoadWord, IP, base, offset);
   blx(IP);  // Use blx instruction so that the return branch prediction works.
 }
 
@@ -1389,14 +1512,13 @@
                                Register base,
                                int32_t offset,
                                Condition cond) {
-  if (!Address::CanHoldLoadOffset(type, offset)) {
+  int32_t offset_mask = 0;
+  if (!Address::CanHoldLoadOffset(type, offset, &offset_mask)) {
     ASSERT(base != IP);
-    LoadImmediate(IP, offset, cond);
-    add(IP, IP, ShifterOperand(base), cond);
+    AddImmediate(IP, base, offset & ~offset_mask, cond);
     base = IP;
-    offset = 0;
+    offset = offset & offset_mask;
   }
-  ASSERT(Address::CanHoldLoadOffset(type, offset));
   switch (type) {
     case kLoadSignedByte:
       ldrsb(reg, Address(base, offset), cond);
@@ -1427,15 +1549,14 @@
                               Register base,
                               int32_t offset,
                               Condition cond) {
-  if (!Address::CanHoldStoreOffset(type, offset)) {
+  int32_t offset_mask = 0;
+  if (!Address::CanHoldStoreOffset(type, offset, &offset_mask)) {
     ASSERT(reg != IP);
     ASSERT(base != IP);
-    LoadImmediate(IP, offset, cond);
-    add(IP, IP, ShifterOperand(base), cond);
+    AddImmediate(IP, base, offset & ~offset_mask, cond);
     base = IP;
-    offset = 0;
+    offset = offset & offset_mask;
   }
-  ASSERT(Address::CanHoldStoreOffset(type, offset));
   switch (type) {
     case kStoreByte:
       strb(reg, Address(base, offset), cond);
@@ -1459,14 +1580,13 @@
                                 Register base,
                                 int32_t offset,
                                 Condition cond) {
-  if (!Address::CanHoldLoadOffset(kLoadSWord, offset)) {
+  int32_t offset_mask = 0;
+  if (!Address::CanHoldLoadOffset(kLoadSWord, offset, &offset_mask)) {
     ASSERT(base != IP);
-    LoadImmediate(IP, offset, cond);
-    add(IP, IP, ShifterOperand(base), cond);
+    AddImmediate(IP, base, offset & ~offset_mask, cond);
     base = IP;
-    offset = 0;
+    offset = offset & offset_mask;
   }
-  ASSERT(Address::CanHoldLoadOffset(kLoadSWord, offset));
   vldrs(reg, Address(base, offset), cond);
 }
 
@@ -1475,14 +1595,13 @@
                                Register base,
                                int32_t offset,
                                Condition cond) {
-  if (!Address::CanHoldStoreOffset(kStoreSWord, offset)) {
+  int32_t offset_mask = 0;
+  if (!Address::CanHoldStoreOffset(kStoreSWord, offset, &offset_mask)) {
     ASSERT(base != IP);
-    LoadImmediate(IP, offset, cond);
-    add(IP, IP, ShifterOperand(base), cond);
+    AddImmediate(IP, base, offset & ~offset_mask, cond);
     base = IP;
-    offset = 0;
+    offset = offset & offset_mask;
   }
-  ASSERT(Address::CanHoldStoreOffset(kStoreSWord, offset));
   vstrs(reg, Address(base, offset), cond);
 }
 
@@ -1491,14 +1610,13 @@
                                 Register base,
                                 int32_t offset,
                                 Condition cond) {
-  if (!Address::CanHoldLoadOffset(kLoadDWord, offset)) {
+  int32_t offset_mask = 0;
+  if (!Address::CanHoldLoadOffset(kLoadDWord, offset, &offset_mask)) {
     ASSERT(base != IP);
-    LoadImmediate(IP, offset, cond);
-    add(IP, IP, ShifterOperand(base), cond);
+    AddImmediate(IP, base, offset & ~offset_mask, cond);
     base = IP;
-    offset = 0;
+    offset = offset & offset_mask;
   }
-  ASSERT(Address::CanHoldLoadOffset(kLoadDWord, offset));
   vldrd(reg, Address(base, offset), cond);
 }
 
@@ -1507,14 +1625,13 @@
                                Register base,
                                int32_t offset,
                                Condition cond) {
-  if (!Address::CanHoldStoreOffset(kStoreDWord, offset)) {
+  int32_t offset_mask = 0;
+  if (!Address::CanHoldStoreOffset(kStoreDWord, offset, &offset_mask)) {
     ASSERT(base != IP);
-    LoadImmediate(IP, offset, cond);
-    add(IP, IP, ShifterOperand(base), cond);
+    AddImmediate(IP, base, offset & ~offset_mask, cond);
     base = IP;
-    offset = 0;
+    offset = offset & offset_mask;
   }
-  ASSERT(Address::CanHoldStoreOffset(kStoreDWord, offset));
   vstrd(reg, Address(base, offset), cond);
 }
 
@@ -1677,11 +1794,10 @@
 
 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) {
   // Preserve volatile CPU registers.
-  EnterFrame(kDartVolatileCpuRegs | (1 << FP), 0);
+  EnterFrame(kDartVolatileCpuRegs | (1 << FP) | (1 << LR), 0);
 
   // Preserve all volatile FPU registers.
-  // TODO(regis): Use vstmd instruction once supported.
-  // vstmd(DB_W, SP, kDartFirstVolatileFpuReg, kDartLastVolatileFpuReg);
+  vstmd(DB_W, SP, kDartFirstVolatileFpuReg, kDartLastVolatileFpuReg);
 
   ReserveAlignedFrameSpace(frame_space);
 }
@@ -1692,16 +1808,15 @@
   // and ensure proper alignment of the stack frame.
   // We need to restore it before restoring registers.
   const intptr_t kPushedRegistersSize =
-      kDartVolatileCpuRegCount * kWordSize;
-  // TODO(regis): + kDartVolatileFpuRegCount * 2 * kWordSize;
+      kDartVolatileCpuRegCount * kWordSize +
+      kDartVolatileFpuRegCount * 2 * kWordSize;
   AddImmediate(SP, FP, -kPushedRegistersSize);
 
   // Restore all volatile FPU registers.
-  // TODO(regis): Use vldmd instruction once supported.
-  // vldmd(IA_W, SP, kDartFirstVolatileFpuReg, kDartLastVolatileFpuReg);
+  vldmd(IA_W, SP, kDartFirstVolatileFpuReg, kDartLastVolatileFpuReg);
 
   // Restore volatile CPU registers.
-  LeaveFrame(kDartVolatileCpuRegs | (1 << FP));
+  LeaveFrame(kDartVolatileCpuRegs | (1 << FP) | (1 << LR));
 }
 
 
@@ -1710,6 +1825,61 @@
 }
 
 
+void Assembler::EnterDartFrame(intptr_t frame_size) {
+  const intptr_t offset = CodeSize();
+  // Save PC in frame for fast identification of corresponding code.
+  // Note that callee-saved registers can be added to the register list.
+  EnterFrame((1 << PP) | (1 << FP) | (1 << LR) | (1 << PC), 0);
+
+  if (offset != 0) {
+    // Adjust saved PC for any intrinsic code that could have been generated
+    // before a frame is created. Use PP as temp register.
+    ldr(PP, Address(FP, 2 * kWordSize));
+    AddImmediate(PP, PP, -offset);
+    str(PP, Address(FP, 2 * kWordSize));
+  }
+
+  // Setup pool pointer for this dart function.
+  const intptr_t object_pool_pc_dist =
+     Instructions::HeaderSize() - Instructions::object_pool_offset() +
+     CodeSize() + Instr::kPCReadOffset;
+  ldr(PP, Address(PC, -object_pool_pc_dist));
+
+  // Reserve space for locals.
+  AddImmediate(SP, -frame_size);
+}
+
+
+void Assembler::LeaveDartFrame() {
+  LeaveFrame((1 << PP) | (1 << FP) | (1 << LR));
+  // Adjust SP for PC pushed in EnterDartFrame.
+  AddImmediate(SP, kWordSize);
+}
+
+
+void Assembler::EnterStubFrame() {
+  // Push 0 as saved PC for stub frames.
+  mov(IP, ShifterOperand(LR));
+  mov(LR, ShifterOperand(0));
+  EnterFrame((1 << FP) | (1 << IP) | (1 << LR), 0);
+}
+
+
+void Assembler::LeaveStubFrame() {
+  LeaveFrame((1 << FP) | (1 << LR));
+  // Adjust SP for null PC pushed in EnterStubFrame.
+  AddImmediate(SP, kWordSize);
+}
+
+
+void Assembler::TryAllocate(const Class& cls,
+                            Label* failure,
+                            bool near_jump,
+                            Register instance_reg) {
+  UNIMPLEMENTED();
+}
+
+
 void Assembler::Stop(const char* message) {
   if (FLAG_print_stop_message) {
     PushList((1 << R0) | (1 << IP) | (1 << LR));  // Preserve R0, IP, LR.
@@ -1729,7 +1899,7 @@
 }
 
 
-int32_t Assembler::EncodeBranchOffset(int offset, int32_t inst) {
+int32_t Assembler::EncodeBranchOffset(int32_t offset, int32_t inst) {
   // The offset is off by 8 due to the way the ARM CPUs read PC.
   offset -= 8;
   ASSERT(Utils::IsAligned(offset, 4));
diff --git a/runtime/vm/assembler_arm.h b/runtime/vm/assembler_arm.h
index f2203d6..67e385a 100644
--- a/runtime/vm/assembler_arm.h
+++ b/runtime/vm/assembler_arm.h
@@ -12,6 +12,7 @@
 #include "platform/assert.h"
 #include "platform/utils.h"
 #include "vm/constants_arm.h"
+#include "vm/simulator.h"
 
 namespace dart {
 
@@ -64,11 +65,20 @@
 
 class CPUFeatures : public AllStatic {
  public:
-  static void InitOnce() { }
+  static void InitOnce();
   static bool double_truncate_round_supported() {
     UNIMPLEMENTED();
     return false;
   }
+  static bool integer_division_supported();
+#if defined(USING_SIMULATOR)
+  static void set_integer_division_supported(bool supported);
+#endif
+ private:
+  static bool integer_division_supported_;
+#if defined(DEBUG)
+  static bool initialized_;
+#endif
 };
 
 
@@ -249,8 +259,12 @@
     encoding_ = so.encoding() | am | (static_cast<uint32_t>(rn) << kRnShift);
   }
 
-  static bool CanHoldLoadOffset(LoadOperandType type, int offset);
-  static bool CanHoldStoreOffset(StoreOperandType type, int offset);
+  static bool CanHoldLoadOffset(LoadOperandType type,
+                                int32_t offset,
+                                int32_t* offset_mask);
+  static bool CanHoldStoreOffset(StoreOperandType type,
+                                 int32_t offset,
+                                 int32_t* offset_mask);
 
  private:
   uint32_t encoding() const { return encoding_; }
@@ -380,6 +394,7 @@
 
   // Multiply instructions.
   void mul(Register rd, Register rn, Register rm, Condition cond = AL);
+  void muls(Register rd, Register rn, Register rm, Condition cond = AL);
   void mla(Register rd, Register rn, Register rm, Register ra,
            Condition cond = AL);
   void mls(Register rd, Register rn, Register rm, Register ra,
@@ -387,6 +402,10 @@
   void umull(Register rd_lo, Register rd_hi, Register rn, Register rm,
              Condition cond = AL);
 
+  // Division instructions.
+  void sdiv(Register rd, Register rn, Register rm, Condition cond = AL);
+  void udiv(Register rd, Register rn, Register rm, Condition cond = AL);
+
   // Load/store instructions.
   void ldr(Register rd, Address ad, Condition cond = AL);
   void str(Register rd, Address ad, Condition cond = AL);
@@ -491,10 +510,17 @@
   void bx(Register rm, Condition cond = AL);
   void blx(Register rm, Condition cond = AL);
 
+  // Move to ARM core register from Coprocessor.
+  void mrc(Register rd, int32_t coproc, int32_t opc1,
+           int32_t crn, int32_t crm, int32_t opc2, Condition cond = AL);
+
   // Macros.
   // Branch to an entry address. Call sequence is never patched.
   void Branch(const ExternalLabel* label, Condition cond = AL);
 
+  // Branch to an entry address. Call sequence can be patched or even replaced.
+  void BranchPatchable(const ExternalLabel* label);
+
   // Branch and link to an entry address. Call sequence is never patched.
   void BranchLink(const ExternalLabel* label);
 
@@ -506,7 +532,7 @@
   void BranchLinkStore(const ExternalLabel* label, Address ad);
 
   // Branch and link to [base + offset]. Call sequence is never patched.
-  void BranchLinkOffset(Register base, int offset);
+  void BranchLinkOffset(Register base, int32_t offset);
 
   // Add signed immediate value to rd. May clobber IP.
   void AddImmediate(Register rd, int32_t value, Condition cond = AL);
@@ -528,6 +554,8 @@
   void MarkExceptionHandler(Label* label);
   void Drop(intptr_t stack_elements);
   void LoadObject(Register rd, const Object& object);
+  void PushObject(const Object& object);
+  void LoadWordFromPoolOffset(Register rd, int32_t offset);
   void LoadFromOffset(LoadOperandType type,
                       Register reg,
                       Register base,
@@ -593,6 +621,31 @@
 
   void CallRuntime(const RuntimeEntry& entry);
 
+  // Set up a Dart frame on entry with a frame pointer and PC information to
+  // enable easy access to the RawInstruction object of code corresponding
+  // to this frame.
+  void EnterDartFrame(intptr_t frame_size);
+  void LeaveDartFrame();
+
+  // Set up a stub frame so that the stack traversal code can easily identify
+  // a stub frame.
+  void EnterStubFrame();
+  void LeaveStubFrame();
+
+  // Instruction pattern from entrypoint is used in Dart frame prologs
+  // to set up the frame and save a PC which can be used to figure out the
+  // RawInstruction object corresponding to the code running in the frame.
+  static const intptr_t kOffsetOfSavedPCfromEntrypoint = Instr::kPCReadOffset;
+
+  // Inlined allocation of an instance of class 'cls', code has no runtime
+  // calls. Jump to 'failure' if the instance cannot be allocated here.
+  // Allocated instance is returned in 'instance_reg'.
+  // Only the tags field of the object is initialized.
+  void TryAllocate(const Class& cls,
+                   Label* failure,
+                   bool near_jump,
+                   Register instance_reg);
+
   // Emit data (e.g encoded instruction or immediate) in instruction stream.
   void Emit(int32_t value);
 
@@ -629,7 +682,7 @@
                   Register rd,
                   ShifterOperand so);
 
-  void EmitType5(Condition cond, int offset, bool link);
+  void EmitType5(Condition cond, int32_t offset, bool link);
 
   void EmitMemOp(Condition cond,
                  bool load,
@@ -667,6 +720,12 @@
                  Register rm,
                  Register rs);
 
+  void EmitDivOp(Condition cond,
+                 int32_t opcode,
+                 Register rd,
+                 Register rn,
+                 Register rm);
+
   void EmitMultiVSMemOp(Condition cond,
                         BlockAddressMode am,
                         bool load,
@@ -704,9 +763,9 @@
                  SRegister sm);
 
   void EmitBranch(Condition cond, Label* label, bool link);
-  static int32_t EncodeBranchOffset(int offset, int32_t inst);
+  static int32_t EncodeBranchOffset(int32_t offset, int32_t inst);
   static int DecodeBranchOffset(int32_t inst);
-  int32_t EncodeTstOffset(int offset, int32_t inst);
+  int32_t EncodeTstOffset(int32_t offset, int32_t inst);
   int DecodeTstOffset(int32_t inst);
 
   // Returns whether or not the given register is used for passing parameters.
diff --git a/runtime/vm/assembler_arm_test.cc b/runtime/vm/assembler_arm_test.cc
index bdd0837..fa47c7f 100644
--- a/runtime/vm/assembler_arm_test.cc
+++ b/runtime/vm/assembler_arm_test.cc
@@ -1361,6 +1361,181 @@
   EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
 }
 
+
+// Check that assembler mrc instruction encoding, and simulator decoding
+// are in agreement.
+#if defined(USING_SIMULATOR)
+ASSEMBLER_TEST_GENERATE(MrcHaveDiv, assembler) {
+  __ mrc(R0, 15, 0, 0, 2, 0);
+  __ Lsr(R0, R0, 24);
+  __ and_(R0, R0, ShifterOperand(0xf));
+  __ mov(PC, ShifterOperand(LR));
+}
+
+
+ASSEMBLER_TEST_RUN(MrcHaveDiv, test) {
+  EXPECT(test != NULL);
+  typedef int (*Tst)();
+  bool b = CPUFeatures::integer_division_supported();
+  CPUFeatures::set_integer_division_supported(true);
+  EXPECT_LT(0, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
+  CPUFeatures::set_integer_division_supported(b);
+}
+
+
+ASSEMBLER_TEST_GENERATE(MrcNoDiv, assembler) {
+  __ mrc(R0, 15, 0, 0, 2, 0);
+  __ Lsr(R0, R0, 24);
+  __ and_(R0, R0, ShifterOperand(0xf));
+  __ mov(PC, ShifterOperand(LR));
+}
+
+
+ASSEMBLER_TEST_RUN(MrcNoDiv, test) {
+  EXPECT(test != NULL);
+  typedef int (*Tst)();
+  bool b = CPUFeatures::integer_division_supported();
+  CPUFeatures::set_integer_division_supported(false);
+  EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
+  CPUFeatures::set_integer_division_supported(b);
+}
+#endif  // defined(USING_SIMULATOR)
+
+
+ASSEMBLER_TEST_GENERATE(MrcReal, assembler) {
+  __ mrc(R0, 15, 0, 0, 2, 0);
+  __ Lsr(R0, R0, 24);
+  __ and_(R0, R0, ShifterOperand(0xf));
+  __ mov(PC, ShifterOperand(LR));
+}
+
+
+ASSEMBLER_TEST_RUN(MrcReal, test) {
+  EXPECT(test != NULL);
+  typedef int (*Tst)();
+  bool have_div = CPUFeatures::integer_division_supported();
+  int32_t r = EXECUTE_TEST_CODE_INT32(Tst, test->entry());
+  if (have_div) {
+    EXPECT_LT(0, r);
+  } else {
+    EXPECT_EQ(0, r);
+  }
+}
+
+
+ASSEMBLER_TEST_GENERATE(Udiv, assembler) {
+  __ mov(R0, ShifterOperand(27));
+  __ mov(R1, ShifterOperand(9));
+  __ udiv(R2, R0, R1);
+  __ Mov(R0, R2);
+  __ mov(PC, ShifterOperand(LR));
+}
+
+
+ASSEMBLER_TEST_RUN(Udiv, test) {
+  EXPECT(test != NULL);
+  typedef int (*Tst)();
+  EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Sdiv, assembler) {
+  __ mov(R0, ShifterOperand(27));
+  __ LoadImmediate(R1, -9);
+  __ sdiv(R2, R0, R1);
+  __ Mov(R0, R2);
+  __ mov(PC, ShifterOperand(LR));
+}
+
+
+ASSEMBLER_TEST_RUN(Sdiv, test) {
+  EXPECT(test != NULL);
+  typedef int (*Tst)();
+  EXPECT_EQ(-3, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Udiv_zero, assembler) {
+  __ mov(R0, ShifterOperand(27));
+  __ mov(R1, ShifterOperand(0));
+  __ udiv(R2, R0, R1);
+  __ Mov(R0, R2);
+  __ mov(PC, ShifterOperand(LR));
+}
+
+
+ASSEMBLER_TEST_RUN(Udiv_zero, test) {
+  EXPECT(test != NULL);
+  typedef int (*Tst)();
+  EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Sdiv_zero, assembler) {
+  __ mov(R0, ShifterOperand(27));
+  __ mov(R1, ShifterOperand(0));
+  __ udiv(R2, R0, R1);
+  __ Mov(R0, R2);
+  __ mov(PC, ShifterOperand(LR));
+}
+
+
+ASSEMBLER_TEST_RUN(Sdiv_zero, test) {
+  EXPECT(test != NULL);
+  typedef int (*Tst)();
+  EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Udiv_corner, assembler) {
+  __ LoadImmediate(R0, 0x80000000);
+  __ LoadImmediate(R1, 0xffffffff);
+  __ udiv(R2, R0, R1);
+  __ Mov(R0, R2);
+  __ mov(PC, ShifterOperand(LR));
+}
+
+
+ASSEMBLER_TEST_RUN(Udiv_corner, test) {
+  EXPECT(test != NULL);
+  typedef int (*Tst)();
+  EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Sdiv_corner, assembler) {
+  __ LoadImmediate(R0, 0x80000000);
+  __ LoadImmediate(R1, 0xffffffff);
+  __ sdiv(R2, R0, R1);
+  __ Mov(R0, R2);
+  __ mov(PC, ShifterOperand(LR));
+}
+
+
+ASSEMBLER_TEST_RUN(Sdiv_corner, test) {
+  EXPECT(test != NULL);
+  typedef int (*Tst)();
+  EXPECT_EQ(static_cast<int32_t>(0x80000000),
+            EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Muls, assembler) {
+  __ mov(R0, ShifterOperand(3));
+  __ LoadImmediate(R1, -9);
+  __ muls(R2, R0, R1);
+  __ mov(R0, ShifterOperand(42), MI);
+  __ mov(PC, ShifterOperand(LR));
+}
+
+
+ASSEMBLER_TEST_RUN(Muls, test) {
+  EXPECT(test != NULL);
+  typedef int (*Tst)();
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
+}
+
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_ARM
diff --git a/runtime/vm/assembler_ia32.cc b/runtime/vm/assembler_ia32.cc
index 824b592..2acf8ce 100644
--- a/runtime/vm/assembler_ia32.cc
+++ b/runtime/vm/assembler_ia32.cc
@@ -17,6 +17,7 @@
 
 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
 DEFINE_FLAG(bool, use_sse41, true, "Use SSE 4.1 if available");
+DECLARE_FLAG(bool, inline_alloc);
 
 
 bool CPUFeatures::sse2_supported_ = false;
@@ -2114,6 +2115,58 @@
 }
 
 
+void Assembler::TryAllocate(const Class& cls,
+                            Label* failure,
+                            bool near_jump,
+                            Register instance_reg) {
+  ASSERT(failure != NULL);
+  if (FLAG_inline_alloc) {
+    Heap* heap = Isolate::Current()->heap();
+    const intptr_t instance_size = cls.instance_size();
+    movl(instance_reg, Address::Absolute(heap->TopAddress()));
+    addl(instance_reg, Immediate(instance_size));
+    // instance_reg: potential next object start.
+    cmpl(instance_reg, Address::Absolute(heap->EndAddress()));
+    j(ABOVE_EQUAL, failure, near_jump);
+    // Successfully allocated the object, now update top to point to
+    // next object start and store the class in the class field of object.
+    movl(Address::Absolute(heap->TopAddress()), instance_reg);
+    ASSERT(instance_size >= kHeapObjectTag);
+    subl(instance_reg, Immediate(instance_size - kHeapObjectTag));
+    uword tags = 0;
+    tags = RawObject::SizeTag::update(instance_size, tags);
+    ASSERT(cls.id() != kIllegalCid);
+    tags = RawObject::ClassIdTag::update(cls.id(), tags);
+    movl(FieldAddress(instance_reg, Object::tags_offset()), Immediate(tags));
+  } else {
+    jmp(failure);
+  }
+}
+
+
+void Assembler::EnterDartFrame(intptr_t frame_size) {
+  const intptr_t offset = CodeSize();
+  EnterFrame(0);
+  Label dart_entry;
+  call(&dart_entry);
+  Bind(&dart_entry);
+  // Adjust saved PC for any intrinsic code that could have been generated
+  // before a frame is created.
+  if (offset != 0) {
+    addl(Address(ESP, 0), Immediate(-offset));
+  }
+  if (frame_size != 0) {
+    subl(ESP, Immediate(frame_size));
+  }
+}
+
+
+void Assembler::EnterStubFrame() {
+  EnterFrame(0);
+  pushl(Immediate(0));  // Push 0 in the saved PC area for stub frames.
+}
+
+
 void Assembler::Stop(const char* message) {
   if (FLAG_print_stop_message) {
     pushl(EAX);  // Preserve EAX.
diff --git a/runtime/vm/assembler_ia32.h b/runtime/vm/assembler_ia32.h
index adc9494..07088a4 100644
--- a/runtime/vm/assembler_ia32.h
+++ b/runtime/vm/assembler_ia32.h
@@ -683,6 +683,58 @@
     buffer_.FinalizeInstructions(region);
   }
 
+  // Set up a Dart frame on entry with a frame pointer and PC information to
+  // enable easy access to the RawInstruction object of code corresponding
+  // to this frame.
+  // The dart frame layout is as follows:
+  //   ....
+  //   ret PC
+  //   saved EBP     <=== EBP
+  //   pc (used to derive the RawInstruction Object of the dart code)
+  //   locals space  <=== ESP
+  //   .....
+  // This code sets this up with the sequence:
+  //   pushl ebp
+  //   movl ebp, esp
+  //   call L
+  //   L: <code to adjust saved pc if there is any intrinsification code>
+  //   .....
+  void EnterDartFrame(intptr_t frame_size);
+
+  // Set up a stub frame so that the stack traversal code can easily identify
+  // a stub frame.
+  // The stub frame layout is as follows:
+  //   ....
+  //   ret PC
+  //   saved EBP
+  //   0 (used to indicate frame is a stub frame)
+  //   .....
+  // This code sets this up with the sequence:
+  //   pushl ebp
+  //   movl ebp, esp
+  //   pushl immediate(0)
+  //   .....
+  void EnterStubFrame();
+
+  // Instruction pattern from entrypoint is used in dart frame prologs
+  // to set up the frame and save a PC which can be used to figure out the
+  // RawInstruction object corresponding to the code running in the frame.
+  // entrypoint:
+  //   pushl ebp          (size is 1 byte)
+  //   movl ebp, esp      (size is 2 bytes)
+  //   call L             (size is 5 bytes)
+  //   L:
+  static const intptr_t kOffsetOfSavedPCfromEntrypoint = 8;
+
+  // Inlined allocation of an instance of class 'cls', code has no runtime
+  // calls. Jump to 'failure' if the instance cannot be allocated here.
+  // Allocated instance is returned in 'instance_reg'.
+  // Only the tags field of the object is initialized.
+  void TryAllocate(const Class& cls,
+                          Label* failure,
+                          bool near_jump,
+                          Register instance_reg);
+
   // Debugging and bringup support.
   void Stop(const char* message);
   void Unimplemented(const char* message);
diff --git a/runtime/vm/assembler_macros.h b/runtime/vm/assembler_macros.h
deleted file mode 100644
index a4a4e31..0000000
--- a/runtime/vm/assembler_macros.h
+++ /dev/null
@@ -1,20 +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.
-
-#ifndef VM_ASSEMBLER_MACROS_H_
-#define VM_ASSEMBLER_MACROS_H_
-
-#if defined(TARGET_ARCH_IA32)
-#include "vm/assembler_macros_ia32.h"
-#elif defined(TARGET_ARCH_X64)
-#include "vm/assembler_macros_x64.h"
-#elif defined(TARGET_ARCH_ARM)
-#include "vm/assembler_macros_arm.h"
-#elif defined(TARGET_ARCH_MIPS)
-#include "vm/assembler_macros_mips.h"
-#else
-#error Unknown architecture.
-#endif
-
-#endif  // VM_ASSEMBLER_MACROS_H_
diff --git a/runtime/vm/assembler_macros_arm.cc b/runtime/vm/assembler_macros_arm.cc
deleted file mode 100644
index 38cd6a5..0000000
--- a/runtime/vm/assembler_macros_arm.cc
+++ /dev/null
@@ -1,76 +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.
-
-#include "vm/globals.h"
-#if defined(TARGET_ARCH_ARM)
-
-#include "vm/assembler_macros.h"
-
-#include "vm/assembler.h"
-
-namespace dart {
-
-#define __ assembler->
-
-
-void AssemblerMacros::TryAllocate(Assembler* assembler,
-                                  const Class& cls,
-                                  Label* failure,
-                                  bool near_jump,
-                                  Register instance_reg) {
-  UNIMPLEMENTED();
-}
-
-
-void AssemblerMacros::EnterDartFrame(Assembler* assembler,
-                                     intptr_t frame_size) {
-  const intptr_t offset = assembler->CodeSize();
-  // Save PC in frame for fast identification of corresponding code.
-  // Note that callee-saved registers can be added to the register list.
-  __ EnterFrame((1 << PP) | (1 << FP) | (1 << LR) | (1 << PC), 0);
-
-  if (offset != 0) {
-    // Adjust saved PC for any intrinsic code that could have been generated
-    // before a frame is created. Use PP as temp register.
-    __ ldr(PP, Address(FP, 2 * kWordSize));
-    __ AddImmediate(PP, PP, -offset);
-    __ str(PP, Address(FP, 2 * kWordSize));
-  }
-
-  // Setup pool pointer for this dart function.
-  const intptr_t object_pool_pc_dist =
-     Instructions::HeaderSize() - Instructions::object_pool_offset() +
-     assembler->CodeSize() + Instr::kPCReadOffset;
-  __ ldr(PP, Address(PC, -object_pool_pc_dist));
-
-  // Reserve space for locals.
-  __ AddImmediate(SP, -frame_size);
-}
-
-
-void AssemblerMacros::LeaveDartFrame(Assembler* assembler) {
-  __ LeaveFrame((1 << PP) | (1 << FP) | (1 << LR));
-  // Adjust SP for PC pushed in EnterDartFrame.
-  __ AddImmediate(SP, kWordSize);
-}
-
-
-void AssemblerMacros::EnterStubFrame(Assembler* assembler) {
-  // Push 0 as saved PC for stub frames.
-  __ mov(IP, ShifterOperand(LR));
-  __ mov(LR, ShifterOperand(0));
-  __ EnterFrame((1 << FP) | (1 << IP) | (1 << LR), 0);
-}
-
-
-void AssemblerMacros::LeaveStubFrame(Assembler* assembler) {
-  __ LeaveFrame((1 << FP) | (1 << LR));
-  // Adjust SP for null PC pushed in EnterStubFrame.
-  __ AddImmediate(SP, kWordSize);
-}
-
-}  // namespace dart
-
-#endif  // defined TARGET_ARCH_ARM
-
diff --git a/runtime/vm/assembler_macros_arm.h b/runtime/vm/assembler_macros_arm.h
deleted file mode 100644
index 0a5119b..0000000
--- a/runtime/vm/assembler_macros_arm.h
+++ /dev/null
@@ -1,56 +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.
-// The class 'AssemblerMacros' contains assembler instruction groups that
-// are used in Dart.
-
-#ifndef VM_ASSEMBLER_MACROS_ARM_H_
-#define VM_ASSEMBLER_MACROS_ARM_H_
-
-#ifndef VM_ASSEMBLER_MACROS_H_
-#error Do not include assembler_macros_arm.h directly; use assembler_macros.h.
-#endif
-
-#include "vm/allocation.h"
-#include "vm/constants_arm.h"
-
-namespace dart {
-
-// Forward declarations.
-class Assembler;
-class Class;
-class Label;
-
-class AssemblerMacros : public AllStatic {
- public:
-  // Inlined allocation of an instance of class 'cls', code has no runtime
-  // calls. Jump to 'failure' if the instance cannot be allocated here.
-  // Allocated instance is returned in 'instance_reg'.
-  // Only the tags field of the object is initialized.
-  static void TryAllocate(Assembler* assembler,
-                          const Class& cls,
-                          Label* failure,
-                          bool near_jump,
-                          Register instance_reg);
-
-  // Set up a dart frame on entry with a frame pointer and PC information to
-  // enable easy access to the RawInstruction object of code corresponding
-  // to this frame.
-  static void EnterDartFrame(Assembler* assembler, intptr_t frame_size);
-  static void LeaveDartFrame(Assembler* assembler);
-
-  // Set up a stub frame so that the stack traversal code can easily identify
-  // a stub frame.
-  static void EnterStubFrame(Assembler* assembler);
-  static void LeaveStubFrame(Assembler* assembler);
-
-  // Instruction pattern from entrypoint is used in dart frame prologs
-  // to set up the frame and save a PC which can be used to figure out the
-  // RawInstruction object corresponding to the code running in the frame.
-  static const intptr_t kOffsetOfSavedPCfromEntrypoint = Instr::kPCReadOffset;
-};
-
-}  // namespace dart.
-
-#endif  // VM_ASSEMBLER_MACROS_ARM_H_
-
diff --git a/runtime/vm/assembler_macros_ia32.cc b/runtime/vm/assembler_macros_ia32.cc
deleted file mode 100644
index 38ebf3e..0000000
--- a/runtime/vm/assembler_macros_ia32.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// 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.
-
-#include "vm/globals.h"
-#if defined(TARGET_ARCH_IA32)
-
-#include "vm/assembler_macros.h"
-
-#include "vm/assembler.h"
-
-namespace dart {
-
-DECLARE_FLAG(bool, inline_alloc);
-
-#define __ assembler->
-
-// Static.
-void AssemblerMacros::TryAllocate(Assembler* assembler,
-                                  const Class& cls,
-                                  Label* failure,
-                                  bool near_jump,
-                                  Register instance_reg) {
-  ASSERT(failure != NULL);
-  if (FLAG_inline_alloc) {
-    Heap* heap = Isolate::Current()->heap();
-    const intptr_t instance_size = cls.instance_size();
-    __ movl(instance_reg, Address::Absolute(heap->TopAddress()));
-    __ addl(instance_reg, Immediate(instance_size));
-    // instance_reg: potential next object start.
-    __ cmpl(instance_reg, Address::Absolute(heap->EndAddress()));
-    __ j(ABOVE_EQUAL, failure, near_jump);
-    // Successfully allocated the object, now update top to point to
-    // next object start and store the class in the class field of object.
-    __ movl(Address::Absolute(heap->TopAddress()), instance_reg);
-    ASSERT(instance_size >= kHeapObjectTag);
-    __ subl(instance_reg, Immediate(instance_size - kHeapObjectTag));
-    uword tags = 0;
-    tags = RawObject::SizeTag::update(instance_size, tags);
-    ASSERT(cls.id() != kIllegalCid);
-    tags = RawObject::ClassIdTag::update(cls.id(), tags);
-    __ movl(FieldAddress(instance_reg, Object::tags_offset()), Immediate(tags));
-  } else {
-    __ jmp(failure);
-  }
-}
-
-
-void AssemblerMacros::EnterDartFrame(Assembler* assembler,
-                                     intptr_t frame_size) {
-  const intptr_t offset = assembler->CodeSize();
-  __ EnterFrame(0);
-  Label dart_entry;
-  __ call(&dart_entry);
-  __ Bind(&dart_entry);
-  // Adjust saved PC for any intrinsic code that could have been generated
-  // before a frame is created.
-  if (offset != 0) {
-    __ addl(Address(ESP, 0), Immediate(-offset));
-  }
-  if (frame_size != 0) {
-    __ subl(ESP, Immediate(frame_size));
-  }
-}
-
-
-void AssemblerMacros::EnterStubFrame(Assembler* assembler) {
-  __ EnterFrame(0);
-  __ pushl(Immediate(0));  // Push 0 in the saved PC area for stub frames.
-}
-
-#undef __
-
-}  // namespace dart
-
-#endif  // defined TARGET_ARCH_IA32
diff --git a/runtime/vm/assembler_macros_ia32.h b/runtime/vm/assembler_macros_ia32.h
deleted file mode 100644
index 4d185f9..0000000
--- a/runtime/vm/assembler_macros_ia32.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// 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.
-// The class 'AssemblerMacros' contains assembler instruction groups that
-// are used in Dart.
-
-#ifndef VM_ASSEMBLER_MACROS_IA32_H_
-#define VM_ASSEMBLER_MACROS_IA32_H_
-
-#ifndef VM_ASSEMBLER_MACROS_H_
-#error Do not include assembler_macros_ia32.h directly; use assembler_macros.h.
-#endif
-
-#include "vm/allocation.h"
-#include "vm/constants_ia32.h"
-
-namespace dart {
-
-// Forward declarations.
-class Assembler;
-class Class;
-class Label;
-
-class AssemblerMacros : public AllStatic {
- public:
-  // Inlined allocation of an instance of class 'cls', code has no runtime
-  // calls. Jump to 'failure' if the instance cannot be allocated here.
-  // Allocated instance is returned in 'instance_reg'.
-  // Only the tags field of the object is initialized.
-  static void TryAllocate(Assembler* assembler,
-                          const Class& cls,
-                          Label* failure,
-                          bool near_jump,
-                          Register instance_reg);
-
-  // Set up a dart frame on entry with a frame pointer and PC information to
-  // enable easy access to the RawInstruction object of code corresponding
-  // to this frame.
-  // The dart frame layout is as follows:
-  //   ....
-  //   ret PC
-  //   saved EBP     <=== EBP
-  //   pc (used to derive the RawInstruction Object of the dart code)
-  //   locals space  <=== ESP
-  //   .....
-  // This code sets this up with the sequence:
-  //   pushl ebp
-  //   movl ebp, esp
-  //   call L
-  //   L: <code to adjust saved pc if there is any intrinsification code>
-  //   .....
-  static void EnterDartFrame(Assembler* assembler, intptr_t frame_size);
-
-  // Set up a stub frame so that the stack traversal code can easily identify
-  // a stub frame.
-  // The stub frame layout is as follows:
-  //   ....
-  //   ret PC
-  //   saved EBP
-  //   0 (used to indicate frame is a stub frame)
-  //   .....
-  // This code sets this up with the sequence:
-  //   pushl ebp
-  //   movl ebp, esp
-  //   pushl immediate(0)
-  //   .....
-  static void EnterStubFrame(Assembler* assembler);
-
-  // Instruction pattern from entrypoint is used in dart frame prologs
-  // to set up the frame and save a PC which can be used to figure out the
-  // RawInstruction object corresponding to the code running in the frame.
-  // entrypoint:
-  //   pushl ebp          (size is 1 byte)
-  //   movl ebp, esp      (size is 2 bytes)
-  //   call L             (size is 5 bytes)
-  //   L:
-  static const intptr_t kOffsetOfSavedPCfromEntrypoint = 8;
-};
-
-}  // namespace dart.
-
-#endif  // VM_ASSEMBLER_MACROS_IA32_H_
diff --git a/runtime/vm/assembler_macros_mips.cc b/runtime/vm/assembler_macros_mips.cc
deleted file mode 100644
index 3910345..0000000
--- a/runtime/vm/assembler_macros_mips.cc
+++ /dev/null
@@ -1,34 +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.
-
-#include "vm/globals.h"
-#if defined(TARGET_ARCH_MIPS)
-
-#include "vm/assembler_macros.h"
-
-namespace dart {
-
-void AssemblerMacros::TryAllocate(Assembler* assembler,
-                                  const Class& cls,
-                                  Label* failure,
-                                  bool near_jump,
-                                  Register instance_reg) {
-  UNIMPLEMENTED();
-}
-
-
-void AssemblerMacros::EnterDartFrame(Assembler* assembler,
-                                     intptr_t frame_size) {
-  UNIMPLEMENTED();
-}
-
-
-void AssemblerMacros::EnterStubFrame(Assembler* assembler) {
-  UNIMPLEMENTED();
-}
-
-}  // namespace dart
-
-#endif  // defined TARGET_ARCH_MIPS
-
diff --git a/runtime/vm/assembler_macros_mips.h b/runtime/vm/assembler_macros_mips.h
deleted file mode 100644
index cf4ff44..0000000
--- a/runtime/vm/assembler_macros_mips.h
+++ /dev/null
@@ -1,54 +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.
-// The class 'AssemblerMacros' contains assembler instruction groups that
-// are used in Dart.
-
-#ifndef VM_ASSEMBLER_MACROS_MIPS_H_
-#define VM_ASSEMBLER_MACROS_MIPS_H_
-
-#ifndef VM_ASSEMBLER_MACROS_H_
-#error Do not include assembler_macros_mips.h directly; use assembler_macros.h.
-#endif
-
-#include "vm/allocation.h"
-#include "vm/constants_mips.h"
-
-namespace dart {
-
-// Forward declarations.
-class Assembler;
-class Class;
-class Label;
-
-class AssemblerMacros : public AllStatic {
- public:
-  // Inlined allocation of an instance of class 'cls', code has no runtime
-  // calls. Jump to 'failure' if the instance cannot be allocated here.
-  // Allocated instance is returned in 'instance_reg'.
-  // Only the tags field of the object is initialized.
-  static void TryAllocate(Assembler* assembler,
-                          const Class& cls,
-                          Label* failure,
-                          bool near_jump,
-                          Register instance_reg);
-
-  // Set up a dart frame on entry with a frame pointer and PC information to
-  // enable easy access to the RawInstruction object of code corresponding
-  // to this frame.
-  static void EnterDartFrame(Assembler* assembler, intptr_t frame_size);
-
-  // Set up a stub frame so that the stack traversal code can easily identify
-  // a stub frame.
-  static void EnterStubFrame(Assembler* assembler);
-
-  // Instruction pattern from entrypoint is used in dart frame prologs
-  // to set up the frame and save a PC which can be used to figure out the
-  // RawInstruction object corresponding to the code running in the frame.
-  static const intptr_t kOffsetOfSavedPCfromEntrypoint = -1;  // UNIMPLEMENTED.
-};
-
-}  // namespace dart.
-
-#endif  // VM_ASSEMBLER_MACROS_MIPS_H_
-
diff --git a/runtime/vm/assembler_macros_x64.cc b/runtime/vm/assembler_macros_x64.cc
deleted file mode 100644
index 0731cb5..0000000
--- a/runtime/vm/assembler_macros_x64.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-// 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.
-
-#include "vm/globals.h"
-#if defined(TARGET_ARCH_X64)
-
-#include "vm/assembler_macros.h"
-
-#include "vm/assembler.h"
-
-namespace dart {
-
-DECLARE_FLAG(bool, inline_alloc);
-
-#define __ assembler->
-
-// Static.
-void AssemblerMacros::TryAllocate(Assembler* assembler,
-                                  const Class& cls,
-                                  Label* failure,
-                                  bool near_jump,
-                                  Register instance_reg) {
-  ASSERT(failure != NULL);
-  if (FLAG_inline_alloc) {
-    Heap* heap = Isolate::Current()->heap();
-    const intptr_t instance_size = cls.instance_size();
-    __ movq(TMP, Immediate(heap->TopAddress()));
-    __ movq(instance_reg, Address(TMP, 0));
-    __ addq(instance_reg, Immediate(instance_size));
-    // instance_reg: potential next object start.
-    __ movq(TMP, Immediate(heap->EndAddress()));
-    __ cmpq(instance_reg, Address(TMP, 0));
-    __ j(ABOVE_EQUAL, failure, near_jump);
-    // Successfully allocated the object, now update top to point to
-    // next object start and store the class in the class field of object.
-    __ movq(TMP, Immediate(heap->TopAddress()));
-    __ movq(Address(TMP, 0), instance_reg);
-    ASSERT(instance_size >= kHeapObjectTag);
-    __ subq(instance_reg, Immediate(instance_size - kHeapObjectTag));
-    uword tags = 0;
-    tags = RawObject::SizeTag::update(instance_size, tags);
-    ASSERT(cls.id() != kIllegalCid);
-    tags = RawObject::ClassIdTag::update(cls.id(), tags);
-    __ movq(FieldAddress(instance_reg, Object::tags_offset()), Immediate(tags));
-  } else {
-    __ jmp(failure);
-  }
-}
-
-
-void AssemblerMacros::EnterDartFrame(Assembler* assembler,
-                                     intptr_t frame_size) {
-  const intptr_t offset = assembler->CodeSize();
-  __ EnterFrame(0);
-  Label dart_entry;
-  __ call(&dart_entry);
-  __ Bind(&dart_entry);
-  // Adjust saved PC for any intrinsic code that could have been generated
-  // before a frame is created.
-  if (offset != 0) {
-    __ addq(Address(RSP, 0), Immediate(-offset));
-  }
-  if (frame_size != 0) {
-    __ subq(RSP, Immediate(frame_size));
-  }
-}
-
-
-void AssemblerMacros::EnterStubFrame(Assembler* assembler) {
-  __ EnterFrame(0);
-  __ pushq(Immediate(0));  // Push 0 in the saved PC area for stub frames.
-}
-
-#undef __
-
-}  // namespace dart
-
-#endif  // defined TARGET_ARCH_X64
diff --git a/runtime/vm/assembler_macros_x64.h b/runtime/vm/assembler_macros_x64.h
deleted file mode 100644
index a6912cf..0000000
--- a/runtime/vm/assembler_macros_x64.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// 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.
-// The class 'AssemblerMacros' contains assembler instruction groups that
-// are used in Dart.
-
-#ifndef VM_ASSEMBLER_MACROS_X64_H_
-#define VM_ASSEMBLER_MACROS_X64_H_
-
-#ifndef VM_ASSEMBLER_MACROS_H_
-#error Do not include assembler_macros_x64.h directly; use assembler_macros.h.
-#endif
-
-#include "vm/allocation.h"
-#include "vm/constants_x64.h"
-
-namespace dart {
-
-// Forward declarations.
-class Assembler;
-class Class;
-class Label;
-
-class AssemblerMacros : public AllStatic {
- public:
-  // Inlined allocation of an instance of class 'cls', code has no runtime
-  // calls. Jump to 'failure' if the instance cannot be allocated here.
-  // Allocated instance is returned in 'instance_reg'.
-  // Only the tags field of the object is initialized.
-  static void TryAllocate(Assembler* assembler,
-                          const Class& cls,
-                          Label* failure,
-                          bool near_jump,
-                          Register instance_reg);
-
-  // Set up a dart frame on entry with a frame pointer and PC information to
-  // enable easy access to the RawInstruction object of code corresponding
-  // to this frame.
-  // The dart frame layout is as follows:
-  //   ....
-  //   ret PC
-  //   saved RBP     <=== RBP
-  //   pc (used to derive the RawInstruction Object of the dart code)
-  //   locals space  <=== RSP
-  //   .....
-  // This code sets this up with the sequence:
-  //   pushq rbp
-  //   movq rbp, rsp
-  //   call L
-  //   L: <code to adjust saved pc if there is any intrinsification code>
-  //   .....
-  static void EnterDartFrame(Assembler* assembler, intptr_t frame_size);
-
-  // Set up a stub frame so that the stack traversal code can easily identify
-  // a stub frame.
-  // The stub frame layout is as follows:
-  //   ....
-  //   ret PC
-  //   saved RBP
-  //   pc (used to derive the RawInstruction Object of the stub)
-  //   .....
-  // This code sets this up with the sequence:
-  //   pushq rbp
-  //   movq rbp, rsp
-  //   pushq immediate(0)
-  //   .....
-  static void EnterStubFrame(Assembler* assembler);
-
-  // Instruction pattern from entrypoint is used in dart frame prologs
-  // to set up the frame and save a PC which can be used to figure out the
-  // RawInstruction object corresponding to the code running in the frame.
-  // entrypoint:
-  //   pushq rbp          (size is 1 byte)
-  //   movq rbp, rsp      (size is 3 bytes)
-  //   call L             (size is 5 bytes)
-  //   L:
-  static const intptr_t kOffsetOfSavedPCfromEntrypoint = 9;
-};
-
-}  // namespace dart.
-
-#endif  // VM_ASSEMBLER_MACROS_X64_H_
diff --git a/runtime/vm/assembler_mips.cc b/runtime/vm/assembler_mips.cc
index d6db404..f74e06e 100644
--- a/runtime/vm/assembler_mips.cc
+++ b/runtime/vm/assembler_mips.cc
@@ -11,6 +11,17 @@
 
 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
 
+
+void Assembler::InitializeMemoryWithBreakpoints(uword data, int length) {
+  ASSERT(Utils::IsAligned(data, 4));
+  ASSERT(Utils::IsAligned(length, 4));
+  const uword end = data + length;
+  while (data < end) {
+    *reinterpret_cast<int32_t*>(data) = Instr::kBreakPointInstruction;
+    data += 4;
+  }
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_MIPS
diff --git a/runtime/vm/assembler_mips.h b/runtime/vm/assembler_mips.h
index 1c72fd8..67ad01f 100644
--- a/runtime/vm/assembler_mips.h
+++ b/runtime/vm/assembler_mips.h
@@ -12,36 +12,55 @@
 #include "platform/assert.h"
 #include "vm/constants_mips.h"
 
+// References to documentation in this file refer to:
+// "MIPS® Architecture For Programmers Volume I-A:
+//   Introduction to the MIPS32® Architecture" in short "VolI-A"
+// and
+// "MIPS® Architecture For Programmers Volume II-A:
+//   The MIPS32® Instruction Set" in short "VolII-A"
 namespace dart {
 
-class Operand : public ValueObject {
+class Immediate : public ValueObject {
  public:
-  Operand(const Operand& other) : ValueObject() {
-    UNIMPLEMENTED();
-  }
+  explicit Immediate(int32_t value) : value_(value) { }
 
-  Operand& operator=(const Operand& other) {
-    UNIMPLEMENTED();
+  Immediate(const Immediate& other) : ValueObject(), value_(other.value_) { }
+  Immediate& operator=(const Immediate& other) {
+    value_ = other.value_;
     return *this;
   }
 
- protected:
-  Operand() { }  // Needed by subclass Address.
+ private:
+  int32_t value_;
+
+  int32_t value() const { return value_; }
+
+  friend class Assembler;
 };
 
 
-class Address : public Operand {
+class Address : public ValueObject {
  public:
-  Address(Register base, int32_t disp) {
-    UNIMPLEMENTED();
-  }
+  Address(Register base, int32_t offset = 0)
+      : ValueObject(), base_(base), offset_(offset) { }
 
-  Address(const Address& other) : Operand(other) { }
-
+  Address(const Address& other)
+      : ValueObject(), base_(other.base_), offset_(other.offset_) { }
   Address& operator=(const Address& other) {
-    Operand::operator=(other);
+    base_ = other.base_;
+    offset_ = other.offset_;
     return *this;
   }
+
+  uint32_t encoding() const {
+    ASSERT(Utils::IsInt(16, offset_));
+    uint16_t imm_value = static_cast<uint16_t>(offset_);
+    return (base_ << kRsShift) | imm_value;
+  }
+
+ private:
+  Register base_;
+  int32_t offset_;
 };
 
 
@@ -119,6 +138,8 @@
       : buffer_(),
         object_pool_(GrowableObjectArray::Handle()),
         prologue_offset_(-1),
+        delay_slot_available_(false),
+        in_delay_slot_(false),
         comments_() { }
   ~Assembler() { }
 
@@ -131,23 +152,42 @@
   }
 
   // Misc. functionality
-  int CodeSize() const {
-    UNIMPLEMENTED();
-    return 0;
-  }
-  int prologue_offset() const {
-    UNIMPLEMENTED();
-    return 0;
-  }
+  int CodeSize() const { return buffer_.Size(); }
+  int prologue_offset() const { return -1; }
   const ZoneGrowableArray<int>& GetPointerOffsets() const {
-    UNIMPLEMENTED();
-    return *pointer_offsets_;
+    return buffer_.pointer_offsets();
   }
-  const GrowableObjectArray& object_pool() const {
-    UNIMPLEMENTED();
-    return object_pool_;
-  }
+  const GrowableObjectArray& object_pool() const { return object_pool_; }
   void FinalizeInstructions(const MemoryRegion& region) {
+    buffer_.FinalizeInstructions(region);
+  }
+
+  // Set up a Dart frame on entry with a frame pointer and PC information to
+  // enable easy access to the RawInstruction object of code corresponding
+  // to this frame.
+  void EnterDartFrame(intptr_t frame_size) {
+    UNIMPLEMENTED();
+  }
+
+  // Set up a stub frame so that the stack traversal code can easily identify
+  // a stub frame.
+  void EnterStubFrame() {
+    UNIMPLEMENTED();
+  }
+
+  // Instruction pattern from entrypoint is used in dart frame prologs
+  // to set up the frame and save a PC which can be used to figure out the
+  // RawInstruction object corresponding to the code running in the frame.
+  static const intptr_t kOffsetOfSavedPCfromEntrypoint = -1;  // UNIMPLEMENTED.
+
+  // Inlined allocation of an instance of class 'cls', code has no runtime
+  // calls. Jump to 'failure' if the instance cannot be allocated here.
+  // Allocated instance is returned in 'instance_reg'.
+  // Only the tags field of the object is initialized.
+  void TryAllocate(const Class& cls,
+                   Label* failure,
+                   bool near_jump,
+                   Register instance_reg) {
     UNIMPLEMENTED();
   }
 
@@ -157,9 +197,7 @@
   void Untested(const char* message);
   void Unreachable(const char* message);
 
-  static void InitializeMemoryWithBreakpoints(uword data, int length) {
-    UNIMPLEMENTED();
-  }
+  static void InitializeMemoryWithBreakpoints(uword data, int length);
 
   void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
 
@@ -175,12 +213,139 @@
     return NULL;
   }
 
+  // A utility to be able to assemble an instruction into the delay slot.
+  Assembler* delay_slot() {
+    ASSERT(delay_slot_available_);
+    ASSERT(buffer_.Load<int32_t>(buffer_.GetPosition() - sizeof(int32_t)) ==
+        Instr::kNopInstruction);
+    buffer_.Remit<int32_t>();
+    delay_slot_available_ = false;
+    in_delay_slot_ = true;
+    return this;
+  }
+
+  // CPU instructions.
+  void addiu(Register rt, Register rs, const Immediate& imm) {
+    ASSERT(Utils::IsInt(16, imm.value()));
+    uint16_t imm_value = static_cast<uint16_t>(imm.value());
+    EmitIType(ADDIU, rs, rt, imm_value);
+  }
+
+  void addu(Register rd, Register rs, Register rt) {
+    EmitRType(SPECIAL, rs, rt, rd, 0, ADDU);
+  }
+
+  void and_(Register rd, Register rs, Register rt) {
+    EmitRType(SPECIAL, rs, rt, rd, 0, AND);
+  }
+
+  void andi(Register rt, Register rs, const Immediate& imm) {
+    ASSERT(Utils::IsUint(16, imm.value()));
+    uint16_t imm_value = static_cast<uint16_t>(imm.value());
+    EmitIType(ANDI, rs, rt, imm_value);
+  }
+
+  void break_(int32_t code) {
+    ASSERT(Utils::IsUint(20, code));
+    Emit(SPECIAL << kOpcodeShift |
+         code << kBreakCodeShift |
+         BREAK << kFunctionShift);
+  }
+
+  void clo(Register rd, Register rs) {
+    EmitRType(SPECIAL2, rs, rd, rd, 0, CLO);
+  }
+
+  void clz(Register rd, Register rs) {
+    EmitRType(SPECIAL2, rs, rd, rd, 0, CLZ);
+  }
+
+  void div(Register rs, Register rt) {
+    EmitRType(SPECIAL, rs, rt, R0, 0, DIV);
+  }
+
+  void divu(Register rs, Register rt) {
+    EmitRType(SPECIAL, rs, rt, R0, 0, DIVU);
+  }
+
+
+  void lb(Register rt, const Address& addr) {
+    EmitLoadStore(LB, rt, addr);
+  }
+
+  void lbu(Register rt, const Address& addr) {
+    EmitLoadStore(LBU, rt, addr);
+  }
+
+  void lh(Register rt, const Address& addr) {
+    EmitLoadStore(LH, rt, addr);
+  }
+
+  void lhu(Register rt, const Address& addr) {
+    EmitLoadStore(LHU, rt, addr);
+  }
+
+  void lui(Register rt, const Immediate& imm) {
+    ASSERT(Utils::IsUint(16, imm.value()));
+    uint16_t imm_value = static_cast<uint16_t>(imm.value());
+    EmitIType(LUI, R0, rt, imm_value);
+  }
+
+  void lw(Register rt, const Address& addr) {
+    EmitLoadStore(LW, rt, addr);
+  }
+
+  void mfhi(Register rd) {
+    EmitRType(SPECIAL, R0, R0, rd, 0, MFHI);
+  }
+
+  void mflo(Register rd) {
+    EmitRType(SPECIAL, R0, R0, rd, 0, MFLO);
+  }
+
+  void ori(Register rt, Register rs, const Immediate& imm) {
+    ASSERT(Utils::IsUint(16, imm.value()));
+    uint16_t imm_value = static_cast<uint16_t>(imm.value());
+    EmitIType(ORI, rs, rt, imm_value);
+  }
+
+  void jr(Register rs) {
+    ASSERT(!in_delay_slot_);  // Jump within a delay slot is not supported.
+    EmitRType(SPECIAL, rs, R0, R0, 0, JR);
+    Emit(Instr::kNopInstruction);  // Branch delay NOP.
+    delay_slot_available_ = true;
+  }
+
+  void sb(Register rt, const Address& addr) {
+    EmitLoadStore(SB, rt, addr);
+  }
+
+  void sh(Register rt, const Address& addr) {
+    EmitLoadStore(SH, rt, addr);
+  }
+
+  void sw(Register rt, const Address& addr) {
+    EmitLoadStore(SW, rt, addr);
+  }
+
+  void sll(Register rd, Register rt, int sa) {
+    EmitRType(SPECIAL, R0, rt, rd, sa, SLL);
+  }
+
+  // Macros.
+  void LoadImmediate(Register rd, int32_t value) {
+    lui(rd, Immediate((value >> 16) & 0xffff));
+    ori(rd, rd, Immediate(value & 0xffff));
+  }
+
  private:
   AssemblerBuffer buffer_;
   GrowableObjectArray& object_pool_;  // Objects and patchable jump targets.
-  ZoneGrowableArray<int>* pointer_offsets_;
   int prologue_offset_;
 
+  bool delay_slot_available_;
+  bool in_delay_slot_;
+
   class CodeComment : public ZoneAllocated {
    public:
     CodeComment(intptr_t pc_offset, const String& comment)
@@ -198,6 +363,62 @@
 
   GrowableArray<CodeComment*> comments_;
 
+  void Emit(int32_t value) {
+    // Emitting an instruction clears the delay slot state.
+    in_delay_slot_ = false;
+    delay_slot_available_ = false;
+    AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+    buffer_.Emit<int32_t>(value);
+  }
+
+  // Encode CPU instructions according to the types specified in
+  // Figures 4-1, 4-2 and 4-3 in VolI-A.
+  void EmitIType(Opcode opcode,
+                 Register rs,
+                 Register rt,
+                 uint16_t imm) {
+    Emit(opcode << kOpcodeShift |
+         rs << kRsShift |
+         rt << kRtShift |
+         imm);
+  }
+
+  void EmitLoadStore(Opcode opcode, Register rt,
+                     const Address &addr) {
+    Emit(opcode << kOpcodeShift |
+         rt << kRtShift |
+         addr.encoding());
+  }
+
+  void EmitRegImmType(Opcode opcode,
+                      Register rs,
+                      RtRegImm code,
+                      uint16_t imm) {
+    Emit(opcode << kOpcodeShift |
+         rs << kRsShift |
+         code << kRtShift |
+         imm);
+  }
+
+  void EmitJType(Opcode opcode, Label* label) {
+    UNIMPLEMENTED();
+  }
+
+  void EmitRType(Opcode opcode,
+                 Register rs,
+                 Register rt,
+                 Register rd,
+                 int sa,
+                 SpecialFunction func) {
+    ASSERT(Utils::IsUint(5, sa));
+    Emit(opcode << kOpcodeShift |
+         rs << kRsShift |
+         rt << kRtShift |
+         rd << kRdShift |
+         sa << kSaShift |
+         func << kFunctionShift);
+  }
+
   DISALLOW_ALLOCATION();
   DISALLOW_COPY_AND_ASSIGN(Assembler);
 };
diff --git a/runtime/vm/assembler_mips_test.cc b/runtime/vm/assembler_mips_test.cc
index dddd1f4..82287ff 100644
--- a/runtime/vm/assembler_mips_test.cc
+++ b/runtime/vm/assembler_mips_test.cc
@@ -15,8 +15,316 @@
 #define __ assembler->
 
 
+ASSEMBLER_TEST_GENERATE(Addiu, assembler) {
+  __ addiu(V0, ZR, Immediate(42));
+  __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(Addiu, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Addiu_overflow, assembler) {
+  __ LoadImmediate(V0, 0x7fffffff);
+  __ addiu(V0, V0, Immediate(1));  // V0 is modified on overflow.
+  __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(Addiu_overflow, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(static_cast<int32_t>(0x80000000),
+            EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Addu, assembler) {
+  __ addiu(R2, ZR, Immediate(21));
+  __ addiu(R3, ZR, Immediate(21));
+  __ addu(V0, R2, R3);
+  __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(Addu, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Addu_overflow, assembler) {
+  __ LoadImmediate(R2, 0x7fffffff);
+  __ addiu(R3, R0, Immediate(1));
+  __ addu(V0, R2, R3);
+  __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(Addu_overflow, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(static_cast<int32_t>(0x80000000),
+            EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(And, assembler) {
+  __ addiu(R2, ZR, Immediate(42));
+  __ addiu(R3, ZR, Immediate(2));
+  __ and_(V0, R2, R3);
+  __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(And, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(2, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Andi, assembler) {
+  __ addiu(R1, ZR, Immediate(42));
+  __ andi(V0, R1, Immediate(2));
+  __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(Andi, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(2, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Clo, assembler) {
+  __ addiu(R1, ZR, Immediate(-1));
+  __ clo(V0, R1);
+  __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(Clo, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(32, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Clz, assembler) {
+  __ addiu(R1, ZR, Immediate(0x7fff));
+  __ clz(V0, R1);
+  __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(Clz, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(17, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Divu, assembler) {
+  __ addiu(R1, ZR, Immediate(27));
+  __ addiu(R2, ZR, Immediate(9));
+  __ divu(R1, R2);
+  __ mflo(V0);
+  __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(Divu, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Div, assembler) {
+  __ addiu(R1, ZR, Immediate(27));
+  __ addiu(R2, ZR, Immediate(9));
+  __ div(R1, R2);
+  __ mflo(V0);
+  __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(Div, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Divu_zero, assembler) {
+  __ addiu(R1, ZR, Immediate(27));
+  __ addiu(R2, ZR, Immediate(0));
+  __ divu(R1, R2);
+  __ mflo(V0);
+  __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(Divu_zero, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Div_zero, assembler) {
+  __ addiu(R1, ZR, Immediate(27));
+  __ addiu(R2, ZR, Immediate(0));
+  __ div(R1, R2);
+  __ mflo(V0);
+  __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(Div_zero, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Divu_corner, assembler) {
+  __ LoadImmediate(R1, 0x80000000);
+  __ LoadImmediate(R2, 0xffffffff);
+  __ divu(R1, R2);
+  __ mflo(V0);
+  __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(Divu_corner, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Div_corner, assembler) {
+  __ LoadImmediate(R1, 0x80000000);
+  __ LoadImmediate(R2, 0xffffffff);
+  __ div(R1, R2);
+  __ mflo(V0);
+  __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(Div_corner, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(static_cast<int32_t>(0x80000000),
+            EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Lb, assembler) {
+  __ addiu(SP, SP, Immediate(-kWordSize * 30));
+  __ LoadImmediate(R1, 0xff);
+  __ sb(R1, Address(SP));
+  __ lb(V0, Address(SP));
+  __ addiu(SP, SP, Immediate(kWordSize * 30));
+  __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(Lb, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(-1, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Lb_offset, assembler) {
+  __ addiu(SP, SP, Immediate(-kWordSize * 30));
+  __ LoadImmediate(R1, 0xff);
+  __ sb(R1, Address(SP, 1));
+  __ lb(V0, Address(SP, 1));
+  __ addiu(SP, SP, Immediate(kWordSize * 30));
+  __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(Lb_offset, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(-1, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Lbu, assembler) {
+  __ addiu(SP, SP, Immediate(-kWordSize * 30));
+  __ LoadImmediate(R1, 0xff);
+  __ sb(R1, Address(SP));
+  __ lbu(V0, Address(SP));
+  __ addiu(SP, SP, Immediate(kWordSize * 30));
+  __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(Lbu, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(255, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Lh, assembler) {
+  __ addiu(SP, SP, Immediate(-kWordSize * 30));
+  __ LoadImmediate(R1, 0xffff);
+  __ sh(R1, Address(SP));
+  __ lh(V0, Address(SP));
+  __ addiu(SP, SP, Immediate(kWordSize * 30));
+  __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(Lh, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(-1, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Lhu, assembler) {
+  __ addiu(SP, SP, Immediate(-kWordSize * 30));
+  __ LoadImmediate(R1, 0xffff);
+  __ sh(R1, Address(SP));
+  __ lhu(V0, Address(SP));
+  __ addiu(SP, SP, Immediate(kWordSize * 30));
+  __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(Lhu, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(65535, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Lw, assembler) {
+  __ addiu(SP, SP, Immediate(-kWordSize * 30));
+  __ LoadImmediate(R1, -1);
+  __ sw(R1, Address(SP));
+  __ lw(V0, Address(SP));
+  __ addiu(SP, SP, Immediate(kWordSize * 30));
+  __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(Lw, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(-1, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Lui, assembler) {
+  __ lui(V0, Immediate(42));
+  __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(Lui, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(42 << 16, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
 ASSEMBLER_TEST_GENERATE(Simple, assembler) {
-  UNIMPLEMENTED();
+  __ jr(RA);
+  __ delay_slot()->ori(V0, ZR, Immediate(42));
 }
 
 
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc
index 2db5f67..0d621b1 100644
--- a/runtime/vm/assembler_x64.cc
+++ b/runtime/vm/assembler_x64.cc
@@ -15,6 +15,7 @@
 
 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
 DEFINE_FLAG(bool, use_sse41, true, "Use SSE 4.1 if available");
+DECLARE_FLAG(bool, inline_alloc);
 
 
 bool CPUFeatures::sse4_1_supported_ = false;
@@ -2218,6 +2219,61 @@
 }
 
 
+void Assembler::EnterDartFrame(intptr_t frame_size) {
+  const intptr_t offset = CodeSize();
+  EnterFrame(0);
+  Label dart_entry;
+  call(&dart_entry);
+  Bind(&dart_entry);
+  // Adjust saved PC for any intrinsic code that could have been generated
+  // before a frame is created.
+  if (offset != 0) {
+    addq(Address(RSP, 0), Immediate(-offset));
+  }
+  if (frame_size != 0) {
+    subq(RSP, Immediate(frame_size));
+  }
+}
+
+
+void Assembler::EnterStubFrame() {
+  EnterFrame(0);
+  pushq(Immediate(0));  // Push 0 in the saved PC area for stub frames.
+}
+
+
+void Assembler::TryAllocate(const Class& cls,
+                            Label* failure,
+                            bool near_jump,
+                            Register instance_reg) {
+  ASSERT(failure != NULL);
+  if (FLAG_inline_alloc) {
+    Heap* heap = Isolate::Current()->heap();
+    const intptr_t instance_size = cls.instance_size();
+    movq(TMP, Immediate(heap->TopAddress()));
+    movq(instance_reg, Address(TMP, 0));
+    addq(instance_reg, Immediate(instance_size));
+    // instance_reg: potential next object start.
+    movq(TMP, Immediate(heap->EndAddress()));
+    cmpq(instance_reg, Address(TMP, 0));
+    j(ABOVE_EQUAL, failure, near_jump);
+    // Successfully allocated the object, now update top to point to
+    // next object start and store the class in the class field of object.
+    movq(TMP, Immediate(heap->TopAddress()));
+    movq(Address(TMP, 0), instance_reg);
+    ASSERT(instance_size >= kHeapObjectTag);
+    subq(instance_reg, Immediate(instance_size - kHeapObjectTag));
+    uword tags = 0;
+    tags = RawObject::SizeTag::update(instance_size, tags);
+    ASSERT(cls.id() != kIllegalCid);
+    tags = RawObject::ClassIdTag::update(cls.id(), tags);
+    movq(FieldAddress(instance_reg, Object::tags_offset()), Immediate(tags));
+  } else {
+    jmp(failure);
+  }
+}
+
+
 void Assembler::Align(int alignment, int offset) {
   ASSERT(Utils::IsPowerOfTwo(alignment));
   int pos = offset + buffer_.GetPosition();
diff --git a/runtime/vm/assembler_x64.h b/runtime/vm/assembler_x64.h
index 61894c0..aa6c21b 100644
--- a/runtime/vm/assembler_x64.h
+++ b/runtime/vm/assembler_x64.h
@@ -701,6 +701,58 @@
     buffer_.FinalizeInstructions(region);
   }
 
+  // Set up a Dart frame on entry with a frame pointer and PC information to
+  // enable easy access to the RawInstruction object of code corresponding
+  // to this frame.
+  // The dart frame layout is as follows:
+  //   ....
+  //   ret PC
+  //   saved RBP     <=== RBP
+  //   pc (used to derive the RawInstruction Object of the dart code)
+  //   locals space  <=== RSP
+  //   .....
+  // This code sets this up with the sequence:
+  //   pushq rbp
+  //   movq rbp, rsp
+  //   call L
+  //   L: <code to adjust saved pc if there is any intrinsification code>
+  //   .....
+  void EnterDartFrame(intptr_t frame_size);
+
+  // Set up a stub frame so that the stack traversal code can easily identify
+  // a stub frame.
+  // The stub frame layout is as follows:
+  //   ....
+  //   ret PC
+  //   saved RBP
+  //   pc (used to derive the RawInstruction Object of the stub)
+  //   .....
+  // This code sets this up with the sequence:
+  //   pushq rbp
+  //   movq rbp, rsp
+  //   pushq immediate(0)
+  //   .....
+  void EnterStubFrame();
+
+  // Instruction pattern from entrypoint is used in dart frame prologs
+  // to set up the frame and save a PC which can be used to figure out the
+  // RawInstruction object corresponding to the code running in the frame.
+  // entrypoint:
+  //   pushq rbp          (size is 1 byte)
+  //   movq rbp, rsp      (size is 3 bytes)
+  //   call L             (size is 5 bytes)
+  //   L:
+  static const intptr_t kOffsetOfSavedPCfromEntrypoint = 9;
+
+  // Inlined allocation of an instance of class 'cls', code has no runtime
+  // calls. Jump to 'failure' if the instance cannot be allocated here.
+  // Allocated instance is returned in 'instance_reg'.
+  // Only the tags field of the object is initialized.
+  void TryAllocate(const Class& cls,
+                   Label* failure,
+                   bool near_jump,
+                   Register instance_reg);
+
   // Debugging and bringup support.
   void Stop(const char* message);
   void Unimplemented(const char* message);
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index 4ff0081..f0cd598 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -98,6 +98,13 @@
 }
 
 
+RawScript* Bootstrap::LoadTypedDataScript(bool patch) {
+  const char* url = patch ? "dart:typeddata_patch" : "dart:typeddata";
+  const char* source = patch ? typeddata_patch_ : typeddata_source_;
+  return LoadScript(url, source, patch);
+}
+
+
 RawScript* Bootstrap::LoadUriScript(bool patch) {
   const char* url = patch ? "dart:uri-patch" : "dart:uri";
   const char* source = patch ? uri_source_ : uri_source_;
diff --git a/runtime/vm/bootstrap.h b/runtime/vm/bootstrap.h
index 56fdc8c..d0e7e63 100644
--- a/runtime/vm/bootstrap.h
+++ b/runtime/vm/bootstrap.h
@@ -27,6 +27,7 @@
   static RawScript* LoadMathScript(bool patch);
   static RawScript* LoadMirrorsScript(bool patch);
   static RawScript* LoadScalarlistScript(bool patch);
+  static RawScript* LoadTypedDataScript(bool patch);
   static RawScript* LoadUriScript(bool patch);
   static RawScript* LoadUtfScript(bool patch);
   static RawError* Compile(const Library& library, const Script& script);
@@ -52,6 +53,8 @@
   static const char mirrors_patch_[];
   static const char scalarlist_source_[];
   static const char scalarlist_patch_[];
+  static const char typeddata_source_[];
+  static const char typeddata_patch_[];
   static const char uri_source_[];
   static const char utf_source_[];
 };
diff --git a/runtime/vm/bootstrap_natives.cc b/runtime/vm/bootstrap_natives.cc
index 2f9ade3..03ae7c7 100644
--- a/runtime/vm/bootstrap_natives.cc
+++ b/runtime/vm/bootstrap_natives.cc
@@ -79,6 +79,10 @@
   library = Library::ScalarlistLibrary();
   ASSERT(!library.IsNull());
   library.set_native_entry_resolver(resolver);
+
+  library = Library::TypedDataLibrary();
+  ASSERT(!library.IsNull());
+  library.set_native_entry_resolver(resolver);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 9f0db00..4c4ef11 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -78,6 +78,7 @@
   V(ObjectArray_copyFromObjectArray, 5)                                        \
   V(StringBase_createFromCodePoints, 1)                                        \
   V(StringBase_substringUnchecked, 3)                                          \
+  V(StringBuffer_createStringFromUint16Array, 3)                               \
   V(OneByteString_substringUnchecked, 3)                                       \
   V(OneByteString_splitWithCharCode, 2)                                        \
   V(String_getHashCode, 1)                                                     \
@@ -264,6 +265,50 @@
   V(ExternalFloat32Array_setIndexed, 3)                                        \
   V(ExternalFloat64Array_getIndexed, 2)                                        \
   V(ExternalFloat64Array_setIndexed, 3)                                        \
+  V(TypedData_Int8Array_new, 1)                                                \
+  V(TypedData_Uint8Array_new, 1)                                               \
+  V(TypedData_Uint8ClampedArray_new, 1)                                        \
+  V(TypedData_Int16Array_new, 1)                                               \
+  V(TypedData_Uint16Array_new, 1)                                              \
+  V(TypedData_Int32Array_new, 1)                                               \
+  V(TypedData_Uint32Array_new, 1)                                              \
+  V(TypedData_Int64Array_new, 1)                                               \
+  V(TypedData_Uint64Array_new, 1)                                              \
+  V(TypedData_Float32Array_new, 1)                                             \
+  V(TypedData_Float64Array_new, 1)                                             \
+  V(ExternalTypedData_Int8Array_new, 1)                                        \
+  V(ExternalTypedData_Uint8Array_new, 1)                                       \
+  V(ExternalTypedData_Uint8ClampedArray_new, 1)                                \
+  V(ExternalTypedData_Int16Array_new, 1)                                       \
+  V(ExternalTypedData_Uint16Array_new, 1)                                      \
+  V(ExternalTypedData_Int32Array_new, 1)                                       \
+  V(ExternalTypedData_Uint32Array_new, 1)                                      \
+  V(ExternalTypedData_Int64Array_new, 1)                                       \
+  V(ExternalTypedData_Uint64Array_new, 1)                                      \
+  V(ExternalTypedData_Float32Array_new, 1)                                     \
+  V(ExternalTypedData_Float64Array_new, 1)                                     \
+  V(TypedData_length, 1)                                                       \
+  V(TypedData_setRange, 5)                                                     \
+  V(TypedData_GetInt8, 2)                                                      \
+  V(TypedData_SetInt8, 3)                                                      \
+  V(TypedData_GetUint8, 2)                                                     \
+  V(TypedData_SetUint8, 3)                                                     \
+  V(TypedData_GetInt16, 2)                                                     \
+  V(TypedData_SetInt16, 3)                                                     \
+  V(TypedData_GetUint16, 2)                                                    \
+  V(TypedData_SetUint16, 3)                                                    \
+  V(TypedData_GetInt32, 2)                                                     \
+  V(TypedData_SetInt32, 3)                                                     \
+  V(TypedData_GetUint32, 2)                                                    \
+  V(TypedData_SetUint32, 3)                                                    \
+  V(TypedData_GetInt64, 2)                                                     \
+  V(TypedData_SetInt64, 3)                                                     \
+  V(TypedData_GetUint64, 2)                                                    \
+  V(TypedData_SetUint64, 3)                                                    \
+  V(TypedData_GetFloat32, 2)                                                   \
+  V(TypedData_SetFloat32, 3)                                                   \
+  V(TypedData_GetFloat64, 2)                                                   \
+  V(TypedData_SetFloat64, 3)                                                   \
   V(isolate_getPortInternal, 0)                                                \
   V(isolate_spawnFunction, 2)                                                  \
   V(isolate_spawnUri, 1)                                                       \
diff --git a/runtime/vm/bootstrap_nocorelib.cc b/runtime/vm/bootstrap_nocorelib.cc
index 1e6799a..7deed99 100644
--- a/runtime/vm/bootstrap_nocorelib.cc
+++ b/runtime/vm/bootstrap_nocorelib.cc
@@ -75,6 +75,12 @@
 }
 
 
+RawScript* Bootstrap::LoadTypedDataScript(bool is_patch) {
+  UNREACHABLE();
+  return Script::null();
+}
+
+
 RawScript* Bootstrap::LoadUriScript(bool is_patch) {
   UNREACHABLE();
   return Script::null();
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 81c7c87..48faa6b 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -65,7 +65,7 @@
 }
 
 
-void AddSuperType(const Type& type,
+void AddSuperType(const AbstractType& type,
                   GrowableArray<intptr_t>* finalized_super_classes) {
   ASSERT(type.HasResolvedTypeClass());
   if (type.IsObjectType()) {
@@ -81,7 +81,7 @@
     }
   }
   finalized_super_classes->Add(cid);
-  const Type& super_type = Type::Handle(cls.super_type());
+  const AbstractType& super_type = AbstractType::Handle(cls.super_type());
   AddSuperType(super_type, finalized_super_classes);
 }
 
@@ -92,11 +92,11 @@
     const GrowableObjectArray& pending_classes,
     GrowableArray<intptr_t>* finalized_super_classes) {
   Class& cls = Class::Handle();
-  Type& super_type = Type::Handle();
+  AbstractType& super_type = Type::Handle();
   for (intptr_t i = 0; i < pending_classes.Length(); i++) {
     cls ^= pending_classes.At(i);
     ASSERT(!cls.is_finalized());
-    super_type ^= cls.super_type();
+    super_type = cls.super_type();
     if (!super_type.IsNull()) {
       if (!super_type.IsMalformed() &&
           super_type.HasResolvedTypeClass() &&
@@ -434,10 +434,14 @@
     if (!target_type.IsInstantiated()) {
       const AbstractTypeArguments& type_args = AbstractTypeArguments::Handle(
           type.arguments());
-      target_type ^= target_type.InstantiateFrom(type_args);
-      // TODO(regis): Check bounds in checked mode.
-      target_type ^= FinalizeType(cls, target_type, kCanonicalize);
-      if (target_type.IsMalformed()) {
+      Error& malformed_error = Error::Handle();
+      target_type ^= target_type.InstantiateFrom(type_args, &malformed_error);
+      if (malformed_error.IsNull()) {
+        target_type ^= FinalizeType(cls, target_type, kCanonicalize);
+      } else {
+        FinalizeMalformedType(malformed_error,
+                              cls, target_type, kFinalize,
+                              "cannot resolve redirecting factory");
         target_target = Function::null();
       }
     }
@@ -504,6 +508,7 @@
 
 
 void ClassFinalizer::FinalizeTypeParameters(const Class& cls) {
+  // The type parameter bounds are not finalized here.
   const TypeArguments& type_parameters =
       TypeArguments::Handle(cls.type_parameters());
   if (!type_parameters.IsNull()) {
@@ -537,12 +542,13 @@
 void ClassFinalizer::FinalizeTypeArguments(
     const Class& cls,
     const AbstractTypeArguments& arguments,
-    FinalizationKind finalization) {
+    FinalizationKind finalization,
+    Error* bound_error) {
   ASSERT(arguments.Length() >= cls.NumTypeArguments());
   if (!cls.is_finalized()) {
     FinalizeTypeParameters(cls);
   }
-  Type& super_type = Type::Handle(cls.super_type());
+  AbstractType& super_type = AbstractType::Handle(cls.super_type());
   if (!super_type.IsNull()) {
     const Class& super_class = Class::Handle(super_type.type_class());
     AbstractTypeArguments& super_type_args = AbstractTypeArguments::Handle();
@@ -576,7 +582,16 @@
       if (!super_type_args.IsNull()) {
         super_type_arg = super_type_args.TypeAt(super_offset + i);
         if (!super_type_arg.IsInstantiated()) {
-          super_type_arg = super_type_arg.InstantiateFrom(arguments);
+          Error& malformed_error = Error::Handle();
+          super_type_arg = super_type_arg.InstantiateFrom(arguments,
+                                                          &malformed_error);
+          if (!malformed_error.IsNull()) {
+            if (!super_type_arg.IsInstantiated()) {
+              // CheckTypeArgumentBounds will insert a BoundedType.
+            } else if (bound_error->IsNull()) {
+              *bound_error = malformed_error.raw();
+            }
+          }
         }
         if (finalization >= kCanonicalize) {
           super_type_arg = super_type_arg.Canonicalize();
@@ -584,7 +599,85 @@
       }
       arguments.SetTypeAt(super_offset + i, super_type_arg);
     }
-    FinalizeTypeArguments(super_class, arguments, finalization);
+    FinalizeTypeArguments(super_class, arguments, finalization, bound_error);
+  }
+}
+
+
+// Check the type argument vector 'arguments' against the corresponding bounds
+// of the type parameters of class 'cls' and, recursively, of its superclasses.
+// Replace a type argument that cannot be checked at compile time by a
+// BoundedType, thereby postponing the bound check to run time.
+// Return a bound error if a type argument is not within bound at compile time.
+void ClassFinalizer::CheckTypeArgumentBounds(
+    const Class& cls,
+    const AbstractTypeArguments& arguments,
+    Error* bound_error) {
+  if (!cls.is_finalized()) {
+    ResolveAndFinalizeUpperBounds(cls);
+  }
+  // Note that when finalizing a type, we need to verify the bounds in both
+  // production mode and checked mode, because the finalized type may be written
+  // to a snapshot. It would be wrong to ignore bounds when generating the
+  // snapshot in production mode and then use the unchecked type in checked mode
+  // after reading it from the snapshot.
+  // However, we do not immediately report a bound error, which would be wrong
+  // in production mode, but simply postpone the bound checking to runtime.
+  const intptr_t num_type_params = cls.NumTypeParameters();
+  const intptr_t offset = cls.NumTypeArguments() - num_type_params;
+  AbstractType& type_arg = AbstractType::Handle();
+  AbstractType& cls_type_param = AbstractType::Handle();
+  AbstractType& bound = AbstractType::Handle();
+  const TypeArguments& cls_type_params =
+      TypeArguments::Handle(cls.type_parameters());
+  ASSERT((cls_type_params.IsNull() && (num_type_params == 0)) ||
+         (cls_type_params.Length() == num_type_params));
+  for (intptr_t i = 0; i < num_type_params; i++) {
+    type_arg = arguments.TypeAt(offset + i);
+    if (type_arg.IsDynamicType()) {
+      continue;
+    }
+    cls_type_param = cls_type_params.TypeAt(i);
+    const TypeParameter& type_param = TypeParameter::Cast(cls_type_param);
+    ASSERT(type_param.IsFinalized());
+    bound = type_param.bound();
+    if (!bound.IsObjectType() && !bound.IsDynamicType()) {
+      Error& malformed_error = Error::Handle();
+      // Note that the bound may be malformed, in which case the bound check
+      // will return an error and the bound check will be postponed to run time.
+      // Note also that the bound may still be unfinalized.
+      if (!bound.IsFinalized()) {
+        ASSERT(bound.IsBeingFinalized());
+        // The bound refers to type parameters, creating a cycle; postpone
+        // bound check to run time, when the bound will be finalized.
+        // TODO(regis): Do we need to instantiate an uninstantiated bound here?
+        type_arg = BoundedType::New(type_arg, bound, type_param);
+        arguments.SetTypeAt(offset + i, type_arg);
+        continue;
+      }
+      if (!bound.IsInstantiated()) {
+        bound = bound.InstantiateFrom(arguments, &malformed_error);
+      }
+      // TODO(regis): We could simplify this code if we could differentiate
+      // between a failed bound check and a bound check that is undecidable at
+      // compile time.
+      if (malformed_error.IsNull()) {
+        type_param.CheckBound(type_arg, bound, &malformed_error);
+      }
+      if (!malformed_error.IsNull()) {
+        if (!type_arg.IsInstantiated() || !bound.IsInstantiated()) {
+          type_arg = BoundedType::New(type_arg, bound, type_param);
+          arguments.SetTypeAt(offset + i, type_arg);
+        } else if (bound_error->IsNull()) {
+          *bound_error = malformed_error.raw();
+        }
+      }
+    }
+  }
+  AbstractType& super_type = AbstractType::Handle(cls.super_type());
+  if (!super_type.IsNull()) {
+    const Class& super_class = Class::Handle(super_type.type_class());
+    CheckTypeArgumentBounds(super_class, arguments, bound_error);
   }
 }
 
@@ -627,8 +720,6 @@
                             parameterized_class.NumTypeParameters();
     type_parameter.set_index(type_parameter.index() + offset);
     type_parameter.set_is_finalized();
-    // TODO(regis): We are not able to finalize the bound here without getting
-    // into cycles. Revisit.
     // We do not canonicalize type parameters.
     return type_parameter.raw();
   }
@@ -718,6 +809,7 @@
   // super types of type_class, which may be initialized from the parsed
   // type arguments, followed by the parsed type arguments.
   TypeArguments& full_arguments = TypeArguments::Handle();
+  Error& bound_error = Error::Handle();
   if (num_type_arguments > 0) {
     // If no type arguments were parsed and if the super types do not prepend
     // type arguments to the vector, we can leave the vector as null.
@@ -749,9 +841,13 @@
             Function::Handle(type_class.signature_function());
         ASSERT(!signature_fun.is_static());
         const Class& sig_fun_owner = Class::Handle(signature_fun.Owner());
-        FinalizeTypeArguments(sig_fun_owner, full_arguments, finalization);
+        FinalizeTypeArguments(
+            sig_fun_owner, full_arguments, finalization, &bound_error);
+        CheckTypeArgumentBounds(sig_fun_owner, full_arguments, &bound_error);
       } else {
-        FinalizeTypeArguments(type_class, full_arguments, finalization);
+        FinalizeTypeArguments(
+            type_class, full_arguments, finalization, &bound_error);
+        CheckTypeArgumentBounds(type_class, full_arguments, &bound_error);
       }
       if (full_arguments.IsRaw(num_type_arguments)) {
         // The parameterized_type is raw. Set its argument vector to null, which
@@ -774,33 +870,6 @@
     parameterized_type.SetIsFinalized();
   }
 
-  // Upper bounds of the finalized type arguments are only verified in checked
-  // mode, since bound errors are never reported by the vm in production mode.
-  if (FLAG_enable_type_checks &&
-      !full_arguments.IsNull() &&
-      full_arguments.IsInstantiated()) {
-    ResolveAndFinalizeUpperBounds(type_class);
-    Error& malformed_error = Error::Handle();
-    // Pass the full type argument vector as the bounds instantiator.
-    if (!full_arguments.IsWithinBoundsOf(type_class,
-                                         full_arguments,
-                                         &malformed_error)) {
-      ASSERT(!malformed_error.IsNull());
-      // The type argument vector of the type is not within bounds. The type
-      // is malformed. Prepend malformed_error to new malformed type error in
-      // order to report both locations.
-      // Note that malformed bounds never result in a compile time error, even
-      // in checked mode. Therefore, overwrite finalization with kFinalize
-      // when finalizing the malformed type.
-      FinalizeMalformedType(
-          malformed_error,
-          cls, parameterized_type, kFinalize,
-          "type arguments of type '%s' are not within bounds",
-          String::Handle(parameterized_type.UserVisibleName()).ToCString());
-      return parameterized_type.raw();
-    }
-  }
-
   // If the type class is a signature class, we are currently finalizing a
   // signature type, i.e. finalizing the result type and parameter types of the
   // signature function of this signature type.
@@ -812,6 +881,27 @@
     FinalizeClass(type_class);
   }
 
+  // If a bound error occurred, return a BoundedType with a malformed bound.
+  // The malformed bound will be ignored in production mode.
+  if (!bound_error.IsNull()) {
+    FinalizationKind bound_finalization = kTryResolve;  // No compile error.
+    if (FLAG_enable_type_checks || FLAG_error_on_malformed_type) {
+      bound_finalization = finalization;
+    }
+    const String& parameterized_type_name = String::Handle(
+        parameterized_type.UserVisibleName());
+    const Type& malformed_bound = Type::Handle(
+        NewFinalizedMalformedType(bound_error,
+                                  cls,
+                                  parameterized_type.token_pos(),
+                                  bound_finalization,
+                                  "type '%s' has an out of bound type argument",
+                                  parameterized_type_name.ToCString()));
+    return BoundedType::New(parameterized_type,
+                            malformed_bound,
+                            TypeParameter::Handle());
+  }
+
   if (finalization >= kCanonicalize) {
     return parameterized_type.Canonicalize();
   } else {
@@ -1094,6 +1184,104 @@
 }
 
 
+// Copy the type parameters of the super and mixin classes to the
+// mixin application class. Change type arguments of super type to
+// refer to the respective type parameters of the mixin application
+// class.
+void ClassFinalizer::CloneTypeParameters(const Class& mixapp_class) {
+  ASSERT(mixapp_class.NumTypeParameters() == 0);
+
+  const AbstractType& super_type =
+      AbstractType::Handle(mixapp_class.super_type());
+  ASSERT(super_type.IsResolved());
+  const Class& super_class = Class::Handle(super_type.type_class());
+  const Type& mixin_type = Type::Handle(mixapp_class.mixin());
+  const Class& mixin_class = Class::Handle(mixin_type.type_class());
+  const int num_super_parameters = super_class.NumTypeParameters();
+  const int num_mixin_parameters = mixin_class.NumTypeParameters();
+  if ((num_super_parameters + num_mixin_parameters) == 0) {
+    return;
+  }
+
+  // First, clone the super class type parameters. Rename them so that
+  // there can be no name conflict between the parameters of the super
+  // class and the mixin class.
+  const TypeArguments& cloned_type_params = TypeArguments::Handle(
+      TypeArguments::New(num_super_parameters + num_mixin_parameters));
+  TypeParameter& param = TypeParameter::Handle();
+  TypeParameter& cloned_param = TypeParameter::Handle();
+  String& param_name = String::Handle();
+  AbstractType& param_bound = AbstractType::Handle();
+  int cloned_index = 0;
+  if (num_super_parameters > 0) {
+    const TypeArguments& super_params =
+        TypeArguments::Handle(super_class.type_parameters());
+    const TypeArguments& super_type_args =
+        TypeArguments::Handle(TypeArguments::New(num_super_parameters));
+    for (int i = 0; i < num_super_parameters; i++) {
+      param ^= super_params.TypeAt(i);
+      param_name = param.name();
+      param_bound = param.bound();
+      // TODO(hausner): handle type bounds.
+      if (!param_bound.IsObjectType()) {
+        const Script& script = Script::Handle(mixapp_class.script());
+        ReportError(script, param.token_pos(),
+                    "type parameter '%s': type bounds not yet"
+                    " implemented for mixins\n",
+                    param_name.ToCString());
+      }
+      param_name = String::Concat(param_name, Symbols::Backtick());
+      param_name = Symbols::New(param_name);
+      cloned_param = TypeParameter::New(mixapp_class,
+                                        cloned_index,
+                                        param_name,
+                                        param_bound,
+                                        param.token_pos());
+      cloned_type_params.SetTypeAt(cloned_index, cloned_param);
+      // Change the type arguments of the super type to refer to the
+      // cloned type parameters of the mixin application class.
+      super_type_args.SetTypeAt(cloned_index, cloned_param);
+      cloned_index++;
+    }
+    // TODO(hausner): May need to handle BoundedType here.
+    ASSERT(super_type.IsType());
+    Type::Cast(super_type).set_arguments(super_type_args);
+  }
+
+  // Second, clone the type parameters of the mixin class.
+  // We need to retain the parameter names of the mixin class
+  // since the code that will be compiled in the context of the
+  // mixin application class may refer to the type parameters
+  // with that name.
+  if (num_mixin_parameters > 0) {
+    const TypeArguments& mixin_params =
+        TypeArguments::Handle(mixin_class.type_parameters());
+    for (int i = 0; i < num_mixin_parameters; i++) {
+      param ^= mixin_params.TypeAt(i);
+      param_name = param.name();
+      param_bound = param.bound();
+
+      // TODO(hausner): handle type bounds.
+      if (!param_bound.IsObjectType()) {
+        const Script& script = Script::Handle(mixapp_class.script());
+        ReportError(script, param.token_pos(),
+                    "type parameter '%s': type bounds not yet"
+                    " implemented for mixins\n",
+                    param_name.ToCString());
+      }
+      cloned_param = TypeParameter::New(mixapp_class,
+                                        cloned_index,
+                                        param_name,
+                                        param_bound,
+                                        param.token_pos());
+      cloned_type_params.SetTypeAt(cloned_index, cloned_param);
+      cloned_index++;
+    }
+  }
+  mixapp_class.set_type_parameters(cloned_type_params);
+}
+
+
 void ClassFinalizer::ApplyMixin(const Class& cls) {
   const Type& mixin_type = Type::Handle(cls.mixin());
   ASSERT(!mixin_type.IsNull());
@@ -1101,14 +1289,16 @@
   const Class& mixin_cls = Class::Handle(mixin_type.type_class());
 
   if (FLAG_trace_class_finalization) {
-    OS::Print("Applying mixin '%s' to '%s'\n",
+    OS::Print("Applying mixin '%s' to '%s' at pos %"Pd"\n",
               String::Handle(mixin_cls.Name()).ToCString(),
-              cls.ToCString());
+              cls.ToCString(),
+              cls.token_pos());
   }
 
   // Check that the super class of the mixin class is extending
   // class Object.
-  const Type& mixin_super_type = Type::Handle(mixin_cls.super_type());
+  const AbstractType& mixin_super_type =
+      AbstractType::Handle(mixin_cls.super_type());
   if (!mixin_super_type.IsObjectType()) {
     const Script& script = Script::Handle(cls.script());
     const String& class_name = String::Handle(mixin_cls.Name());
@@ -1117,30 +1307,8 @@
                 class_name.ToCString());
   }
 
-  // Copy the type parameters of the mixin class to the mixin
-  // application class.
-  const int num_type_parameters = mixin_cls.NumTypeParameters();
-  if (num_type_parameters > 0) {
-    ASSERT(cls.NumTypeParameters() == 0);
-    const TypeArguments& type_params =
-        TypeArguments::Handle(mixin_cls.type_parameters());
-    const TypeArguments& cloned_type_params =
-        TypeArguments::Handle(TypeArguments::New(num_type_parameters));
-    ASSERT(!type_params.IsNull());
-    TypeParameter& param = TypeParameter::Handle();
-    TypeParameter& cloned_param = TypeParameter::Handle();
-    String& param_name = String::Handle();
-    AbstractType& param_bound = AbstractType::Handle();
-    for (int i = 0; i < num_type_parameters; i++) {
-      param ^= type_params.TypeAt(i);
-      param_name = param.name();
-      param_bound = param.bound();
-      cloned_param = TypeParameter::New(
-          cls, i, param_name, param_bound, param.token_pos());
-      cloned_type_params.SetTypeAt(i, cloned_param);
-    }
-    cls.set_type_parameters(cloned_type_params);
-  }
+  // Copy type parameters to mixin application class.
+  CloneTypeParameters(cls);
 
   const GrowableObjectArray& cloned_funcs =
       GrowableObjectArray::Handle(GrowableObjectArray::New());
@@ -1193,6 +1361,13 @@
   }
   fields = Array::MakeArray(cloned_fields);
   cls.SetFields(fields);
+
+  if (FLAG_trace_class_finalization) {
+    OS::Print("done mixin appl %s %s extending %s\n",
+              String::Handle(cls.Name()).ToCString(),
+              TypeArguments::Handle(cls.type_parameters()).ToCString(),
+              AbstractType::Handle(cls.super_type()).ToCString());
+  }
 }
 
 
@@ -1224,9 +1399,15 @@
   // Finalize type parameters before finalizing the super type.
   FinalizeTypeParameters(cls);
   // Finalize super type.
-  Type& super_type = Type::Handle(cls.super_type());
+  AbstractType& super_type = AbstractType::Handle(cls.super_type());
   if (!super_type.IsNull()) {
-    super_type ^= FinalizeType(cls, super_type, kCanonicalizeWellFormed);
+    // In case of a bound error in the super type in production mode, the
+    // finalized super type will be a BoundedType with a malformed bound.
+    // It should not be a problem if the class is written to a snapshot and
+    // later executed in checked mode. Note that the finalized type argument
+    // vector of any type of the base class will contain a BoundedType for the
+    // out of bound type argument.
+    super_type = FinalizeType(cls, super_type, kCanonicalizeWellFormed);
     cls.set_super_type(super_type);
   }
   if (cls.IsSignatureClass()) {
@@ -1244,6 +1425,9 @@
     // subclasses of Object.
     ASSERT(super_type.IsNull() || super_type.IsObjectType());
 
+    // The type parameters of signature classes may have bounds.
+    ResolveAndFinalizeUpperBounds(cls);
+
     // Resolve and finalize the result and parameter types of the signature
     // function of this signature class.
     const Function& sig_function = Function::Handle(cls.signature_function());
@@ -1265,6 +1449,8 @@
   // Mark as finalized before resolving type parameter upper bounds and member
   // types in order to break cycles.
   cls.Finalize();
+  // Finalize bounds even if running in production mode, so that a snapshot
+  // contains them.
   ResolveAndFinalizeUpperBounds(cls);
   ResolveAndFinalizeMemberTypes(cls);
   // Run additional checks after all types are finalized.
@@ -1349,6 +1535,86 @@
 }
 
 
+void ClassFinalizer::CollectTypeArguments(const Class& cls,
+                              const Type& type,
+                              const GrowableObjectArray& collected_args) {
+  ASSERT(type.HasResolvedTypeClass());
+  Class& type_class = Class::Handle(type.type_class());
+  AbstractTypeArguments& type_args =
+      AbstractTypeArguments::Handle(type.arguments());
+  intptr_t num_type_parameters = type_class.NumTypeParameters();
+  intptr_t num_type_arguments = type_args.IsNull() ? 0 : type_args.Length();
+  AbstractType& arg = AbstractType::Handle();
+  if (num_type_arguments > 0) {
+    if (num_type_arguments != num_type_parameters) {
+      const Script& script = Script::Handle(cls.script());
+      const String& type_class_name = String::Handle(type_class.Name());
+      ReportError(script, type.token_pos(),
+          "wrong number of type arguments for class '%s'",
+          type_class_name.ToCString());
+    }
+    for (int i = 0; i < num_type_arguments; i++) {
+      arg = type_args.TypeAt(i);
+      collected_args.Add(arg);
+    }
+  } else {
+    // Fill arguments with type dynamic.
+    for (int i = 0; i < num_type_parameters; i++) {
+      arg = Type::DynamicType();
+      collected_args.Add(arg);
+    }
+  }
+}
+
+
+RawType* ClassFinalizer::ResolveMixinAppType(const Class& cls,
+                                             const MixinAppType& mixin_app) {
+  // Resolve super type and all mixin types.
+  const GrowableObjectArray& type_args =
+      GrowableObjectArray::Handle(GrowableObjectArray::New());
+  AbstractType& type = AbstractType::Handle(mixin_app.super_type());
+  ResolveType(cls, type, kCanonicalizeWellFormed);
+  ASSERT(type.HasResolvedTypeClass());
+  // TODO(hausner): May need to handle BoundedType here.
+  ASSERT(type.IsType());
+  CollectTypeArguments(cls, Type::Cast(type), type_args);
+  const Array& mixins = Array::Handle(mixin_app.mixin_types());
+  for (int i = 0; i < mixins.Length(); i++) {
+    type ^= mixins.At(i);
+    ASSERT(type.HasResolvedTypeClass());  // Newly created class in parser.
+    const Class& mixin_app_class = Class::Handle(type.type_class());
+    type = mixin_app_class.mixin();
+    ASSERT(!type.IsNull());
+    ResolveType(cls, type, kCanonicalizeWellFormed);
+    ASSERT(type.HasResolvedTypeClass());
+    ASSERT(type.IsType());
+    CollectTypeArguments(cls, Type::Cast(type), type_args);
+  }
+  const TypeArguments& mixin_app_args =
+    TypeArguments::Handle(TypeArguments::New(type_args.Length()));
+  for (int i = 0; i < type_args.Length(); i++) {
+    type ^= type_args.At(i);
+    mixin_app_args.SetTypeAt(i, type);
+  }
+  if (FLAG_trace_class_finalization) {
+    OS::Print("ResolveMixinAppType: mixin appl type args: %s\n",
+              mixin_app_args.ToCString());
+  }
+  // The last element in the mixins array is the lowest mixin application
+  // type in the mixin chain. Build a new super type with its type class
+  // and the collected type arguments from the super type and all
+  // mixin types. This super type replaces the MixinAppType object
+  // in the class that extends the mixin application.
+  type ^= mixins.At(mixins.Length() - 1);
+  const Class& resolved_mixin_app_class = Class::Handle(type.type_class());
+  Type& resolved_mixin_app_type = Type::Handle();
+  resolved_mixin_app_type = Type::New(resolved_mixin_app_class,
+                                      mixin_app_args,
+                                      mixin_app.token_pos());
+  return resolved_mixin_app_type.raw();
+}
+
+
 // Recursively walks the graph of explicitly declared super type and
 // interfaces, resolving unresolved super types and interfaces.
 // Reports an error if there is an interface reference that cannot be
@@ -1373,17 +1639,17 @@
 
   // If the class/interface has no explicit super class/interfaces
   // and is not a mixin application, we are done.
-  Type& super_type = Type::Handle(cls.super_type());
-  Type& mixin_type = Type::Handle(cls.mixin());
+  AbstractType& super_type = AbstractType::Handle(cls.super_type());
   Array& super_interfaces = Array::Handle(cls.interfaces());
   if ((super_type.IsNull() || super_type.IsObjectType()) &&
-      (super_interfaces.Length() == 0) &&
-      (mixin_type.IsNull())) {
+      (super_interfaces.Length() == 0)) {
     return;
   }
 
-  if (!mixin_type.IsNull()) {
-    ResolveType(cls, mixin_type, kCanonicalizeWellFormed);
+  if (super_type.IsMixinAppType()) {
+    const MixinAppType& mixin_app_type = MixinAppType::Cast(super_type);
+    super_type = ResolveMixinAppType(cls, mixin_app_type);
+    cls.set_super_type(super_type);
   }
 
   // If cls belongs to core lib, restrictions about allowed interfaces
@@ -1441,6 +1707,11 @@
       case kExternalFloat32ArrayCid:
       case kFloat64ArrayCid:
       case kExternalFloat64ArrayCid:
+#define DO_NOT_EXTEND_TYPED_DATA_CLASSES(clazz)                               \
+      case kTypedData##clazz##Cid:                                            \
+      case kExternalTypedData##clazz##Cid:
+      CLASS_LIST_TYPED_DATA(DO_NOT_EXTEND_TYPED_DATA_CLASSES)
+#undef DO_NOT_EXTEND_TYPED_DATA_CLASSES
       case kDartFunctionCid:
       case kWeakPropertyCid:
         is_error = true;
@@ -1553,7 +1824,7 @@
   } else {
     OS::Print(" (null library):\n");
   }
-  const Type& super_type = Type::Handle(cls.super_type());
+  const AbstractType& super_type = AbstractType::Handle(cls.super_type());
   if (super_type.IsNull()) {
     OS::Print("  Super: NULL");
   } else {
@@ -1612,21 +1883,15 @@
       ReportError(error);
     }
   }
+  // In checked mode, always mark the type as malformed.
+  // In production mode, mark the type as malformed only if its type class is
+  // not resolved.
+  // In both mode, make the type raw, since it may not be possible to
+  // properly finalize its type arguments.
   if (FLAG_enable_type_checks || !type.HasResolvedTypeClass()) {
-    // In check mode, always mark the type as malformed.
-    // In production mode, mark the type as malformed only if its type class is
-    // not resolved.
     type.set_malformed_error(error);
-    if (!type.HasResolvedTypeClass()) {
-      // We do not want an unresolved class to end up in a snapshot.
-      type.set_type_class(Object::Handle(Object::null_class()));
-    }
-  } else {
-     // In production mode, do not mark the type with a resolved type class as
-     // malformed, but make it raw.
-    type.set_arguments(AbstractTypeArguments::Handle());
   }
-  ASSERT(type.HasResolvedTypeClass());
+  type.set_arguments(AbstractTypeArguments::Handle());
   if (!type.IsFinalized()) {
     type.SetIsFinalized();
     // Do not canonicalize malformed types, since they may not be resolved.
@@ -1655,6 +1920,7 @@
   ReportMalformedType(prev_error, cls, type, finalization, format, args);
   va_end(args);
   ASSERT(type.IsMalformed());
+  ASSERT(type.IsFinalized());
   return type.raw();
 }
 
diff --git a/runtime/vm/class_finalizer.h b/runtime/vm/class_finalizer.h
index 237c40d..e59e591 100644
--- a/runtime/vm/class_finalizer.h
+++ b/runtime/vm/class_finalizer.h
@@ -11,6 +11,7 @@
 namespace dart {
 
 class AbstractType;
+class MixinAppType;
 class AbstractTypeArguments;
 class Class;
 class Error;
@@ -99,13 +100,23 @@
       const Class& cls,
       const Function& factory,
       const GrowableObjectArray& visited_factories);
+  static void CloneTypeParameters(const Class& mixapp_class);
   static void ApplyMixin(const Class& cls);
+  static void CollectTypeArguments(const Class& cls,
+                                   const Type& type,
+                                   const GrowableObjectArray& collected_args);
+  static RawType* ResolveMixinAppType(const Class& cls,
+                                      const MixinAppType& mixin_app);
   static void ResolveSuperTypeAndInterfaces(const Class& cls,
                                             GrowableArray<intptr_t>* visited);
   static void FinalizeTypeParameters(const Class& cls);
   static void FinalizeTypeArguments(const Class& cls,
                                     const AbstractTypeArguments& arguments,
-                                    FinalizationKind finalization);
+                                    FinalizationKind finalization,
+                                    Error* bound_error);
+  static void CheckTypeArgumentBounds(const Class& cls,
+                                      const AbstractTypeArguments& arguments,
+                                      Error* bound_error);
   static void ResolveType(const Class& cls,
                           const AbstractType& type,
                           FinalizationKind finalization);
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 94ff500..b1f11df 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -4,7 +4,7 @@
 
 #include "vm/code_generator.h"
 
-#include "vm/assembler_macros.h"
+#include "vm/assembler.h"
 #include "vm/ast.h"
 #include "vm/bigint_operations.h"
 #include "vm/code_patcher.h"
@@ -181,7 +181,6 @@
       AbstractTypeArguments::CheckedHandle(arguments.ArgAt(1));
   ASSERT(type_arguments.IsNull() ||
          (type_arguments.Length() == cls.NumTypeArguments()));
-  AbstractTypeArguments& bounds_instantiator = AbstractTypeArguments::Handle();
   if (Object::Handle(arguments.ArgAt(2)).IsSmi()) {
     ASSERT(Smi::CheckedHandle(arguments.ArgAt(2)).Value() ==
            StubCode::kNoInstantiator);
@@ -190,36 +189,29 @@
     const AbstractTypeArguments& instantiator =
         AbstractTypeArguments::CheckedHandle(arguments.ArgAt(2));
     ASSERT(instantiator.IsNull() || instantiator.IsInstantiated());
+    Error& malformed_error = Error::Handle();
     if (instantiator.IsNull()) {
-      type_arguments =
-          InstantiatedTypeArguments::New(type_arguments, instantiator);
+      type_arguments = type_arguments.InstantiateFrom(instantiator,
+                                                      &malformed_error);
     } else if (instantiator.IsTypeArguments()) {
       // Code inlined in the caller should have optimized the case where the
       // instantiator is a TypeArguments and can be used as type argument
       // vector.
       ASSERT(!type_arguments.IsUninstantiatedIdentity() ||
              (instantiator.Length() != type_arguments.Length()));
-      type_arguments =
-          InstantiatedTypeArguments::New(type_arguments, instantiator);
+      type_arguments = type_arguments.InstantiateFrom(instantiator,
+                                                      &malformed_error);
     } else {
       // If possible, use the instantiator as the type argument vector.
       if (type_arguments.IsUninstantiatedIdentity() &&
           (instantiator.Length() == type_arguments.Length())) {
         type_arguments = instantiator.raw();
       } else {
-        type_arguments =
-            InstantiatedTypeArguments::New(type_arguments, instantiator);
+        type_arguments = type_arguments.InstantiateFrom(instantiator,
+                                                        &malformed_error);
       }
     }
-    bounds_instantiator = instantiator.raw();
-  }
-  if (!type_arguments.IsNull()) {
-    ASSERT(type_arguments.IsInstantiated());
-    Error& malformed_error = Error::Handle();
-    if (!type_arguments.IsWithinBoundsOf(cls,
-                                         bounds_instantiator,
-                                         &malformed_error)) {
-      ASSERT(!malformed_error.IsNull());
+    if (!malformed_error.IsNull()) {
       // Throw a dynamic type error.
       const intptr_t location = GetCallerLocation();
       String& malformed_error_message =  String::Handle(
@@ -230,6 +222,7 @@
       UNREACHABLE();
     }
   }
+  ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated());
   instance.SetTypeArguments(type_arguments);
 }
 
@@ -373,8 +366,9 @@
                  caller_frame->pc());
   } else {
     // Instantiate type before printing.
-    const AbstractType& instantiated_type =
-        AbstractType::Handle(type.InstantiateFrom(instantiator_type_arguments));
+    Error& malformed_error = Error::Handle();
+    const AbstractType& instantiated_type = AbstractType::Handle(
+        type.InstantiateFrom(instantiator_type_arguments, &malformed_error));
     OS::PrintErr("%s: '%s' %s '%s' instantiated from '%s' (pc: %#"Px").\n",
                  message,
                  String::Handle(instance_type.Name()).ToCString(),
@@ -382,6 +376,9 @@
                  String::Handle(instantiated_type.Name()).ToCString(),
                  String::Handle(type.Name()).ToCString(),
                  caller_frame->pc());
+    if (!malformed_error.IsNull()) {
+      OS::Print("  malformed error: %s\n", malformed_error.ToErrorCString());
+    }
   }
   const Function& function = Function::Handle(
       caller_frame->LookupDartFunction());
@@ -413,7 +410,10 @@
       uninstantiated =
           instantiated_type_arguments.uninstantiated_type_arguments();
       instantiator = instantiated_type_arguments.instantiator_type_arguments();
-      type_arguments = uninstantiated.InstantiateFrom(instantiator);
+      Error& malformed_error = Error::Handle();
+      type_arguments = uninstantiated.InstantiateFrom(instantiator,
+                                                      &malformed_error);
+      ASSERT(malformed_error.IsNull());  // Malformed types are not optimized.
     } while (type_arguments.IsInstantiatedTypeArguments());
     AbstractTypeArguments& new_type_arguments = AbstractTypeArguments::Handle();
     new_type_arguments = type_arguments.Canonicalize();
@@ -516,7 +516,10 @@
   if (FLAG_trace_type_checks) {
     AbstractType& test_type = AbstractType::Handle(type.raw());
     if (!test_type.IsInstantiated()) {
-      test_type = type.InstantiateFrom(instantiator_type_arguments);
+      Error& malformed_error = Error::Handle();
+      test_type = type.InstantiateFrom(instantiator_type_arguments,
+                                       &malformed_error);
+      ASSERT(malformed_error.IsNull());  // Malformed types are not optimized.
     }
     OS::PrintErr("  Updated test cache %p ix: %"Pd" with (%"Pd", %p, %p, %s)\n"
         "    [%p %s %"Pd", %p %s]\n"
@@ -631,7 +634,8 @@
     if (!dst_type.IsInstantiated()) {
       // Instantiate dst_type before reporting the error.
       const AbstractType& instantiated_dst_type = AbstractType::Handle(
-          dst_type.InstantiateFrom(instantiator_type_arguments));
+          dst_type.InstantiateFrom(instantiator_type_arguments, NULL));
+      // Note that instantiated_dst_type may be malformed.
       dst_type_name = instantiated_dst_type.UserVisibleName();
     } else {
       dst_type_name = dst_type.UserVisibleName();
diff --git a/runtime/vm/code_patcher.cc b/runtime/vm/code_patcher.cc
index 8f78be5..c353cac 100644
--- a/runtime/vm/code_patcher.cc
+++ b/runtime/vm/code_patcher.cc
@@ -3,19 +3,23 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/code_patcher.h"
+#include "vm/cpu.h"
 #include "vm/instructions.h"
 #include "vm/object.h"
 
 namespace dart {
 
-static void SwapCode(intptr_t num_bytes, char* a, char* b) {
+static void SwapCode(intptr_t num_bytes, char* code, char* buffer) {
+  uword code_address = reinterpret_cast<uword>(code);
   for (intptr_t i = 0; i < num_bytes; i++) {
-    char tmp = *a;
-    *a = *b;
-    *b = tmp;
-    a++;
-    b++;
+    char tmp = *code;
+    *code = *buffer;
+    *buffer = tmp;
+    code++;
+    buffer++;
   }
+  CPU::FlushICache(code_address, num_bytes);
+  // The buffer is not executed. No need to flush.
 }
 
 
diff --git a/runtime/vm/code_patcher_arm.cc b/runtime/vm/code_patcher_arm.cc
index 8f75660..8239239 100644
--- a/runtime/vm/code_patcher_arm.cc
+++ b/runtime/vm/code_patcher_arm.cc
@@ -33,7 +33,8 @@
                                       const Code& code,
                                       uword new_target) {
   ASSERT(code.ContainsInstructionAt(return_address));
-  UNIMPLEMENTED();
+  CallPattern call(return_address, code);
+  call.SetTargetAddress(new_target);
 }
 
 
@@ -47,13 +48,20 @@
                                      ICData* ic_data,
                                      Array* arguments_descriptor) {
   ASSERT(code.ContainsInstructionAt(return_address));
-  UNIMPLEMENTED();
-  return 0;
+  CallPattern call(return_address, code);
+  if (ic_data != NULL) {
+    *ic_data = call.IcData();
+  }
+  if (arguments_descriptor != NULL) {
+    *arguments_descriptor = call.ArgumentsDescriptor();
+  }
+  return call.TargetAddress();
 }
 
 
 intptr_t CodePatcher::InstanceCallSizeInBytes() {
-  UNIMPLEMENTED();
+  // The instance call instruction sequence has a variable size on ARM.
+  UNREACHABLE();
   return 0;
 }
 
diff --git a/runtime/vm/code_patcher_arm_test.cc b/runtime/vm/code_patcher_arm_test.cc
index 5b9d1fb..5ffdac0 100644
--- a/runtime/vm/code_patcher_arm_test.cc
+++ b/runtime/vm/code_patcher_arm_test.cc
@@ -45,12 +45,34 @@
 #define __ assembler->
 
 ASSEMBLER_TEST_GENERATE(IcDataAccess, assembler) {
-  UNIMPLEMENTED();
+  const String& class_name = String::Handle(Symbols::New("ownerClass"));
+  const Script& script = Script::Handle();
+  const Class& owner_class =
+      Class::Handle(Class::New(class_name, script, Scanner::kDummyTokenIndex));
+  const String& function_name =
+      String::ZoneHandle(Symbols::New("callerFunction"));
+  const Function& function = Function::ZoneHandle(
+      Function::New(function_name, RawFunction::kRegularFunction,
+                    true, false, false, false, owner_class, 0));
+
+  const String& target_name = String::Handle(String::New("targetFunction"));
+  const ICData& ic_data =
+      ICData::ZoneHandle(ICData::New(function, target_name, 15, 1));
+  const Array& arg_descriptor =
+      Array::ZoneHandle(ArgumentsDescriptor::New(1, Array::Handle()));
+
+  __ LoadObject(R5, ic_data);
+  __ LoadObject(R4, arg_descriptor);
+  ExternalLabel target_label(
+      "InlineCache", StubCode::OneArgCheckInlineCacheEntryPoint());
+  __ BranchLinkPatchable(&target_label);
+  __ Ret();
 }
 
 
 ASSEMBLER_TEST_RUN(IcDataAccess, test) {
-  uword return_address = test->entry() + CodePatcher::InstanceCallSizeInBytes();
+  uword return_address =
+      test->entry() + test->code().Size() - Instr::kInstrSize;
   ICData& ic_data = ICData::Handle();
   CodePatcher::GetInstanceCallAt(return_address, test->code(), &ic_data, NULL);
   EXPECT_STREQ("targetFunction",
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 4e19724..d993415 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -208,6 +208,9 @@
       optimizer.Canonicalize();
       DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
+      BranchSimplifier::Simplify(flow_graph);
+      DEBUG_ASSERT(flow_graph->VerifyUseLists());
+
       if (FLAG_constant_propagation) {
         ConstantPropagator::Optimize(flow_graph);
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
@@ -256,6 +259,13 @@
       }
 
       // The final canonicalization pass before the code generation.
+      if (FLAG_propagate_types) {
+        // Recompute types after code movement was done to ensure correct
+        // reaching types for hoisted values.
+        FlowGraphTypePropagator propagator(flow_graph);
+        propagator.Propagate();
+        DEBUG_ASSERT(flow_graph->VerifyUseLists());
+      }
       optimizer.Canonicalize();
       DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
diff --git a/runtime/vm/compiler_test.cc b/runtime/vm/compiler_test.cc
index 05c3f0d..0058593 100644
--- a/runtime/vm/compiler_test.cc
+++ b/runtime/vm/compiler_test.cc
@@ -11,8 +11,10 @@
 
 namespace dart {
 
-// Compiler only implemented on IA32 and X64 now.
-#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
+// Compiler only implemented on IA32, X64, and ARM.
+#if defined(TARGET_ARCH_IA32) ||                                               \
+    defined(TARGET_ARCH_X64) ||                                                \
+    defined(TARGET_ARCH_ARM)
 
 TEST_CASE(CompileScript) {
   const char* kScriptChars =
@@ -65,6 +67,6 @@
   EXPECT(function_moo.HasCode());
 }
 
-#endif  // TARGET_ARCH_IA32 || TARGET_ARCH_X64
+#endif  // TARGET_ARCH_IA32 || TARGET_ARCH_X64 || TARGET_ARCH_ARM
 
 }  // namespace dart
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index 0a0c928..43547b6 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -5,6 +5,8 @@
 #ifndef VM_CONSTANTS_ARM_H_
 #define VM_CONSTANTS_ARM_H_
 
+#include "platform/assert.h"
+
 namespace dart {
 
 // We support both VFPv3-D16 and VFPv3-D32 profiles, but currently only one at
@@ -176,6 +178,11 @@
 const int kDartVolatileFpuRegCount = 8;
 
 
+// Dart stack frame layout.
+static const int kLastParamSlotIndex = 3;
+static const int kFirstLocalSlotIndex = -2;
+
+
 // Values for the condition field as defined in section A3.2.
 enum Condition {
   kNoCondition = -1,
@@ -293,6 +300,18 @@
   kMulRnShift = 12,
   kMulRnBits = 4,
 
+  // MRC instruction offset field encoding.
+  kCRmShift = 0,
+  kCRmBits = 4,
+  kOpc2Shift = 5,
+  kOpc2Bits = 3,
+  kCoprocShift = 8,
+  kCoprocBits = 4,
+  kCRnShift = 16,
+  kCRnBits = 4,
+  kOpc1Shift = 21,
+  kOpc1Bits = 3,
+
   kBranchOffsetMask = 0x00ffffff
 };
 
@@ -480,6 +499,13 @@
     return static_cast<DRegister>(Bits(kRmShift, kRmBits) + (Bit(5) << 4));
   }
 
+  inline bool IsDivision() const {
+    ASSERT(ConditionField() != kSpecialCondition);
+    ASSERT(TypeField() == 3);
+    return ((Bit(4) == 1) && (Bits(5, 3) == 0) &&
+            (Bit(20) == 1) && (Bits(22, 3) == 4));
+  }
+
   // Test for VFP data processing or single transfer instructions of type 7.
   inline bool IsVFPDataProcessingOrSingleTransfer() const {
     ASSERT(ConditionField() != kSpecialCondition);
@@ -504,6 +530,15 @@
     return ((Bits(20, 5) & 0x12) == 0x10) && (Bits(9, 3) == 5);
   }
 
+  // Only handle mrc of the id_isar0 register.
+  inline bool IsMrcIdIsar0() const {
+    ASSERT(ConditionField() != kSpecialCondition);
+    ASSERT(TypeField() == 7);
+    return (Bits(21, 3) == 0) && (Bits(16, 4) == 0) &&
+           (Bits(8, 4) == 0xf) && (Bits(5, 3) == 0) &&
+           (Bits(0, 4) == 2);
+  }
+
   // Test for VFP multiple load and store instructions of type 6.
   inline bool IsVFPMultipleLoadStore() const {
     ASSERT(ConditionField() != kSpecialCondition);
@@ -526,7 +561,6 @@
   // to allocate or create instances of class Instr.
   // Use the At(pc) function to create references to Instr.
   static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); }
-  Instr* Next() { return this + kInstrSize; }
 
  private:
   DISALLOW_ALLOCATION();
diff --git a/runtime/vm/constants_ia32.h b/runtime/vm/constants_ia32.h
index ad3f3c6..92a5bb7 100644
--- a/runtime/vm/constants_ia32.h
+++ b/runtime/vm/constants_ia32.h
@@ -73,6 +73,12 @@
 // an exception is thrown.
 const Register kStackTraceObjectReg = EDX;
 
+
+// Dart stack frame layout.
+static const int kLastParamSlotIndex = 2;
+static const int kFirstLocalSlotIndex = -2;
+
+
 enum ScaleFactor {
   TIMES_1 = 0,
   TIMES_2 = 1,
diff --git a/runtime/vm/constants_mips.h b/runtime/vm/constants_mips.h
index ea670bc..aba778d 100644
--- a/runtime/vm/constants_mips.h
+++ b/runtime/vm/constants_mips.h
@@ -8,42 +8,83 @@
 namespace dart {
 
 enum Register {
-  ZR =  0,
-  AT =  1,
+  R0  =  0,
+  R1  =  1,
   kFirstFreeCpuRegister = 2,
-  V0 =  2,
-  V1 =  3,
-  A0 =  4,
-  A1 =  5,
-  A2 =  6,
-  A3 =  7,
-  T0 =  8,
-  T1 =  9,
-  T2 = 10,
-  T3 = 11,
-  T4 = 12,
-  T5 = 13,
-  T6 = 14,
-  T7 = 15,
-  S0 = 16,
-  S1 = 17,
-  S2 = 18,
-  S3 = 19,
-  S4 = 20,
-  S5 = 21,
-  S6 = 22,
-  S7 = 23,
-  T8 = 24,
-  T9 = 25,
+  R2  =  2,
+  R3  =  3,
+  R4  =  4,
+  R5  =  5,
+  R6  =  6,
+  R7  =  7,
+  R8  =  8,
+  R9  =  9,
+  R10 = 10,
+  R11 = 11,
+  R12 = 12,
+  R13 = 13,
+  R14 = 14,
+  R15 = 15,
+  R16 = 16,
+  R17 = 17,
+  R18 = 18,
+  R19 = 19,
+  R20 = 20,
+  R21 = 21,
+  R22 = 22,
+  R23 = 23,
+  R24 = 24,
+  R25 = 25,
   kLastFreeCpuRegister = 25,
-  K0 = 26,
-  K1 = 27,
-  GP = 28,
-  SP = 29,
-  FP = 30,
-  RA = 31,
+  R26 = 26,
+  R27 = 27,
+  R28 = 28,
+  R29 = 29,
+  R30 = 30,
+  R31 = 31,
   kNumberOfCpuRegisters = 32,
   kNoRegister = -1,
+
+  // Register aliases.
+  ZR = R0,
+  AT = R1,
+
+  V0 = R2,
+  V1 = R3,
+
+  A0 = R4,
+  A1 = R5,
+  A2 = R6,
+  A3 = R7,
+
+  T0 = R8,
+  T1 = R9,
+  T2 = R10,
+  T3 = R11,
+  T4 = R12,
+  T5 = R13,
+  T6 = R14,
+  T7 = R15,
+
+  S0 = R16,
+  S1 = R17,
+  S2 = R18,
+  S3 = R19,
+  S4 = R20,
+  S5 = R21,
+  S6 = R22,
+  S7 = R23,
+
+  T8 = R24,
+  T9 = R25,
+
+  K0 = R26,
+  K1 = R27,
+
+  GP = R28,
+  SP = R29,
+  FP = R30,
+  RA = R31,
 };
 
 
@@ -100,12 +141,246 @@
 const Register FPREG = FP;  // Frame pointer register.
 
 
+// Dart stack frame layout.
+static const int kLastParamSlotIndex = 3;
+static const int kFirstLocalSlotIndex = -2;
+
+
 // Values for the condition field.  // UNIMPLEMENTED.
 enum Condition {
   kNoCondition = -1,
   kMaxCondition = 16,
 };
 
+
+// Constants used for the decoding or encoding of the individual fields of
+// instructions. Based on the "Table 4.25 CPU Instruction Format Fields".
+enum InstructionFields {
+  kOpcodeShift = 26,
+  kOpcodeBits = 6,
+  kRsShift = 21,
+  kRsBits = 5,
+  kRtShift = 16,
+  kRtBits = 5,
+  kRdShift = 11,
+  kRdBits = 5,
+  kSaShift = 6,
+  kSaBits = 5,
+  kFunctionShift = 0,
+  kFunctionBits = 6,
+  kImmShift = 0,
+  kImmBits = 16,
+  kInstrShift = 0,
+  kInstrBits = 26,
+  kBreakCodeShift = 5,
+  kBreakCodeBits = 20,
+};
+
+
+enum Opcode {
+  SPECIAL = 0,
+  REGIMM = 1,
+  J = 2,
+  JAL = 3,
+  BEQ = 4,
+  BNE = 5,
+  BLEZ = 6,
+  BGTZ = 7,
+  ADDI = 8,
+  ADDIU = 9,
+  SLTI = 10,
+  SLTIU = 11,
+  ANDI = 12,
+  ORI = 13,
+  XORI = 14,
+  LUI = 15,
+  CPO0 = 16,
+  COP1 = 17,
+  COP2 = 18,
+  COP1X = 19,
+  BEQL = 20,
+  BNEL = 21,
+  BLEZL = 22,
+  BGTZL = 23,
+  SPECIAL2 = 28,
+  JALX = 29,
+  SPECIAL3 = 31,
+  LB = 32,
+  LH = 33,
+  LWL = 34,
+  LW = 35,
+  LBU = 36,
+  LHU = 37,
+  LWR = 38,
+  SB = 40,
+  SH = 41,
+  SWL = 42,
+  SW = 43,
+  SWR = 46,
+  CACHE = 47,
+  LL = 48,
+  LWC1 = 49,
+  LWC2 = 50,
+  PREF = 51,
+  LDC1 = 53,
+  LDC2 = 54,
+  SC = 56,
+  SWC1 = 57,
+  SWC2 = 58,
+  SDC1 = 61,
+  SDC2 = 62,
+};
+
+
+enum SpecialFunction {
+  // SPECIAL opcodes.
+  SLL = 0,
+  MOVCI = 1,
+  SRL = 2,
+  SRA = 3,
+  SLLV = 4,
+  SRLV = 6,
+  SRAV = 7,
+  JR = 8,
+  JALR = 9,
+  MOVZ = 10,
+  MOVN = 11,
+  SYSCALL = 12,
+  BREAK = 13,
+  SYNC = 15,
+  MFHI =16,
+  MTHI = 17,
+  MFLO = 18,
+  MTLO = 19,
+  MULT = 24,
+  MUTLU = 25,
+  DIV = 26,
+  DIVU = 27,
+  ADD = 32,
+  ADDU = 33,
+  SUB = 34,
+  SUBU = 35,
+  AND = 36,
+  OR = 37,
+  XOR = 38,
+  NOR = 39,
+  SLT = 42,
+  SLTU = 43,
+  TGE = 48,
+  TGEU = 49,
+  TLT = 50,
+  TLTU = 51,
+  TEQ = 52,
+  TNE = 54,
+
+  // SPECIAL2 opcodes.
+  CLZ = 32,
+  CLO = 33,
+};
+
+
+enum RtRegImm {
+  BLTZ = 0,
+  BGEZ = 1,
+  BLTZL = 2,
+  BGEZL = 3,
+  TGEI = 8,
+  TGEIU = 9,
+  TLTI = 10,
+  TLTIU = 11,
+  TEQI = 12,
+  TNEI = 14,
+  BLTZAL = 16,
+  BGEZAL = 17,
+  BLTZALL = 18,
+  BGEZALL = 19,
+  SYNCI = 31,
+};
+
+
+class Instr {
+ public:
+  enum {
+    kInstrSize = 4,
+  };
+
+  static const int32_t kBreakPointInstruction =
+      (SPECIAL << kOpcodeShift) | (BREAK << kFunctionShift);
+  static const int32_t kNopInstruction = 0;
+
+  // Get the raw instruction bits.
+  inline int32_t InstructionBits() const {
+    return *reinterpret_cast<const int32_t*>(this);
+  }
+
+  // Set the raw instruction bits to value.
+  inline void SetInstructionBits(int32_t value) {
+    *reinterpret_cast<int32_t*>(this) = value;
+  }
+
+  // Read one particular bit out of the instruction bits.
+  inline int32_t Bit(int nr) const {
+    return (InstructionBits() >> nr) & 1;
+  }
+
+  // Read a bit field out of the instruction bits.
+  inline int32_t Bits(int shift, int count) const {
+    return (InstructionBits() >> shift) & ((1 << count) - 1);
+  }
+
+  // Accessors to the different named fields used in the MIPS encoding.
+  inline Opcode OpcodeField() const {
+    return static_cast<Opcode>(Bits(kOpcodeShift, kOpcodeBits));
+  }
+
+  inline Register RsField() const {
+    return static_cast<Register>(Bits(kRsShift, kRsBits));
+  }
+
+  inline Register RtField() const {
+    return static_cast<Register>(Bits(kRtShift, kRtBits));
+  }
+
+  inline Register RdField() const {
+    return static_cast<Register>(Bits(kRdShift, kRdBits));
+  }
+
+  inline int SaField() const {
+    return Bits(kSaShift, kSaBits);
+  }
+
+  inline int32_t UImmField() const {
+    return Bits(kImmShift, kImmBits);
+  }
+
+  inline int32_t SImmField() const {
+    // Sign-extend the imm field.
+    return (Bits(kImmShift, kImmBits) << (32 - kImmBits)) >> (32 - kImmBits);
+  }
+
+  inline int32_t BreakCodeField() const {
+    return Bits(kBreakCodeShift, kBreakCodeBits);
+  }
+
+  inline SpecialFunction FunctionField() const {
+    return static_cast<SpecialFunction>(Bits(kFunctionShift, kFunctionBits));
+  }
+
+  inline bool IsBreakPoint() {
+    return (OpcodeField() == SPECIAL) && (FunctionField() == BREAK);
+  }
+
+  // Instructions are read out of a code stream. The only way to get a
+  // reference to an instruction is to convert a pc. There is no way
+  // to allocate or create instances of class Instr.
+  // Use the At(pc) function to create references to Instr.
+  static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); }
+
+ private:
+  DISALLOW_ALLOCATION();
+  DISALLOW_IMPLICIT_CONSTRUCTORS(Instr);
+};
+
 }  // namespace dart
 
 #endif  // VM_CONSTANTS_MIPS_H_
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index 38a8793..2cbb7e7 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -97,6 +97,12 @@
 // an exception is thrown.
 const Register kStackTraceObjectReg = RDX;
 
+
+// Dart stack frame layout.
+static const int kLastParamSlotIndex = 2;
+static const int kFirstLocalSlotIndex = -2;
+
+
 enum ScaleFactor {
   TIMES_1 = 0,
   TIMES_2 = 1,
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index d8ba637..4ed5a7d 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -4,6 +4,7 @@
 
 #include "include/dart_api.h"
 
+#include "platform/assert.h"
 #include "vm/bigint_operations.h"
 #include "vm/class_finalizer.h"
 #include "vm/compiler.h"
@@ -1006,8 +1007,10 @@
   Isolate* isolate = Isolate::Current();
   CHECK_ISOLATE(isolate);
   if (!isolate->message_handler()->HandleNextMessage()) {
-    // TODO(turnidge): Clear sticky error here?
-    return Api::NewHandle(isolate, isolate->object_store()->sticky_error());
+    Dart_Handle error =
+        Api::NewHandle(isolate, isolate->object_store()->sticky_error());
+    isolate->object_store()->clear_sticky_error();
+    return error;
   }
   return Api::Success(isolate);
 }
@@ -2329,48 +2332,48 @@
     case kByteArrayCid :
       type = kByteData;
       break;
-    case kInt8ArrayCid :
-    case kExternalInt8ArrayCid :
+    case kTypedDataInt8ArrayCid :
+    case kExternalTypedDataInt8ArrayCid :
       type = kInt8;
       break;
-    case kUint8ArrayCid :
-    case kExternalUint8ArrayCid :
+    case kTypedDataUint8ArrayCid :
+    case kExternalTypedDataUint8ArrayCid :
       type = kUint8;
       break;
-    case kUint8ClampedArrayCid :
-    case kExternalUint8ClampedArrayCid :
+    case kTypedDataUint8ClampedArrayCid :
+    case kExternalTypedDataUint8ClampedArrayCid :
       type = kUint8Clamped;
       break;
-    case kInt16ArrayCid :
-    case kExternalInt16ArrayCid :
+    case kTypedDataInt16ArrayCid :
+    case kExternalTypedDataInt16ArrayCid :
       type = kInt16;
       break;
-    case kUint16ArrayCid :
-    case kExternalUint16ArrayCid :
+    case kTypedDataUint16ArrayCid :
+    case kExternalTypedDataUint16ArrayCid :
       type = kUint16;
       break;
-    case kInt32ArrayCid :
-    case kExternalInt32ArrayCid :
+    case kTypedDataInt32ArrayCid :
+    case kExternalTypedDataInt32ArrayCid :
       type = kInt32;
       break;
-    case kUint32ArrayCid :
-    case kExternalUint32ArrayCid :
+    case kTypedDataUint32ArrayCid :
+    case kExternalTypedDataUint32ArrayCid :
       type = kUint32;
       break;
-    case kInt64ArrayCid :
-    case kExternalInt64ArrayCid :
+    case kTypedDataInt64ArrayCid :
+    case kExternalTypedDataInt64ArrayCid :
       type = kInt64;
       break;
-    case kUint64ArrayCid :
-    case kExternalUint64ArrayCid :
+    case kTypedDataUint64ArrayCid :
+    case kExternalTypedDataUint64ArrayCid :
       type = kUint64;
       break;
-    case kFloat32ArrayCid :
-    case kExternalFloat32ArrayCid :
+    case kTypedDataFloat32ArrayCid :
+    case kExternalTypedDataFloat32ArrayCid :
       type = kFloat32;
       break;
-    case kFloat64ArrayCid :
-    case kExternalFloat64ArrayCid :
+    case kTypedDataFloat64ArrayCid :
+    case kExternalTypedDataFloat64ArrayCid :
       type = kFloat64;
       break;
     default:
@@ -2383,6 +2386,9 @@
 
 DART_EXPORT Dart_TypedData_Type Dart_GetTypeOfTypedData(Dart_Handle object) {
   intptr_t class_id = Api::ClassId(object);
+  if (!RawObject::IsTypedDataClassId(class_id)) {
+    return kInvalid;
+  }
   return GetType(class_id);
 }
 
@@ -2390,29 +2396,32 @@
 DART_EXPORT Dart_TypedData_Type Dart_GetTypeOfExternalTypedData(
     Dart_Handle object) {
   intptr_t class_id = Api::ClassId(object);
-  if (!RawObject::IsExternalByteArrayClassId(class_id)) {
+  if (!RawObject::IsExternalTypedDataClassId(class_id)) {
     return kInvalid;
   }
   return GetType(class_id);
 }
 
 
-template<typename type>
-static Dart_Handle NewTypedData(Isolate* isolate, intptr_t length) {
-  CHECK_LENGTH(length, type::kMaxElements);
-  return Api::NewHandle(isolate, type::New(length));
+static Dart_Handle NewTypedData(Isolate* isolate,
+                                intptr_t cid,
+                                intptr_t length) {
+  CHECK_LENGTH(length, TypedData::MaxElements(cid));
+  return Api::NewHandle(isolate, TypedData::New(cid, length));
 }
 
 
-template<typename type, typename datatype>
 static Dart_Handle NewExternalTypedData(
+    intptr_t cid,
     void* data,
     intptr_t length,
     void* peer,
     Dart_WeakPersistentHandleFinalizer callback) {
-  CHECK_LENGTH(length, type::kMaxElements);
-  const type& obj =
-      type::Handle(type::New(reinterpret_cast<datatype*>(data), length));
+  CHECK_LENGTH(length, ExternalTypedData::MaxElements(cid));
+  const ExternalTypedData& obj = ExternalTypedData::Handle(
+      ExternalTypedData::New(cid,
+                             reinterpret_cast<uint8_t*>(data),
+                             length));
   return reinterpret_cast<Dart_Handle>(obj.AddFinalizer(peer, callback));
 }
 
@@ -2427,27 +2436,27 @@
       // TODO(asiva): Add a new ByteArray::New() method.
       break;
     case kInt8 :
-      return NewTypedData<Int8Array>(isolate, length);
+      return NewTypedData(isolate, kTypedDataInt8ArrayCid, length);
     case kUint8 :
-      return NewTypedData<Uint8Array>(isolate, length);
+      return NewTypedData(isolate, kTypedDataUint8ArrayCid, length);
     case kUint8Clamped :
-      return NewTypedData<Uint8ClampedArray>(isolate, length);
+      return NewTypedData(isolate, kTypedDataUint8ClampedArrayCid, length);
     case kInt16 :
-      return NewTypedData<Int16Array>(isolate, length);
+      return NewTypedData(isolate, kTypedDataInt16ArrayCid, length);
     case kUint16 :
-      return NewTypedData<Uint16Array>(isolate, length);
+      return NewTypedData(isolate, kTypedDataUint16ArrayCid, length);
     case kInt32 :
-      return NewTypedData<Int32Array>(isolate, length);
+      return NewTypedData(isolate, kTypedDataInt32ArrayCid, length);
     case kUint32 :
-      return NewTypedData<Uint32Array>(isolate, length);
+      return NewTypedData(isolate, kTypedDataUint32ArrayCid, length);
     case kInt64 :
-      return NewTypedData<Int64Array>(isolate, length);
+      return NewTypedData(isolate, kTypedDataInt64ArrayCid, length);
     case kUint64 :
-      return NewTypedData<Uint64Array>(isolate, length);
+      return NewTypedData(isolate, kTypedDataUint64ArrayCid, length);
     case kFloat32 :
-      return NewTypedData<Float32Array>(isolate, length);
+      return NewTypedData(isolate, kTypedDataFloat32ArrayCid,  length);
     case kFloat64 :
-      return NewTypedData<Float64Array>(isolate, length);
+      return NewTypedData(isolate, kTypedDataFloat64ArrayCid, length);
     default:
       return Api::NewError("%s expects argument 'type' to be of 'TypedData'",
                            CURRENT_FUNC);
@@ -2474,60 +2483,71 @@
       // TODO(asiva): Allocate external ByteData object.
       break;
     case kInt8 :
-      return NewExternalTypedData<ExternalInt8Array, int8_t>(data,
-                                                             length,
-                                                             peer,
-                                                             callback);
+      return NewExternalTypedData(kExternalTypedDataInt8ArrayCid,
+                                  data,
+                                  length,
+                                  peer,
+                                  callback);
     case kUint8 :
-      return NewExternalTypedData<ExternalUint8Array, uint8_t>(data,
-                                                               length,
-                                                               peer,
-                                                               callback);
+      return NewExternalTypedData(kExternalTypedDataUint8ArrayCid,
+                                  data,
+                                  length,
+                                  peer,
+                                  callback);
     case kUint8Clamped :
-      return NewExternalTypedData<ExternalUint8ClampedArray, uint8_t>(data,
-                                                                      length,
-                                                                      peer,
-                                                                      callback);
+      return NewExternalTypedData(kExternalTypedDataUint8ClampedArrayCid,
+                                  data,
+                                  length,
+                                  peer,
+                                  callback);
     case kInt16 :
-      return NewExternalTypedData<ExternalInt16Array, int16_t>(data,
-                                                               length,
-                                                               peer,
-                                                               callback);
+      return NewExternalTypedData(kExternalTypedDataInt16ArrayCid,
+                                  data,
+                                  length,
+                                  peer,
+                                  callback);
     case kUint16 :
-      return NewExternalTypedData<ExternalUint16Array, uint16_t>(data,
-                                                                 length,
-                                                                 peer,
-                                                                 callback);
+      return NewExternalTypedData(kExternalTypedDataUint16ArrayCid,
+                                  data,
+                                  length,
+                                  peer,
+                                  callback);
     case kInt32 :
-      return NewExternalTypedData<ExternalInt32Array, int32_t>(data,
-                                                               length,
-                                                               peer,
-                                                               callback);
+      return NewExternalTypedData(kExternalTypedDataInt32ArrayCid,
+                                  data,
+                                  length,
+                                  peer,
+                                  callback);
     case kUint32 :
-      return NewExternalTypedData<ExternalUint32Array, uint32_t>(data,
-                                                                 length,
-                                                                 peer,
-                                                                 callback);
+      return NewExternalTypedData(kExternalTypedDataUint32ArrayCid,
+                                  data,
+                                  length,
+                                  peer,
+                                  callback);
     case kInt64 :
-      return NewExternalTypedData<ExternalInt64Array, int64_t>(data,
-                                                               length,
-                                                               peer,
-                                                               callback);
+      return NewExternalTypedData(kExternalTypedDataInt64ArrayCid,
+                                  data,
+                                  length,
+                                  peer,
+                                  callback);
     case kUint64 :
-      return NewExternalTypedData<ExternalUint64Array, uint64_t>(data,
-                                                                 length,
-                                                                 peer,
-                                                                 callback);
+      return NewExternalTypedData(kExternalTypedDataUint64ArrayCid,
+                                  data,
+                                  length,
+                                  peer,
+                                  callback);
     case kFloat32 :
-      return NewExternalTypedData<ExternalFloat32Array, float>(data,
-                                                               length,
-                                                               peer,
-                                                               callback);
+      return NewExternalTypedData(kExternalTypedDataFloat32ArrayCid,
+                                  data,
+                                  length,
+                                  peer,
+                                  callback);
     case kFloat64 :
-      return NewExternalTypedData<ExternalFloat64Array, double>(data,
-                                                                length,
-                                                                peer,
-                                                                callback);
+      return NewExternalTypedData(kExternalTypedDataFloat64ArrayCid,
+                                  data,
+                                  length,
+                                  peer,
+                                  callback);
     default:
       return Api::NewError("%s expects argument 'type' to be of"
                            " 'external TypedData'", CURRENT_FUNC);
@@ -2541,10 +2561,10 @@
                                                       void** peer) {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
-  const ByteArray& array =
-      Api::UnwrapByteArrayHandle(isolate, object);
+  const ExternalTypedData& array =
+      Api::UnwrapExternalTypedDataHandle(isolate, object);
   if (array.IsNull()) {
-    RETURN_TYPE_ERROR(isolate, object, ByteArray);
+    RETURN_TYPE_ERROR(isolate, object, ExternalTypedData);
   }
   if (peer == NULL) {
     RETURN_NULL_ERROR(peer);
@@ -2561,7 +2581,8 @@
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
   intptr_t class_id = Api::ClassId(object);
-  if (!RawObject::IsByteArrayClassId(class_id)) {
+  if (!RawObject::IsExternalTypedDataClassId(class_id) &&
+      !RawObject::IsTypedDataClassId(class_id)) {
     RETURN_TYPE_ERROR(isolate, object, 'TypedData');
   }
   if (type == NULL) {
@@ -2575,17 +2596,21 @@
   }
   // Get the type of typed data object.
   *type = GetType(class_id);
-  const ByteArray& obj = Api::UnwrapByteArrayHandle(isolate, object);
-  ASSERT(!obj.IsNull());
-  *len = obj.Length();
   // If it is an external typed data object just return the data field.
-  if (RawObject::IsExternalByteArrayClassId(class_id)) {
-    *data = reinterpret_cast<void*>(obj.ByteAddr(0));
+  if (RawObject::IsExternalTypedDataClassId(class_id)) {
+    const ExternalTypedData& obj =
+        Api::UnwrapExternalTypedDataHandle(isolate, object);
+    ASSERT(!obj.IsNull());
+    *len = obj.Length();
+    *data = reinterpret_cast<void*>(obj.DataAddr(0));
   } else {
     // Regular typed data object, set up some GC and API callback guards.
+    const TypedData& obj = Api::UnwrapTypedDataHandle(isolate, object);
+    ASSERT(!obj.IsNull());
+    *len = obj.Length();
     isolate->IncrementNoGCScopeDepth();
     START_NO_CALLBACK_SCOPE(isolate);
-    *data = reinterpret_cast<void*>(obj.ByteAddr(0));
+    *data = reinterpret_cast<void*>(obj.DataAddr(0));
   }
   return Api::Success(isolate);
 }
@@ -2595,10 +2620,11 @@
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
   intptr_t class_id = Api::ClassId(object);
-  if (!RawObject::IsByteArrayClassId(class_id)) {
+  if (!RawObject::IsExternalTypedDataClassId(class_id) &&
+      !RawObject::IsTypedDataClassId(class_id)) {
     RETURN_TYPE_ERROR(isolate, object, 'TypedData');
   }
-  if (!RawObject::IsExternalByteArrayClassId(class_id)) {
+  if (!RawObject::IsExternalTypedDataClassId(class_id)) {
     isolate->DecrementNoGCScopeDepth();
     END_NO_CALLBACK_SCOPE(isolate);
   }
@@ -4167,17 +4193,16 @@
 }
 
 
-// This function has friend access to SetReturnUnsafe.
-void SetReturnValueHelper(Dart_NativeArguments args, Dart_Handle retval) {
-  NoGCScope no_gc_scope;
-  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
-  arguments->SetReturnUnsafe(Api::UnwrapHandle(retval));
-}
-
-
 DART_EXPORT void Dart_SetReturnValue(Dart_NativeArguments args,
                                      Dart_Handle retval) {
-  SetReturnValueHelper(args, retval);
+  const Object& ret_obj = Object::Handle(Api::UnwrapHandle(retval));
+  if (!ret_obj.IsNull() && !ret_obj.IsInstance()) {
+    FATAL1("Return value check failed: saw '%s' expected a dart Instance.",
+           ret_obj.ToCString());
+  }
+  NoGCScope no_gc_scope;
+  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
+  arguments->SetReturn(ret_obj);
 }
 
 
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 77860db..efca65a 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -958,7 +958,7 @@
 
 TEST_CASE(TypedDataDirectAccess1) {
   const char* kScriptChars =
-      "import 'dart:scalarlist';\n"
+      "import 'dart:typeddata';\n"
       "void setMain(var a) {"
       "  for (var i = 0; i < 10; i++) {"
       "    a[i] = i;"
@@ -1000,7 +1000,6 @@
                                          uint8_t data[],
                                          intptr_t data_length) {
   EXPECT_VALID(obj);
-  EXPECT_EQ(expected_type, Dart_GetTypeOfTypedData(obj));
   EXPECT_EQ(expected_type, Dart_GetTypeOfExternalTypedData(obj));
   EXPECT(Dart_IsList(obj));
 
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc
index 61a9fc6..180a43c 100644
--- a/runtime/vm/dart_api_message.cc
+++ b/runtime/vm/dart_api_message.cc
@@ -430,7 +430,8 @@
       ::free(utf16);
       return object;
     }
-    case kUint8ArrayCid: {
+    case kTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ArrayCid: {
       intptr_t len = ReadSmiValue();
       Dart_CObject* object = AllocateDartCObjectUint8Array(len);
       AddBackRef(object_id, object, kIsDeserialized);
@@ -846,8 +847,9 @@
       // Write out the serialization header value for this object.
       WriteInlinedHeader(object);
       // Write out the class and tags information.
-      WriteIndexedObject(kUint8ArrayCid);
-      WriteIntptrValue(0);
+      WriteIndexedObject(kTypedDataUint8ArrayCid);
+      WriteIntptrValue(RawObject::ClassIdTag::update(
+          kTypedDataUint8ArrayCid, 0));
       uint8_t* bytes = object->value.as_byte_array.values;
       intptr_t len = object->value.as_byte_array.length;
       WriteSmi(len);
@@ -865,8 +867,9 @@
       // Write out serialization header value for this object.
       WriteInlinedHeader(object);
       // Write out the class and tag information.
-      WriteIndexedObject(kExternalUint8ArrayCid);
-      WriteIntptrValue(0);
+      WriteIndexedObject(kExternalTypedDataUint8ArrayCid);
+      WriteIntptrValue(RawObject::ClassIdTag::update(
+          kExternalTypedDataUint8ArrayCid, 0));
       int length = object->value.as_external_byte_array.length;
       uint8_t* data = object->value.as_external_byte_array.data;
       void* peer = object->value.as_external_byte_array.peer;
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index c6b5dc3..08bef08 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -55,14 +55,13 @@
   const Code& code = Code::Handle(function.CurrentCode());
   ASSERT(!code.IsNull());
   ASSERT(Isolate::Current()->no_callback_scope_depth() == 0);
-#ifdef USING_SIMULATOR
+#if defined(USING_SIMULATOR)
     return bit_copy<RawObject*, int64_t>(Simulator::Current()->Call(
         reinterpret_cast<int32_t>(entrypoint),
         static_cast<int32_t>(code.EntryPoint()),
         reinterpret_cast<int32_t>(&arguments_descriptor),
         reinterpret_cast<int32_t>(&arguments),
-        reinterpret_cast<int32_t>(&context),
-        0));
+        reinterpret_cast<int32_t>(&context)));
 #else
     return entrypoint(code.EntryPoint(),
                       arguments_descriptor,
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 388db67..30909a9 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -304,7 +304,8 @@
 
 // Calculate the context level at the current token index of the frame.
 intptr_t ActivationFrame::ContextLevel() {
-  if (context_level_ < 0) {
+  if (context_level_ < 0 && !ctx_.IsNull()) {
+    ASSERT(!code_.is_optimized());
     context_level_ = 0;
     intptr_t pc_desc_idx = PcDescIndex();
     ASSERT(!pc_desc_.IsNull());
@@ -493,13 +494,13 @@
   if (var_info.kind == RawLocalVarDescriptors::kStackVar) {
     *value = GetLocalVarValue(var_info.index);
   } else {
-    // TODO(tball): enable context variables once problem with VariableAt() is
-    // fixed, where frame_ctx_level is sometimes off by 1 (issues 8593 and 8594)
-    /*
     ASSERT(var_info.kind == RawLocalVarDescriptors::kContextVar);
-    ASSERT(!ctx_.IsNull());
     // The context level at the PC/token index of this activation frame.
     intptr_t frame_ctx_level = ContextLevel();
+    if (ctx_.IsNull()) {
+      *value = Symbols::New("<unknown>");
+      return;
+    }
     // The context level of the variable.
     intptr_t var_ctx_level = var_info.scope_id;
     intptr_t level_diff = frame_ctx_level - var_ctx_level;
@@ -516,8 +517,7 @@
       }
       ASSERT(!ctx.IsNull());
       *value = ctx.At(ctx_slot);
-    } */
-    *value = Symbols::New("<unknown>");
+    }
   }
 }
 
@@ -877,6 +877,7 @@
   StackFrameIterator iterator(false);
   StackFrame* frame = iterator.NextFrame();
   bool get_saved_context = false;
+  bool optimized_frame_found = false;
   while (frame != NULL) {
     ASSERT(frame->IsValid());
     if (frame->IsDartFrame()) {
@@ -885,10 +886,16 @@
                                                         frame->fp(),
                                                         frame->sp(),
                                                         code);
-      if (get_saved_context && !activation->code().is_optimized()) {
-        ctx = activation->GetSavedContext();
+      if (optimized_frame_found || code.is_optimized()) {
+        // Set context to null, to avoid returning bad context variable values.
+        activation->SetContext(Context::Handle());
+        optimized_frame_found = true;
+      } else {
+        if (get_saved_context) {
+          ctx = activation->GetSavedContext();
+        }
+        activation->SetContext(ctx);
       }
-      activation->SetContext(ctx);
       stack_trace->AddActivation(activation);
       get_saved_context = activation->function().IsClosureFunction();
     } else if (frame->IsEntryFrame()) {
diff --git a/runtime/vm/debugger_api_impl.cc b/runtime/vm/debugger_api_impl.cc
index b096c82..97ccf7c 100644
--- a/runtime/vm/debugger_api_impl.cc
+++ b/runtime/vm/debugger_api_impl.cc
@@ -568,9 +568,8 @@
 }
 
 
-DART_EXPORT Dart_Handle Dart_GetScriptSource(
-                            Dart_Handle library_url_in,
-                            Dart_Handle script_url_in) {
+DART_EXPORT Dart_Handle Dart_GenerateScriptSource(Dart_Handle library_url_in,
+                                                  Dart_Handle script_url_in) {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
   UNWRAP_AND_CHECK_PARAM(String, library_url, library_url_in);
@@ -589,7 +588,7 @@
                          library_url.ToCString());
   }
 
-  return Api::NewHandle(isolate, script.Source());
+  return Api::NewHandle(isolate, script.GenerateSource());
 }
 
 
diff --git a/runtime/vm/debugger_api_impl_test.cc b/runtime/vm/debugger_api_impl_test.cc
index f33e5f7..9b6d5e3 100644
--- a/runtime/vm/debugger_api_impl_test.cc
+++ b/runtime/vm/debugger_api_impl_test.cc
@@ -1024,7 +1024,7 @@
   }
 
   Dart_Handle lib_url = NewString(TestCase::url());
-  Dart_Handle source = Dart_GetScriptSource(lib_url, lib_url);
+  Dart_Handle source = Dart_ScriptGetSource((num_libs - 1), lib_url);
   EXPECT(Dart_IsString(source));
   char const* source_chars;
   Dart_StringToCString(source, &source_chars);
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index 1e4a614..b153b8c 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -4,7 +4,7 @@
 
 #include "vm/deopt_instructions.h"
 
-#include "vm/assembler_macros.h"
+#include "vm/assembler.h"
 #include "vm/code_patcher.h"
 #include "vm/intermediate_language.h"
 #include "vm/locations.h"
@@ -440,7 +440,7 @@
         Code::Handle(deopt_context->isolate(), function.unoptimized_code());
     ASSERT(!code.IsNull());
     intptr_t pc_marker = code.EntryPoint() +
-                         AssemblerMacros::kOffsetOfSavedPCfromEntrypoint;
+                         Assembler::kOffsetOfSavedPCfromEntrypoint;
     intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index);
     *to_addr = pc_marker;
     // Increment the deoptimization counter. This effectively increments each
@@ -709,14 +709,12 @@
   } else if (from_loc.IsStackSlot()) {
     intptr_t from_index = (from_loc.stack_index() < 0) ?
         from_loc.stack_index() + num_args_ :
-        from_loc.stack_index() + num_args_ -
-            ParsedFunction::kFirstLocalSlotIndex + 1;
+        from_loc.stack_index() + num_args_ - kFirstLocalSlotIndex + 1;
     deopt_instr = new DeoptStackSlotInstr(from_index);
   } else if (from_loc.IsDoubleStackSlot()) {
     intptr_t from_index = (from_loc.stack_index() < 0) ?
         from_loc.stack_index() + num_args_ :
-        from_loc.stack_index() + num_args_ -
-            ParsedFunction::kFirstLocalSlotIndex + 1;
+        from_loc.stack_index() + num_args_ - kFirstLocalSlotIndex + 1;
     if (from_loc.representation() == Location::kDouble) {
       deopt_instr = new DeoptDoubleStackSlotInstr(from_index);
     } else {
diff --git a/runtime/vm/disassembler.h b/runtime/vm/disassembler.h
index 25224c7..9958b20 100644
--- a/runtime/vm/disassembler.h
+++ b/runtime/vm/disassembler.h
@@ -59,50 +59,52 @@
  public:
   // Disassemble instructions between start and end.
   // (The assumption is that start is at a valid instruction).
-  static void Disassemble(uword start,
+  // Return true if all instructions were successfully decoded, false otherwise.
+  static bool Disassemble(uword start,
                           uword end,
                           DisassemblyFormatter* formatter,
                           const Code::Comments& comments);
 
-  static void Disassemble(uword start,
+  static bool Disassemble(uword start,
                           uword end,
                           DisassemblyFormatter* formatter) {
-    Disassemble(start, end, formatter, Code::Comments::New(0));
+    return Disassemble(start, end, formatter, Code::Comments::New(0));
   }
 
-  static void Disassemble(uword start,
+  static bool Disassemble(uword start,
                           uword end,
                           const Code::Comments& comments) {
     DisassembleToStdout stdout_formatter;
-    Disassemble(start, end, &stdout_formatter, comments);
+    return Disassemble(start, end, &stdout_formatter, comments);
   }
 
-  static void Disassemble(uword start, uword end) {
+  static bool Disassemble(uword start, uword end) {
     DisassembleToStdout stdout_formatter;
-    Disassemble(start, end, &stdout_formatter);
+    return Disassemble(start, end, &stdout_formatter);
   }
 
   // Disassemble instructions in a memory region.
-  static void DisassembleMemoryRegion(const MemoryRegion& instructions,
+  static bool DisassembleMemoryRegion(const MemoryRegion& instructions,
                                       DisassemblyFormatter* formatter) {
     uword start = instructions.start();
     uword end = instructions.end();
-    Disassemble(start, end, formatter);
+    return Disassemble(start, end, formatter);
   }
 
-  static void DisassembleMemoryRegion(const MemoryRegion& instructions) {
+  static bool DisassembleMemoryRegion(const MemoryRegion& instructions) {
     uword start = instructions.start();
     uword end = instructions.end();
-    Disassemble(start, end);
+    return Disassemble(start, end);
   }
 
   // Decodes one instruction.
   // Writes a hexadecimal representation into the hex_buffer and a
   // human-readable representation into the human_buffer.
-  // Returns the length of the decoded instruction in bytes.
-  static int DecodeInstruction(char* hex_buffer, intptr_t hex_size,
-                               char* human_buffer, intptr_t human_size,
-                               uword pc);
+  // Writes the length of the decoded instruction in bytes in out_instr_len.
+  // Returns false if the instruction could not be decoded.
+  static bool DecodeInstruction(char* hex_buffer, intptr_t hex_size,
+                                char* human_buffer, intptr_t human_size,
+                                int *out_instr_len, uword pc);
 
  private:
   static const int kHexadecimalBufferSize = 32;
diff --git a/runtime/vm/disassembler_arm.cc b/runtime/vm/disassembler_arm.cc
index 9e098cc..6cecb45 100644
--- a/runtime/vm/disassembler_arm.cc
+++ b/runtime/vm/disassembler_arm.cc
@@ -15,15 +15,20 @@
   ARMDecoder(char* buffer, size_t buffer_size)
       : buffer_(buffer),
         buffer_size_(buffer_size),
-        buffer_pos_(0) {
+        buffer_pos_(0),
+        decode_failure_(false) {
     buffer_[buffer_pos_] = '\0';
   }
 
   ~ARMDecoder() {}
 
   // Writes one disassembled instruction into 'buffer' (0-terminated).
+  // Returns true if the instruction was successfully decoded, false otherwise.
   void InstructionDecode(uword pc);
 
+  void set_decode_failure(bool b) { decode_failure_ = b; }
+  bool decode_failure() const { return decode_failure_; }
+
  private:
   // Bottleneck functions to print into the out_buffer.
   void Print(const char* str);
@@ -66,6 +71,9 @@
   size_t buffer_size_;  // The size of the character buffer.
   size_t buffer_pos_;  // Current character position in buffer.
 
+  bool decode_failure_;  // Set to true when a failure to decode is detected.
+
+  DISALLOW_ALLOCATION();
   DISALLOW_COPY_AND_ASSIGN(ARMDecoder);
 };
 
@@ -571,6 +579,7 @@
 // which will just print "unknown" of the instruction bits.
 void ARMDecoder::Unknown(Instr* instr) {
   Format(instr, "unknown");
+  set_decode_failure(true);
 }
 
 
@@ -852,6 +861,14 @@
 
 
 void ARMDecoder::DecodeType3(Instr* instr) {
+  if (instr->IsDivision()) {
+    if (instr->Bit(21)) {
+      Format(instr, "udiv'cond 'rd, 'rn, 'rm");
+    } else {
+      Format(instr, "sdiv'cond 'rd, 'rn, 'rm");
+    }
+    return;
+  }
   switch (instr->PUField()) {
     case 0: {
       if (instr->HasW()) {
@@ -1192,6 +1209,8 @@
         Unknown(instr);
       }
     }
+  } else if (instr->IsMrcIdIsar0()) {
+    Format(instr, "mrc'cond p15, 0, 'rd, c0, c2, 0");
   } else {
     Unknown(instr);
   }
@@ -1199,7 +1218,8 @@
 
 
 void ARMDecoder::InstructionDecode(uword pc) {
-Instr* instr = Instr::At(pc);
+  Instr* instr = Instr::At(pc);
+
   if (instr->ConditionField() == kSpecialCondition) {
     if (instr->InstructionBits() == static_cast<int32_t>(0xf57ff01f)) {
       Format(instr, "clrex");
@@ -1247,22 +1267,26 @@
 }
 
 
-int Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size,
+bool Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size,
                                     char* human_buffer, intptr_t human_size,
-                                    uword pc) {
+                                    int* out_instr_size, uword pc) {
   ARMDecoder decoder(human_buffer, human_size);
   decoder.InstructionDecode(pc);
   int32_t instruction_bits = Instr::At(pc)->InstructionBits();
   OS::SNPrint(hex_buffer, hex_size, "%08x", instruction_bits);
-  return Instr::kInstrSize;
+  if (out_instr_size) {
+    *out_instr_size = Instr::kInstrSize;
+  }
+  return !decoder.decode_failure();
 }
 
 
-void Disassembler::Disassemble(uword start,
+bool Disassembler::Disassemble(uword start,
                                uword end,
                                DisassemblyFormatter* formatter,
                                const Code::Comments& comments) {
   ASSERT(formatter != NULL);
+  bool success = true;
   char hex_buffer[kHexadecimalBufferSize];  // Instruction in hexadecimal form.
   char human_buffer[kUserReadableBufferSize];  // Human-readable instruction.
   uword pc = start;
@@ -1276,11 +1300,13 @@
           String::Handle(comments.CommentAt(comment_finger)).ToCString());
       comment_finger++;
     }
-    int instruction_length = DecodeInstruction(hex_buffer,
-                                               sizeof(hex_buffer),
-                                               human_buffer,
-                                               sizeof(human_buffer),
-                                               pc);
+    int instruction_length;
+    bool res = DecodeInstruction(hex_buffer, sizeof(hex_buffer),
+                                 human_buffer, sizeof(human_buffer),
+                                 &instruction_length, pc);
+    if (!res) {
+      success = false;
+    }
     formatter->ConsumeInstruction(hex_buffer,
                                   sizeof(hex_buffer),
                                   human_buffer,
@@ -1288,6 +1314,8 @@
                                   pc);
     pc += instruction_length;
   }
+
+  return success;
 }
 
 }  // namespace dart
diff --git a/runtime/vm/disassembler_ia32.cc b/runtime/vm/disassembler_ia32.cc
index 5610b5f..9aa3a49 100644
--- a/runtime/vm/disassembler_ia32.cc
+++ b/runtime/vm/disassembler_ia32.cc
@@ -1744,9 +1744,9 @@
 }
 
 
-int Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size,
+bool Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size,
                                     char* human_buffer, intptr_t human_size,
-                                    uword pc) {
+                                    int* out_instr_len, uword pc) {
   ASSERT(hex_size > 0);
   ASSERT(human_size > 0);
   X86Decoder decoder(human_buffer, human_size);
@@ -1760,11 +1760,14 @@
     remaining_size -= 2;
   }
   hex_buffer[hex_index] = '\0';
-  return instruction_length;
+  if (out_instr_len) {
+    *out_instr_len = instruction_length;
+  }
+  return true;
 }
 
 
-void Disassembler::Disassemble(uword start,
+bool Disassembler::Disassemble(uword start,
                                uword end,
                                DisassemblyFormatter* formatter,
                                const Code::Comments& comments) {
@@ -1782,11 +1785,12 @@
           String::Handle(comments.CommentAt(comment_finger)).ToCString());
       comment_finger++;
     }
-    int instruction_length = DecodeInstruction(hex_buffer,
-                                               sizeof(hex_buffer),
-                                               human_buffer,
-                                               sizeof(human_buffer),
-                                               pc);
+    int instruction_length;
+    DecodeInstruction(hex_buffer,
+                      sizeof(hex_buffer),
+                      human_buffer,
+                      sizeof(human_buffer),
+                      &instruction_length, pc);
     formatter->ConsumeInstruction(hex_buffer,
                                   sizeof(hex_buffer),
                                   human_buffer,
@@ -1794,6 +1798,8 @@
                                   pc);
     pc += instruction_length;
   }
+
+  return true;
 }
 
 }  // namespace dart
diff --git a/runtime/vm/disassembler_mips.cc b/runtime/vm/disassembler_mips.cc
index 72512ee..d7a83c0 100644
--- a/runtime/vm/disassembler_mips.cc
+++ b/runtime/vm/disassembler_mips.cc
@@ -10,19 +10,385 @@
 
 namespace dart {
 
-int Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size,
-                                    char* human_buffer, intptr_t human_size,
-                                    uword pc) {
-  UNIMPLEMENTED();
-  return 0;
+class MIPSDecoder : public ValueObject {
+ public:
+  MIPSDecoder(char* buffer, size_t buffer_size)
+      : buffer_(buffer),
+        buffer_size_(buffer_size),
+        buffer_pos_(0),
+        decode_failure_(false) {
+    buffer_[buffer_pos_] = '\0';
+  }
+
+  ~MIPSDecoder() {}
+
+  // Writes one disassembled instruction into 'buffer' (0-terminated).
+  // Returns true if the instruction was successfully decoded, false otherwise.
+  void InstructionDecode(Instr* instr);
+
+  void set_decode_failure(bool b) { decode_failure_ = b; }
+  bool decode_failure() const { return decode_failure_; }
+
+ private:
+  // Bottleneck functions to print into the out_buffer.
+  void Print(const char* str);
+
+  // Printing of common values.
+  void PrintRegister(Register reg);
+
+  int FormatRegister(Instr* instr, const char* format);
+  int FormatOption(Instr* instr, const char* format);
+  void Format(Instr* instr, const char* format);
+  void Unknown(Instr* instr);
+
+  void DecodeSpecial(Instr* instr);
+  void DecodeSpecial2(Instr* instr);
+
+  // Convenience functions.
+  char* get_buffer() const { return buffer_; }
+  char* current_position_in_buffer() { return buffer_ + buffer_pos_; }
+  size_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; }
+
+  char* buffer_;  // Decode instructions into this buffer.
+  size_t buffer_size_;  // The size of the character buffer.
+  size_t buffer_pos_;  // Current character position in buffer.
+
+  bool decode_failure_;  // Set to true when a failure to decode is detected.
+
+  DISALLOW_ALLOCATION();
+  DISALLOW_COPY_AND_ASSIGN(MIPSDecoder);
+};
+
+
+// Support for assertions in the MIPSDecoder formatting functions.
+#define STRING_STARTS_WITH(string, compare_string) \
+  (strncmp(string, compare_string, strlen(compare_string)) == 0)
+
+
+// Append the str to the output buffer.
+void MIPSDecoder::Print(const char* str) {
+  char cur = *str++;
+  while (cur != '\0' && (buffer_pos_ < (buffer_size_ - 1))) {
+    buffer_[buffer_pos_++] = cur;
+    cur = *str++;
+  }
+  buffer_[buffer_pos_] = '\0';
 }
 
 
-void Disassembler::Disassemble(uword start,
+static const char* reg_names[kNumberOfCpuRegisters] = {
+  "r0" , "r1" , "r2" , "r3" , "r4" , "r5" , "r6" , "r7" ,
+  "r8" , "r9" , "r10", "r11", "r12", "r13", "r14", "r15",
+  "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+  "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+};
+
+
+void MIPSDecoder::PrintRegister(Register reg) {
+  ASSERT(0 <= reg);
+  ASSERT(reg < kNumberOfCpuRegisters);
+  Print(reg_names[reg]);
+}
+
+
+// Handle all register based formatting in these functions to reduce the
+// complexity of FormatOption.
+int MIPSDecoder::FormatRegister(Instr* instr, const char* format) {
+  ASSERT(format[0] == 'r');
+  switch (format[1]) {
+    case 's': {  // 'rs: Rs register
+      PrintRegister(instr->RsField());
+      return 2;
+    }
+    case 't': {  // 'rt: Rt register
+      PrintRegister(instr->RtField());
+      return 2;
+    }
+    case 'd': {  // 'rd: Rd register
+      PrintRegister(instr->RdField());
+      return 2;
+    }
+  }
+  UNREACHABLE();
+  return -1;
+}
+
+
+// FormatOption takes a formatting string and interprets it based on
+// the current instructions. The format string points to the first
+// character of the option string (the option escape has already been
+// consumed by the caller.)  FormatOption returns the number of
+// characters that were consumed from the formatting string.
+int MIPSDecoder::FormatOption(Instr* instr, const char* format) {
+  switch (format[0]) {
+    case 'c': {
+      ASSERT(STRING_STARTS_WITH(format, "code"));
+      buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
+                                remaining_size_in_buffer(),
+                                "%d", instr->BreakCodeField());
+      return 4;
+    }
+    case 'h': {
+      ASSERT(STRING_STARTS_WITH(format, "hint"));
+      if (instr->SaField() == 0x10) {
+        // The high bit of the SA field is the only one that means something for
+        // JALR and JR. TODO(zra): Fill in the other cases for PREF if needed.
+        buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
+                                   remaining_size_in_buffer(),
+                                   ".hb");
+      } else if (instr->SaField() != 0) {
+        buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
+                           remaining_size_in_buffer(),
+                           ".unknown");
+      }
+      return 4;
+    }
+    case 'i': {
+      ASSERT(STRING_STARTS_WITH(format, "imm"));
+      if (format[3] == 'u') {
+        int32_t imm = instr->UImmField();
+        buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
+                                   remaining_size_in_buffer(),
+                                   "0x%x",
+                                   imm);
+      } else {
+        ASSERT(STRING_STARTS_WITH(format, "imms"));
+        int32_t imm = instr->SImmField();
+        buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
+                                   remaining_size_in_buffer(),
+                                   "%d",
+                                   imm);
+      }
+      return 4;
+    }
+    case 'r': {
+      return FormatRegister(instr, format);
+    }
+    case 's': {
+      ASSERT(STRING_STARTS_WITH(format, "sa"));
+      buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
+                                 remaining_size_in_buffer(),
+                                 "%d",
+                                 instr->SaField());
+      return 2;
+    }
+    default: {
+      UNREACHABLE();
+    }
+  }
+  UNREACHABLE();
+  return -1;
+}
+
+
+// Format takes a formatting string for a whole instruction and prints it into
+// the output buffer. All escaped options are handed to FormatOption to be
+// parsed further.
+void MIPSDecoder::Format(Instr* instr, const char* format) {
+  char cur = *format++;
+  while ((cur != 0) && (buffer_pos_ < (buffer_size_ - 1))) {
+    if (cur == '\'') {  // Single quote is used as the formatting escape.
+      format += FormatOption(instr, format);
+    } else {
+      buffer_[buffer_pos_++] = cur;
+    }
+    cur = *format++;
+  }
+  buffer_[buffer_pos_]  = '\0';
+}
+
+
+// For currently unimplemented decodings the disassembler calls Unknown(instr)
+// which will just print "unknown" of the instruction bits.
+void MIPSDecoder::Unknown(Instr* instr) {
+  Format(instr, "unknown");
+  set_decode_failure(true);
+}
+
+
+void MIPSDecoder::DecodeSpecial(Instr* instr) {
+  ASSERT(instr->OpcodeField() == SPECIAL);
+  switch (instr->FunctionField()) {
+    case ADDU: {
+      Format(instr, "addu 'rd, 'rs, 'rt");
+      break;
+    }
+    case AND: {
+      Format(instr, "and 'rd, 'rs, 'rt");
+      break;
+    }
+    case BREAK: {
+      Format(instr, "break 'code");
+      break;
+    }
+    case DIV: {
+      Format(instr, "div 'rs, 'rt");
+      break;
+    }
+    case DIVU: {
+      Format(instr, "divu 'rs, 'rt");
+      break;
+    }
+    case MFHI: {
+      Format(instr, "mfhi 'rd");
+      break;
+    }
+    case MFLO: {
+      Format(instr, "mflo 'rd");
+      break;
+    }
+    case SLL: {
+      if ((instr->RdField() == R0) &&
+          (instr->RtField() == R0) &&
+          (instr->SaField() == 0)) {
+        Format(instr, "nop");
+      } else {
+        Format(instr, "sll 'rd, 'rt, 'sa");
+      }
+      break;
+    }
+    case JR: {
+      Format(instr, "jr'hint 'rs");
+      break;
+    }
+    default: {
+      Unknown(instr);
+      break;
+    }
+  }
+}
+
+
+void MIPSDecoder::DecodeSpecial2(Instr* instr) {
+  ASSERT(instr->OpcodeField() == SPECIAL2);
+  switch (instr->FunctionField()) {
+    case CLO: {
+      Format(instr, "clo 'rd, 'rs");
+      break;
+    }
+    case CLZ: {
+      Format(instr, "clz 'rd, 'rs");
+      break;
+    }
+    default: {
+      Unknown(instr);
+      break;
+    }
+  }
+}
+
+
+void MIPSDecoder::InstructionDecode(Instr* instr) {
+  switch (instr->OpcodeField()) {
+    case SPECIAL: {
+      DecodeSpecial(instr);
+      break;
+    }
+    case SPECIAL2: {
+      DecodeSpecial2(instr);
+      break;
+    }
+    case ADDIU: {
+      Format(instr, "addiu 'rt, 'rs, 'imms");
+      break;
+    }
+    case ANDI: {
+      Format(instr, "andi 'rt, 'rs, 'immu");
+      break;
+    }
+    case LB: {
+      Format(instr, "lb 'rt, 'imms('rs)");
+      break;
+    }
+    case LBU: {
+      Format(instr, "lbu 'rt, 'imms('rs)");
+      break;
+    }
+    case LH: {
+      Format(instr, "lh 'rt, 'imms('rs)");
+      break;
+    }
+    case LUI: {
+      Format(instr, "lui 'rt, 'immu");
+      break;
+    }
+    case LW: {
+      Format(instr, "lw 'rt, 'imms('rs)");
+      break;
+    }
+    case ORI: {
+      Format(instr, "ori 'rt, 'rs, 'immu");
+      break;
+    }
+    case SB: {
+      Format(instr, "sb 'rt, 'imms('rs)");
+      break;
+    }
+    case SH: {
+      Format(instr, "sh 'rt, 'imms('rs)");
+      break;
+    }
+    case SW: {
+      Format(instr, "sw 'rt, 'imms('rs)");
+      break;
+    }
+    default: {
+      Unknown(instr);
+      break;
+    }
+  }
+}
+
+
+bool Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size,
+                                    char* human_buffer, intptr_t human_size,
+                                    int *out_instr_len, uword pc) {
+  MIPSDecoder decoder(human_buffer, human_size);
+  Instr* instr = Instr::At(pc);
+  decoder.InstructionDecode(instr);
+  OS::SNPrint(hex_buffer, hex_size, "%08x", instr->InstructionBits());
+  if (out_instr_len) {
+    *out_instr_len = Instr::kInstrSize;
+  }
+  return !decoder.decode_failure();
+}
+
+
+bool Disassembler::Disassemble(uword start,
                                uword end,
                                DisassemblyFormatter* formatter,
                                const Code::Comments& comments) {
-  UNIMPLEMENTED();
+  ASSERT(formatter != NULL);
+  bool success = true;
+  char hex_buffer[kHexadecimalBufferSize];  // Instruction in hexadecimal form.
+  char human_buffer[kUserReadableBufferSize];  // Human-readable instruction.
+  uword pc = start;
+  intptr_t comment_finger = 0;
+  while (pc < end) {
+    const intptr_t offset = pc - start;
+    while (comment_finger < comments.Length() &&
+           comments.PCOffsetAt(comment_finger) <= offset) {
+      formatter->Print(
+          "        ;; %s\n",
+          String::Handle(comments.CommentAt(comment_finger)).ToCString());
+      comment_finger++;
+    }
+    int instruction_length;
+    bool res = DecodeInstruction(hex_buffer, sizeof(hex_buffer),
+                                 human_buffer, sizeof(human_buffer),
+                                 &instruction_length, pc);
+    if (!res) {
+      success = false;
+    }
+    formatter->ConsumeInstruction(hex_buffer,
+                                  sizeof(hex_buffer),
+                                  human_buffer,
+                                  sizeof(human_buffer),
+                                  pc);
+    pc += instruction_length;
+  }
+
+  return success;
 }
 
 }  // namespace dart
diff --git a/runtime/vm/disassembler_x64.cc b/runtime/vm/disassembler_x64.cc
index 958c2b7..c1e442f 100644
--- a/runtime/vm/disassembler_x64.cc
+++ b/runtime/vm/disassembler_x64.cc
@@ -1865,9 +1865,9 @@
 }
 
 
-int Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size,
+bool Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size,
                                     char* human_buffer, intptr_t human_size,
-                                    uword pc) {
+                                    int* out_instr_len, uword pc) {
   ASSERT(hex_size > 0);
   ASSERT(human_size > 0);
   DisassemblerX64 decoder(human_buffer, human_size);
@@ -1881,11 +1881,14 @@
     remaining_size -= 2;
   }
   hex_buffer[hex_index] = '\0';
-  return instruction_length;
+  if (out_instr_len) {
+    *out_instr_len = instruction_length;
+  }
+  return true;
 }
 
 
-void Disassembler::Disassemble(uword start,
+bool Disassembler::Disassemble(uword start,
                                uword end,
                                DisassemblyFormatter* formatter,
                                const Code::Comments& comments) {
@@ -1903,11 +1906,12 @@
           String::Handle(comments.CommentAt(comment_finger)).ToCString());
       comment_finger++;
     }
-    int instruction_length = DecodeInstruction(hex_buffer,
-                                               sizeof(hex_buffer),
-                                               human_buffer,
-                                               sizeof(human_buffer),
-                                               pc);
+    int instruction_length;
+    DecodeInstruction(hex_buffer,
+                      sizeof(hex_buffer),
+                      human_buffer,
+                      sizeof(human_buffer),
+                      &instruction_length, pc);
     formatter->ConsumeInstruction(hex_buffer,
                                   sizeof(hex_buffer),
                                   human_buffer,
@@ -1915,6 +1919,8 @@
                                   pc);
     pc += instruction_length;
   }
+
+  return true;
 }
 
 }  // namespace dart
diff --git a/runtime/vm/flow_graph.h b/runtime/vm/flow_graph.h
index fa8c796..14c298a 100644
--- a/runtime/vm/flow_graph.h
+++ b/runtime/vm/flow_graph.h
@@ -142,6 +142,7 @@
 #endif  // DEBUG
 
  private:
+  friend class BranchSimplifier;
   friend class ConstantPropagator;
 
   void DiscoverBlocks();
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index f06d426..9f4072f 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -9,6 +9,7 @@
 #include "vm/code_descriptors.h"
 #include "vm/dart_entry.h"
 #include "vm/flags.h"
+#include "vm/flow_graph_compiler.h"
 #include "vm/il_printer.h"
 #include "vm/intermediate_language.h"
 #include "vm/longjump.h"
@@ -56,16 +57,11 @@
     graph_entry_(NULL) { }
 
 
-void FlowGraphBuilder::AddCatchEntry(TargetEntryInstr* entry) {
+void FlowGraphBuilder::AddCatchEntry(CatchBlockEntryInstr* entry) {
   graph_entry_->AddCatchEntry(entry);
 }
 
 
-InliningContext* InliningContext::Create(Definition* call) {
-  return new ValueInliningContext();
-}
-
-
 void InliningContext::PrepareGraphs(FlowGraph* caller_graph,
                                     Definition* call,
                                     FlowGraph* callee_graph) {
@@ -96,18 +92,18 @@
 }
 
 
-void ValueInliningContext::AddExit(ReturnInstr* exit) {
+void InliningContext::AddExit(ReturnInstr* exit) {
   Data data = { NULL, exit };
   exits_.Add(data);
 }
 
 
-int ValueInliningContext::LowestBlockIdFirst(const Data* a, const Data* b) {
+int InliningContext::LowestBlockIdFirst(const Data* a, const Data* b) {
   return (a->exit_block->block_id() - b->exit_block->block_id());
 }
 
 
-void ValueInliningContext::SortExits() {
+void InliningContext::SortExits() {
   // Assign block entries here because we did not necessarily know them when
   // the return exit was added to the array.
   for (int i = 0; i < exits_.length(); ++i) {
@@ -117,9 +113,9 @@
 }
 
 
-void ValueInliningContext::ReplaceCall(FlowGraph* caller_graph,
-                                       Definition* call,
-                                       FlowGraph* callee_graph) {
+void InliningContext::ReplaceCall(FlowGraph* caller_graph,
+                                  Definition* call,
+                                  FlowGraph* callee_graph) {
   ASSERT(call->previous() != NULL);
   ASSERT(call->next() != NULL);
   PrepareGraphs(caller_graph, call, callee_graph);
@@ -406,7 +402,7 @@
 Definition* EffectGraphVisitor::BuildStoreTemp(const LocalVariable& local,
                                                Value* value) {
   ASSERT(!local.is_captured());
-  return new StoreLocalInstr(local, value, owner()->context_level());
+  return new StoreLocalInstr(local, value);
 }
 
 
@@ -450,7 +446,7 @@
       return store;
     }
   } else {
-    return new StoreLocalInstr(local, value, owner()->context_level());
+    return new StoreLocalInstr(local, value);
   }
 }
 
@@ -470,7 +466,7 @@
                               Context::variable_offset(local.index()),
                               local.type());
   } else {
-    return new LoadLocalInstr(local, owner()->context_level());
+    return new LoadLocalInstr(local);
   }
 }
 
@@ -1062,13 +1058,17 @@
       // instantiated).
       result = new ConstantInstr(negate_result ? Bool::True() : Bool::False());
     } else {
-      if (literal_value.IsInstanceOf(type, TypeArguments::Handle(), NULL)) {
+      Error& malformed_error = Error::Handle();
+      if (literal_value.IsInstanceOf(type,
+                                     TypeArguments::Handle(),
+                                     &malformed_error)) {
         result = new ConstantInstr(negate_result ?
                                    Bool::False() : Bool::True());
       } else {
         result = new ConstantInstr(negate_result ?
                                    Bool::True() : Bool::False());
       }
+      ASSERT(malformed_error.IsNull());
     }
     ReturnDefinition(result);
     return;
@@ -1675,7 +1675,7 @@
   const intptr_t deopt_id = Isolate::kNoDeoptId;
   for (int i = 0; i < node->length(); ++i) {
     Value* array = Bind(
-        new LoadLocalInstr(node->temp_local(), owner()->context_level()));
+        new LoadLocalInstr(node->temp_local()));
     Value* index = Bind(new ConstantInstr(Smi::ZoneHandle(Smi::New(i))));
     ValueGraphVisitor for_value(owner(), temp_index());
     node->ElementAt(i)->Visit(&for_value);
@@ -1685,14 +1685,14 @@
         for_value.value()->BindsToConstant()
             ? kNoStoreBarrier
             : kEmitStoreBarrier;
+    intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(class_id);
     StoreIndexedInstr* store = new StoreIndexedInstr(
         array, index, for_value.value(),
-        emit_store_barrier, class_id, deopt_id);
+        emit_store_barrier, index_scale, class_id, deopt_id);
     Do(store);
   }
 
-  ReturnDefinition(
-      new LoadLocalInstr(node->temp_local(), owner()->context_level()));
+  ReturnDefinition(new LoadLocalInstr(node->temp_local()));
 }
 
 
@@ -1927,18 +1927,13 @@
       requires_type_arguments &&
       !node->type_arguments().IsNull() &&
       !node->type_arguments().IsInstantiated() &&
-      !node->type_arguments().IsWithinBoundsOf(cls,
-                                               node->type_arguments(),
-                                               NULL)) {
+      node->type_arguments().IsBounded()) {
     Value* type_arguments = NULL;
     Value* instantiator = NULL;
     BuildConstructorTypeArguments(node, &type_arguments, &instantiator, NULL);
 
     // The uninstantiated type arguments cannot be verified to be within their
     // bounds at compile time, so verify them at runtime.
-    // Although the type arguments may be uninstantiated at compile time, they
-    // may represent the identity vector and may be replaced by the instantiated
-    // type arguments of the instantiator at run time.
     allocate_comp = new AllocateObjectWithBoundsCheckInstr(node,
                                                            type_arguments,
                                                            instantiator);
@@ -1976,12 +1971,25 @@
 }
 
 
-// List of recognized factories in core lib (factories with known result-cid):
+// List of recognized list factories in core lib:
 // (factory-name-symbol, result-cid, fingerprint).
-#define RECOGNIZED_FACTORY_LIST(V)                                             \
-  V(ObjectArrayDot, kArrayCid, 97987288)                                       \
+// TODO(srdjan): Store the values in the snapshot instead.
+// TODO(srdjan): Add Float32x4List.
+#define RECOGNIZED_LIST_FACTORY_LIST(V)                                        \
+  V(ObjectArrayFactory, kArrayCid, 97987288)                                   \
   V(GrowableObjectArrayWithData, kGrowableObjectArrayCid, 816132033)           \
-  V(GrowableObjectArrayDot, kGrowableObjectArrayCid, 1896741574)               \
+  V(GrowableObjectArrayFactory, kGrowableObjectArrayCid, 1896741574)           \
+  V(Int8ListFactory, kInt8ArrayCid, 817410959)                                 \
+  V(Uint8ListFactory, kUint8ArrayCid, 220896178)                               \
+  V(Uint8ClampedListFactory, kUint8ClampedArrayCid, 422034060)                 \
+  V(Int16ListFactory, kInt16ArrayCid, 214246025)                               \
+  V(Uint16ListFactory, kUint16ArrayCid, 137929963)                             \
+  V(Int32ListFactory, kInt32ArrayCid, 1977571010)                              \
+  V(Uint32ListFactory, kUint32ArrayCid, 407638944)                             \
+  V(Int64ListFactory, kInt64ArrayCid, 885130273)                               \
+  V(Uint64ListFactory, kUint64ArrayCid, 1471017221)                            \
+  V(Float64ListFactory, kFloat64ArrayCid, 1037441059)                          \
+  V(Float32ListFactory, kFloat32ArrayCid, 2035252095)                          \
 
 
 // Class that recognizes factories and returns corresponding result cid.
@@ -1992,10 +2000,8 @@
     ASSERT(factory.IsFactory());
     const Class& function_class = Class::Handle(factory.Owner());
     const Library& lib = Library::Handle(function_class.library());
-    if (lib.raw() != Library::CoreLibrary()) {
-      // Only core library factories recognized.
-      return kDynamicCid;
-    }
+    ASSERT((lib.raw() == Library::CoreLibrary()) ||
+        (lib.raw() == Library::ScalarlistLibrary()));
     const String& factory_name = String::Handle(factory.name());
 #define RECOGNIZE_FACTORY(test_factory_symbol, cid, fp)                        \
     if (String::EqualsIgnoringPrivateKey(                                      \
@@ -2004,7 +2010,7 @@
       return cid;                                                              \
     }                                                                          \
 
-RECOGNIZED_FACTORY_LIST(RECOGNIZE_FACTORY);
+RECOGNIZED_LIST_FACTORY_LIST(RECOGNIZE_FACTORY);
 #undef RECOGNIZE_FACTORY
 
     return kDynamicCid;
@@ -2012,12 +2018,12 @@
 };
 
 
-static intptr_t GetResultCidOfConstructor(ConstructorCallNode* node) {
+static intptr_t GetResultCidOfListFactory(ConstructorCallNode* node) {
   const Function& function = node->constructor();
   const Class& function_class = Class::Handle(function.Owner());
-  const Library& core_lib = Library::Handle(Library::CoreLibrary());
 
-  if (function_class.library() != core_lib.raw()) {
+  if ((function_class.library() != Library::CoreLibrary()) &&
+      (function_class.library() != Library::ScalarlistLibrary())) {
     return kDynamicCid;
   }
 
@@ -2032,7 +2038,7 @@
     }
     return FactoryRecognizer::ResultCid(function);
   }
-  return kDynamicCid;   // Result cid not known.
+  return kDynamicCid;   // Not a known list constructor.
 }
 
 
@@ -2051,10 +2057,15 @@
                             node->constructor(),
                             node->arguments()->names(),
                             arguments);
-    // List factories return kArrayCid or kGrowableObjectArrayCid.
-    const intptr_t result_cid = GetResultCidOfConstructor(node);
-    call->set_result_cid(result_cid);
-    call->set_is_known_constructor(result_cid != kDynamicCid);
+    const intptr_t result_cid = GetResultCidOfListFactory(node);
+    if (result_cid != kDynamicCid) {
+      call->set_result_cid(result_cid);
+      call->set_is_known_list_constructor(true);
+      // Recognized fixed length array factory must have two arguments:
+      // (0) type-arguments, (1) length.
+      ASSERT(!LoadFieldInstr::IsFixedLengthArrayCid(result_cid) ||
+             arguments->length() == 2);
+    }
     ReturnDefinition(call);
     return;
   }
@@ -2705,18 +2716,25 @@
     if (super_function->IsNull()) {
       // Could not resolve super operator. Generate call noSuchMethod() of the
       // super class instead.
-      if (result_is_needed) {
-        // Even though noSuchMethod most likely does not return,
-        // we save the stored value if the result is needed.
-        ValueGraphVisitor for_value(owner(), temp_index());
-        node->value()->Visit(&for_value);
-        Append(for_value);
-        Bind(BuildStoreExprTemp(for_value.value()));
-      }
       ArgumentListNode* arguments = new ArgumentListNode(node->token_pos());
       arguments->Add(node->array());
       arguments->Add(node->index_expr());
-      arguments->Add(node->value());
+
+      // Even though noSuchMethod most likely does not return,
+      // we save the stored value if the result is needed.
+      if (result_is_needed) {
+        ValueGraphVisitor for_value(owner(), temp_index());
+        node->value()->Visit(&for_value);
+        Append(for_value);
+        Do(BuildStoreExprTemp(for_value.value()));
+
+        const LocalVariable* temp =
+            owner()->parsed_function().expression_temp_var();
+        AstNode* value = new LoadLocalNode(node->token_pos(), temp);
+        arguments->Add(value);
+      } else {
+        arguments->Add(node->value());
+      }
       StaticCallInstr* call =
           BuildStaticNoSuchMethodCall(node->super_class(),
                                       node->array(),
@@ -2858,10 +2876,10 @@
       const Function& function = owner()->parsed_function().function();
       int num_params = function.NumParameters();
       int param_frame_index = (num_params == function.num_fixed_parameters()) ?
-          (1 + num_params) : ParsedFunction::kFirstLocalSlotIndex;
+          (kLastParamSlotIndex + num_params - 1) : kFirstLocalSlotIndex;
       // Handle the saved arguments descriptor as an additional parameter.
       if (owner()->parsed_function().GetSavedArgumentsDescriptorVar() != NULL) {
-        ASSERT(param_frame_index == ParsedFunction::kFirstLocalSlotIndex);
+        ASSERT(param_frame_index == kFirstLocalSlotIndex);
         num_params++;
       }
       for (int pos = 0; pos < num_params; param_frame_index--, pos++) {
@@ -3017,10 +3035,11 @@
     catch_block->set_try_index(try_index);
     EffectGraphVisitor for_catch_block(owner(), temp_index());
     catch_block->Visit(&for_catch_block);
-    TargetEntryInstr* catch_entry =
-        new TargetEntryInstr(owner()->AllocateBlockId(), old_try_index);
-    catch_entry->set_catch_try_index(try_index);
-    catch_entry->set_catch_handler_types(catch_block->handler_types());
+    CatchBlockEntryInstr* catch_entry =
+        new CatchBlockEntryInstr(owner()->AllocateBlockId(),
+                                 old_try_index,
+                                 catch_block->handler_types(),
+                                 try_index);
     owner()->AddCatchEntry(catch_entry);
     ASSERT(!for_catch_block.is_open());
     AppendFragment(catch_entry, for_catch_block);
diff --git a/runtime/vm/flow_graph_builder.h b/runtime/vm/flow_graph_builder.h
index 92f5174..78a9460 100644
--- a/runtime/vm/flow_graph_builder.h
+++ b/runtime/vm/flow_graph_builder.h
@@ -16,14 +16,13 @@
 class Instruction;
 class ParsedFunction;
 
-// An abstraction of the graph context in which an inlined call occurs.
-class InliningContext: public ZoneAllocated {
+// An InliningContext collects the exits from an inlined function during
+// graph construction so they can be plugged into the caller's flow graph.
+class InliningContext: public ValueObject {
  public:
-  // Create the appropriate inlining context for the flow graph context of a
-  // call.
-  static InliningContext* Create(Definition* call);
+  InliningContext() : exits_(4) { }
 
-  virtual void AddExit(ReturnInstr* exit) = 0;
+  void AddExit(ReturnInstr* exit);
 
   // Inline a flow graph at a call site.
   //
@@ -33,29 +32,9 @@
   //
   // After inlining the caller graph will correctly have adjusted the
   // pre/post orders, the dominator tree and the use lists.
-  virtual void ReplaceCall(FlowGraph* caller_graph,
-                           Definition* call,
-                           FlowGraph* callee_graph) = 0;
-
- protected:
-  static void PrepareGraphs(FlowGraph* caller_graph,
-                            Definition* call,
-                            FlowGraph* callee_graph);
-};
-
-
-// The context of a call inlined for its value (including calls inlined for
-// their effects, i.e., when the value is ignored).  Collects normal exit
-// blocks and return values.
-class ValueInliningContext: public InliningContext {
- public:
-  ValueInliningContext() : exits_(4) { }
-
-  virtual void AddExit(ReturnInstr* exit);
-
-  virtual void ReplaceCall(FlowGraph* caller_graph,
-                           Definition* call,
-                           FlowGraph* callee_graph);
+  void ReplaceCall(FlowGraph* caller_graph,
+                   Definition* call,
+                   FlowGraph* callee_graph);
 
  private:
   struct Data {
@@ -63,6 +42,10 @@
     ReturnInstr* exit_return;
   };
 
+  static void PrepareGraphs(FlowGraph* caller_graph,
+                            Definition* call,
+                            FlowGraph* callee_graph);
+
   BlockEntryInstr* ExitBlockAt(intptr_t i) const {
     ASSERT(exits_[i].exit_block != NULL);
     return exits_[i].exit_block;
@@ -107,7 +90,7 @@
   void set_try_index(intptr_t value) { try_index_ = value; }
   intptr_t try_index() const { return try_index_; }
 
-  void AddCatchEntry(TargetEntryInstr* entry);
+  void AddCatchEntry(CatchBlockEntryInstr* entry);
 
   intptr_t num_copied_params() const {
     return num_copied_params_;
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index dc6d4ab..c4228e8 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -209,12 +209,62 @@
 }
 
 
+static bool IsEmptyBlock(BlockEntryInstr* block) {
+  return !block->HasParallelMove() &&
+         block->next()->IsGoto() &&
+         !block->next()->AsGoto()->HasParallelMove();
+}
+
+
+void FlowGraphCompiler::CompactBlock(BlockEntryInstr* block) {
+  BlockInfo* block_info = block_info_[block->postorder_number()];
+
+  if (block_info->is_marked()) {
+    return;
+  }
+  block_info->mark();
+
+  if (IsEmptyBlock(block)) {
+    BlockEntryInstr* target = block->next()->AsGoto()->successor();
+    CompactBlock(target);
+    block_info->set_jump_label(GetJumpLabel(target));
+  }
+}
+
+
+void FlowGraphCompiler::CompactBlocks() {
+  Label* fallthrough_label = NULL;
+  for (intptr_t i = block_order().length() - 1; i >= 1; --i) {
+    BlockEntryInstr* block = block_order()[i];
+
+    CompactBlock(block);
+
+    if (!WasCompacted(block)) {
+      BlockInfo* block_info = block_info_[block->postorder_number()];
+      block_info->set_fallthrough_label(fallthrough_label);
+      fallthrough_label = GetJumpLabel(block);
+    }
+  }
+
+  ASSERT(block_order()[0]->IsGraphEntry());
+  BlockInfo* block_info = block_info_[block_order()[0]->postorder_number()];
+  block_info->set_fallthrough_label(fallthrough_label);
+}
+
+
 void FlowGraphCompiler::VisitBlocks() {
+  CompactBlocks();
+
   for (intptr_t i = 0; i < block_order().length(); ++i) {
     // Compile the block entry.
     BlockEntryInstr* entry = block_order()[i];
     assembler()->Comment("B%"Pd"", entry->block_id());
     set_current_block(entry);
+
+    if (WasCompacted(entry)) {
+      continue;
+    }
+
     entry->PrepareEntry(this);
     // Compile all successors until an exit, branch, or a block entry.
     for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
@@ -259,17 +309,24 @@
 }
 
 
-Label* FlowGraphCompiler::GetBlockLabel(
+Label* FlowGraphCompiler::GetJumpLabel(
     BlockEntryInstr* block_entry) const {
-  intptr_t block_index = block_entry->postorder_number();
-  return &block_info_[block_index]->label;
+  const intptr_t block_index = block_entry->postorder_number();
+  return block_info_[block_index]->jump_label();
 }
 
 
-bool FlowGraphCompiler::IsNextBlock(BlockEntryInstr* block_entry) const {
-  intptr_t current_index = reverse_index(current_block()->postorder_number());
-  return (current_index < (block_order().length() - 1)) &&
-      (block_order()[current_index + 1] == block_entry);
+bool FlowGraphCompiler::WasCompacted(
+    BlockEntryInstr* block_entry) const {
+  const intptr_t block_index = block_entry->postorder_number();
+  return block_info_[block_index]->WasCompacted();
+}
+
+
+bool FlowGraphCompiler::CanFallThroughTo(BlockEntryInstr* block_entry) const {
+  const intptr_t current_index = current_block()->postorder_number();
+  Label* fallthrough_label = block_info_[current_index]->fallthrough_label();
+  return fallthrough_label == GetJumpLabel(block_entry);
 }
 
 
@@ -884,6 +941,11 @@
 
 
 intptr_t FlowGraphCompiler::ElementSizeFor(intptr_t cid) {
+  if (RawObject::IsExternalTypedDataClassId(cid)) {
+    return ExternalTypedData::ElementSizeInBytes(cid);
+  } else if (RawObject::IsTypedDataClassId(cid)) {
+    return TypedData::ElementSizeInBytes(cid);
+  }
   switch (cid) {
     case kArrayCid:
     case kImmutableArrayCid:
@@ -922,6 +984,13 @@
 
 
 intptr_t FlowGraphCompiler::DataOffsetFor(intptr_t cid) {
+  if (RawObject::IsExternalTypedDataClassId(cid)) {
+    // Elements start at offset 0 of the external data.
+    return 0;
+  }
+  if (RawObject::IsTypedDataClassId(cid)) {
+    return TypedData::data_offset();
+  }
   switch (cid) {
     case kArrayCid:
     case kImmutableArrayCid:
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index d0ff1f7..f141fd1 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -7,7 +7,6 @@
 
 #include "vm/allocation.h"
 #include "vm/assembler.h"
-#include "vm/assembler_macros.h"
 #include "vm/code_descriptors.h"
 #include "vm/code_generator.h"
 #include "vm/intermediate_language.h"
@@ -162,10 +161,38 @@
 
 class FlowGraphCompiler : public ValueObject {
  private:
-  struct BlockInfo : public ZoneAllocated {
+  class BlockInfo : public ZoneAllocated {
    public:
-    BlockInfo() : label() { }
-    Label label;
+    BlockInfo()
+        : jump_label_(&block_label_),
+          block_label_(),
+          fallthrough_label_(NULL),
+          is_marked_(false) {}
+
+    Label* jump_label() const { return jump_label_; }
+    void set_jump_label(Label* label) { jump_label_ = label; }
+
+    // Label of the block that will follow this block in the generated code.
+    // Can be NULL if the block is the last block.
+    Label* fallthrough_label() const { return fallthrough_label_; }
+    void set_fallthrough_label(Label* fallthrough_label) {
+      fallthrough_label_ = fallthrough_label;
+    }
+
+    bool WasCompacted() const {
+      return jump_label_ != &block_label_;
+    }
+
+    bool is_marked() const { return is_marked_; }
+    void mark() { is_marked_ = true; }
+
+   private:
+    Label* jump_label_;
+    Label block_label_;
+
+    Label* fallthrough_label_;
+
+    bool is_marked_;
   };
 
  public:
@@ -322,11 +349,12 @@
   intptr_t StackSize() const;
 
   // Returns assembler label associated with the given block entry.
-  Label* GetBlockLabel(BlockEntryInstr* block_entry) const;
+  Label* GetJumpLabel(BlockEntryInstr* block_entry) const;
+  bool WasCompacted(BlockEntryInstr* block_entry) const;
 
   // Returns true if there is a next block after the current one in
   // the block order and if it is the given block.
-  bool IsNextBlock(BlockEntryInstr* block_entry) const;
+  bool CanFallThroughTo(BlockEntryInstr* block_entry) const;
 
   void AddExceptionHandler(intptr_t try_index,
                            intptr_t outer_try_index,
@@ -386,12 +414,10 @@
                                                 intptr_t index_scale,
                                                 Register array,
                                                 Register index);
-  static Address ExternalElementAddressForIntIndex(intptr_t cid,
-                                                   intptr_t index_scale,
+  static Address ExternalElementAddressForIntIndex(intptr_t index_scale,
                                                    Register array,
                                                    intptr_t offset);
-  static Address ExternalElementAddressForRegIndex(intptr_t cid,
-                                                   intptr_t index_scale,
+  static Address ExternalElementAddressForRegIndex(intptr_t index_scale,
                                                    Register array,
                                                    Register index);
 
@@ -489,6 +515,9 @@
   static void SortICDataByCount(const ICData& ic_data,
                                 GrowableArray<CidTarget>* sorted);
 
+  void CompactBlock(BlockEntryInstr* block);
+  void CompactBlocks();
+
   class Assembler* assembler_;
   const ParsedFunction& parsed_function_;
   const GrowableArray<BlockEntryInstr*>& block_order_;
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 502de90..9b2bb20 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -29,7 +29,7 @@
   // BlockInfos are zone-allocated, so their destructors are not called.
   // Verify the labels explicitly here.
   for (int i = 0; i < block_info_.length(); ++i) {
-    ASSERT(!block_info_[i]->label.IsLinked());
+    ASSERT(!block_info_[i]->jump_label()->IsLinked());
   }
 }
 
@@ -187,7 +187,22 @@
     const bool can_optimize = !is_optimizing() || may_reoptimize();
     const Register function_reg = R6;
     if (can_optimize) {
-      __ LoadObject(function_reg, function);
+      // The pool pointer is not setup before entering the Dart frame.
+
+      // Preserve PP of caller.
+      __ mov(R7, ShifterOperand(PP));
+
+      // Temporarily setup pool pointer for this dart function.
+      const intptr_t object_pool_pc_dist =
+         Instructions::HeaderSize() - Instructions::object_pool_offset() +
+         assembler()->CodeSize() + Instr::kPCReadOffset;
+      __ ldr(PP, Address(PC, -object_pool_pc_dist));
+
+      // Load function object from object pool.
+      __ LoadObject(function_reg, function);  // Uses PP.
+
+      // Restore PP of caller.
+      __ mov(PP, ShifterOperand(R7));
     }
     // Patch point is after the eventually inlined function object.
     AddCurrentDescriptor(PcDescriptors::kEntryPatch,
@@ -216,7 +231,7 @@
                          0);  // No token position.
   }
   __ Comment("Enter frame");
-  AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize));
+  __ EnterDartFrame((StackSize() * kWordSize));
 }
 
 
@@ -306,7 +321,7 @@
                                             0);  // No registers.
         }
         // The noSuchMethod call may return.
-        AssemblerMacros::LeaveDartFrame(assembler());
+        __ LeaveDartFrame();
         __ Ret();
       } else {
         __ Stop("Wrong number of arguments");
@@ -374,7 +389,9 @@
                                      const ExternalLabel* label,
                                      PcDescriptors::Kind kind,
                                      LocationSummary* locs) {
-  UNIMPLEMENTED();
+  __ BranchLinkPatchable(label);
+  AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos);
+  RecordSafepoint(locs);
 }
 
 
@@ -571,7 +588,6 @@
 
 
 Address FlowGraphCompiler::ExternalElementAddressForIntIndex(
-    intptr_t cid,
     intptr_t index_scale,
     Register array,
     intptr_t index) {
@@ -581,7 +597,6 @@
 
 
 Address FlowGraphCompiler::ExternalElementAddressForRegIndex(
-    intptr_t cid,
     intptr_t index_scale,
     Register array,
     Register index) {
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 138ecf3..76f89b84 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -32,8 +32,8 @@
   // BlockInfos are zone-allocated, so their destructors are not called.
   // Verify the labels explicitly here.
   for (int i = 0; i < block_info_.length(); ++i) {
-    ASSERT(!block_info_[i]->label.IsLinked());
-    ASSERT(!block_info_[i]->label.HasNear());
+    ASSERT(!block_info_[i]->jump_label()->IsLinked());
+    ASSERT(!block_info_[i]->jump_label()->HasNear());
   }
 }
 
@@ -655,8 +655,7 @@
   const int num_params =
       num_fixed_params + num_opt_pos_params + num_opt_named_params;
   ASSERT(function.NumParameters() == num_params);
-  ASSERT(parsed_function().first_parameter_index() ==
-         ParsedFunction::kFirstLocalSlotIndex);
+  ASSERT(parsed_function().first_parameter_index() == kFirstLocalSlotIndex);
 
   // Check that min_num_pos_args <= num_pos_args <= max_num_pos_args,
   // where num_pos_args is the number of positional arguments passed in.
@@ -674,20 +673,19 @@
   __ j(GREATER, &wrong_num_arguments);
 
   // Copy positional arguments.
-  // Argument i passed at fp[1 + num_args - i] is copied
-  // to fp[ParsedFunction::kFirstLocalSlotIndex - i].
+  // Argument i passed at fp[kLastParamSlotIndex + num_args - 1 - i] is copied
+  // to fp[kFirstLocalSlotIndex - i].
 
   __ movl(EBX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
   // Since EBX and ECX are Smi, use TIMES_2 instead of TIMES_4.
   // Let EBX point to the last passed positional argument, i.e. to
-  // fp[1 + num_args - (num_pos_args - 1)].
+  // fp[kLastParamSlotIndex + num_args - 1 - (num_pos_args - 1)].
   __ subl(EBX, ECX);
-  __ leal(EBX, Address(EBP, EBX, TIMES_2, 2 * kWordSize));
+  __ leal(EBX, Address(EBP, EBX, TIMES_2, kLastParamSlotIndex * kWordSize));
 
   // Let EDI point to the last copied positional argument, i.e. to
-  // fp[ParsedFunction::kFirstLocalSlotIndex - (num_pos_args - 1)].
-  const int index = ParsedFunction::kFirstLocalSlotIndex + 1;
-  __ leal(EDI, Address(EBP, (index * kWordSize)));
+  // fp[kFirstLocalSlotIndex - (num_pos_args - 1)].
+  __ leal(EDI, Address(EBP, (kFirstLocalSlotIndex + 1) * kWordSize));
   __ subl(EDI, ECX);  // ECX is a Smi, subtract twice for TIMES_4 scaling.
   __ subl(EDI, ECX);
   __ SmiUntag(ECX);
@@ -764,12 +762,11 @@
               param_pos - num_fixed_params));
       __ LoadObject(EAX, value);
       __ Bind(&assign_optional_parameter);
-      // Assign EAX to fp[ParsedFunction::kFirstLocalSlotIndex - param_pos].
+      // Assign EAX to fp[kFirstLocalSlotIndex - param_pos].
       // We do not use the final allocation index of the variable here, i.e.
       // scope->VariableAt(i)->index(), because captured variables still need
       // to be copied to the context that is not yet allocated.
-      const intptr_t computed_param_pos =
-          ParsedFunction::kFirstLocalSlotIndex - param_pos;
+      const intptr_t computed_param_pos = kFirstLocalSlotIndex - param_pos;
       const Address param_addr(EBP, (computed_param_pos * kWordSize));
       __ movl(param_addr, EAX);
       __ Bind(&next_parameter);
@@ -796,12 +793,11 @@
       const Object& value = Object::ZoneHandle(
           parsed_function().default_parameter_values().At(i));
       __ LoadObject(EAX, value);
-      // Assign EAX to fp[ParsedFunction::kFirstLocalSlotIndex - param_pos].
+      // Assign EAX to fp[kFirstLocalSlotIndex - param_pos].
       // We do not use the final allocation index of the variable here, i.e.
       // scope->VariableAt(i)->index(), because captured variables still need
       // to be copied to the context that is not yet allocated.
-      const intptr_t computed_param_pos =
-          ParsedFunction::kFirstLocalSlotIndex - param_pos;
+      const intptr_t computed_param_pos = kFirstLocalSlotIndex - param_pos;
       const Address param_addr(EBP, (computed_param_pos * kWordSize));
       __ movl(param_addr, EAX);
       __ Bind(&next_parameter);
@@ -924,7 +920,7 @@
                          0);  // No token position.
   }
   __ Comment("Enter frame");
-  AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize));
+  __ EnterDartFrame((StackSize() * kWordSize));
 }
 
 
@@ -1437,7 +1433,7 @@
   assembler()->comisd(left, right);
   BlockEntryInstr* nan_result = (true_condition == NOT_EQUAL) ?
       branch->true_successor() : branch->false_successor();
-  assembler()->j(PARITY_EVEN, GetBlockLabel(nan_result));
+  assembler()->j(PARITY_EVEN, GetJumpLabel(nan_result));
   branch->EmitBranchOnCondition(this, true_condition);
 }
 
@@ -1542,7 +1538,6 @@
 
 
 Address FlowGraphCompiler::ExternalElementAddressForIntIndex(
-    intptr_t cid,
     intptr_t index_scale,
     Register array,
     intptr_t index) {
@@ -1551,18 +1546,10 @@
 
 
 Address FlowGraphCompiler::ExternalElementAddressForRegIndex(
-    intptr_t cid,
     intptr_t index_scale,
     Register array,
     Register index) {
-  switch (cid) {
-    case kExternalUint8ArrayCid:
-    case kExternalUint8ClampedArrayCid:
-      return Address(array, index, ToScaleFactor(index_scale), 0);
-    default:
-      UNIMPLEMENTED();
-      return Address(SPREG, 0);
-  }
+  return Address(array, index, ToScaleFactor(index_scale), 0);
 }
 
 
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index e3c0cd6..b455448 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -15,7 +15,7 @@
   // BlockInfos are zone-allocated, so their destructors are not called.
   // Verify the labels explicitly here.
   for (int i = 0; i < block_info_.length(); ++i) {
-    ASSERT(!block_info_[i]->label.IsLinked());
+    ASSERT(!block_info_[i]->jump_label()->IsLinked());
   }
 }
 
@@ -322,7 +322,6 @@
 
 
 Address FlowGraphCompiler::ExternalElementAddressForIntIndex(
-    intptr_t cid,
     intptr_t index_scale,
     Register array,
     intptr_t index) {
@@ -332,7 +331,6 @@
 
 
 Address FlowGraphCompiler::ExternalElementAddressForRegIndex(
-    intptr_t cid,
     intptr_t index_scale,
     Register array,
     Register index) {
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index 6d62e562..30c751c 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -31,8 +31,8 @@
   // BlockInfos are zone-allocated, so their destructors are not called.
   // Verify the labels explicitly here.
   for (int i = 0; i < block_info_.length(); ++i) {
-    ASSERT(!block_info_[i]->label.IsLinked());
-    ASSERT(!block_info_[i]->label.HasNear());
+    ASSERT(!block_info_[i]->jump_label()->IsLinked());
+    ASSERT(!block_info_[i]->jump_label()->HasNear());
   }
 }
 
@@ -651,8 +651,7 @@
   const int num_params =
       num_fixed_params + num_opt_pos_params + num_opt_named_params;
   ASSERT(function.NumParameters() == num_params);
-  ASSERT(parsed_function().first_parameter_index() ==
-         ParsedFunction::kFirstLocalSlotIndex);
+  ASSERT(parsed_function().first_parameter_index() == kFirstLocalSlotIndex);
 
   // Check that min_num_pos_args <= num_pos_args <= max_num_pos_args,
   // where num_pos_args is the number of positional arguments passed in.
@@ -670,25 +669,24 @@
   __ j(GREATER, &wrong_num_arguments);
 
   // Copy positional arguments.
-  // Argument i passed at fp[1 + num_args - i] is copied
-  // to fp[ParsedFunction::kFirstLocalSlotIndex - i].
+  // Argument i passed at fp[kLastParamSlotIndex + num_args - 1 - i] is copied
+  // to fp[kFirstLocalSlotIndex - i].
 
   __ movq(RBX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
   // Since RBX and RCX are Smi, use TIMES_4 instead of TIMES_8.
   // Let RBX point to the last passed positional argument, i.e. to
-  // fp[1 + num_args - (num_pos_args - 1)].
+  // fp[kLastParamSlotIndex + num_args - 1 - (num_pos_args - 1)].
   __ subq(RBX, RCX);
-  __ leaq(RBX, Address(RBP, RBX, TIMES_4, 2 * kWordSize));
+  __ leaq(RBX, Address(RBP, RBX, TIMES_4, kLastParamSlotIndex * kWordSize));
 
   // Let RDI point to the last copied positional argument, i.e. to
-  // fp[ParsedFunction::kFirstLocalSlotIndex - (num_pos_args - 1)].
-  const int index = ParsedFunction::kFirstLocalSlotIndex + 1;
+  // fp[kFirstLocalSlotIndex - (num_pos_args - 1)].
   __ SmiUntag(RCX);
   __ movq(RAX, RCX);
   __ negq(RAX);
   // -num_pos_args is in RAX.
-  // (ParsedFunction::kFirstLocalSlotIndex + 1) is in index.
-  __ leaq(RDI, Address(RBP, RAX, TIMES_8, (index * kWordSize)));
+  __ leaq(RDI,
+          Address(RBP, RAX, TIMES_8, (kFirstLocalSlotIndex + 1) * kWordSize));
   Label loop, loop_condition;
   __ jmp(&loop_condition, Assembler::kNearJump);
   // We do not use the final allocation index of the variable here, i.e.
@@ -762,12 +760,11 @@
               param_pos - num_fixed_params));
       __ LoadObject(RAX, value);
       __ Bind(&assign_optional_parameter);
-      // Assign RAX to fp[ParsedFunction::kFirstLocalSlotIndex - param_pos].
+      // Assign RAX to fp[kFirstLocalSlotIndex - param_pos].
       // We do not use the final allocation index of the variable here, i.e.
       // scope->VariableAt(i)->index(), because captured variables still need
       // to be copied to the context that is not yet allocated.
-      const intptr_t computed_param_pos =
-          ParsedFunction::kFirstLocalSlotIndex - param_pos;
+      const intptr_t computed_param_pos = kFirstLocalSlotIndex - param_pos;
       const Address param_addr(RBP, (computed_param_pos * kWordSize));
       __ movq(param_addr, RAX);
       __ Bind(&next_parameter);
@@ -794,12 +791,11 @@
       const Object& value = Object::ZoneHandle(
           parsed_function().default_parameter_values().At(i));
       __ LoadObject(RAX, value);
-      // Assign RAX to fp[ParsedFunction::kFirstLocalSlotIndex - param_pos].
+      // Assign RAX to fp[kFirstLocalSlotIndex - param_pos].
       // We do not use the final allocation index of the variable here, i.e.
       // scope->VariableAt(i)->index(), because captured variables still need
       // to be copied to the context that is not yet allocated.
-      const intptr_t computed_param_pos =
-          ParsedFunction::kFirstLocalSlotIndex - param_pos;
+      const intptr_t computed_param_pos = kFirstLocalSlotIndex - param_pos;
       const Address param_addr(RBP, (computed_param_pos * kWordSize));
       __ movq(param_addr, RAX);
       __ Bind(&next_parameter);
@@ -922,7 +918,7 @@
                      0);  // No token position.
   }
   __ Comment("Enter frame");
-  AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize));
+  __ EnterDartFrame((StackSize() * kWordSize));
 }
 
 
@@ -1437,7 +1433,7 @@
   assembler()->comisd(left, right);
   BlockEntryInstr* nan_result = (true_condition == NOT_EQUAL) ?
       branch->true_successor() : branch->false_successor();
-  assembler()->j(PARITY_EVEN, GetBlockLabel(nan_result));
+  assembler()->j(PARITY_EVEN, GetJumpLabel(nan_result));
   branch->EmitBranchOnCondition(this, true_condition);
 }
 
@@ -1542,7 +1538,6 @@
 
 
 Address FlowGraphCompiler::ExternalElementAddressForIntIndex(
-    intptr_t cid,
     intptr_t index_scale,
     Register array,
     intptr_t index) {
@@ -1551,18 +1546,10 @@
 
 
 Address FlowGraphCompiler::ExternalElementAddressForRegIndex(
-    intptr_t cid,
     intptr_t index_scale,
     Register array,
     Register index) {
-  switch (cid) {
-    case kExternalUint8ArrayCid:
-    case kExternalUint8ClampedArrayCid:
-      return Address(array, index, ToScaleFactor(index_scale), 0);
-    default:
-      UNIMPLEMENTED();
-      return Address(SPREG, 0);
-  }
+  return Address(array, index, ToScaleFactor(index_scale), 0);
 }
 
 
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index ebc2053..5de4224 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -436,8 +436,8 @@
       }
 
       // Build the callee graph.
-      InliningContext* inlining_context = InliningContext::Create(call);
-      FlowGraphBuilder builder(*parsed_function, inlining_context);
+      InliningContext inlining_context;
+      FlowGraphBuilder builder(*parsed_function, &inlining_context);
       builder.SetInitialBlockId(caller_graph_->max_block_id());
       FlowGraph* callee_graph;
       {
@@ -559,7 +559,7 @@
                          isolate);
 
         // Plug result in the caller graph.
-        inlining_context->ReplaceCall(caller_graph_, call, callee_graph);
+        inlining_context.ReplaceCall(caller_graph_, call, callee_graph);
 
         // Replace each stub with the actual argument or the caller's constant.
         // Nulls denote optional parameters for which no actual was given.
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 522dee1..345f228 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -692,6 +692,13 @@
 }
 
 
+static bool CanUnboxInt32() {
+  // Int32/Uint32 can be unboxed if it fits into a smi or the platform
+  // supports unboxed mints.
+  return (kSmiBits >= 32) || FlowGraphCompiler::SupportsUnboxedMints();
+}
+
+
 bool FlowGraphOptimizer::TryReplaceWithStoreIndexed(InstanceCallInstr* call) {
   const intptr_t class_id = ReceiverClassId(call);
   ICData& value_check = ICData::ZoneHandle();
@@ -709,6 +716,13 @@
     case kExternalUint8ClampedArrayCid:
     case kInt16ArrayCid:
     case kUint16ArrayCid:
+    case kTypedDataInt8ArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid:
+    case kTypedDataInt16ArrayCid:
+    case kTypedDataUint16ArrayCid:
       // Check that value is always smi.
       value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2);
       if ((value_check.NumberOfChecks() != 1) ||
@@ -717,12 +731,10 @@
       }
       break;
     case kInt32ArrayCid:
-    case kUint32ArrayCid: {
-      // Check if elements fit into a smi or the platform supports unboxed
-      // mints.
-      if ((kSmiBits < 32) && !FlowGraphCompiler::SupportsUnboxedMints()) {
-        return false;
-      }
+    case kUint32ArrayCid:
+    case kTypedDataInt32ArrayCid:
+    case kTypedDataUint32ArrayCid: {
+      if (!CanUnboxInt32()) return false;
       // Check that value is always smi or mint, if the platform has unboxed
       // mints (ia32 with at least SSE 4.1).
       value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2);
@@ -739,7 +751,9 @@
       break;
     }
     case kFloat32ArrayCid:
-    case kFloat64ArrayCid: {
+    case kFloat64ArrayCid:
+    case kTypedDataFloat32ArrayCid:
+    case kTypedDataFloat64ArrayCid: {
       // Check that value is always double.
       value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2);
       if ((value_check.NumberOfChecks() != 1) ||
@@ -779,11 +793,8 @@
     }
     case kInt32ArrayCid:
     case kUint32ArrayCid:
-      // Check if elements fit into a smi or the platform supports unboxed
-      // mints.
-      if ((kSmiBits < 32) && !FlowGraphCompiler::SupportsUnboxedMints()) {
-        return false;
-      }
+      if (!CanUnboxInt32()) return false;
+
       // We don't have ICData for the value stored, so we optimistically assume
       // smis first. If we ever deoptimized here, we require to unbox the value
       // before storing to handle the mint case, too.
@@ -853,12 +864,26 @@
       case kUint16ArrayCid:
       case kInt32ArrayCid:
       case kUint32ArrayCid:
+      case kTypedDataInt8ArrayCid:
+      case kTypedDataUint8ArrayCid:
+      case kTypedDataUint8ClampedArrayCid:
+      case kExternalTypedDataUint8ArrayCid:
+      case kExternalTypedDataUint8ClampedArrayCid:
+      case kTypedDataInt16ArrayCid:
+      case kTypedDataUint16ArrayCid:
+      case kTypedDataInt32ArrayCid:
+      case kTypedDataUint32ArrayCid:
         ASSERT(value_type.IsIntType());
         // Fall through.
       case kFloat32ArrayCid:
-      case kFloat64ArrayCid: {
+      case kFloat64ArrayCid:
+      case kTypedDataFloat32ArrayCid:
+      case kTypedDataFloat64ArrayCid: {
         type_args = instantiator = flow_graph_->constant_null();
-        ASSERT((class_id != kFloat32ArrayCid && class_id != kFloat64ArrayCid) ||
+        ASSERT((class_id != kFloat32ArrayCid &&
+                class_id != kFloat64ArrayCid &&
+                class_id != kTypedDataFloat32ArrayCid &&
+                class_id != kTypedDataFloat64ArrayCid) ||
                value_type.IsDoubleType());
         ASSERT(value_type.IsInstantiated());
         break;
@@ -895,10 +920,12 @@
                   call);
   }
 
+  intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(array_cid);
   Definition* array_op = new StoreIndexedInstr(new Value(array),
                                                new Value(index),
                                                new Value(stored_value),
                                                needs_store_barrier,
+                                               index_scale,
                                                array_cid,
                                                call->deopt_id());
   ReplaceCall(call, array_op);
@@ -923,15 +950,22 @@
     case kExternalUint8ClampedArrayCid:
     case kInt16ArrayCid:
     case kUint16ArrayCid:
+    case kTypedDataFloat32ArrayCid:
+    case kTypedDataFloat64ArrayCid:
+    case kTypedDataInt8ArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid:
+    case kTypedDataInt16ArrayCid:
+    case kTypedDataUint16ArrayCid:
       break;
     case kInt32ArrayCid:
     case kUint32ArrayCid:
-      // Check if elements fit into a smi or the platform supports unboxed
-      // mints.
-      if ((kSmiBits < 32) && !FlowGraphCompiler::SupportsUnboxedMints()) {
-        return false;
-      }
-      {
+    case kTypedDataInt32ArrayCid:
+    case kTypedDataUint32ArrayCid: {
+        if (!CanUnboxInt32()) return false;
+
         // Set deopt_id if we can optimistically assume that the result is Smi.
         // Assume mixed Mint/Smi if this instruction caused deoptimization once.
         ASSERT(call->HasICData());
@@ -946,10 +980,11 @@
   Definition* array = call->ArgumentAt(0);
   Definition* index = call->ArgumentAt(1);
   intptr_t array_cid = PrepareIndexedOp(call, class_id, &array, &index);
+  intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(array_cid);
   Definition* array_op =
       new LoadIndexedInstr(new Value(array),
                            new Value(index),
-                           FlowGraphCompiler::ElementSizeFor(array_cid),
+                           index_scale,
                            array_cid,
                            deopt_id);
   ReplaceCall(call, array_op);
@@ -1328,6 +1363,11 @@
       return Array::length_offset();
     case MethodRecognizer::kByteArrayBaseLength:
       return ByteArray::length_offset();
+    case MethodRecognizer::kTypedDataLength:
+      // .length is defined in _TypedList which is the base class for internal
+      // and external typed data.
+      ASSERT(TypedData::length_offset() == ExternalTypedData::length_offset());
+      return TypedData::length_offset();
     case MethodRecognizer::kGrowableArrayLength:
       return GrowableObjectArray::length_offset();
     default:
@@ -1366,6 +1406,7 @@
     case MethodRecognizer::kObjectArrayLength:
     case MethodRecognizer::kImmutableArrayLength:
     case MethodRecognizer::kByteArrayBaseLength:
+    case MethodRecognizer::kTypedDataLength:
     case MethodRecognizer::kGrowableArrayLength: {
       if (!ic_data.HasOneTarget()) {
         // TODO(srdjan): Implement for mutiple targets.
@@ -1374,7 +1415,8 @@
       const bool is_immutable =
           (recognized_kind == MethodRecognizer::kObjectArrayLength) ||
           (recognized_kind == MethodRecognizer::kImmutableArrayLength) ||
-          (recognized_kind == MethodRecognizer::kByteArrayBaseLength);
+          (recognized_kind == MethodRecognizer::kByteArrayBaseLength) ||
+          (recognized_kind == MethodRecognizer::kTypedDataLength);
       InlineArrayLengthGetter(call,
                               OffsetForLengthGetter(recognized_kind),
                               is_immutable,
@@ -1460,13 +1502,11 @@
 }
 
 
-static bool IsSupportedByteArrayCid(intptr_t cid) {
+static bool IsSupportedByteArrayViewCid(intptr_t cid) {
   switch (cid) {
     case kInt8ArrayCid:
     case kUint8ArrayCid:
     case kUint8ClampedArrayCid:
-    case kExternalUint8ArrayCid:
-    case kExternalUint8ClampedArrayCid:
     case kInt16ArrayCid:
     case kUint16ArrayCid:
     case kInt32ArrayCid:
@@ -1601,57 +1641,177 @@
     }
   }
 
-  if (IsSupportedByteArrayCid(class_ids[0]) &&
+  if (IsSupportedByteArrayViewCid(class_ids[0]) &&
       (ic_data.NumberOfChecks() == 1)) {
-    Definition* array_op = NULL;
+    // For elements that may not fit into a smi on all platforms, check if
+    // elements fit into a smi or the platform supports unboxed mints.
+    if ((recognized_kind == MethodRecognizer::kByteArrayBaseGetInt32) ||
+        (recognized_kind == MethodRecognizer::kByteArrayBaseGetUint32) ||
+        (recognized_kind == MethodRecognizer::kByteArrayBaseSetInt32) ||
+        (recognized_kind == MethodRecognizer::kByteArrayBaseSetUint32)) {
+      if (!CanUnboxInt32()) return false;
+    }
+
     switch (recognized_kind) {
+      // ByteArray getters.
       case MethodRecognizer::kByteArrayBaseGetInt8:
-        array_op = BuildByteArrayViewLoad(call, class_ids[0], kInt8ArrayCid);
-        break;
+        return BuildByteArrayViewLoad(call, class_ids[0], kInt8ArrayCid);
       case MethodRecognizer::kByteArrayBaseGetUint8:
-        array_op = BuildByteArrayViewLoad(call, class_ids[0], kUint8ArrayCid);
-        break;
+        return BuildByteArrayViewLoad(call, class_ids[0], kUint8ArrayCid);
       case MethodRecognizer::kByteArrayBaseGetInt16:
-        array_op = BuildByteArrayViewLoad(call, class_ids[0], kInt16ArrayCid);
-        break;
+        return BuildByteArrayViewLoad(call, class_ids[0], kInt16ArrayCid);
       case MethodRecognizer::kByteArrayBaseGetUint16:
-        array_op = BuildByteArrayViewLoad(call, class_ids[0], kUint16ArrayCid);
-        break;
+        return BuildByteArrayViewLoad(call, class_ids[0], kUint16ArrayCid);
       case MethodRecognizer::kByteArrayBaseGetInt32:
-        // Check if elements fit into a smi or the platform supports unboxed
-        // mints.
-        if ((kSmiBits < 32) && !FlowGraphCompiler::SupportsUnboxedMints()) {
-          return false;
-        }
-        array_op = BuildByteArrayViewLoad(call, class_ids[0], kInt32ArrayCid);
-        break;
+        return BuildByteArrayViewLoad(call, class_ids[0], kInt32ArrayCid);
       case MethodRecognizer::kByteArrayBaseGetUint32:
-        // Check if elements fit into a smi or the platform supports unboxed
-        // mints.
-        if ((kSmiBits < 32) && !FlowGraphCompiler::SupportsUnboxedMints()) {
-          return false;
-        }
-        array_op = BuildByteArrayViewLoad(call, class_ids[0], kUint32ArrayCid);
-        break;
+        return BuildByteArrayViewLoad(call, class_ids[0], kUint32ArrayCid);
       case MethodRecognizer::kByteArrayBaseGetFloat32:
-        array_op = BuildByteArrayViewLoad(call, class_ids[0], kFloat32ArrayCid);
-        break;
+        return BuildByteArrayViewLoad(call, class_ids[0], kFloat32ArrayCid);
       case MethodRecognizer::kByteArrayBaseGetFloat64:
-        array_op = BuildByteArrayViewLoad(call, class_ids[0], kFloat64ArrayCid);
-        break;
+        return BuildByteArrayViewLoad(call, class_ids[0], kFloat64ArrayCid);
+
+      // ByteArray setters.
+      case MethodRecognizer::kByteArrayBaseSetInt8:
+        return BuildByteArrayViewStore(call, class_ids[0], kInt8ArrayCid);
+      case MethodRecognizer::kByteArrayBaseSetUint8:
+        return BuildByteArrayViewStore(call, class_ids[0], kUint8ArrayCid);
+      case MethodRecognizer::kByteArrayBaseSetInt16:
+        return BuildByteArrayViewStore(call, class_ids[0], kInt16ArrayCid);
+      case MethodRecognizer::kByteArrayBaseSetUint16:
+        return BuildByteArrayViewStore(call, class_ids[0], kUint16ArrayCid);
+      case MethodRecognizer::kByteArrayBaseSetInt32:
+        return BuildByteArrayViewStore(call, class_ids[0], kInt32ArrayCid);
+      case MethodRecognizer::kByteArrayBaseSetUint32:
+        return BuildByteArrayViewStore(call, class_ids[0], kUint32ArrayCid);
+      case MethodRecognizer::kByteArrayBaseSetFloat32:
+        return BuildByteArrayViewStore(call, class_ids[0], kFloat32ArrayCid);
+      case MethodRecognizer::kByteArrayBaseSetFloat64:
+        return BuildByteArrayViewStore(call, class_ids[0], kFloat64ArrayCid);
       default:
         // Unsupported method.
         return false;
     }
-    ASSERT(array_op != NULL);
-    ReplaceCall(call, array_op);
-    return true;
   }
   return false;
 }
 
 
-LoadIndexedInstr* FlowGraphOptimizer::BuildByteArrayViewLoad(
+bool FlowGraphOptimizer::BuildByteArrayViewLoad(
+    InstanceCallInstr* call,
+    intptr_t receiver_cid,
+    intptr_t view_cid) {
+  PrepareByteArrayViewOp(call, receiver_cid, view_cid);
+
+  Definition* array = call->ArgumentAt(0);
+  Definition* byte_index = call->ArgumentAt(1);
+
+  // Optimistically build a smi-checked load for Int32 and Uint32
+  // loads on ia32 like we do for normal array loads, and only revert to
+  // mint case after deoptimizing here.
+  intptr_t deopt_id = Isolate::kNoDeoptId;
+  if ((view_cid == kInt32ArrayCid || view_cid == kUint32ArrayCid) &&
+      call->ic_data()->deopt_reason() == kDeoptUnknown) {
+    deopt_id = call->deopt_id();
+  }
+  LoadIndexedInstr* array_op = new LoadIndexedInstr(new Value(array),
+                                                    new Value(byte_index),
+                                                    1,  // Index scale.
+                                                    view_cid,
+                                                    deopt_id);
+  ReplaceCall(call, array_op);
+  return true;
+}
+
+
+bool FlowGraphOptimizer::BuildByteArrayViewStore(
+    InstanceCallInstr* call,
+    intptr_t receiver_cid,
+    intptr_t view_cid) {
+  PrepareByteArrayViewOp(call, receiver_cid, view_cid);
+  ICData& value_check = ICData::ZoneHandle();
+  switch (view_cid) {
+    case kInt8ArrayCid:
+    case kUint8ArrayCid:
+    case kUint8ClampedArrayCid:
+    case kExternalUint8ArrayCid:
+    case kExternalUint8ClampedArrayCid:
+    case kInt16ArrayCid:
+    case kUint16ArrayCid: {
+      // Check that value is always smi.
+      value_check = ICData::New(Function::Handle(),
+                                String::Handle(),
+                                Isolate::kNoDeoptId,
+                                1);
+      value_check.AddReceiverCheck(kSmiCid, Function::Handle());
+      break;
+    }
+    case kInt32ArrayCid:
+    case kUint32ArrayCid:
+      // We don't have ICData for the value stored, so we optimistically assume
+      // smis first. If we ever deoptimized here, we require to unbox the value
+      // before storing to handle the mint case, too.
+      if (call->ic_data()->deopt_reason() == kDeoptUnknown) {
+        value_check = ICData::New(Function::Handle(),
+                                  String::Handle(),
+                                  Isolate::kNoDeoptId,
+                                  1);
+        value_check.AddReceiverCheck(kSmiCid, Function::Handle());
+      }
+      break;
+    case kFloat32ArrayCid:
+    case kFloat64ArrayCid: {
+      // Check that value is always double.
+      value_check = ICData::New(Function::Handle(),
+                                String::Handle(),
+                                Isolate::kNoDeoptId,
+                                1);
+      value_check.AddReceiverCheck(kDoubleCid, Function::Handle());
+      break;
+    }
+    default:
+      // Array cids are already checked in the caller.
+      UNREACHABLE();
+      return NULL;
+  }
+
+  Definition* array = call->ArgumentAt(0);
+  Definition* index = call->ArgumentAt(1);
+  Definition* stored_value = call->ArgumentAt(2);
+  if (!value_check.IsNull()) {
+    AddCheckClass(stored_value, value_check, call->deopt_id(), call->env(),
+                  call);
+  }
+  StoreBarrierType needs_store_barrier = kNoStoreBarrier;
+
+
+  // result = index + bytesPerElement.
+  intptr_t element_size = FlowGraphCompiler::ElementSizeFor(receiver_cid);
+  ConstantInstr* bytes_per_element =
+      new ConstantInstr(Smi::Handle(Smi::New(element_size)));
+  InsertBefore(call, bytes_per_element, NULL, Definition::kValue);
+  BinarySmiOpInstr* result =
+      new BinarySmiOpInstr(Token::kADD,
+                           call,
+                           new Value(index),
+                           new Value(bytes_per_element));
+  InsertBefore(call, result, call->env(), Definition::kValue);
+
+  StoreIndexedInstr* array_op = new StoreIndexedInstr(new Value(array),
+                                                      new Value(index),
+                                                      new Value(stored_value),
+                                                      needs_store_barrier,
+                                                      1,  // Index scale
+                                                      view_cid,
+                                                      call->deopt_id());
+  call->ReplaceUsesWith(result);  // Fix uses of the call's return value.
+  ReplaceCall(call, array_op);
+  array_op->ClearSSATempIndex();  // Store has no uses.
+  return true;
+}
+
+
+void FlowGraphOptimizer::PrepareByteArrayViewOp(
     InstanceCallInstr* call,
     intptr_t receiver_cid,
     intptr_t view_cid) {
@@ -1690,15 +1850,6 @@
                                         call),
                call->env(),
                Definition::kEffect);
-
-  // TODO(fschneider): Optimistically build smi load for Int32 and Uint32
-  // loads on ia32 like we do for normal array loads, and only revert to
-  // mint case after deoptimizing here.
-  return new LoadIndexedInstr(new Value(array),
-                              new Value(byte_index),
-                              1,  // Index scale.
-                              view_cid,
-                              Isolate::kNoDeoptId);  // Can't deoptimize.
 }
 
 
@@ -1790,8 +1941,7 @@
     return;
   }
 
-  if ((op_kind == Token::kASSIGN_INDEX) &&
-      TryReplaceWithStoreIndexed(instr)) {
+  if ((op_kind == Token::kASSIGN_INDEX) && TryReplaceWithStoreIndexed(instr)) {
     return;
   }
   if ((op_kind == Token::kINDEX) && TryReplaceWithLoadIndexed(instr)) {
@@ -3593,6 +3743,13 @@
 }
 
 
+void ConstantPropagator::VisitCatchBlockEntry(CatchBlockEntryInstr* block) {
+  for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
+    it.Current()->Accept(this);
+  }
+}
+
+
 void ConstantPropagator::VisitParallelMove(ParallelMoveInstr* instr) {
   // Parallel moves have not yet been inserted in the graph.
   UNREACHABLE();
@@ -4374,4 +4531,185 @@
 }
 
 
+bool BranchSimplifier::Match(JoinEntryInstr* block) {
+  // Match the pattern of a branch on a comparison whose left operand is a
+  // phi from the same block, and whose right operand is a constant.
+  //
+  //   Branch(Comparison(kind, Phi, Constant))
+  //
+  // These are the branches produced by inlining in a test context.  Also,
+  // the phi and the constant have no other uses so they can simply be
+  // eliminated.  The block has no other phis and no instructions
+  // intervening between the phi, constant, and branch so the block can
+  // simply be eliminated.
+  BranchInstr* branch = block->last_instruction()->AsBranch();
+  ASSERT(branch != NULL);
+  ComparisonInstr* comparison = branch->comparison();
+  Value* left = comparison->left();
+  PhiInstr* phi = left->definition()->AsPhi();
+  Value* right = comparison->right();
+  ConstantInstr* constant = right->definition()->AsConstant();
+  return (phi != NULL) &&
+      (constant != NULL) &&
+      (phi->GetBlock() == block) &&
+      phi->HasOnlyUse(left) &&
+      constant->HasOnlyUse(right) &&
+      (block->next() == constant) &&
+      (constant->next() == branch) &&
+      (block->phis()->length() == 1);
+}
+
+
+JoinEntryInstr* BranchSimplifier::ToJoinEntry(TargetEntryInstr* target) {
+  // Convert a target block into a join block.  Branches will be duplicated
+  // so the former true and false targets become joins of the control flows
+  // from all the duplicated branches.
+  JoinEntryInstr* join =
+      new JoinEntryInstr(target->block_id(), target->try_index());
+  join->LinkTo(target->next());
+  join->set_last_instruction(target->last_instruction());
+  return join;
+}
+
+
+ConstantInstr* BranchSimplifier::CloneConstant(FlowGraph* flow_graph,
+                                               ConstantInstr* constant) {
+  ConstantInstr* new_constant = new ConstantInstr(constant->value());
+  new_constant->set_ssa_temp_index(flow_graph->alloc_ssa_temp_index());
+  return new_constant;
+}
+
+
+BranchInstr* BranchSimplifier::CloneBranch(BranchInstr* branch,
+                                           Value* left,
+                                           Value* right) {
+  ComparisonInstr* comparison = branch->comparison();
+  ComparisonInstr* new_comparison = NULL;
+  if (comparison->IsStrictCompare()) {
+    new_comparison = new StrictCompareInstr(comparison->kind(), left, right);
+  } else if (comparison->IsEqualityCompare()) {
+    new_comparison =
+        new EqualityCompareInstr(comparison->AsEqualityCompare()->token_pos(),
+                                 comparison->kind(),
+                                 left,
+                                 right);
+  } else {
+    ASSERT(comparison->IsRelationalOp());
+    new_comparison =
+        new RelationalOpInstr(comparison->AsRelationalOp()->token_pos(),
+                              comparison->kind(),
+                              left,
+                              right);
+  }
+  return new BranchInstr(new_comparison, branch->is_checked());
+}
+
+
+void BranchSimplifier::Simplify(FlowGraph* flow_graph) {
+  // Optimize some branches that test the value of a phi.  When it is safe
+  // to do so, push the branch to each of the predecessor blocks.  This is
+  // an optimization when (a) it can avoid materializing a boolean object at
+  // the phi only to test its value, and (b) it can expose opportunities for
+  // constant propagation and unreachable code elimination.  This
+  // optimization is intended to run after inlining which creates
+  // opportunities for optimization (a) and before constant folding which
+  // can perform optimization (b).
+
+  // Begin with a worklist of join blocks ending in branches.  They are
+  // candidates for the pattern below.
+  const GrowableArray<BlockEntryInstr*>& postorder = flow_graph->postorder();
+  GrowableArray<BlockEntryInstr*> worklist(postorder.length());
+  for (BlockIterator it(postorder); !it.Done(); it.Advance()) {
+    BlockEntryInstr* block = it.Current();
+    if (block->IsJoinEntry() && block->last_instruction()->IsBranch()) {
+      worklist.Add(block);
+    }
+  }
+
+  // Rewrite until no more instance of the pattern exists.
+  bool changed = false;
+  while (!worklist.is_empty()) {
+    // All blocks in the worklist are join blocks (ending with a branch).
+    JoinEntryInstr* block = worklist.RemoveLast()->AsJoinEntry();
+    ASSERT(block != NULL);
+
+    if (Match(block)) {
+      changed = true;
+
+      // The branch will be copied and pushed to all the join's
+      // predecessors.  Convert the true and false target blocks into join
+      // blocks to join the control flows from all of the true
+      // (respectively, false) targets of the copied branches.
+      //
+      // The converted join block will have no phis, so it cannot be another
+      // instance of the pattern.  There is thus no need to add it to the
+      // worklist.
+      BranchInstr* branch = block->last_instruction()->AsBranch();
+      ASSERT(branch != NULL);
+      JoinEntryInstr* join_true = ToJoinEntry(branch->true_successor());
+      JoinEntryInstr* join_false = ToJoinEntry(branch->false_successor());
+
+      ComparisonInstr* comparison = branch->comparison();
+      PhiInstr* phi = comparison->left()->definition()->AsPhi();
+      ConstantInstr* constant = comparison->right()->definition()->AsConstant();
+      ASSERT(constant != NULL);
+      // Copy the constant and branch and push it to all the predecessors.
+      for (intptr_t i = 0, count = block->PredecessorCount(); i < count; ++i) {
+        GotoInstr* old_goto =
+            block->PredecessorAt(i)->last_instruction()->AsGoto();
+        ASSERT(old_goto != NULL);
+
+        // Insert a copy of the constant in all the predecessors.
+        ConstantInstr* new_constant = CloneConstant(flow_graph, constant);
+        new_constant->InsertBefore(old_goto);
+
+        // Replace the goto in each predecessor with a rewritten branch,
+        // rewritten to use the corresponding phi input instead of the phi.
+        Value* new_left = phi->InputAt(i)->Copy();
+        Value* new_right = new Value(new_constant);
+        BranchInstr* new_branch = CloneBranch(branch, new_left, new_right);
+        new_branch->InsertBefore(old_goto);
+        new_branch->set_next(NULL);  // Detaching the goto from the graph.
+        old_goto->UnuseAllInputs();
+
+        // Update the predecessor block.  We may have created another
+        // instance of the pattern so add it to the worklist if necessary.
+        BlockEntryInstr* branch_block = new_branch->GetBlock();
+        branch_block->set_last_instruction(new_branch);
+        if (branch_block->IsJoinEntry()) worklist.Add(branch_block);
+
+        // Connect the branch to the true and false joins, via empty target
+        // blocks.
+        TargetEntryInstr* true_target =
+            new TargetEntryInstr(flow_graph->max_block_id() + 1,
+                                 block->try_index());
+        TargetEntryInstr* false_target =
+            new TargetEntryInstr(flow_graph->max_block_id() + 2,
+                                 block->try_index());
+        flow_graph->set_max_block_id(flow_graph->max_block_id() + 2);
+        *new_branch->true_successor_address() = true_target;
+        *new_branch->false_successor_address() = false_target;
+        GotoInstr* goto_true = new GotoInstr(join_true);
+        true_target->LinkTo(goto_true);
+        true_target->set_last_instruction(goto_true);
+        GotoInstr* goto_false = new GotoInstr(join_false);
+        false_target->LinkTo(goto_false);
+        false_target->set_last_instruction(goto_false);
+      }
+      // When all predecessors have been rewritten, the original block is
+      // unreachable from the graph.
+      phi->UnuseAllInputs();
+      branch->UnuseAllInputs();
+    }
+  }
+
+  if (changed) {
+    // We may have changed the block order and the dominator tree.
+    flow_graph->DiscoverBlocks();
+    GrowableArray<BitVector*> dominance_frontier;
+    flow_graph->ComputeDominators(&dominance_frontier);
+  }
+}
+
+
 }  // namespace dart
diff --git a/runtime/vm/flow_graph_optimizer.h b/runtime/vm/flow_graph_optimizer.h
index 83515bc..fa6fab8 100644
--- a/runtime/vm/flow_graph_optimizer.h
+++ b/runtime/vm/flow_graph_optimizer.h
@@ -87,9 +87,15 @@
   LoadIndexedInstr* BuildStringCodeUnitAt(InstanceCallInstr* call,
                                           intptr_t cid);
 
-  LoadIndexedInstr* BuildByteArrayViewLoad(InstanceCallInstr* call,
-                                           intptr_t receiver_cid,
-                                           intptr_t view_cid);
+  bool BuildByteArrayViewLoad(InstanceCallInstr* call,
+                              intptr_t receiver_cid,
+                              intptr_t view_cid);
+  bool BuildByteArrayViewStore(InstanceCallInstr* call,
+                               intptr_t receiver_cid,
+                               intptr_t view_cid);
+  void PrepareByteArrayViewOp(InstanceCallInstr* call,
+                              intptr_t receiver_cid,
+                              intptr_t view_cid);
 
   // Insert a check of 'to_check' determined by 'unary_checks'.  If the
   // check fails it will deoptimize to 'deopt_id' using the deoptimization
@@ -260,6 +266,35 @@
 };
 
 
+// Rewrite branches to eliminate materialization of boolean values after
+// inlining, and to expose other optimizations (e.g., constant folding of
+// branches, unreachable code elimination).
+class BranchSimplifier : public AllStatic {
+ public:
+  static void Simplify(FlowGraph* flow_graph);
+
+ private:
+  // Match an instance of the pattern to rewrite.  See the implementation
+  // for the patterns that are handled by this pass.
+  static bool Match(JoinEntryInstr* block);
+
+  // Replace a target entry instruction with a join entry instruction.  Does
+  // not update the original target's predecessors to point to the new block
+  // and does not replace the target in already computed block order lists.
+  static JoinEntryInstr* ToJoinEntry(TargetEntryInstr* target);
+
+  // Duplicate a constant, assigning it a new SSA name.
+  static ConstantInstr* CloneConstant(FlowGraph* flow_graph,
+                                      ConstantInstr* constant);
+
+  // Duplicate a branch while replacing its comparison's left and right
+  // inputs.
+  static BranchInstr* CloneBranch(BranchInstr* branch,
+                                  Value* left,
+                                  Value* right);
+};
+
+
 }  // namespace dart
 
 #endif  // VM_FLOW_GRAPH_OPTIMIZER_H_
diff --git a/runtime/vm/heap_profiler.cc b/runtime/vm/heap_profiler.cc
index 27c7c57..17a1232 100644
--- a/runtime/vm/heap_profiler.cc
+++ b/runtime/vm/heap_profiler.cc
@@ -208,11 +208,17 @@
 
 const RawClass* HeapProfiler::GetSuperClass(const RawClass* raw_class) {
   ASSERT(raw_class != Class::null());
-  const RawType* super_type = raw_class->ptr()->super_type_;
-  if (super_type == Type::null()) {
+  const RawAbstractType* super_type = raw_class->ptr()->super_type_;
+  if (super_type == AbstractType::null()) {
     return Class::null();
   }
-  return reinterpret_cast<const RawClass*>(super_type->ptr()->type_class_);
+  while (super_type->GetClassId() == kBoundedTypeCid) {
+    super_type =
+        reinterpret_cast<const RawBoundedType*>(super_type)->ptr()->type_;
+  }
+  ASSERT(super_type->GetClassId() == kTypeCid);
+  return reinterpret_cast<const RawClass*>(
+      reinterpret_cast<const RawType*>(super_type)->ptr()->type_class_);
 }
 
 
diff --git a/runtime/vm/il_printer.cc b/runtime/vm/il_printer.cc
index d938145..74bc99b 100644
--- a/runtime/vm/il_printer.cc
+++ b/runtime/vm/il_printer.cc
@@ -40,28 +40,27 @@
 }
 
 
+void FlowGraphPrinter::PrintBlock(BlockEntryInstr* block,
+                                  bool print_locations) {
+  // Print the block entry.
+  PrintOneInstruction(block, print_locations);
+  OS::Print("\n");
+  // And all the successors in the block.
+  for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
+    Instruction* current = it.Current();
+    PrintOneInstruction(current, print_locations);
+    OS::Print("\n");
+  }
+}
+
+
 void FlowGraphPrinter::PrintBlocks() {
   if (!function_.IsNull()) {
     OS::Print("==== %s\n", function_.ToFullyQualifiedCString());
   }
 
   for (intptr_t i = 0; i < block_order_.length(); ++i) {
-    // Print the block entry.
-    PrintInstruction(block_order_[i]);
-    // And all the successors until an exit, branch, or a block entry.
-    Instruction* current = block_order_[i];
-    for (ForwardInstructionIterator it(current->AsBlockEntry());
-         !it.Done();
-         it.Advance()) {
-      current = it.Current();
-      OS::Print("\n");
-      PrintInstruction(current);
-    }
-    if (current->next() != NULL) {
-      ASSERT(current->next()->IsBlockEntry());
-      OS::Print(" goto %"Pd"", current->next()->AsBlockEntry()->block_id());
-    }
-    OS::Print("\n");
+    PrintBlock(block_order_[i], print_locations_);
   }
 }
 
@@ -381,14 +380,13 @@
 
 
 void LoadLocalInstr::PrintOperandsTo(BufferFormatter* f) const {
-  f->Print("%s lvl:%"Pd"", local().name().ToCString(), context_level());
+  f->Print("%s", local().name().ToCString());
 }
 
 
 void StoreLocalInstr::PrintOperandsTo(BufferFormatter* f) const {
   f->Print("%s, ", local().name().ToCString());
   value()->PrintTo(f);
-  f->Print(", lvl: %"Pd"", context_level());
 }
 
 
@@ -651,12 +649,16 @@
 
 
 void TargetEntryInstr::PrintTo(BufferFormatter* f) const {
-  f->Print("B%"Pd"[target", block_id());
-  if (IsCatchEntry()) {
-    f->Print(" catch %"Pd"]", catch_try_index());
-  } else {
-    f->Print("]");
+  f->Print("B%"Pd"[target]", block_id());
+  if (HasParallelMove()) {
+    f->Print(" ");
+    parallel_move()->PrintTo(f);
   }
+}
+
+
+void CatchBlockEntryInstr::PrintTo(BufferFormatter* f) const {
+  f->Print("B%"Pd"[target catch %"Pd"]", block_id(), catch_try_index());
   if (HasParallelMove()) {
     f->Print(" ");
     parallel_move()->PrintTo(f);
diff --git a/runtime/vm/il_printer.h b/runtime/vm/il_printer.h
index aaa62b7..77a642f 100644
--- a/runtime/vm/il_printer.h
+++ b/runtime/vm/il_printer.h
@@ -53,6 +53,7 @@
                              const AbstractType& dst_type,
                              const String& dst_name,
                              bool eliminated);
+  static void PrintBlock(BlockEntryInstr* block, bool print_locations);
 
   static void PrintGraph(const char* phase, FlowGraph* flow_graph);
 
diff --git a/runtime/vm/instructions_arm.cc b/runtime/vm/instructions_arm.cc
index 8dab5d9..a57545e 100644
--- a/runtime/vm/instructions_arm.cc
+++ b/runtime/vm/instructions_arm.cc
@@ -5,60 +5,113 @@
 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_ARM.
 #if defined(TARGET_ARCH_ARM)
 
+#include "vm/constants_arm.h"
+#include "vm/cpu.h"
 #include "vm/instructions.h"
 #include "vm/object.h"
 
 namespace dart {
 
-uword InstructionPattern::Back(int n) const {
+CallPattern::CallPattern(uword pc, const Code& code)
+    : end_(reinterpret_cast<uword*>(pc)),
+      target_address_pool_index_(-1),
+      args_desc_load_end_(-1),
+      args_desc_pool_index_(-1),
+      ic_data_load_end_(-1),
+      ic_data_pool_index_(-1),
+      object_pool_(Array::Handle(code.ObjectPool())) {
+  ASSERT(code.ContainsInstructionAt(pc));
+  ASSERT(Back(1) == 0xe12fff3e);  // Last instruction: blx lr
+  Register reg;
+  args_desc_load_end_ =
+      DecodeLoadWordFromPool(1, &reg, &target_address_pool_index_);
+  ASSERT(reg == LR);
+}
+
+
+uword CallPattern::Back(int n) const {
   ASSERT(n > 0);
   return *(end_ - n);
 }
 
 
-CallPattern::CallPattern(uword pc, const Code& code)
-    : InstructionPattern(pc),
-      pool_index_(DecodePoolIndex()),
-      object_pool_(Array::Handle(code.ObjectPool())) { }
-
-
-int CallPattern::DecodePoolIndex() {
-  ASSERT(Back(1) == 0xe12fff3e);  // Last instruction: blx lr
-  // Decode the second to last instruction.
-  uword instr = Back(2);
+// Decodes a load sequence ending at end. Returns the register being loaded and
+// the index in the pool being read from.
+// Returns the location of the load sequence, counting the number of
+// instructions back from the end of the call pattern.
+int CallPattern::DecodeLoadWordFromPool(int end, Register* reg, int* index) {
+  ASSERT(end > 0);
+  uword instr = Back(++end);
   int offset = 0;
-  if ((instr & 0xfffff000) == 0xe59ae000) {  // ldr lr, [pp, #+offset]
+  if ((instr & 0xffff0000) == 0xe59a0000) {  // ldr reg, [pp, #+offset]
     offset = instr & 0xfff;
+    *reg = static_cast<Register>((instr & 0xf000) >> 12);
   } else {
-    ASSERT((instr & 0xfffff000) == 0xe59ee000);  // ldr lr, [lr, #+offset]
+    ASSERT((instr & 0xfff00000) == 0xe5900000);  // ldr reg, [reg, #+offset]
     offset = instr & 0xfff;
-    instr = Back(3);
-    if ((instr & 0xfffff000) == 0xe28ae000) {  // add lr, pp, shifter_op
+    instr = Back(++end);
+    if ((instr & 0xffff0000) == 0xe28a0000) {  // add reg, pp, shifter_op
       const int rot = (instr & 0xf00) * 2;
       const int imm8 = instr & 0xff;
       offset |= (imm8 >> rot) | (imm8 << (32 - rot));
+      *reg = static_cast<Register>((instr & 0xf000) >> 12);
     } else {
-      ASSERT(instr == 0xe08ae00e);  // add lr, pp, lr
-      instr = Back(4);
-      if ((instr & 0xfff0f000) == 0xe340e000) {  // movt lr, offset_hi
+      ASSERT((instr & 0xffff0000) == 0xe08a0000);  // add reg, pp, reg
+      instr = Back(++end);
+      if ((instr & 0xfff00000) == 0xe3400000) {  // movt reg, offset_hi
         offset |= (instr & 0xf0000) << 12;
         offset |= (instr & 0xfff) << 16;
-        instr = Back(5);
+        instr = Back(++end);
       }
-      ASSERT((instr & 0xfff0f000) == 0xe300e000);  // movw lr, offset_lo
+      ASSERT((instr & 0xfff00000) == 0xe3000000);  // movw reg, offset_lo
       ASSERT((offset & 0xffff) == 0);
       offset |= (instr & 0xf0000) >> 4;
       offset |= instr & 0xfff;
+      *reg = static_cast<Register>((instr & 0xf000) >> 12);
     }
   }
   offset += kHeapObjectTag;
   ASSERT(Utils::IsAligned(offset, 4));
-  return (offset - Array::data_offset())/4;
+  *index = (offset - Array::data_offset())/4;
+  return end;
+}
+
+
+RawICData* CallPattern::IcData() {
+  if (ic_data_pool_index_ < 0) {
+    Register reg;
+    // Loading of the argument descriptor must be decoded first, if not already.
+    if (args_desc_pool_index_ < 0) {
+      ic_data_load_end_ = DecodeLoadWordFromPool(
+          args_desc_load_end_, &reg, &args_desc_pool_index_);
+      ASSERT(reg == R4);
+    }
+    DecodeLoadWordFromPool(ic_data_load_end_, &reg, &ic_data_pool_index_);
+    ASSERT(reg == R5);
+  }
+  ICData& ic_data = ICData::Handle();
+  ic_data ^= object_pool_.At(ic_data_pool_index_);
+  return ic_data.raw();
+}
+
+
+RawArray* CallPattern::ArgumentsDescriptor() {
+  if (args_desc_pool_index_ < 0) {
+    Register reg;
+    ic_data_load_end_ = DecodeLoadWordFromPool(
+        args_desc_load_end_, &reg, &args_desc_pool_index_);
+    ASSERT(reg == R4);
+  }
+  Array& args_desc = Array::Handle();
+  args_desc ^= object_pool_.At(args_desc_pool_index_);
+  return args_desc.raw();
 }
 
 
 uword CallPattern::TargetAddress() const {
-  const Object& target_address = Object::Handle(object_pool_.At(pool_index_));
+  ASSERT(target_address_pool_index_ >= 0);
+  const Object& target_address =
+      Object::Handle(object_pool_.At(target_address_pool_index_));
   ASSERT(target_address.IsSmi());
   // The address is stored in the object array as a RawSmi.
   return reinterpret_cast<uword>(target_address.raw());
@@ -69,24 +122,41 @@
   ASSERT(Utils::IsAligned(target_address, 4));
   // The address is stored in the object array as a RawSmi.
   const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(target_address));
-  object_pool_.SetAt(pool_index_, smi);
+  object_pool_.SetAt(target_address_pool_index_, smi);
+  // No need to flush the instruction cache, since the code is not modified.
 }
 
 
+JumpPattern::JumpPattern(uword pc) : pc_(pc) { }
+
+
 bool JumpPattern::IsValid() const {
-  UNIMPLEMENTED();
-  return false;
+  Instr* movw = Instr::At(pc_ + (0 * Instr::kInstrSize));  // movw ip, target_lo
+  Instr* movt = Instr::At(pc_ + (1 * Instr::kInstrSize));  // movw ip, target_lo
+  Instr* bxip = Instr::At(pc_ + (2 * Instr::kInstrSize));  // bx ip
+  return (movw->InstructionBits() & 0xfff0f000) == 0xe300c000 &&
+         (movt->InstructionBits() & 0xfff0f000) == 0xe340c000 &&
+         (bxip->InstructionBits() & 0xffffffff) == 0xe12fff1c;
 }
 
 
 uword JumpPattern::TargetAddress() const {
-  UNIMPLEMENTED();
-  return 0;
+  Instr* movw = Instr::At(pc_ + (0 * Instr::kInstrSize));  // movw ip, target_lo
+  Instr* movt = Instr::At(pc_ + (1 * Instr::kInstrSize));  // movw ip, target_lo
+  uint16_t target_lo = movw->MovwField();
+  uint16_t target_hi = movt->MovwField();
+  return (target_hi << 16) | target_lo;
 }
 
 
-void JumpPattern::SetTargetAddress(uword target) const {
-  UNIMPLEMENTED();
+void JumpPattern::SetTargetAddress(uword target_address) const {
+  uint16_t target_lo = target_address & 0xffff;
+  uint16_t target_hi = target_address >> 16;
+  uword movw = 0xe300c000 | ((target_lo >> 12) << 16) | (target_lo & 0xfff);
+  uword movt = 0xe340c000 | ((target_hi >> 12) << 16) | (target_hi & 0xfff);
+  *reinterpret_cast<uword*>(pc_ + (0 * Instr::kInstrSize)) = movw;
+  *reinterpret_cast<uword*>(pc_ + (1 * Instr::kInstrSize)) = movt;
+  CPU::FlushICache(pc_, 2 * Instr::kInstrSize);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/instructions_arm.h b/runtime/vm/instructions_arm.h
index 0ebac6f..3995c69 100644
--- a/runtime/vm/instructions_arm.h
+++ b/runtime/vm/instructions_arm.h
@@ -10,58 +10,53 @@
 #error Do not include instructions_arm.h directly; use instructions.h instead.
 #endif
 
+#include "vm/constants_arm.h"
 #include "vm/object.h"
 
 namespace dart {
 
-// Abstract class for all instruction pattern classes.
-class InstructionPattern : public ValueObject {
- public:
-  explicit InstructionPattern(uword pc) : end_(reinterpret_cast<uword*>(pc)) {
-    ASSERT(pc != 0);
-  }
-  virtual ~InstructionPattern() { }
-
- protected:
-  uword Back(int n) const;
-
- private:
-  const uword* end_;
-
-  DISALLOW_COPY_AND_ASSIGN(InstructionPattern);
-};
-
-
-class CallPattern : public InstructionPattern {
+class CallPattern : public ValueObject {
  public:
   CallPattern(uword pc, const Code& code);
 
+  RawICData* IcData();
+  RawArray* ArgumentsDescriptor();
+
   uword TargetAddress() const;
   void SetTargetAddress(uword target_address) const;
 
  private:
-  int DecodePoolIndex();
-  const int pool_index_;
+  uword Back(int n) const;
+  int DecodeLoadWordFromPool(int end, Register* reg, int* index);
+  const uword* end_;
+  int target_address_pool_index_;
+  int args_desc_load_end_;
+  int args_desc_pool_index_;
+  int ic_data_load_end_;
+  int ic_data_pool_index_;
   const Array& object_pool_;
 
   DISALLOW_COPY_AND_ASSIGN(CallPattern);
 };
 
 
-class JumpPattern : public InstructionPattern {
+class JumpPattern : public ValueObject {
  public:
-  explicit JumpPattern(uword pc) : InstructionPattern(pc) { }
+  explicit JumpPattern(uword pc);
 
-  static const int kLengthInBytes = 3*kWordSize;
+  static const int kLengthInBytes = 3 * Instr::kInstrSize;
 
   int pattern_length_in_bytes() const {
     return kLengthInBytes;
   }
+
   bool IsValid() const;
   uword TargetAddress() const;
   void SetTargetAddress(uword target_address) const;
 
  private:
+  const uword pc_;
+
   DISALLOW_COPY_AND_ASSIGN(JumpPattern);
 };
 
diff --git a/runtime/vm/instructions_arm_test.cc b/runtime/vm/instructions_arm_test.cc
index cf2e98c..0b23884 100644
--- a/runtime/vm/instructions_arm_test.cc
+++ b/runtime/vm/instructions_arm_test.cc
@@ -16,20 +16,24 @@
 
 ASSEMBLER_TEST_GENERATE(Call, assembler) {
   __ BranchLinkPatchable(&StubCode::InstanceFunctionLookupLabel());
-  // Do not emit any code after the call above, since we decode backwards
-  // starting from the return address, i.e. from the end of this code buffer.
+  __ Ret();
 }
 
 
 ASSEMBLER_TEST_RUN(Call, test) {
-  CallPattern call(test->entry() + test->code().Size(), test->code());
+  // The return address, which must be the address of an instruction contained
+  // in the code, points to the Ret instruction above, i.e. one instruction
+  // before the end of the code buffer.
+  CallPattern call(test->entry() + test->code().Size() - Instr::kInstrSize,
+                   test->code());
   EXPECT_EQ(StubCode::InstanceFunctionLookupLabel().address(),
             call.TargetAddress());
 }
 
 
 ASSEMBLER_TEST_GENERATE(Jump, assembler) {
-  UNIMPLEMENTED();
+  __ BranchPatchable(&StubCode::InstanceFunctionLookupLabel());
+  __ BranchPatchable(&StubCode::AllocateArrayLabel());
 }
 
 
diff --git a/runtime/vm/instructions_ia32.cc b/runtime/vm/instructions_ia32.cc
index cedaab1..0b6a57b 100644
--- a/runtime/vm/instructions_ia32.cc
+++ b/runtime/vm/instructions_ia32.cc
@@ -5,6 +5,7 @@
 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_IA32.
 #if defined(TARGET_ARCH_IA32)
 
+#include "vm/cpu.h"
 #include "vm/instructions.h"
 #include "vm/object.h"
 
@@ -32,6 +33,7 @@
 void CallOrJumpPattern::SetTargetAddress(uword target) const {
   ASSERT(IsValid());
   *reinterpret_cast<uword*>(start() + 1) = target - start() - kLengthInBytes;
+  CPU::FlushICache(start() + 1, kWordSize);
 }
 
 
diff --git a/runtime/vm/instructions_mips.cc b/runtime/vm/instructions_mips.cc
index 5dd5a0b..3bba216 100644
--- a/runtime/vm/instructions_mips.cc
+++ b/runtime/vm/instructions_mips.cc
@@ -5,14 +5,27 @@
 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_MIPS.
 #if defined(TARGET_ARCH_MIPS)
 
+#include "vm/constants_mips.h"
 #include "vm/instructions.h"
 #include "vm/object.h"
 
 namespace dart {
 
-bool InstructionPattern::TestBytesWith(const int* data, int num_bytes) const {
+CallPattern::CallPattern(uword pc, const Code& code)
+    : end_(reinterpret_cast<uword*>(pc)),
+      pool_index_(DecodePoolIndex()),
+      object_pool_(Array::Handle(code.ObjectPool())) { }
+
+
+uword CallPattern::Back(int n) const {
+  ASSERT(n > 0);
+  return *(end_ - n);
+}
+
+
+int CallPattern::DecodePoolIndex() {
   UNIMPLEMENTED();
-  return false;
+  return 0;
 }
 
 
@@ -22,35 +35,30 @@
 }
 
 
+void CallPattern::SetTargetAddress(uword target_address) const {
+  UNIMPLEMENTED();
+}
+
+
+JumpPattern::JumpPattern(uword pc) : pc_(pc) { }
+
+
+bool JumpPattern::IsValid() const {
+  UNIMPLEMENTED();
+  return false;
+}
+
+
 uword JumpPattern::TargetAddress() const {
   UNIMPLEMENTED();
   return 0;
 }
 
 
-
-void CallPattern::SetTargetAddress(uword target) const {
+void JumpPattern::SetTargetAddress(uword target_address) const {
   UNIMPLEMENTED();
 }
 
-
-void JumpPattern::SetTargetAddress(uword target) const {
-  UNIMPLEMENTED();
-}
-
-
-
-const int* CallPattern::pattern() const {
-  UNIMPLEMENTED();
-  return NULL;
-}
-
-
-const int* JumpPattern::pattern() const {
-  UNIMPLEMENTED();
-  return NULL;
-}
-
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_MIPS
diff --git a/runtime/vm/instructions_mips.h b/runtime/vm/instructions_mips.h
index 47400f7..15c5cd3 100644
--- a/runtime/vm/instructions_mips.h
+++ b/runtime/vm/instructions_mips.h
@@ -10,85 +10,45 @@
 #error Do not include instructions_mips.h directly; use instructions.h instead.
 #endif
 
-#include "vm/allocation.h"
+#include "vm/constants_mips.h"
 #include "vm/object.h"
 
 namespace dart {
 
-// Forward declarations.
-class RawClass;
-class Immediate;
-class RawObject;
-
-// Abstract class for all instruction pattern classes.
-class InstructionPattern : public ValueObject {
+class CallPattern : public ValueObject {
  public:
-  explicit InstructionPattern(uword pc) : end_(pc) {
-    ASSERT(pc != 0);
-  }
-  virtual ~InstructionPattern() { }
+  CallPattern(uword pc, const Code& code);
 
-  // Check if the instruction ending at 'end_' matches the expected pattern.
-  virtual bool IsValid() const {
-    return TestBytesWith(pattern(), pattern_length_in_bytes());
-  }
-
-  // 'pattern' returns the expected byte pattern in form of an integer array
-  // with length of 'pattern_length_in_bytes'. A '-1' element means 'any byte'.
-  virtual const int* pattern() const = 0;
-  virtual int pattern_length_in_bytes() const = 0;
-
- protected:
-  uword end() const { return end_; }
-
- private:
-  // Returns true if the 'num_bytes' bytes at 'num_bytes' before 'end_'
-  // correspond to array of integers 'data'. 'data' elements are either a byte
-  // or -1, which represents any byte.
-  bool TestBytesWith(const int* data, int num_bytes) const;
-
-  const uword end_;
-
-  DISALLOW_COPY_AND_ASSIGN(InstructionPattern);
-};
-
-
-class CallPattern : public InstructionPattern {
- public:
-  CallPattern(uword pc, const Code& code)
-      : InstructionPattern(pc), code_(code) { }
-
-  static const int kLengthInBytes = 1*kWordSize;
-
-  virtual int pattern_length_in_bytes() const {
-    return kLengthInBytes;
-  }
   uword TargetAddress() const;
-  void SetTargetAddress(uword new_target) const;
+  void SetTargetAddress(uword target_address) const;
 
  private:
-  virtual const int* pattern() const;
-
-  const Code& code_;
+  uword Back(int n) const;
+  int DecodePoolIndex();
+  const uword* end_;
+  const int pool_index_;
+  const Array& object_pool_;
 
   DISALLOW_COPY_AND_ASSIGN(CallPattern);
 };
 
 
-class JumpPattern : public InstructionPattern {
+class JumpPattern : public ValueObject {
  public:
-  explicit JumpPattern(uword pc) : InstructionPattern(pc) { }
+  explicit JumpPattern(uword pc);
 
-  static const int kLengthInBytes = 3*kWordSize;
+  static const int kLengthInBytes = 3*Instr::kInstrSize;
 
-  virtual int pattern_length_in_bytes() const {
+  int pattern_length_in_bytes() const {
     return kLengthInBytes;
   }
+
+  bool IsValid() const;
   uword TargetAddress() const;
-  void SetTargetAddress(uword new_target) const;
+  void SetTargetAddress(uword target_address) const;
 
  private:
-  virtual const int* pattern() const;
+  const uword pc_;
 
   DISALLOW_COPY_AND_ASSIGN(JumpPattern);
 };
diff --git a/runtime/vm/instructions_x64.cc b/runtime/vm/instructions_x64.cc
index 4bb592ee..62a4aa4 100644
--- a/runtime/vm/instructions_x64.cc
+++ b/runtime/vm/instructions_x64.cc
@@ -5,6 +5,7 @@
 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_X64.
 #if defined(TARGET_ARCH_X64)
 
+#include "vm/cpu.h"
 #include "vm/instructions.h"
 #include "vm/object.h"
 
@@ -32,6 +33,7 @@
 void CallOrJumpPattern::SetTargetAddress(uword target) const {
   ASSERT(IsValid());
   *reinterpret_cast<uword*>(start() + 2) = target;
+  CPU::FlushICache(start() + 2, kWordSize);
 }
 
 
@@ -56,6 +58,7 @@
 void ShortCallPattern::SetTargetAddress(uword target) const {
   ASSERT(IsValid());
   *reinterpret_cast<uint32_t*>(start() + 1) = target - start() - kLengthInBytes;
+  CPU::FlushICache(start() + 1, kWordSize);
 }
 
 
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index dcb64cc..9f87020 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -271,6 +271,7 @@
   // List of libraries where methods can be recognized.
   return (library.raw() == Library::CoreLibrary())
       || (library.raw() == Library::MathLibrary())
+      || (library.raw() == Library::TypedDataLibrary())
       || (library.raw() == Library::ScalarlistLibrary());
 }
 
@@ -497,6 +498,15 @@
 }
 
 
+bool Definition::HasOnlyUse(Value* use) const {
+  if (((input_use_list() == use) && (env_use_list() == NULL)) ||
+      ((input_use_list() == NULL) && (env_use_list() == use))) {
+    return (use->next_use() == NULL);
+  }
+  return false;
+}
+
+
 void Definition::ReplaceUsesWith(Definition* other) {
   ASSERT(other != NULL);
   ASSERT(this != other);
@@ -1103,6 +1113,7 @@
     case MethodRecognizer::kObjectArrayLength:
     case MethodRecognizer::kImmutableArrayLength:
     case MethodRecognizer::kByteArrayBaseLength:
+    case MethodRecognizer::kTypedDataLength:
     case MethodRecognizer::kStringBaseLength:
       return true;
     default:
@@ -1113,6 +1124,10 @@
 
 MethodRecognizer::Kind LoadFieldInstr::RecognizedKindFromArrayCid(
     intptr_t cid) {
+  if (RawObject::IsTypedDataClassId(cid) ||
+      RawObject::IsExternalTypedDataClassId(cid)) {
+    return MethodRecognizer::kTypedDataLength;
+  }
   switch (cid) {
     case kArrayCid:
       return MethodRecognizer::kObjectArrayLength;
@@ -1141,6 +1156,33 @@
 }
 
 
+bool LoadFieldInstr::IsFixedLengthArrayCid(intptr_t cid) {
+  switch (cid) {
+    case kArrayCid:
+    case kImmutableArrayCid:
+    case kInt8ArrayCid:
+    case kUint8ArrayCid:
+    case kUint8ClampedArrayCid:
+    case kInt16ArrayCid:
+    case kUint16ArrayCid:
+    case kInt32ArrayCid:
+    case kUint32ArrayCid:
+    case kInt64ArrayCid:
+    case kUint64ArrayCid:
+    case kFloat32ArrayCid:
+    case kFloat64ArrayCid:
+      return true;
+    default:
+      return false;
+  }
+}
+
+
+Definition* ConstantInstr::Canonicalize(FlowGraphOptimizer* optimizer) {
+  return HasUses() ? this : NULL;
+}
+
+
 Definition* LoadFieldInstr::Canonicalize(FlowGraphOptimizer* optimizer) {
   if (!IsImmutableLengthLoad()) return this;
 
@@ -1148,9 +1190,9 @@
   // call we can replace the length load with the length argument passed to
   // the constructor.
   StaticCallInstr* call = value()->definition()->AsStaticCall();
-  if (call != NULL &&
-      call->is_known_constructor() &&
-      (call->Type()->ToCid() == kArrayCid)) {
+  if ((call != NULL) &&
+      call->is_known_list_constructor() &&
+      IsFixedLengthArrayCid(call->Type()->ToCid())) {
     return call->ArgumentAt(1);
   }
   return this;
@@ -1184,7 +1226,7 @@
     const TypeArguments& instantiator_type_args =
         TypeArguments::Cast(constant_type_args->value());
     const AbstractType& new_dst_type = AbstractType::Handle(
-        dst_type().InstantiateFrom(instantiator_type_args));
+        dst_type().InstantiateFrom(instantiator_type_args, NULL));
     set_dst_type(AbstractType::ZoneHandle(new_dst_type.Canonicalize()));
     ConstantInstr* null_constant = new ConstantInstr(Object::ZoneHandle());
     // It is ok to insert instructions before the current during
@@ -1300,7 +1342,7 @@
 
 
 void JoinEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) {
-  __ Bind(compiler->GetBlockLabel(this));
+  __ Bind(compiler->GetJumpLabel(this));
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
   }
@@ -1308,13 +1350,19 @@
 
 
 void TargetEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) {
-  __ Bind(compiler->GetBlockLabel(this));
-  if (IsCatchEntry()) {
-    compiler->AddExceptionHandler(catch_try_index(),
-                                  try_index(),
-                                  compiler->assembler()->CodeSize(),
-                                  catch_handler_types_);
+  __ Bind(compiler->GetJumpLabel(this));
+  if (HasParallelMove()) {
+    compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
   }
+}
+
+
+void CatchBlockEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) {
+  __ Bind(compiler->GetJumpLabel(this));
+  compiler->AddExceptionHandler(catch_try_index(),
+                                try_index(),
+                                compiler->assembler()->CodeSize(),
+                                catch_handler_types_);
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
   }
@@ -1354,6 +1402,17 @@
 }
 
 
+LocationSummary* CatchBlockEntryInstr::MakeLocationSummary() const {
+  UNREACHABLE();
+  return NULL;
+}
+
+
+void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  UNREACHABLE();
+}
+
+
 LocationSummary* PhiInstr::MakeLocationSummary() const {
   UNREACHABLE();
   return NULL;
@@ -1871,7 +1930,8 @@
     return;
   }
   if ((range_ == NULL) &&
-      (recognized_kind() == MethodRecognizer::kByteArrayBaseLength)) {
+      (recognized_kind() == MethodRecognizer::kByteArrayBaseLength ||
+       recognized_kind() == MethodRecognizer::kTypedDataLength)) {
     range_ = new Range(RangeBoundary::FromConstant(0), RangeBoundary::MaxSmi());
     return;
   }
@@ -1889,6 +1949,7 @@
 void LoadIndexedInstr::InferRange() {
   switch (class_id()) {
     case kInt8ArrayCid:
+    case kTypedDataInt8ArrayCid:
       range_ = new Range(RangeBoundary::FromConstant(-128),
                          RangeBoundary::FromConstant(127));
       break;
@@ -1896,14 +1957,20 @@
     case kUint8ClampedArrayCid:
     case kExternalUint8ArrayCid:
     case kExternalUint8ClampedArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid:
       range_ = new Range(RangeBoundary::FromConstant(0),
                          RangeBoundary::FromConstant(255));
       break;
     case kInt16ArrayCid:
+    case kTypedDataInt16ArrayCid:
       range_ = new Range(RangeBoundary::FromConstant(-32768),
                          RangeBoundary::FromConstant(32767));
       break;
     case kUint16ArrayCid:
+    case kTypedDataUint16ArrayCid:
       range_ = new Range(RangeBoundary::FromConstant(0),
                          RangeBoundary::FromConstant(65535));
       break;
@@ -2095,24 +2162,7 @@
 
 
 bool CheckArrayBoundInstr::IsFixedLengthArrayType(intptr_t cid) {
-  switch (cid) {
-    case kArrayCid:
-    case kImmutableArrayCid:
-    case kInt8ArrayCid:
-    case kUint8ArrayCid:
-    case kUint8ClampedArrayCid:
-    case kInt16ArrayCid:
-    case kUint16ArrayCid:
-    case kInt32ArrayCid:
-    case kUint32ArrayCid:
-    case kInt64ArrayCid:
-    case kUint64ArrayCid:
-    case kFloat32ArrayCid:
-    case kFloat64ArrayCid:
-      return true;
-    default:
-      return false;
-  }
+  return LoadFieldInstr::IsFixedLengthArrayCid(cid);
 }
 
 
@@ -2154,6 +2204,12 @@
 
 
 intptr_t CheckArrayBoundInstr::LengthOffsetFor(intptr_t class_id) {
+  if (RawObject::IsExternalTypedDataClassId(class_id)) {
+    return ExternalTypedData::length_offset();
+  }
+  if (RawObject::IsTypedDataClassId(class_id)) {
+    return TypedData::length_offset();
+  }
   switch (class_id) {
     case kGrowableObjectArrayCid:
       return GrowableObjectArray::length_offset();
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 976fa13..ea7ef86 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -17,6 +17,7 @@
 class BitVector;
 class BlockEntryInstr;
 class BufferFormatter;
+class CatchBlockEntryInstr;
 class ComparisonInstr;
 class ControlInstruction;
 class Definition;
@@ -36,6 +37,7 @@
 #define RECOGNIZED_LIST(V)                                                     \
   V(_ObjectArray, get:length, ObjectArrayLength, 405297088)                    \
   V(_ImmutableArray, get:length, ImmutableArrayLength, 433698233)              \
+  V(_TypedList, get:length, TypedDataLength, 231908172)                        \
   V(_ByteArrayBase, get:length, ByteArrayBaseLength, 1098081765)               \
   V(_ByteArrayBase, _getInt8, ByteArrayBaseGetInt8, 261365835)                 \
   V(_ByteArrayBase, _getUint8, ByteArrayBaseGetUint8, 261365835)               \
@@ -45,6 +47,14 @@
   V(_ByteArrayBase, _getUint32, ByteArrayBaseGetUint32, 261365835)             \
   V(_ByteArrayBase, _getFloat32, ByteArrayBaseGetFloat32, 434247298)           \
   V(_ByteArrayBase, _getFloat64, ByteArrayBaseGetFloat64, 434247298)           \
+  V(_ByteArrayBase, _setInt8, ByteArrayBaseSetInt8, 501962848)                 \
+  V(_ByteArrayBase, _setUint8, ByteArrayBaseSetUint8, 501962848)               \
+  V(_ByteArrayBase, _setInt16, ByteArrayBaseSetInt16, 501962848)               \
+  V(_ByteArrayBase, _setUint16, ByteArrayBaseSetUint16, 501962848)             \
+  V(_ByteArrayBase, _setInt32, ByteArrayBaseSetInt32, 501962848)               \
+  V(_ByteArrayBase, _setUint32, ByteArrayBaseSetUint32, 501962848)             \
+  V(_ByteArrayBase, _setFloat32, ByteArrayBaseSetFloat32, 864506525)           \
+  V(_ByteArrayBase, _setFloat64, ByteArrayBaseSetFloat64, 864506525)           \
   V(_Float32Array, _getIndexed, Float32ArrayGetIndexed, 734006846)             \
   V(_Float64Array, _getIndexed, Float64ArrayGetIndexed, 498074772)             \
   V(_Int8Array, _getIndexed, Int8ArrayGetIndexed, 712069760)                   \
@@ -77,10 +87,10 @@
   V(_StringBase, [], StringBaseCharAt, 1062366987)                             \
   V(_IntegerImplementation, toDouble, IntegerToDouble, 733149324)              \
   V(_Double, toInt, DoubleToInteger, 362666636)                                \
-  V(_Double, truncate, DoubleTruncate, 620870996)                              \
-  V(_Double, round, DoubleRound, 620870996)                                    \
-  V(_Double, floor, DoubleFloor, 620870996)                                    \
-  V(_Double, ceil, DoubleCeil, 620870996)                                      \
+  V(_Double, truncateToDouble, DoubleTruncate, 620870996)                      \
+  V(_Double, roundToDouble, DoubleRound, 620870996)                            \
+  V(_Double, floorToDouble, DoubleFloor, 620870996)                            \
+  V(_Double, ceilToDouble, DoubleCeil, 620870996)                              \
   V(_Double, pow, DoublePow, 1131958048)                                       \
   V(_Double, _modulo, DoubleMod, 437099337)                                    \
   V(::, sqrt, MathSqrt, 1662640002)                                            \
@@ -405,6 +415,7 @@
   M(GraphEntry)                                                                \
   M(JoinEntry)                                                                 \
   M(TargetEntry)                                                               \
+  M(CatchBlockEntry)                                                           \
   M(Phi)                                                                       \
   M(Parameter)                                                                 \
   M(ParallelMove)                                                              \
@@ -563,7 +574,7 @@
   void set_next(Instruction* instr) {
     ASSERT(!IsGraphEntry());
     ASSERT(!IsReturn());
-    ASSERT(!IsControl());
+    ASSERT(!IsControl() || (instr == NULL));
     ASSERT(!IsPhi());
     ASSERT(instr == NULL || !instr->IsBlockEntry());
     // TODO(fschneider): Also add Throw and ReThrow to the list of instructions
@@ -731,6 +742,7 @@
   friend class InvokeMathCFunctionInstr;
   friend class FlowGraphOptimizer;
   friend class LoadIndexedInstr;
+  friend class StoreIndexedInstr;
 
   virtual void RawSetInputAt(intptr_t i, Value* value) = 0;
 
@@ -1077,7 +1089,7 @@
   virtual intptr_t SuccessorCount() const;
   virtual BlockEntryInstr* SuccessorAt(intptr_t index) const;
 
-  void AddCatchEntry(TargetEntryInstr* entry) { catch_entries_.Add(entry); }
+  void AddCatchEntry(CatchBlockEntryInstr* entry) { catch_entries_.Add(entry); }
 
   virtual void PrepareEntry(FlowGraphCompiler* compiler);
 
@@ -1106,7 +1118,7 @@
 
   const ParsedFunction& parsed_function_;
   TargetEntryInstr* normal_entry_;
-  GrowableArray<TargetEntryInstr*> catch_entries_;
+  GrowableArray<CatchBlockEntryInstr*> catch_entries_;
   GrowableArray<Definition*> initial_definitions_;
   intptr_t spill_slot_count_;
 
@@ -1145,7 +1157,7 @@
  private:
   // Classes that have access to predecessors_ when inlining.
   friend class BlockEntryInstr;
-  friend class ValueInliningContext;
+  friend class InliningContext;
 
   // Direct access to phis_ in order to resize it due to phi elimination.
   friend class ConstantPropagator;
@@ -1187,10 +1199,7 @@
 class TargetEntryInstr : public BlockEntryInstr {
  public:
   TargetEntryInstr(intptr_t block_id, intptr_t try_index)
-      : BlockEntryInstr(block_id, try_index),
-        predecessor_(NULL),
-        catch_try_index_(CatchClauseNode::kInvalidTryIndex),
-        catch_handler_types_(Array::ZoneHandle()) { }
+      : BlockEntryInstr(block_id, try_index), predecessor_(NULL) { }
 
   DECLARE_INSTRUCTION(TargetEntry)
 
@@ -1202,22 +1211,6 @@
     return predecessor_;
   }
 
-  // Returns true if this Block is an entry of a catch handler.
-  bool IsCatchEntry() const {
-    return catch_try_index_ != CatchClauseNode::kInvalidTryIndex;
-  }
-
-  // Returns try index for the try block to which this catch handler
-  // corresponds.
-  intptr_t catch_try_index() const {
-    ASSERT(IsCatchEntry());
-    return catch_try_index_;
-  }
-  void set_catch_try_index(intptr_t index) { catch_try_index_ = index; }
-  void set_catch_handler_types(const Array& handler_types) {
-    catch_handler_types_ = handler_types.raw();
-  }
-
   virtual void PrepareEntry(FlowGraphCompiler* compiler);
 
   virtual void PrintTo(BufferFormatter* f) const;
@@ -1232,13 +1225,59 @@
   }
 
   BlockEntryInstr* predecessor_;
-  intptr_t catch_try_index_;
-  Array& catch_handler_types_;
 
   DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr);
 };
 
 
+class CatchBlockEntryInstr : public BlockEntryInstr {
+ public:
+  CatchBlockEntryInstr(intptr_t block_id,
+                       intptr_t try_index,
+                       const Array& handler_types,
+                       intptr_t catch_try_index)
+      : BlockEntryInstr(block_id, try_index),
+        predecessor_(NULL),
+        catch_handler_types_(Array::ZoneHandle(handler_types.raw())),
+        catch_try_index_(catch_try_index) { }
+
+  DECLARE_INSTRUCTION(CatchBlockEntry)
+
+  virtual intptr_t PredecessorCount() const {
+    return (predecessor_ == NULL) ? 0 : 1;
+  }
+  virtual BlockEntryInstr* PredecessorAt(intptr_t index) const {
+    ASSERT((index == 0) && (predecessor_ != NULL));
+    return predecessor_;
+  }
+
+  // Returns try index for the try block to which this catch handler
+  // corresponds.
+  intptr_t catch_try_index() const {
+    return catch_try_index_;
+  }
+
+  virtual void PrepareEntry(FlowGraphCompiler* compiler);
+
+  virtual void PrintTo(BufferFormatter* f) const;
+
+ private:
+  friend class BlockEntryInstr;  // Access to predecessor_ when inlining.
+
+  virtual void ClearPredecessors() { predecessor_ = NULL; }
+  virtual void AddPredecessor(BlockEntryInstr* predecessor) {
+    ASSERT(predecessor_ == NULL);
+    predecessor_ = predecessor;
+  }
+
+  BlockEntryInstr* predecessor_;
+  const Array& catch_handler_types_;
+  const intptr_t catch_try_index_;
+
+  DISALLOW_COPY_AND_ASSIGN(CatchBlockEntryInstr);
+};
+
+
 // Abstract super-class of all instructions that define a value (Bind, Phi).
 class Definition : public Instruction {
  public:
@@ -1312,6 +1351,7 @@
   bool HasUses() const {
     return (input_use_list_ != NULL) || (env_use_list_ != NULL);
   }
+  bool HasOnlyUse(Value* use) const;
 
   Value* input_use_list() const { return input_use_list_; }
   void set_input_use_list(Value* head) { input_use_list_ = head; }
@@ -2033,6 +2073,8 @@
   DECLARE_INSTRUCTION(Constant)
   virtual CompileType ComputeType() const;
 
+  virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer);
+
   const Object& value() const { return value_; }
 
   virtual void PrintOperandsTo(BufferFormatter* f) const;
@@ -2589,7 +2631,7 @@
         argument_names_(argument_names),
         arguments_(arguments),
         result_cid_(kDynamicCid),
-        is_known_constructor_(false) {
+        is_known_list_constructor_(false) {
     ASSERT(function.IsZoneHandle());
     ASSERT(argument_names.IsZoneHandle());
   }
@@ -2615,9 +2657,9 @@
 
   void set_result_cid(intptr_t value) { result_cid_ = value; }
 
-  bool is_known_constructor() const { return is_known_constructor_; }
-  void set_is_known_constructor(bool is_known_constructor) {
-    is_known_constructor_ = is_known_constructor;
+  bool is_known_list_constructor() const { return is_known_list_constructor_; }
+  void set_is_known_list_constructor(bool value) {
+    is_known_list_constructor_ = value;
   }
 
  private:
@@ -2627,8 +2669,8 @@
   ZoneGrowableArray<PushArgumentInstr*>* arguments_;
   intptr_t result_cid_;  // For some library functions we know the result.
 
-  // Some library constructors have known semantics.
-  bool is_known_constructor_;
+  // 'True' for recognized list constructors.
+  bool is_known_list_constructor_;
 
   DISALLOW_COPY_AND_ASSIGN(StaticCallInstr);
 };
@@ -2636,15 +2678,12 @@
 
 class LoadLocalInstr : public TemplateDefinition<0> {
  public:
-  LoadLocalInstr(const LocalVariable& local, intptr_t context_level)
-      : local_(local),
-        context_level_(context_level) { }
+  explicit LoadLocalInstr(const LocalVariable& local) : local_(local) { }
 
   DECLARE_INSTRUCTION(LoadLocal)
   virtual CompileType ComputeType() const;
 
   const LocalVariable& local() const { return local_; }
-  intptr_t context_level() const { return context_level_; }
 
   virtual void PrintOperandsTo(BufferFormatter* f) const;
 
@@ -2657,7 +2696,6 @@
 
  private:
   const LocalVariable& local_;
-  const intptr_t context_level_;
 
   DISALLOW_COPY_AND_ASSIGN(LoadLocalInstr);
 };
@@ -2665,11 +2703,7 @@
 
 class StoreLocalInstr : public TemplateDefinition<1> {
  public:
-  StoreLocalInstr(const LocalVariable& local,
-                  Value* value,
-                  intptr_t context_level)
-      : local_(local),
-        context_level_(context_level) {
+  StoreLocalInstr(const LocalVariable& local, Value* value) : local_(local) {
     SetInputAt(0, value);
   }
 
@@ -2678,7 +2712,6 @@
 
   const LocalVariable& local() const { return local_; }
   Value* value() const { return inputs_[0]; }
-  intptr_t context_level() const { return context_level_; }
 
   virtual void RecordAssignedVars(BitVector* assigned_vars,
                                   intptr_t fixed_parameter_count);
@@ -2694,7 +2727,6 @@
 
  private:
   const LocalVariable& local_;
-  const intptr_t context_level_;
 
   DISALLOW_COPY_AND_ASSIGN(StoreLocalInstr);
 };
@@ -2906,14 +2938,16 @@
                     Value* index,
                     Value* value,
                     StoreBarrierType emit_store_barrier,
+                    intptr_t index_scale,
                     intptr_t class_id,
                     intptr_t deopt_id)
       : emit_store_barrier_(emit_store_barrier),
-        class_id_(class_id),
-        deopt_id_(deopt_id) {
+        index_scale_(index_scale),
+        class_id_(class_id) {
     SetInputAt(0, array);
     SetInputAt(1, index);
     SetInputAt(2, value);
+    deopt_id_ = deopt_id;
   }
 
   DECLARE_INSTRUCTION(StoreIndexed)
@@ -2921,6 +2955,7 @@
   Value* array() const { return inputs_[0]; }
   Value* index() const { return inputs_[1]; }
   Value* value() const { return inputs_[2]; }
+  intptr_t index_scale() const { return index_scale_; }
   intptr_t class_id() const { return class_id_; }
 
   bool ShouldEmitStoreBarrier() const {
@@ -2942,8 +2977,8 @@
 
  private:
   const StoreBarrierType emit_store_barrier_;
+  const intptr_t index_scale_;
   const intptr_t class_id_;
-  const intptr_t deopt_id_;
 
   DISALLOW_COPY_AND_ASSIGN(StoreIndexedInstr);
 };
@@ -3204,6 +3239,8 @@
 
   static MethodRecognizer::Kind RecognizedKindFromArrayCid(intptr_t cid);
 
+  static bool IsFixedLengthArrayCid(intptr_t cid);
+
  private:
   const intptr_t offset_in_bytes_;
   const AbstractType& type_;
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 6ca6c8f..636596d 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -13,6 +13,7 @@
 #include "vm/locations.h"
 #include "vm/object_store.h"
 #include "vm/parser.h"
+#include "vm/simulator.h"
 #include "vm/stub_code.h"
 #include "vm/symbols.h"
 
@@ -65,13 +66,14 @@
   // has its own return instruction. Method that have finally are currently
   // not optimized.
   if (!compiler->HasFinally()) {
+    __ Comment("Stack Check");
+    const int sp_fp_dist = compiler->StackSize() + (-kFirstLocalSlotIndex - 1);
     __ sub(R2, FP, ShifterOperand(SP));
-    // + 1 for saved PP.
-    __ CompareImmediate(R2, (compiler->StackSize() + 1) * kWordSize);
+    __ CompareImmediate(R2, sp_fp_dist * kWordSize);
     __ bkpt(0, NE);
   }
 #endif
-  AssemblerMacros::LeaveDartFrame(compiler->assembler());
+  __ LeaveDartFrame();
   __ Ret();
 
   // Generate 2 NOP instructions so that the debugger can patch the return
@@ -91,13 +93,15 @@
 
 
 LocationSummary* LoadLocalInstr::MakeLocationSummary() const {
-  UNIMPLEMENTED();
-  return NULL;
+  return LocationSummary::Make(0,
+                               Location::RequiresRegister(),
+                               LocationSummary::kNoCall);
 }
 
 
 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+  Register result = locs()->out().reg();
+  __ LoadFromOffset(kLoadWord, result, FP, local().index() * kWordSize);
 }
 
 
@@ -191,13 +195,47 @@
 
 
 LocationSummary* NativeCallInstr::MakeLocationSummary() const {
-  UNIMPLEMENTED();
-  return NULL;
+  const intptr_t kNumInputs = 0;
+  const intptr_t kNumTemps = 3;
+  LocationSummary* locs =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
+  locs->set_temp(0, Location::RegisterLocation(R1));
+  locs->set_temp(1, Location::RegisterLocation(R2));
+  locs->set_temp(2, Location::RegisterLocation(R5));
+  locs->set_out(Location::RegisterLocation(R0));
+  return locs;
 }
 
 
 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+  ASSERT(locs()->temp(0).reg() == R1);
+  ASSERT(locs()->temp(1).reg() == R2);
+  ASSERT(locs()->temp(2).reg() == R5);
+  Register result = locs()->out().reg();
+
+  // Push the result place holder initialized to NULL.
+  __ PushObject(Object::ZoneHandle());
+  // Pass a pointer to the first argument in R2.
+  if (!function().HasOptionalParameters()) {
+    __ AddImmediate(R2, FP, (kLastParamSlotIndex +
+                             function().NumParameters() - 1) * kWordSize);
+  } else {
+    __ AddImmediate(R2, FP, kFirstLocalSlotIndex * kWordSize);
+  }
+  // Compute the effective address. When running under the simulator,
+  // this is a redirection address that forces the simulator to call
+  // into the runtime system.
+  uword entry = reinterpret_cast<uword>(native_c_function());
+#if defined(USING_SIMULATOR)
+  entry = Simulator::RedirectExternalReference(entry, Simulator::kNativeCall);
+#endif
+  __ LoadImmediate(R5, entry);
+  __ LoadImmediate(R1, NativeArguments::ComputeArgcTag(function()));
+  compiler->GenerateCall(token_pos(),
+                         &StubCode::CallNativeCFunctionLabel(),
+                         PcDescriptors::kOther,
+                         locs());
+  __ Pop(result);
 }
 
 
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index 776f6dc..dc963bb 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -83,10 +83,10 @@
   if (!compiler->HasFinally()) {
     __ Comment("Stack Check");
     Label done;
+    const int sp_fp_dist = compiler->StackSize() + (-kFirstLocalSlotIndex - 1);
     __ movl(EDI, EBP);
     __ subl(EDI, ESP);
-    // + 1 for Pc marker.
-    __ cmpl(EDI, Immediate((compiler->StackSize() + 1) * kWordSize));
+    __ cmpl(EDI, Immediate(sp_fp_dist * kWordSize));
     __ j(EQUAL, &done, Assembler::kNearJump);
     __ int3();
     __ Bind(&done);
@@ -732,9 +732,9 @@
   __ pextrd(right_tmp, right, Immediate(1));
   __ cmpl(left_tmp, right_tmp);
   if (branch != NULL) {
-    __ j(hi_cond, compiler->GetBlockLabel(branch->true_successor()));
+    __ j(hi_cond, compiler->GetJumpLabel(branch->true_successor()));
     __ j(FlowGraphCompiler::FlipCondition(hi_cond),
-         compiler->GetBlockLabel(branch->false_successor()));
+         compiler->GetJumpLabel(branch->false_successor()));
   } else {
     __ j(hi_cond, &is_true);
     __ j(FlowGraphCompiler::FlipCondition(hi_cond), &is_false);
@@ -1043,10 +1043,10 @@
   __ PushObject(Object::ZoneHandle());
   // Pass a pointer to the first argument in EAX.
   if (!function().HasOptionalParameters()) {
-    __ leal(EAX, Address(EBP, (1 + function().NumParameters()) * kWordSize));
+    __ leal(EAX, Address(EBP, (kLastParamSlotIndex +
+                               function().NumParameters() - 1) * kWordSize));
   } else {
-    __ leal(EAX,
-            Address(EBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize));
+    __ leal(EAX, Address(EBP, kFirstLocalSlotIndex * kWordSize));
   }
   __ movl(ECX, Immediate(reinterpret_cast<uword>(native_c_function())));
   __ movl(EDX, Immediate(NativeArguments::ComputeArgcTag(function())));
@@ -1102,6 +1102,8 @@
 
     case kFloat32ArrayCid :
     case kFloat64ArrayCid :
+    case kTypedDataFloat32ArrayCid:
+    case kTypedDataFloat64ArrayCid:
       return CompileType::FromCid(kDoubleCid);
 
     case kInt8ArrayCid:
@@ -1111,12 +1113,21 @@
     case kExternalUint8ClampedArrayCid:
     case kInt16ArrayCid:
     case kUint16ArrayCid:
+    case kTypedDataInt8ArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid:
+    case kTypedDataInt16ArrayCid:
+    case kTypedDataUint16ArrayCid:
     case kOneByteStringCid:
     case kTwoByteStringCid:
       return CompileType::FromCid(kSmiCid);
 
     case kInt32ArrayCid:
     case kUint32ArrayCid:
+    case kTypedDataInt32ArrayCid:
+    case kTypedDataUint32ArrayCid:
       // Result can be Smi or Mint when boxed.
       // Instruction can deoptimize if we optimistically assumed that the result
       // fits into Smi.
@@ -1141,16 +1152,27 @@
     case kExternalUint8ClampedArrayCid:
     case kInt16ArrayCid:
     case kUint16ArrayCid:
+    case kTypedDataInt8ArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid:
+    case kTypedDataInt16ArrayCid:
+    case kTypedDataUint16ArrayCid:
     case kOneByteStringCid:
     case kTwoByteStringCid:
       return kTagged;
     case kInt32ArrayCid:
     case kUint32ArrayCid:
+    case kTypedDataInt32ArrayCid:
+    case kTypedDataUint32ArrayCid:
       // Instruction can deoptimize if we optimistically assumed that the result
       // fits into Smi.
       return CanDeoptimize() ? kTagged : kUnboxedMint;
     case kFloat32ArrayCid :
     case kFloat64ArrayCid :
+    case kTypedDataFloat32ArrayCid:
+    case kTypedDataFloat64ArrayCid:
       return kUnboxedDouble;
     default:
       UNIMPLEMENTED();
@@ -1192,14 +1214,15 @@
   Location index = locs()->in(1);
 
   if ((class_id() == kExternalUint8ArrayCid) ||
-      (class_id() == kExternalUint8ClampedArrayCid)) {
+      (class_id() == kExternalUint8ClampedArrayCid) ||
+      (class_id() == kExternalTypedDataUint8ArrayCid) ||
+      (class_id() == kExternalTypedDataUint8ClampedArrayCid)) {
     Register result = locs()->out().reg();
     const Address& element_address = index.IsRegister()
         ? FlowGraphCompiler::ExternalElementAddressForRegIndex(
-            class_id(), index_scale(), result, index.reg())
+            index_scale(), result, index.reg())
         : FlowGraphCompiler::ExternalElementAddressForIntIndex(
-            class_id(), index_scale(), result,
-            Smi::Cast(index.constant()).Value());
+            index_scale(), result, Smi::Cast(index.constant()).Value());
     ASSERT(index_scale() == 1);
     if (index.IsRegister()) {
       __ SmiUntag(index.reg());
@@ -1226,19 +1249,23 @@
     }
     switch (class_id()) {
       case kInt32ArrayCid:
+      case kTypedDataInt32ArrayCid:
         __ movss(result, element_address);
         __ pmovsxdq(result, result);
         break;
       case kUint32ArrayCid:
+      case kTypedDataUint32ArrayCid:
         __ xorpd(result, result);
         __ movss(result, element_address);
         break;
       case kFloat32ArrayCid:
+      case kTypedDataFloat32ArrayCid:
         // Load single precision float and promote to double.
         __ movss(result, element_address);
         __ cvtss2sd(result, locs()->out().fpu_reg());
         break;
       case kFloat64ArrayCid:
+      case kTypedDataFloat64ArrayCid:
         __ movsd(result, element_address);
         break;
     }
@@ -1251,27 +1278,33 @@
   }
   switch (class_id()) {
     case kInt8ArrayCid:
+    case kTypedDataInt8ArrayCid:
+      ASSERT(index_scale() == 1);
+      __ movsxb(result, element_address);
+      __ SmiTag(result);
+      break;
     case kUint8ArrayCid:
     case kUint8ClampedArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
     case kOneByteStringCid:
       ASSERT(index_scale() == 1);
-      if (class_id() == kInt8ArrayCid) {
-        __ movsxb(result, element_address);
-      } else {
-        __ movzxb(result, element_address);
-      }
+      __ movzxb(result, element_address);
       __ SmiTag(result);
       break;
     case kInt16ArrayCid:
+    case kTypedDataInt16ArrayCid:
       __ movsxw(result, element_address);
       __ SmiTag(result);
       break;
     case kUint16ArrayCid:
+    case kTypedDataUint16ArrayCid:
     case kTwoByteStringCid:
       __ movzxw(result, element_address);
       __ SmiTag(result);
       break;
-    case kInt32ArrayCid: {
+    case kInt32ArrayCid:
+    case kTypedDataInt32ArrayCid: {
         Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptInt32Load);
         __ movl(result, element_address);
         // Verify that the signed value in 'result' can fit inside a Smi.
@@ -1280,7 +1313,8 @@
         __ SmiTag(result);
       }
       break;
-    case kUint32ArrayCid: {
+    case kUint32ArrayCid:
+    case kTypedDataUint32ArrayCid: {
         Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptUint32Load);
         __ movl(result, element_address);
         // Verify that the unsigned value in 'result' can fit inside a Smi.
@@ -1310,12 +1344,23 @@
     case kExternalUint8ClampedArrayCid:
     case kInt16ArrayCid:
     case kUint16ArrayCid:
+    case kTypedDataInt8ArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid:
+    case kTypedDataInt16ArrayCid:
+    case kTypedDataUint16ArrayCid:
       return kTagged;
     case kInt32ArrayCid:
     case kUint32ArrayCid:
+    case kTypedDataInt32ArrayCid:
+    case kTypedDataUint32ArrayCid:
       return value()->IsSmiValue() ? kTagged : kUnboxedMint;
     case kFloat32ArrayCid :
     case kFloat64ArrayCid :
+    case kTypedDataFloat32ArrayCid :
+    case kTypedDataFloat64ArrayCid :
       return kUnboxedDouble;
     default:
       UNIMPLEMENTED();
@@ -1332,8 +1377,7 @@
   locs->set_in(0, Location::RequiresRegister());
   // The smi index is either untagged (element size == 1), or it is left smi
   // tagged (for all element sizes > 1).
-  intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(class_id());
-  if (index_scale == 1) {
+  if (index_scale() == 1) {
     locs->set_in(1, CanBeImmediateIndex(index(), class_id())
                       ? Location::Constant(
                           index()->definition()->AsConstant()->value())
@@ -1352,23 +1396,32 @@
       break;
     case kExternalUint8ArrayCid:
     case kExternalUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid:
       // Need temp register to load the external array's data array.
       locs->AddTemp(Location::RequiresRegister());
       // Fall through.
     case kInt8ArrayCid:
     case kUint8ArrayCid:
     case kUint8ClampedArrayCid:
+    case kTypedDataInt8ArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
       // TODO(fschneider): Add location constraint for byte registers (EAX,
       // EBX, ECX, EDX) instead of using a fixed register.
       locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), EAX));
       break;
     case kInt16ArrayCid:
     case kUint16ArrayCid:
+    case kTypedDataInt16ArrayCid:
+    case kTypedDataUint16ArrayCid:
       // Writable register because the value must be untagged before storing.
       locs->set_in(2, Location::WritableRegister());
       break;
     case kInt32ArrayCid:
     case kUint32ArrayCid:
+    case kTypedDataInt32ArrayCid:
+    case kTypedDataUint32ArrayCid:
       // Mints are stored in XMM registers. For smis, use a writable register
       // because the value must be untagged before storing.
       locs->set_in(2, value()->IsSmiValue()
@@ -1376,10 +1429,12 @@
                       : Location::RequiresFpuRegister());
       break;
     case kFloat32ArrayCid:
+    case kTypedDataFloat32ArrayCid:
       // Need temp register for float-to-double conversion.
       locs->AddTemp(Location::RequiresFpuRegister());
       // Fall through.
     case kFloat64ArrayCid:
+    case kTypedDataFloat64ArrayCid:
       // TODO(srdjan): Support Float64 constants.
       locs->set_in(2, Location::RequiresFpuRegister());
       break;
@@ -1395,28 +1450,31 @@
   Register array = locs()->in(0).reg();
   Location index = locs()->in(1);
 
-  intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(class_id());
-
   Address element_address(kNoRegister, 0);
   if ((class_id() == kExternalUint8ArrayCid) ||
-      (class_id() == kExternalUint8ClampedArrayCid)) {
+      (class_id() == kExternalUint8ClampedArrayCid) ||
+      (class_id() == kExternalTypedDataUint8ArrayCid) ||
+      (class_id() == kExternalTypedDataUint8ClampedArrayCid)) {
     Register temp = locs()->temp(0).reg();
     element_address = index.IsRegister()
         ? FlowGraphCompiler::ExternalElementAddressForRegIndex(
-            class_id(), index_scale, temp, index.reg())
+            index_scale(), temp, index.reg())
         : FlowGraphCompiler::ExternalElementAddressForIntIndex(
-            class_id(), index_scale, temp,
-            Smi::Cast(index.constant()).Value());
+            index_scale(), temp, Smi::Cast(index.constant()).Value());
     __ movl(temp,
             FieldAddress(array, ExternalUint8Array::data_offset()));
   } else {
     element_address = index.IsRegister()
         ? FlowGraphCompiler::ElementAddressForRegIndex(
-          class_id(), index_scale, array, index.reg())
+          class_id(), index_scale(), array, index.reg())
         : FlowGraphCompiler::ElementAddressForIntIndex(
-          class_id(), index_scale, array, Smi::Cast(index.constant()).Value());
+          class_id(), index_scale(), array,
+          Smi::Cast(index.constant()).Value());
   }
 
+  if ((index_scale() == 1) && index.IsRegister()) {
+    __ SmiUntag(index.reg());
+  }
   switch (class_id()) {
     case kArrayCid:
       if (ShouldEmitStoreBarrier()) {
@@ -1433,9 +1491,9 @@
     case kInt8ArrayCid:
     case kUint8ArrayCid:
     case kExternalUint8ArrayCid:
-      if (index.IsRegister()) {
-        __ SmiUntag(index.reg());
-      }
+    case kTypedDataInt8ArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ArrayCid:
       if (locs()->in(2).IsConstant()) {
         const Smi& constant = Smi::Cast(locs()->in(2).constant());
         __ movb(element_address,
@@ -1447,10 +1505,9 @@
       }
       break;
     case kUint8ClampedArrayCid:
-    case kExternalUint8ClampedArrayCid: {
-      if (index.IsRegister()) {
-        __ SmiUntag(index.reg());
-      }
+    case kExternalUint8ClampedArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid: {
       if (locs()->in(2).IsConstant()) {
         const Smi& constant = Smi::Cast(locs()->in(2).constant());
         intptr_t value = constant.Value();
@@ -1480,7 +1537,9 @@
       break;
     }
     case kInt16ArrayCid:
-    case kUint16ArrayCid: {
+    case kUint16ArrayCid:
+    case kTypedDataInt16ArrayCid:
+    case kTypedDataUint16ArrayCid: {
       Register value = locs()->in(2).reg();
       __ SmiUntag(value);
       __ movw(element_address, value);
@@ -1488,6 +1547,8 @@
     }
     case kInt32ArrayCid:
     case kUint32ArrayCid:
+    case kTypedDataInt32ArrayCid:
+    case kTypedDataUint32ArrayCid:
       if (value()->IsSmiValue()) {
         ASSERT(RequiredInputRepresentation(2) == kTagged);
         Register value = locs()->in(2).reg();
@@ -1499,12 +1560,14 @@
       }
       break;
     case kFloat32ArrayCid:
+    case kTypedDataFloat32ArrayCid:
       // Convert to single precision.
       __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg());
       // Store.
       __ movss(element_address, locs()->temp(0).fpu_reg());
       break;
     case kFloat64ArrayCid:
+    case kTypedDataFloat64ArrayCid:
       __ movsd(element_address, locs()->in(2).fpu_reg());
       break;
     default:
@@ -2476,11 +2539,10 @@
   Register out_reg = locs()->out().reg();
   XmmRegister value = locs()->in(0).fpu_reg();
 
-  AssemblerMacros::TryAllocate(compiler->assembler(),
-                               compiler->double_class(),
-                               slow_path->entry_label(),
-                               Assembler::kFarJump,
-                               out_reg);
+  __ TryAllocate(compiler->double_class(),
+                 slow_path->entry_label(),
+                 Assembler::kFarJump,
+                 out_reg);
   __ Bind(slow_path->exit_label());
   __ movsd(FieldAddress(out_reg, Double::value_offset()), value);
 }
@@ -3068,8 +3130,7 @@
   __ jmp(&done);
 
   __ Bind(&not_smi);
-  AssemblerMacros::TryAllocate(
-      compiler->assembler(),
+  __ TryAllocate(
       Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()),
       slow_path->entry_label(),
       Assembler::kFarJump,
@@ -3295,8 +3356,8 @@
 
   // We can fall through if the successor is the next block in the list.
   // Otherwise, we need a jump.
-  if (!compiler->IsNextBlock(successor())) {
-    __ jmp(compiler->GetBlockLabel(successor()));
+  if (!compiler->CanFallThroughTo(successor())) {
+    __ jmp(compiler->GetJumpLabel(successor()));
   }
 }
 
@@ -3323,25 +3384,29 @@
 
 void ControlInstruction::EmitBranchOnValue(FlowGraphCompiler* compiler,
                                            bool value) {
-  if (value && compiler->IsNextBlock(false_successor())) {
-    __ jmp(compiler->GetBlockLabel(true_successor()));
-  } else if (!value && compiler->IsNextBlock(true_successor())) {
-    __ jmp(compiler->GetBlockLabel(false_successor()));
+  if (value && !compiler->CanFallThroughTo(true_successor())) {
+    __ jmp(compiler->GetJumpLabel(true_successor()));
+  } else if (!value && !compiler->CanFallThroughTo(false_successor())) {
+    __ jmp(compiler->GetJumpLabel(false_successor()));
   }
 }
 
 
 void ControlInstruction::EmitBranchOnCondition(FlowGraphCompiler* compiler,
                                                Condition true_condition) {
-  if (compiler->IsNextBlock(false_successor())) {
+  if (compiler->CanFallThroughTo(false_successor())) {
     // If the next block is the false successor we will fall through to it.
-    __ j(true_condition, compiler->GetBlockLabel(true_successor()));
+    __ j(true_condition, compiler->GetJumpLabel(true_successor()));
   } else {
     // If the next block is the true successor we negate comparison and fall
     // through to it.
-    ASSERT(compiler->IsNextBlock(true_successor()));
     Condition false_condition = NegateCondition(true_condition);
-    __ j(false_condition, compiler->GetBlockLabel(false_successor()));
+    __ j(false_condition, compiler->GetJumpLabel(false_successor()));
+
+    // Fall through or jump to the true successor.
+    if (!compiler->CanFallThroughTo(true_successor())) {
+      __ jmp(compiler->GetJumpLabel(true_successor()));
+    }
   }
 }
 
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 7d023f8..9f5793f 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -81,11 +81,12 @@
   // has its own return instruction. Method that have finally are currently
   // not optimized.
   if (!compiler->HasFinally()) {
+    __ Comment("Stack Check");
     Label done;
+    const int sp_fp_dist = compiler->StackSize() + (-kFirstLocalSlotIndex - 1);
     __ movq(RDI, RBP);
     __ subq(RDI, RSP);
-    // + 1 for Pc marker.
-    __ cmpq(RDI, Immediate((compiler->StackSize() + 1) * kWordSize));
+    __ cmpq(RDI, Immediate(sp_fp_dist * kWordSize));
     __ j(EQUAL, &done, Assembler::kNearJump);
     __ int3();
     __ Bind(&done);
@@ -908,10 +909,11 @@
   __ PushObject(Object::ZoneHandle());
   // Pass a pointer to the first argument in RAX.
   if (!function().HasOptionalParameters()) {
-    __ leaq(RAX, Address(RBP, (1 + function().NumParameters()) * kWordSize));
+    __ leaq(RAX, Address(RBP, (kLastParamSlotIndex +
+                               function().NumParameters() - 1) * kWordSize));
   } else {
     __ leaq(RAX,
-            Address(RBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize));
+            Address(RBP, kFirstLocalSlotIndex * kWordSize));
   }
   __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function())));
   __ movq(R10, Immediate(NativeArguments::ComputeArgcTag(function())));
@@ -965,8 +967,10 @@
     case kImmutableArrayCid:
       return CompileType::Dynamic();
 
-    case kFloat32ArrayCid :
-    case kFloat64ArrayCid :
+    case kFloat32ArrayCid:
+    case kFloat64ArrayCid:
+    case kTypedDataFloat32ArrayCid:
+    case kTypedDataFloat64ArrayCid:
       return CompileType::FromCid(kDoubleCid);
 
     case kInt8ArrayCid:
@@ -976,10 +980,19 @@
     case kExternalUint8ClampedArrayCid:
     case kInt16ArrayCid:
     case kUint16ArrayCid:
+    case kTypedDataInt8ArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid:
+    case kTypedDataInt16ArrayCid:
+    case kTypedDataUint16ArrayCid:
     case kOneByteStringCid:
     case kTwoByteStringCid:
     case kInt32ArrayCid:
     case kUint32ArrayCid:
+    case kTypedDataInt32ArrayCid:
+    case kTypedDataUint32ArrayCid:
       return CompileType::FromCid(kSmiCid);
 
     default:
@@ -1000,13 +1013,24 @@
     case kExternalUint8ClampedArrayCid:
     case kInt16ArrayCid:
     case kUint16ArrayCid:
+    case kTypedDataInt8ArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid:
+    case kTypedDataInt16ArrayCid:
+    case kTypedDataUint16ArrayCid:
     case kOneByteStringCid:
     case kTwoByteStringCid:
     case kInt32ArrayCid:
     case kUint32ArrayCid:
+    case kTypedDataInt32ArrayCid:
+    case kTypedDataUint32ArrayCid:
       return kTagged;
     case kFloat32ArrayCid :
     case kFloat64ArrayCid :
+    case kTypedDataFloat32ArrayCid:
+    case kTypedDataFloat64ArrayCid:
       return kUnboxedDouble;
     default:
       UNIMPLEMENTED();
@@ -1048,14 +1072,15 @@
   Location index = locs()->in(1);
 
   if ((class_id() == kExternalUint8ArrayCid) ||
-      (class_id() == kExternalUint8ClampedArrayCid)) {
+      (class_id() == kExternalUint8ClampedArrayCid) ||
+      (class_id() == kExternalTypedDataUint8ArrayCid) ||
+      (class_id() == kExternalTypedDataUint8ClampedArrayCid)) {
     Register result = locs()->out().reg();
     Address element_address = index.IsRegister()
         ? FlowGraphCompiler::ExternalElementAddressForRegIndex(
-            class_id(), index_scale(), result, index.reg())
+            index_scale(), result, index.reg())
         : FlowGraphCompiler::ExternalElementAddressForIntIndex(
-            class_id(), index_scale(), result,
-            Smi::Cast(index.constant()).Value());
+            index_scale(), result, Smi::Cast(index.constant()).Value());
     ASSERT(index_scale() == 1);
     if (index.IsRegister()) {
       __ SmiUntag(index.reg());
@@ -1080,13 +1105,15 @@
     }
 
     XmmRegister result = locs()->out().fpu_reg();
-    if (class_id() == kFloat32ArrayCid) {
+    if (class_id() == kFloat32ArrayCid ||
+        class_id() == kTypedDataFloat32ArrayCid) {
       // Load single precision float.
       __ movss(result, element_address);
       // Promote to double.
       __ cvtss2sd(result, locs()->out().fpu_reg());
     } else {
-      ASSERT(class_id() == kFloat64ArrayCid);
+      ASSERT(class_id() == kFloat64ArrayCid ||
+             class_id() == kTypedDataFloat64ArrayCid);
       __ movsd(result, element_address);
     }
     return;
@@ -1098,30 +1125,36 @@
   Register result = locs()->out().reg();
   switch (class_id()) {
     case kInt8ArrayCid:
+    case kTypedDataInt8ArrayCid:
+      __ movsxb(result, element_address);
+      __ SmiTag(result);
+      break;
     case kUint8ArrayCid:
     case kUint8ClampedArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
     case kOneByteStringCid:
-      if (class_id() == kInt8ArrayCid) {
-        __ movsxb(result, element_address);
-      } else {
-        __ movzxb(result, element_address);
-      }
+      __ movzxb(result, element_address);
       __ SmiTag(result);
       break;
     case kInt16ArrayCid:
+    case kTypedDataInt16ArrayCid:
       __ movsxw(result, element_address);
       __ SmiTag(result);
       break;
     case kUint16ArrayCid:
+    case kTypedDataUint16ArrayCid:
     case kTwoByteStringCid:
       __ movzxw(result, element_address);
       __ SmiTag(result);
       break;
     case kInt32ArrayCid:
+    case kTypedDataInt32ArrayCid:
       __ movsxl(result, element_address);
       __ SmiTag(result);
       break;
     case kUint32ArrayCid:
+    case kTypedDataUint32ArrayCid:
       __ movl(result, element_address);
       __ SmiTag(result);
       break;
@@ -1148,9 +1181,20 @@
     case kUint16ArrayCid:
     case kInt32ArrayCid:
     case kUint32ArrayCid:
+    case kTypedDataInt8ArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid:
+    case kTypedDataInt16ArrayCid:
+    case kTypedDataUint16ArrayCid:
+    case kTypedDataInt32ArrayCid:
+    case kTypedDataUint32ArrayCid:
       return kTagged;
-    case kFloat32ArrayCid :
-    case kFloat64ArrayCid :
+    case kFloat32ArrayCid:
+    case kFloat64ArrayCid:
+    case kTypedDataFloat32ArrayCid:
+    case kTypedDataFloat64ArrayCid:
       return kUnboxedDouble;
     default:
       UNIMPLEMENTED();
@@ -1167,8 +1211,7 @@
   locs->set_in(0, Location::RequiresRegister());
   // The smi index is either untagged (element size == 1), or it is left smi
   // tagged (for all element sizes > 1).
-  intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(class_id());
-  if (index_scale == 1) {
+  if (index_scale() == 1) {
     locs->set_in(1, CanBeImmediateIndex(index(), class_id())
                       ? Location::Constant(
                           index()->definition()->AsConstant()->value())
@@ -1187,12 +1230,17 @@
       break;
     case kExternalUint8ArrayCid:
     case kExternalUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid:
       // Need temp register to load the external array's data array.
       locs->AddTemp(Location::RequiresRegister());
       // Fall through.
     case kInt8ArrayCid:
     case kUint8ArrayCid:
     case kUint8ClampedArrayCid:
+    case kTypedDataInt8ArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
       // TODO(fschneider): Add location constraint for byte registers (RAX,
       // RBX, RCX, RDX) instead of using a fixed register.
       locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), RAX));
@@ -1201,14 +1249,20 @@
     case kUint16ArrayCid:
     case kInt32ArrayCid:
     case kUint32ArrayCid:
+    case kTypedDataInt16ArrayCid:
+    case kTypedDataUint16ArrayCid:
+    case kTypedDataInt32ArrayCid:
+    case kTypedDataUint32ArrayCid:
       // Writable register because the value must be untagged before storing.
       locs->set_in(2, Location::WritableRegister());
       break;
     case kFloat32ArrayCid:
+    case kTypedDataFloat32ArrayCid:
       // Need temp register for float-to-double conversion.
       locs->AddTemp(Location::RequiresFpuRegister());
       // Fall through.
     case kFloat64ArrayCid:
+    case kTypedDataFloat64ArrayCid:
       // TODO(srdjan): Support Float64 constants.
       locs->set_in(2, Location::RequiresFpuRegister());
       break;
@@ -1224,28 +1278,31 @@
   Register array = locs()->in(0).reg();
   Location index = locs()->in(1);
 
-  intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(class_id());
   Address element_address(kNoRegister, 0);
   if ((class_id() == kExternalUint8ArrayCid) ||
-      (class_id() == kExternalUint8ClampedArrayCid)) {
+      (class_id() == kExternalUint8ClampedArrayCid) ||
+      (class_id() == kExternalTypedDataUint8ArrayCid) ||
+      (class_id() == kExternalTypedDataUint8ClampedArrayCid)) {
     Register temp = locs()->temp(0).reg();
     element_address = index.IsRegister()
         ? FlowGraphCompiler::ExternalElementAddressForRegIndex(
-            class_id(), index_scale, temp, index.reg())
+            index_scale(), temp, index.reg())
         : FlowGraphCompiler::ExternalElementAddressForIntIndex(
-            class_id(), index_scale, temp,
-            Smi::Cast(index.constant()).Value());
+            index_scale(), temp, Smi::Cast(index.constant()).Value());
     __ movq(temp,
             FieldAddress(array, ExternalUint8Array::data_offset()));
   } else {
     element_address = index.IsRegister()
         ? FlowGraphCompiler::ElementAddressForRegIndex(
-            class_id(), index_scale, array, index.reg())
+            class_id(), index_scale(), array, index.reg())
         : FlowGraphCompiler::ElementAddressForIntIndex(
-            class_id(), index_scale, array,
+            class_id(), index_scale(), array,
             Smi::Cast(index.constant()).Value());
   }
 
+  if ((index_scale() == 1) && index.IsRegister()) {
+    __ SmiUntag(index.reg());
+  }
   switch (class_id()) {
     case kArrayCid:
       if (ShouldEmitStoreBarrier()) {
@@ -1262,9 +1319,9 @@
     case kInt8ArrayCid:
     case kUint8ArrayCid:
     case kExternalUint8ArrayCid:
-      if (index.IsRegister()) {
-        __ SmiUntag(index.reg());
-      }
+    case kTypedDataInt8ArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ArrayCid:
       if (locs()->in(2).IsConstant()) {
         const Smi& constant = Smi::Cast(locs()->in(2).constant());
         __ movb(element_address,
@@ -1276,10 +1333,9 @@
       }
       break;
     case kUint8ClampedArrayCid:
-    case kExternalUint8ClampedArrayCid: {
-      if (index.IsRegister()) {
-        __ SmiUntag(index.reg());
-      }
+    case kExternalUint8ClampedArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid: {
       if (locs()->in(2).IsConstant()) {
         const Smi& constant = Smi::Cast(locs()->in(2).constant());
         intptr_t value = constant.Value();
@@ -1309,26 +1365,32 @@
       break;
     }
     case kInt16ArrayCid:
-    case kUint16ArrayCid: {
+    case kUint16ArrayCid:
+    case kTypedDataInt16ArrayCid:
+    case kTypedDataUint16ArrayCid: {
       Register value = locs()->in(2).reg();
       __ SmiUntag(value);
       __ movw(element_address, value);
       break;
     }
     case kInt32ArrayCid:
-    case kUint32ArrayCid: {
+    case kUint32ArrayCid:
+    case kTypedDataInt32ArrayCid:
+    case kTypedDataUint32ArrayCid: {
       Register value = locs()->in(2).reg();
       __ SmiUntag(value);
       __ movl(element_address, value);
         break;
     }
     case kFloat32ArrayCid:
+    case kTypedDataFloat32ArrayCid:
       // Convert to single precision.
       __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg());
       // Store.
       __ movss(element_address, locs()->temp(0).fpu_reg());
       break;
     case kFloat64ArrayCid:
+    case kTypedDataFloat64ArrayCid:
       __ movsd(element_address, locs()->in(2).fpu_reg());
       break;
     default:
@@ -2319,11 +2381,10 @@
   Register out_reg = locs()->out().reg();
   XmmRegister value = locs()->in(0).fpu_reg();
 
-  AssemblerMacros::TryAllocate(compiler->assembler(),
-                               compiler->double_class(),
-                               slow_path->entry_label(),
-                               Assembler::kFarJump,
-                               out_reg);
+  __ TryAllocate(compiler->double_class(),
+                 slow_path->entry_label(),
+                 Assembler::kFarJump,
+                 out_reg);
   __ Bind(slow_path->exit_label());
   __ movsd(FieldAddress(out_reg, Double::value_offset()), value);
 }
@@ -2898,8 +2959,8 @@
 
   // We can fall through if the successor is the next block in the list.
   // Otherwise, we need a jump.
-  if (!compiler->IsNextBlock(successor())) {
-    __ jmp(compiler->GetBlockLabel(successor()));
+  if (!compiler->CanFallThroughTo(successor())) {
+    __ jmp(compiler->GetJumpLabel(successor()));
   }
 }
 
@@ -2926,25 +2987,29 @@
 
 void ControlInstruction::EmitBranchOnValue(FlowGraphCompiler* compiler,
                                            bool value) {
-  if (value && compiler->IsNextBlock(false_successor())) {
-    __ jmp(compiler->GetBlockLabel(true_successor()));
-  } else if (!value && compiler->IsNextBlock(true_successor())) {
-    __ jmp(compiler->GetBlockLabel(false_successor()));
+  if (value && !compiler->CanFallThroughTo(true_successor())) {
+    __ jmp(compiler->GetJumpLabel(true_successor()));
+  } else if (!value && !compiler->CanFallThroughTo(false_successor())) {
+    __ jmp(compiler->GetJumpLabel(false_successor()));
   }
 }
 
 
 void ControlInstruction::EmitBranchOnCondition(FlowGraphCompiler* compiler,
                                                Condition true_condition) {
-  if (compiler->IsNextBlock(false_successor())) {
+  if (compiler->CanFallThroughTo(false_successor())) {
     // If the next block is the false successor we will fall through to it.
-    __ j(true_condition, compiler->GetBlockLabel(true_successor()));
+    __ j(true_condition, compiler->GetJumpLabel(true_successor()));
   } else {
     // If the next block is the true successor we negate comparison and fall
     // through to it.
-    ASSERT(compiler->IsNextBlock(true_successor()));
     Condition false_condition = NegateCondition(true_condition);
-    __ j(false_condition, compiler->GetBlockLabel(false_successor()));
+    __ j(false_condition, compiler->GetJumpLabel(false_successor()));
+
+    // Fall through or jump to the true successor.
+    if (!compiler->CanFallThroughTo(true_successor())) {
+      __ jmp(compiler->GetJumpLabel(true_successor()));
+    }
   }
 }
 
diff --git a/runtime/vm/intrinsifier.cc b/runtime/vm/intrinsifier.cc
index aa78b99..1908db6 100644
--- a/runtime/vm/intrinsifier.cc
+++ b/runtime/vm/intrinsifier.cc
@@ -127,6 +127,10 @@
   lib = Library::ScalarlistLibrary();
   SCALARLIST_LIB_INTRINSIC_LIST(SETUP_FUNCTION);
 
+  // Set up all dart:typeddata lib functions that can be intrisified.
+  lib = Library::TypedDataLibrary();
+  TYPEDDATA_LIB_INTRINSIC_LIST(SETUP_FUNCTION);
+
 #undef SETUP_FUNCTION
 }
 
@@ -149,6 +153,8 @@
 
   if (lib.raw() == Library::CoreLibrary()) {
     CORE_LIB_INTRINSIC_LIST(FIND_INTRINSICS);
+  } else if (lib.raw() == Library::TypedDataLibrary()) {
+    TYPEDDATA_LIB_INTRINSIC_LIST(FIND_INTRINSICS);
   } else if (lib.raw() == Library::ScalarlistLibrary()) {
     SCALARLIST_LIB_INTRINSIC_LIST(FIND_INTRINSICS);
   } else if (lib.raw() == Library::MathLibrary()) {
diff --git a/runtime/vm/intrinsifier.h b/runtime/vm/intrinsifier.h
index 16b3893..5c0aee9 100644
--- a/runtime/vm/intrinsifier.h
+++ b/runtime/vm/intrinsifier.h
@@ -88,8 +88,12 @@
   V(::, cos, Math_cos, 1749547468)                                             \
 
 
+// Note that any intrinsified function is not inlined. Some optimizations
+// rely on seeing the factories below instead of their inlined code.
 #define SCALARLIST_LIB_INTRINSIC_LIST(V)                                       \
   V(_ByteArrayBase, get:length, ByteArrayBase_getLength, 1098081765)           \
+  V(_Int64Array, [], Int64Array_getIndexed, 504894128)                         \
+  V(_Uint64Array, [], Uint64Array_getIndexed, 31272531)                        \
   V(_Int8Array, _new, Int8Array_new, 535958453)                                \
   V(_Uint8Array, _new, Uint8Array_new, 604355565)                              \
   V(_Uint8ClampedArray, _new, Uint8ClampedArray_new, 1070949952)               \
@@ -97,13 +101,46 @@
   V(_Uint16Array, _new, Uint16Array_new, 133542762)                            \
   V(_Int32Array, _new, Int32Array_new, 8218286)                                \
   V(_Uint32Array, _new, Uint32Array_new, 469402161)                            \
-  V(_Int64Array, [], Int64Array_getIndexed, 504894128)                         \
   V(_Int64Array, _new, Int64Array_new, 60605075)                               \
-  V(_Uint64Array, [], Uint64Array_getIndexed, 31272531)                        \
   V(_Uint64Array, _new, Uint64Array_new, 624354107)                            \
   V(_Float32Array, _new, Float32Array_new, 109944959)                          \
   V(_Float64Array, _new, Float64Array_new, 147668392)                          \
+  V(Int8List, ., Int8Array_factory, 817410959)                                 \
+  V(Uint8List, ., Uint8Array_factory, 220896178)                               \
+  V(Uint8ClampedList, ., Uint8ClampedArray_factory, 422034060)                 \
+  V(Int16List, ., Int16Array_factory, 214246025)                               \
+  V(Uint16List, ., Uint16Array_factory, 137929963)                             \
+  V(Int32List, ., Int32Array_factory, 1977571010)                              \
+  V(Uint32List, ., Uint32Array_factory, 407638944)                             \
+  V(Int64List, ., Int64Array_factory, 885130273)                               \
+  V(Uint64List, ., Uint64Array_factory, 1471017221)                            \
+  V(Float32List, ., Float32Array_factory, 2035252095)                          \
+  V(Float64List, ., Float64Array_factory, 1037441059)                          \
 
+#define TYPEDDATA_LIB_INTRINSIC_LIST(V)                                        \
+  V(_TypedList, get:length, TypedData_getLength, 231908172)                    \
+  V(_Int8Array, _new, TypedData_Int8Array_new, 844274443)                      \
+  V(_Uint8Array, _new, TypedData_Uint8Array_new, 997951645)                    \
+  V(_Uint8ClampedArray, _new, TypedData_Uint8ClampedArray_new, 1025045044)     \
+  V(_Int16Array, _new, TypedData_Int16Array_new, 1064563368)                   \
+  V(_Uint16Array, _new, TypedData_Uint16Array_new, 110927177)                  \
+  V(_Int32Array, _new, TypedData_Int32Array_new, 770802406)                    \
+  V(_Uint32Array, _new, TypedData_Uint32Array_new, 856841876)                  \
+  V(_Int64Array, _new, TypedData_Int64Array_new, 941769528)                    \
+  V(_Uint64Array, _new, TypedData_Uint64Array_new, 977566635)                  \
+  V(_Float32Array, _new, TypedData_Float32Array_new, 1053133615)               \
+  V(_Float64Array, _new, TypedData_Float64Array_new, 936673303)                \
+  V(_Int8Array, ., TypedData_Int8Array_factory, 1852699666)                    \
+  V(_Uint8Array, ., TypedData_Uint8Array_factory, 1014667000)                  \
+  V(_Uint8ClampedArray, ., TypedData_Uint8ClampedArray_factory, 519376744)     \
+  V(_Int16Array, ., TypedData_Int16Array_factory, 1069515268)                  \
+  V(_Uint16Array, ., TypedData_Uint16Array_factory, 1892182763)                \
+  V(_Int32Array, ., TypedData_Int32Array_factory, 1724127394)                  \
+  V(_Uint32Array, ., TypedData_Uint32Array_factory, 1251657079)                \
+  V(_Int64Array, ., TypedData_Int64Array_factory, 1922050636)                  \
+  V(_Uint64Array, ., TypedData_Uint64Array_factory, 1279581075)                \
+  V(_Float32Array, ., TypedData_Float32Array_factory, 112704438)               \
+  V(_Float64Array, ., TypedData_Float64Array_factory, 41426340)                \
 
 // TODO(srdjan): Implement _FixedSizeArrayIterator, get:current and
 //   _FixedSizeArrayIterator, moveNext.
@@ -128,6 +165,7 @@
   CORE_LIB_INTRINSIC_LIST(DECLARE_FUNCTION)
   MATH_LIB_INTRINSIC_LIST(DECLARE_FUNCTION)
   SCALARLIST_LIB_INTRINSIC_LIST(DECLARE_FUNCTION)
+  TYPEDDATA_LIB_INTRINSIC_LIST(DECLARE_FUNCTION)
 
 #undef DECLARE_FUNCTION
 };
diff --git a/runtime/vm/intrinsifier_arm.cc b/runtime/vm/intrinsifier_arm.cc
index 2905a38..a1b756e 100644
--- a/runtime/vm/intrinsifier_arm.cc
+++ b/runtime/vm/intrinsifier_arm.cc
@@ -6,6 +6,7 @@
 #if defined(TARGET_ARCH_ARM)
 
 #include "vm/intrinsifier.h"
+#include "vm/object.h"
 
 namespace dart {
 
@@ -89,36 +90,71 @@
 }
 
 
+bool Intrinsifier::Int8Array_factory(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Uint8Array_new(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Uint8Array_factory(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Uint8ClampedArray_new(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Uint8ClampedArray_factory(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Int16Array_new(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Int16Array_factory(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Uint16Array_new(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Uint16Array_factory(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Int32Array_new(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Int32Array_factory(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Uint32Array_new(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Uint32Array_factory(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Int64Array_getIndexed(Assembler* assembler) {
   return false;
 }
@@ -129,6 +165,11 @@
 }
 
 
+bool Intrinsifier::Int64Array_factory(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Uint64Array_getIndexed(Assembler* assembler) {
   return false;
 }
@@ -139,16 +180,47 @@
 }
 
 
+bool Intrinsifier::Uint64Array_factory(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Float32Array_new(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Float32Array_factory(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Float64Array_new(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Float64Array_factory(Assembler* assembler) {
+  return false;
+}
+
+
+bool Intrinsifier::TypedData_getLength(Assembler* assembler) {
+  return true;
+}
+
+
+#define TYPEDDATA_ALLOCATOR(clazz)                                             \
+bool Intrinsifier::TypedData_##clazz##_new(Assembler* assembler) {             \
+  return false;                                                                \
+}                                                                              \
+bool Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler) {         \
+  return false;                                                                \
+}
+CLASS_LIST_TYPED_DATA(TYPEDDATA_ALLOCATOR)
+#undef TYPEDDATA_ALLOCATOR
+
+
 bool Intrinsifier::Integer_addFromInteger(Assembler* assembler) {
   return false;
 }
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index c25075d..db68d84 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -14,7 +14,6 @@
 #include "vm/intrinsifier.h"
 
 #include "vm/assembler.h"
-#include "vm/assembler_macros.h"
 #include "vm/object.h"
 #include "vm/object_store.h"
 #include "vm/os.h"
@@ -468,7 +467,7 @@
 }
 
 
-#define TYPED_ARRAY_ALLOCATION(type_name, scale_factor)                        \
+#define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_factor)          \
   Label fall_through;                                                          \
   const intptr_t kArrayLengthStackOffset = 1 * kWordSize;                      \
   __ movl(EDI, Address(ESP, kArrayLengthStackOffset));  /* Array length. */    \
@@ -481,7 +480,7 @@
   __ SmiUntag(EDI);                                                            \
   /* Check for maximum allowed length. */                                      \
   /* EDI: untagged array length. */                                            \
-  __ cmpl(EDI, Immediate(type_name::kMaxElements));                            \
+  __ cmpl(EDI, Immediate(max_len));                                            \
   __ j(GREATER, &fall_through);                                                \
   const intptr_t fixed_size = sizeof(Raw##type_name) + kObjectAlignment - 1;   \
   __ leal(EDI, Address(EDI, scale_factor, fixed_size));                        \
@@ -523,7 +522,7 @@
     __ Bind(&done);                                                            \
                                                                                \
     /* Get the class index and insert it into the tags. */                     \
-    __ orl(EDI, Immediate(RawObject::ClassIdTag::encode(k##type_name##Cid)));  \
+    __ orl(EDI, Immediate(RawObject::ClassIdTag::encode(cid)));                \
     __ movl(FieldAddress(EAX, type_name::tags_offset()), EDI);  /* Tags. */    \
   }                                                                            \
   /* Set the length field. */                                                  \
@@ -554,46 +553,28 @@
   __ Bind(&fall_through);                                                      \
 
 
-bool Intrinsifier::Int8Array_new(Assembler* assembler) {
-  TYPED_ARRAY_ALLOCATION(Int8Array, TIMES_1);
-  return false;
+#define SCALARLIST_ALLOCATOR(clazz, scale)                                     \
+bool Intrinsifier::clazz##_new(Assembler* assembler) {                         \
+  TYPED_ARRAY_ALLOCATION(clazz, k##clazz##Cid, clazz::kMaxElements, scale);    \
+  return false;                                                                \
+}                                                                              \
+bool Intrinsifier::clazz##_factory(Assembler* assembler) {                     \
+  TYPED_ARRAY_ALLOCATION(clazz, k##clazz##Cid, clazz::kMaxElements, scale);    \
+  return false;                                                                \
 }
 
 
-bool Intrinsifier::Uint8Array_new(Assembler* assembler) {
-  TYPED_ARRAY_ALLOCATION(Uint8Array, TIMES_1);
-  return false;
-}
-
-
-bool Intrinsifier::Uint8ClampedArray_new(Assembler* assembler) {
-  TYPED_ARRAY_ALLOCATION(Uint8ClampedArray, TIMES_1);
-  return false;
-}
-
-
-bool Intrinsifier::Int16Array_new(Assembler* assembler) {
-  TYPED_ARRAY_ALLOCATION(Int16Array, TIMES_2);
-  return false;
-}
-
-
-bool Intrinsifier::Uint16Array_new(Assembler* assembler) {
-  TYPED_ARRAY_ALLOCATION(Uint16Array, TIMES_2);
-  return false;
-}
-
-
-bool Intrinsifier::Int32Array_new(Assembler* assembler) {
-  TYPED_ARRAY_ALLOCATION(Int32Array, TIMES_4);
-  return false;
-}
-
-
-bool Intrinsifier::Uint32Array_new(Assembler* assembler) {
-  TYPED_ARRAY_ALLOCATION(Uint32Array, TIMES_4);
-  return false;
-}
+SCALARLIST_ALLOCATOR(Int8Array, TIMES_1)
+SCALARLIST_ALLOCATOR(Uint8Array, TIMES_1)
+SCALARLIST_ALLOCATOR(Uint8ClampedArray, TIMES_1)
+SCALARLIST_ALLOCATOR(Int16Array, TIMES_2)
+SCALARLIST_ALLOCATOR(Uint16Array, TIMES_2)
+SCALARLIST_ALLOCATOR(Int32Array, TIMES_4)
+SCALARLIST_ALLOCATOR(Uint32Array, TIMES_4)
+SCALARLIST_ALLOCATOR(Int64Array, TIMES_8)
+SCALARLIST_ALLOCATOR(Uint64Array, TIMES_8)
+SCALARLIST_ALLOCATOR(Float32Array, TIMES_4)
+SCALARLIST_ALLOCATOR(Float64Array, TIMES_8)
 
 
 bool Intrinsifier::Int64Array_getIndexed(Assembler* assembler) {
@@ -601,33 +582,49 @@
 }
 
 
-bool Intrinsifier::Int64Array_new(Assembler* assembler) {
-  TYPED_ARRAY_ALLOCATION(Int64Array, TIMES_8);
-  return false;
-}
-
-
 bool Intrinsifier::Uint64Array_getIndexed(Assembler* assembler) {
   return false;
 }
 
 
-bool Intrinsifier::Uint64Array_new(Assembler* assembler) {
-  TYPED_ARRAY_ALLOCATION(Uint64Array, TIMES_8);
-  return false;
+// Gets the length of a TypedData.
+bool Intrinsifier::TypedData_getLength(Assembler* assembler) {
+  __ movl(EAX, Address(ESP, + 1 * kWordSize));
+  __ movl(EAX, FieldAddress(EAX, TypedData::length_offset()));
+  __ ret();
+  return true;
 }
 
 
-bool Intrinsifier::Float32Array_new(Assembler* assembler) {
-  TYPED_ARRAY_ALLOCATION(Float32Array, TIMES_4);
-  return false;
-}
+static ScaleFactor GetScaleFactor(intptr_t size) {
+  switch (size) {
+    case 1: return TIMES_1;
+    case 2: return TIMES_2;
+    case 4: return TIMES_4;
+    case 8: return TIMES_8;
+  }
+  UNREACHABLE();
+  return static_cast<ScaleFactor>(0);
+};
 
 
-bool Intrinsifier::Float64Array_new(Assembler* assembler) {
-  TYPED_ARRAY_ALLOCATION(Float64Array, TIMES_8);
-  return false;
+#define TYPEDDATA_ALLOCATOR(clazz)                                             \
+bool Intrinsifier::TypedData_##clazz##_new(Assembler* assembler) {             \
+  intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid);       \
+  intptr_t max_len = TypedData::MaxElements(kTypedData##clazz##Cid);           \
+  ScaleFactor scale = GetScaleFactor(size);                                    \
+  TYPED_ARRAY_ALLOCATION(TypedData, kTypedData##clazz##Cid, max_len, scale);   \
+  return false;                                                                \
+}                                                                              \
+bool Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler) {         \
+  intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid);       \
+  intptr_t max_len = TypedData::MaxElements(kTypedData##clazz##Cid);           \
+  ScaleFactor scale = GetScaleFactor(size);                                    \
+  TYPED_ARRAY_ALLOCATION(TypedData, kTypedData##clazz##Cid, max_len, scale);   \
+  return false;                                                                \
 }
+CLASS_LIST_TYPED_DATA(TYPEDDATA_ALLOCATOR)
+#undef TYPEDDATA_ALLOCATOR
 
 
 // Tests if two top most arguments are smis, jumps to label not_smi if not.
@@ -866,11 +863,10 @@
   // Result in EDI (high) and EBX (low).
   const Class& mint_class = Class::Handle(
       Isolate::Current()->object_store()->mint_class());
-  AssemblerMacros::TryAllocate(assembler,
-                               mint_class,
-                               &fall_through,
-                               Assembler::kNearJump,
-                               EAX);  // Result register.
+  __ TryAllocate(mint_class,
+                 &fall_through,
+                 Assembler::kNearJump,
+                 EAX);  // Result register.
   // EBX and EDI are not objects but integer values.
   __ movl(FieldAddress(EAX, Mint::value_offset()), EBX);
   __ movl(FieldAddress(EAX, Mint::value_offset() + kWordSize), EDI);
@@ -1178,11 +1174,10 @@
   }
   const Class& double_class = Class::Handle(
       Isolate::Current()->object_store()->double_class());
-  AssemblerMacros::TryAllocate(assembler,
-                               double_class,
-                               &fall_through,
-                               Assembler::kNearJump,
-                               EAX);  // Result register.
+  __ TryAllocate(double_class,
+                 &fall_through,
+                 Assembler::kNearJump,
+                 EAX);  // Result register.
   __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
   __ ret();
   __ Bind(&fall_through);
@@ -1225,11 +1220,10 @@
   __ mulsd(XMM0, XMM1);
   const Class& double_class = Class::Handle(
       Isolate::Current()->object_store()->double_class());
-  AssemblerMacros::TryAllocate(assembler,
-                               double_class,
-                               &fall_through,
-                               Assembler::kNearJump,
-                               EAX);  // Result register.
+  __ TryAllocate(double_class,
+                 &fall_through,
+                 Assembler::kNearJump,
+                 EAX);  // Result register.
   __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
   __ ret();
   __ Bind(&fall_through);
@@ -1247,11 +1241,10 @@
   __ cvtsi2sd(XMM0, EAX);
   const Class& double_class = Class::Handle(
       Isolate::Current()->object_store()->double_class());
-  AssemblerMacros::TryAllocate(assembler,
-                               double_class,
-                               &fall_through,
-                               Assembler::kNearJump,
-                               EAX);  // Result register.
+  __ TryAllocate(double_class,
+                 &fall_through,
+                 Assembler::kNearJump,
+                 EAX);  // Result register.
   __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
   __ ret();
   __ Bind(&fall_through);
@@ -1325,11 +1318,10 @@
   __ sqrtsd(XMM0, XMM1);
   const Class& double_class = Class::Handle(
       Isolate::Current()->object_store()->double_class());
-  AssemblerMacros::TryAllocate(assembler,
-                               double_class,
-                               &fall_through,
-                               Assembler::kNearJump,
-                               EAX);  // Result register.
+  __ TryAllocate(double_class,
+                 &fall_through,
+                 Assembler::kNearJump,
+                 EAX);  // Result register.
   __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
   __ ret();
   __ Bind(&is_smi);
@@ -1363,11 +1355,10 @@
   const Class& double_class = Class::Handle(
       Isolate::Current()->object_store()->double_class());
   Label alloc_failed;
-  AssemblerMacros::TryAllocate(assembler,
-                               double_class,
-                               &alloc_failed,
-                               Assembler::kNearJump,
-                               EAX);  // Result register.
+  __ TryAllocate(double_class,
+                 &alloc_failed,
+                 Assembler::kNearJump,
+                 EAX);  // Result register.
   __ fstpl(FieldAddress(EAX, Double::value_offset()));
   __ ret();
 
diff --git a/runtime/vm/intrinsifier_mips.cc b/runtime/vm/intrinsifier_mips.cc
index 08a298c..cfe0b82 100644
--- a/runtime/vm/intrinsifier_mips.cc
+++ b/runtime/vm/intrinsifier_mips.cc
@@ -6,6 +6,7 @@
 #if defined(TARGET_ARCH_MIPS)
 
 #include "vm/intrinsifier.h"
+#include "vm/object.h"
 
 namespace dart {
 
@@ -89,36 +90,71 @@
 }
 
 
+bool Intrinsifier::Int8Array_factory(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Uint8Array_new(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Uint8Array_factory(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Uint8ClampedArray_new(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Uint8ClampedArray_factory(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Int16Array_new(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Int16Array_factory(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Uint16Array_new(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Uint16Array_factory(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Int32Array_new(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Int32Array_factory(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Uint32Array_new(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Uint32Array_factory(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Int64Array_getIndexed(Assembler* assembler) {
   return false;
 }
@@ -129,6 +165,11 @@
 }
 
 
+bool Intrinsifier::Int64Array_factory(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Uint64Array_getIndexed(Assembler* assembler) {
   return false;
 }
@@ -139,16 +180,47 @@
 }
 
 
+bool Intrinsifier::Uint64Array_factory(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Float32Array_new(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Float32Array_factory(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Float64Array_new(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Float64Array_factory(Assembler* assembler) {
+  return false;
+}
+
+
+bool Intrinsifier::TypedData_getLength(Assembler* assembler) {
+  return true;
+}
+
+
+#define TYPEDDATA_ALLOCATOR(clazz)                                             \
+bool Intrinsifier::TypedData_##clazz##_new(Assembler* assembler) {             \
+  return false;                                                                \
+}                                                                              \
+bool Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler) {         \
+  return false;                                                                \
+}
+CLASS_LIST_TYPED_DATA(TYPEDDATA_ALLOCATOR)
+#undef TYPEDDATA_ALLOCATOR
+
+
 bool Intrinsifier::Integer_addFromInteger(Assembler* assembler) {
   return false;
 }
diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc
index b72beb0..3119fdb 100644
--- a/runtime/vm/intrinsifier_x64.cc
+++ b/runtime/vm/intrinsifier_x64.cc
@@ -8,7 +8,6 @@
 #include "vm/intrinsifier.h"
 
 #include "vm/assembler.h"
-#include "vm/assembler_macros.h"
 #include "vm/instructions.h"
 #include "vm/object_store.h"
 #include "vm/symbols.h"
@@ -440,7 +439,7 @@
 }
 
 
-#define TYPED_ARRAY_ALLOCATION(type_name, scale_factor)                        \
+#define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_factor)          \
   Label fall_through;                                                          \
   const intptr_t kArrayLengthStackOffset = 1 * kWordSize;                      \
   __ movq(RDI, Address(RSP, kArrayLengthStackOffset));  /* Array length. */    \
@@ -453,7 +452,7 @@
   __ SmiUntag(RDI);                                                            \
   /* Check for maximum allowed length. */                                      \
   /* RDI: untagged array length. */                                            \
-  __ cmpq(RDI, Immediate(type_name::kMaxElements));                            \
+  __ cmpq(RDI, Immediate(max_len));                                            \
   __ j(GREATER, &fall_through);                                                \
   const intptr_t fixed_size = sizeof(Raw##type_name) + kObjectAlignment - 1;   \
   __ leaq(RDI, Address(RDI, scale_factor, fixed_size));                        \
@@ -500,7 +499,7 @@
     __ Bind(&done);                                                            \
                                                                                \
     /* Get the class index and insert it into the tags. */                     \
-    __ orq(RDI, Immediate(RawObject::ClassIdTag::encode(k##type_name##Cid)));  \
+    __ orq(RDI, Immediate(RawObject::ClassIdTag::encode(cid)));                \
     __ movq(FieldAddress(RAX, type_name::tags_offset()), RDI);  /* Tags. */    \
   }                                                                            \
   /* Set the length field. */                                                  \
@@ -531,46 +530,28 @@
   __ Bind(&fall_through);                                                      \
 
 
-bool Intrinsifier::Int8Array_new(Assembler* assembler) {
-  TYPED_ARRAY_ALLOCATION(Int8Array, TIMES_1);
-  return false;
+#define SCALARLIST_ALLOCATOR(clazz, scale)                                     \
+bool Intrinsifier::clazz##_new(Assembler* assembler) {                         \
+  TYPED_ARRAY_ALLOCATION(clazz, k##clazz##Cid, clazz::kMaxElements, scale);    \
+  return false;                                                                \
+}                                                                              \
+bool Intrinsifier::clazz##_factory(Assembler* assembler) {                     \
+  TYPED_ARRAY_ALLOCATION(clazz, k##clazz##Cid, clazz::kMaxElements, scale);    \
+  return false;                                                                \
 }
 
 
-bool Intrinsifier::Uint8Array_new(Assembler* assembler) {
-  TYPED_ARRAY_ALLOCATION(Uint8Array, TIMES_1);
-  return false;
-}
-
-
-bool Intrinsifier::Uint8ClampedArray_new(Assembler* assembler) {
-  TYPED_ARRAY_ALLOCATION(Uint8ClampedArray, TIMES_1);
-  return false;
-}
-
-
-bool Intrinsifier::Int16Array_new(Assembler* assembler) {
-  TYPED_ARRAY_ALLOCATION(Int16Array, TIMES_2);
-  return false;
-}
-
-
-bool Intrinsifier::Uint16Array_new(Assembler* assembler) {
-  TYPED_ARRAY_ALLOCATION(Uint16Array, TIMES_2);
-  return false;
-}
-
-
-bool Intrinsifier::Int32Array_new(Assembler* assembler) {
-  TYPED_ARRAY_ALLOCATION(Int32Array, TIMES_4);
-  return false;
-}
-
-
-bool Intrinsifier::Uint32Array_new(Assembler* assembler) {
-  TYPED_ARRAY_ALLOCATION(Uint32Array, TIMES_4);
-  return false;
-}
+SCALARLIST_ALLOCATOR(Int8Array, TIMES_1)
+SCALARLIST_ALLOCATOR(Uint8Array, TIMES_1)
+SCALARLIST_ALLOCATOR(Uint8ClampedArray, TIMES_1)
+SCALARLIST_ALLOCATOR(Int16Array, TIMES_2)
+SCALARLIST_ALLOCATOR(Uint16Array, TIMES_2)
+SCALARLIST_ALLOCATOR(Int32Array, TIMES_4)
+SCALARLIST_ALLOCATOR(Uint32Array, TIMES_4)
+SCALARLIST_ALLOCATOR(Int64Array, TIMES_8)
+SCALARLIST_ALLOCATOR(Uint64Array, TIMES_8)
+SCALARLIST_ALLOCATOR(Float32Array, TIMES_4)
+SCALARLIST_ALLOCATOR(Float64Array, TIMES_8)
 
 
 bool Intrinsifier::Int64Array_getIndexed(Assembler* assembler) {
@@ -596,12 +577,6 @@
 }
 
 
-bool Intrinsifier::Int64Array_new(Assembler* assembler) {
-  TYPED_ARRAY_ALLOCATION(Int64Array, TIMES_8);
-  return false;
-}
-
-
 bool Intrinsifier::Uint64Array_getIndexed(Assembler* assembler) {
   Label fall_through;
   TestByteArrayGetIndex(assembler, &fall_through);
@@ -624,22 +599,47 @@
 }
 
 
-bool Intrinsifier::Uint64Array_new(Assembler* assembler) {
-  TYPED_ARRAY_ALLOCATION(Uint64Array, TIMES_8);
-  return false;
+// Gets the length of a TypedData.
+bool Intrinsifier::TypedData_getLength(Assembler* assembler) {
+  __ movq(RAX, Address(RSP, + 1 * kWordSize));
+  __ movq(RAX, FieldAddress(RAX, TypedData::length_offset()));
+  __ ret();
+  // Generate enough code to satisfy patchability constraint.
+  intptr_t offset = __ CodeSize();
+  __ nop(JumpPattern::InstructionLength() - offset);
+  return true;
 }
 
 
-bool Intrinsifier::Float32Array_new(Assembler* assembler) {
-  TYPED_ARRAY_ALLOCATION(Float32Array, TIMES_4);
-  return false;
-}
+static ScaleFactor GetScaleFactor(intptr_t size) {
+  switch (size) {
+    case 1: return TIMES_1;
+    case 2: return TIMES_2;
+    case 4: return TIMES_4;
+    case 8: return TIMES_8;
+  }
+  UNREACHABLE();
+  return static_cast<ScaleFactor>(0);
+};
 
 
-bool Intrinsifier::Float64Array_new(Assembler* assembler) {
-  TYPED_ARRAY_ALLOCATION(Float64Array, TIMES_8);
-  return false;
+#define TYPEDDATA_ALLOCATOR(clazz)                                             \
+bool Intrinsifier::TypedData_##clazz##_new(Assembler* assembler) {             \
+  intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid);       \
+  intptr_t max_len = TypedData::MaxElements(kTypedData##clazz##Cid);           \
+  ScaleFactor scale = GetScaleFactor(size);                                    \
+  TYPED_ARRAY_ALLOCATION(TypedData, kTypedData##clazz##Cid, max_len, scale);   \
+  return false;                                                                \
+}                                                                              \
+bool Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler) {         \
+  intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid);       \
+  intptr_t max_len = TypedData::MaxElements(kTypedData##clazz##Cid);           \
+  ScaleFactor scale = GetScaleFactor(size);                                    \
+  TYPED_ARRAY_ALLOCATION(TypedData, kTypedData##clazz##Cid, max_len, scale);   \
+  return false;                                                                \
 }
+CLASS_LIST_TYPED_DATA(TYPEDDATA_ALLOCATOR)
+#undef TYPEDDATA_ALLOCATOR
 
 
 // Tests if two top most arguments are smis, jumps to label not_smi if not.
@@ -1101,11 +1101,10 @@
   }
   const Class& double_class = Class::Handle(
       Isolate::Current()->object_store()->double_class());
-  AssemblerMacros::TryAllocate(assembler,
-                               double_class,
-                               &fall_through,
-                               Assembler::kNearJump,
-                               RAX);  // Result register.
+  __ TryAllocate(double_class,
+                 &fall_through,
+                 Assembler::kNearJump,
+                 RAX);  // Result register.
   __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
   __ ret();
   __ Bind(&fall_through);
@@ -1147,11 +1146,10 @@
   __ mulsd(XMM0, XMM1);
   const Class& double_class = Class::Handle(
       Isolate::Current()->object_store()->double_class());
-  AssemblerMacros::TryAllocate(assembler,
-                               double_class,
-                               &fall_through,
-                               Assembler::kNearJump,
-                               RAX);  // Result register.
+  __ TryAllocate(double_class,
+                 &fall_through,
+                 Assembler::kNearJump,
+                 RAX);  // Result register.
   __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
   __ ret();
   __ Bind(&fall_through);
@@ -1170,11 +1168,10 @@
   __ cvtsi2sd(XMM0, RAX);
   const Class& double_class = Class::Handle(
       Isolate::Current()->object_store()->double_class());
-  AssemblerMacros::TryAllocate(assembler,
-                               double_class,
-                               &fall_through,
-                               Assembler::kNearJump,
-                               RAX);  // Result register.
+  __ TryAllocate(double_class,
+                 &fall_through,
+                 Assembler::kNearJump,
+                 RAX);  // Result register.
   __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
   __ ret();
   __ Bind(&fall_through);
@@ -1244,11 +1241,10 @@
   const Class& double_class = Class::Handle(
       Isolate::Current()->object_store()->double_class());
   Label alloc_failed;
-  AssemblerMacros::TryAllocate(assembler,
-                               double_class,
-                               &alloc_failed,
-                               Assembler::kNearJump,
-                               RAX);  // Result register.
+  __ TryAllocate(double_class,
+                 &alloc_failed,
+                 Assembler::kNearJump,
+                 RAX);  // Result register.
   __ fstpl(FieldAddress(RAX, Double::value_offset()));
   __ ret();
 
@@ -1293,11 +1289,10 @@
   __ sqrtsd(XMM0, XMM1);
   const Class& double_class = Class::Handle(
       Isolate::Current()->object_store()->double_class());
-  AssemblerMacros::TryAllocate(assembler,
-                               double_class,
-                               &fall_through,
-                               Assembler::kNearJump,
-                               RAX);  // Result register.
+  __ TryAllocate(double_class,
+                 &fall_through,
+                 Assembler::kNearJump,
+                 RAX);  // Result register.
   __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
   __ ret();
   __ Bind(&is_smi);
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 31e909b..6afc6fb 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -388,7 +388,7 @@
 
 
 void Isolate::SetStackLimitFromCurrentTOS(uword stack_top_value) {
-#ifdef USING_SIMULATOR
+#if defined(USING_SIMULATOR)
   // Ignore passed-in native stack top and use Simulator stack top.
   Simulator* sim = Simulator::Current();  // May allocate a simulator.
   ASSERT(simulator() == sim);  // This isolate's simulator is the current one.
diff --git a/runtime/vm/locations.cc b/runtime/vm/locations.cc
index 49db8ae..50ef036 100644
--- a/runtime/vm/locations.cc
+++ b/runtime/vm/locations.cc
@@ -89,11 +89,10 @@
 Address Location::ToStackSlotAddress() const {
   const intptr_t index = stack_index();
   if (index < 0) {
-    const intptr_t offset = (1 - index)  * kWordSize;
+    const intptr_t offset = (kLastParamSlotIndex - index - 1)  * kWordSize;
     return Address(FPREG, offset);
   } else {
-    const intptr_t offset =
-        (ParsedFunction::kFirstLocalSlotIndex - index) * kWordSize;
+    const intptr_t offset = (kFirstLocalSlotIndex - index) * kWordSize;
     return Address(FPREG, offset);
   }
 }
diff --git a/runtime/vm/native_entry.h b/runtime/vm/native_entry.h
index 6058c11..09b5f7f 100644
--- a/runtime/vm/native_entry.h
+++ b/runtime/vm/native_entry.h
@@ -28,6 +28,15 @@
 
 #define NATIVE_ENTRY_FUNCTION(name) BootstrapNatives::DN_##name
 
+#ifdef DEBUG
+#define SET_NATIVE_RETVAL(args, value)                                         \
+  RawObject* retval = value;                                                   \
+  ASSERT(retval->IsDartInstance());                                            \
+  arguments->SetReturnUnsafe(retval);
+#else
+#define SET_NATIVE_RETVAL(arguments, value)                                    \
+  arguments->SetReturnUnsafe(value);
+#endif
 
 #define DEFINE_NATIVE_ENTRY(name, argument_count)                              \
   static RawObject* DN_Helper##name(Isolate* isolate,                          \
@@ -41,8 +50,8 @@
     {                                                                          \
       StackZone zone(arguments->isolate());                                    \
       HANDLESCOPE(arguments->isolate());                                       \
-      arguments->SetReturnUnsafe(                                              \
-          DN_Helper##name(arguments->isolate(), arguments));                   \
+      SET_NATIVE_RETVAL(arguments,                                             \
+                        DN_Helper##name(arguments->isolate(), arguments));     \
       if (FLAG_deoptimize_alot) DeoptimizeAll();                               \
     }                                                                          \
     VERIFY_ON_TRANSITION;                                                      \
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 5bceca2..b3c4336 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -702,6 +702,12 @@
   cls = Class::New<TypeParameter>();
   object_store->set_type_parameter_class(cls);
 
+  cls = Class::New<BoundedType>();
+  object_store->set_bounded_type_class(cls);
+
+  cls = Class::New<MixinAppType>();
+  object_store->set_mixin_app_type_class(cls);
+
   // Pre-allocate the OneByteString class needed by the symbol table.
   cls = Class::NewStringClass(kOneByteStringCid);
   object_store->set_one_byte_string_class(cls);
@@ -851,116 +857,67 @@
   // Pre-register the scalarlist library so the native class implementations
   // can be hooked up before compiling it.
   LOAD_LIBRARY(Scalarlist, scalarlist);
+  ASSERT(!lib.IsNull());
+  ASSERT(lib.raw() == Library::ScalarlistLibrary());
+#define REGISTER_SCALARLIST_CLASS(name, object_store_name)                     \
+  cls = Class::New<name>();                                                    \
+  object_store->set_##object_store_name##_class(cls);                          \
+  RegisterPrivateClass(cls, Symbols::_##name(), lib);                          \
 
-  Library& scalarlist_lib = Library::Handle(Library::ScalarlistLibrary());
-  ASSERT(!scalarlist_lib.IsNull());
+  REGISTER_SCALARLIST_CLASS(Float32x4, float32x4);
+  REGISTER_SCALARLIST_CLASS(Uint32x4, uint32x4);
+  REGISTER_SCALARLIST_CLASS(Int8Array, int8_array);
+  REGISTER_SCALARLIST_CLASS(Uint8Array, uint8_array);
+  REGISTER_SCALARLIST_CLASS(Uint8ClampedArray, uint8_clamped_array);
+  REGISTER_SCALARLIST_CLASS(Int16Array, int16_array);
+  REGISTER_SCALARLIST_CLASS(Uint16Array, uint16_array);
+  REGISTER_SCALARLIST_CLASS(Int32Array, int32_array);
+  REGISTER_SCALARLIST_CLASS(Uint32Array, uint32_array);
+  REGISTER_SCALARLIST_CLASS(Int64Array, int64_array);
+  REGISTER_SCALARLIST_CLASS(Uint64Array, uint64_array);
+  REGISTER_SCALARLIST_CLASS(Float32x4Array, float32x4_array);
+  REGISTER_SCALARLIST_CLASS(Float32Array, float32_array);
+  REGISTER_SCALARLIST_CLASS(Float64Array, float64_array);
+  REGISTER_SCALARLIST_CLASS(ExternalInt8Array, external_int8_array);
+  REGISTER_SCALARLIST_CLASS(ExternalUint8Array, external_uint8_array);
+  REGISTER_SCALARLIST_CLASS(ExternalUint8ClampedArray,
+                            external_uint8_clamped_array);
+  REGISTER_SCALARLIST_CLASS(ExternalInt16Array, external_int16_array);
+  REGISTER_SCALARLIST_CLASS(ExternalUint16Array, external_uint16_array);
+  REGISTER_SCALARLIST_CLASS(ExternalInt32Array, external_int32_array);
+  REGISTER_SCALARLIST_CLASS(ExternalUint32Array, external_uint32_array);
+  REGISTER_SCALARLIST_CLASS(ExternalInt64Array, external_int64_array);
+  REGISTER_SCALARLIST_CLASS(ExternalUint64Array, external_uint64_array);
+  REGISTER_SCALARLIST_CLASS(ExternalFloat32x4Array, external_float32x4_array);
+  REGISTER_SCALARLIST_CLASS(ExternalFloat32Array, external_float32_array);
+  REGISTER_SCALARLIST_CLASS(ExternalFloat64Array, external_float64_array);
+#undef REGISTER_SCALARLIST_CLASS
 
-  cls = Class::New<Float32x4>();
-  object_store->set_float32x4_class(cls);
-  RegisterPrivateClass(cls, Symbols::_Float32x4(), scalarlist_lib);
+  // Pre-register the typeddata library so the native class implementations
+  // can be hooked up before compiling it.
+  LOAD_LIBRARY(TypedData, typeddata);
+  ASSERT(!lib.IsNull());
+  ASSERT(lib.raw() == Library::TypedDataLibrary());
+  Array& typeddata_classes =
+      Array::Handle(Array::New(RawObject::NumberOfTypedDataClasses()));
+  int index = 0;
+#define REGISTER_TYPED_DATA_CLASS(clazz)                                       \
+  cls = Class::NewTypedDataClass(kTypedData##clazz##Cid);                      \
+  index = kTypedData##clazz##Cid - kTypedDataInt8ArrayCid;                     \
+  typeddata_classes.SetAt(index, cls);                                         \
+  RegisterPrivateClass(cls, Symbols::_##clazz(), lib);                         \
 
-  cls = Class::New<Uint32x4>();
-  object_store->set_uint32x4_class(cls);
-  RegisterPrivateClass(cls, Symbols::_Uint32x4(), scalarlist_lib);
+  CLASS_LIST_TYPED_DATA(REGISTER_TYPED_DATA_CLASS);
+#undef REGISTER_TYPED_DATA_CLASS
+#define REGISTER_EXT_TYPED_DATA_CLASS(clazz)                                   \
+  cls = Class::NewExternalTypedDataClass(kExternalTypedData##clazz##Cid);      \
+  index = kExternalTypedData##clazz##Cid - kTypedDataInt8ArrayCid;             \
+  typeddata_classes.SetAt(index, cls);                                         \
+  RegisterPrivateClass(cls, Symbols::_External##clazz(), lib);                 \
 
-  cls = Class::New<Int8Array>();
-  object_store->set_int8_array_class(cls);
-  RegisterPrivateClass(cls, Symbols::_Int8Array(), scalarlist_lib);
-
-  cls = Class::New<Uint8Array>();
-  object_store->set_uint8_array_class(cls);
-  RegisterPrivateClass(cls, Symbols::_Uint8Array(), scalarlist_lib);
-
-  cls = Class::New<Uint8ClampedArray>();
-  object_store->set_uint8_clamped_array_class(cls);
-  RegisterPrivateClass(cls, Symbols::_Uint8ClampedArray(), scalarlist_lib);
-
-  cls = Class::New<Int16Array>();
-  object_store->set_int16_array_class(cls);
-  RegisterPrivateClass(cls, Symbols::_Int16Array(), scalarlist_lib);
-
-  cls = Class::New<Uint16Array>();
-  object_store->set_uint16_array_class(cls);
-  RegisterPrivateClass(cls, Symbols::_Uint16Array(), scalarlist_lib);
-
-  cls = Class::New<Int32Array>();
-  object_store->set_int32_array_class(cls);
-  RegisterPrivateClass(cls, Symbols::_Int32Array(), scalarlist_lib);
-
-  cls = Class::New<Uint32Array>();
-  object_store->set_uint32_array_class(cls);
-  RegisterPrivateClass(cls, Symbols::_Uint32Array(), scalarlist_lib);
-
-  cls = Class::New<Int64Array>();
-  object_store->set_int64_array_class(cls);
-  RegisterPrivateClass(cls, Symbols::_Int64Array(), scalarlist_lib);
-
-  cls = Class::New<Uint64Array>();
-  object_store->set_uint64_array_class(cls);
-  RegisterPrivateClass(cls, Symbols::_Uint64Array(), scalarlist_lib);
-
-  cls = Class::New<Float32x4Array>();
-  object_store->set_float32x4_array_class(cls);
-  RegisterPrivateClass(cls, Symbols::_Float32x4Array(), scalarlist_lib);
-
-  cls = Class::New<Float32Array>();
-  object_store->set_float32_array_class(cls);
-  RegisterPrivateClass(cls, Symbols::_Float32Array(), scalarlist_lib);
-
-  cls = Class::New<Float64Array>();
-  object_store->set_float64_array_class(cls);
-  RegisterPrivateClass(cls, Symbols::_Float64Array(), scalarlist_lib);
-
-  cls = Class::New<ExternalInt8Array>();
-  object_store->set_external_int8_array_class(cls);
-  RegisterPrivateClass(cls, Symbols::_ExternalInt8Array(), scalarlist_lib);
-
-  cls = Class::New<ExternalUint8Array>();
-  object_store->set_external_uint8_array_class(cls);
-  RegisterPrivateClass(cls, Symbols::_ExternalUint8Array(), scalarlist_lib);
-
-  cls = Class::New<ExternalUint8ClampedArray>();
-  object_store->set_external_uint8_clamped_array_class(cls);
-  RegisterPrivateClass(cls,
-                       Symbols::_ExternalUint8ClampedArray(),
-                       scalarlist_lib);
-
-  cls = Class::New<ExternalInt16Array>();
-  object_store->set_external_int16_array_class(cls);
-  RegisterPrivateClass(cls, Symbols::_ExternalInt16Array(), scalarlist_lib);
-
-  cls = Class::New<ExternalUint16Array>();
-  object_store->set_external_uint16_array_class(cls);
-  RegisterPrivateClass(cls, Symbols::_ExternalUint16Array(), scalarlist_lib);
-
-  cls = Class::New<ExternalInt32Array>();
-  object_store->set_external_int32_array_class(cls);
-  RegisterPrivateClass(cls, Symbols::_ExternalInt32Array(), scalarlist_lib);
-
-  cls = Class::New<ExternalUint32Array>();
-  object_store->set_external_uint32_array_class(cls);
-  RegisterPrivateClass(cls, Symbols::_ExternalUint32Array(), scalarlist_lib);
-
-  cls = Class::New<ExternalInt64Array>();
-  object_store->set_external_int64_array_class(cls);
-  RegisterPrivateClass(cls, Symbols::_ExternalInt64Array(), scalarlist_lib);
-
-  cls = Class::New<ExternalUint64Array>();
-  object_store->set_external_uint64_array_class(cls);
-  RegisterPrivateClass(cls, Symbols::_ExternalUint64Array(), scalarlist_lib);
-
-  cls = Class::New<ExternalFloat32x4Array>();
-  object_store->set_external_float32x4_array_class(cls);
-  RegisterPrivateClass(cls, Symbols::_ExternalFloat32x4Array(),
-                       scalarlist_lib);
-
-  cls = Class::New<ExternalFloat32Array>();
-  object_store->set_external_float32_array_class(cls);
-  RegisterPrivateClass(cls, Symbols::_ExternalFloat32Array(), scalarlist_lib);
-
-  cls = Class::New<ExternalFloat64Array>();
-  object_store->set_external_float64_array_class(cls);
-  RegisterPrivateClass(cls, Symbols::_ExternalFloat64Array(), scalarlist_lib);
+  CLASS_LIST_TYPED_DATA(REGISTER_EXT_TYPED_DATA_CLASS);
+#undef REGISTER_EXT_TYPED_DATA_CLASS
+  object_store->set_typeddata_classes(typeddata_classes);
 
   // Set the super type of class Stacktrace to Object type so that the
   // 'toString' method is implemented.
@@ -1054,6 +1011,7 @@
   INIT_LIBRARY(Math, math, true);
   INIT_LIBRARY(Mirrors, mirrors, true);
   INIT_LIBRARY(Scalarlist, scalarlist, true);
+  INIT_LIBRARY(TypedData, typeddata, true);
   INIT_LIBRARY(Utf, utf, false);
   INIT_LIBRARY(Uri, uri, false);
 
@@ -1092,6 +1050,12 @@
   cls = Class::New<TypeParameter>();
   object_store->set_type_parameter_class(cls);
 
+  cls = Class::New<BoundedType>();
+  object_store->set_bounded_type_class(cls);
+
+  cls = Class::New<MixinAppType>();
+  object_store->set_mixin_app_type_class(cls);
+
   cls = Class::New<Array>();
   object_store->set_array_class(cls);
 
@@ -1101,83 +1065,47 @@
   cls = Class::New<GrowableObjectArray>();
   object_store->set_growable_object_array_class(cls);
 
-  cls = Class::New<Float32x4>();
-  object_store->set_float32x4_class(cls);
+#define REGISTER_SCALARLIST_CLASS(name, object_store_name)                     \
+  cls = Class::New<name>();                                                    \
+  object_store->set_##object_store_name##_class(cls);                          \
 
-  cls = Class::New<Uint32x4>();
-  object_store->set_uint32x4_class(cls);
+  REGISTER_SCALARLIST_CLASS(Float32x4, float32x4);
+  REGISTER_SCALARLIST_CLASS(Uint32x4, uint32x4);
+  REGISTER_SCALARLIST_CLASS(Int8Array, int8_array);
+  REGISTER_SCALARLIST_CLASS(Uint8Array, uint8_array);
+  REGISTER_SCALARLIST_CLASS(Uint8ClampedArray, uint8_clamped_array);
+  REGISTER_SCALARLIST_CLASS(Int16Array, int16_array);
+  REGISTER_SCALARLIST_CLASS(Uint16Array, uint16_array);
+  REGISTER_SCALARLIST_CLASS(Int32Array, int32_array);
+  REGISTER_SCALARLIST_CLASS(Uint32Array, uint32_array);
+  REGISTER_SCALARLIST_CLASS(Int64Array, int64_array);
+  REGISTER_SCALARLIST_CLASS(Uint64Array, uint64_array);
+  REGISTER_SCALARLIST_CLASS(Float32x4Array, float32x4_array);
+  REGISTER_SCALARLIST_CLASS(Float32Array, float32_array);
+  REGISTER_SCALARLIST_CLASS(Float64Array, float64_array);
+  REGISTER_SCALARLIST_CLASS(ExternalInt8Array, external_int8_array);
+  REGISTER_SCALARLIST_CLASS(ExternalUint8Array, external_uint8_array);
+  REGISTER_SCALARLIST_CLASS(ExternalUint8ClampedArray,
+                            external_uint8_clamped_array);
+  REGISTER_SCALARLIST_CLASS(ExternalInt16Array, external_int16_array);
+  REGISTER_SCALARLIST_CLASS(ExternalUint16Array, external_uint16_array);
+  REGISTER_SCALARLIST_CLASS(ExternalInt32Array, external_int32_array);
+  REGISTER_SCALARLIST_CLASS(ExternalUint32Array, external_uint32_array);
+  REGISTER_SCALARLIST_CLASS(ExternalInt64Array, external_int64_array);
+  REGISTER_SCALARLIST_CLASS(ExternalUint64Array, external_uint64_array);
+  REGISTER_SCALARLIST_CLASS(ExternalFloat32x4Array, external_float32x4_array);
+  REGISTER_SCALARLIST_CLASS(ExternalFloat32Array, external_float32_array);
+  REGISTER_SCALARLIST_CLASS(ExternalFloat64Array, external_float64_array);
+#undef REGISTER_SCALARLIST_CLASS
 
-  cls = Class::New<Int8Array>();
-  object_store->set_int8_array_class(cls);
-
-  cls = Class::New<Uint8Array>();
-  object_store->set_uint8_array_class(cls);
-
-  cls = Class::New<Uint8ClampedArray>();
-  object_store->set_uint8_clamped_array_class(cls);
-
-  cls = Class::New<Int16Array>();
-  object_store->set_int16_array_class(cls);
-
-  cls = Class::New<Uint16Array>();
-  object_store->set_uint16_array_class(cls);
-
-  cls = Class::New<Int32Array>();
-  object_store->set_int32_array_class(cls);
-
-  cls = Class::New<Uint32Array>();
-  object_store->set_uint32_array_class(cls);
-
-  cls = Class::New<Int64Array>();
-  object_store->set_int64_array_class(cls);
-
-  cls = Class::New<Uint64Array>();
-  object_store->set_uint64_array_class(cls);
-
-  cls = Class::New<Float32x4Array>();
-  object_store->set_float32x4_array_class(cls);
-
-  cls = Class::New<Float32Array>();
-  object_store->set_float32_array_class(cls);
-
-  cls = Class::New<Float64Array>();
-  object_store->set_float64_array_class(cls);
-
-  cls = Class::New<ExternalInt8Array>();
-  object_store->set_external_int8_array_class(cls);
-
-  cls = Class::New<ExternalUint8Array>();
-  object_store->set_external_uint8_array_class(cls);
-
-  cls = Class::New<ExternalUint8ClampedArray>();
-  object_store->set_external_uint8_clamped_array_class(cls);
-
-  cls = Class::New<ExternalInt16Array>();
-  object_store->set_external_int16_array_class(cls);
-
-  cls = Class::New<ExternalUint16Array>();
-  object_store->set_external_uint16_array_class(cls);
-
-  cls = Class::New<ExternalInt32Array>();
-  object_store->set_external_int32_array_class(cls);
-
-  cls = Class::New<ExternalUint32Array>();
-  object_store->set_external_uint32_array_class(cls);
-
-  cls = Class::New<ExternalInt64Array>();
-  object_store->set_external_int64_array_class(cls);
-
-  cls = Class::New<ExternalUint64Array>();
-  object_store->set_external_uint64_array_class(cls);
-
-  cls = Class::New<ExternalFloat32x4Array>();
-  object_store->set_external_float32x4_array_class(cls);
-
-  cls = Class::New<ExternalFloat32Array>();
-  object_store->set_external_float32_array_class(cls);
-
-  cls = Class::New<ExternalFloat64Array>();
-  object_store->set_external_float64_array_class(cls);
+#define REGISTER_TYPED_DATA_CLASS(clazz)                                       \
+  cls = Class::NewTypedDataClass(kTypedData##clazz##Cid);
+  CLASS_LIST_TYPED_DATA(REGISTER_TYPED_DATA_CLASS);
+#undef REGISTER_TYPED_DATA_CLASS
+#define REGISTER_EXT_TYPED_DATA_CLASS(clazz)                                   \
+  cls = Class::NewExternalTypedDataClass(kExternalTypedData##clazz##Cid);
+  CLASS_LIST_TYPED_DATA(REGISTER_EXT_TYPED_DATA_CLASS);
+#undef REGISTER_EXT_TYPED_DATA_CLASS
 
   cls = Class::New<Integer>();
   object_store->set_integer_implementation_class(cls);
@@ -1662,7 +1590,7 @@
 
 
 RawClass* Class::SuperClass() const {
-  const Type& sup_type = Type::Handle(super_type());
+  const AbstractType& sup_type = AbstractType::Handle(super_type());
   if (sup_type.IsNull()) {
     return Class::null();
   }
@@ -1670,7 +1598,11 @@
 }
 
 
-void Class::set_super_type(const Type& value) const {
+void Class::set_super_type(const AbstractType& value) const {
+  ASSERT(value.IsNull() ||
+         value.IsType() ||
+         value.IsBoundedType() ||
+         value.IsMixinAppType());
   StorePointer(&raw_ptr()->super_type_, value.raw());
 }
 
@@ -1685,24 +1617,11 @@
     intptr_t num_type_params = type_params.Length();
     TypeParameter& type_param = TypeParameter::Handle();
     String& type_param_name = String::Handle();
-    // TODO(regis): We do not copy the bound (= type_param.bound()), since
-    // we are not able to finalize the bounds of type parameter references
-    // without getting into cycles. Revisit.
-    const AbstractType& bound = AbstractType::Handle(
-        Isolate::Current()->object_store()->object_type());
     for (intptr_t i = 0; i < num_type_params; i++) {
       type_param ^= type_params.TypeAt(i);
       type_param_name = type_param.name();
       if (type_param_name.Equals(type_name)) {
-        intptr_t index = type_param.index();
-        // Create a non-finalized new TypeParameter with the given token_pos.
-        if (type_param.IsFinalized()) {
-          // The index was adjusted during finalization. Revert.
-          index -= NumTypeArguments() - num_type_params;
-        } else {
-          ASSERT(type_param.index() == i);
-        }
-        return TypeParameter::New(*this, index, type_name, bound, token_pos);
+        return type_param.raw();
       }
     }
   }
@@ -2016,6 +1935,28 @@
 }
 
 
+RawClass* Class::NewTypedDataClass(intptr_t class_id) {
+  ASSERT(RawObject::IsTypedDataClassId(class_id));
+  intptr_t instance_size = TypedData::InstanceSize();
+  Class& result = Class::Handle(New<TypedData>(class_id));
+  result.set_instance_size(instance_size);
+  result.set_next_field_offset(instance_size);
+  result.set_is_prefinalized();
+  return result.raw();
+}
+
+
+RawClass* Class::NewExternalTypedDataClass(intptr_t class_id) {
+  ASSERT(RawObject::IsExternalTypedDataClassId(class_id));
+  intptr_t instance_size = ExternalTypedData::InstanceSize();
+  Class& result = Class::Handle(New<ExternalTypedData>(class_id));
+  result.set_instance_size(instance_size);
+  result.set_next_field_offset(instance_size);
+  result.set_is_prefinalized();
+  return result.raw();
+}
+
+
 void Class::set_name(const String& value) const {
   ASSERT(value.IsSymbol());
   StorePointer(&raw_ptr()->name_, value.raw());
@@ -2243,6 +2184,7 @@
   AbstractType& interface = AbstractType::Handle();
   Class& interface_class = Class::Handle();
   AbstractTypeArguments& interface_args = AbstractTypeArguments::Handle();
+  Error& args_malformed_error = Error::Handle();
   for (intptr_t i = 0; i < interfaces.Length(); i++) {
     interface ^= interfaces.At(i);
     interface_class = interface.type_class();
@@ -2257,19 +2199,15 @@
       // after the type arguments of the super type of this type.
       // The index of the type parameters is adjusted upon finalization.
       ASSERT(interface.IsFinalized());
-      interface_args = interface_args.InstantiateFrom(type_arguments);
-      // In checked mode, verify that the instantiated interface type
-      // arguments are within the bounds specified by the interface class.
-      // Note that the additional bounds check in checked mode may lead to a
-      // dynamic type error, but it will never change the result of the type
-      // check from true in production mode to false in checked mode.
-      if (FLAG_enable_type_checks && !interface_args.IsNull()) {
-        // Pass type_arguments as bounds instantiator.
-        if (!interface_args.IsWithinBoundsOf(interface_class,
-                                             type_arguments,
-                                             malformed_error)) {
-          continue;
+      args_malformed_error = Error::null();
+      interface_args = interface_args.InstantiateFrom(type_arguments,
+                                                      &args_malformed_error);
+      if (!args_malformed_error.IsNull()) {
+        // Return the first malformed error to the caller if it requests it.
+        if ((malformed_error != NULL) && malformed_error->IsNull()) {
+          *malformed_error = args_malformed_error.raw();
         }
+        continue;  // Another interface may work better.
       }
     }
     if (interface_class.TypeTest(test_kind,
@@ -2693,6 +2631,13 @@
 }
 
 
+bool AbstractTypeArguments::IsBounded() const {
+  // AbstractTypeArguments is an abstract class.
+  UNREACHABLE();
+  return false;
+}
+
+
 static intptr_t FinalizeHash(uword hash) {
   hash += hash << 3;
   hash ^= hash >> 11;
@@ -2784,7 +2729,8 @@
 
 
 RawAbstractTypeArguments* AbstractTypeArguments::InstantiateFrom(
-    const AbstractTypeArguments& instantiator_type_arguments) const {
+    const AbstractTypeArguments& instantiator_type_arguments,
+    Error* malformed_error) const {
   // AbstractTypeArguments is an abstract class.
   UNREACHABLE();
   return NULL;
@@ -2801,10 +2747,12 @@
     ASSERT(!type.IsNull());
     if (!type.HasResolvedTypeClass()) {
       if (raw_instantiated && type.IsTypeParameter()) {
-        // An uninstantiated type parameter is equivalent to dynamic.
+        // An uninstantiated type parameter is equivalent to dynamic (even in
+        // the presence of a malformed bound in checked mode).
         continue;
       }
       ASSERT((!raw_instantiated && type.IsTypeParameter()) ||
+             type.IsBoundedType() ||
              type.IsMalformed());
       return false;
     }
@@ -2832,69 +2780,6 @@
 }
 
 
-bool AbstractTypeArguments::IsWithinBoundsOf(
-    const Class& cls,
-    const AbstractTypeArguments& bounds_instantiator,
-    Error* malformed_error) const {
-  ASSERT(FLAG_enable_type_checks);
-  // This function may be called at compile time on (partially) uninstantiated
-  // type arguments and may return true, in which case a run time bounds check
-  // can be avoided.
-  ASSERT(Length() >= cls.NumTypeArguments());
-  const intptr_t num_type_params = cls.NumTypeParameters();
-  const intptr_t offset = cls.NumTypeArguments() - num_type_params;
-  AbstractType& this_type_arg = AbstractType::Handle();
-  AbstractType& cls_type_arg = AbstractType::Handle();
-  AbstractType& bound = AbstractType::Handle();
-  const TypeArguments& cls_type_params =
-      TypeArguments::Handle(cls.type_parameters());
-  ASSERT((cls_type_params.IsNull() && (num_type_params == 0)) ||
-         (cls_type_params.Length() == num_type_params));
-  for (intptr_t i = 0; i < num_type_params; i++) {
-    cls_type_arg = cls_type_params.TypeAt(i);
-    const TypeParameter& cls_type_param = TypeParameter::Cast(cls_type_arg);
-    bound = cls_type_param.bound();
-    if (!bound.IsDynamicType()) {
-      this_type_arg = TypeAt(offset + i);
-      Error& malformed_bound_error = Error::Handle();
-      if (bound.IsMalformed()) {
-        malformed_bound_error = bound.malformed_error();
-      } else if (!bound.IsInstantiated()) {
-        bound = bound.InstantiateFrom(bounds_instantiator);
-      }
-      if (!malformed_bound_error.IsNull() ||
-          !this_type_arg.IsSubtypeOf(bound, malformed_error)) {
-        // Ignore this bound error if another malformed error was already
-        // reported for this type test.
-        if ((malformed_error != NULL) && malformed_error->IsNull()) {
-          const String& type_arg_name =
-              String::Handle(this_type_arg.UserVisibleName());
-          const String& class_name = String::Handle(cls.Name());
-          const String& bound_name = String::Handle(bound.UserVisibleName());
-          const Script& script = Script::Handle(cls.script());
-          // Since the bound was canonicalized, its token index was lost,
-          // therefore, use the token index of the corresponding type parameter.
-          *malformed_error ^= FormatError(malformed_bound_error,
-                                          script, cls_type_param.token_pos(),
-                                          "type argument '%s' does not "
-                                          "extend bound '%s' of '%s'\n",
-                                          type_arg_name.ToCString(),
-                                          bound_name.ToCString(),
-                                          class_name.ToCString());
-        }
-        return false;
-      }
-    }
-  }
-  const Class& super_class = Class::Handle(cls.SuperClass());
-  if (!super_class.IsNull() &&
-      !IsWithinBoundsOf(super_class, bounds_instantiator, malformed_error)) {
-    return false;
-  }
-  return true;
-}
-
-
 bool AbstractTypeArguments::TypeTest(TypeTestKind test_kind,
                                      const AbstractTypeArguments& other,
                                      intptr_t len,
@@ -2982,16 +2867,53 @@
       return false;
     }
     const TypeParameter& type_param = TypeParameter::Cast(type);
+    ASSERT(type_param.IsFinalized());
     if ((type_param.index() != i)) {
       return false;
     }
+    // If this type parameter specifies an upper bound, then the type argument
+    // vector does not really represent the identity vector. It cannot be
+    // substituted by the instantiator's type argument vector without checking
+    // the upper bound.
+    const AbstractType& bound = AbstractType::Handle(type_param.bound());
+    ASSERT(bound.IsFinalized());
+    if (!bound.IsObjectType() && !bound.IsDynamicType()) {
+      return false;
+    }
   }
   return true;
 }
 
 
+bool TypeArguments::IsBounded() const {
+  AbstractType& type = AbstractType::Handle();
+  intptr_t num_types = Length();
+  for (intptr_t i = 0; i < num_types; i++) {
+    type = TypeAt(i);
+    if (type.IsBoundedType()) {
+      return true;
+    }
+    if (type.IsTypeParameter()) {
+      const AbstractType& bound = AbstractType::Handle(
+          TypeParameter::Cast(type).bound());
+      if (!bound.IsObjectType() && !bound.IsDynamicType()) {
+        return true;
+      }
+      continue;
+    }
+    const AbstractTypeArguments& type_args = AbstractTypeArguments::Handle(
+        Type::Cast(type).arguments());
+    if (!type_args.IsNull() && type_args.IsBounded()) {
+      return true;
+    }
+  }
+  return false;
+}
+
+
 RawAbstractTypeArguments* TypeArguments::InstantiateFrom(
-    const AbstractTypeArguments& instantiator_type_arguments) const {
+    const AbstractTypeArguments& instantiator_type_arguments,
+    Error* malformed_error) const {
   ASSERT(!IsInstantiated());
   if (!instantiator_type_arguments.IsNull() &&
       IsUninstantiatedIdentity() &&
@@ -3005,7 +2927,7 @@
   for (intptr_t i = 0; i < num_types; i++) {
     type = TypeAt(i);
     if (!type.IsInstantiated()) {
-      type = type.InstantiateFrom(instantiator_type_arguments);
+      type = type.InstantiateFrom(instantiator_type_arguments, malformed_error);
     }
     instantiated_array.SetTypeAt(i, type);
   }
@@ -3179,13 +3101,18 @@
 
 
 RawAbstractType* InstantiatedTypeArguments::TypeAt(intptr_t index) const {
-  const AbstractType& type = AbstractType::Handle(
-      AbstractTypeArguments::Handle(
-          uninstantiated_type_arguments()).TypeAt(index));
+  AbstractType& type = AbstractType::Handle(AbstractTypeArguments::Handle(
+      uninstantiated_type_arguments()).TypeAt(index));
   if (!type.IsInstantiated()) {
     const AbstractTypeArguments& instantiator_type_args =
         AbstractTypeArguments::Handle(instantiator_type_arguments());
-    return type.InstantiateFrom(instantiator_type_args);
+    Error& malformed_error = Error::Handle();
+    type = type.InstantiateFrom(instantiator_type_args, &malformed_error);
+    // InstantiatedTypeArguments cannot include unchecked bounds.
+    // In the presence of unchecked bounds, no InstantiatedTypeArguments are
+    // allocated, but the type arguments are instantiated individually and their
+    // bounds are checked.
+    ASSERT(malformed_error.IsNull());
   }
   return type.raw();
 }
@@ -3983,7 +3910,9 @@
   AbstractType& other_param_type =
       AbstractType::Handle(other.ParameterTypeAt(other_parameter_position));
   if (!other_param_type.IsInstantiated()) {
-    other_param_type = other_param_type.InstantiateFrom(other_type_arguments);
+    other_param_type = other_param_type.InstantiateFrom(other_type_arguments,
+                                                        malformed_error);
+    ASSERT((malformed_error == NULL) || malformed_error->IsNull());
   }
   if (other_param_type.IsDynamicType()) {
     return true;
@@ -3991,7 +3920,8 @@
   AbstractType& param_type =
       AbstractType::Handle(ParameterTypeAt(parameter_position));
   if (!param_type.IsInstantiated()) {
-    param_type = param_type.InstantiateFrom(type_arguments);
+    param_type = param_type.InstantiateFrom(type_arguments, malformed_error);
+    ASSERT((malformed_error == NULL) || malformed_error->IsNull());
   }
   if (param_type.IsDynamicType()) {
     return test_kind == kIsSubtypeOf;
@@ -4032,12 +3962,15 @@
   // Check the result type.
   AbstractType& other_res_type = AbstractType::Handle(other.result_type());
   if (!other_res_type.IsInstantiated()) {
-    other_res_type = other_res_type.InstantiateFrom(other_type_arguments);
+    other_res_type = other_res_type.InstantiateFrom(other_type_arguments,
+                                                    malformed_error);
+    ASSERT((malformed_error == NULL) || malformed_error->IsNull());
   }
   if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) {
     AbstractType& res_type = AbstractType::Handle(result_type());
     if (!res_type.IsInstantiated()) {
-      res_type = res_type.InstantiateFrom(type_arguments);
+      res_type = res_type.InstantiateFrom(type_arguments, malformed_error);
+      ASSERT((malformed_error == NULL) || malformed_error->IsNull());
     }
     if (res_type.IsVoidType()) {
       return false;
@@ -4349,7 +4282,7 @@
     param_type = ParameterTypeAt(i);
     ASSERT(!param_type.IsNull());
     if (instantiate && !param_type.IsInstantiated()) {
-      param_type = param_type.InstantiateFrom(instantiator);
+      param_type = param_type.InstantiateFrom(instantiator, NULL);
     }
     name = param_type.BuildName(name_visibility);
     pieces.Add(name);
@@ -4374,7 +4307,7 @@
       }
       param_type = ParameterTypeAt(i);
       if (instantiate && !param_type.IsInstantiated()) {
-        param_type = param_type.InstantiateFrom(instantiator);
+        param_type = param_type.InstantiateFrom(instantiator, NULL);
       }
       ASSERT(!param_type.IsNull());
       name = param_type.BuildName(name_visibility);
@@ -4392,7 +4325,7 @@
   pieces.Add(Symbols::RParenArrow());
   AbstractType& res_type = AbstractType::Handle(result_type());
   if (instantiate && !res_type.IsInstantiated()) {
-    res_type = res_type.InstantiateFrom(instantiator);
+    res_type = res_type.InstantiateFrom(instantiator, NULL);
   }
   name = res_type.BuildName(name_visibility);
   pieces.Add(name);
@@ -4930,6 +4863,9 @@
             escape_characters = true;
           }
         }
+        if ((literal.CharAt(i) == '$')) {
+          escape_characters = true;
+        }
       }
       if ((prev != Token::kINTERPOL_VAR) && (prev != Token::kINTERPOL_END)) {
         if (is_raw_string) {
@@ -5406,11 +5342,15 @@
 RawString* Script::Source() const {
   String& source = String::Handle(raw_ptr()->source_);
   if (source.IsNull()) {
-    const TokenStream& token_stream = TokenStream::Handle(tokens());
-    return token_stream.GenerateSource();
-  } else {
-    return raw_ptr()->source_;
+    return GenerateSource();
   }
+  return raw_ptr()->source_;
+}
+
+
+RawString* Script::GenerateSource() const {
+  const TokenStream& token_stream = TokenStream::Handle(tokens());
+  return token_stream.GenerateSource();
 }
 
 
@@ -6498,6 +6438,11 @@
 }
 
 
+RawLibrary* Library::TypedDataLibrary() {
+  return Isolate::Current()->object_store()->typeddata_library();
+}
+
+
 RawLibrary* Library::UriLibrary() {
   return Isolate::Current()->object_store()->uri_library();
 }
@@ -8803,7 +8748,7 @@
     // Verify that the number of type arguments in the instance matches the
     // number of type arguments expected by the instance class.
     // A discrepancy is allowed for closures, which borrow the type argument
-    // vector of their instantiator, which may be of a super class of the class
+    // vector of their instantiator, which may be of a subclass of the class
     // defining the closure. Truncating the vector to the correct length on
     // instantiation is unnecessary. The vector may therefore be longer.
     ASSERT(type_arguments.IsNull() ||
@@ -8813,31 +8758,19 @@
   }
   Class& other_class = Class::Handle();
   AbstractTypeArguments& other_type_arguments = AbstractTypeArguments::Handle();
-  // In case 'other' is not instantiated, we could simply call
-  // other.InstantiateFrom(other_instantiator), however, we can save the
-  // allocation of a new AbstractType by inlining the code.
-  if (other.IsTypeParameter()) {
-    if (other_instantiator.IsNull()) {
-      // An uninstantiated type parameter is equivalent to dynamic.
-      return true;
-    }
-    const TypeParameter& other_type_param = TypeParameter::Cast(other);
-    AbstractType& instantiated_other = AbstractType::Handle(
-        other_instantiator.TypeAt(other_type_param.index()));
-    if (instantiated_other.IsDynamicType() ||
-        instantiated_other.IsTypeParameter()) {
-      return true;
+  // Note that we may encounter a bound error in checked mode.
+  if (!other.IsInstantiated()) {
+    const AbstractType& instantiated_other = AbstractType::Handle(
+        other.InstantiateFrom(other_instantiator, malformed_error));
+    if ((malformed_error != NULL) && !malformed_error->IsNull()) {
+      ASSERT(FLAG_enable_type_checks);
+      return false;
     }
     other_class = instantiated_other.type_class();
     other_type_arguments = instantiated_other.arguments();
   } else {
     other_class = other.type_class();
     other_type_arguments = other.arguments();
-    if (!other_type_arguments.IsNull() &&
-        !other_type_arguments.IsInstantiated()) {
-      other_type_arguments =
-          other_type_arguments.InstantiateFrom(other_instantiator);
-    }
   }
   return cls.IsSubtypeOf(type_arguments, other_class, other_type_arguments,
                          malformed_error);
@@ -9031,13 +8964,14 @@
 
 bool AbstractType::Equals(const Instance& other) const {
   // AbstractType is an abstract class.
-  UNREACHABLE();
-  return false;
+  ASSERT(raw() == AbstractType::null());
+  return other.IsNull();
 }
 
 
 RawAbstractType* AbstractType::InstantiateFrom(
-    const AbstractTypeArguments& instantiator_type_arguments) const {
+    const AbstractTypeArguments& instantiator_type_arguments,
+    Error* malformed_error) const {
   // AbstractType is an abstract class.
   UNREACHABLE();
   return NULL;
@@ -9052,6 +8986,13 @@
 
 
 RawString* AbstractType::BuildName(NameVisibility name_visibility) const {
+  if (IsBoundedType()) {
+    // TODO(regis): Should the bound be visible in the name for debug purposes
+    // if name_visibility is kInternalName?
+    const AbstractType& type = AbstractType::Handle(
+        BoundedType::Cast(*this).type());
+    return type.BuildName(name_visibility);
+  }
   if (IsTypeParameter()) {
     return TypeParameter::Cast(*this).name();
   }
@@ -9190,42 +9131,48 @@
     return false;
   }
   if (other.IsMalformed()) {
-    ASSERT(FLAG_enable_type_checks);
+    // Note that 'other' may represent an unresolved bound that is checked at
+    // compile time, even in production mode, in which case the resulting
+    // BoundedType is ignored at run time if in production mode.
+    // Therefore, we cannot assert that we are in checked mode here.
     if ((malformed_error != NULL) && malformed_error->IsNull()) {
       *malformed_error = other.malformed_error();
     }
     return false;
   }
-  // AbstractType parameters cannot be handled by Class::TypeTest().
+  if (IsBoundedType() || other.IsBoundedType()) {
+    if (Equals(other)) {
+      return true;
+    }
+    return false;  // TODO(regis): We should return "maybe after instantiation".
+  }
+  // Type parameters cannot be handled by Class::TypeTest().
   // When comparing two uninstantiated function types, one returning type
   // parameter K, the other returning type parameter V, we cannot assume that K
-  // is a subtype of V, or vice versa. We only return true if K == V, i.e. if
-  // they have the same index (both are finalized, so their indices are
-  // comparable).
-  // The same rule applies When checking the upper bound of a still
+  // is a subtype of V, or vice versa. We only return true if K equals V, as
+  // defined by TypeParameter::Equals.
+  // The same rule applies when checking the upper bound of a still
   // uninstantiated type at compile time. Returning false will defer the test
-  // to run time. But there are cases where it can be decided at compile time.
+  // to run time.
+  // We may think that some cases can be decided at compile time.
   // For example, with class A<K, V extends K>, new A<T, T> called from within
-  // a class B<T> will never require a run time bounds check, even it T is
+  // a class B<T> will never require a run time bound check, even if T is
   // uninstantiated at compile time.
+  // However, this is not true, because bounds are ignored in production mode,
+  // and even if we are running in checked mode, we may generate a snapshot
+  // that will be executed in production mode.
   if (IsTypeParameter()) {
     const TypeParameter& type_param = TypeParameter::Cast(*this);
     if (other.IsTypeParameter()) {
       const TypeParameter& other_type_param = TypeParameter::Cast(other);
-      return type_param.index() == other_type_param.index();
-    } else if (FLAG_enable_type_checks) {
-      // In checked mode, if the upper bound of this type is more specific than
-      // the other type, then this type is more specific than the other type.
-      const AbstractType& type_param_bound =
-          AbstractType::Handle(type_param.bound());
-      if (type_param_bound.IsMoreSpecificThan(other, malformed_error)) {
+      if (type_param.Equals(other_type_param)) {
         return true;
       }
     }
-    return false;
+    return false;  // TODO(regis): We should return "maybe after instantiation".
   }
   if (other.IsTypeParameter()) {
-    return false;
+    return false;  // TODO(regis): We should return "maybe after instantiation".
   }
   const Class& cls = Class::Handle(type_class());
   return cls.TypeTest(test_kind,
@@ -9436,14 +9383,22 @@
 
 
 RawAbstractType* Type::InstantiateFrom(
-    const AbstractTypeArguments& instantiator_type_arguments) const {
+    const AbstractTypeArguments& instantiator_type_arguments,
+    Error* malformed_error) const {
   ASSERT(IsFinalized());
   ASSERT(!IsInstantiated());
+  // Return the uninstantiated type unchanged if malformed. No copy needed.
+  if (IsMalformed()) {
+    return raw();
+  }
   AbstractTypeArguments& type_arguments =
       AbstractTypeArguments::Handle(arguments());
-  type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments);
+  type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments,
+                                                  malformed_error);
   const Class& cls = Class::Handle(type_class());
   ASSERT(cls.is_finalized());
+  // This uninstantiated type is not modified, as it can be instantiated
+  // with different instantiators.
   Type& instantiated_type = Type::Handle(
       Type::New(cls, type_arguments, token_pos()));
   ASSERT(type_arguments.IsNull() ||
@@ -9460,7 +9415,7 @@
   if (!other.IsType()) {
     return false;
   }
-  const AbstractType& other_type = AbstractType::Cast(other);
+  const Type& other_type = Type::Cast(other);
   ASSERT(IsFinalized() && other_type.IsFinalized());
   if (IsMalformed() || other_type.IsMalformed()) {
     return false;
@@ -9626,6 +9581,7 @@
 
 
 bool TypeParameter::Equals(const Instance& other) const {
+  ASSERT(IsFinalized());
   if (raw() == other.raw()) {
     return true;
   }
@@ -9633,9 +9589,7 @@
     return false;
   }
   const TypeParameter& other_type_param = TypeParameter::Cast(other);
-  if (IsFinalized() != other_type_param.IsFinalized()) {
-    return false;
-  }
+  ASSERT(other_type_param.IsFinalized());
   if (parameterized_class() != other_type_param.parameterized_class()) {
     return false;
   }
@@ -9668,20 +9622,65 @@
   StorePointer(&raw_ptr()->bound_, value.raw());
 }
 
+
 RawAbstractType* TypeParameter::InstantiateFrom(
-    const AbstractTypeArguments& instantiator_type_arguments) const {
+    const AbstractTypeArguments& instantiator_type_arguments,
+    Error* malformed_error) const {
   ASSERT(IsFinalized());
   if (instantiator_type_arguments.IsNull()) {
     return Type::DynamicType();
   }
+  // Bound checks should never appear in the instantiator type arguments.
+  ASSERT(!AbstractType::Handle(
+      instantiator_type_arguments.TypeAt(index())).IsBoundedType());
   return instantiator_type_arguments.TypeAt(index());
 }
 
 
+void TypeParameter::CheckBound(const AbstractType& bounded_type,
+                               const AbstractType& upper_bound,
+                               Error* malformed_error) const {
+  ASSERT(malformed_error->IsNull());
+  ASSERT(bounded_type.IsFinalized());
+  ASSERT(upper_bound.IsFinalized());
+  ASSERT(!bounded_type.IsMalformed());
+  if (bounded_type.IsSubtypeOf(upper_bound, malformed_error) ||
+      !malformed_error->IsNull()) {
+    return;
+  }
+  // Report the bound error.
+  const String& bounded_type_name = String::Handle(
+      bounded_type.UserVisibleName());
+  const String& upper_bound_name = String::Handle(
+      upper_bound.UserVisibleName());
+  const AbstractType& declared_bound = AbstractType::Handle(bound());
+  const String& declared_bound_name = String::Handle(
+      declared_bound.UserVisibleName());
+  const String& type_param_name = String::Handle(UserVisibleName());
+  const Class& cls = Class::Handle(parameterized_class());
+  const String& class_name = String::Handle(cls.Name());
+  const Script& script = Script::Handle(cls.script());
+  // Since the bound may have been canonicalized, its token index is
+  // meaningless, therefore use the token index of this type parameter.
+  *malformed_error = FormatError(
+      *malformed_error,
+      script,
+      token_pos(),
+      "type parameter '%s' of class '%s' must extend bound '%s', "
+      "but type argument '%s' is not a subtype of '%s'\n",
+      type_param_name.ToCString(),
+      class_name.ToCString(),
+      declared_bound_name.ToCString(),
+      bounded_type_name.ToCString(),
+      upper_bound_name.ToCString());
+}
+
+
 intptr_t TypeParameter::Hash() const {
   ASSERT(IsFinalized());
   uword result = 0;
   result += Class::Handle(parameterized_class()).id();
+  // Do not include the hash of the bound, which could lead to cycles.
   result <<= index();
   return FinalizeHash(result);
 }
@@ -9740,6 +9739,196 @@
 }
 
 
+bool BoundedType::IsMalformed() const {
+  return FLAG_enable_type_checks && AbstractType::Handle(bound()).IsMalformed();
+}
+
+
+RawError* BoundedType::malformed_error() const {
+  ASSERT(FLAG_enable_type_checks);
+  return AbstractType::Handle(bound()).malformed_error();
+}
+
+
+bool BoundedType::Equals(const Instance& other) const {
+  // BoundedType are not canonicalized, because their bound may get finalized
+  // after the BoundedType is created and initialized.
+  if (raw() == other.raw()) {
+    return true;
+  }
+  if (!other.IsBoundedType()) {
+    return false;
+  }
+  const BoundedType& other_bounded = BoundedType::Cast(other);
+  if (type_parameter() != other_bounded.type_parameter()) {
+    // Not a structural compare.
+    // Note that a deep comparison of bounds could lead to cycles.
+    return false;
+  }
+  const AbstractType& this_type = AbstractType::Handle(type());
+  const AbstractType& other_type = AbstractType::Handle(other_bounded.type());
+  if (!this_type.Equals(other_type)) {
+    return false;
+  }
+  const AbstractType& this_bound = AbstractType::Handle(bound());
+  const AbstractType& other_bound = AbstractType::Handle(other_bounded.bound());
+  return this_bound.IsFinalized() &&
+         other_bound.IsFinalized() &&
+         this_bound.Equals(other_bound);
+}
+
+
+void BoundedType::set_type(const AbstractType& value) const {
+  ASSERT(value.IsFinalized());
+  ASSERT(!value.IsMalformed());
+  StorePointer(&raw_ptr()->type_, value.raw());
+}
+
+
+void BoundedType::set_bound(const AbstractType& value) const {
+  // The bound may still be unfinalized because of legal cycles.
+  // It must be finalized before it is checked at run time, though.
+  StorePointer(&raw_ptr()->bound_, value.raw());
+}
+
+
+void BoundedType::set_type_parameter(const TypeParameter& value) const {
+  // A null type parameter is set when marking a type malformed because of a
+  // bound error at compile time.
+  ASSERT(value.IsNull() || value.IsFinalized());
+  StorePointer(&raw_ptr()->type_parameter_, value.raw());
+}
+
+
+void BoundedType::set_is_being_checked(bool value) const {
+  raw_ptr()->is_being_checked_ = value;
+}
+
+
+RawAbstractType* BoundedType::InstantiateFrom(
+    const AbstractTypeArguments& instantiator_type_arguments,
+    Error* malformed_error) const {
+  ASSERT(IsFinalized());
+  AbstractType& bounded_type = AbstractType::Handle(type());
+  if (!bounded_type.IsInstantiated()) {
+    bounded_type = bounded_type.InstantiateFrom(instantiator_type_arguments,
+                                                malformed_error);
+  }
+  if (FLAG_enable_type_checks &&
+      malformed_error->IsNull() &&
+      !is_being_checked()) {
+    // Avoid endless recursion while checking and instantiating bound.
+    set_is_being_checked(true);
+    AbstractType& upper_bound = AbstractType::Handle(bound());
+    ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType());
+    const TypeParameter& type_param = TypeParameter::Handle(type_parameter());
+    if (!upper_bound.IsInstantiated()) {
+      upper_bound = upper_bound.InstantiateFrom(instantiator_type_arguments,
+                                                malformed_error);
+    }
+    if (malformed_error->IsNull()) {
+      type_param.CheckBound(bounded_type, upper_bound, malformed_error);
+    }
+    set_is_being_checked(false);
+  }
+  return bounded_type.raw();
+}
+
+
+intptr_t BoundedType::Hash() const {
+  uword result = 0;
+  result += AbstractType::Handle(type()).Hash();
+  // Do not include the hash of the bound, which could lead to cycles.
+  TypeParameter& type_param = TypeParameter::Handle(type_parameter());
+  if (!type_param.IsNull()) {
+    result += type_param.Hash();
+  }
+return FinalizeHash(result);
+}
+
+
+RawBoundedType* BoundedType::New() {
+  ASSERT(Isolate::Current()->object_store()->bounded_type_class() !=
+         Class::null());
+  RawObject* raw = Object::Allocate(BoundedType::kClassId,
+                                    BoundedType::InstanceSize(),
+                                    Heap::kOld);
+  return reinterpret_cast<RawBoundedType*>(raw);
+}
+
+
+RawBoundedType* BoundedType::New(const AbstractType& type,
+                                 const AbstractType& bound,
+                                 const TypeParameter& type_parameter) {
+  const BoundedType& result = BoundedType::Handle(BoundedType::New());
+  result.set_type(type);
+  result.set_bound(bound);
+  result.set_type_parameter(type_parameter);
+  result.set_is_being_checked(false);
+  return result.raw();
+}
+
+
+const char* BoundedType::ToCString() const {
+  const char* format = "BoundedType: type %s; bound: %s; class: %s";
+  const char* type_cstr = String::Handle(AbstractType::Handle(
+      type()).Name()).ToCString();
+  const char* bound_cstr = String::Handle(AbstractType::Handle(
+      bound()).Name()).ToCString();
+  const Class& cls = Class::Handle(TypeParameter::Handle(
+      type_parameter()).parameterized_class());
+  const char* cls_cstr =
+      cls.IsNull() ? " null" : String::Handle(cls.Name()).ToCString();
+  intptr_t len = OS::SNPrint(
+      NULL, 0, format, type_cstr, bound_cstr, cls_cstr) + 1;
+  char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
+  OS::SNPrint(chars, len, format, type_cstr, bound_cstr, cls_cstr);
+  return chars;
+}
+
+
+
+RawString* MixinAppType::Name() const {
+  return String::New("MixinApplication");
+}
+
+
+const char* MixinAppType::ToCString() const {
+  return "MixinAppType";
+}
+
+
+void MixinAppType::set_super_type(const AbstractType& value) const {
+  StorePointer(&raw_ptr()->super_type_, value.raw());
+}
+
+
+void MixinAppType::set_mixin_types(const Array& value) const {
+  StorePointer(&raw_ptr()->mixin_types_, value.raw());
+}
+
+
+RawMixinAppType* MixinAppType::New() {
+  ASSERT(Isolate::Current()->object_store()->mixin_app_type_class() !=
+         Class::null());
+  // MixinAppType objects do not survive finalization, so allocate
+  // on new heap.
+  RawObject* raw = Object::Allocate(MixinAppType::kClassId,
+                                    MixinAppType::InstanceSize(),
+                                    Heap::kNew);
+  return reinterpret_cast<RawMixinAppType*>(raw);
+}
+
+
+RawMixinAppType* MixinAppType::New(const AbstractType& super_type,
+                                   const Array& mixin_types) {
+  const MixinAppType& result = MixinAppType::Handle(MixinAppType::New());
+  result.set_super_type(super_type);
+  result.set_mixin_types(mixin_types);
+  return result.raw();
+}
+
+
 const char* Number::ToCString() const {
   // Number is an interface. No instances of Number should exist.
   UNREACHABLE();
@@ -11348,6 +11537,7 @@
     intptr_t index = 0;
     for (intptr_t i = 0; i < len; i++) {
       if (IsSpecialCharacter(*CharAddr(str, i)) ||
+          (!raw_str && (*CharAddr(str, i) == '$')) ||
           (!raw_str && (*CharAddr(str, i) == '\\'))) {
         num_escapes += 1;
       }
@@ -11359,6 +11549,10 @@
         *(CharAddr(dststr, index)) = '\\';
         *(CharAddr(dststr, index + 1)) = SpecialCharacter(*CharAddr(str, i));
         index += 2;
+      } else if (!raw_str && (*CharAddr(str, i) == '$')) {
+        *(CharAddr(dststr, index)) = '\\';
+        *(CharAddr(dststr, index + 1)) = '$';
+        index += 2;
       } else if (!raw_str && (*CharAddr(str, i) == '\\')) {
         *(CharAddr(dststr, index)) = '\\';
         *(CharAddr(dststr, index + 1)) = '\\';
@@ -12223,6 +12417,125 @@
 }
 
 
+const intptr_t TypedData::element_size[] = {
+  1,  // kTypedDataInt8ArrayCid.
+  1,  // kTypedDataUint8ArrayCid.
+  1,  // kTypedDataUint8ClampedArrayCid.
+  2,  // kTypedDataInt16ArrayCid.
+  2,  // kTypedDataUint16ArrayCid.
+  4,  // kTypedDataInt32ArrayCid.
+  4,  // kTypedDataUint32ArrayCid.
+  8,  // kTypedDataInt64ArrayCid.
+  8,  // kTypedDataUint64ArrayCid.
+  4,  // kTypedDataFloat32ArrayCid.
+  8,  // kTypedDataFloat64ArrayCid.
+};
+
+
+void TypedData::Copy(const TypedData& dst,
+                     intptr_t dst_offset_in_bytes,
+                     const TypedData& src,
+                     intptr_t src_offset_in_bytes,
+                     intptr_t length_in_bytes) {
+  ASSERT(Utils::RangeCheck(src_offset_in_bytes,
+                           length_in_bytes,
+                           src.LengthInBytes()));
+  ASSERT(Utils::RangeCheck(dst_offset_in_bytes,
+                           length_in_bytes,
+                           dst.LengthInBytes()));
+  {
+    NoGCScope no_gc;
+    if (length_in_bytes > 0) {
+      memmove(dst.DataAddr(dst_offset_in_bytes),
+              src.DataAddr(src_offset_in_bytes),
+              length_in_bytes);
+    }
+  }
+}
+
+
+RawTypedData* TypedData::New(intptr_t class_id,
+                             intptr_t len,
+                             Heap::Space space) {
+  // TODO(asiva): Add a check for maximum elements.
+  TypedData& result = TypedData::Handle();
+  {
+    // The len field has already been checked by the caller, we only assert
+    // here that it is within a valid range.
+    ASSERT((len >= 0) &&
+           (len < (kSmiMax / TypedData::ElementSizeInBytes(class_id))));
+    intptr_t lengthInBytes = len * ElementSizeInBytes(class_id);
+    RawObject* raw = Object::Allocate(class_id,
+                                      TypedData::InstanceSize(lengthInBytes),
+                                      space);
+    NoGCScope no_gc;
+    result ^= raw;
+    result.SetLength(len);
+    if (len > 0) {
+      memset(result.DataAddr(0), 0, lengthInBytes);
+    }
+  }
+  return result.raw();
+}
+
+
+const char* TypedData::ToCString() const {
+  return "TypedData";
+}
+
+
+FinalizablePersistentHandle* ExternalTypedData::AddFinalizer(
+    void* peer, Dart_WeakPersistentHandleFinalizer callback) const {
+  SetPeer(peer);
+  return dart::AddFinalizer(*this, peer, callback);
+}
+
+
+void ExternalTypedData::Copy(const ExternalTypedData& dst,
+                             intptr_t dst_offset_in_bytes,
+                             const ExternalTypedData& src,
+                             intptr_t src_offset_in_bytes,
+                             intptr_t length_in_bytes) {
+  ASSERT(Utils::RangeCheck(src_offset_in_bytes,
+                           length_in_bytes,
+                           src.LengthInBytes()));
+  ASSERT(Utils::RangeCheck(dst_offset_in_bytes,
+                           length_in_bytes,
+                           dst.LengthInBytes()));
+  {
+    NoGCScope no_gc;
+    if (length_in_bytes > 0) {
+      memmove(dst.DataAddr(dst_offset_in_bytes),
+              src.DataAddr(src_offset_in_bytes),
+              length_in_bytes);
+    }
+  }
+}
+
+
+RawExternalTypedData* ExternalTypedData::New(intptr_t class_id,
+                                             uint8_t* data,
+                                             intptr_t len,
+                                             Heap::Space space) {
+  ExternalTypedData& result = ExternalTypedData::Handle();
+  {
+    RawObject* raw = Object::Allocate(class_id,
+                                      ExternalTypedData::InstanceSize(),
+                                      space);
+    NoGCScope no_gc;
+    result ^= raw;
+    result.SetLength(len);
+    result.SetData(data);
+  }
+  return result.raw();
+}
+
+
+const char* ExternalTypedData::ToCString() const {
+  return "ExternalTypedData";
+}
+
+
 void ByteArray::Copy(void* dst,
                      const ByteArray& src,
                      intptr_t src_offset,
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index e2ed725..11a369e 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -652,8 +652,10 @@
   }
 
   // The super type of this class, Object type if not explicitly specified.
-  RawType* super_type() const { return raw_ptr()->super_type_; }
-  void set_super_type(const Type& value) const;
+  // Note that the super type may be bounded, as in this example:
+  // class C<T> extends S<T> { }; class S<T extends num> { };
+  RawAbstractType* super_type() const { return raw_ptr()->super_type_; }
+  void set_super_type(const AbstractType& value) const;
   static intptr_t super_type_offset() {
     return OFFSET_OF(RawClass, super_type_);
   }
@@ -831,6 +833,12 @@
   // Allocate the raw string classes.
   static RawClass* NewStringClass(intptr_t class_id);
 
+  // Allocate the raw TypedData classes.
+  static RawClass* NewTypedDataClass(intptr_t class_id);
+
+  // Allocate the raw ExternalTypedData classes.
+  static RawClass* NewExternalTypedDataClass(intptr_t class_id);
+
   // Allocate a class representing a function signature described by
   // signature_function, which must be a closure function or a signature
   // function.
@@ -951,8 +959,10 @@
   // not refer to type parameters. Otherwise, return a new type argument vector
   // where each reference to a type parameter is replaced with the corresponding
   // type of the instantiator type argument vector.
+  // If malformed_error is not NULL, it may be set to reflect a bound error.
   virtual RawAbstractTypeArguments* InstantiateFrom(
-      const AbstractTypeArguments& instantiator_type_arguments) const;
+      const AbstractTypeArguments& instantiator_type_arguments,
+      Error* malformed_error) const;
 
   // Do not canonicalize InstantiatedTypeArguments or NULL objects
   virtual RawAbstractTypeArguments* Canonicalize() const { return this->raw(); }
@@ -982,12 +992,6 @@
     return IsDynamicTypes(true, len);
   }
 
-  // Check that this type argument vector is within the declared bounds of the
-  // given class. If not, set malformed_error (if not yet set).
-  bool IsWithinBoundsOf(const Class& cls,
-                        const AbstractTypeArguments& bounds_instantiator,
-                        Error* malformed_error) const;
-
   // Check the subtype relationship, considering only a prefix of length 'len'.
   bool IsSubtypeOf(const AbstractTypeArguments& other,
                    intptr_t len,
@@ -1012,6 +1016,7 @@
   virtual bool IsResolved() const;
   virtual bool IsInstantiated() const;
   virtual bool IsUninstantiatedIdentity() const;
+  virtual bool IsBounded() const;
 
   virtual intptr_t Hash() const;
 
@@ -1054,11 +1059,13 @@
   virtual bool IsResolved() const;
   virtual bool IsInstantiated() const;
   virtual bool IsUninstantiatedIdentity() const;
+  virtual bool IsBounded() const;
   // Canonicalize only if instantiated, otherwise returns 'this'.
   virtual RawAbstractTypeArguments* Canonicalize() const;
 
   virtual RawAbstractTypeArguments* InstantiateFrom(
-      const AbstractTypeArguments& instantiator_type_arguments) const;
+      const AbstractTypeArguments& instantiator_type_arguments,
+      Error* malformed_error) const;
 
   static const intptr_t kBytesPerElement = kWordSize;
   static const intptr_t kMaxElements = kSmiMax / kBytesPerElement;
@@ -1109,6 +1116,7 @@
   virtual bool IsResolved() const { return true; }
   virtual bool IsInstantiated() const { return true; }
   virtual bool IsUninstantiatedIdentity() const  { return false; }
+  virtual bool IsBounded() const { return false; }  // Bounds were checked.
 
   RawAbstractTypeArguments* uninstantiated_type_arguments() const {
     return raw_ptr()->uninstantiated_type_arguments_;
@@ -1922,6 +1930,7 @@
   RawString* url() const { return raw_ptr()->url_; }
   bool HasSource() const;
   RawString* Source() const;
+  RawString* GenerateSource() const;  // Generates source code from Tokenstream.
   RawScript::Kind kind() const {
     return static_cast<RawScript::Kind>(raw_ptr()->kind_);
   }
@@ -2127,6 +2136,7 @@
   static RawLibrary* MirrorsLibrary();
   static RawLibrary* NativeWrappersLibrary();
   static RawLibrary* ScalarlistLibrary();
+  static RawLibrary* TypedDataLibrary();
   static RawLibrary* UriLibrary();
   static RawLibrary* UtfLibrary();
 
@@ -3399,8 +3409,10 @@
 
   // Instantiate this type using the given type argument vector.
   // Return a new type, or return 'this' if it is already instantiated.
+  // If malformed_error is not NULL, it may be set to reflect a bound error.
   virtual RawAbstractType* InstantiateFrom(
-      const AbstractTypeArguments& instantiator_type_arguments) const;
+      const AbstractTypeArguments& instantiator_type_arguments,
+      Error* malformed_error) const;
 
   // Return the canonical version of this type.
   virtual RawAbstractType* Canonicalize() const;
@@ -3526,7 +3538,8 @@
   virtual bool IsInstantiated() const;
   virtual bool Equals(const Instance& other) const;
   virtual RawAbstractType* InstantiateFrom(
-      const AbstractTypeArguments& instantiator_type_arguments) const;
+      const AbstractTypeArguments& instantiator_type_arguments,
+      Error* malformed_error) const;
   virtual RawAbstractType* Canonicalize() const;
 
   virtual intptr_t Hash() const;
@@ -3602,7 +3615,7 @@
 // Upon finalization, the TypeParameter index is changed to reflect its position
 // as type argument (rather than type parameter) of the parameterized class.
 // If the type parameter is declared without an extends clause, its bound is set
-// to the DynamicType.
+// to the ObjectType.
 class TypeParameter : public AbstractType {
  public:
   virtual bool IsFinalized() const {
@@ -3622,11 +3635,15 @@
   void set_index(intptr_t value) const;
   RawAbstractType* bound() const { return raw_ptr()->bound_; }
   void set_bound(const AbstractType& value) const;
+  void CheckBound(const AbstractType& bounded_type,
+                  const AbstractType& upper_bound,
+                  Error* malformed_error) const;
   virtual intptr_t token_pos() const { return raw_ptr()->token_pos_; }
   virtual bool IsInstantiated() const { return false; }
   virtual bool Equals(const Instance& other) const;
   virtual RawAbstractType* InstantiateFrom(
-      const AbstractTypeArguments& instantiator_type_arguments) const;
+      const AbstractTypeArguments& instantiator_type_arguments,
+      Error* malformed_error) const;
   virtual RawAbstractType* Canonicalize() const { return raw(); }
 
   virtual intptr_t Hash() const;
@@ -3653,6 +3670,122 @@
 };
 
 
+// A BoundedType represents a type instantiated at compile time from a type
+// parameter specifying a bound that either cannot be checked at compile time
+// because the type or the bound are still uninstantiated or can be checked and
+// would trigger a bound error in checked mode. The bound must be checked at
+// runtime once the type and its bound are instantiated and when the execution
+// mode is known to be checked mode.
+class BoundedType : public AbstractType {
+ public:
+  virtual bool IsFinalized() const {
+    return AbstractType::Handle(type()).IsFinalized();
+  }
+  virtual bool IsBeingFinalized() const {
+    return AbstractType::Handle(type()).IsBeingFinalized();
+  }
+  virtual bool IsMalformed() const;
+  virtual RawError* malformed_error() const;
+  virtual bool IsResolved() const { return true; }
+  virtual bool HasResolvedTypeClass() const {
+    return AbstractType::Handle(type()).HasResolvedTypeClass();
+  }
+  virtual RawClass* type_class() const {
+    return AbstractType::Handle(type()).type_class();
+  }
+  virtual RawUnresolvedClass* unresolved_class() const {
+    return AbstractType::Handle(type()).unresolved_class();
+  }
+  virtual RawAbstractTypeArguments* arguments() const {
+    return AbstractType::Handle(type()).arguments();
+  }
+  RawAbstractType* type() const { return raw_ptr()->type_; }
+  RawAbstractType* bound() const { return raw_ptr()->bound_; }
+  RawTypeParameter* type_parameter() const {
+    return raw_ptr()->type_parameter_;
+  }
+  virtual intptr_t token_pos() const {
+    return AbstractType::Handle(type()).token_pos();
+  }
+  virtual bool IsInstantiated() const {
+    return AbstractType::Handle(type()).IsInstantiated();
+  }
+  virtual bool Equals(const Instance& other) const;
+  virtual RawAbstractType* InstantiateFrom(
+      const AbstractTypeArguments& instantiator_type_arguments,
+      Error* malformed_error) const;
+  virtual RawAbstractType* Canonicalize() const { return raw(); }
+
+  virtual intptr_t Hash() const;
+
+  static intptr_t InstanceSize() {
+    return RoundedAllocationSize(sizeof(RawBoundedType));
+  }
+
+  static RawBoundedType* New(const AbstractType& type,
+                             const AbstractType& bound,
+                             const TypeParameter& type_parameter);
+
+ private:
+  void set_type(const AbstractType& value) const;
+  void set_bound(const AbstractType& value) const;
+  void set_type_parameter(const TypeParameter& value) const;
+
+  bool is_being_checked() const {
+    return raw_ptr()->is_being_checked_;
+  }
+  void set_is_being_checked(bool value) const;
+
+  static RawBoundedType* New();
+
+  FINAL_HEAP_OBJECT_IMPLEMENTATION(BoundedType, AbstractType);
+  friend class Class;
+};
+
+
+// A MixinAppType represents a mixin application clause, e.g.
+// "S<T> with M<U, N>". The class finalizer builds the type
+// parameters and arguments at finalization time.
+// MixinType objects do not survive finalization, so they do not
+// need to be written to and read from snapshots.
+class MixinAppType : public AbstractType {
+ public:
+  // MixinAppType objects are replaced with their actual finalized type.
+  virtual bool IsFinalized() const { return false; }
+  virtual bool IsMalformed() const { return false; }
+  virtual bool IsResolved() const { return false; }
+  virtual bool HasResolvedTypeClass() const { return false; }
+  virtual RawString* Name() const;
+
+  virtual intptr_t token_pos() const {
+    return AbstractType::Handle(super_type()).token_pos();
+  }
+
+  virtual RawAbstractTypeArguments* arguments() const {
+    return AbstractTypeArguments::null();
+  }
+
+  RawAbstractType* super_type() const { return raw_ptr()->super_type_; }
+  RawArray* mixin_types() const { return raw_ptr()->mixin_types_; }
+
+  static intptr_t InstanceSize() {
+    return RoundedAllocationSize(sizeof(RawMixinAppType));
+  }
+
+  static RawMixinAppType* New(const AbstractType& super_type,
+                              const Array& mixin_types);
+
+ private:
+  void set_super_type(const AbstractType& value) const;
+  void set_mixin_types(const Array& value) const;
+
+  static RawMixinAppType* New();
+
+  FINAL_HEAP_OBJECT_IMPLEMENTATION(MixinAppType, AbstractType);
+  friend class Class;
+};
+
+
 class Number : public Instance {
  public:
   // TODO(iposva): Fill in a useful Number interface.
@@ -4766,7 +4899,7 @@
 class Float32x4 : public Instance {
  public:
   static RawFloat32x4* New(float value0, float value1, float value2,
-                                float value3, Heap::Space space = Heap::kNew);
+                           float value3, Heap::Space space = Heap::kNew);
   static RawFloat32x4* New(simd_value_t value, Heap::Space space = Heap::kNew);
 
   float x() const;
@@ -4799,7 +4932,7 @@
 class Uint32x4 : public Instance {
  public:
   static RawUint32x4* New(uint32_t value0, uint32_t value1, uint32_t value2,
-                             uint32_t value3, Heap::Space space = Heap::kNew);
+                          uint32_t value3, Heap::Space space = Heap::kNew);
   static RawUint32x4* New(simd_value_t value, Heap::Space space = Heap::kNew);
 
   uint32_t x() const;
@@ -4829,6 +4962,197 @@
 };
 
 
+class TypedData : public Instance {
+ public:
+  intptr_t Length() const {
+    ASSERT(!IsNull());
+    return Smi::Value(raw_ptr()->length_);
+  }
+
+  intptr_t ElementSizeInBytes() const {
+    intptr_t cid = raw()->GetClassId();
+    return ElementSizeInBytes(cid);
+  }
+
+  intptr_t LengthInBytes() const {
+    intptr_t cid = raw()->GetClassId();
+    return (ElementSizeInBytes(cid) * Length());
+  }
+
+  void* DataAddr(intptr_t byte_offset) const {
+    ASSERT((byte_offset >= 0) && (byte_offset < LengthInBytes()));
+    return reinterpret_cast<void*>(raw_ptr()->data_ + byte_offset);
+  }
+
+#define TYPED_GETTER_SETTER(name, type)                                        \
+  type Get##name(intptr_t byte_offset) const {                                 \
+    return *reinterpret_cast<type*>(DataAddr(byte_offset));                    \
+  }                                                                            \
+  void Set##name(intptr_t byte_offset, type value) const {                     \
+    *reinterpret_cast<type*>(DataAddr(byte_offset)) = value;                   \
+  }
+  TYPED_GETTER_SETTER(Int8, int8_t)
+  TYPED_GETTER_SETTER(Uint8, uint8_t)
+  TYPED_GETTER_SETTER(Int16, int16_t)
+  TYPED_GETTER_SETTER(Uint16, uint16_t)
+  TYPED_GETTER_SETTER(Int32, int32_t)
+  TYPED_GETTER_SETTER(Uint32, uint32_t)
+  TYPED_GETTER_SETTER(Int64, int64_t)
+  TYPED_GETTER_SETTER(Uint64, uint64_t)
+  TYPED_GETTER_SETTER(Float32, float)
+  TYPED_GETTER_SETTER(Float64, double)
+
+  static intptr_t length_offset() {
+    return OFFSET_OF(RawTypedData, length_);
+  }
+
+  static intptr_t data_offset() {
+    return OFFSET_OF(RawTypedData, data_);
+  }
+
+  static intptr_t InstanceSize() {
+    ASSERT(sizeof(RawTypedData) == OFFSET_OF(RawTypedData, data_));
+    return 0;
+  }
+
+  static intptr_t InstanceSize(intptr_t lengthInBytes) {
+    ASSERT(0 <= lengthInBytes && lengthInBytes <= kSmiMax);
+    return RoundedAllocationSize(sizeof(RawTypedData) + lengthInBytes);
+  }
+
+  static intptr_t ElementSizeInBytes(intptr_t class_id) {
+    ASSERT(RawObject::IsTypedDataClassId(class_id));
+    return element_size[class_id - kTypedDataInt8ArrayCid];
+  }
+
+  static intptr_t MaxElements(intptr_t class_id) {
+    ASSERT(RawObject::IsTypedDataClassId(class_id));
+    return (kSmiMax / ElementSizeInBytes(class_id));
+  }
+
+  static RawTypedData* New(intptr_t class_id,
+                           intptr_t len,
+                           Heap::Space space = Heap::kNew);
+
+  static void Copy(const TypedData& dst,
+                   intptr_t dst_offset_in_bytes,
+                   const TypedData& src,
+                   intptr_t src_offset_in_bytes,
+                   intptr_t length_in_bytes);
+
+ protected:
+  void SetLength(intptr_t value) const {
+    raw_ptr()->length_ = Smi::New(value);
+  }
+
+ private:
+  static const intptr_t element_size[];
+
+  FINAL_HEAP_OBJECT_IMPLEMENTATION(TypedData, Instance);
+  friend class Class;
+  friend class ExternalTypedData;
+};
+
+
+class ExternalTypedData : public Instance {
+ public:
+  intptr_t Length() const {
+    ASSERT(!IsNull());
+    return Smi::Value(raw_ptr()->length_);
+  }
+
+  intptr_t ElementSizeInBytes() const {
+    intptr_t cid = raw()->GetClassId();
+    return ElementSizeInBytes(cid);
+  }
+
+  intptr_t LengthInBytes() const {
+    intptr_t cid = raw()->GetClassId();
+    return (ElementSizeInBytes(cid) * Length());
+  }
+
+  void* GetPeer() const {
+    return raw_ptr()->peer_;
+  }
+
+  void* DataAddr(intptr_t byte_offset) const {
+    ASSERT((byte_offset >= 0) && (byte_offset < LengthInBytes()));
+    return reinterpret_cast<void*>(raw_ptr()->data_ + byte_offset);
+  }
+
+#define TYPED_GETTER_SETTER(name, type)                                        \
+  type Get##name(intptr_t byte_offset) const {                                 \
+    return *reinterpret_cast<type*>(DataAddr(byte_offset));                    \
+  }                                                                            \
+  void Set##name(intptr_t byte_offset, type value) const {                     \
+    *reinterpret_cast<type*>(DataAddr(byte_offset)) = value;                   \
+  }
+  TYPED_GETTER_SETTER(Int8, int8_t)
+  TYPED_GETTER_SETTER(Uint8, uint8_t)
+  TYPED_GETTER_SETTER(Int16, int16_t)
+  TYPED_GETTER_SETTER(Uint16, uint16_t)
+  TYPED_GETTER_SETTER(Int32, int32_t)
+  TYPED_GETTER_SETTER(Uint32, uint32_t)
+  TYPED_GETTER_SETTER(Int64, int64_t)
+  TYPED_GETTER_SETTER(Uint64, uint64_t)
+  TYPED_GETTER_SETTER(Float32, float)
+  TYPED_GETTER_SETTER(Float64, double)
+
+  FinalizablePersistentHandle* AddFinalizer(
+      void* peer, Dart_WeakPersistentHandleFinalizer callback) const;
+
+  static intptr_t length_offset() {
+    return OFFSET_OF(RawExternalTypedData, length_);
+  }
+
+  static intptr_t data_offset() {
+    return OFFSET_OF(RawExternalTypedData, data_);
+  }
+
+  static intptr_t InstanceSize() {
+    return RoundedAllocationSize(sizeof(RawExternalTypedData));
+  }
+
+  static intptr_t ElementSizeInBytes(intptr_t class_id) {
+    ASSERT(RawObject::IsExternalTypedDataClassId(class_id));
+    return TypedData::element_size[class_id - kExternalTypedDataInt8ArrayCid];
+  }
+
+  static intptr_t MaxElements(intptr_t class_id) {
+    ASSERT(RawObject::IsExternalTypedDataClassId(class_id));
+    return (kSmiMax / ElementSizeInBytes(class_id));
+  }
+
+  static RawExternalTypedData* New(intptr_t class_id,
+                                   uint8_t* data,
+                                   intptr_t len,
+                                   Heap::Space space = Heap::kNew);
+
+  static void Copy(const ExternalTypedData& dst,
+                   intptr_t dst_offset_in_bytes,
+                   const ExternalTypedData& src,
+                   intptr_t src_offset_in_bytes,
+                   intptr_t length_in_bytes);
+
+ protected:
+  void SetLength(intptr_t value) const {
+    raw_ptr()->length_ = Smi::New(value);
+  }
+
+  void SetData(uint8_t* data) const {
+    raw_ptr()->data_ = data;
+  }
+
+  void SetPeer(void* peer) const {
+    raw_ptr()->peer_ = peer;
+  }
+
+ private:
+  FINAL_HEAP_OBJECT_IMPLEMENTATION(ExternalTypedData, Instance);
+  friend class Class;
+};
+
+
 class ByteArray : public Instance {
  public:
   intptr_t Length() const {
@@ -5149,12 +5473,12 @@
                              intptr_t len,
                              Heap::Space space = Heap::kNew);
 
- private:
   uint8_t* ByteAddr(intptr_t byte_offset) const {
     ASSERT((byte_offset >= 0) && (byte_offset < ByteLength()));
     return reinterpret_cast<uint8_t*>(&raw_ptr()->data_) + byte_offset;
   }
 
+ private:
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Uint16Array, ByteArray);
   friend class ByteArray;
   friend class Class;
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index 31b9ccc..a59973d 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -61,6 +61,7 @@
     external_uint64_array_class_(Class::null()),
     external_float32_array_class_(Class::null()),
     external_float64_array_class_(Class::null()),
+    typeddata_classes_(Array::null()),
     stacktrace_class_(Class::null()),
     jsregexp_class_(Class::null()),
     weak_property_class_(Class::null()),
@@ -78,6 +79,7 @@
     native_wrappers_library_(Library::null()),
     root_library_(Library::null()),
     scalarlist_library_(Library::null()),
+    typeddata_library_(Library::null()),
     uri_library_(Library::null()),
     utf_library_(Library::null()),
     libraries_(GrowableObjectArray::null()),
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 1811803..60131b5 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -63,6 +63,16 @@
     type_parameter_class_ = value.raw();
   }
 
+  RawClass* bounded_type_class() const { return bounded_type_class_; }
+  void set_bounded_type_class(const Class& value) {
+    bounded_type_class_ = value.raw();
+  }
+
+  RawClass* mixin_app_type_class() const { return mixin_app_type_class_; }
+  void set_mixin_app_type_class(const Class& value) {
+    mixin_app_type_class_ = value.raw();
+  }
+
   RawType* number_type() const { return number_type_; }
   void set_number_type(const Type& value) {
     number_type_ = value.raw();
@@ -346,6 +356,13 @@
     external_float64_array_class_ = value.raw();
   }
 
+  RawArray* typeddata_classes() const {
+    return typeddata_classes_;
+  }
+  void set_typeddata_classes(const Array& value) {
+    typeddata_classes_ = value.raw();
+  }
+
   RawClass* stacktrace_class() const {
     return stacktrace_class_;
   }
@@ -471,6 +488,13 @@
     scalarlist_library_ = value.raw();
   }
 
+  RawLibrary* typeddata_library() const {
+    return typeddata_library_;
+  }
+  void set_typeddata_library(const Library& value) {
+    typeddata_library_ = value.raw();
+  }
+
   RawLibrary* uri_library() const {
     return uri_library_;
   }
@@ -581,6 +605,8 @@
   RawType* function_type_;
   RawClass* type_class_;
   RawClass* type_parameter_class_;
+  RawClass* bounded_type_class_;
+  RawClass* mixin_app_type_class_;
   RawType* number_type_;
   RawType* int_type_;
   RawClass* integer_implementation_class_;
@@ -629,6 +655,7 @@
   RawClass* external_float32x4_array_class_;
   RawClass* external_float32_array_class_;
   RawClass* external_float64_array_class_;
+  RawArray* typeddata_classes_;
   RawClass* stacktrace_class_;
   RawClass* jsregexp_class_;
   RawClass* weak_property_class_;
@@ -648,6 +675,7 @@
   RawLibrary* native_wrappers_library_;
   RawLibrary* root_library_;
   RawLibrary* scalarlist_library_;
+  RawLibrary* typeddata_library_;
   RawLibrary* uri_library_;
   RawLibrary* utf_library_;
   RawGrowableObjectArray* libraries_;
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 47c8b1e..06772b9 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -158,10 +158,10 @@
   // Compute start indices to parameters and locals, and the number of
   // parameters to copy.
   if (num_opt_params == 0) {
-    // Parameter i will be at fp[1 + num_params - i] and local variable
-    // j will be at fp[kFirstLocalSlotIndex - j].
+    // Parameter i will be at fp[kLastParamSlotIndex + num_params - 1 - i] and
+    // local variable j will be at fp[kFirstLocalSlotIndex - j].
     ASSERT(GetSavedArgumentsDescriptorVar() == NULL);
-    first_parameter_index_ = 1 + num_params;
+    first_parameter_index_ = kLastParamSlotIndex + num_params - 1;
     first_stack_local_index_ = kFirstLocalSlotIndex;
     num_copied_params_ = 0;
   } else {
@@ -3244,19 +3244,17 @@
     }
     cls.set_type_parameters(orig_type_parameters);
   }
-  Type& super_type = Type::Handle();
+  AbstractType& super_type = Type::Handle();
   if (CurrentToken() == Token::kEXTENDS) {
     ConsumeToken();
     const intptr_t type_pos = TokenPos();
-    const AbstractType& type = AbstractType::Handle(
-        ParseType(ClassFinalizer::kTryResolve));
-    if (type.IsTypeParameter()) {
+    super_type = ParseType(ClassFinalizer::kTryResolve);
+    if (super_type.IsTypeParameter()) {
       ErrorMsg(type_pos,
                "class '%s' may not extend type parameter '%s'",
                class_name.ToCString(),
-               String::Handle(type.UserVisibleName()).ToCString());
+               String::Handle(super_type.UserVisibleName()).ToCString());
     }
-    super_type ^= type.raw();
     if (CurrentToken() == Token::kWITH) {
       super_type = ParseMixins(super_type);
     }
@@ -3416,12 +3414,6 @@
   set_current_class(mixin_application);
   ParseTypeParameters(mixin_application);
 
-  // TODO(hausner): Handle mixin application aliases with generics.
-  if (mixin_application.NumTypeParameters() > 0) {
-    ErrorMsg(classname_pos,
-             "type parameters on mixin applications not yet supported");
-  }
-
   ExpectToken(Token::kASSIGN);
 
   if (CurrentToken() == Token::kABSTRACT) {
@@ -3429,55 +3421,34 @@
     ConsumeToken();
   }
 
-  const intptr_t supertype_pos = TokenPos();
-  const AbstractType& type =
+  const intptr_t type_pos = TokenPos();
+  AbstractType& type =
       AbstractType::Handle(ParseType(ClassFinalizer::kTryResolve));
   if (type.IsTypeParameter()) {
-    ErrorMsg(supertype_pos,
+    ErrorMsg(type_pos,
              "class '%s' may not extend type parameter '%s'",
              class_name.ToCString(),
              String::Handle(type.UserVisibleName()).ToCString());
   }
-  Type& mixin_super_type = Type::Handle();
-  mixin_super_type ^= type.raw();
 
   if (CurrentToken() != Token::kWITH) {
     ErrorMsg("mixin application 'with Type' expected");
   }
+  type = ParseMixins(type);
 
-  const Type& mixin_application_type =
-      Type::Handle(ParseMixins(mixin_super_type));
-  // TODO(hausner): Implement generic mixin support.
-  if (mixin_application_type.arguments() != AbstractTypeArguments::null()) {
-    ErrorMsg(mixin_application_type.token_pos(),
-             "mixin class with type arguments not yet supported");
-  }
+  // TODO(hausner): treat the mixin application as an alias, not as a base
+  // class whose super class is the mixin application!
+  mixin_application.set_super_type(type);
 
-  // The result of ParseMixins() is a chain of super types that is the
-  // result of the mixin composition 'S with M1, M2, ...'. The mixin
-  // application classes are anonymous (i.e. not registered in the current
-  // library). We steal the super type and mixin type from the bottom of
-  // the chain and add it to the named mixin application class. The bottom
-  // anonymous class in the chain is thrown away.
-  const Class& anon_mixin_app_class =
-      Class::Handle(mixin_application_type.type_class());
-  mixin_application.set_super_type(
-      Type::Handle(anon_mixin_app_class.super_type()));
-  mixin_application.set_mixin(Type::Handle(anon_mixin_app_class.mixin()));
-  const Array& interfaces = Array::Handle(anon_mixin_app_class.interfaces());
-  mixin_application.set_interfaces(interfaces);
   AddImplicitConstructor(mixin_application);
-
   if (CurrentToken() == Token::kIMPLEMENTS) {
     Array& interfaces = Array::Handle();
     const intptr_t interfaces_pos = TokenPos();
-    const Type& super_type = Type::Handle(mixin_application.super_type());
-    interfaces = ParseInterfaceList(super_type);
+    interfaces = ParseInterfaceList(type);
     AddInterfaces(interfaces_pos, mixin_application, interfaces);
   }
-
-  pending_classes.Add(mixin_application, Heap::kOld);
   ExpectSemicolon();
+  pending_classes.Add(mixin_application, Heap::kOld);
 }
 
 
@@ -3809,7 +3780,7 @@
 
 
 // Parse and return an array of interface types.
-RawArray* Parser::ParseInterfaceList(const Type& super_type) {
+RawArray* Parser::ParseInterfaceList(const AbstractType& super_type) {
   TRACE_PARSER("ParseInterfaceList");
   ASSERT(CurrentToken() == Token::kIMPLEMENTS);
   const GrowableObjectArray& interfaces =
@@ -3845,22 +3816,20 @@
 }
 
 
-RawType* Parser::ParseMixins(const Type& super_type) {
+RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) {
   TRACE_PARSER("ParseMixins");
   ASSERT(CurrentToken() == Token::kWITH);
 
-  // TODO(hausner): Remove this restriction.
-  if (super_type.arguments() != AbstractTypeArguments::null()) {
-    ErrorMsg(super_type.token_pos(),
-             "super class in mixin application may not have type arguments");
-  }
-
+  const GrowableObjectArray& mixin_apps =
+      GrowableObjectArray::Handle(GrowableObjectArray::New());
   AbstractType& mixin_type = AbstractType::Handle();
   AbstractTypeArguments& mixin_type_arguments =
       AbstractTypeArguments::Handle();
   Class& mixin_application = Class::Handle();
   Type& mixin_application_type = Type::Handle();
-  Type& mixin_super_type = Type::Handle(super_type.raw());
+  Type& mixin_super_type = Type::Handle();
+  ASSERT(super_type.IsType());
+  mixin_super_type ^= super_type.raw();
   Array& mixin_application_interfaces = Array::Handle();
   do {
     ConsumeToken();
@@ -3904,8 +3873,10 @@
                                        mixin_type_arguments,
                                        mixin_pos);
     mixin_super_type = mixin_application_type.raw();
+    mixin_apps.Add(mixin_application_type);
   } while (CurrentToken() == Token::kCOMMA);
-  return mixin_application_type.raw();
+  return MixinAppType::New(super_type,
+                           Array::Handle(Array::MakeArray(mixin_apps)));
 }
 
 
@@ -5931,10 +5902,9 @@
   if (IsForInStatement()) {
     return ParseForInStatement(for_pos, label);
   }
-  OpenBlock();
-  // The label is added to the implicit scope that also contains
-  // the loop variable declarations.
-  current_block_->scope->AddLabel(label);
+  // Open a block that contains the loop variable. Make it a loop block so
+  // that we allocate a new context if the loop variable is captured.
+  OpenLoopBlock();
   AstNode* initializer = NULL;
   const intptr_t init_pos = TokenPos();
   LocalScope* init_scope = current_block_->scope;
@@ -5953,13 +5923,12 @@
   ExpectSemicolon();
   AstNode* increment = NULL;
   const intptr_t incr_pos = TokenPos();
-  LocalScope* incr_scope = current_block_->scope;
   if (CurrentToken() != Token::kRPAREN) {
     increment = ParseExprList();
   }
   ExpectToken(Token::kRPAREN);
   const bool parsing_loop_body =  true;
-  SequenceNode* body = ParseNestedStatement(parsing_loop_body, NULL);
+  SequenceNode* body = ParseNestedStatement(parsing_loop_body, label);
 
   // Check whether any of the variables in the initializer part of
   // the for statement are captured by a closure. If so, we insert a
@@ -5968,7 +5937,7 @@
   for (int i = 0; i < init_scope->num_variables(); i++) {
     if (init_scope->VariableAt(i)->is_captured() &&
         (init_scope->VariableAt(i)->owner() == init_scope)) {
-      SequenceNode* incr_sequence = new SequenceNode(incr_pos, incr_scope);
+      SequenceNode* incr_sequence = new SequenceNode(incr_pos, NULL);
       incr_sequence->Add(new CloneContextNode(for_pos));
       if (increment != NULL) {
         incr_sequence->Add(increment);
@@ -5977,13 +5946,15 @@
       break;
     }
   }
-  CloseBlock();
-  return new ForNode(for_pos,
-                     label,
-                     NodeAsSequenceNode(init_pos, initializer, init_scope),
-                     condition,
-                     NodeAsSequenceNode(incr_pos, increment, incr_scope),
-                     body);
+  AstNode* for_node =
+      new ForNode(for_pos,
+                  label,
+                  NodeAsSequenceNode(init_pos, initializer, NULL),
+                  condition,
+                  NodeAsSequenceNode(incr_pos, increment, NULL),
+                  body);
+  current_block_->statements->Add(for_node);
+  return CloseBlock();
 }
 
 
@@ -9332,12 +9303,16 @@
       if (!redirect_type.IsMalformed() && !redirect_type.IsInstantiated()) {
         // The type arguments of the redirection type are instantiated from the
         // type arguments of the parsed type of the 'new' or 'const' expression.
-        redirect_type ^= redirect_type.InstantiateFrom(type_arguments);
+        Error& malformed_error = Error::Handle();
+        redirect_type ^= redirect_type.InstantiateFrom(type_arguments,
+                                                       &malformed_error);
+        if (!malformed_error.IsNull()) {
+          redirect_type.set_malformed_error(malformed_error);
+        }
       }
       if (redirect_type.IsMalformed()) {
         if (is_const) {
-          const Error& error = Error::Handle(redirect_type.malformed_error());
-          ErrorMsg(error);
+          ErrorMsg(Error::Handle(redirect_type.malformed_error()));
         }
         return ThrowTypeError(redirect_type.token_pos(), redirect_type);
       }
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 5dd2aa6..d1a175e 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -31,8 +31,6 @@
 // The class ParsedFunction holds the result of parsing a function.
 class ParsedFunction : public ZoneAllocated {
  public:
-  static const int kFirstLocalSlotIndex = -2;
-
   explicit ParsedFunction(const Function& function)
       : function_(function),
         node_sequence_(NULL),
@@ -388,8 +386,8 @@
                          LocalVariable* receiver,
                          GrowableArray<Field*>* initialized_fields);
   String& ParseNativeDeclaration();
-  RawArray* ParseInterfaceList(const Type& super_type);
-  RawType* ParseMixins(const Type& super_type);
+  RawArray* ParseInterfaceList(const AbstractType& super_type);
+  RawAbstractType* ParseMixins(const AbstractType& super_type);
   void AddInterfaceIfUnique(intptr_t interfaces_pos,
                             const GrowableObjectArray& interface_list,
                             const AbstractType& interface);
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 0e47312..4c0e66e 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -203,6 +203,18 @@
         instance_size = Float64Array::InstanceSize(byte_array_length);
         break;
       }
+#define SIZE_FROM_CLASS(clazz)                                                 \
+      case kTypedData##clazz##Cid:
+      CLASS_LIST_TYPED_DATA(SIZE_FROM_CLASS) {
+        const RawTypedData* raw_obj =
+            reinterpret_cast<const RawTypedData*>(this);
+        intptr_t cid = raw_obj->GetClassId();
+        intptr_t array_len = Smi::Value(raw_obj->ptr()->length_);
+        intptr_t lengthInBytes = array_len * TypedData::ElementSizeInBytes(cid);
+        instance_size = TypedData::InstanceSize(lengthInBytes);
+        break;
+      }
+#undef SIZE_FROM_CLASS
       case kTypeArgumentsCid: {
         const RawTypeArguments* raw_array =
             reinterpret_cast<const RawTypeArguments*>(this);
@@ -291,6 +303,24 @@
       }
       CLASS_LIST_NO_OBJECT(RAW_VISITPOINTERS)
 #undef RAW_VISITPOINTERS
+#define RAW_VISITPOINTERS(clazz)                                               \
+      case kTypedData##clazz##Cid:
+      CLASS_LIST_TYPED_DATA(RAW_VISITPOINTERS) {
+        RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(this);
+        size = RawTypedData::VisitTypedDataPointers(raw_obj, visitor);
+        break;
+      }
+#undef RAW_VISITPOINTERS
+#define RAW_VISITPOINTERS(clazz)                                               \
+      case kExternalTypedData##clazz##Cid:
+      CLASS_LIST_TYPED_DATA(RAW_VISITPOINTERS) {
+        RawExternalTypedData* raw_obj =
+            reinterpret_cast<RawExternalTypedData*>(this);
+        size = RawExternalTypedData::VisitExternalTypedDataPointers(raw_obj,
+                                                                    visitor);
+        break;
+      }
+#undef RAW_VISITPOINTERS
       case kFreeListElement: {
         ASSERT(FreeBit::decode(ptr()->tags_));
         uword addr = RawObject::ToAddr(const_cast<RawObject*>(this));
@@ -356,6 +386,20 @@
 }
 
 
+intptr_t RawBoundedType::VisitBoundedTypePointers(
+    RawBoundedType* raw_obj, ObjectPointerVisitor* visitor) {
+  visitor->VisitPointers(raw_obj->from(), raw_obj->to());
+  return BoundedType::InstanceSize();
+}
+
+
+intptr_t RawMixinAppType::VisitMixinAppTypePointers(
+    RawMixinAppType* raw_obj, ObjectPointerVisitor* visitor) {
+  visitor->VisitPointers(raw_obj->from(), raw_obj->to());
+  return MixinAppType::InstanceSize();
+}
+
+
 intptr_t RawAbstractTypeArguments::VisitAbstractTypeArgumentsPointers(
     RawAbstractTypeArguments* raw_obj, ObjectPointerVisitor* visitor) {
   // RawAbstractTypeArguments is an abstract class.
@@ -992,8 +1036,7 @@
 }
 
 
-intptr_t
-    RawExternalFloat32x4Array::VisitExternalFloat32x4ArrayPointers(
+intptr_t RawExternalFloat32x4Array::VisitExternalFloat32x4ArrayPointers(
     RawExternalFloat32x4Array* raw_obj, ObjectPointerVisitor* visitor) {
   // Make sure that we got here with the tagged pointer as this.
   ASSERT(raw_obj->IsHeapObject());
@@ -1020,6 +1063,27 @@
 }
 
 
+intptr_t RawTypedData::VisitTypedDataPointers(
+    RawTypedData* raw_obj, ObjectPointerVisitor* visitor) {
+  // Make sure that we got here with the tagged pointer as this.
+  ASSERT(raw_obj->IsHeapObject());
+  intptr_t cid = raw_obj->GetClassId();
+  intptr_t array_len = Smi::Value(raw_obj->ptr()->length_);
+  intptr_t lengthInBytes = array_len * TypedData::ElementSizeInBytes(cid);
+  visitor->VisitPointers(raw_obj->from(), raw_obj->to());
+  return TypedData::InstanceSize(lengthInBytes);
+}
+
+
+intptr_t RawExternalTypedData::VisitExternalTypedDataPointers(
+    RawExternalTypedData* raw_obj, ObjectPointerVisitor* visitor) {
+  // Make sure that we got here with the tagged pointer as this.
+  ASSERT(raw_obj->IsHeapObject());
+  visitor->VisitPointers(raw_obj->from(), raw_obj->to());
+  return ExternalTypedData::InstanceSize();
+}
+
+
 intptr_t RawDartFunction::VisitDartFunctionPointers(
     RawDartFunction* raw_obj, ObjectPointerVisitor* visitor) {
   // Function (defined in core library) is an abstract class.
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 6d829fe..82ba994 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -51,6 +51,8 @@
     V(AbstractType)                                                            \
       V(Type)                                                                  \
       V(TypeParameter)                                                         \
+      V(BoundedType)                                                           \
+      V(MixinAppType)                                                          \
     V(Number)                                                                  \
       V(Integer)                                                               \
         V(Smi)                                                                 \
@@ -86,6 +88,8 @@
       V(ExternalFloat32x4Array)                                                \
       V(ExternalFloat32Array)                                                  \
       V(ExternalFloat64Array)                                                  \
+    V(TypedData)                                                               \
+    V(ExternalTypedData)                                                       \
     V(Stacktrace)                                                              \
     V(JSRegExp)                                                                \
     V(WeakProperty)                                                            \
@@ -101,6 +105,19 @@
     V(ExternalOneByteString)                                                   \
     V(ExternalTwoByteString)
 
+#define CLASS_LIST_TYPED_DATA(V)                                               \
+  V(Int8Array)                                                                 \
+  V(Uint8Array)                                                                \
+  V(Uint8ClampedArray)                                                         \
+  V(Int16Array)                                                                \
+  V(Uint16Array)                                                               \
+  V(Int32Array)                                                                \
+  V(Uint32Array)                                                               \
+  V(Int64Array)                                                                \
+  V(Uint64Array)                                                               \
+  V(Float32Array)                                                              \
+  V(Float64Array)                                                              \
+
 #define CLASS_LIST_FOR_HANDLES(V)                                              \
   CLASS_LIST_NO_OBJECT_OR_STRING(V)                                            \
   V(String)
@@ -132,6 +149,16 @@
 CLASS_LIST(DEFINE_OBJECT_KIND)
 #undef DEFINE_OBJECT_KIND
 
+#define DEFINE_OBJECT_KIND(clazz)                                              \
+  kTypedData##clazz##Cid,
+CLASS_LIST_TYPED_DATA(DEFINE_OBJECT_KIND)
+#undef DEFINE_OBJECT_KIND
+
+#define DEFINE_OBJECT_KIND(clazz)                                              \
+  kExternalTypedData##clazz##Cid,
+CLASS_LIST_TYPED_DATA(DEFINE_OBJECT_KIND)
+#undef DEFINE_OBJECT_KIND
+
   // The following entries do not describe a predefined class, but instead
   // are class indexes for pre-allocated instance (Null, dynamic and Void).
   kNullCid,
@@ -315,6 +342,10 @@
     ptr()->tags_ = CreatedFromSnapshotTag::update(true, tags);
   }
 
+  bool IsDartInstance() {
+    return (!IsHeapObject() || (GetClassId() >= kInstanceCid));
+  }
+
   intptr_t Size() const {
     uword tags = ptr()->tags_;
     intptr_t result = SizeTag::decode(tags);
@@ -360,6 +391,10 @@
   static bool IsBuiltinListClassId(intptr_t index);
   static bool IsByteArrayClassId(intptr_t index);
   static bool IsExternalByteArrayClassId(intptr_t index);
+  static bool IsTypedDataClassId(intptr_t index);
+  static bool IsExternalTypedDataClassId(intptr_t index);
+
+  static intptr_t NumberOfTypedDataClasses();
 
  private:
   uword tags_;  // Various object tags (bits).
@@ -395,6 +430,7 @@
   friend class Array;
   friend class FreeListElement;
   friend class GCMarker;
+  friend class ExternalTypedData;
   friend class Heap;
   friend class HeapProfiler;
   friend class HeapProfilerRootVisitor;
@@ -404,12 +440,15 @@
   friend class HeapTraceVisitor;
   friend class MarkingVisitor;
   friend class Object;
+  friend class RawExternalTypedData;
   friend class RawInstructions;
   friend class RawInstance;
+  friend class RawTypedData;
   friend class Scavenger;
   friend class SnapshotReader;
   friend class SnapshotWriter;
   friend class String;
+  friend class TypedData;
 
   DISALLOW_ALLOCATION();
   DISALLOW_IMPLICIT_CONSTRUCTORS(RawObject);
@@ -437,7 +476,7 @@
   RawScript* script_;
   RawLibrary* library_;
   RawTypeArguments* type_parameters_;  // Array of TypeParameter.
-  RawType* super_type_;
+  RawAbstractType* super_type_;
   RawType* mixin_;
   RawFunction* signature_function_;  // Associated function for signature class.
   RawArray* constants_;  // Canonicalized values of this class.
@@ -1119,6 +1158,38 @@
 };
 
 
+class RawBoundedType : public RawAbstractType {
+ private:
+  RAW_HEAP_OBJECT_IMPLEMENTATION(BoundedType);
+
+  RawObject** from() {
+    return reinterpret_cast<RawObject**>(&ptr()->type_);
+  }
+  RawAbstractType* type_;
+  RawAbstractType* bound_;
+  RawTypeParameter* type_parameter_;  // For more detailed error reporting.
+  RawObject** to() {
+    return reinterpret_cast<RawObject**>(&ptr()->type_parameter_);
+  }
+  bool is_being_checked_;
+};
+
+
+class RawMixinAppType : public RawAbstractType {
+ private:
+  RAW_HEAP_OBJECT_IMPLEMENTATION(MixinAppType);
+
+  RawObject** from() {
+    return reinterpret_cast<RawObject**>(&ptr()->super_type_);
+  }
+  RawAbstractType* super_type_;
+  RawArray* mixin_types_;
+  RawObject** to() {
+    return reinterpret_cast<RawObject**>(&ptr()->mixin_types_);
+  }
+};
+
+
 class RawNumber : public RawInstance {
   RAW_OBJECT_IMPLEMENTATION(Number);
 };
@@ -1336,6 +1407,32 @@
 #endif  // ARCH_IS_32_BIT
 
 
+class RawTypedData : public RawInstance {
+  RAW_HEAP_OBJECT_IMPLEMENTATION(TypedData);
+
+ protected:
+  RawObject** from() { return reinterpret_cast<RawObject**>(&ptr()->length_); }
+  RawSmi* length_;
+  RawObject** to() { return reinterpret_cast<RawObject**>(&ptr()->length_); }
+
+  // Variable length data follows here.
+  uint8_t data_[0];
+};
+
+
+class RawExternalTypedData : public RawInstance {
+  RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalTypedData);
+
+ protected:
+  RawObject** from() { return reinterpret_cast<RawObject**>(&ptr()->length_); }
+  RawSmi* length_;
+  RawObject** to() { return reinterpret_cast<RawObject**>(&ptr()->length_); }
+
+  uint8_t* data_;
+  void* peer_;
+};
+
+
 class RawByteArray : public RawInstance {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ByteArray);
 
@@ -1726,10 +1823,11 @@
          kExternalFloat32x4ArrayCid == kByteArrayCid + 22 &&
          kExternalFloat32ArrayCid == kByteArrayCid + 23 &&
          kExternalFloat64ArrayCid == kByteArrayCid + 24 &&
-         kStacktraceCid == kByteArrayCid + 25);
+         kTypedDataCid == kByteArrayCid + 25);
   return (index >= kByteArrayCid && index <= kExternalFloat64ArrayCid);
 }
 
+
 inline bool RawObject::IsExternalByteArrayClassId(intptr_t index) {
   // Make sure this function is updated when new ByteArray types are added.
   ASSERT(kExternalUint8ArrayCid == kExternalInt8ArrayCid + 1 &&
@@ -1743,10 +1841,64 @@
          kExternalFloat32x4ArrayCid == kExternalInt8ArrayCid + 9 &&
          kExternalFloat32ArrayCid == kExternalInt8ArrayCid + 10 &&
          kExternalFloat64ArrayCid == kExternalInt8ArrayCid + 11 &&
-         kStacktraceCid == kExternalInt8ArrayCid + 12);
+         kTypedDataCid == kExternalInt8ArrayCid + 12);
   return (index >= kExternalInt8ArrayCid && index <= kExternalFloat64ArrayCid);
 }
 
+
+inline bool RawObject::IsTypedDataClassId(intptr_t index) {
+  // Make sure this is updated when new TypedData types are added.
+  ASSERT(kTypedDataUint8ArrayCid == kTypedDataInt8ArrayCid + 1 &&
+         kTypedDataUint8ClampedArrayCid == kTypedDataInt8ArrayCid + 2 &&
+         kTypedDataInt16ArrayCid == kTypedDataInt8ArrayCid + 3 &&
+         kTypedDataUint16ArrayCid == kTypedDataInt8ArrayCid + 4 &&
+         kTypedDataInt32ArrayCid == kTypedDataInt8ArrayCid + 5 &&
+         kTypedDataUint32ArrayCid == kTypedDataInt8ArrayCid + 6 &&
+         kTypedDataInt64ArrayCid == kTypedDataInt8ArrayCid + 7 &&
+         kTypedDataUint64ArrayCid == kTypedDataInt8ArrayCid + 8 &&
+         kTypedDataFloat32ArrayCid == kTypedDataInt8ArrayCid + 9 &&
+         kTypedDataFloat64ArrayCid == kTypedDataInt8ArrayCid + 10 &&
+         kExternalTypedDataInt8ArrayCid == kTypedDataInt8ArrayCid + 11);
+  return (index >= kTypedDataInt8ArrayCid &&
+          index <= kTypedDataFloat64ArrayCid);
+}
+
+
+inline bool RawObject::IsExternalTypedDataClassId(intptr_t index) {
+  // Make sure this is updated when new ExternalTypedData types are added.
+  ASSERT((kExternalTypedDataUint8ArrayCid ==
+          kExternalTypedDataInt8ArrayCid + 1) &&
+         (kExternalTypedDataUint8ClampedArrayCid ==
+          kExternalTypedDataInt8ArrayCid + 2) &&
+         (kExternalTypedDataInt16ArrayCid ==
+          kExternalTypedDataInt8ArrayCid + 3) &&
+         (kExternalTypedDataUint16ArrayCid ==
+          kExternalTypedDataInt8ArrayCid + 4) &&
+         (kExternalTypedDataInt32ArrayCid ==
+          kExternalTypedDataInt8ArrayCid + 5) &&
+         (kExternalTypedDataUint32ArrayCid ==
+          kExternalTypedDataInt8ArrayCid + 6) &&
+         (kExternalTypedDataInt64ArrayCid ==
+          kExternalTypedDataInt8ArrayCid + 7) &&
+         (kExternalTypedDataUint64ArrayCid ==
+          kExternalTypedDataInt8ArrayCid + 8) &&
+         (kExternalTypedDataFloat32ArrayCid ==
+          kExternalTypedDataInt8ArrayCid + 9) &&
+         (kExternalTypedDataFloat64ArrayCid ==
+          kExternalTypedDataInt8ArrayCid + 10) &&
+         (kNullCid == kExternalTypedDataInt8ArrayCid + 11));
+  return (index >= kExternalTypedDataInt8ArrayCid &&
+          index <= kExternalTypedDataFloat64ArrayCid);
+}
+
+
+inline intptr_t RawObject::NumberOfTypedDataClasses() {
+  // Make sure this is updated when new TypedData types are added.
+  ASSERT(kExternalTypedDataInt8ArrayCid == kTypedDataInt8ArrayCid + 11);
+  ASSERT(kNullCid == kExternalTypedDataInt8ArrayCid + 11);
+  return (kNullCid - kTypedDataInt8ArrayCid);
+}
+
 }  // namespace dart
 
 #endif  // VM_RAW_OBJECT_H_
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 99370a2..dcecda6 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -115,28 +115,13 @@
 }
 
 
-static const char* RawOneByteStringToCString(RawOneByteString* str) {
-  const char* start = reinterpret_cast<char*>(str) - kHeapObjectTag +
-      OneByteString::data_offset();
-  const int len = Smi::Value(*reinterpret_cast<RawSmi**>(
-      reinterpret_cast<uword>(str) - kHeapObjectTag + String::length_offset()));
-  char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
-  memmove(chars, start, len);
-  chars[len] = '\0';
-  return chars;
-}
-
-
 RawUnresolvedClass* UnresolvedClass::ReadFrom(SnapshotReader* reader,
                                               intptr_t object_id,
                                               intptr_t tags,
                                               Snapshot::Kind kind) {
   ASSERT(reader != NULL);
 
-  // Only resolved and finalized types should be written to a snapshot.
-  // TODO(regis): Replace this code by an UNREACHABLE().
-
-  // Allocate parameterized type object.
+  // Allocate unresolved class object.
   UnresolvedClass& unresolved_class = UnresolvedClass::ZoneHandle(
       reader->isolate(), NEW_OBJECT(UnresolvedClass));
   reader->AddBackRef(object_id, &unresolved_class, kIsDeserialized);
@@ -165,19 +150,6 @@
                                  Snapshot::Kind kind) {
   ASSERT(writer != NULL);
 
-  // Only resolved and finalized types should be written to a snapshot.
-  // TODO(regis): Replace this code by an UNREACHABLE().
-  if (FLAG_error_on_malformed_type) {
-    // Print the name of the unresolved class, as well as the token location
-    // from where it is referred to, making sure not to allocate any handles.
-    // Unfortunately, we cannot print the script name.
-    OS::Print("Snapshotting unresolved class '%s' at token pos %"Pd"\n",
-              RawOneByteStringToCString(
-                  reinterpret_cast<RawOneByteString*>(ptr()->ident_)),
-              ptr()->token_pos_);
-    UNREACHABLE();
-  }
-
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
 
@@ -245,13 +217,25 @@
 }
 
 
+static const char* RawOneByteStringToCString(RawOneByteString* str) {
+  const char* start = reinterpret_cast<char*>(str) - kHeapObjectTag +
+      OneByteString::data_offset();
+  const int len = Smi::Value(*reinterpret_cast<RawSmi**>(
+      reinterpret_cast<uword>(str) - kHeapObjectTag + String::length_offset()));
+  char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
+  memmove(chars, start, len);
+  chars[len] = '\0';
+  return chars;
+}
+
+
 void RawType::WriteTo(SnapshotWriter* writer,
                       intptr_t object_id,
                       Snapshot::Kind kind) {
   ASSERT(writer != NULL);
 
   // Only resolved and finalized types should be written to a snapshot.
-  // TODO(regis): Replace the test below by an ASSERT().
+  // TODO(regis): Replace the test below by an ASSERT() or remove the flag test.
   if (FLAG_error_on_malformed_type &&
       (ptr()->type_state_ != RawType::kFinalizedInstantiated) &&
       (ptr()->type_state_ != RawType::kFinalizedUninstantiated)) {
@@ -336,7 +320,7 @@
   ASSERT(writer != NULL);
 
   // Only finalized type parameters should be written to a snapshot.
-  // TODO(regis): Replace the test below by an ASSERT().
+  // TODO(regis): Replace the test below by an ASSERT() or remove the flag test.
   if (FLAG_error_on_malformed_type &&
       (ptr()->type_state_ != RawTypeParameter::kFinalizedUninstantiated)) {
     // Print the name of the unfinalized type parameter, the name of the class
@@ -373,6 +357,70 @@
 }
 
 
+RawBoundedType* BoundedType::ReadFrom(SnapshotReader* reader,
+                                      intptr_t object_id,
+                                      intptr_t tags,
+                                      Snapshot::Kind kind) {
+  ASSERT(reader != NULL);
+
+  // Allocate bounded type object.
+  BoundedType& bounded_type = BoundedType::ZoneHandle(
+      reader->isolate(), NEW_OBJECT(BoundedType));
+  reader->AddBackRef(object_id, &bounded_type, kIsDeserialized);
+
+  // Set the object tags.
+  bounded_type.set_tags(tags);
+
+  // Set all the object fields.
+  // TODO(5411462): Need to assert No GC can happen here, even though
+  // allocations may happen.
+  intptr_t num_flds = (bounded_type.raw()->to() -
+                       bounded_type.raw()->from());
+  for (intptr_t i = 0; i <= num_flds; i++) {
+    bounded_type.StorePointer((bounded_type.raw()->from() + i),
+                              reader->ReadObjectRef());
+  }
+
+  bounded_type.set_is_being_checked(false);
+
+  return bounded_type.raw();
+}
+
+
+void RawBoundedType::WriteTo(SnapshotWriter* writer,
+                             intptr_t object_id,
+                             Snapshot::Kind kind) {
+  ASSERT(writer != NULL);
+
+  // Write out the serialization header value for this object.
+  writer->WriteInlinedObjectHeader(object_id);
+
+  // Write out the class and tags information.
+  writer->WriteIndexedObject(kBoundedTypeCid);
+  writer->WriteIntptrValue(writer->GetObjectTags(this));
+
+  // Write out all the object pointer fields.
+  SnapshotWriterVisitor visitor(writer);
+  visitor.VisitPointers(from(), to());
+}
+
+
+RawMixinAppType* MixinAppType::ReadFrom(SnapshotReader* reader,
+                                        intptr_t object_id,
+                                        intptr_t tags,
+                                        Snapshot::Kind kind) {
+  UNREACHABLE();  // MixinAppType objects do not survive finalization.
+  return MixinAppType::null();
+}
+
+
+void RawMixinAppType::WriteTo(SnapshotWriter* writer,
+                              intptr_t object_id,
+                              Snapshot::Kind kind) {
+  UNREACHABLE();  // MixinAppType objects do not survive finalization.
+}
+
+
 RawAbstractTypeArguments* AbstractTypeArguments::ReadFrom(
     SnapshotReader* reader,
     intptr_t object_id,
@@ -2367,6 +2415,217 @@
 #undef BYTEARRAY_TYPE_LIST
 
 
+#define TYPED_DATA_READ(setter, type)                                          \
+  for (intptr_t i = 0; i < lengthInBytes; i += element_size) {                 \
+    result.Set##setter(i, reader->Read<type>());                               \
+  }                                                                            \
+
+RawTypedData* TypedData::ReadFrom(SnapshotReader* reader,
+                                  intptr_t object_id,
+                                  intptr_t tags,
+                                  Snapshot::Kind kind) {
+  ASSERT(reader != NULL);
+
+  intptr_t cid = RawObject::ClassIdTag::decode(tags);
+  intptr_t len = reader->ReadSmiValue();
+  TypedData& result = TypedData::ZoneHandle(
+      reader->isolate(), TypedData::New(cid, len, HEAP_SPACE(kind)));
+  reader->AddBackRef(object_id, &result, kIsDeserialized);
+
+  // Set the object tags.
+  result.set_tags(tags);
+
+  // Setup the array elements.
+  intptr_t element_size = ElementSizeInBytes(cid);
+  intptr_t lengthInBytes = len * element_size;
+  switch (cid) {
+    case kTypedDataInt8ArrayCid:
+      TYPED_DATA_READ(Int8, int8_t);
+      break;
+    case kTypedDataUint8ArrayCid:
+      TYPED_DATA_READ(Uint8, uint8_t);
+      break;
+    case kTypedDataUint8ClampedArrayCid:
+      TYPED_DATA_READ(Uint8, uint8_t);
+      break;
+    case kTypedDataInt16ArrayCid:
+      TYPED_DATA_READ(Int16, int16_t);
+      break;
+    case kTypedDataUint16ArrayCid:
+      TYPED_DATA_READ(Uint16, uint16_t);
+      break;
+    case kTypedDataInt32ArrayCid:
+      TYPED_DATA_READ(Int32, int32_t);
+      break;
+    case kTypedDataUint32ArrayCid:
+      TYPED_DATA_READ(Uint32, uint32_t);
+      break;
+    case kTypedDataInt64ArrayCid:
+      TYPED_DATA_READ(Int64, int64_t);
+      break;
+    case kTypedDataUint64ArrayCid:
+      TYPED_DATA_READ(Uint64, uint64_t);
+      break;
+    case kTypedDataFloat32ArrayCid:
+      TYPED_DATA_READ(Float32, float);
+      break;
+    case kTypedDataFloat64ArrayCid:
+      TYPED_DATA_READ(Float64, double);
+      break;
+    default:
+      UNREACHABLE();
+  }
+  return result.raw();
+}
+#undef TYPED_DATA_READ
+
+
+RawExternalTypedData* ExternalTypedData::ReadFrom(SnapshotReader* reader,
+                                                  intptr_t object_id,
+                                                  intptr_t tags,
+                                                  Snapshot::Kind kind) {
+  ASSERT(kind != Snapshot::kFull);
+  intptr_t cid = RawObject::ClassIdTag::decode(tags);
+  intptr_t length = reader->ReadSmiValue();
+  uint8_t* data = reinterpret_cast<uint8_t*>(reader->ReadIntptrValue());
+  const ExternalTypedData& obj = ExternalTypedData::Handle(
+      ExternalTypedData::New(cid, data, length));
+  void* peer = reinterpret_cast<void*>(reader->ReadIntptrValue());
+  Dart_WeakPersistentHandleFinalizer callback =
+      reinterpret_cast<Dart_WeakPersistentHandleFinalizer>(
+          reader->ReadIntptrValue());
+  obj.AddFinalizer(peer, callback);
+  return obj.raw();
+}
+
+
+#define TYPED_DATA_WRITE(type)                                                 \
+  {                                                                            \
+    type* data = reinterpret_cast<type*>(ptr()->data_);                        \
+    for (intptr_t i = 0; i < len; i++) {                                       \
+      writer->Write(data[i]);                                                  \
+    }                                                                          \
+  }                                                                            \
+
+
+void RawTypedData::WriteTo(SnapshotWriter* writer,
+                           intptr_t object_id,
+                           Snapshot::Kind kind) {
+  ASSERT(writer != NULL);
+  intptr_t tags = writer->GetObjectTags(this);
+  intptr_t cid = ClassIdTag::decode(tags);
+  intptr_t len = Smi::Value(ptr()->length_);
+
+  // Write out the serialization header value for this object.
+  writer->WriteInlinedObjectHeader(object_id);
+
+  // Write out the class and tags information.
+  writer->WriteIndexedObject(cid);
+  writer->WriteIntptrValue(tags);
+
+  // Write out the length field.
+  writer->Write<RawObject*>(ptr()->length_);
+
+  // Write out the array elements.
+  switch (cid) {
+    case kTypedDataInt8ArrayCid:
+      TYPED_DATA_WRITE(int8_t);
+      break;
+    case kTypedDataUint8ArrayCid:
+      TYPED_DATA_WRITE(uint8_t);
+      break;
+    case kTypedDataUint8ClampedArrayCid:
+      TYPED_DATA_WRITE(uint8_t);
+      break;
+    case kTypedDataInt16ArrayCid:
+      TYPED_DATA_WRITE(int16_t);
+      break;
+    case kTypedDataUint16ArrayCid:
+      TYPED_DATA_WRITE(uint16_t);
+      break;
+    case kTypedDataInt32ArrayCid:
+      TYPED_DATA_WRITE(int32_t);
+      break;
+    case kTypedDataUint32ArrayCid:
+      TYPED_DATA_WRITE(uint32_t);
+      break;
+    case kTypedDataInt64ArrayCid:
+      TYPED_DATA_WRITE(int64_t);
+      break;
+    case kTypedDataUint64ArrayCid:
+      TYPED_DATA_WRITE(uint64_t);
+      break;
+    case kTypedDataFloat32ArrayCid:
+      TYPED_DATA_WRITE(float);  // NOLINT.
+      break;
+    case kTypedDataFloat64ArrayCid:
+      TYPED_DATA_WRITE(double);  // NOLINT.
+      break;
+    default:
+      UNREACHABLE();
+  }
+}
+
+
+void RawExternalTypedData::WriteTo(SnapshotWriter* writer,
+                                   intptr_t object_id,
+                                   Snapshot::Kind kind) {
+  ASSERT(writer != NULL);
+  intptr_t tags = writer->GetObjectTags(this);
+  intptr_t cid = ClassIdTag::decode(tags);
+  intptr_t len = Smi::Value(ptr()->length_);
+
+  // Write out the serialization header value for this object.
+  writer->WriteInlinedObjectHeader(object_id);
+
+  // Write out the class and tags information.
+  writer->WriteIndexedObject(cid);
+  writer->WriteIntptrValue(tags);
+
+  // Write out the length field.
+  writer->Write<RawObject*>(ptr()->length_);
+
+  switch (cid) {
+    case kExternalTypedDataInt8ArrayCid:
+      TYPED_DATA_WRITE(int8_t);
+      break;
+    case kExternalTypedDataUint8ArrayCid:
+      TYPED_DATA_WRITE(uint8_t);
+      break;
+    case kExternalTypedDataUint8ClampedArrayCid:
+      TYPED_DATA_WRITE(uint8_t);
+      break;
+    case kExternalTypedDataInt16ArrayCid:
+      TYPED_DATA_WRITE(int16_t);
+      break;
+    case kExternalTypedDataUint16ArrayCid:
+      TYPED_DATA_WRITE(uint16_t);
+      break;
+    case kExternalTypedDataInt32ArrayCid:
+      TYPED_DATA_WRITE(int32_t);
+      break;
+    case kExternalTypedDataUint32ArrayCid:
+      TYPED_DATA_WRITE(uint32_t);
+      break;
+    case kExternalTypedDataInt64ArrayCid:
+      TYPED_DATA_WRITE(int64_t);
+      break;
+    case kExternalTypedDataUint64ArrayCid:
+      TYPED_DATA_WRITE(uint64_t);
+      break;
+    case kExternalTypedDataFloat32ArrayCid:
+      TYPED_DATA_WRITE(float);  // NOLINT.
+      break;
+    case kExternalTypedDataFloat64ArrayCid:
+      TYPED_DATA_WRITE(double);  // NOLINT.
+      break;
+    default:
+      UNREACHABLE();
+  }
+}
+#undef TYPED_DATA_WRITE
+
+
 RawDartFunction* DartFunction::ReadFrom(SnapshotReader* reader,
                                         intptr_t object_id,
                                         intptr_t tags,
diff --git a/runtime/vm/resolver_test.cc b/runtime/vm/resolver_test.cc
index 8b5499b..5ce8ebb 100644
--- a/runtime/vm/resolver_test.cc
+++ b/runtime/vm/resolver_test.cc
@@ -14,8 +14,10 @@
 
 namespace dart {
 
-// Only ia32 and x64 can run execution tests.
-#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
+// Compiler only implemented on IA32, X64, and ARM.
+#if defined(TARGET_ARCH_IA32) ||                                               \
+    defined(TARGET_ARCH_X64) ||                                                \
+    defined(TARGET_ARCH_ARM)
 
 // Setup function for invocation.
 static void SetupFunction(const char* test_library_name,
@@ -219,6 +221,6 @@
   }
 }
 
-#endif  // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64).
+#endif  // TARGET_ARCH_IA32 || TARGET_ARCH_X64 || TARGET_ARCH_ARM
 
 }  // namespace dart
diff --git a/runtime/vm/runtime_entry_arm.cc b/runtime/vm/runtime_entry_arm.cc
index 77e6b54..af005b6 100644
--- a/runtime/vm/runtime_entry_arm.cc
+++ b/runtime/vm/runtime_entry_arm.cc
@@ -27,7 +27,12 @@
   // into the runtime system.
   uword entry = GetEntryPoint();
 #if defined(USING_SIMULATOR)
-  entry = Simulator::RedirectExternalReference(entry, argument_count());
+  // Redirection to leaf runtime calls supports a maximum of 4 arguments passed
+  // in registers.
+  ASSERT(!is_leaf() || (argument_count() <= 4));
+  Simulator::CallKind call_kind =
+      is_leaf() ? Simulator::kLeafRuntimeCall : Simulator::kRuntimeCall;
+  entry = Simulator::RedirectExternalReference(entry, call_kind);
 #endif
   if (is_leaf()) {
     ExternalLabel label(name(), entry);
diff --git a/runtime/vm/scavenger.cc b/runtime/vm/scavenger.cc
index 0cc302c..3b90a0d 100644
--- a/runtime/vm/scavenger.cc
+++ b/runtime/vm/scavenger.cc
@@ -75,8 +75,10 @@
         delayed_weak_stack_(),
         growth_policy_(PageSpace::kControlGrowth),
         bytes_promoted_(0),
-        visiting_old_pointers_(false),
-        in_scavenge_pointer_(false) {}
+#ifdef DEBUG
+        in_scavenge_pointer_(false),
+#endif
+        visiting_old_pointers_(false) { }
 
   void VisitPointers(RawObject** first, RawObject** last) {
     for (RawObject** current = first; current <= last; current++) {
@@ -125,8 +127,10 @@
 
   void ScavengePointer(RawObject** p) {
     // ScavengePointer cannot be called recursively.
+#ifdef DEBUG
     ASSERT(!in_scavenge_pointer_);
     BoolScope bs(&in_scavenge_pointer_, true);
+#endif
 
     RawObject* raw_obj = *p;
 
@@ -251,8 +255,10 @@
   // new space growth policy.
   intptr_t bytes_promoted_;
 
-  bool visiting_old_pointers_;
+#ifdef DEBUG
   bool in_scavenge_pointer_;
+#endif
+  bool visiting_old_pointers_;
 
   DISALLOW_COPY_AND_ASSIGN(ScavengerVisitor);
 };
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index 86dceae..0570259 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -557,17 +557,16 @@
 
 int LocalVariable::BitIndexIn(intptr_t fixed_parameter_count) const {
   ASSERT(!is_captured());
-  // Parameters have positive indexes with the lowest index being 2.  Locals
-  // and copied parameters have negative indexes with the lowest (closest to
-  // zero) index being ParsedFunction::kFirstLocalSlotIndex.
+  // Parameters have positive indexes with the lowest index being
+  // kLastParamSlotIndex.  Locals and copied parameters have negative indexes
+  // with the lowest (closest to zero) index being kFirstLocalSlotIndex.
   if (index() > 0) {
     // Shift non-negative indexes so that the lowest one is 0.
-    return (fixed_parameter_count - 1) - (index() - 2);
+    return (fixed_parameter_count - 1) - (index() - kLastParamSlotIndex);
   } else {
     // Shift negative indexes so that the lowest one is 0 (they are still
     // non-positive).
-    return fixed_parameter_count -
-        (index() - ParsedFunction::kFirstLocalSlotIndex);
+    return fixed_parameter_count - (index() - kFirstLocalSlotIndex);
   }
 }
 
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index 5d14e41..232a69d 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -293,6 +293,7 @@
 void SimulatorDebugger::Debug() {
   intptr_t last_pc = -1;
   bool done = false;
+  bool decoded = true;
 
 #define COMMAND_SIZE 63
 #define ARG_SIZE 255
@@ -316,7 +317,7 @@
   while (!done) {
     if (last_pc != sim_->get_pc()) {
       last_pc = sim_->get_pc();
-      Disassembler::Disassemble(last_pc, last_pc + Instr::kInstrSize);
+      decoded = Disassembler::Disassemble(last_pc, last_pc + Instr::kInstrSize);
     }
     char* line = ReadLine("sim> ");
     if (line == NULL) {
@@ -346,14 +347,26 @@
                   "pd/printdouble <dreg or *addr> -- print double value\n"
                   "po/printobject <*reg or *addr> -- print object\n"
                   "si/stepi -- single step an instruction\n"
-                  "unstop -- if current pc is a stop instr make it a nop\n");
+                  "unstop -- if current pc is a stop instr make it a nop\n"
+                  "q/quit -- Quit the debugger and exit the program\n");
+      } else if ((strcmp(cmd, "quit") == 0) || (strcmp(cmd, "q") == 0)) {
+        OS::Print("Quitting\n");
+        OS::Exit(0);
       } else if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
-        sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
+        if (decoded) {
+          sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
+        } else {
+          OS::Print("Instruction could not be decoded. Stepping disabled.\n");
+        }
       } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
-        // Execute the one instruction we broke at with breakpoints disabled.
-        sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
-        // Leave the debugger shell.
-        done = true;
+        if (decoded) {
+          // Execute the one instruction we broke at with breakpoints disabled.
+          sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
+          // Leave the debugger shell.
+          done = true;
+        } else {
+          OS::Print("Instruction could not be decoded. Cannot continue.\n");
+        }
       } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
         if (args == 2) {
           uint32_t value;
@@ -682,14 +695,15 @@
 
   uword external_function() const { return external_function_; }
 
-  uint32_t argument_count() const { return argument_count_; }
+  Simulator::CallKind call_kind() const { return call_kind_; }
 
-  static Redirection* Get(uword external_function, uint32_t argument_count) {
+  static Redirection* Get(uword external_function,
+                          Simulator::CallKind call_kind) {
     Redirection* current;
     for (current = list_; current != NULL; current = current->next_) {
       if (current->external_function_ == external_function) return current;
     }
-    return new Redirection(external_function, argument_count);
+    return new Redirection(external_function, call_kind);
   }
 
   static Redirection* FromSvcInstruction(Instr* svc_instruction) {
@@ -702,16 +716,16 @@
  private:
   static const int32_t kRedirectSvcInstruction =
     ((AL << kConditionShift) | (0xf << 24) | kRedirectionSvcCode);
-  Redirection(uword external_function, uint32_t argument_count)
+  Redirection(uword external_function, Simulator::CallKind call_kind)
       : external_function_(external_function),
-        argument_count_(argument_count),
+        call_kind_(call_kind),
         svc_instruction_(kRedirectSvcInstruction),
         next_(list_) {
     list_ = this;
   }
 
   uword external_function_;
-  const uint32_t argument_count_;
+  Simulator::CallKind call_kind_;
   uint32_t svc_instruction_;
   Redirection* next_;
   static Redirection* list_;
@@ -721,9 +735,8 @@
 Redirection* Redirection::list_ = NULL;
 
 
-uword Simulator::RedirectExternalReference(uword function,
-                                           uint32_t argument_count) {
-  Redirection* redirection = Redirection::Get(function, argument_count);
+uword Simulator::RedirectExternalReference(uword function, CallKind call_kind) {
+  Redirection* redirection = Redirection::Get(function, call_kind);
   return redirection->address_of_svc_instruction();
 }
 
@@ -1298,15 +1311,15 @@
 }
 
 
-// Calls into the Dart runtime are based on this simple interface.
+// Calls into the Dart runtime are based on this interface.
 typedef void (*SimulatorRuntimeCall)(NativeArguments arguments);
 
+// Calls to leaf Dart runtime functions are based on this interface.
+typedef int32_t (*SimulatorLeafRuntimeCall)(
+    int32_t r0, int32_t r1, int32_t r2, int32_t r3);
 
-static void PrintExternalCallTrace(intptr_t external,
-                                   NativeArguments arguments) {
-  // TODO(regis): Do a reverse lookup on this address and print the symbol.
-  UNIMPLEMENTED();
-}
+// Calls to native Dart functions are based on this interface.
+typedef void (*SimulatorNativeCall)(NativeArguments* arguments);
 
 
 void Simulator::SupervisorCall(Instr* instr) {
@@ -1316,25 +1329,45 @@
       SimulatorSetjmpBuffer buffer(this);
 
       if (!setjmp(buffer.buffer_)) {
-        NativeArguments arguments;
-        ASSERT(sizeof(NativeArguments) == 4*kWordSize);
-        arguments.isolate_ = reinterpret_cast<Isolate*>(get_register(R0));
-        arguments.argc_tag_ = get_register(R1);
-        arguments.argv_ = reinterpret_cast<RawObject*(*)[]>(get_register(R2));
-        arguments.retval_ = reinterpret_cast<RawObject**>(get_register(R3));
-
         int32_t saved_lr = get_register(LR);
         Redirection* redirection = Redirection::FromSvcInstruction(instr);
         uword external = redirection->external_function();
-        SimulatorRuntimeCall target =
-            reinterpret_cast<SimulatorRuntimeCall>(external);
         if (FLAG_trace_sim) {
-          PrintExternalCallTrace(external, arguments);
+          OS::Print("Call to host function at 0x%"Pd"\n", external);
         }
-        target(arguments);
+        if (redirection->call_kind() == kRuntimeCall) {
+          NativeArguments arguments;
+          ASSERT(sizeof(NativeArguments) == 4*kWordSize);
+          arguments.isolate_ = reinterpret_cast<Isolate*>(get_register(R0));
+          arguments.argc_tag_ = get_register(R1);
+          arguments.argv_ = reinterpret_cast<RawObject*(*)[]>(get_register(R2));
+          arguments.retval_ = reinterpret_cast<RawObject**>(get_register(R3));
+          SimulatorRuntimeCall target =
+              reinterpret_cast<SimulatorRuntimeCall>(external);
+          target(arguments);
+          set_register(R0, icount_);  // Zap result register from void function.
+        } else if (redirection->call_kind() == kLeafRuntimeCall) {
+          int32_t r0 = get_register(R0);
+          int32_t r1 = get_register(R1);
+          int32_t r2 = get_register(R2);
+          int32_t r3 = get_register(R3);
+          SimulatorLeafRuntimeCall target =
+              reinterpret_cast<SimulatorLeafRuntimeCall>(external);
+          r0 = target(r0, r1, r2, r3);
+          set_register(R0, r0);  // Set returned result from function.
+        } else {
+          ASSERT(redirection->call_kind() == kNativeCall);
+          NativeArguments* arguments;
+          arguments = reinterpret_cast<NativeArguments*>(get_register(R0));
+          SimulatorNativeCall target =
+              reinterpret_cast<SimulatorNativeCall>(external);
+          target(arguments);
+          set_register(R0, icount_);  // Zap result register from void function.
+        }
 
         // Zap caller-saved registers, since the actual runtime call could have
         // used them.
+        set_register(R1, icount_);
         set_register(R2, icount_);
         set_register(R3, icount_);
         set_register(IP, icount_);
@@ -1350,9 +1383,7 @@
         }
 #endif  // VFPv3_D32
 
-        // Zap result register pair R0:R1 and return.
-        set_register(R0, icount_);
-        set_register(R1, icount_);
+        // Return.
         set_pc(saved_lr);
       }
 
@@ -1996,7 +2027,46 @@
 }
 
 
+void Simulator::DoDivision(Instr* instr) {
+  ASSERT(CPUFeatures::integer_division_supported());
+  Register rd = instr->RdField();
+  Register rn = instr->RnField();
+  Register rm = instr->RmField();
+
+  // TODO(zra): Does the hardware trap on divide-by-zero?
+  //     Revisit when we test on ARM hardware.
+  if (get_register(rm) == 0) {
+    set_register(rd, 0);
+    return;
+  }
+
+  if (instr->Bit(21) == 1) {
+    // unsigned division.
+    uint32_t rn_val = static_cast<uint32_t>(get_register(rn));
+    uint32_t rm_val = static_cast<uint32_t>(get_register(rm));
+    uint32_t result = rn_val / rm_val;
+    set_register(rd, static_cast<int32_t>(result));
+  } else {
+    // signed division.
+    int32_t rn_val = get_register(rn);
+    int32_t rm_val = get_register(rm);
+    int32_t result;
+    if ((rn_val == static_cast<int32_t>(0x80000000)) &&
+        (rm_val == static_cast<int32_t>(0xffffffff))) {
+      result = 0x80000000;
+    } else {
+      result = rn_val / rm_val;
+    }
+    set_register(rd, result);
+  }
+}
+
+
 void Simulator::DecodeType3(Instr* instr) {
+  if (instr->IsDivision()) {
+    DoDivision(instr);
+    return;
+  }
   Register rd = instr->RdField();
   Register rn = instr->RnField();
   int32_t rn_val = get_register(rn);
@@ -2584,6 +2654,14 @@
         UNIMPLEMENTED();
       }
     }
+  } else if (instr->IsMrcIdIsar0()) {
+    // mrc of ID_ISAR0.
+    Register rd = instr->RdField();
+    if (CPUFeatures::integer_division_supported()) {
+      set_register(rd, 0x02100010);  // sim has sdiv, udiv, bkpt and clz.
+    } else {
+      set_register(rd, 0x00100010);  // simulator has only bkpt and clz.
+    }
   } else {
     UNIMPLEMENTED();
   }
@@ -2694,8 +2772,7 @@
                         int32_t parameter0,
                         int32_t parameter1,
                         int32_t parameter2,
-                        int32_t parameter3,
-                        int32_t parameter4) {
+                        int32_t parameter3) {
   // Save the SP register before the call so we can restore it.
   int32_t sp_before_call = get_register(SP);
 
@@ -2705,18 +2782,12 @@
   set_register(R2, parameter2);
   set_register(R3, parameter3);
 
-  // Reserve room for one stack parameter.
-  int32_t stack_pointer = sp_before_call;
-  stack_pointer -= kWordSize;
-
   // Make sure the activation frames are properly aligned.
+  int32_t stack_pointer = sp_before_call;
   static const int kFrameAlignment = OS::ActivationFrameAlignment();
   if (kFrameAlignment > 0) {
     stack_pointer = Utils::RoundDown(stack_pointer, kFrameAlignment);
   }
-
-  // Write the fourth parameter to the stack and update register SP.
-  *reinterpret_cast<int32_t*>(stack_pointer) = parameter4;
   set_register(SP, stack_pointer);
 
   // Prepare to execute the code at entry.
diff --git a/runtime/vm/simulator_arm.h b/runtime/vm/simulator_arm.h
index 2b4589c..9bedd7f 100644
--- a/runtime/vm/simulator_arm.h
+++ b/runtime/vm/simulator_arm.h
@@ -68,8 +68,7 @@
                int32_t parameter0,
                int32_t parameter1,
                int32_t parameter2,
-               int32_t parameter3,
-               int32_t parameter4);
+               int32_t parameter3);
 
   // Implementation of atomic compare and exchange in the same synchronization
   // domain as other synchronization primitive instructions (e.g. ldrex, strex).
@@ -77,9 +76,13 @@
                                uword compare_value,
                                uword new_value);
 
-  // Runtime call support.
-  static uword RedirectExternalReference(uword function,
-                                         uint32_t argument_count);
+  // Runtime and native call support.
+  enum CallKind {
+    kRuntimeCall,
+    kLeafRuntimeCall,
+    kNativeCall
+  };
+  static uword RedirectExternalReference(uword function, CallKind call_kind);
 
   void Longjmp(int32_t pc, int32_t sp, int32_t fp, const Instance& object);
 
@@ -114,7 +117,6 @@
   char* stack_;
   bool pc_modified_;
   int icount_;
-  static bool flag_trace_sim_;
   static int32_t flag_stop_sim_at_;
   SimulatorSetjmpBuffer* last_setjmp_buffer_;
 
@@ -155,6 +157,9 @@
   // Read and write memory.
   void UnalignedAccess(const char* msg, uword addr, Instr* instr);
 
+  // Perform a division.
+  void DoDivision(Instr* instr);
+
   inline uint8_t ReadBU(uword addr);
   inline int8_t ReadB(uword addr);
   inline void WriteB(uword addr, uint8_t value);
diff --git a/runtime/vm/simulator_mips.cc b/runtime/vm/simulator_mips.cc
index 39f92ce..3ec2c27 100644
--- a/runtime/vm/simulator_mips.cc
+++ b/runtime/vm/simulator_mips.cc
@@ -16,6 +16,474 @@
 
 namespace dart {
 
+DEFINE_FLAG(int, stop_sim_at, 0, "Address to stop simulator at.");
+
+
+// This macro provides a platform independent use of sscanf. The reason for
+// SScanF not being implemented in a platform independent way through
+// OS in the same way as SNPrint is that the Windows C Run-Time
+// Library does not provide vsscanf.
+#define SScanF sscanf  // NOLINT
+
+
+// The SimulatorDebugger class is used by the simulator while debugging
+// simulated MIPS code.
+class SimulatorDebugger {
+ public:
+  explicit SimulatorDebugger(Simulator* sim);
+  ~SimulatorDebugger();
+
+  void Stop(Instr* instr, const char* message);
+  void Debug();
+  char* ReadLine(const char* prompt);
+
+ private:
+  Simulator* sim_;
+
+  bool GetValue(char* desc, uint32_t* value);
+  bool GetFValue(char* desc, double* value);
+
+  // Set or delete a breakpoint. Returns true if successful.
+  bool SetBreakpoint(Instr* breakpc);
+  bool DeleteBreakpoint(Instr* breakpc);
+
+  // Undo and redo all breakpoints. This is needed to bracket disassembly and
+  // execution to skip past breakpoints when run from the debugger.
+  void UndoBreakpoints();
+  void RedoBreakpoints();
+};
+
+
+SimulatorDebugger::SimulatorDebugger(Simulator* sim) {
+  sim_ = sim;
+}
+
+
+SimulatorDebugger::~SimulatorDebugger() {
+}
+
+
+void SimulatorDebugger::Stop(Instr* instr, const char* message) {
+  OS::Print("Simulator hit %s\n", message);
+  Debug();
+}
+
+
+static Register LookupCpuRegisterByName(const char* name) {
+  static const char* kNames[] = {
+      "r0",  "r1",  "r2",  "r3",
+      "r4",  "r5",  "r6",  "r7",
+      "r8",  "r9",  "r10", "r11",
+      "r12", "r13", "r14", "r15",
+      "r16", "r17", "r18", "r19",
+      "r20", "r21", "r22", "r23",
+      "r24", "r25", "r26", "r27",
+      "r28", "r29", "r30", "r31",
+
+      "zr",  "at",  "v0",  "v1",
+      "a0",  "a1",  "a2",  "a3",
+      "t0",  "t1",  "t2",  "t3",
+      "t4",  "t5",  "t6",  "t7",
+      "s0",  "s1",  "s2",  "s3",
+      "s4",  "s5",  "s6",  "s7",
+      "t8",  "t9",  "k0",  "k1",
+      "gp",  "sp",  "fp",  "ra"
+  };
+  static const Register kRegisters[] = {
+      R0,  R1,  R2,  R3,
+      R4,  R5,  R6,  R7,
+      R8,  R9,  R10, R11,
+      R12, R13, R14, R15,
+      R16, R17, R18, R19,
+      R20, R21, R22, R23,
+      R24, R25, R26, R27,
+      R28, R29, R30, R31,
+
+      ZR,  AT,  V0,  V1,
+      A0,  A1,  A2,  A3,
+      T0,  T1,  T2,  T3,
+      T4,  T5,  T6,  T7,
+      S0,  S1,  S2,  S3,
+      S4,  S5,  S6,  S7,
+      T8,  T9,  K0,  K1,
+      GP,  SP,  FP,  RA
+  };
+  ASSERT(ARRAY_SIZE(kNames) == ARRAY_SIZE(kRegisters));
+  for (unsigned i = 0; i < ARRAY_SIZE(kNames); i++) {
+    if (strcmp(kNames[i], name) == 0) {
+      return kRegisters[i];
+    }
+  }
+  return kNoRegister;
+}
+
+
+static FRegister LookupFRegisterByName(const char* name) {
+  int reg_nr = -1;
+  bool ok = SScanF(name, "f%d", &reg_nr);
+  if (ok && (0 <= reg_nr) && (reg_nr < kNumberOfFRegisters)) {
+    return static_cast<FRegister>(reg_nr);
+  }
+  return kNoFRegister;
+}
+
+
+bool SimulatorDebugger::GetValue(char* desc, uint32_t* value) {
+  Register reg = LookupCpuRegisterByName(desc);
+  if (reg != kNoRegister) {
+    *value = sim_->get_register(reg);
+    return true;
+  }
+  if ((desc[0] == '*')) {
+    uint32_t addr;
+    if (GetValue(desc + 1, &addr)) {
+      if (Simulator::IsIllegalAddress(addr)) {
+        return false;
+      }
+      *value = *(reinterpret_cast<uint32_t*>(addr));
+      return true;
+    }
+  }
+  if (strcmp("pc", desc) == 0) {
+    *value = sim_->get_pc();
+    return true;
+  }
+  bool retval = SScanF(desc, "0x%x", value) == 1;
+  if (!retval) {
+    retval = SScanF(desc, "%x", value) == 1;
+  }
+  return retval;
+}
+
+
+bool SimulatorDebugger::GetFValue(char* desc, double* value) {
+  FRegister freg = LookupFRegisterByName(desc);
+  if (freg != kNoFRegister) {
+    *value = sim_->get_fregister(freg);
+    return true;
+  }
+  if ((desc[0] == '*')) {
+    uint32_t addr;
+    if (GetValue(desc + 1, &addr)) {
+      if (Simulator::IsIllegalAddress(addr)) {
+        return false;
+      }
+      *value = *(reinterpret_cast<float*>(addr));
+      return true;
+    }
+  }
+  return false;
+}
+
+
+bool SimulatorDebugger::SetBreakpoint(Instr* breakpc) {
+  // Check if a breakpoint can be set. If not return without any side-effects.
+  if (sim_->break_pc_ != NULL) {
+    return false;
+  }
+
+  // Set the breakpoint.
+  sim_->break_pc_ = breakpc;
+  sim_->break_instr_ = breakpc->InstructionBits();
+  // Not setting the breakpoint instruction in the code itself. It will be set
+  // when the debugger shell continues.
+  return true;
+}
+
+
+bool SimulatorDebugger::DeleteBreakpoint(Instr* breakpc) {
+  if (sim_->break_pc_ != NULL) {
+    sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
+  }
+
+  sim_->break_pc_ = NULL;
+  sim_->break_instr_ = 0;
+  return true;
+}
+
+
+void SimulatorDebugger::UndoBreakpoints() {
+  if (sim_->break_pc_ != NULL) {
+    sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
+  }
+}
+
+
+void SimulatorDebugger::RedoBreakpoints() {
+  if (sim_->break_pc_ != NULL) {
+    sim_->break_pc_->SetInstructionBits(Instr::kBreakPointInstruction);
+  }
+}
+
+
+void SimulatorDebugger::Debug() {
+  intptr_t last_pc = -1;
+  bool done = false;
+  bool decoded = true;
+
+#define COMMAND_SIZE 63
+#define ARG_SIZE 255
+
+#define STR(a) #a
+#define XSTR(a) STR(a)
+
+  char cmd[COMMAND_SIZE + 1];
+  char arg1[ARG_SIZE + 1];
+  char arg2[ARG_SIZE + 1];
+
+  // make sure to have a proper terminating character if reaching the limit
+  cmd[COMMAND_SIZE] = 0;
+  arg1[ARG_SIZE] = 0;
+  arg2[ARG_SIZE] = 0;
+
+  // Undo all set breakpoints while running in the debugger shell. This will
+  // make them invisible to all commands.
+  UndoBreakpoints();
+
+  while (!done) {
+    if (last_pc != sim_->get_pc()) {
+      last_pc = sim_->get_pc();
+      decoded = Disassembler::Disassemble(last_pc, last_pc + Instr::kInstrSize);
+    }
+    char* line = ReadLine("sim> ");
+    if (line == NULL) {
+      break;
+    } else {
+      // Use sscanf to parse the individual parts of the command line. At the
+      // moment no command expects more than two parameters.
+      int args = SScanF(line,
+                        "%" XSTR(COMMAND_SIZE) "s "
+                        "%" XSTR(ARG_SIZE) "s "
+                        "%" XSTR(ARG_SIZE) "s",
+                        cmd, arg1, arg2);
+      if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) {
+        OS::Print("c/cont -- continue execution\n"
+                  "disasm -- disassemble instrs at current pc location\n"
+                  "  other variants are:\n"
+                  "    disasm <address>\n"
+                  "    disasm <address> <number_of_instructions>\n"
+                  "  by default 10 instrs are disassembled\n"
+                  "del -- delete breakpoints\n"
+                  "gdb -- transfer control to gdb\n"
+                  "h/help -- print this help string\n"
+                  "break <address> -- set break point at specified address\n"
+                  "p/print <reg or value or *addr> -- print integer value\n"
+                  "pf/printfloat <freg or *addr> -- print float value\n"
+                  "po/printobject <*reg or *addr> -- print object\n"
+                  "si/stepi -- single step an instruction\n"
+                  "unstop -- if current pc is a stop instr make it a nop\n"
+                  "q/quit -- Quit the debugger and exit the program\n");
+      } else if ((strcmp(cmd, "quit") == 0) || (strcmp(cmd, "q") == 0)) {
+        OS::Print("Quitting\n");
+        OS::Exit(0);
+      } else if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
+        if (decoded) {
+          sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
+        } else {
+          OS::Print("Instruction could not be decoded. Stepping disabled.\n");
+        }
+      } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
+        if (decoded) {
+          // Execute the one instruction we broke at with breakpoints disabled.
+          sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
+          // Leave the debugger shell.
+          done = true;
+        } else {
+          OS::Print("Instruction could not be decoded. Cannot continue.\n");
+        }
+      } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
+        if (args == 2) {
+          uint32_t value;
+          if (GetValue(arg1, &value)) {
+            OS::Print("%s: %u 0x%x\n", arg1, value, value);
+          } else {
+            OS::Print("%s unrecognized\n", arg1);
+          }
+        } else {
+          OS::Print("print <reg or value or *addr>\n");
+        }
+      } else if ((strcmp(cmd, "pf") == 0) ||
+                 (strcmp(cmd, "printfloat") == 0)) {
+        if (args == 2) {
+          double dvalue;
+          if (GetFValue(arg1, &dvalue)) {
+            uint64_t long_value = bit_cast<uint64_t, double>(dvalue);
+            OS::Print("%s: %llu 0x%llx %.8g\n",
+                arg1, long_value, long_value, dvalue);
+          } else {
+            OS::Print("%s unrecognized\n", arg1);
+          }
+        } else {
+          OS::Print("printfloat <dreg or *addr>\n");
+        }
+      } else if ((strcmp(cmd, "po") == 0) ||
+                 (strcmp(cmd, "printobject") == 0)) {
+        if (args == 2) {
+          uint32_t value;
+          // Make the dereferencing '*' optional.
+          if (((arg1[0] == '*') && GetValue(arg1 + 1, &value)) ||
+              GetValue(arg1, &value)) {
+            if (Isolate::Current()->heap()->Contains(value)) {
+              OS::Print("%s: \n", arg1);
+#if defined(DEBUG)
+              const Object& obj = Object::Handle(
+                  reinterpret_cast<RawObject*>(value));
+              obj.Print();
+#endif  // defined(DEBUG)
+            } else {
+              OS::Print("0x%x is not an object reference\n", value);
+            }
+          } else {
+            OS::Print("%s unrecognized\n", arg1);
+          }
+        } else {
+          OS::Print("printobject <*reg or *addr>\n");
+        }
+      } else if (strcmp(cmd, "disasm") == 0) {
+        uint32_t start = 0;
+        uint32_t end = 0;
+        if (args == 1) {
+          start = sim_->get_pc();
+          end = start + (10 * Instr::kInstrSize);
+        } else if (args == 2) {
+          if (GetValue(arg1, &start)) {
+            // no length parameter passed, assume 10 instructions
+            if (Simulator::IsIllegalAddress(start)) {
+              // If start isn't a valid address, warn and use PC instead
+              OS::Print("First argument yields invalid address: 0x%x\n", start);
+              OS::Print("Using PC instead");
+              start = sim_->get_pc();
+            }
+            end = start + (10 * Instr::kInstrSize);
+          }
+        } else {
+          uint32_t length;
+          if (GetValue(arg1, &start) && GetValue(arg2, &length)) {
+            if (Simulator::IsIllegalAddress(start)) {
+              // If start isn't a valid address, warn and use PC instead
+              OS::Print("First argument yields invalid address: 0x%x\n", start);
+              OS::Print("Using PC instead\n");
+              start = sim_->get_pc();
+            }
+            end = start + (length * Instr::kInstrSize);
+          }
+        }
+
+        Disassembler::Disassemble(start, end);
+      } else if (strcmp(cmd, "gdb") == 0) {
+        OS::Print("relinquishing control to gdb\n");
+        OS::DebugBreak();
+        OS::Print("regaining control from gdb\n");
+      } else if (strcmp(cmd, "break") == 0) {
+        if (args == 2) {
+          uint32_t addr;
+          if (GetValue(arg1, &addr)) {
+            if (!SetBreakpoint(reinterpret_cast<Instr*>(addr))) {
+              OS::Print("setting breakpoint failed\n");
+            }
+          } else {
+            OS::Print("%s unrecognized\n", arg1);
+          }
+        } else {
+          OS::Print("break <addr>\n");
+        }
+      } else if (strcmp(cmd, "del") == 0) {
+        if (!DeleteBreakpoint(NULL)) {
+          OS::Print("deleting breakpoint failed\n");
+        }
+      } else if (strcmp(cmd, "unstop") == 0) {
+        intptr_t stop_pc = sim_->get_pc() - Instr::kInstrSize;
+        Instr* stop_instr = reinterpret_cast<Instr*>(stop_pc);
+        if (stop_instr->IsBreakPoint()) {
+          stop_instr->SetInstructionBits(Instr::kNopInstruction);
+        } else {
+          OS::Print("Not at debugger stop.\n");
+        }
+      } else {
+        OS::Print("Unknown command: %s\n", cmd);
+      }
+    }
+    delete[] line;
+  }
+
+  // Add all the breakpoints back to stop execution and enter the debugger
+  // shell when hit.
+  RedoBreakpoints();
+
+#undef COMMAND_SIZE
+#undef ARG_SIZE
+
+#undef STR
+#undef XSTR
+}
+
+
+char* SimulatorDebugger::ReadLine(const char* prompt) {
+  char* result = NULL;
+  char line_buf[256];
+  int offset = 0;
+  bool keep_going = true;
+  fprintf(stdout, "%s", prompt);
+  fflush(stdout);
+  while (keep_going) {
+    if (fgets(line_buf, sizeof(line_buf), stdin) == NULL) {
+      // fgets got an error. Just give up.
+      if (result != NULL) {
+        delete[] result;
+      }
+      return NULL;
+    }
+    int len = strlen(line_buf);
+    if (len > 1 &&
+        line_buf[len - 2] == '\\' &&
+        line_buf[len - 1] == '\n') {
+      // When we read a line that ends with a "\" we remove the escape and
+      // append the remainder.
+      line_buf[len - 2] = '\n';
+      line_buf[len - 1] = 0;
+      len -= 1;
+    } else if ((len > 0) && (line_buf[len - 1] == '\n')) {
+      // Since we read a new line we are done reading the line. This
+      // will exit the loop after copying this buffer into the result.
+      keep_going = false;
+    }
+    if (result == NULL) {
+      // Allocate the initial result and make room for the terminating '\0'
+      result = new char[len + 1];
+      if (result == NULL) {
+        // OOM, so cannot readline anymore.
+        return NULL;
+      }
+    } else {
+      // Allocate a new result with enough room for the new addition.
+      int new_len = offset + len + 1;
+      char* new_result = new char[new_len];
+      if (new_result == NULL) {
+        // OOM, free the buffer allocated so far and return NULL.
+        delete[] result;
+        return NULL;
+      } else {
+        // Copy the existing input into the new array and set the new
+        // array as the result.
+        memmove(new_result, result, offset);
+        delete[] result;
+        result = new_result;
+      }
+    }
+    // Copy the newly read line into the result.
+    memmove(result + offset, line_buf, len);
+    offset += len;
+  }
+  ASSERT(result != NULL);
+  result[offset] = '\0';
+  return result;
+}
+
+
+void Simulator::InitOnce() {
+}
+
+
 Simulator::Simulator() {
   // Setup simulator support first. Some of this information is needed to
   // setup the architecture state.
@@ -26,6 +494,20 @@
   stack_ = new char[(Isolate::GetSpecifiedStackSize() +
                      Isolate::kStackSizeBuffer +
                      kSimulatorStackUnderflowSize)];
+  icount_ = 0;
+  delay_slot_ = false;
+  break_pc_ = NULL;
+  break_instr_ = 0;
+
+  // Setup architecture state.
+  // All registers are initialized to zero to start with.
+  for (int i = 0; i < kNumberOfCpuRegisters; i++) {
+    registers_[i] = 0;
+  }
+  pc_ = 0;
+  // The sp is initialized to point to the bottom (high address) of the
+  // allocated stack area.
+  registers_[SP] = StackTop();
 }
 
 
@@ -51,15 +533,59 @@
 // Sets the register in the architecture state. It will also deal with updating
 // Simulator internal state for special registers such as PC.
 void Simulator::set_register(Register reg, int32_t value) {
-  UNIMPLEMENTED();
+  if (reg != R0) {
+    registers_[reg] = value;
+  }
 }
 
 
 // Get the register from the architecture state. This function does handle
 // the special case of accessing the PC register.
 int32_t Simulator::get_register(Register reg) const {
-  UNIMPLEMENTED();
-  return 0;
+  if (reg == R0) {
+    return 0;
+  }
+  return registers_[reg];
+}
+
+
+void Simulator::set_fregister(FRegister reg, double value) {
+  ASSERT((reg >= 0) && (reg < kNumberOfFRegisters));
+  fregisters_[reg] = value;
+}
+
+
+double Simulator::get_fregister(FRegister reg) const {
+  ASSERT((reg >= 0) && (reg < kNumberOfFRegisters));
+  return fregisters_[reg];
+}
+
+
+void Simulator::HandleIllegalAccess(uword addr, Instr* instr) {
+  uword fault_pc = get_pc();
+  // The debugger will not be able to single step past this instruction, but
+  // it will be possible to disassemble the code and inspect registers.
+  char buffer[128];
+  snprintf(buffer, sizeof(buffer),
+           "illegal memory access at 0x%"Px", pc=0x%"Px"\n",
+           addr, fault_pc);
+  SimulatorDebugger dbg(this);
+  dbg.Stop(instr, buffer);
+  // The debugger will return control in non-interactive mode.
+  FATAL("Cannot continue execution after illegal memory access.");
+}
+
+
+void Simulator::UnalignedAccess(const char* msg, uword addr, Instr* instr) {
+  // The debugger will not be able to single step past this instruction, but
+  // it will be possible to disassemble the code and inspect registers.
+  char buffer[64];
+  snprintf(buffer, sizeof(buffer),
+           "unaligned %s at 0x%"Px", pc=%p\n", msg, addr, instr);
+  SimulatorDebugger dbg(this);
+  dbg.Stop(instr, buffer);
+  // The debugger will return control in non-interactive mode.
+  FATAL("Cannot continue execution after unaligned access.");
 }
 
 
@@ -73,7 +599,441 @@
 }
 
 
-void Simulator::InitOnce() {
+void Simulator::Format(Instr* instr, const char* format) {
+  OS::PrintErr("Simulator - unknown instruction: %s\n", format);
+  UNIMPLEMENTED();
+}
+
+
+int8_t Simulator::ReadB(uword addr) {
+  int8_t* ptr = reinterpret_cast<int8_t*>(addr);
+  return *ptr;
+}
+
+
+uint8_t Simulator::ReadBU(uword addr) {
+  uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
+  return *ptr;
+}
+
+
+int16_t Simulator::ReadH(uword addr, Instr* instr) {
+  if ((addr & 1) == 0) {
+    int16_t* ptr = reinterpret_cast<int16_t*>(addr);
+    return *ptr;
+  }
+  UnalignedAccess("signed halfword read", addr, instr);
+  return 0;
+}
+
+
+uint16_t Simulator::ReadHU(uword addr, Instr* instr) {
+  if ((addr & 1) == 0) {
+    uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
+    return *ptr;
+  }
+  UnalignedAccess("unsigned halfword read", addr, instr);
+  return 0;
+}
+
+
+int Simulator::ReadW(uword addr, Instr* instr) {
+  if ((addr & 3) == 0) {
+    intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
+    return *ptr;
+  }
+  UnalignedAccess("read", addr, instr);
+  return 0;
+}
+
+
+void Simulator::WriteB(uword addr, uint8_t value) {
+  uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
+  *ptr = value;
+}
+
+
+void Simulator::WriteH(uword addr, uint16_t value, Instr* instr) {
+  if ((addr & 1) == 0) {
+    uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
+    *ptr = value;
+    return;
+  }
+  UnalignedAccess("halfword write", addr, instr);
+}
+
+
+void Simulator::WriteW(uword addr, int value, Instr* instr) {
+  if ((addr & 3) == 0) {
+    intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
+    *ptr = value;
+    return;
+  }
+  UnalignedAccess("write", addr, instr);
+}
+
+
+bool Simulator::OverflowFrom(int32_t alu_out,
+                             int32_t left, int32_t right, bool addition) {
+  bool overflow;
+  if (addition) {
+               // Operands have the same sign.
+    overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0))
+               // And operands and result have different sign.
+               && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
+  } else {
+               // Operands have different signs.
+    overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0))
+               // And first operand and result have different signs.
+               && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
+  }
+  return overflow;
+}
+
+
+void Simulator::DecodeSpecial(Instr* instr) {
+  ASSERT(instr->OpcodeField() == SPECIAL);
+  switch (instr->FunctionField()) {
+    case ADDU: {
+      ASSERT(instr->SaField() == 0);
+      // Format(instr, "addu 'rd, 'rs, 'rt");
+      int32_t rs_val = get_register(instr->RsField());
+      int32_t rt_val = get_register(instr->RtField());
+      set_register(instr->RdField(), rs_val + rt_val);
+      break;
+    }
+    case AND: {
+      ASSERT(instr->SaField() == 0);
+      // Format(instr, "and 'rd, 'rs, 'rt");
+      int32_t rs_val = get_register(instr->RsField());
+      int32_t rt_val = get_register(instr->RtField());
+      set_register(instr->RdField(), rs_val & rt_val);
+      break;
+    }
+    case BREAK: {
+      SimulatorDebugger dbg(this);
+      dbg.Stop(instr, "breakpoint");
+      break;
+    }
+    case DIV: {
+      ASSERT(instr->RdField() == 0);
+      ASSERT(instr->SaField() == 0);
+      // Format(instr, "div 'rs, 'rt");
+      int32_t rs_val = get_register(instr->RsField());
+      int32_t rt_val = get_register(instr->RtField());
+      if (rt_val == 0) {
+        // Results are unpredictable.
+        set_hi_register(0);
+        set_lo_register(0);
+        // TODO(zra): Drop into the debugger here.
+        break;
+      }
+
+      if ((rs_val == static_cast<int32_t>(0x80000000)) &&
+          (rt_val == static_cast<int32_t>(0xffffffff))) {
+        set_lo_register(0x80000000);
+        set_hi_register(0);
+      } else {
+        set_lo_register(rs_val / rt_val);
+        set_hi_register(rs_val % rt_val);
+      }
+      break;
+    }
+    case DIVU: {
+      ASSERT(instr->RdField() == 0);
+      ASSERT(instr->SaField() == 0);
+      // Format(instr, "divu 'rs, 'rt");
+      uint32_t rs_val = get_register(instr->RsField());
+      uint32_t rt_val = get_register(instr->RtField());
+      if (rt_val == 0) {
+        // Results are unpredictable.
+        set_hi_register(0);
+        set_lo_register(0);
+        // TODO(zra): Drop into the debugger here.
+        break;
+      }
+
+      set_lo_register(rs_val / rt_val);
+      set_hi_register(rs_val % rt_val);
+      break;
+    }
+    case MFHI: {
+      ASSERT(instr->RsField() == 0);
+      ASSERT(instr->RtField() == 0);
+      ASSERT(instr->SaField() == 0);
+      // Format(instr, "mfhi 'rd");
+      set_register(instr->RdField(), get_hi_register());
+      break;
+    }
+    case MFLO: {
+      ASSERT(instr->RsField() == 0);
+      ASSERT(instr->RtField() == 0);
+      ASSERT(instr->SaField() == 0);
+      // Format(instr, "mflo 'rd");
+      set_register(instr->RdField(), get_lo_register());
+      break;
+    }
+    case SLL: {
+      ASSERT(instr->RsField() == 0);
+      if ((instr->RdField() == R0) &&
+          (instr->RtField() == R0) &&
+          (instr->SaField() == 0)) {
+        // Format(instr, "nop");
+        // Nothing to be done for NOP.
+      } else {
+        int32_t rt_val = get_register(instr->RtField());
+        int sa = instr->SaField();
+        set_register(instr->RdField(), rt_val << sa);
+      }
+      break;
+    }
+    case JR: {
+      ASSERT(instr->RtField() == R0);
+      ASSERT(instr->RdField() == R0);
+      ASSERT(!delay_slot_);
+      // Format(instr, "jr'hint 'rs");
+      uword next_pc = get_register(instr->RsField());
+      ExecuteDelaySlot();
+      pc_ = next_pc - Instr::kInstrSize;  // Account for regular PC increment.
+      break;
+    }
+    default: {
+      OS::PrintErr("DecodeSpecial: 0x%x\n", instr->InstructionBits());
+      UNIMPLEMENTED();
+      break;
+    }
+  }
+}
+
+
+void Simulator::DecodeSpecial2(Instr* instr) {
+  ASSERT(instr->OpcodeField() == SPECIAL2);
+  switch (instr->FunctionField()) {
+    case CLO: {
+      ASSERT(instr->SaField() == 0);
+      ASSERT(instr->RtField() == instr->RdField());
+      // Format(instr, "clo 'rd, 'rs");
+      int32_t rs_val = get_register(instr->RsField());
+      int32_t bitcount = 0;
+      while (rs_val < 0) {
+        bitcount++;
+        rs_val <<= 1;
+      }
+      set_register(instr->RdField(), bitcount);
+      break;
+    }
+    case CLZ: {
+      ASSERT(instr->SaField() == 0);
+      ASSERT(instr->RtField() == instr->RdField());
+      // Format(instr, "clz 'rd, 'rs");
+      int32_t rs_val = get_register(instr->RsField());
+      int32_t bitcount = 0;
+      if (rs_val != 0) {
+        while (rs_val > 0) {
+          bitcount++;
+          rs_val <<= 1;
+        }
+      } else {
+        bitcount = 32;
+      }
+      set_register(instr->RdField(), bitcount);
+      break;
+    }
+    default: {
+      OS::PrintErr("DecodeSpecial2: 0x%x\n", instr->InstructionBits());
+      UNIMPLEMENTED();
+      break;
+    }
+  }
+}
+
+
+void Simulator::InstructionDecode(Instr* instr) {
+  switch (instr->OpcodeField()) {
+    case SPECIAL: {
+      DecodeSpecial(instr);
+      break;
+    }
+    case SPECIAL2: {
+      DecodeSpecial2(instr);
+      break;
+    }
+    case ADDIU: {
+      // Format(instr, "addiu 'rt, 'rs, 'imms");
+      int32_t rs_val = get_register(instr->RsField());
+      int32_t imm_val = instr->SImmField();
+      int32_t res = rs_val + imm_val;
+      // Rt is set even on overflow.
+      set_register(instr->RtField(), res);
+      break;
+    }
+    case ANDI: {
+      // Format(instr, "andi 'rt, 'rs, 'immu");
+      int32_t rs_val = get_register(instr->RsField());
+      set_register(instr->RtField(), rs_val & instr->UImmField());
+      break;
+    }
+    case LB: {
+      // Format(instr, "lb 'rt, 'imms('rs)");
+      int32_t base_val = get_register(instr->RsField());
+      int32_t imm_val = instr->SImmField();
+      uword addr = base_val + imm_val;
+      if (Simulator::IsIllegalAddress(addr)) {
+        HandleIllegalAccess(addr, instr);
+      } else {
+        int32_t res = ReadB(addr);
+        set_register(instr->RtField(), res);
+      }
+      break;
+    }
+    case LBU: {
+      // Format(instr, "lbu 'rt, 'imms('rs)");
+      int32_t base_val = get_register(instr->RsField());
+      int32_t imm_val = instr->SImmField();
+      uword addr = base_val + imm_val;
+      if (Simulator::IsIllegalAddress(addr)) {
+        HandleIllegalAccess(addr, instr);
+      } else {
+        int32_t res = ReadBU(addr);
+        set_register(instr->RtField(), res);
+      }
+      break;
+    }
+    case LH: {
+      // Format(instr, "lh 'rt, 'imms('rs)");
+      int32_t base_val = get_register(instr->RsField());
+      int32_t imm_val = instr->SImmField();
+      uword addr = base_val + imm_val;
+      if (Simulator::IsIllegalAddress(addr)) {
+        HandleIllegalAccess(addr, instr);
+      } else {
+        int32_t res = ReadH(addr, instr);
+        set_register(instr->RtField(), res);
+      }
+      break;
+    }
+    case LHU: {
+      // Format(instr, "lhu 'rt, 'imms('rs)");
+      int32_t base_val = get_register(instr->RsField());
+      int32_t imm_val = instr->SImmField();
+      uword addr = base_val + imm_val;
+      if (Simulator::IsIllegalAddress(addr)) {
+        HandleIllegalAccess(addr, instr);
+      } else {
+        int32_t res = ReadHU(addr, instr);
+        set_register(instr->RtField(), res);
+      }
+      break;
+    }
+    case LUI: {
+      ASSERT(instr->RsField() == 0);
+      set_register(instr->RtField(), instr->UImmField() << 16);
+      break;
+    }
+    case LW: {
+      // Format(instr, "lw 'rt, 'imms('rs)");
+      int32_t base_val = get_register(instr->RsField());
+      int32_t imm_val = instr->SImmField();
+      uword addr = base_val + imm_val;
+      if (Simulator::IsIllegalAddress(addr)) {
+        HandleIllegalAccess(addr, instr);
+      } else {
+        int32_t res = ReadW(addr, instr);
+        set_register(instr->RtField(), res);
+      }
+      break;
+    }
+    case ORI: {
+      // Format(instr, "ori 'rt, 'rs, 'immu");
+      int32_t rs_val = get_register(instr->RsField());
+      set_register(instr->RtField(), rs_val | instr->UImmField());
+      break;
+    }
+    case SB: {
+      // Format(instr, "sb 'rt, 'imms('rs)");
+      int32_t rt_val = get_register(instr->RtField());
+      int32_t base_val = get_register(instr->RsField());
+      int32_t imm_val = instr->SImmField();
+      uword addr = base_val + imm_val;
+      if (Simulator::IsIllegalAddress(addr)) {
+        HandleIllegalAccess(addr, instr);
+      } else {
+        WriteB(addr, rt_val & 0xff);
+      }
+      break;
+    }
+    case SH: {
+      // Format(instr, "sh 'rt, 'imms('rs)");
+      int32_t rt_val = get_register(instr->RtField());
+      int32_t base_val = get_register(instr->RsField());
+      int32_t imm_val = instr->SImmField();
+      uword addr = base_val + imm_val;
+      if (Simulator::IsIllegalAddress(addr)) {
+        HandleIllegalAccess(addr, instr);
+      } else {
+        WriteH(addr, rt_val & 0xffff, instr);
+      }
+      break;
+    }
+    case SW: {
+      // Format(instr, "sw 'rt, 'imms('rs)");
+      int32_t rt_val = get_register(instr->RtField());
+      int32_t base_val = get_register(instr->RsField());
+      int32_t imm_val = instr->SImmField();
+      uword addr = base_val + imm_val;
+      if (Simulator::IsIllegalAddress(addr)) {
+        HandleIllegalAccess(addr, instr);
+      } else {
+        WriteW(addr, rt_val, instr);
+      }
+      break;
+    }
+    default: {
+      OS::PrintErr("Undecoded instruction: 0x%x at %p\n",
+                    instr->InstructionBits(), instr);
+      UNIMPLEMENTED();
+      break;
+    }
+  }
+  pc_ += Instr::kInstrSize;
+}
+
+
+void Simulator::ExecuteDelaySlot() {
+  ASSERT(pc_ != kEndSimulatingPC);
+  delay_slot_ = true;
+  icount_++;
+  if (icount_ == FLAG_stop_sim_at) {
+    UNIMPLEMENTED();
+  }
+  Instr* instr = Instr::At(pc_ + Instr::kInstrSize);
+  InstructionDecode(instr);
+  delay_slot_ = false;
+}
+
+
+void Simulator::Execute() {
+  if (FLAG_stop_sim_at == 0) {
+    // Fast version of the dispatch loop without checking whether the simulator
+    // should be stopping at a particular executed instruction.
+    while (pc_ != kEndSimulatingPC) {
+      icount_++;
+      Instr* instr = Instr::At(pc_);
+      InstructionDecode(instr);
+    }
+  } else {
+    // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
+    // we reach the particular instruction count.
+    while (pc_ != kEndSimulatingPC) {
+      icount_++;
+      if (icount_ == FLAG_stop_sim_at) {
+        UNIMPLEMENTED();
+      } else {
+        Instr* instr = Instr::At(pc_);
+        InstructionDecode(instr);
+      }
+    }
+  }
 }
 
 
@@ -81,10 +1041,81 @@
                         int32_t parameter0,
                         int32_t parameter1,
                         int32_t parameter2,
-                        int32_t parameter3,
-                        int32_t parameter4) {
-  UNIMPLEMENTED();
-  return 0LL;
+                        int32_t parameter3) {
+  // Save the SP register before the call so we can restore it.
+  int32_t sp_before_call = get_register(SP);
+
+  // Setup parameters.
+  set_register(A0, parameter0);
+  set_register(A1, parameter1);
+  set_register(A2, parameter2);
+  set_register(A3, parameter3);
+
+  // Make sure the activation frames are properly aligned.
+  int32_t stack_pointer = sp_before_call;
+  static const int kFrameAlignment = OS::ActivationFrameAlignment();
+  if (kFrameAlignment > 0) {
+    stack_pointer = Utils::RoundDown(stack_pointer, kFrameAlignment);
+  }
+  set_register(SP, stack_pointer);
+
+  // Prepare to execute the code at entry.
+  set_pc(entry);
+  // Put down marker for end of simulation. The simulator will stop simulation
+  // when the PC reaches this value. By saving the "end simulation" value into
+  // RA the simulation stops when returning to this call point.
+  set_register(RA, kEndSimulatingPC);
+
+  // Remember the values of callee-saved registers.
+  // The code below assumes that r9 is not used as sb (static base) in
+  // simulator code and therefore is regarded as a callee-saved register.
+  int32_t r16_val = get_register(R16);
+  int32_t r17_val = get_register(R17);
+  int32_t r18_val = get_register(R18);
+  int32_t r19_val = get_register(R19);
+  int32_t r20_val = get_register(R20);
+  int32_t r21_val = get_register(R21);
+  int32_t r22_val = get_register(R22);
+  int32_t r23_val = get_register(R23);
+
+  // Setup the callee-saved registers with a known value. To be able to check
+  // that they are preserved properly across dart execution.
+  int32_t callee_saved_value = icount_;
+  set_register(R16, callee_saved_value);
+  set_register(R17, callee_saved_value);
+  set_register(R18, callee_saved_value);
+  set_register(R19, callee_saved_value);
+  set_register(R20, callee_saved_value);
+  set_register(R21, callee_saved_value);
+  set_register(R22, callee_saved_value);
+  set_register(R23, callee_saved_value);
+
+  // Start the simulation
+  Execute();
+
+  // Check that the callee-saved registers have been preserved.
+  ASSERT(callee_saved_value == get_register(R16));
+  ASSERT(callee_saved_value == get_register(R17));
+  ASSERT(callee_saved_value == get_register(R18));
+  ASSERT(callee_saved_value == get_register(R19));
+  ASSERT(callee_saved_value == get_register(R20));
+  ASSERT(callee_saved_value == get_register(R21));
+  ASSERT(callee_saved_value == get_register(R22));
+  ASSERT(callee_saved_value == get_register(R23));
+
+  // Restore callee-saved registers with the original value.
+  set_register(R16, r16_val);
+  set_register(R17, r17_val);
+  set_register(R18, r18_val);
+  set_register(R19, r19_val);
+  set_register(R20, r20_val);
+  set_register(R21, r21_val);
+  set_register(R22, r22_val);
+  set_register(R23, r23_val);
+
+  // Restore the SP register and return R1:R0.
+  set_register(SP, sp_before_call);
+  return Utils::LowHighTo64Bits(get_register(V0), get_register(V1));
 }
 
 }  // namespace dart
diff --git a/runtime/vm/simulator_mips.h b/runtime/vm/simulator_mips.h
index cd8df77..919ed99 100644
--- a/runtime/vm/simulator_mips.h
+++ b/runtime/vm/simulator_mips.h
@@ -35,6 +35,19 @@
   void set_register(Register reg, int32_t value);
   int32_t get_register(Register reg) const;
 
+  // Accessors for floating point register state.
+  void set_fregister(FRegister freg, double value);
+  double get_fregister(FRegister) const;
+
+  // Accessor for the pc.
+  int32_t get_pc() const { return pc_; }
+
+  // Accessors for hi, lo registers.
+  void set_hi_register(int32_t value) { hi_reg_ = value; }
+  void set_lo_register(int32_t value) { lo_reg_ = value; }
+  int32_t get_hi_register() const { return hi_reg_; }
+  int32_t get_lo_register() const { return lo_reg_; }
+
   // Accessor to the internal simulator stack top.
   uword StackTop() const;
 
@@ -48,11 +61,68 @@
                int32_t parameter0,
                int32_t parameter1,
                int32_t parameter2,
-               int32_t parameter3,
-               int32_t parameter4);
+               int32_t parameter3);
 
  private:
+  // A pc value used to signal the simulator to stop execution.  Generally
+  // the ra is set to this value on transition from native C code to
+  // simulated execution, so that the simulator can "return" to the native
+  // C code.
+  static const uword kEndSimulatingPC = -1;
+
+  // Special registers for the results of div, divu.
+  int32_t hi_reg_;
+  int32_t lo_reg_;
+
+  int32_t registers_[kNumberOfCpuRegisters];
+  double fregisters_[kNumberOfFRegisters];
+  uword pc_;
+
+  // Simulator support.
   char* stack_;
+  int icount_;
+  bool delay_slot_;
+
+  // Registered breakpoints.
+  Instr* break_pc_;
+  int32_t break_instr_;
+
+  // Illegal memory access support.
+  static bool IsIllegalAddress(uword addr) {
+    return addr < 64*1024;
+  }
+  void HandleIllegalAccess(uword addr, Instr* instr);
+
+  // Read and write memory.
+  void UnalignedAccess(const char* msg, uword addr, Instr* instr);
+
+  bool OverflowFrom(int32_t alu_out,
+                    int32_t left,
+                    int32_t right,
+                    bool addition);
+
+  void set_pc(uword value) { pc_ = value; }
+
+  void Format(Instr* instr, const char* format);
+
+  inline int8_t ReadB(uword addr);
+  inline uint8_t ReadBU(uword addr);
+  inline int16_t ReadH(uword addr, Instr* instr);
+  inline uint16_t ReadHU(uword addr, Instr *instr);
+  inline int ReadW(uword addr, Instr* instr);
+
+  inline void WriteB(uword addr, uint8_t value);
+  inline void WriteH(uword addr, uint16_t value, Instr* isntr);
+  inline void WriteW(uword addr, int value, Instr* instr);
+
+  void DecodeSpecial(Instr* instr);
+  void DecodeSpecial2(Instr* instr);
+  void InstructionDecode(Instr* instr);
+
+  void Execute();
+  void ExecuteDelaySlot();
+
+  friend class SimulatorDebugger;
 };
 
 }  // namespace dart
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index b729606..c477c7c 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -33,7 +33,9 @@
   // Check if this is a class which is stored in the object store.
   return (class_id == kObjectCid ||
           (class_id >= kInstanceCid && class_id <= kWeakPropertyCid) ||
-          RawObject::IsStringClassId(class_id));
+          RawObject::IsStringClassId(class_id) ||
+          RawObject::IsTypedDataClassId(class_id) ||
+          RawObject::IsExternalTypedDataClassId(class_id));
 }
 
 
@@ -312,6 +314,17 @@
     }
     CLASS_LIST_NO_OBJECT(SNAPSHOT_READ)
 #undef SNAPSHOT_READ
+#define SNAPSHOT_READ(clazz)                                                   \
+    case kTypedData##clazz##Cid: {                                             \
+      obj_ = TypedData::ReadFrom(this, object_id, tags, kind_);                \
+      break;                                                                   \
+    }                                                                          \
+    case kExternalTypedData##clazz##Cid: {                                     \
+      obj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_);        \
+      break;                                                                   \
+    }
+    CLASS_LIST_TYPED_DATA(SNAPSHOT_READ)
+#undef SNAPSHOT_READ
     default: UNREACHABLE(); break;
   }
   if (kind_ == Snapshot::kFull) {
@@ -448,7 +461,7 @@
   ASSERT(isolate()->no_gc_scope_depth() != 0);
   if (class_id < kNumPredefinedCids) {
     ASSERT((class_id >= kInstanceCid) &&
-           (class_id <= kExternalTwoByteStringCid));
+           (class_id <= kExternalTypedDataFloat64ArrayCid));
     return isolate()->class_table()->At(class_id);
   }
   cls_ = Object::class_class();
@@ -522,6 +535,16 @@
 }
 
 
+RawBoundedType* SnapshotReader::NewBoundedType() {
+  ALLOC_NEW_OBJECT(BoundedType, object_store()->bounded_type_class());
+}
+
+
+RawMixinAppType* SnapshotReader::NewMixinAppType() {
+  ALLOC_NEW_OBJECT(MixinAppType, object_store()->mixin_app_type_class());
+}
+
+
 RawPatchClass* SnapshotReader::NewPatchClass() {
   ALLOC_NEW_OBJECT(PatchClass, Object::patch_class_class());
 }
@@ -779,6 +802,17 @@
     }
     CLASS_LIST_NO_OBJECT(SNAPSHOT_READ)
 #undef SNAPSHOT_READ
+#define SNAPSHOT_READ(clazz)                                                   \
+    case kTypedData##clazz##Cid: {                                             \
+      obj_ = TypedData::ReadFrom(this, object_id, tags, kind_);                \
+      break;                                                                   \
+    }                                                                          \
+    case kExternalTypedData##clazz##Cid: {                                     \
+      obj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_);        \
+      break;                                                                   \
+    }
+    CLASS_LIST_TYPED_DATA(SNAPSHOT_READ)
+#undef SNAPSHOT_READ
     default: UNREACHABLE(); break;
   }
   if (kind_ == Snapshot::kFull) {
@@ -972,6 +1006,21 @@
 
     CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE)
 #undef SNAPSHOT_WRITE
+#define SNAPSHOT_WRITE(clazz)                                                  \
+    case kTypedData##clazz##Cid: {                                             \
+      RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(raw);            \
+      raw_obj->WriteTo(this, object_id, kind_);                                \
+      return;                                                                  \
+    }                                                                          \
+    case kExternalTypedData##clazz##Cid: {                                     \
+      RawExternalTypedData* raw_obj =                                          \
+        reinterpret_cast<RawExternalTypedData*>(raw);                          \
+      raw_obj->WriteTo(this, object_id, kind_);                                \
+      return;                                                                  \
+    }                                                                          \
+
+    CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE)
+#undef SNAPSHOT_WRITE
     default: break;
   }
   UNREACHABLE();
@@ -1202,6 +1251,21 @@
 
     CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE)
 #undef SNAPSHOT_WRITE
+#define SNAPSHOT_WRITE(clazz)                                                  \
+    case kTypedData##clazz##Cid: {                                             \
+      RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(raw);            \
+      raw_obj->WriteTo(this, object_id, kind_);                                \
+      return;                                                                  \
+    }                                                                          \
+    case kExternalTypedData##clazz##Cid: {                                     \
+      RawExternalTypedData* raw_obj =                                          \
+        reinterpret_cast<RawExternalTypedData*>(raw);                          \
+      raw_obj->WriteTo(this, object_id, kind_);                                \
+      return;                                                                  \
+    }                                                                          \
+
+    CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE)
+#undef SNAPSHOT_WRITE
     default: break;
   }
   UNREACHABLE();
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index be21112..5d199f6 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -34,6 +34,8 @@
 class RawApiError;
 class RawArray;
 class RawBigint;
+class RawBoundedType;
+class RawMixinAppType;
 class RawClass;
 class RawContext;
 class RawDouble;
@@ -255,6 +257,8 @@
   RawUnresolvedClass* NewUnresolvedClass();
   RawType* NewType();
   RawTypeParameter* NewTypeParameter();
+  RawBoundedType* NewBoundedType();
+  RawMixinAppType* NewMixinAppType();
   RawPatchClass* NewPatchClass();
   RawClosureData* NewClosureData();
   RawRedirectionData* NewRedirectionData();
@@ -328,6 +332,8 @@
 
   friend class ApiError;
   friend class Array;
+  friend class BoundedType;
+  friend class MixinAppType;
   friend class Class;
   friend class Context;
   friend class ContextScope;
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index db65502..fce9b23 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -613,10 +613,10 @@
   uint8_t* buffer;
   MessageWriter writer(&buffer, &zone_allocator);
   const int kByteArrayLength = 256;
-  Uint8Array& byte_array =
-      Uint8Array::Handle(Uint8Array::New(kByteArrayLength));
+  TypedData& byte_array = TypedData::Handle(
+      TypedData::New(kTypedDataUint8ArrayCid, kByteArrayLength));
   for (int i = 0; i < kByteArrayLength; i++) {
-    byte_array.SetAt(i, i);
+    byte_array.SetUint8(i, i);
   }
   writer.WriteMessage(byte_array);
   intptr_t buffer_len = writer.BytesWritten();
@@ -624,9 +624,9 @@
   // Read object back from the snapshot.
   SnapshotReader reader(buffer, buffer_len,
                         Snapshot::kMessage, Isolate::Current());
-  ByteArray& serialized_byte_array = ByteArray::Handle();
+  TypedData& serialized_byte_array = TypedData::Handle();
   serialized_byte_array ^= reader.ReadObject();
-  EXPECT(serialized_byte_array.IsByteArray());
+  EXPECT(serialized_byte_array.IsTypedData());
 
   // Read object back from the snapshot into a C structure.
   ApiNativeScope scope;
@@ -719,17 +719,17 @@
   uint8_t* buffer;
   MessageWriter writer(&buffer, &zone_allocator);
   const int kByteArrayLength = 0;
-  Uint8Array& byte_array =
-      Uint8Array::Handle(Uint8Array::New(kByteArrayLength));
+  TypedData& byte_array = TypedData::Handle(
+      TypedData::New(kTypedDataUint8ArrayCid, kByteArrayLength));
   writer.WriteMessage(byte_array);
   intptr_t buffer_len = writer.BytesWritten();
 
   // Read object back from the snapshot.
   SnapshotReader reader(buffer, buffer_len,
                         Snapshot::kMessage, Isolate::Current());
-  ByteArray& serialized_byte_array = ByteArray::Handle();
+  TypedData& serialized_byte_array = TypedData::Handle();
   serialized_byte_array ^= reader.ReadObject();
-  EXPECT(serialized_byte_array.IsByteArray());
+  EXPECT(serialized_byte_array.IsTypedData());
 
   // Read object back from the snapshot into a C structure.
   ApiNativeScope scope;
@@ -1763,7 +1763,7 @@
 UNIT_TEST_CASE(DartGeneratedListMessagesWithBackref) {
   const int kArrayLength = 10;
   static const char* kScriptChars =
-      "import 'dart:scalarlist';\n"
+      "import 'dart:typeddata';\n"
       "final int kArrayLength = 10;\n"
       "getStringList() {\n"
       "  var s = 'Hello, world!';\n"
@@ -1934,7 +1934,7 @@
 UNIT_TEST_CASE(DartGeneratedArrayLiteralMessagesWithBackref) {
   const int kArrayLength = 10;
   static const char* kScriptChars =
-      "import 'dart:scalarlist';\n"
+      "import 'dart:typeddata';\n"
       "final int kArrayLength = 10;\n"
       "getStringList() {\n"
       "  var s = 'Hello, world!';\n"
diff --git a/runtime/vm/snapshot_test.dart b/runtime/vm/snapshot_test.dart
index 9742c38..50ed111 100644
--- a/runtime/vm/snapshot_test.dart
+++ b/runtime/vm/snapshot_test.dart
@@ -1483,10 +1483,10 @@
     for (int i = 0; i < _result.length; i++) {
       List<int> line = _result[i];
       for (int j = 0; j < line.length; j++) {
-        if (line[j] < 10) output.add("0");
-        output.add(line[j]);
+        if (line[j] < 10) output.write("0");
+        output.write(line[j]);
       }
-      output.add("\n");
+      output.write("\n");
     }
     // print(output);
   }
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index f0fdd3e..47a72d2 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -4,7 +4,7 @@
 
 #include "vm/stack_frame.h"
 
-#include "vm/assembler_macros.h"
+#include "vm/assembler.h"
 #include "vm/deopt_instructions.h"
 #include "vm/isolate.h"
 #include "vm/object.h"
@@ -61,8 +61,8 @@
   ASSERT(visitor != NULL);
   NoGCScope no_gc;
   RawObject** start_addr = reinterpret_cast<RawObject**>(sp());
-  RawObject** end_addr = reinterpret_cast<RawObject**>(fp()) +
-      ParsedFunction::kFirstLocalSlotIndex;
+  RawObject** end_addr =
+      reinterpret_cast<RawObject**>(fp()) + kFirstLocalSlotIndex;
   Code code;
   code = LookupDartCode();
   if (!code.IsNull()) {
@@ -143,7 +143,7 @@
       *(reinterpret_cast<uword*>(fp() + EntrypointMarkerOffsetFromFp()));
   if (saved_pc != 0) {
     uword entry_point =
-        (saved_pc - AssemblerMacros::kOffsetOfSavedPCfromEntrypoint);
+        (saved_pc - Assembler::kOffsetOfSavedPCfromEntrypoint);
     RawInstructions* instr = Instructions::FromEntryPoint(entry_point);
     if (instr != Instructions::null()) {
       return instr->ptr()->code_;
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index 32ea56f..6ad9611 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -6,7 +6,6 @@
 #if defined(TARGET_ARCH_ARM)
 
 #include "vm/assembler.h"
-#include "vm/assembler_macros.h"
 #include "vm/code_generator.h"
 #include "vm/dart_entry.h"
 #include "vm/instructions.h"
@@ -29,6 +28,7 @@
   const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
   const intptr_t argv_offset = NativeArguments::argv_offset();
   const intptr_t retval_offset = NativeArguments::retval_offset();
+
   __ EnterFrame((1 << FP) | (1 << LR), 0);
 
   // Load current Isolate pointer from Context structure into R0.
@@ -36,26 +36,10 @@
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to Dart VM C++ code.
-  {
-    // TODO(regis): Add assembler macro for {Load,Store}BasedOffset with no
-    // restriction on the offset.
-    const intptr_t offset = Isolate::top_exit_frame_info_offset();
-    const int32_t offset12_hi = offset & ~kOffset12Mask;  // signed
-    const uint32_t offset12_lo = offset & kOffset12Mask;  // unsigned
-    __ AddImmediate(IP, R0, offset12_hi);
-    __ str(SP, Address(IP, offset12_lo));
-  }
+  __ StoreToOffset(kStoreWord, SP, R0, Isolate::top_exit_frame_info_offset());
 
   // Save current Context pointer into Isolate structure.
-  {
-    // TODO(regis): Add assembler macro for {Load,Store}BasedOffset with no
-    // restriction on the offset.
-    const intptr_t offset = Isolate::top_context_offset();
-    const int32_t offset12_hi = offset & ~kOffset12Mask;  // signed
-    const uint32_t offset12_lo = offset & kOffset12Mask;  // unsigned
-    __ AddImmediate(IP, R0, offset12_hi);
-    __ str(CTX, Address(IP, offset12_lo));
-  }
+  __ StoreToOffset(kStoreWord, CTX, R0, Isolate::top_context_offset());
 
   // Cache Isolate pointer into CTX while executing runtime code.
   __ mov(CTX, ShifterOperand(R0));
@@ -69,7 +53,7 @@
   // Registers R0, R1, R2, and R3 are used.
 
   ASSERT(isolate_offset == 0 * kWordSize);
-  __ mov(R0, ShifterOperand(CTX));  // Set isolate in NativeArgs.
+  // Set isolate in NativeArgs: R0 already contains CTX.
 
   // There are no runtime calls to closures, so we do not need to set the tag
   // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
@@ -88,38 +72,14 @@
 
   // Reset exit frame information in Isolate structure.
   __ LoadImmediate(R2, 0);
-  {
-    // TODO(regis): Add assembler macro for {Load,Store}BasedOffset with no
-    // restriction on the offset.
-    const intptr_t offset = Isolate::top_exit_frame_info_offset();
-    const int32_t offset12_hi = offset & ~kOffset12Mask;  // signed
-    const uint32_t offset12_lo = offset & kOffset12Mask;  // unsigned
-    __ AddImmediate(IP, CTX, offset12_hi);
-    __ str(R2, Address(IP, offset12_lo));
-  }
+  __ StoreToOffset(kStoreWord, R2, CTX, Isolate::top_exit_frame_info_offset());
 
   // Load Context pointer from Isolate structure into R2.
-  {
-    // TODO(regis): Add assembler macro for {Load,Store}BasedOffset with no
-    // restriction on the offset.
-    const intptr_t offset = Isolate::top_context_offset();
-    const int32_t offset12_hi = offset & ~kOffset12Mask;  // signed
-    const uint32_t offset12_lo = offset & kOffset12Mask;  // unsigned
-    __ AddImmediate(IP, CTX, offset12_hi);
-    __ ldr(R2, Address(IP, offset12_lo));
-  }
+  __ LoadFromOffset(kLoadWord, R2, CTX, Isolate::top_context_offset());
 
   // Reset Context pointer in Isolate structure.
   __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null()));
-  {
-    // TODO(regis): Add assembler macro for {Load,Store}BasedOffset with no
-    // restriction on the offset.
-    const intptr_t offset = Isolate::top_context_offset();
-    const int32_t offset12_hi = offset & ~kOffset12Mask;  // signed
-    const uint32_t offset12_lo = offset & kOffset12Mask;  // unsigned
-    __ AddImmediate(IP, CTX, offset12_hi);
-    __ str(R3, Address(IP, offset12_lo));
-  }
+  __ StoreToOffset(kStoreWord, R3, CTX, Isolate::top_context_offset());
 
   // Cache Context pointer into CTX while executing Dart code.
   __ mov(CTX, ShifterOperand(R2));
@@ -129,20 +89,106 @@
 }
 
 
+// Print the stop message.
+DEFINE_LEAF_RUNTIME_ENTRY(void, PrintStopMessage, const char* message) {
+  OS::Print("Stop message: %s\n", message);
+}
+END_LEAF_RUNTIME_ENTRY
+
+
+// Input parameters:
+//   R0 : stop message (const char*).
+// Must preserve all registers.
 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) {
-  __ Unimplemented("PrintStopMessage stub");
+  __ EnterCallRuntimeFrame(0);
+  // Call the runtime leaf function. R0 already contains the parameter.
+  __ CallRuntime(kPrintStopMessageRuntimeEntry);
+  __ LeaveCallRuntimeFrame();
+  __ Ret();
 }
 
 
+// Input parameters:
+//   LR : return address.
+//   SP : address of return value.
+//   R5 : address of the native function to call.
+//   R2 : address of first argument in argument array.
+//   R1 : argc_tag including number of arguments and function kind.
 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
-  __ Unimplemented("CallNativeCFunction stub");
+  const intptr_t isolate_offset = NativeArguments::isolate_offset();
+  const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
+  const intptr_t argv_offset = NativeArguments::argv_offset();
+  const intptr_t retval_offset = NativeArguments::retval_offset();
+
+  __ EnterFrame((1 << FP) | (1 << LR), 0);
+
+  // Load current Isolate pointer from Context structure into R0.
+  __ ldr(R0, FieldAddress(CTX, Context::isolate_offset()));
+
+  // Save exit frame information to enable stack walking as we are about
+  // to transition to native code.
+  __ StoreToOffset(kStoreWord, SP, R0, Isolate::top_exit_frame_info_offset());
+
+  // Save current Context pointer into Isolate structure.
+  __ StoreToOffset(kStoreWord, CTX, R0, Isolate::top_context_offset());
+
+  // Cache Isolate pointer into CTX while executing native code.
+  __ mov(CTX, ShifterOperand(R0));
+
+  // Reserve space for the native arguments structure passed on the stack (the
+  // outgoing pointer parameter to the native arguments structure is passed in
+  // R0) and align frame before entering the C++ world.
+  __ ReserveAlignedFrameSpace(sizeof(NativeArguments));
+
+  // Initialize NativeArguments structure and call native function.
+  // Registers R0, R1, R2, and R3 are used.
+
+  ASSERT(isolate_offset == 0 * kWordSize);
+  // Set isolate in NativeArgs: R0 already contains CTX.
+
+  // There are no native calls to closures, so we do not need to set the tag
+  // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
+  ASSERT(argc_tag_offset == 1 * kWordSize);
+  // Set argc in NativeArguments: R1 already contains argc.
+
+  ASSERT(argv_offset == 2 * kWordSize);
+  // Set argv in NativeArguments: R2 already contains argv.
+
+  ASSERT(retval_offset == 3 * kWordSize);
+  __ add(R3, FP, ShifterOperand(2 * kWordSize));  // Set retval in NativeArgs.
+
+  // TODO(regis): Should we pass the structure by value as in runtime calls?
+  // It would require changing Dart API for native functions.
+  // For now, space is reserved on the stack and we pass a pointer to it.
+  __ stm(IA, SP,  (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3));
+  __ mov(R0, ShifterOperand(SP));  // Pass the pointer to the NativeArguments.
+
+  // Call native function or redirection via simulator.
+  __ blx(R5);
+
+  // Reset exit frame information in Isolate structure.
+  __ LoadImmediate(R2, 0);
+  __ StoreToOffset(kStoreWord, R2, CTX, Isolate::top_exit_frame_info_offset());
+
+  // Load Context pointer from Isolate structure into R2.
+  __ LoadFromOffset(kLoadWord, R2, CTX, Isolate::top_context_offset());
+
+  // Reset Context pointer in Isolate structure.
+  __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null()));
+  __ StoreToOffset(kStoreWord, R3, CTX, Isolate::top_context_offset());
+
+  // Cache Context pointer into CTX while executing Dart code.
+  __ mov(CTX, ShifterOperand(R2));
+
+  __ LeaveFrame((1 << FP) | (1 << LR));
+  __ Ret();
 }
 
 
 // Input parameters:
 //   R4: arguments descriptor array.
 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) {
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   // Setup space on stack for return value and preserve arguments descriptor.
   __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
   __ PushList((1 << R0) | (1 << R4));
@@ -150,7 +196,7 @@
   // Get Code object result and restore arguments descriptor array.
   __ PopList((1 << R0) | (1 << R4));
   // Remove the stub frame as we are about to jump to the dart function.
-  AssemblerMacros::LeaveStubFrame(assembler);
+  __ LeaveStubFrame();
 
   __ ldr(R0, FieldAddress(R0, Code::instructions_offset()));
   __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag);
@@ -202,7 +248,7 @@
 //   R3 : new context containing the current isolate pointer.
 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
   // Save frame pointer coming in.
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
 
   // Save new context and C++ ABI callee-saved registers.
   const intptr_t kNewContextOffset =
@@ -223,30 +269,16 @@
 
   // Save the top exit frame info. Use R5 as a temporary register.
   // StackFrameIterator reads the top exit frame info saved in this frame.
-  {
-    // TODO(regis): Add assembler macro for {Load,Store}BasedOffset with no
-    // restriction on the offset.
-    const intptr_t offset = Isolate::top_exit_frame_info_offset();
-    const int32_t offset12_hi = offset & ~kOffset12Mask;  // signed
-    const uint32_t offset12_lo = offset & kOffset12Mask;  // unsigned
-    __ AddImmediate(R7, R8, offset12_hi);
-    __ ldr(R5, Address(R7, offset12_lo));
-    __ LoadImmediate(R6, 0);
-    __ str(R6, Address(R7, offset12_lo));
-  }
+  __ LoadFromOffset(kLoadWord, R5, R8, Isolate::top_exit_frame_info_offset());
+  __ LoadImmediate(R6, 0);
+  __ StoreToOffset(kStoreWord, R6, R8, Isolate::top_exit_frame_info_offset());
 
   // Save the old Context pointer. Use R4 as a temporary register.
   // Note that VisitObjectPointers will find this saved Context pointer during
   // GC marking, since it traverses any information between SP and
   // FP - kExitLinkOffsetInEntryFrame.
   // EntryFrame::SavedContext reads the context saved in this frame.
-  {
-    const intptr_t offset = Isolate::top_context_offset();
-    const int32_t offset12_hi = offset & ~kOffset12Mask;  // signed
-    const uint32_t offset12_lo = offset & kOffset12Mask;  // unsigned
-    __ AddImmediate(R7, R8, offset12_hi);
-    __ ldr(R4, Address(R7, offset12_lo));
-  }
+  __ LoadFromOffset(kLoadWord, R4, R8, Isolate::top_context_offset());
 
   // The constants kSavedContextOffsetInEntryFrame and
   // kExitLinkOffsetInEntryFrame must be kept in sync with the code below.
@@ -299,27 +331,14 @@
   // Restore the saved top exit frame info back into the Isolate structure.
   // Uses R5 as a temporary register for this.
   __ PopList((1 << R4) | (1 << R5));
-  {
-    const intptr_t offset = Isolate::top_context_offset();
-    const int32_t offset12_hi = offset & ~kOffset12Mask;  // signed
-    const uint32_t offset12_lo = offset & kOffset12Mask;  // unsigned
-    __ AddImmediate(R7, CTX, offset12_hi);
-    __ str(R4, Address(R7, offset12_lo));
-  }
-  {
-    const intptr_t offset = Isolate::top_exit_frame_info_offset();
-    const int32_t offset12_hi = offset & ~kOffset12Mask;  // signed
-    const uint32_t offset12_lo = offset & kOffset12Mask;  // unsigned
-    __ AddImmediate(R7, CTX, offset12_hi);
-    __ str(R5, Address(R7, offset12_lo));
-  }
+  __ StoreToOffset(kStoreWord, R4, CTX, Isolate::top_context_offset());
+  __ StoreToOffset(kStoreWord, R5, CTX, Isolate::top_exit_frame_info_offset());
 
   // Restore C++ ABI callee-saved registers.
   __ PopList((1 << R3) | kAbiPreservedCpuRegs);  // Ignore restored R3.
 
-  // Restore the frame pointer.
-  AssemblerMacros::LeaveStubFrame(assembler);
-
+  // Restore the frame pointer and return.
+  __ LeaveStubFrame();
   __ Ret();
 }
 
diff --git a/runtime/vm/stub_code_arm_test.cc b/runtime/vm/stub_code_arm_test.cc
index 67a15c9..0a11a98 100644
--- a/runtime/vm/stub_code_arm_test.cc
+++ b/runtime/vm/stub_code_arm_test.cc
@@ -39,7 +39,23 @@
 // Test calls to stub code which calls into the runtime.
 static void GenerateCallToCallRuntimeStub(Assembler* assembler,
                                           int value1, int value2) {
-  UNIMPLEMENTED();
+  const int argc = 2;
+  const Smi& smi1 = Smi::ZoneHandle(Smi::New(value1));
+  const Smi& smi2 = Smi::ZoneHandle(Smi::New(value2));
+  const Object& result = Object::ZoneHandle();
+  const Context& context = Context::ZoneHandle(Context::New(0, Heap::kOld));
+  ASSERT(context.isolate() == Isolate::Current());
+  __ EnterDartFrame(0);
+  __ LoadObject(CTX, context);
+  __ PushObject(result);  // Push Null object for return value.
+  __ PushObject(smi1);  // Push argument 1 smi1.
+  __ PushObject(smi2);  // Push argument 2 smi2.
+  ASSERT(kTestSmiSubRuntimeEntry.argument_count() == argc);
+  __ CallRuntime(kTestSmiSubRuntimeEntry);  // Call SmiSub runtime func.
+  __ AddImmediate(SP, argc * kWordSize);
+  __ Pop(R0);  // Pop return value from return slot.
+  __ LeaveDartFrame();
+  __ Ret();
 }
 
 
@@ -64,7 +80,15 @@
 static void GenerateCallToCallLeafRuntimeStub(Assembler* assembler,
                                               int value1,
                                               int value2) {
-  UNIMPLEMENTED();
+  const Smi& smi1 = Smi::ZoneHandle(Smi::New(value1));
+  const Smi& smi2 = Smi::ZoneHandle(Smi::New(value2));
+  __ EnterDartFrame(0);
+  __ ReserveAlignedFrameSpace(0);
+  __ LoadObject(R0, smi1);  // Set up argument 1 smi1.
+  __ LoadObject(R1, smi2);  // Set up argument 2 smi2.
+  __ CallRuntime(kTestLeafSmiAddRuntimeEntry);  // Call SmiAdd runtime func.
+  __ LeaveDartFrame();
+  __ Ret();  // Return value is in R0.
 }
 
 
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index f844588..ddd7963 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -6,7 +6,6 @@
 #if defined(TARGET_ARCH_IA32)
 
 #include "vm/assembler.h"
-#include "vm/assembler_macros.h"
 #include "vm/compiler.h"
 #include "vm/dart_entry.h"
 #include "vm/flow_graph_compiler.h"
@@ -188,7 +187,7 @@
 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) {
   const Immediate& raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   __ pushl(EDX);  // Preserve arguments descriptor array.
   __ pushl(raw_null);  // Setup space on stack for return value.
   __ CallRuntime(kPatchStaticCallRuntimeEntry);
@@ -211,7 +210,7 @@
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   __ pushl(EDX);  // Preserve arguments descriptor array.
   __ pushl(raw_null);  // Setup space on stack for return value.
   __ CallRuntime(kFixCallersTargetRuntimeEntry);
@@ -262,7 +261,7 @@
 //       when trying to resolve the call.
 // Uses EDI.
 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) {
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
 
   const Immediate& raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
@@ -392,7 +391,7 @@
   // Frame is fully rewritten at this point and it is safe to perform a GC.
   // Materialize any objects that were deferred by FillFrame because they
   // require allocation.
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   if (preserve_eax) {
     __ pushl(EBX);  // Preserve result, it will be GC-d here.
   }
@@ -423,7 +422,7 @@
 
 
 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) {
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   // Load the receiver into EAX.  The argument count in the arguments
   // descriptor in EDX is a smi.
   __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
@@ -587,7 +586,7 @@
   __ Bind(&slow_case);
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   __ pushl(raw_null);  // Setup space on stack for return value.
   __ pushl(EDX);  // Array length as Smi.
   __ pushl(ECX);  // Element type.
@@ -644,7 +643,7 @@
 
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
 
   __ pushl(EDX);  // Preserve arguments descriptor array.
   __ pushl(ECX);  // Preserve read-only function object argument.
@@ -676,7 +675,7 @@
 
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
 
   __ pushl(raw_null);  // Setup space on stack for result from error reporting.
   __ pushl(EDX);  // Arguments descriptor.
@@ -938,7 +937,7 @@
   }
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   __ pushl(raw_null);  // Setup space on stack for return value.
   __ SmiTag(EDX);
   __ pushl(EDX);
@@ -1162,7 +1161,7 @@
   }
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   __ pushl(raw_null);  // Setup space on stack for return value.
   __ PushObject(cls);  // Push class of object to be allocated.
   if (is_cls_parameterized) {
@@ -1302,7 +1301,7 @@
   }
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   __ pushl(raw_null);  // Setup space on stack for return value.
   __ PushObject(func);
   if (is_implicit_static_closure) {
@@ -1356,7 +1355,7 @@
 
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
 
   __ pushl(raw_null);  // Setup space on stack for result from noSuchMethod.
   __ pushl(EAX);  // Receiver.
@@ -1400,7 +1399,7 @@
   Register ic_reg = ECX;
   Register func_reg = EDI;
   if (FLAG_trace_optimized_ic_calls) {
-    AssemblerMacros::EnterStubFrame(assembler);
+    __ EnterStubFrame();
     __ pushl(func_reg);     // Preserve
     __ pushl(argdesc_reg);  // Preserve.
     __ pushl(ic_reg);       // Preserve.
@@ -1541,7 +1540,7 @@
   __ leal(EAX, Address(ESP, EAX, TIMES_2, 0));  // EAX is Smi.
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   __ pushl(EDX);  // Preserve arguments descriptor array.
   __ pushl(ECX);  // Preserve IC data object.
   __ pushl(raw_null);  // Setup space on stack for result (target code object).
@@ -1693,7 +1692,7 @@
 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) {
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   __ pushl(EDX);  // Preserve arguments descriptor.
   const Immediate& raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
@@ -1715,7 +1714,7 @@
 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) {
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   __ pushl(EAX);
   __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry);
   __ popl(EAX);
@@ -1736,7 +1735,7 @@
 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   __ pushl(ECX);
   __ pushl(EDX);
   __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry);
@@ -2005,7 +2004,7 @@
   // ECX: ICData
   __ movl(EAX, Address(ESP, 1 * kWordSize));
   __ movl(EDI, Address(ESP, 2 * kWordSize));
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   __ pushl(EDI);  // arg 0
   __ pushl(EAX);  // arg 1
   __ PushObject(Symbols::EqualOperator());  // Target's name.
@@ -2024,7 +2023,7 @@
 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
   const Immediate& raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   __ pushl(EDX);
   __ pushl(raw_null);  // Setup space on stack for return value.
   __ pushl(EDI);
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 703a058..5164808 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -6,7 +6,6 @@
 #if defined(TARGET_ARCH_X64)
 
 #include "vm/assembler.h"
-#include "vm/assembler_macros.h"
 #include "vm/compiler.h"
 #include "vm/dart_entry.h"
 #include "vm/flow_graph_compiler.h"
@@ -187,7 +186,7 @@
 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) {
   const Immediate& raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   __ pushq(R10);  // Preserve arguments descriptor array.
   __ pushq(raw_null);  // Setup space on stack for return value.
   __ CallRuntime(kPatchStaticCallRuntimeEntry);
@@ -208,7 +207,7 @@
 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) {
   const Immediate& raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   __ pushq(R10);  // Preserve arguments descriptor array.
   __ pushq(raw_null);  // Setup space on stack for return value.
   __ CallRuntime(kFixCallersTargetRuntimeEntry);
@@ -257,7 +256,7 @@
 //       called, the stub accesses the receiver from this location directly
 //       when trying to resolve the call.
 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) {
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
 
   const Immediate& raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
@@ -387,7 +386,7 @@
   // Frame is fully rewritten at this point and it is safe to perform a GC.
   // Materialize any objects that were deferred by FillFrame because they
   // require allocation.
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   if (preserve_rax) {
     __ pushq(RBX);  // Preserve result, it will be GC-d here.
   }
@@ -419,7 +418,7 @@
 
 
 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) {
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   // Load the receiver into RAX.  The argument count in the arguments
   // descriptor in R10 is a smi.
   __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
@@ -577,7 +576,7 @@
   __ Bind(&slow_case);
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   __ pushq(raw_null);  // Setup space on stack for return value.
   __ pushq(R10);  // Array length as Smi.
   __ pushq(RBX);  // Element type.
@@ -633,7 +632,7 @@
 
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
 
   __ pushq(R10);  // Preserve arguments descriptor array.
   __ pushq(RBX);  // Preserve read-only function object argument.
@@ -665,7 +664,7 @@
 
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
 
   __ pushq(raw_null);  // Setup space on stack for result from call.
   __ pushq(R10);  // Arguments descriptor.
@@ -928,7 +927,7 @@
     __ Bind(&slow_case);
   }
   // Create a stub frame.
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   __ pushq(raw_null);  // Setup space on stack for the return value.
   __ SmiTag(R10);
   __ pushq(R10);  // Push number of context variables.
@@ -1147,7 +1146,7 @@
     __ movq(RDX, Address(RSP, kInstantiatorTypeArgumentsOffset));
   }
   // Create a stub frame.
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   __ pushq(raw_null);  // Setup space on stack for return value.
   __ PushObject(cls);  // Push class of object to be allocated.
   if (is_cls_parameterized) {
@@ -1289,7 +1288,7 @@
     __ movq(RAX, Address(RSP, kReceiverOffset));
   }
   // Create the stub frame.
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   __ pushq(raw_null);  // Setup space on stack for the return value.
   __ PushObject(func);
   if (is_implicit_static_closure) {
@@ -1341,7 +1340,7 @@
   __ movq(RAX, Address(RBP, R13, TIMES_4, kWordSize));  // Get receiver.
 
   // Create a stub frame.
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
 
   __ pushq(raw_null);  // Setup space on stack for result from noSuchMethod.
   __ pushq(RAX);  // Receiver.
@@ -1385,7 +1384,7 @@
   Register ic_reg = RBX;
   Register func_reg = RDI;
   if (FLAG_trace_optimized_ic_calls) {
-    AssemblerMacros::EnterStubFrame(assembler);
+    __ EnterStubFrame();
     __ pushq(func_reg);     // Preserve
     __ pushq(argdesc_reg);  // Preserve.
     __ pushq(ic_reg);       // Preserve.
@@ -1522,7 +1521,7 @@
   // arguments descriptor array and then compute address on the stack).
   __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
   __ leaq(RAX, Address(RSP, RAX, TIMES_4, 0));  // RAX is Smi.
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   __ pushq(R10);  // Preserve arguments descriptor array.
   __ pushq(RBX);  // Preserve IC data object.
   __ pushq(raw_null);  // Setup space on stack for result (target code object).
@@ -1670,7 +1669,7 @@
 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) {
   const Immediate& raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   __ pushq(R10);  // Preserve arguments descriptor.
   __ pushq(raw_null);  // Room for result.
   __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry);
@@ -1688,7 +1687,7 @@
 
 //  TOS(0): return address (Dart code).
 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) {
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   __ pushq(RAX);
   __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry);
   __ popq(RAX);
@@ -1704,7 +1703,7 @@
 //  R10: Arguments descriptor array.
 //  TOS(0): return address (Dart code).
 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   __ pushq(RBX);
   __ pushq(R10);
   __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry);
@@ -1970,7 +1969,7 @@
   // RCX: ICData
   __ movq(RAX, Address(RSP, 1 * kWordSize));
   __ movq(R13, Address(RSP, 2 * kWordSize));
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   __ pushq(R13);  // arg 0
   __ pushq(RAX);  // arg 1
   __ PushObject(Symbols::EqualOperator());  // Target's name.
@@ -1988,7 +1987,7 @@
 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
   const Immediate& raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
-  AssemblerMacros::EnterStubFrame(assembler);
+  __ EnterStubFrame();
   __ pushq(R10);
   __ pushq(raw_null);  // Setup space on stack for return value.
   __ pushq(RDI);
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index afac4a3..3a05318 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -110,9 +110,9 @@
   V(_Double, "_Double")                                                        \
   V(Bool, "bool")                                                              \
   V(ObjectArray, "_ObjectArray")                                               \
-  V(ObjectArrayDot, "_ObjectArray.")                                           \
+  V(ObjectArrayFactory, "_ObjectArray.")                                       \
   V(GrowableObjectArray, "_GrowableObjectArray")                               \
-  V(GrowableObjectArrayDot, "_GrowableObjectArray.")                           \
+  V(GrowableObjectArrayFactory, "_GrowableObjectArray.")                       \
   V(GrowableObjectArrayWithData, "_GrowableObjectArray.withData")              \
   V(ImmutableArray, "_ImmutableArray")                                         \
   V(OneByteString, "_OneByteString")                                           \
@@ -129,17 +129,28 @@
   V(Float32x4, "Float32x4")                                                    \
   V(Uint32x4, "Uint32x4")                                                      \
   V(Int8List, "Int8List")                                                      \
+  V(Int8ListFactory, "Int8List.")                                              \
   V(Uint8List, "Uint8List")                                                    \
+  V(Uint8ListFactory, "Uint8List.")                                            \
   V(Uint8ClampedList, "Uint8ClampedList")                                      \
+  V(Uint8ClampedListFactory, "Uint8ClampedList.")                              \
   V(Int16List, "Int16List")                                                    \
+  V(Int16ListFactory, "Int16List.")                                            \
   V(Uint16List, "Uint16List")                                                  \
+  V(Uint16ListFactory, "Uint16List.")                                          \
   V(Int32List, "Int32List")                                                    \
+  V(Int32ListFactory, "Int32List.")                                            \
   V(Uint32List, "Uint32List")                                                  \
+  V(Uint32ListFactory, "Uint32List.")                                          \
   V(Int64List, "Int64List")                                                    \
+  V(Int64ListFactory, "Int64List.")                                            \
   V(Uint64List, "Uint64List")                                                  \
+  V(Uint64ListFactory, "Uint64List.")                                          \
   V(Float32x4List, "Float32x4List")                                            \
   V(Float32List, "Float32List")                                                \
+  V(Float32ListFactory, "Float32List.")                                        \
   V(Float64List, "Float64List")                                                \
+  V(Float64ListFactory, "Float64List.")                                        \
   V(_Int8Array, "_Int8Array")                                                  \
   V(_Uint8Array, "_Uint8Array")                                                \
   V(_Uint8ClampedArray, "_Uint8ClampedArray")                                  \
@@ -211,6 +222,7 @@
   V(DartIsolate, "dart:isolate")                                               \
   V(DartMirrors, "dart:mirrors")                                               \
   V(DartScalarlist, "dart:scalarlist")                                         \
+  V(DartTypedData, "dart:typeddata")                                           \
   V(DartNativeWrappers, "dart:nativewrappers")                                 \
   V(DartAsync, "dart:async")                                                   \
   V(DartUri, "dart:uri")                                                       \
@@ -298,6 +310,9 @@
   static const String& Ampersand() {
     return *(symbol_handles_[kNullCharId + '&']);
   }
+  static const String& Backtick() {
+    return *(symbol_handles_[kNullCharId + '`']);
+  }
 
   // Access methods for symbol handles stored in the vm isolate.
 #define DEFINE_SYMBOL_HANDLE_ACCESSOR(symbol, literal)                         \
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h
index 308b8ba..31c307f 100644
--- a/runtime/vm/unit_test.h
+++ b/runtime/vm/unit_test.h
@@ -146,29 +146,28 @@
 // Not running on ARM or MIPS hardware, call simulator to execute code.
 #define EXECUTE_TEST_CODE_INT32(name, entry)                                   \
   static_cast<int32_t>(Simulator::Current()->Call((int32_t)entry,              \
-      0, 0, 0, 0, 0))
+      0, 0, 0, 0))
 #define EXECUTE_TEST_CODE_INT64_LL(name, entry, long_arg0, long_arg1)          \
   static_cast<int64_t>(Simulator::Current()->Call((int32_t)entry,              \
       Utils::Low32Bits(long_arg0),                                             \
       Utils::High32Bits(long_arg0),                                            \
       Utils::Low32Bits(long_arg1),                                             \
-      Utils::High32Bits(long_arg1),                                            \
-      0))
+      Utils::High32Bits(long_arg1)))
 #define EXECUTE_TEST_CODE_FLOAT(name, entry)                                   \
   bit_cast<float, int32_t>(Simulator::Current()->Call((int32_t)entry,          \
-      0, 0, 0, 0, 0))
+      0, 0, 0, 0))
 #define EXECUTE_TEST_CODE_DOUBLE(name, entry)                                  \
   bit_cast<double, int64_t>(Simulator::Current()->Call((int32_t)entry,         \
-      0, 0, 0, 0, 0))
+      0, 0, 0, 0))
 #define EXECUTE_TEST_CODE_INT32_F(name, entry, float_arg)                      \
   static_cast<int32_t>(Simulator::Current()->Call((int32_t)entry,              \
       bit_cast<int32_t, float>(float_arg),                                     \
-      0, 0, 0, 0))
+      0, 0, 0))
 #define EXECUTE_TEST_CODE_INT32_D(name, entry, double_arg)                     \
   static_cast<int32_t>(Simulator::Current()->Call((int32_t)entry,              \
       Utils::Low32Bits(bit_cast<int64_t, double>(double_arg)),                 \
       Utils::High32Bits(bit_cast<int64_t, double>(double_arg)),                \
-      0, 0, 0))
+      0, 0))
 #endif  // defined(HOST_ARCH_ARM) || defined(HOST_ARCH_MIPS)
 #endif  // defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
 
diff --git a/runtime/vm/vm.gypi b/runtime/vm/vm.gypi
index 1c1b10f..a1edd38 100644
--- a/runtime/vm/vm.gypi
+++ b/runtime/vm/vm.gypi
@@ -22,6 +22,8 @@
     'json_patch_cc_file': '<(SHARED_INTERMEDIATE_DIR)/json_patch_gen.cc',
     'scalarlist_cc_file': '<(SHARED_INTERMEDIATE_DIR)/scalarlist_gen.cc',
     'scalarlist_patch_cc_file': '<(SHARED_INTERMEDIATE_DIR)/scalarlist_patch_gen.cc',
+    'typeddata_cc_file': '<(SHARED_INTERMEDIATE_DIR)/typeddata_gen.cc',
+    'typeddata_patch_cc_file': '<(SHARED_INTERMEDIATE_DIR)/typeddata_patch_gen.cc',
     'uri_cc_file': '<(SHARED_INTERMEDIATE_DIR)/uri_gen.cc',
     'utf_cc_file': '<(SHARED_INTERMEDIATE_DIR)/utf_gen.cc',
     'snapshot_test_dat_file': '<(SHARED_INTERMEDIATE_DIR)/snapshot_test.dat',
@@ -107,6 +109,8 @@
         'generate_mirrors_patch_cc_file',
         'generate_scalarlist_cc_file',
         'generate_scalarlist_patch_cc_file',
+        'generate_typeddata_cc_file',
+        'generate_typeddata_patch_cc_file',
         'generate_uri_cc_file',
         'generate_utf_cc_file',
       ],
@@ -117,6 +121,7 @@
         '../lib/math_sources.gypi',
         '../lib/mirrors_sources.gypi',
         '../lib/scalarlist_sources.gypi',
+        '../lib/typeddata_sources.gypi',
       ],
       'sources': [
         'bootstrap.cc',
@@ -138,6 +143,8 @@
         '<(mirrors_patch_cc_file)',
         '<(scalarlist_cc_file)',
         '<(scalarlist_patch_cc_file)',
+        '<(typeddata_cc_file)',
+        '<(typeddata_patch_cc_file)',
         '<(uri_cc_file)',
         '<(utf_cc_file)',
       ],
@@ -155,6 +162,7 @@
         '../lib/math_sources.gypi',
         '../lib/mirrors_sources.gypi',
         '../lib/scalarlist_sources.gypi',
+        '../lib/typeddata_sources.gypi',
       ],
       'sources': [
         'bootstrap_nocorelib.cc',
@@ -984,6 +992,101 @@
       ]
     },
     {
+      'target_name': 'generate_typeddata_cc_file',
+      'type': 'none',
+      'variables': {
+        'typeddata_dart': '<(SHARED_INTERMEDIATE_DIR)/typeddata_gen.dart',
+      },
+      'includes': [
+        # Load the shared library sources.
+        '../../sdk/lib/typeddata/typeddata_sources.gypi',
+      ],
+      'sources/': [
+        # Exclude all .[cc|h] files.
+        # This is only here for reference. Excludes happen after
+        # variable expansion, so the script has to do its own
+        # exclude processing of the sources being passed.
+        ['exclude', '\\.cc|h$'],
+      ],
+      'actions': [
+        {
+          'action_name': 'generate_typeddata_dart',
+          'inputs': [
+            '../tools/concat_library.py',
+            '<@(_sources)',
+          ],
+          'outputs': [
+            '<(typeddata_dart)',
+          ],
+          'action': [
+            'python',
+            '<@(_inputs)',
+            '--output', '<(typeddata_dart)',
+          ],
+          'message': 'Generating ''<(typeddata_dart)'' file.',
+        },
+        {
+          'action_name': 'generate_typeddata_cc',
+          'inputs': [
+            '../tools/create_string_literal.py',
+            '<(builtin_in_cc_file)',
+            '<(typeddata_dart)',
+          ],
+          'outputs': [
+            '<(typeddata_cc_file)',
+          ],
+          'action': [
+            'python',
+            'tools/create_string_literal.py',
+            '--output', '<(typeddata_cc_file)',
+            '--input_cc', '<(builtin_in_cc_file)',
+            '--include', 'vm/bootstrap.h',
+            '--var_name', 'dart::Bootstrap::typeddata_source_',
+            '<(typeddata_dart)',
+          ],
+          'message': 'Generating ''<(typeddata_cc_file)'' file.'
+        },
+      ]
+    },
+    {
+      'target_name': 'generate_typeddata_patch_cc_file',
+      'type': 'none',
+      'includes': [
+        # Load the runtime implementation sources.
+        '../lib/typeddata_sources.gypi',
+      ],
+      'sources/': [
+        # Exclude all .[cc|h] files.
+        # This is only here for reference. Excludes happen after
+        # variable expansion, so the script has to do its own
+        # exclude processing of the sources being passed.
+        ['exclude', '\\.cc|h$'],
+      ],
+      'actions': [
+        {
+          'action_name': 'generate_typeddata_patch_cc',
+          'inputs': [
+            '../tools/create_string_literal.py',
+            '<(builtin_in_cc_file)',
+            '<@(_sources)',
+          ],
+          'outputs': [
+            '<(typeddata_patch_cc_file)',
+          ],
+          'action': [
+            'python',
+            'tools/create_string_literal.py',
+            '--output', '<(typeddata_patch_cc_file)',
+            '--input_cc', '<(builtin_in_cc_file)',
+            '--include', 'vm/bootstrap.h',
+            '--var_name', 'dart::Bootstrap::typeddata_patch_',
+            '<@(_sources)',
+          ],
+          'message': 'Generating ''<(typeddata_patch_cc_file)'' file.'
+        },
+      ]
+    },
+    {
       'target_name': 'generate_uri_cc_file',
       'type': 'none',
       'variables': {
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index 2f70b1a..9df78d4 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -18,15 +18,6 @@
     'assembler_ia32.cc',
     'assembler_ia32.h',
     'assembler_ia32_test.cc',
-    'assembler_macros.h',
-    'assembler_macros_arm.cc',
-    'assembler_macros_arm.h',
-    'assembler_macros_ia32.cc',
-    'assembler_macros_ia32.h',
-    'assembler_macros_mips.cc',
-    'assembler_macros_mips.h',
-    'assembler_macros_x64.cc',
-    'assembler_macros_x64.h',
     'assembler_mips.cc',
     'assembler_mips.h',
     'assembler_mips_test.cc',
diff --git a/sdk/bin/analyzer b/sdk/bin/analyzer
new file mode 100755
index 0000000..0281b61
--- /dev/null
+++ b/sdk/bin/analyzer
@@ -0,0 +1,41 @@
+#!/bin/bash
+# Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# This file is used to execute the analyzer by running the jar file.
+# It is a simple wrapper enabling us to have simpler command lines in
+# the testing infrastructure.
+set -e
+
+function follow_links() {
+  while [ -h "$1" ]; do
+    # On Mac OS, readlink -f doesn't work.
+    1="$(readlink "$1")"
+  done
+  echo "$1"
+}
+
+# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
+PROG_NAME="$(follow_links "$BASH_SOURCE")"
+
+# Handle the case where the binary dir has been symlinked to.
+CUR_DIR="$(follow_links "$(cd "${PROG_NAME%/*}" ; pwd -P)")"
+
+SDK_DIR="$(cd "${CUR_DIR}/.." ; pwd -P)"
+
+if [ -z "$DART_CONFIGURATION" ];
+then
+  DART_CONFIGURATION="ReleaseIA32"
+fi
+
+if [[ `uname` == 'Darwin' ]]; 
+then
+  JAR_DIR="$CUR_DIR"/../../xcodebuild/$DART_CONFIGURATION/new_analyzer
+else
+  JAR_DIR="$CUR_DIR"/../../out/$DART_CONFIGURATION/new_analyzer
+fi 
+
+JAR_FILE="$JAR_DIR/new_analyzer.jar"
+
+exec java -jar $JAR_FILE --dart-sdk "$SDK_DIR" "$@"
diff --git a/sdk/bin/analyzer.bat b/sdk/bin/analyzer.bat
new file mode 100644
index 0000000..21daf3e
--- /dev/null
+++ b/sdk/bin/analyzer.bat
@@ -0,0 +1,27 @@
+@echo off
+rem Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+rem for details. All rights reserved. Use of this source code is governed by a
+rem BSD-style license that can be found in the LICENSE file.
+rem 
+
+rem This file is used to execute the analyzer by running the jar file.
+rem It is a simple wrapper enabling us to have simpler command lines in
+rem the testing infrastructure.
+
+set SCRIPTPATH=%~dp0
+
+rem Does the path have a trailing slash? If so, remove it.
+if %SCRIPTPATH:~-1%==\ set SCRIPTPATH=%SCRIPTPATH:~0,-1%
+
+rem DART_CONFIGURATION defaults to ReleaseIA32
+if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseIA32
+
+set arguments=%*
+
+set "SDK_DIR=%SCRIPTPATH%\..\..\build\%DART_CONFIGURATION%\dart-sdk"
+
+set "JAR_DIR=%SCRIPTPATH%\..\..\build\%DART_CONFIGURATION%\new_analyzer"
+
+set "JAR_FILE=%JAR_DIR%\new_analyzer.jar"
+
+java -jar %JAR_FILE% --dart-sdk %SDK_DIR% %arguments%
diff --git a/sdk/bin/dart2js b/sdk/bin/dart2js
index 80dabd6..825712d 100755
--- a/sdk/bin/dart2js
+++ b/sdk/bin/dart2js
@@ -51,11 +51,6 @@
 # TODO(ahe): Remove this option (http://dartbug.com/6495).
 EXTRA_VM_OPTIONS[${#EXTRA_VM_OPTIONS[@]}]='--heap_growth_rate=512'
 
-# Tell the VM to don't bother inlining methods. So far inlining isn't
-# paying off but the VM team is working on fixing that.
-# TODO(ahe): Remove this option (http://dartbug.com/6495).
-EXTRA_VM_OPTIONS[${#EXTRA_VM_OPTIONS[@]}]='--no_use_inlining'
-
 case $0 in
   *_developer)
     EXTRA_VM_OPTIONS[${#EXTRA_VM_OPTIONS[@]}]='--checked'
diff --git a/sdk/bin/dart2js.bat b/sdk/bin/dart2js.bat
index 87584ff..a5c67f6 100644
--- a/sdk/bin/dart2js.bat
+++ b/sdk/bin/dart2js.bat
@@ -12,4 +12,4 @@
 set SNAPSHOTNAME="%SCRIPTPATH%dart2js.snapshot"
 if exist %SNAPSHOTNAME% set SNAPSHOT=--use-script-snapshot=%SNAPSHOTNAME%
 
-"%SCRIPTPATH%dart" --no_use_inlining --heap_growth_rate=512 %SNAPSHOT% "%SCRIPTPATH%..\lib\_internal\compiler\implementation\dart2js.dart" %arguments%
+"%SCRIPTPATH%dart" --heap_growth_rate=512 %SNAPSHOT% "%SCRIPTPATH%..\lib\_internal\compiler\implementation\dart2js.dart" %arguments%
diff --git a/sdk/bin/dart2js_developer.bat b/sdk/bin/dart2js_developer.bat
index 1156d9e..fa07652 100644
--- a/sdk/bin/dart2js_developer.bat
+++ b/sdk/bin/dart2js_developer.bat
@@ -12,4 +12,4 @@
 set SNAPSHOTNAME=%SCRIPTPATH%dart2js.snapshot
 if exist %SNAPSHOTNAME% set SNAPSHOT=--use_script_snapshot=%SNAPSHOTNAME%
 
-"%SCRIPTPATH%dart" --checked --no_use_inlining --heap_growth_rate=512 %SNAPSHOT% "%SCRIPTPATH%..\lib\_internal\compiler\implementation\dart2js.dart" %arguments%
+"%SCRIPTPATH%dart" --checked --heap_growth_rate=512 %SNAPSHOT% "%SCRIPTPATH%..\lib\_internal\compiler\implementation\dart2js.dart" %arguments%
diff --git a/sdk/bin/dartdoc b/sdk/bin/dartdoc
index 74b7a8a..ed265f7 100755
--- a/sdk/bin/dartdoc
+++ b/sdk/bin/dartdoc
@@ -23,4 +23,4 @@
   echo Using snapshot "$BIN_DIR/../lib/_internal/dartdoc/bin/dartdoc.dart.snapshot" 1>&2
   SNAPSHOT="--use-script-snapshot=$BIN_DIR/../lib/_internal/dartdoc/bin/dartdoc.dart.snapshot"
 fi
-exec "$BIN_DIR"/dart --no_use_inlining --heap_growth_rate=32 $SNAPSHOT "$BIN_DIR/../lib/_internal/dartdoc/bin/dartdoc.dart" $COLORS "$@"
+exec "$BIN_DIR"/dart --heap_growth_rate=32 $SNAPSHOT "$BIN_DIR/../lib/_internal/dartdoc/bin/dartdoc.dart" $COLORS "$@"
diff --git a/sdk/bin/dartdoc.bat b/sdk/bin/dartdoc.bat
index 5923d19..98622eb 100644
--- a/sdk/bin/dartdoc.bat
+++ b/sdk/bin/dartdoc.bat
@@ -12,4 +12,4 @@
 rem set SNAPSHOTNAME="%SCRIPTPATH%dartdoc.snapshot"
 rem if exist %SNAPSHOTNAME% set SNAPSHOT=--use-script-snapshot=%SNAPSHOTNAME%
 
-"%SCRIPTPATH%dart" --no_use_inlining --heap_growth_rate=32 %SNAPSHOT% "%SCRIPTPATH%..\lib\_internal\dartdoc\bin\dartdoc.dart" %arguments%
+"%SCRIPTPATH%dart" --heap_growth_rate=32 %SNAPSHOT% "%SCRIPTPATH%..\lib\_internal\dartdoc\bin\dartdoc.dart" %arguments%
diff --git a/sdk/lib/_collection_dev/arrays.dart b/sdk/lib/_collection_dev/arrays.dart
index f3a7caf..662fa49 100644
--- a/sdk/lib/_collection_dev/arrays.dart
+++ b/sdk/lib/_collection_dev/arrays.dart
@@ -8,9 +8,6 @@
 class Arrays {
   static void copy(List src, int srcStart,
                    List dst, int dstStart, int count) {
-    if (srcStart == null) srcStart = 0;
-    if (dstStart == null) dstStart = 0;
-
     if (srcStart < dstStart) {
       for (int i = srcStart + count - 1, j = dstStart + count - 1;
            i >= srcStart; i--, j--) {
@@ -78,6 +75,15 @@
     return -1;
   }
 
+  static void indicesCheck(List a, int start, int end) {
+    if (start < 0 || start > a.length) {
+      throw new RangeError.range(start, 0, a.length);
+    }
+    if (end != null && (end < start || end > a.length)) {
+      throw new RangeError.range(end, start, a.length);
+    }
+  }
+
   static void rangeCheck(List a, int start, int length) {
     if (length < 0) {
       throw new ArgumentError("negative length $length");
diff --git a/sdk/lib/_collection_dev/iterable.dart b/sdk/lib/_collection_dev/iterable.dart
index daad6af..25515a9 100644
--- a/sdk/lib/_collection_dev/iterable.dart
+++ b/sdk/lib/_collection_dev/iterable.dart
@@ -79,7 +79,7 @@
     return false;
   }
 
-  E firstMatching(bool test(E element), { E orElse() }) {
+  E firstWhere(bool test(E element), { E orElse() }) {
     int length = this.length;
     for (int i = 0; i < length; i++) {
       E element = elementAt(i);
@@ -92,7 +92,7 @@
     throw new StateError("No matching element");
   }
 
-  E lastMatching(bool test(E element), { E orElse() }) {
+  E lastWhere(bool test(E element), { E orElse() }) {
     int length = this.length;
     for (int i = length - 1; i >= 0; i--) {
       E element = elementAt(i);
@@ -105,7 +105,7 @@
     throw new StateError("No matching element");
   }
 
-  E singleMatching(bool test(E element)) {
+  E singleWhere(bool test(E element)) {
     int length = this.length;
     E match = null;
     bool matchFound = false;
@@ -176,8 +176,8 @@
       }
       StringBuffer buffer = new StringBuffer(first);
       for (int i = 1; i < length; i++) {
-        buffer.add(separator);
-        buffer.add("${elementAt(i)}");
+        buffer.write(separator);
+        buffer.write("${elementAt(i)}");
         if (length != this.length) {
           throw new ConcurrentModificationError(this);
         }
@@ -186,7 +186,7 @@
     } else {
       StringBuffer buffer = new StringBuffer();
       for (int i = 0; i < length; i++) {
-        buffer.add("${elementAt(i)}");
+        buffer.write("${elementAt(i)}");
         if (length != this.length) {
           throw new ConcurrentModificationError(this);
         }
@@ -644,17 +644,17 @@
 
   bool any(bool test(E element)) => false;
 
-  E firstMatching(bool test(E element), { E orElse() }) {
+  E firstWhere(bool test(E element), { E orElse() }) {
     if (orElse != null) return orElse();
     throw new StateError("No matching element");
   }
 
-  E lastMatching(bool test(E element), { E orElse() }) {
+  E lastWhere(bool test(E element), { E orElse() }) {
     if (orElse != null) return orElse();
     throw new StateError("No matching element");
   }
 
-  E singleMatching(bool test(E element), { E orElse() }) {
+  E singleWhere(bool test(E element), { E orElse() }) {
     if (orElse != null) return orElse();
     throw new StateError("No matching element");
   }
diff --git a/sdk/lib/_collection_dev/list.dart b/sdk/lib/_collection_dev/list.dart
index 9685fda..01c7e8a 100644
--- a/sdk/lib/_collection_dev/list.dart
+++ b/sdk/lib/_collection_dev/list.dart
@@ -29,20 +29,24 @@
     return new ListMapView(this);
   }
 
-  List<E> getRange(int start, int length) {
+  List<E> sublist(int start, [int end]) {
+    if (end == null) end = length;
     if (start < 0 || start > this.length) {
       throw new RangeError.range(start, 0, this.length);
     }
-    if (length < 0 || start + length > this.length) {
-      throw new RangeError.range(length, 0, this.length - start);
+    if (end < start || end > this.length) {
+      throw new RangeError.range(end, start, this.length);
     }
-    List<E> result = new List<E>(length);
+    int length = end - start;
+    List<E> result = new List<E>()..length = length;
     for (int i = 0; i < length; i++) {
       result[i] = this[start + i];
     }
     return result;
   }
 
+  List<E> getRange(int start, int length) => sublist(start, start + length);
+
   int indexOf(E element, [int start = 0]) {
     return Arrays.indexOf(this, element, start, this.length);
   }
@@ -90,6 +94,11 @@
         "Cannot add to a fixed-length list");
   }
 
+  void insert(int index, E value) {
+    throw new UnsupportedError(
+        "Cannot add to a fixed-length list");
+  }
+
   void addAll(Iterable<E> iterable) {
     throw new UnsupportedError(
         "Cannot add to a fixed-length list");
@@ -110,12 +119,12 @@
         "Cannot remove from a fixed-length list");
   }
 
-  void removeMatching(bool test(E element)) {
+  void removeWhere(bool test(E element)) {
     throw new UnsupportedError(
         "Cannot remove from a fixed-length list");
   }
 
-  void retainMatching(bool test(E element)) {
+  void retainWhere(bool test(E element)) {
     throw new UnsupportedError(
         "Cannot remove from a fixed-length list");
   }
@@ -171,6 +180,11 @@
         "Cannot add to an unmodifiable list");
   }
 
+  E insert(int index, E value) {
+    throw new UnsupportedError(
+        "Cannot add to an unmodifiable list");
+  }
+
   void addAll(Iterable<E> iterable) {
     throw new UnsupportedError(
         "Cannot add to an unmodifiable list");
@@ -191,12 +205,12 @@
         "Cannot remove from an unmodifiable list");
   }
 
-  void removeMatching(bool test(E element)) {
+  void removeWhere(bool test(E element)) {
     throw new UnsupportedError(
         "Cannot remove from an unmodifiable list");
   }
 
-  void retainMatching(bool test(E element)) {
+  void retainWhere(bool test(E element)) {
     throw new UnsupportedError(
         "Cannot remove from an unmodifiable list");
   }
@@ -277,7 +291,9 @@
 
   int get length => _backedList.length;
   int elementAt(int index) {
-    if (index < 0 || index >= length) throw new RangeError(index);
+    if (index < 0 || index >= length) {
+      throw new RangeError.range(index, 0, length);
+    }
     return index;
   }
 }
diff --git a/sdk/lib/_collection_dev/to_string.dart b/sdk/lib/_collection_dev/to_string.dart
index 21cbf0c..f90ff18 100644
--- a/sdk/lib/_collection_dev/to_string.dart
+++ b/sdk/lib/_collection_dev/to_string.dart
@@ -51,18 +51,18 @@
                               List visiting) {
     visiting.add(c);
     bool isList = c is List;
-    result.add(isList ? '[' : '{');
+    result.write(isList ? '[' : '{');
 
     bool first = true;
     for (var e in c) {
       if (!first) {
-        result.add(', ');
+        result.write(', ');
       }
       first = false;
       _emitObject(e, result, visiting);
     }
 
-    result.add(isList ? ']' : '}');
+    result.write(isList ? ']' : '}');
     visiting.removeLast();
   }
 
@@ -82,18 +82,18 @@
   static void _emitObject(Object o, StringBuffer result, List visiting) {
     if (o is Collection) {
       if (_containsRef(visiting, o)) {
-        result.add(o is List ? '[...]' : '{...}');
+        result.write(o is List ? '[...]' : '{...}');
       } else {
         _emitCollection(o, result, visiting);
       }
     } else if (o is Map) {
       if (_containsRef(visiting, o)) {
-        result.add('{...}');
+        result.write('{...}');
       } else {
         _emitMap(o, result, visiting);
       }
     } else { // o is neither a collection nor a map
-      result.add(o);
+      result.write(o);
     }
   }
 
@@ -142,20 +142,20 @@
    */
   static void _emitMap(Map m, StringBuffer result, List visiting) {
     visiting.add(m);
-    result.add('{');
+    result.write('{');
 
     bool first = true;
     m.forEach((k, v) {
       if (!first) {
-        result.add(', ');
+        result.write(', ');
       }
       first = false;
       _emitObject(k, result, visiting);
-      result.add(': ');
+      result.write(': ');
       _emitObject(v, result, visiting);
     });
 
-    result.add('}');
+    result.write('}');
     visiting.removeLast();
   }
 }
diff --git a/sdk/lib/_internal/compiler/compiler.dart b/sdk/lib/_internal/compiler/compiler.dart
index bbee705..b3c72c4 100644
--- a/sdk/lib/_internal/compiler/compiler.dart
+++ b/sdk/lib/_internal/compiler/compiler.dart
@@ -22,7 +22,7 @@
 typedef Future<String> ReadStringFromUri(Uri uri);
 
 /**
- * Returns a [StreamSink] that will serve as compiler output for the given
+ * Returns an [EventSink] that will serve as compiler output for the given
  * component.
  *
  * Components are identified by [name] and [extension]. By convention,
@@ -41,8 +41,8 @@
  * As more features are added to the compiler, new names and
  * extensions may be introduced.
  */
-typedef StreamSink<String> CompilerOutputProvider(String name,
-                                                  String extension);
+typedef EventSink<String> CompilerOutputProvider(String name,
+                                                 String extension);
 
 /**
  * Invoked by the compiler to report diagnostics. If [uri] is
diff --git a/sdk/lib/_internal/compiler/implementation/apiimpl.dart b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
index c9759f3..de0dcf9 100644
--- a/sdk/lib/_internal/compiler/implementation/apiimpl.dart
+++ b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
@@ -44,6 +44,8 @@
             disallowUnsafeEval: hasOption(options, '--disallow-unsafe-eval'),
             analyzeAll: hasOption(options, '--analyze-all'),
             analyzeOnly: hasOption(options, '--analyze-only'),
+            analyzeSignaturesOnly:
+                hasOption(options, '--analyze-signatures-only'),
             rejectDeprecatedFeatures:
                 hasOption(options, '--reject-deprecated-language-features'),
             checkDeprecationInSdk:
@@ -52,7 +54,8 @@
             strips: getStrips(options),
             enableConcreteTypeInference:
                 hasOption(options, '--enable-concrete-type-inference'),
-            preserveComments: hasOption(options, '--preserve-comments')) {
+            preserveComments: hasOption(options, '--preserve-comments'),
+            verbose: hasOption(options, '--verbose')) {
     if (!libraryRoot.path.endsWith("/")) {
       throw new ArgumentError("libraryRoot must end with a /");
     }
diff --git a/sdk/lib/_internal/compiler/implementation/closure.dart b/sdk/lib/_internal/compiler/implementation/closure.dart
index 6df2cc6..dbfd5b8 100644
--- a/sdk/lib/_internal/compiler/implementation/closure.dart
+++ b/sdk/lib/_internal/compiler/implementation/closure.dart
@@ -14,7 +14,7 @@
 
 class ClosureNamer {
   SourceString getClosureVariableName(SourceString name, int id) {
-    return new SourceString("${name.slowToString()}_$id");    
+    return new SourceString("${name.slowToString()}_$id");
   }
 }
 
@@ -80,7 +80,13 @@
 }
 
 class ClosureClassElement extends ClassElementX {
-  ClosureClassElement(SourceString name,
+  DartType rawType;
+  DartType thisType;
+  /// Node that corresponds to this closure, used for source position.
+  final FunctionExpression node;
+
+  ClosureClassElement(this.node,
+                      SourceString name,
                       Compiler compiler,
                       this.methodElement,
                       Element enclosingElement)
@@ -95,10 +101,13 @@
     supertype = compiler.closureClass.computeType(compiler);
     interfaces = const Link<DartType>();
     allSupertypes = const Link<DartType>().prepend(supertype);
+    thisType = rawType = new InterfaceType(this);
   }
 
   bool isClosure() => true;
 
+  Token position() => node.getBeginToken();
+
   /**
    * The most outer method this closure is declared into.
    */
@@ -193,9 +202,11 @@
 
   bool isClosure() => closureElement != null;
 
-  bool captures(Element element) => freeVariableMapping.containsKey(element);
+  bool isVariableCaptured(Element element) {
+    freeVariableMapping.containsKey(element);
+  }
 
-  bool mutates(Element element) {
+  bool isVariableBoxed(Element element) {
     Element copy = freeVariableMapping[element];
     return copy != null && !copy.isMember();
   }
@@ -206,6 +217,21 @@
       f(variable);
     });
   }
+
+  void forEachBoxedVariable(void f(Element element)) {
+    freeVariableMapping.forEach((variable, copy) {
+      if (!isVariableBoxed(variable)) return;
+      f(variable);
+    });
+  }
+
+  void forEachNonBoxedCapturedVariable(void f(Element element)) {
+    freeVariableMapping.forEach((variable, copy) {
+      if (variable is BoxElement) return;
+      if (isVariableBoxed(variable)) return;
+      f(variable);
+    });
+  }
 }
 
 class ClosureTranslator extends Visitor {
@@ -445,9 +471,10 @@
         }
       }
     }
+
     if (outermostElement.isMember() &&
-        compiler.world.needsRti(outermostElement.getEnclosingClass())) {
-      if (outermostElement.isConstructor()) {
+        compiler.backend.needsRti(outermostElement.getEnclosingClass())) {
+      if (outermostElement.isConstructor() || outermostElement.isField()) {
         analyzeTypeVariables(type);
       } else if (outermostElement.isInstanceMember()) {
         if (hasTypeVariable(type)) useLocal(closureData.thisElement);
@@ -563,7 +590,7 @@
   ClosureClassMap globalizeClosure(FunctionExpression node, Element element) {
     SourceString closureName = new SourceString(computeClosureName(element));
     ClassElement globalizedElement = new ClosureClassElement(
-        closureName, compiler, element, element.getCompilationUnit());
+        node, closureName, compiler, element, element.getCompilationUnit());
     FunctionElement callElement =
         new FunctionElementX.from(Compiler.CALL_OPERATOR_NAME,
                                   element,
@@ -609,8 +636,8 @@
         declareLocal(element);
       }
 
-      if (currentElement.isFactoryConstructor()
-          && compiler.world.needsRti(currentElement.enclosingElement)) {
+      if (currentElement.isFactoryConstructor() &&
+          compiler.backend.needsRti(currentElement.enclosingElement)) {
         // Declare the type parameters in the scope. Generative
         // constructors just use 'this'.
         ClassElement cls = currentElement.enclosingElement;
diff --git a/sdk/lib/_internal/compiler/implementation/code_buffer.dart b/sdk/lib/_internal/compiler/implementation/code_buffer.dart
index fafc409..69fab9ae 100644
--- a/sdk/lib/_internal/compiler/implementation/code_buffer.dart
+++ b/sdk/lib/_internal/compiler/implementation/code_buffer.dart
@@ -44,7 +44,7 @@
     return this;
   }
 
-  CodeBuffer writeln(var object) {
+  CodeBuffer writeln([var object = ""]) {
     return write(object).write("\n");
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
index e4758a2..ca8e7b4 100644
--- a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
@@ -42,18 +42,22 @@
 
   String get name => 'ConstantHandler';
 
-  void registerCompileTimeConstant(Constant constant) {
-    registerInstantiatedClass(constant.computeType(compiler).element);
+  void registerCompileTimeConstant(Constant constant, TreeElements elements) {
+    registerInstantiatedClass(constant.computeType(compiler).element, elements);
     if (constant.isFunction()) {
       FunctionConstant function = constant;
       registerGetOfStaticFunction(function.element);
+    } else if (constant.isInterceptor()) {
+      // An interceptor constant references the class's prototype chain.
+      InterceptorConstant interceptor = constant;
+      registerInstantiatedClass(interceptor.dispatchedType.element, elements);
     }
     compiledConstants.add(constant);
   }
 
-  void registerInstantiatedClass(ClassElement element) {
+  void registerInstantiatedClass(ClassElement element, TreeElements elements) {
     if (isMetadata) return;
-    compiler.enqueuer.codegen.registerInstantiatedClass(element);
+    compiler.enqueuer.codegen.registerInstantiatedClass(element, elements);
   }
 
   void registerStaticUse(Element element) {
@@ -66,8 +70,8 @@
     compiler.enqueuer.codegen.registerGetOfStaticFunction(element);
   }
 
-  void registerStringInstance() {
-    registerInstantiatedClass(compiler.stringClass);
+  void registerStringInstance(TreeElements elements) {
+    registerInstantiatedClass(compiler.stringClass, elements);
   }
 
   void registerCreateRuntimeTypeFunction() {
@@ -312,17 +316,17 @@
   }
 
   Constant visitLiteralBool(LiteralBool node) {
-    handler.registerInstantiatedClass(compiler.boolClass);
+    handler.registerInstantiatedClass(compiler.boolClass, elements);
     return constantSystem.createBool(node.value);
   }
 
   Constant visitLiteralDouble(LiteralDouble node) {
-    handler.registerInstantiatedClass(compiler.doubleClass);
+    handler.registerInstantiatedClass(compiler.doubleClass, elements);
     return constantSystem.createDouble(node.value);
   }
 
   Constant visitLiteralInt(LiteralInt node) {
-    handler.registerInstantiatedClass(compiler.intClass);
+    handler.registerInstantiatedClass(compiler.intClass, elements);
     return constantSystem.createInt(node.value);
   }
 
@@ -340,7 +344,7 @@
     compiler.listClass.computeType(compiler);
     DartType type = compiler.listClass.rawType;
     Constant constant = new ListConstant(type, arguments);
-    handler.registerCompileTimeConstant(constant);
+    handler.registerCompileTimeConstant(constant, elements);
     return constant;
   }
 
@@ -377,7 +381,7 @@
     compiler.listClass.computeType(compiler);
     DartType keysType = compiler.listClass.rawType;
     ListConstant keysList = new ListConstant(keysType, keys);
-    handler.registerCompileTimeConstant(keysList);
+    handler.registerCompileTimeConstant(keysList, elements);
     SourceString className = hasProtoKey
                              ? MapConstant.DART_PROTO_CLASS
                              : MapConstant.DART_CLASS;
@@ -385,9 +389,9 @@
     classElement.ensureResolved(compiler);
     // TODO(floitsch): copy over the generic type.
     DartType type = classElement.rawType;
-    handler.registerInstantiatedClass(classElement);
+    handler.registerInstantiatedClass(classElement, elements);
     Constant constant = new MapConstant(type, keysList, values, protoValue);
-    handler.registerCompileTimeConstant(constant);
+    handler.registerCompileTimeConstant(constant, elements);
     return constant;
   }
 
@@ -396,7 +400,7 @@
   }
 
   Constant visitLiteralString(LiteralString node) {
-    handler.registerStringInstance();
+    handler.registerStringInstance(elements);
     return constantSystem.createString(node.dartString, node);
   }
 
@@ -404,7 +408,7 @@
     StringConstant left = evaluate(node.first);
     StringConstant right = evaluate(node.second);
     if (left == null || right == null) return null;
-    handler.registerStringInstance();
+    handler.registerStringInstance(elements);
     return constantSystem.createString(
         new DartString.concat(left.value, right.value), node);
   }
@@ -432,7 +436,7 @@
       if (partString == null) return null;
       accumulator = new DartString.concat(accumulator, partString.value);
     };
-    handler.registerStringInstance();
+    handler.registerStringInstance(elements);
     return constantSystem.createString(accumulator, node);
   }
 
@@ -444,7 +448,7 @@
     // constant emitter will generate a call to the createRuntimeType
     // helper so we register a use of that.
     handler.registerCreateRuntimeTypeFunction();
-    handler.registerCompileTimeConstant(constant);
+    handler.registerCompileTimeConstant(constant, elements);
     return constant;
   }
 
@@ -454,7 +458,7 @@
     if (send.isPropertyAccess) {
       if (Elements.isStaticOrTopLevelFunction(element)) {
         Constant constant = new FunctionConstant(element);
-        handler.registerCompileTimeConstant(constant);
+        handler.registerCompileTimeConstant(constant, elements);
         return constant;
       } else if (Elements.isStaticOrTopLevelField(element)) {
         Constant result;
@@ -660,12 +664,12 @@
     evaluator.evaluateConstructorFieldValues(arguments);
     List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement);
 
-    handler.registerInstantiatedClass(classElement);
+    handler.registerInstantiatedClass(classElement, elements);
     // TODO(floitsch): take generic types into account.
     classElement.computeType(compiler);
     DartType type = classElement.rawType;
     Constant constant = new ConstructedConstant(type, jsNewArguments);
-    handler.registerCompileTimeConstant(constant);
+    handler.registerCompileTimeConstant(constant, elements);
     return constant;
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index bdda72e..bbac476 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -106,12 +106,7 @@
     });
   }
 
-  // TODO(karlklose): get rid of this and add a factory constructor to [List]
-  // that creates an instance of JSArray to make the dependency visible in from
-  // the source code.
-  void addBackendRtiDependencies(World world);
-
-  void enqueueHelpers(ResolutionEnqueuer world);
+  void enqueueHelpers(ResolutionEnqueuer world, TreeElements elements);
   void codegen(CodegenWorkItem work);
 
   // The backend determines the native resolution enqueuer, with a no-op
@@ -126,6 +121,8 @@
   void assembleProgram();
   List<CompilerTask> get tasks;
 
+  void onResolutionComplete() {}
+
   // TODO(ahe,karlklose): rename this?
   void dumpInferredTypes() {}
 
@@ -133,24 +130,52 @@
     return new ItemCompilationContext();
   }
 
+  bool needsRti(ClassElement cls);
+
   // The following methods are hooks for the backend to register its
   // helper methods.
-  void registerInstantiatedClass(ClassElement cls, Enqueuer enqueuer) {}
-  void registerStringInterpolation() {}
-  void registerCatchStatement() {}
-  void registerThrow() {}
-  void registerLazyField() {}
-  void registerTypeLiteral() {}
-  void registerStackTraceInCatch() {}
-  void registerIsCheck(DartType type, Enqueuer enqueuer) {}
-  void registerAsCheck(DartType type) {}
-  void registerThrowNoSuchMethod() {}
-  void registerThrowRuntimeError() {}
-  void registerAbstractClassInstantiation() {}
-  void registerFallThroughError() {}
-  void registerSuperNoSuchMethod() {}
-  void registerConstantMap() {}
-  void registerRuntimeType() {}
+  void registerInstantiatedClass(ClassElement cls,
+                                 Enqueuer enqueuer,
+                                 TreeElements elements) {}
+  void registerStringInterpolation(TreeElements elements) {}
+  void registerCatchStatement(TreeElements elements) {}
+  void registerThrow(TreeElements elements) {}
+  void registerLazyField(TreeElements elements) {}
+  void registerTypeVariableExpression(TreeElements elements) {}
+  void registerTypeLiteral(TreeElements elements) {}
+  void registerStackTraceInCatch(TreeElements elements) {}
+  void registerIsCheck(DartType type,
+                       Enqueuer enqueuer,
+                       TreeElements elements) {}
+  void registerAsCheck(DartType type, TreeElements elements) {}
+  void registerThrowNoSuchMethod(TreeElements elements) {}
+  void registerThrowRuntimeError(TreeElements elements) {}
+  void registerAbstractClassInstantiation(TreeElements elements) {}
+  void registerFallThroughError(TreeElements elements) {}
+  void registerSuperNoSuchMethod(TreeElements elements) {}
+  void registerConstantMap(TreeElements elements) {}
+  void registerRuntimeType(TreeElements elements) {}
+
+  void registerRequiredType(DartType type, Element enclosingElement) {}
+  void registerClassUsingVariableExpression(ClassElement cls) {}
+
+  bool isNullImplementation(ClassElement cls) {
+    return cls == compiler.nullClass;
+  }
+  ClassElement get intImplementation => compiler.intClass;
+  ClassElement get doubleImplementation => compiler.doubleClass;
+  ClassElement get numImplementation => compiler.numClass;
+  ClassElement get stringImplementation => compiler.stringClass;
+  ClassElement get listImplementation => compiler.listClass;
+  ClassElement get growableListImplementation => compiler.listClass;
+  ClassElement get fixedListImplementation => compiler.listClass;
+  ClassElement get constListImplementation => compiler.listClass;
+  ClassElement get mapImplementation => compiler.mapClass;
+  ClassElement get constMapImplementation => compiler.mapClass;
+  ClassElement get functionImplementation => compiler.functionClass;
+  ClassElement get typeImplementation => compiler.typeClass;
+  ClassElement get boolImplementation => compiler.boolClass;
+  ClassElement get nullImplementation => compiler.nullClass;
 }
 
 /**
@@ -205,6 +230,15 @@
    */
   final TokenMap commentMap = new TokenMap();
 
+  /**
+   * Records global dependencies, that is, dependencies that don't
+   * correspond to a particular element.
+   *
+   * We should get rid of this and ensure that all dependencies are
+   * associated with a particular element.
+   */
+  final TreeElements globalDependencies = new TreeElementMapping(null);
+
   final bool enableMinification;
   final bool enableTypeAssertions;
   final bool enableUserAssertions;
@@ -216,6 +250,11 @@
   final int maxConcreteTypeSize;
   final bool analyzeAll;
   final bool analyzeOnly;
+  /**
+   * If true, skip analysis of method bodies and field initializers. Implies
+   * [analyzeOnly].
+   */
+  final bool analyzeSignaturesOnly;
   final bool enableNativeLiveTypeAnalysis;
   final bool rejectDeprecatedFeatures;
   final bool checkDeprecationInSdk;
@@ -225,6 +264,11 @@
    */
   final bool preserveComments;
 
+  /**
+   * Is the compiler in verbose mode.
+   */
+  final bool verbose;
+
   final api.CompilerOutputProvider outputProvider;
 
   bool disableInlining = false;
@@ -256,7 +300,6 @@
   ClassElement listClass;
   ClassElement typeClass;
   ClassElement mapClass;
-  ClassElement mapLiteralClass;
   ClassElement jsInvocationMirrorClass;
   /// Document class from dart:mirrors.
   ClassElement documentClass;
@@ -335,34 +378,52 @@
 
   static const int PHASE_SCANNING = 0;
   static const int PHASE_RESOLVING = 1;
-  static const int PHASE_COMPILING = 2;
+  static const int PHASE_DONE_RESOLVING = 2;
+  static const int PHASE_COMPILING = 3;
   int phase;
 
   bool compilationFailed = false;
 
   bool hasCrashed = false;
 
-  Compiler({this.tracer: const Tracer(),
-            this.enableTypeAssertions: false,
-            this.enableUserAssertions: false,
-            this.enableConcreteTypeInference: false,
-            this.maxConcreteTypeSize: 5,
-            this.enableMinification: false,
-            this.enableNativeLiveTypeAnalysis: false,
+  Compiler({Tracer tracer: const Tracer(),
+            bool enableTypeAssertions: false,
+            bool enableUserAssertions: false,
+            bool enableConcreteTypeInference: false,
+            int maxConcreteTypeSize: 5,
+            bool enableMinification: false,
+            bool enableNativeLiveTypeAnalysis: false,
             bool emitJavaScript: true,
             bool generateSourceMap: true,
             bool disallowUnsafeEval: false,
-            this.analyzeAll: false,
-            this.analyzeOnly: false,
-            this.rejectDeprecatedFeatures: false,
-            this.checkDeprecationInSdk: false,
-            this.preserveComments: false,
+            bool analyzeAll: false,
+            bool analyzeOnly: false,
+            bool analyzeSignaturesOnly: false,
+            bool rejectDeprecatedFeatures: false,
+            bool checkDeprecationInSdk: false,
+            bool preserveComments: false,
+            bool verbose: false,
             outputProvider,
             List<String> strips: const []})
-      : libraries = new Map<String, LibraryElement>(),
+      : tracer = tracer,
+        enableTypeAssertions = enableTypeAssertions,
+        enableUserAssertions = enableUserAssertions,
+        enableConcreteTypeInference = enableConcreteTypeInference,
+        maxConcreteTypeSize = maxConcreteTypeSize,
+        enableMinification = enableMinification,
+        enableNativeLiveTypeAnalysis = enableNativeLiveTypeAnalysis,
+        analyzeAll = analyzeAll,
+        rejectDeprecatedFeatures = rejectDeprecatedFeatures,
+        checkDeprecationInSdk = checkDeprecationInSdk,
+        preserveComments = preserveComments,
+        verbose = verbose,
+        libraries = new Map<String, LibraryElement>(),
         progress = new Stopwatch(),
+        this.analyzeOnly = analyzeOnly || analyzeSignaturesOnly,
+        this.analyzeSignaturesOnly = analyzeSignaturesOnly,
         this.outputProvider =
             (outputProvider == null) ? NullSink.outputProvider : outputProvider
+
   {
     progress.start();
     world = new World(this);
@@ -502,6 +563,19 @@
     } on CompilerCancelledException catch (exception) {
       log('Error: $exception');
       return false;
+    } catch (exception) {
+      try {
+        if (!hasCrashed) {
+          hasCrashed = true;
+          reportDiagnostic(new SourceSpan(uri, 0, 0),
+                           MessageKind.COMPILER_CRASHED.error().toString(),
+                           api.Diagnostic.CRASH);
+          pleaseReportCrash();
+        }
+      } catch (doubleFault) {
+        // Ignoring exceptions in exception handling.
+      }
+      throw;
     } finally {
       tracer.close();
       totalCompileTime.stop();
@@ -547,8 +621,6 @@
     listClass = lookupCoreClass('List');
     typeClass = lookupCoreClass('Type');
     mapClass = lookupCoreClass('Map');
-    // TODO: find a proper way to get to the implementation class.
-    mapLiteralClass = lookupCoreClass('LinkedHashMap');
     if (!missingCoreClasses.isEmpty) {
       internalErrorOnElement(coreLibrary,
           'dart:core library does not contain required classes: '
@@ -575,6 +647,17 @@
 
     types = new Types(this, dynamicClass);
     backend.initializeHelperClasses();
+
+    dynamicClass.ensureResolved(this);
+  }
+
+  Element _unnamedListConstructor;
+  Element get unnamedListConstructor {
+    if (_unnamedListConstructor != null) return _unnamedListConstructor;
+    Selector callConstructor = new Selector.callConstructor(
+        const SourceString(""), listClass.getLibrary());
+    return _unnamedListConstructor =
+        listClass.lookupConstructor(callConstructor);
   }
 
   void scanBuiltinLibraries() {
@@ -662,26 +745,40 @@
           reportFatalError('main cannot have parameters', parameter);
         });
       }
-    }
 
-    deferredLoadTask.registerMainApp(mainApp);
+      // In order to see if a library is deferred, we must compute the
+      // compile-time constants that are metadata.  This means adding
+      // something to the resolution queue.  So we cannot wait with
+      // this until after the resolution queue is processed.
+      // TODO(ahe): Clean this up, for example, by not enqueueing
+      // classes only used for metadata.
+      deferredLoadTask.findDeferredLibraries(mainApp);
+    }
 
     log('Resolving...');
     phase = PHASE_RESOLVING;
     if (analyzeAll) {
       libraries.forEach((_, lib) => fullyEnqueueLibrary(lib));
     }
-    backend.enqueueHelpers(enqueuer.resolution);
+    // Elements required by enqueueHelpers are global dependencies
+    // that are not pulled in by a particular element.
+    backend.enqueueHelpers(enqueuer.resolution, globalDependencies);
     processQueue(enqueuer.resolution, main);
     enqueuer.resolution.logSummary(log);
 
     if (compilationFailed) return;
     if (analyzeOnly) return;
     assert(main != null);
+    phase = PHASE_DONE_RESOLVING;
 
     // TODO(ahe): Remove this line. Eventually, enqueuer.resolution
     // should know this.
     world.populate();
+    // Compute whole-program-knowledge that the backend needs. (This might
+    // require the information computed in [world.populate].)
+    backend.onResolutionComplete();
+
+    deferredLoadTask.onResolutionComplete(main);
 
     log('Inferring types...');
     typesTask.onResolutionComplete(main);
@@ -1051,12 +1148,15 @@
   final Compiler compiler;
   final Stopwatch watch;
 
-  CompilerTask(this.compiler) : watch = new Stopwatch();
+  CompilerTask(Compiler compiler)
+      : this.compiler = compiler,
+        watch = (compiler.verbose) ? new Stopwatch() : null;
 
   String get name => 'Unknown task';
-  int get timing => watch.elapsedMilliseconds;
+  int get timing => (watch != null) ? watch.elapsedMilliseconds : 0;
 
   measure(action()) {
+    if (watch == null) return action();
     CompilerTask previous = compiler.measuredTask;
     if (identical(this, previous)) return action();
     compiler.measuredTask = this;
@@ -1147,14 +1247,14 @@
 }
 
 /// A sink that drains into /dev/null.
-class NullSink extends StreamSink<String> {
+class NullSink implements EventSink<String> {
   final String name;
 
   NullSink(this.name);
 
   add(String value) {}
 
-  void signalError(AsyncError error) {}
+  void addError(AsyncError error) {}
 
   void close() {}
 
diff --git a/sdk/lib/_internal/compiler/implementation/constants.dart b/sdk/lib/_internal/compiler/implementation/constants.dart
index ad5dc74..eae62ead 100644
--- a/sdk/lib/_internal/compiler/implementation/constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/constants.dart
@@ -17,6 +17,7 @@
   R visitMap(MapConstant constant);
   R visitConstructed(ConstructedConstant constant);
   R visitType(TypeConstant constant);
+  R visitInterceptor(InterceptorConstant constant);
 }
 
 abstract class Constant {
@@ -40,6 +41,7 @@
   bool isObject() => false;
   bool isType() => false;
   bool isSentinel() => false;
+  bool isInterceptor() => false;
 
   bool isNaN() => false;
   bool isMinusZero() => false;
@@ -126,7 +128,7 @@
   }
 
   void _writeJsCode(CodeBuffer buffer, ConstantHandler handler) {
-    buffer.add(JsNull);
+    buffer.write(JsNull);
   }
 
   // The magic constant has no meaning. It is just a random value.
@@ -432,6 +434,29 @@
   accept(ConstantVisitor visitor) => visitor.visitMap(this);
 }
 
+class InterceptorConstant extends Constant {
+  /// The type for which this interceptor holds the methods.  The constant
+  /// is a dispatch table for this type.
+  final DartType dispatchedType;
+
+  InterceptorConstant(this.dispatchedType);
+
+  bool isInterceptor() => true;
+
+  bool operator ==(other) {
+    return other is InterceptorConstant
+        && dispatchedType == other.dispatchedType;
+  }
+
+  int get hashCode => dispatchedType.hashCode * 43;
+
+  List<Constant> getDependencies() => const <Constant>[];
+
+  accept(ConstantVisitor visitor) => visitor.visitInterceptor(this);
+
+  DartType computeType(Compiler compiler) => compiler.types.dynamicType;
+}
+
 class ConstructedConstant extends ObjectConstant {
   final List<Constant> fields;
   final int hashCode;
diff --git a/sdk/lib/_internal/compiler/implementation/dart2js.dart b/sdk/lib/_internal/compiler/implementation/dart2js.dart
index c76c45f..bc5be23 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2js.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2js.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -128,6 +128,11 @@
     passThrough(argument);
   }
 
+  setVerbose(_) {
+    diagnosticHandler.verbose = true;
+    passThrough('--verbose');
+  }
+
   setCategories(String argument) {
     List<String> categories = extractParameter(argument).split(',');
     Set<String> allowedCategories =
@@ -156,7 +161,7 @@
     for (var shortOption in shortOptions) {
       switch (shortOption) {
         case 'v':
-          diagnosticHandler.verbose = true;
+          setVerbose(null);
           break;
         case 'h':
         case '?':
@@ -179,7 +184,7 @@
     new OptionHandler('--suppress-warnings',
                       (_) => diagnosticHandler.showWarnings = false),
     new OptionHandler('--output-type=dart|--output-type=js', setOutputType),
-    new OptionHandler('--verbose', (_) => diagnosticHandler.verbose = true),
+    new OptionHandler('--verbose', setVerbose),
     new OptionHandler('--library-root=.+', setLibraryRoot),
     new OptionHandler('--out=.+|-o.+', setOutput),
     new OptionHandler('--allow-mock-compilation', passThrough),
@@ -199,6 +204,7 @@
     new OptionHandler('--disallow-unsafe-eval', passThrough),
     new OptionHandler('--analyze-all', passThrough),
     new OptionHandler('--analyze-only', setAnalyzeOnly),
+    new OptionHandler('--analyze-signatures-only', passThrough),
     new OptionHandler('--disable-native-live-type-analysis', passThrough),
     new OptionHandler('--reject-deprecated-language-features', passThrough),
     new OptionHandler('--report-sdk-use-of-deprecated-language-features',
@@ -225,7 +231,7 @@
     helpAndFail('Error: No Dart file specified.');
   }
   if (arguments.length > 1) {
-    var extra = arguments.getRange(1, arguments.length - 1);
+    var extra = arguments.sublist(1);
     helpAndFail('Error: Extra arguments: ${extra.join(" ")}');
   }
 
@@ -261,7 +267,7 @@
     }
   }
 
-  StreamSink<String> outputProvider(String name, String extension) {
+  EventSink<String> outputProvider(String name, String extension) {
     Uri uri;
     String sourceMapFileName;
     bool isPrimaryOutput = false;
@@ -292,7 +298,7 @@
       if (sourceMapFileName != null) {
         String sourceMapTag = '//@ sourceMappingURL=$sourceMapFileName\n';
         sink.count += sourceMapTag.length;
-        output.addString(sourceMapTag);
+        output.write(sourceMapTag);
       }
       output.close();
       if (isPrimaryOutput) {
@@ -301,7 +307,7 @@
     }
 
     var controller = new StreamController<String>();
-    controller.stream.listen(output.addString, onDone: onDone);
+    controller.stream.listen(output.write, onDone: onDone);
     sink = new CountingSink(controller);
     return sink;
   }
@@ -313,20 +319,20 @@
 }
 
 // TODO(ahe): Get rid of this class if http://dartbug.com/8118 is fixed.
-class CountingSink implements StreamSink<String> {
-  final StreamSink<String> sink;
+class CountingSink implements EventSink<String> {
+  final EventSink<String> sink;
   int count = 0;
 
   CountingSink(this.sink);
 
-  add(String value) {
+  void add(String value) {
     sink.add(value);
     count += value.length;
   }
 
-  signalError(AsyncError error) => sink.signalError(error);
+  void addError(AsyncError error) { sink.addError(error); }
 
-  close() => sink.close();
+  void close() { sink.close(); }
 }
 
 class AbortLeg {
@@ -403,6 +409,10 @@
   --analyze-only
     Analyze but do not generate code.
 
+  --analyze-signatures-only
+    Skip analysis of method bodies and field initializers. This option implies
+    --analyze-only.
+
   --minify
     Generate minified output.
 
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
index 91cff3e..1611434 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
@@ -217,9 +217,9 @@
         stripAsserts = strips.indexOf('asserts') != -1,
         super(compiler);
 
-  void addBackendRtiDependencies(World world) {}
+  bool needsRti(ClassElement cls) => false;
 
-  void enqueueHelpers(ResolutionEnqueuer world) {
+  void enqueueHelpers(ResolutionEnqueuer world, TreeElements elements) {
     // Right now resolver doesn't always resolve interfaces needed
     // for literals, so force them. TODO(antonm): fix in the resolver.
     final LITERAL_TYPE_NAMES = const [
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart
index 693afa0..601d136 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart
@@ -423,11 +423,15 @@
                element is TypeVariableElement);
         makeElementPlaceholder(send.selector, element);
       } else {
-        assert(send.selector is Identifier);
+        Identifier identifier = send.selector.asIdentifier();
+        if (identifier == null) {
+          // Handle optional function expression parameters with default values.
+          identifier = send.selector.asFunctionExpression().name;
+        }
         if (Elements.isInstanceField(element)) {
-          tryMakeMemberPlaceholder(send.selector);
+          tryMakeMemberPlaceholder(identifier);
         } else {
-          tryMakeLocalPlaceholder(element, send.selector);
+          tryMakeLocalPlaceholder(element, identifier);
         }
       }
     }
diff --git a/sdk/lib/_internal/compiler/implementation/dart_types.dart b/sdk/lib/_internal/compiler/implementation/dart_types.dart
index ec79917..5f00a62 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_types.dart
@@ -102,6 +102,36 @@
 
   DartType asRaw() => this;
 
+  /**
+   * Is [: true :] if this type is the dynamic type.
+   */
+  bool get isDynamic => false;
+
+  /**
+   * Is [: true :] if this type is the void type.
+   */
+  bool get isVoid => false;
+
+  /**
+   * Returns an occurrence of a type variable within this type, if any.
+   */
+  TypeVariableType get typeVariableOccurrence => null;
+
+  TypeVariableType _findTypeVariableOccurrence(Link<DartType> types) {
+    for (Link<DartType> link = types; !link.isEmpty ; link = link.tail) {
+      TypeVariableType typeVariable = link.head.typeVariableOccurrence;
+      if (typeVariable != null) {
+        return typeVariable;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Is [: true :] if this type contains any type variables.
+   */
+  bool get containsTypeVariables => typeVariableOccurrence != null;
+
   accept(DartTypeVisitor visitor, var argument);
 }
 
@@ -161,6 +191,8 @@
 
   DartType unalias(Compiler compiler) => this;
 
+  DartType get typeVariableOccurrence => this;
+
   accept(DartTypeVisitor visitor, var argument) {
     return visitor.visitTypeVariableType(this, argument);
   }
@@ -239,6 +271,8 @@
     return visitor.visitVoidType(this, argument);
   }
 
+  bool get isVoid => true;
+
   int get hashCode => 1729;
 
   bool operator ==(other) => other is VoidType;
@@ -358,6 +392,10 @@
     return true;
   }
 
+  TypeVariableType get typeVariableOccurrence {
+    return _findTypeVariableOccurrence(typeArguments);
+  }
+
   String toString() {
     StringBuffer sb = new StringBuffer();
     sb.write(name.slowToString());
@@ -531,7 +569,7 @@
                         Link<SourceString> this.namedParameters,
                         Link<DartType> this.namedParameterTypes,
                         bool this.isMalformed) {
-    assert(element == null || invariant(element, element.isDeclaration));
+    assert(invariant(element, element.isDeclaration));
     // Assert that optional and named parameters are not used at the same time.
     assert(optionalParameterTypes.isEmpty || namedParameterTypes.isEmpty);
     assert(namedParameters.slowLength() == namedParameterTypes.slowLength());
@@ -608,6 +646,19 @@
 
   DartType unalias(Compiler compiler) => this;
 
+  DartType get typeVariableOccurrence {
+    TypeVariableType typeVariableType = returnType.typeVariableOccurrence;
+    if (typeVariableType != null) return typeVariableType;
+
+    typeVariableType = _findTypeVariableOccurrence(parameterTypes);
+    if (typeVariableType != null) return typeVariableType;
+
+    typeVariableType = _findTypeVariableOccurrence(optionalParameterTypes);
+    if (typeVariableType != null) return typeVariableType;
+
+    return _findTypeVariableOccurrence(namedParameterTypes);
+  }
+
   accept(DartTypeVisitor visitor, var argument) {
     return visitor.visitFunctionType(this, argument);
   }
@@ -660,18 +711,18 @@
   }
 
   int get hashCode {
-    int hash = 17 * element.hashCode + 3 * returnType.hashCode;
+    int hash = 3 * returnType.hashCode;
     for (DartType parameter  in parameterTypes) {
-      hash = 17 * hash + 3 * parameter.hashCode;
+      hash = 17 * hash + 5 * parameter.hashCode;
     }
     for (DartType parameter  in optionalParameterTypes) {
-      hash = 17 * hash + 3 * parameter.hashCode;
+      hash = 19 * hash + 7 * parameter.hashCode;
     }
     for (SourceString name  in namedParameters) {
-      hash = 17 * hash + 3 * name.hashCode;
+      hash = 23 * hash + 11 * name.hashCode;
     }
     for (DartType parameter  in namedParameterTypes) {
-      hash = 17 * hash + 3 * parameter.hashCode;
+      hash = 29 * hash + 13 * parameter.hashCode;
     }
     return hash;
   }
@@ -737,6 +788,8 @@
 
   SourceString get name => const SourceString('dynamic');
 
+  bool get isDynamic => true;
+
   accept(DartTypeVisitor visitor, var argument) {
     return visitor.visitDynamicType(this, argument);
   }
@@ -844,8 +897,11 @@
 class SubtypeVisitor extends DartTypeVisitor<bool, DartType> {
   final Compiler compiler;
   final DynamicType dynamicType;
+  final VoidType voidType;
 
-  SubtypeVisitor(Compiler this.compiler, DynamicType this.dynamicType);
+  SubtypeVisitor(Compiler this.compiler,
+                 DynamicType this.dynamicType,
+                 VoidType this.voidType);
 
   bool isSubtype(DartType t, DartType s) {
     if (identical(t, s) ||
@@ -877,11 +933,10 @@
   }
 
   bool visitInterfaceType(InterfaceType t, DartType s) {
-    if (s is !InterfaceType) return false;
 
-    bool checkTypeArguments(InterfaceType instance) {
+    bool checkTypeArguments(InterfaceType instance, InterfaceType other) {
       Link<DartType> tTypeArgs = instance.typeArguments;
-      Link<DartType> sTypeArgs = s.typeArguments;
+      Link<DartType> sTypeArgs = other.typeArguments;
       while (!tTypeArgs.isEmpty) {
         assert(!sTypeArgs.isEmpty);
         if (!isSubtype(tTypeArgs.head, sTypeArgs.head)) {
@@ -894,16 +949,31 @@
       return true;
     }
 
+    lookupCall(type) => type.lookupMember(Compiler.CALL_OPERATOR_NAME);
+
     // TODO(johnniwinther): Currently needed since literal types like int,
     // double, bool etc. might not have been resolved yet.
     t.element.ensureResolved(compiler);
 
-    InterfaceType instance = t.asInstanceOf(s.element);
-    return instance != null && checkTypeArguments(instance);
+    if (s is InterfaceType) {
+      if (s.element == compiler.functionClass && lookupCall(t) != null) {
+        return true;
+      }
+      InterfaceType instance = t.asInstanceOf(s.element);
+      return instance != null && checkTypeArguments(instance, s);
+    } else if (s is FunctionType) {
+      Member call = lookupCall(t);
+      if (call == null) return false;
+      return isSubtype(call.computeType(compiler), s);
+    } else {
+      return false;
+    }
   }
 
   bool visitFunctionType(FunctionType t, DartType s) {
-    if (identical(s.element, compiler.functionClass)) return true;
+    if (s is InterfaceType && identical(s.element, compiler.functionClass)) {
+      return true;
+    }
     if (s is !FunctionType) return false;
     FunctionType tf = t;
     FunctionType sf = s;
@@ -915,8 +985,10 @@
       sps = sps.tail;
     }
     if (!tps.isEmpty || !sps.isEmpty) return false;
-    // TODO(johnniwinther): Handle the void type correctly.
-    if (!isAssignable(tf.returnType, sf.returnType)) return false;
+    if (!identical(sf.returnType, voidType) &&
+        !isAssignable(tf.returnType, sf.returnType)) {
+      return false;
+    }
     if (!sf.namedParameters.isEmpty) {
       // Since named parameters are globally ordered we can determine the
       // subset relation with a linear search for [:sf.NamedParameters:]
@@ -978,7 +1050,8 @@
     VoidType voidType = new VoidType(new VoidElementX(library));
     DynamicType dynamicType = new DynamicType(dynamicElement);
     dynamicElement.rawType = dynamicElement.thisType = dynamicType;
-    SubtypeVisitor subtypeVisitor = new SubtypeVisitor(compiler, dynamicType);
+    SubtypeVisitor subtypeVisitor =
+        new SubtypeVisitor(compiler, dynamicType, voidType);
     return new Types.internal(compiler, voidType, dynamicType, subtypeVisitor);
   }
 
@@ -1037,4 +1110,14 @@
     });
     return reasons.join(', ');
   }
+
+  /**
+   * Returns the [ClassElement] which declares the type variables occurring in
+   * [type], or [:null:] if [type] does not contain type variables.
+   */
+  static ClassElement getClassContext(DartType type) {
+    TypeVariableType typeVariable = type.typeVariableOccurrence;
+    if (typeVariable == null) return null;
+    return typeVariable.element.enclosingElement;
+  }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/deferred_load.dart b/sdk/lib/_internal/compiler/implementation/deferred_load.dart
index c623bd8..a9045d0c 100644
--- a/sdk/lib/_internal/compiler/implementation/deferred_load.dart
+++ b/sdk/lib/_internal/compiler/implementation/deferred_load.dart
@@ -4,7 +4,12 @@
 
 library deferred_load;
 
-import 'dart:uri';
+import 'dart:uri'
+       show Uri;
+
+import 'dart:collection'
+       show LinkedHashMap,
+            LinkedHashSet;
 
 import 'dart2jslib.dart'
        show Compiler,
@@ -17,23 +22,39 @@
 import 'elements/elements.dart'
        show ClassElement,
             Element,
+            Elements,
+            FunctionElement,
             LibraryElement,
-            MetadataAnnotation;
+            MetadataAnnotation,
+            ScopeContainerElement;
 
 import 'util/util.dart'
        show Link;
 
 import 'tree/tree.dart'
-       show LibraryTag;
+       show LibraryTag,
+            Node,
+            Visitor;
+
+import 'resolution/resolution.dart'
+       show TreeElements;
 
 class DeferredLoadTask extends CompilerTask {
-  final Set<LibraryElement> deferredLibraries = new Set<LibraryElement>();
+  final Set<LibraryElement> deferredLibraries =
+      new LinkedHashSet<LibraryElement>();
+
+  /// Records all elements that are deferred.
+  ///
+  /// Long term, we want to split deferred element into more than one
+  /// file (one for each library that is deferred), and this field
+  /// should become obsolete.
+  final Set<Element> allDeferredElements = new LinkedHashSet<Element>();
 
   ClassElement cachedDeferredLibraryClass;
 
   DeferredLoadTask(Compiler compiler) : super(compiler);
 
-  String get name => 'Lazy';
+  String get name => 'Deferred Loading';
 
   /// DeferredLibrary from dart:async
   ClassElement get deferredLibraryClass {
@@ -58,23 +79,135 @@
   }
 
   bool isDeferred(Element element) {
-    // TODO(ahe): This is really a graph coloring problem. We should
-    // make sure that libraries and elements only used by a deferred
-    // library are also deferred.
-    // Also, if something is deferred depends on your
-    // perspective. Inside a deferred library, other elements of the
-    // same library are not deferred. We should add an extra parameter
-    // to this method to indicate "from where".
+    element = element.implementation;
+    return allDeferredElements.contains(element);
+  }
+
+  bool isExplicitlyDeferred(Element element) {
+    element = element.implementation;
     return deferredLibraries.contains(element.getLibrary());
   }
 
-  void registerMainApp(LibraryElement mainApp) {
-    if (mainApp == null) return;
+  void onResolutionComplete(FunctionElement main) {
+    if (main == null) return;
+    LibraryElement mainApp = main.getLibrary();
     measureElement(mainApp, () {
       deferredLibraries.addAll(findDeferredLibraries(mainApp));
+      if (deferredLibraries.isEmpty) return;
+
+      // TODO(ahe): Enforce the following invariants on
+      // [deferredElements] and [eagerElements]:
+      // 1. Only static or top-level elements are recorded.
+      // 2. Only implementation is stored.
+      Map<LibraryElement, Set<Element>> deferredElements =
+          new LinkedHashMap<LibraryElement, Set<Element>>();
+      Set<Element> eagerElements = new LinkedHashSet<Element>();
+
+      // Iterate through the local members of the main script.  Create
+      // a root-set of elements that must be loaded eagerly
+      // (everything that is directly referred to from the main
+      // script, but not imported from a deferred library), as well as
+      // root-sets for deferred libraries.
+      mainApp.forEachLocalMember((Element e) {
+        for (Element dependency in allElementsResolvedFrom(e)) {
+          if (isExplicitlyDeferred(dependency)) {
+            Set<Element> deferredElementsFromLibrary =
+                deferredElements.putIfAbsent(
+                    dependency.getLibrary(),
+                    () => new LinkedHashSet<Element>());
+            deferredElementsFromLibrary.add(dependency);
+          } else if (dependency.getLibrary() != mainApp) {
+            eagerElements.add(dependency.implementation);
+          }
+        }
+      });
+
+      // Also add "global" dependencies to the eager root-set.  These
+      // are things that the backend need but cannot associate with a
+      // particular element, for example, startRootIsolate.  This set
+      // also contains elements for which we lack precise information.
+      eagerElements.addAll(compiler.globalDependencies.otherDependencies);
+
+      addTransitiveClosureTo(eagerElements);
+
+      for (Set<Element> e in deferredElements.values) {
+        addTransitiveClosureTo(e);
+        e.removeAll(eagerElements);
+        for (Element element in e) {
+          allDeferredElements.add(element);
+        }
+      }
+
+      // TODO(ahe): The following code has no effect yet.  I'm
+      // including it as a comment for how to extend this to support
+      // multiple deferred files.
+      Map<Element, List<LibraryElement>> reverseMap =
+          new LinkedHashMap<Element, List<LibraryElement>>();
+
+      deferredElements.forEach((LibraryElement library, Set<Element> map) {
+        for (Element element in map) {
+          List<LibraryElement> libraries =
+              reverseMap.putIfAbsent(element, () => <LibraryElement>[]);
+          libraries.add(library);
+        }
+      });
+
+      // Now compute the output files based on the lists in reverseMap.
+      // TODO(ahe): Do that.
     });
   }
 
+  /// Returns all elements in the tree map of [element], but not the
+  /// transitive closure.
+  Set<Element> allElementsResolvedFrom(Element element) {
+    element = element.implementation;
+    Set<Element> result = new LinkedHashSet<Element>();
+    if (element.isGenerativeConstructor()) {
+      // When instantiating a class, we record a reference to the
+      // constructor, not the class itself.
+      element = element.getEnclosingClass().implementation;
+    }
+    if (element.isClass()) {
+      // If we see a class, add everything its instance members refer
+      // to.  Static members are not relevant.
+      ClassElement cls = element.declaration;
+      cls.forEachLocalMember((Element e) {
+        if (!e.isInstanceMember()) return;
+        result.addAll(DependencyCollector.collect(e.implementation, compiler));
+      });
+      if (cls.implementation != cls) {
+        // TODO(ahe): Why doesn't ClassElement.forEachLocalMember do this?
+        cls.implementation.forEachLocalMember((Element e) {
+          if (!e.isInstanceMember()) return;
+          result.addAll(DependencyCollector.collect(e.implementation,
+                                                    compiler));
+        });
+      }
+      for (var type in cls.allSupertypes) {
+        result.add(type.element.implementation);
+      }
+      result.add(cls.implementation);
+    } else if (Elements.isStaticOrTopLevel(element)) {
+      result.addAll(DependencyCollector.collect(element, compiler));
+    }
+    // Other elements, in particular instance members, are ignored as
+    // they are processed as part of the class.
+    return result;
+  }
+
+  void addTransitiveClosureTo(Set<Element> elements) {
+    Set<Element> workSet = new LinkedHashSet.from(elements);
+    Set<Element> closure = new LinkedHashSet<Element>();
+    while (!workSet.isEmpty) {
+      Element current = workSet.first;
+      workSet.remove(current);
+      if (closure.contains(current)) continue;
+      workSet.addAll(allElementsResolvedFrom(current));
+      closure.add(current);
+    }
+    elements.addAll(closure);
+  }
+
   Link<LibraryElement> findDeferredLibraries(LibraryElement library) {
     Link<LibraryElement> link = const Link<LibraryElement>();
     for (LibraryTag tag in library.tags) {
@@ -104,3 +237,29 @@
     return link;
   }
 }
+
+class DependencyCollector extends Visitor {
+  final Set<Element> dependencies = new LinkedHashSet<Element>();
+  final TreeElements elements;
+  final Compiler compiler;
+
+  DependencyCollector(this.elements, this.compiler);
+
+  visitNode(Node node) {
+    node.visitChildren(this);
+    Element dependency = elements[node];
+    if (dependency == null) return;
+    dependencies.add(dependency.implementation);
+  }
+
+  static Set<Element> collect(Element element, Compiler compiler) {
+    TreeElements elements =
+        compiler.enqueuer.resolution.getCachedElements(element);
+    if (elements == null) return new LinkedHashSet<Element>();
+    Node node = element.parseNode(compiler);
+    var collector = new DependencyCollector(elements, compiler);
+    node.accept(collector);
+    collector.dependencies.addAll(elements.otherDependencies);
+    return collector.dependencies;
+  }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/elements/elements.dart b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
index 6432679..3768453 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/elements.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
@@ -486,6 +486,23 @@
   static List<Element> sortedByPosition(Iterable<Element> elements) {
     return elements.toList()..sort(compareByPosition);
   }
+
+  static bool isFixedListConstructorCall(Element element,
+                                         Send node,
+                                         Compiler compiler) {
+    return element == compiler.unnamedListConstructor
+        && node.isCall
+        && !node.arguments.isEmpty
+        && node.arguments.tail.isEmpty;
+  }
+
+  static bool isGrowableListConstructorCall(Element element,
+                                            Send node,
+                                            Compiler compiler) {
+    return element == compiler.unnamedListConstructor
+        && node.isCall
+        && node.arguments.isEmpty;
+  }
 }
 
 abstract class ErroneousElement extends Element implements FunctionElement {
@@ -504,6 +521,8 @@
 // just an interface shared by classes and libraries.
 abstract class ScopeContainerElement {
   Element localLookup(SourceString elementName);
+
+  void forEachLocalMember(f(Element element));
 }
 
 abstract class CompilationUnitElement extends Element {
@@ -572,8 +591,6 @@
   Element findLocal(SourceString elementName);
   void forEachExport(f(Element element));
 
-  void forEachLocalMember(f(Element element));
-
   bool hasLibraryName();
   String getLibraryOrScriptName();
 }
@@ -760,6 +777,7 @@
 
   Element lookupMember(SourceString memberName);
   Element lookupSelector(Selector selector);
+  Element lookupSuperSelector(Selector selector);
 
   Element lookupLocalMember(SourceString memberName);
   Element lookupBackendMember(SourceString memberName);
@@ -787,7 +805,6 @@
                             {includeBackendMembers: false,
                              includeSuperMembers: false});
 
-  void forEachLocalMember(void f(Element member));
   void forEachBackendMember(void f(Element member));
 }
 
diff --git a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
index 42b33e9..cbcb559 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
@@ -1522,10 +1522,18 @@
    * origin and the patch class are returned.
    */
   Element lookupSelector(Selector selector) {
+    return internalLookupSelector(selector, false);
+  }
+
+  Element lookupSuperSelector(Selector selector) {
+    return internalLookupSelector(selector, true);
+  }
+  
+  Element internalLookupSelector(Selector selector, bool isSuperLookup) {
     SourceString name = selector.name;
     bool isPrivate = name.isPrivate();
     LibraryElement library = selector.library;
-    for (ClassElement current = this;
+    for (ClassElement current = isSuperLookup ? superclass : this;
          current != null;
          current = current.superclass) {
       Element member = current.lookupLocalMember(name);
diff --git a/sdk/lib/_internal/compiler/implementation/enqueue.dart b/sdk/lib/_internal/compiler/implementation/enqueue.dart
index 615ffe8..8c351c2 100644
--- a/sdk/lib/_internal/compiler/implementation/enqueue.dart
+++ b/sdk/lib/_internal/compiler/implementation/enqueue.dart
@@ -67,7 +67,8 @@
     // runtime type.
     if (element.isGetter() && element.name == Compiler.RUNTIME_TYPE) {
       compiler.enabledRuntimeType = true;
-      compiler.backend.registerRuntimeType();
+      // TODO(ahe): Record precise dependency here.
+      compiler.backend.registerRuntimeType(compiler.globalDependencies);
     } else if (element == compiler.functionApplyMethod) {
       compiler.enabledFunctionApply = true;
     } else if (element == compiler.invokeOnMethod) {
@@ -86,18 +87,26 @@
   // the work list'?
   bool addElementToWorkList(Element element, [TreeElements elements]);
 
-  void registerInstantiatedType(InterfaceType type) {
+  void registerInstantiatedType(InterfaceType type, TreeElements elements) {
+    ClassElement cls = type.element;
+    elements.registerDependency(cls);
+    cls.ensureResolved(compiler);
     universe.instantiatedTypes.add(type);
-    registerInstantiatedClass(type.element);
-  }
-
-  void registerInstantiatedClass(ClassElement cls) {
     if (universe.instantiatedClasses.contains(cls)) return;
     if (!cls.isAbstract(compiler)) {
       universe.instantiatedClasses.add(cls);
     }
     onRegisterInstantiatedClass(cls);
-    compiler.backend.registerInstantiatedClass(cls, this);
+    // We only tell the backend once that [cls] was instantiated, so
+    // any additional dependencies must be treated as global
+    // dependencies.
+    compiler.backend.registerInstantiatedClass(
+        cls, this, compiler.globalDependencies);
+  }
+
+  void registerInstantiatedClass(ClassElement cls, TreeElements elements) {
+    cls.ensureResolved(compiler);
+    registerInstantiatedType(cls.rawType, elements);
   }
 
   bool checkNoEnqueuedInvokedInstanceMethods() {
@@ -150,7 +159,9 @@
         // We will emit a closure, so make sure the closure class is
         // generated.
         compiler.closureClass.ensureResolved(compiler);
-        registerInstantiatedClass(compiler.closureClass);
+        registerInstantiatedClass(compiler.closureClass,
+                                  // Precise dependency is not important here.
+                                  compiler.globalDependencies);
         return addToWorkList(member);
       }
     } else if (member.kind == ElementKind.GETTER) {
@@ -339,6 +350,16 @@
     selectors.add(selector);
   }
 
+  void registerSelectorUse(Selector selector) {
+    if (selector.isGetter()) {
+      registerInvokedGetter(selector.name, selector);
+    } else if (selector.isSetter()) {
+      registerInvokedSetter(selector.name, selector);
+    } else {
+      registerInvocation(selector.name, selector);
+    }
+  }
+
   void registerDynamicGetter(SourceString methodName, Selector selector) {
     registerInvokedGetter(methodName, selector);
   }
@@ -355,19 +376,19 @@
     universe.fieldSetters.add(element);
   }
 
-  void registerIsCheck(DartType type) {
+  void registerIsCheck(DartType type, TreeElements elements) {
     // Even in checked mode, type annotations for return type and argument
     // types do not imply type checks, so there should never be a check
     // against the type variable of a typedef.
     assert(type.kind != TypeKind.TYPE_VARIABLE ||
            !type.element.enclosingElement.isTypedef());
     universe.isChecks.add(type);
-    compiler.backend.registerIsCheck(type, this);
+    compiler.backend.registerIsCheck(type, this, elements);
   }
 
-  void registerAsCheck(DartType type) {
-    registerIsCheck(type);
-    compiler.backend.registerAsCheck(type);
+  void registerAsCheck(DartType type, TreeElements elements) {
+    registerIsCheck(type, elements);
+    compiler.backend.registerAsCheck(type, elements);
   }
 
   void forEach(f(WorkItem work));
@@ -412,6 +433,9 @@
       element = cls.methodElement;
     }
     Element owner = element.getOutermostEnclosingMemberOrTopLevel();
+    if (owner == null) {
+      owner = element;
+    }
     return resolvedElements[owner.declaration];
   }
 
@@ -467,8 +491,10 @@
 
   void enableIsolateSupport(LibraryElement element) {
     compiler.isolateLibrary = element.patch;
-    addToWorkList(
-        compiler.isolateHelperLibrary.find(Compiler.START_ROOT_ISOLATE));
+    var startRootIsolate =
+        compiler.isolateHelperLibrary.find(Compiler.START_ROOT_ISOLATE);
+    addToWorkList(startRootIsolate);
+    compiler.globalDependencies.registerDependency(startRootIsolate);
     addToWorkList(compiler.isolateHelperLibrary.find(
         const SourceString('_currentIsolate')));
     addToWorkList(compiler.isolateHelperLibrary.find(
diff --git a/sdk/lib/_internal/compiler/implementation/js/builder.dart b/sdk/lib/_internal/compiler/implementation/js/builder.dart
new file mode 100644
index 0000000..2e39690
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/js/builder.dart
@@ -0,0 +1,556 @@
+// 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.
+
+// Utilities for building JS ASTs at runtime.  Contains a builder class
+// and a parser that parses part of the language.
+
+part of js;
+
+class JsBuilder {
+  const JsBuilder();
+
+  Expression operator [](String source) {
+    return new MiniJsParser(source).expression();
+  }
+
+  // TODO(ahe): Remove this method.
+  Binary equals(Expression left, Expression right) {
+    return new Binary('==', left, right);
+  }
+
+  // TODO(ahe): Remove this method.
+  Binary strictEquals(Expression left, Expression right) {
+    return new Binary('===', left, right);
+  }
+
+  LiteralString string(String value) => new LiteralString('"$value"');
+
+  If if_(condition, thenPart, [elsePart]) {
+    condition = toExpression(condition);
+    return (elsePart == null)
+        ? new If.noElse(condition, toStatement(thenPart))
+        : new If(condition, toStatement(thenPart), toStatement(elsePart));
+  }
+
+  Return return_([value]) {
+    return new Return(value == null ? null : toExpression(value));
+  }
+
+  Block block(statement) {
+    if (statement is Block) {
+      return statement;
+    } else if (statement is List) {
+      return new Block(statement.map(toStatement).toList());
+    } else {
+      return new Block(<Statement>[toStatement(statement)]);
+    }
+  }
+
+  Fun fun(parameters, body) {
+    Parameter toParameter(parameter) {
+      if (parameter is String) {
+        return new Parameter(parameter);
+      } else if (parameter is Parameter) {
+        return parameter;
+      } else {
+        throw new ArgumentError('parameter should be a String or a Parameter');
+      }
+    }
+    if (parameters is! List) {
+      parameters = [parameters];
+    }
+    return new Fun(parameters.map(toParameter).toList(), block(body));
+  }
+
+  Assignment assign(Expression leftHandSide, Expression value) {
+    return new Assignment(leftHandSide, value);
+  }
+
+  Expression undefined() => new Prefix('void', new LiteralNumber('0'));
+
+  VariableDeclarationList defineVar(String name, [initializer]) {
+    if (initializer != null) {
+      initializer = toExpression(initializer);
+    }
+    var declaration = new VariableDeclaration(name);
+    var initialization = [new VariableInitialization(declaration, initializer)];
+    return new VariableDeclarationList(initialization);
+  }
+
+  Statement toStatement(statement) {
+    if (statement is List) {
+      return new Block(statement.map(toStatement).toList());
+    } else if (statement is Node) {
+      return statement.toStatement();
+    } else {
+      throw new ArgumentError('statement');
+    }
+  }
+
+  Expression toExpression(expression) {
+    if (expression is Expression) {
+      return expression;
+    } else if (expression is String) {
+      return this[expression];
+    } else if (expression is num) {
+      return new LiteralNumber('$expression');
+    } else if (expression is bool) {
+      return new LiteralBool(expression);
+    } else if (expression is Map) {
+      if (!expression.isEmpty) {
+        throw new ArgumentError('expression should be an empty Map');
+      }
+      return new ObjectInitializer([]);
+    } else {
+      throw new ArgumentError('expression should be an Expression, '
+                              'a String, a num, a bool, or a Map');
+    }
+  }
+
+  ForIn forIn(String name, object, statement) {
+    return new ForIn(defineVar(name),
+                     toExpression(object),
+                     toStatement(statement));
+  }
+
+  For for_(init, condition, update, statement) {
+    return new For(
+        toExpression(init), toExpression(condition), toExpression(update),
+        toStatement(statement));
+  }
+
+  While while_(condition, statement) {
+    return new While(
+        toExpression(condition), toStatement(statement));
+  }
+
+  Try try_(body, {catchPart, finallyPart}) {
+    if (catchPart != null) catchPart = toStatement(catchPart);
+    if (finallyPart != null) finallyPart = toStatement(finallyPart);
+    return new Try(toStatement(body), catchPart, finallyPart);
+  }
+
+  Comment comment(String text) => new Comment(text);
+}
+
+const JsBuilder js = const JsBuilder();
+
+LiteralString string(String value) => js.string(value);
+
+class MiniJsParserError {
+  MiniJsParserError(this.parser, this.message) { }
+
+  MiniJsParser parser;
+  String message;
+
+  String toString() {
+    var codes = new List.filled(parser.lastPosition, charCodes.$SPACE);
+    var spaces = new String.fromCharCodes(codes);
+    return "Error in MiniJsParser:\n${parser.src}\n$spaces^\n$spaces$message\n";
+  }
+}
+
+/// Mini JavaScript parser for tiny snippets of code that we want to make into
+/// AST nodes.  Handles:
+/// * identifiers.
+/// * dot access.
+/// * method calls.
+/// * [] access.
+/// * array, string, boolean, null and numeric literals (no hex).
+/// * most operators.
+/// * brackets.
+/// * var declarations.
+/// Notable things it can't do yet include:
+/// * operator precedence.
+/// * non-empty object literals.
+/// * throw, return.
+/// * statements, including any flow control (if, while, for, etc.)
+/// * the 'in' keyword.
+///
+/// It's a fairly standard recursive descent parser.
+///
+/// Literal strings are passed through to the final JS source code unchanged,
+/// including the choice of surrounding quotes, so if you parse
+/// r'var x = "foo\n\"bar\""' you will end up with
+///   var x = "foo\n\"bar\"" in the final program.  String literals are
+/// restricted to a small subset of the full set of allowed JS escapes in order
+/// to get early errors for unintentional escape sequences without complicating
+/// this parser unneccessarily.
+class MiniJsParser {
+  MiniJsParser(this.src)
+      : lastCategory = NONE,
+        lastToken = null,
+        lastPosition = 0,
+        position = 0 {
+    getSymbol();
+  }
+
+  int lastCategory;
+  String lastToken;
+  int lastPosition;
+  int position;
+  String src;
+
+  static const NONE = -1;
+  static const ALPHA = 0;
+  static const NUMERIC = 1;
+  static const STRING = 2;
+  static const SYMBOL = 3;
+  static const RELATION = 4;
+  static const DOT = 5;
+  static const LPAREN = 6;
+  static const RPAREN = 7;
+  static const LBRACE = 8;
+  static const RBRACE = 9;
+  static const LSQUARE = 10;
+  static const RSQUARE = 11;
+  static const COMMA = 12;
+  static const QUERY = 13;
+  static const COLON = 14;
+  static const OTHER = 15;
+
+  // Make sure that ]] is two symbols.
+  bool singleCharCategory(int category) => category >= DOT;
+
+  static String categoryToString(int cat) {
+    switch (cat) {
+      case NONE: return "NONE";
+      case ALPHA: return "ALPHA";
+      case NUMERIC: return "NUMERIC";
+      case SYMBOL: return "SYMBOL";
+      case RELATION: return "RELATION";
+      case DOT: return "DOT";
+      case LPAREN: return "LPAREN";
+      case RPAREN: return "RPAREN";
+      case LBRACE: return "LBRACE";
+      case RBRACE: return "RBRACE";
+      case RSQUARE: return "RSQUARE";
+      case STRING: return "STRING";
+      case COMMA: return "COMMA";
+      case QUERY: return "QUERY";
+      case COLON: return "COLON";
+      case OTHER: return "OTHER";
+    }
+    return "Unknown: $cat";
+  }
+
+  static const CATEGORIES = const <int>[
+      OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,       // 0-7
+      OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,       // 8-15
+      OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,       // 16-23
+      OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,       // 24-31
+      OTHER, RELATION, OTHER, OTHER, ALPHA, SYMBOL, SYMBOL, OTHER,  //  !"#$%&´
+      LPAREN, RPAREN, SYMBOL, SYMBOL, COMMA, SYMBOL, DOT, SYMBOL,   // ()*+,-./
+      NUMERIC, NUMERIC, NUMERIC, NUMERIC, NUMERIC,                  // 01234
+      NUMERIC, NUMERIC, NUMERIC, NUMERIC, NUMERIC,                  // 56789
+      COLON, OTHER, RELATION, RELATION, RELATION, QUERY, OTHER,     // :;<=>?@
+      ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,       // ABCDEFGH
+      ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,       // IJKLMNOP
+      ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,       // QRSTUVWX
+      ALPHA, ALPHA, LSQUARE, OTHER, RSQUARE, SYMBOL, ALPHA, OTHER,  // YZ[\]^_'
+      ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,       // abcdefgh
+      ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,       // ijklmnop
+      ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,       // qrstuvwx
+      ALPHA, ALPHA, LBRACE, SYMBOL, RBRACE, SYMBOL];                // yz{|}~
+
+  static final BINARY_OPERATORS = [
+      '+', '-', '*', '/', '%', '^', '|', '&', '||', '&&', '<<', '>>', '>>>',
+      '+=', '-=', '*=', '/=', '%=', '^=', '|=', '&=', '<<=', '>>=', '>>>=',
+      '=', '!=', '==', '!==', '===', '<', '<=', '>=', '>'].toSet();
+  static final UNARY_OPERATORS = ['++', '--', '+', '-', '~', '!'].toSet();
+
+  // For sanity we only allow \\, \', \" and \n in string literals.
+  static final STRING_LITERAL_PATTERN =
+      new RegExp('^[\'"](?:[^\\\\]|\\\\[\\\\n\'"])*[\'"]\$');
+
+  static int category(int code) {
+    if (code >= CATEGORIES.length) return OTHER;
+    return CATEGORIES[code];
+  }
+
+  void getSymbol() {
+    while (position < src.length &&
+           src.codeUnitAt(position) == charCodes.$SPACE) {
+      position++;
+    }
+    if (position == src.length) {
+      lastCategory = NONE;
+      lastToken = null;
+      lastPosition = position;
+      return;
+    }
+    int code = src.codeUnitAt(position);
+    lastPosition = position;
+    if (code == charCodes.$SQ || code == charCodes.$DQ) {
+      int currentCode;
+      do {
+        position++;
+        if (position >= src.length) {
+          throw new MiniJsParserError(this, "Unterminated string");
+        }
+        currentCode = src.codeUnitAt(position);
+        if (currentCode == charCodes.$BACKSLASH) {
+          if (++position >= src.length) {
+            throw new MiniJsParserError(this, "Unterminated string");
+          }
+        }
+      } while (currentCode != code);
+      lastCategory = STRING;
+      position++;
+      lastToken = src.substring(lastPosition, position);
+      if (!STRING_LITERAL_PATTERN.hasMatch(lastToken)) {
+        throw new MiniJsParserError(
+            this,
+            "Only escapes allowed in string literals are \\, \', \" and \n");
+      }
+    } else {
+      int cat = category(src.codeUnitAt(position));
+      int newCat;
+      do {
+        position++;
+        if (position == src.length) break;
+        newCat = category(src.codeUnitAt(position));
+      } while (!singleCharCategory(cat) &&
+               (cat == newCat ||
+                (cat == ALPHA && newCat == NUMERIC) ||    // eg. level42.
+                (cat == NUMERIC && newCat == DOT) ||      // eg. 3.1415
+                (cat == SYMBOL && newCat == RELATION)));  // eg. +=.
+      lastCategory = cat;
+      lastToken = src.substring(lastPosition, position);
+      if (cat == NUMERIC) {
+        double.parse(lastToken, (_) {
+          throw new MiniJsParserError(this, "Unparseable number");
+        });
+      } else if (cat == SYMBOL || cat == RELATION) {
+        if (!BINARY_OPERATORS.contains(lastToken) &&
+            !UNARY_OPERATORS.contains(lastToken)) {
+          throw new MiniJsParserError(this, "Unknown operator");
+        }
+      }
+    }
+  }
+
+  void expectCategory(int cat) {
+    if (cat != lastCategory) {
+      throw new MiniJsParserError(this, "Expected ${categoryToString(cat)}");
+    }
+    getSymbol();
+  }
+
+  bool acceptCategory(int cat) {
+    if (cat == lastCategory) {
+      getSymbol();
+      return true;
+    }
+    return false;
+  }
+
+  bool acceptString(String string) {
+    if (lastToken == string) {
+      getSymbol();
+      return true;
+    }
+    return false;
+  }
+
+  Expression parsePrimary() {
+    String last = lastToken;
+    if (acceptCategory(ALPHA)) {
+      if (last == "true") {
+        return new LiteralBool(true);
+      } else if (last == "false") {
+        return new LiteralBool(false);
+      } else if (last == "null") {
+        return new LiteralNull();
+      } else {
+        return new VariableUse(last);
+      }
+    } else if (acceptCategory(LPAREN)) {
+      Expression expression = parseExpression();
+      expectCategory(RPAREN);
+      return expression;
+    } else if (acceptCategory(STRING)) {
+      return new LiteralString(last);
+    } else if (acceptCategory(NUMERIC)) {
+      return new LiteralNumber(last);
+    } else if (acceptCategory(LBRACE)) {
+      expectCategory(RBRACE);
+      return new ObjectInitializer([]);
+    } else if (acceptCategory(LSQUARE)) {
+      var values = <ArrayElement>[];
+      if (!acceptCategory(RSQUARE)) {
+        do {
+          values.add(new ArrayElement(values.length, parseExpression()));
+        } while (acceptCategory(COMMA));
+        expectCategory(RSQUARE);
+      }
+      return new ArrayInitializer(values.length, values);
+    } else {
+      throw new MiniJsParserError(this, "Expected primary expression");
+    }
+  }
+
+  Expression parseMember() {
+    Expression receiver = parsePrimary();
+    while (true) {
+      if (acceptCategory(DOT)) {
+        String identifier = lastToken;
+        expectCategory(ALPHA);
+        receiver = new PropertyAccess.field(receiver, identifier);
+      } else if (acceptCategory(LSQUARE)) {
+        Expression inBraces = parseExpression();
+        expectCategory(RSQUARE);
+        receiver = new PropertyAccess(receiver, inBraces);
+      } else {
+        return receiver;
+      }
+    }
+  }
+
+  Expression parseCall() {
+    bool constructor = acceptString("new");
+    Expression receiver = parseMember();
+    if (acceptCategory(LPAREN)) {
+      final arguments = <Expression>[];
+      if (!acceptCategory(RPAREN)) {
+        while (true) {
+          Expression argument = parseExpression();
+          arguments.add(argument);
+          if (acceptCategory(RPAREN)) break;
+          expectCategory(COMMA);
+        }
+      }
+      return constructor ?
+             new New(receiver, arguments) :
+             new Call(receiver, arguments);
+    } else {
+      if (constructor) {
+        // JS allows new without (), but we don't.
+        throw new MiniJsParserError(this, "Parentheses are required for new");
+      }
+      return receiver;
+    }
+  }
+
+  Expression parsePostfix() {
+    Expression expression = parseCall();
+    String operator = lastToken;
+    if (lastCategory == SYMBOL && (acceptString("++") || acceptString("--"))) {
+      return new Postfix(operator, expression);
+    }
+    return expression;
+  }
+
+  Expression parseUnary() {
+    String operator = lastToken;
+    if (lastCategory == ALPHA) {
+     if (acceptString("typeof") || acceptString("void") ||
+         acceptString("delete")) {
+        return new Prefix(operator, parsePostfix());
+     }
+    } else if (lastCategory == SYMBOL) {
+      if (acceptString("~") || acceptString("-") || acceptString("++") ||
+          acceptString("--") || acceptString("+")) {
+        return new Prefix(operator, parsePostfix());
+      }
+    } else if (acceptString("!")) {
+      return new Prefix(operator, parsePostfix());
+    }
+    return parsePostfix();
+  }
+
+  Expression parseBinary() {
+    // Since we don't handle precedence we don't allow two different symbols
+    // without parentheses.
+    Expression lhs = parseUnary();
+    String firstSymbol = lastToken;
+    while (true) {
+      String symbol = lastToken;
+      if (!acceptCategory(SYMBOL)) return lhs;
+      if (!BINARY_OPERATORS.contains(symbol)) {
+        throw new MiniJsParserError(this, "Unknown binary operator");
+      }
+      if (symbol != firstSymbol) {
+        throw new MiniJsParserError(
+            this, "Mixed $firstSymbol and $symbol operators without ()");
+      }
+      Expression rhs = parseUnary();
+      if (symbol.endsWith("=")) {
+        // +=, -=, *= etc.
+        lhs = new Assignment.compound(lhs,
+                                      symbol.substring(0, symbol.length - 1),
+                                      rhs);
+      } else {
+        lhs = new Binary(symbol, lhs, rhs);
+      }
+    }
+  }
+
+  Expression parseRelation() {
+    Expression lhs = parseBinary();
+    String relation = lastToken;
+    // The lexer returns "=" as a relational operator because it looks a bit
+    // like ==, <=, etc.  But we don't want to handle it here (that would give
+    // it the wrong prescedence), so we just return if we see it.
+    if (relation == "=" || !acceptCategory(RELATION)) return lhs;
+    Expression rhs = parseBinary();
+    if (relation == "<<=" || relation == ">>=" || relation == ">>>=") {
+      return new Assignment.compound(lhs,
+                                     relation.substring(0, relation.length - 1),
+                                     rhs);
+    } else {
+      // Regular binary operation.
+      return new Binary(relation, lhs, rhs);
+    }
+  }
+
+  Expression parseConditional() {
+    Expression lhs = parseRelation();
+    if (!acceptCategory(QUERY)) return lhs;
+    Expression ifTrue = parseAssignment();
+    expectCategory(COLON);
+    Expression ifFalse = parseAssignment();
+    return new Conditional(lhs, ifTrue, ifFalse);
+  }
+
+
+  Expression parseAssignment() {
+    Expression lhs = parseConditional();
+    if (acceptString("=")) {
+      return new Assignment(lhs, parseAssignment());
+    }
+    return lhs;
+  }
+
+  Expression parseExpression() => parseAssignment();
+
+  Expression parseVarDeclarationOrExpression() {
+    if (acceptString("var")) {
+      var initialization = [];
+      do {
+        String variable = lastToken;
+        expectCategory(ALPHA);
+        Expression initializer = null;
+        if (acceptString("=")) {
+          initializer = parseExpression();
+        }
+        var declaration = new VariableDeclaration(variable);
+        initialization.add(
+            new VariableInitialization(declaration, initializer));
+      } while (acceptCategory(COMMA));
+      return new VariableDeclarationList(initialization);
+    } else {
+      return parseExpression();
+    }
+  }
+
+  Expression expression() {
+    Expression expression = parseVarDeclarationOrExpression();
+    if (lastCategory != NONE || position != src.length) {
+      throw new MiniJsParserError(
+          this, "Unparsed junk: ${categoryToString(lastCategory)}");
+    }
+    return expression;
+  }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/js/js.dart b/sdk/lib/_internal/compiler/implementation/js/js.dart
index b7df642..f8a2f61 100644
--- a/sdk/lib/_internal/compiler/implementation/js/js.dart
+++ b/sdk/lib/_internal/compiler/implementation/js/js.dart
@@ -12,4 +12,5 @@
 import '../dart2jslib.dart' as leg;
 
 part 'nodes.dart';
+part 'builder.dart';
 part 'printer.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/js/nodes.dart b/sdk/lib/_internal/compiler/implementation/js/nodes.dart
index fe89432..6f0b755 100644
--- a/sdk/lib/_internal/compiler/implementation/js/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/js/nodes.dart
@@ -947,546 +947,3 @@
 
   void visitChildren(NodeVisitor visitor) {}
 }
-
-class JsBuilder {
-  const JsBuilder();
-
-  Expression operator [](String source) {
-    return new MiniJsParser(source).expression();
-  }
-
-  // TODO(ahe): Remove this method.
-  Binary equals(Expression left, Expression right) {
-    return new Binary('==', left, right);
-  }
-
-  // TODO(ahe): Remove this method.
-  Binary strictEquals(Expression left, Expression right) {
-    return new Binary('===', left, right);
-  }
-
-  LiteralString string(String value) => new LiteralString('"$value"');
-
-  If if_(condition, thenPart, [elsePart]) {
-    condition = toExpression(condition);
-    return (elsePart == null)
-        ? new If.noElse(condition, toStatement(thenPart))
-        : new If(condition, toStatement(thenPart), toStatement(elsePart));
-  }
-
-  Return return_([value]) {
-    return new Return(value == null ? null : toExpression(value));
-  }
-
-  Block block(statement) {
-    if (statement is Block) {
-      return statement;
-    } else if (statement is List) {
-      return new Block(statement.map(toStatement).toList());
-    } else {
-      return new Block(<Statement>[toStatement(statement)]);
-    }
-  }
-
-  Fun fun(parameters, body) {
-    Parameter toParameter(parameter) {
-      if (parameter is String) {
-        return new Parameter(parameter);
-      } else if (parameter is Parameter) {
-        return parameter;
-      } else {
-        throw new ArgumentError('parameter should be a String or a Parameter');
-      }
-    }
-    if (parameters is! List) {
-      parameters = [parameters];
-    }
-    return new Fun(parameters.map(toParameter).toList(), block(body));
-  }
-
-  Assignment assign(Expression leftHandSide, Expression value) {
-    return new Assignment(leftHandSide, value);
-  }
-
-  Expression undefined() => new Prefix('void', new LiteralNumber('0'));
-
-  VariableDeclarationList defineVar(String name, [initializer]) {
-    if (initializer != null) {
-      initializer = toExpression(initializer);
-    }
-    var declaration = new VariableDeclaration(name);
-    var initialization = [new VariableInitialization(declaration, initializer)];
-    return new VariableDeclarationList(initialization);
-  }
-
-  Statement toStatement(statement) {
-    if (statement is List) {
-      return new Block(statement.map(toStatement).toList());
-    } else if (statement is Node) {
-      return statement.toStatement();
-    } else {
-      throw new ArgumentError('statement');
-    }
-  }
-
-  Expression toExpression(expression) {
-    if (expression is Expression) {
-      return expression;
-    } else if (expression is String) {
-      return this[expression];
-    } else if (expression is num) {
-      return new LiteralNumber('$expression');
-    } else if (expression is bool) {
-      return new LiteralBool(expression);
-    } else if (expression is Map) {
-      if (!expression.isEmpty) {
-        throw new ArgumentError('expression should be an empty Map');
-      }
-      return new ObjectInitializer([]);
-    } else {
-      throw new ArgumentError('expression should be an Expression, '
-                              'a String, a num, a bool, or a Map');
-    }
-  }
-
-  ForIn forIn(String name, object, statement) {
-    return new ForIn(defineVar(name),
-                     toExpression(object),
-                     toStatement(statement));
-  }
-
-  For for_(init, condition, update, statement) {
-    return new For(
-        toExpression(init), toExpression(condition), toExpression(update),
-        toStatement(statement));
-  }
-
-  Try try_(body, {catchPart, finallyPart}) {
-    if (catchPart != null) catchPart = toStatement(catchPart);
-    if (finallyPart != null) finallyPart = toStatement(finallyPart);
-    return new Try(toStatement(body), catchPart, finallyPart);
-  }
-
-  Comment comment(String text) => new Comment(text);
-}
-
-const JsBuilder js = const JsBuilder();
-
-LiteralString string(String value) => js.string(value);
-
-class MiniJsParserError {
-  MiniJsParserError(this.parser, this.message) { }
-
-  MiniJsParser parser;
-  String message;
-
-  String toString() {
-    var codes = new List.filled(parser.lastPosition, charCodes.$SPACE);
-    var spaces = new String.fromCharCodes(codes);
-    return "Error in MiniJsParser:\n${parser.src}\n$spaces^\n$spaces$message\n";
-  }
-}
-
-/// Mini JavaScript parser for tiny snippets of code that we want to make into
-/// AST nodes.  Handles:
-/// * identifiers.
-/// * dot access.
-/// * method calls.
-/// * [] access.
-/// * array, string, boolean, null and numeric literals (no hex).
-/// * most operators.
-/// * brackets.
-/// * var declarations.
-/// Notable things it can't do yet include:
-/// * operator precedence.
-/// * non-empty object literals.
-/// * throw, return.
-/// * statements, including any flow control (if, while, for, etc.)
-/// * the 'in' keyword.
-///
-/// It's a fairly standard recursive descent parser.
-///
-/// Literal strings are passed through to the final JS source code unchanged,
-/// including the choice of surrounding quotes, so if you parse
-/// r'var x = "foo\n\"bar\""' you will end up with
-///   var x = "foo\n\"bar\"" in the final program.  String literals are
-/// restricted to a small subset of the full set of allowed JS escapes in order
-/// to get early errors for unintentional escape sequences without complicating
-/// this parser unneccessarily.
-class MiniJsParser {
-  MiniJsParser(this.src)
-      : lastCategory = NONE,
-        lastToken = null,
-        lastPosition = 0,
-        position = 0 {
-    getSymbol();
-  }
-
-  int lastCategory;
-  String lastToken;
-  int lastPosition;
-  int position;
-  String src;
-
-  static const NONE = -1;
-  static const ALPHA = 0;
-  static const NUMERIC = 1;
-  static const STRING = 2;
-  static const SYMBOL = 3;
-  static const RELATION = 4;
-  static const DOT = 5;
-  static const LPAREN = 6;
-  static const RPAREN = 7;
-  static const LBRACE = 8;
-  static const RBRACE = 9;
-  static const LSQUARE = 10;
-  static const RSQUARE = 11;
-  static const COMMA = 12;
-  static const QUERY = 13;
-  static const COLON = 14;
-  static const OTHER = 15;
-
-  // Make sure that ]] is two symbols.
-  bool singleCharCategory(int category) => category >= DOT;
-
-  static String categoryToString(int cat) {
-    switch (cat) {
-      case NONE: return "NONE";
-      case ALPHA: return "ALPHA";
-      case NUMERIC: return "NUMERIC";
-      case SYMBOL: return "SYMBOL";
-      case RELATION: return "RELATION";
-      case DOT: return "DOT";
-      case LPAREN: return "LPAREN";
-      case RPAREN: return "RPAREN";
-      case LBRACE: return "LBRACE";
-      case RBRACE: return "RBRACE";
-      case RSQUARE: return "RSQUARE";
-      case STRING: return "STRING";
-      case COMMA: return "COMMA";
-      case QUERY: return "QUERY";
-      case COLON: return "COLON";
-      case OTHER: return "OTHER";
-    }
-    return "Unknown: $cat";
-  }
-
-  static const CATEGORIES = const <int>[
-      OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,       // 0-7
-      OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,       // 8-15
-      OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,       // 16-23
-      OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,       // 24-31
-      OTHER, RELATION, OTHER, OTHER, ALPHA, SYMBOL, SYMBOL, OTHER,  //  !"#$%&´
-      LPAREN, RPAREN, SYMBOL, SYMBOL, COMMA, SYMBOL, DOT, SYMBOL,   // ()*+,-./
-      NUMERIC, NUMERIC, NUMERIC, NUMERIC, NUMERIC,                  // 01234
-      NUMERIC, NUMERIC, NUMERIC, NUMERIC, NUMERIC,                  // 56789
-      COLON, OTHER, RELATION, RELATION, RELATION, QUERY, OTHER,     // :;<=>?@
-      ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,       // ABCDEFGH
-      ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,       // IJKLMNOP
-      ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,       // QRSTUVWX
-      ALPHA, ALPHA, LSQUARE, OTHER, RSQUARE, SYMBOL, ALPHA, OTHER,  // YZ[\]^_'
-      ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,       // abcdefgh
-      ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,       // ijklmnop
-      ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,       // qrstuvwx
-      ALPHA, ALPHA, LBRACE, SYMBOL, RBRACE, SYMBOL];                // yz{|}~
-
-  static final BINARY_OPERATORS = [
-      '+', '-', '*', '/', '%', '^', '|', '&', '||', '&&',
-      '<<', '>>', '+=', '-=', '*=', '/=', '^=', '|=', '&=', '<<=', '>>=',
-      '=', '!=', '==', '!==', '===', '<', '<=', '>=', '>'].toSet();
-  static final UNARY_OPERATORS = ['++', '--', '+', '-', '~', '!'].toSet();
-
-  // For sanity we only allow \\, \', \" and \n in string literals.
-  static final STRING_LITERAL_PATTERN =
-      new RegExp('^[\'"](?:[^\\\\]|\\\\[\\\\n\'"])*[\'"]\$');
-
-  static int category(int code) {
-    if (code >= CATEGORIES.length) return OTHER;
-    return CATEGORIES[code];
-  }
-
-  void getSymbol() {
-    while (position < src.length &&
-           src.codeUnitAt(position) == charCodes.$SPACE) {
-      position++;
-    }
-    if (position == src.length) {
-      lastCategory = NONE;
-      lastToken = null;
-      lastPosition = position;
-      return;
-    }
-    int code = src.codeUnitAt(position);
-    lastPosition = position;
-    if (code == charCodes.$SQ || code == charCodes.$DQ) {
-      int currentCode;
-      do {
-        position++;
-        if (position >= src.length) {
-          throw new MiniJsParserError(this, "Unterminated string");
-        }
-        currentCode = src.codeUnitAt(position);
-        if (currentCode == charCodes.$BACKSLASH) {
-          if (++position >= src.length) {
-            throw new MiniJsParserError(this, "Unterminated string");
-          }
-        }
-      } while (currentCode != code);
-      lastCategory = STRING;
-      position++;
-      lastToken = src.substring(lastPosition, position);
-      if (!STRING_LITERAL_PATTERN.hasMatch(lastToken)) {
-        throw new MiniJsParserError(
-            this,
-            "Only escapes allowed in string literals are \\, \', \" and \n");
-      }
-    } else {
-      int cat = category(src.codeUnitAt(position));
-      int newCat;
-      do {
-        position++;
-        if (position == src.length) break;
-        newCat = category(src.codeUnitAt(position));
-      } while (!singleCharCategory(cat) &&
-               (cat == newCat ||
-                (cat == ALPHA && newCat == NUMERIC) ||    // eg. level42.
-                (cat == NUMERIC && newCat == DOT) ||      // eg. 3.1415
-                (cat == SYMBOL && newCat == RELATION)));  // eg. +=.
-      lastCategory = cat;
-      lastToken = src.substring(lastPosition, position);
-      if (cat == NUMERIC) {
-        double.parse(lastToken, (_) {
-          throw new MiniJsParserError(this, "Unparseable number");
-        });
-      } else if (cat == SYMBOL || cat == RELATION) {
-        if (!BINARY_OPERATORS.contains(lastToken) &&
-            !UNARY_OPERATORS.contains(lastToken)) {
-          throw new MiniJsParserError(this, "Unknown operator");
-        }
-      }
-    }
-  }
-
-  void expectCategory(int cat) {
-    if (cat != lastCategory) {
-      throw new MiniJsParserError(this, "Expected ${categoryToString(cat)}");
-    }
-    getSymbol();
-  }
-
-  bool acceptCategory(int cat) {
-    if (cat == lastCategory) {
-      getSymbol();
-      return true;
-    }
-    return false;
-  }
-
-  bool acceptString(String string) {
-    if (lastToken == string) {
-      getSymbol();
-      return true;
-    }
-    return false;
-  }
-
-  Expression parsePrimary() {
-    String last = lastToken;
-    if (acceptCategory(ALPHA)) {
-      if (last == "true") {
-        return new LiteralBool(true);
-      } else if (last == "false") {
-        return new LiteralBool(false);
-      } else if (last == "null") {
-        return new LiteralNull();
-      } else {
-        return new VariableUse(last);
-      }
-    } else if (acceptCategory(LPAREN)) {
-      Expression expression = parseExpression();
-      expectCategory(RPAREN);
-      return expression;
-    } else if (acceptCategory(STRING)) {
-      return new LiteralString(last);
-    } else if (acceptCategory(NUMERIC)) {
-      return new LiteralNumber(last);
-    } else if (acceptCategory(LBRACE)) {
-      expectCategory(RBRACE);
-      return new ObjectInitializer([]);
-    } else if (acceptCategory(LSQUARE)) {
-      var values = <ArrayElement>[];
-      if (!acceptCategory(RSQUARE)) {
-        do {
-          values.add(new ArrayElement(values.length, parseExpression()));
-        } while (acceptCategory(COMMA));
-        expectCategory(RSQUARE);
-      }
-      return new ArrayInitializer(values.length, values);
-    } else {
-      throw new MiniJsParserError(this, "Expected primary expression");
-    }
-  }
-
-  Expression parseMember() {
-    Expression receiver = parsePrimary();
-    while (true) {
-      if (acceptCategory(DOT)) {
-        String identifier = lastToken;
-        expectCategory(ALPHA);
-        receiver = new PropertyAccess.field(receiver, identifier);
-      } else if (acceptCategory(LSQUARE)) {
-        Expression inBraces = parseExpression();
-        expectCategory(RSQUARE);
-        receiver = new PropertyAccess(receiver, inBraces);
-      } else {
-        return receiver;
-      }
-    }
-  }
-
-  Expression parseCall() {
-    bool constructor = acceptString("new");
-    Expression receiver = parseMember();
-    if (acceptCategory(LPAREN)) {
-      final arguments = <Expression>[];
-      if (!acceptCategory(RPAREN)) {
-        while (true) {
-          Expression argument = parseExpression();
-          arguments.add(argument);
-          if (acceptCategory(RPAREN)) break;
-          expectCategory(COMMA);
-        }
-      }
-      return constructor ?
-             new New(receiver, arguments) :
-             new Call(receiver, arguments);
-    } else {
-      if (constructor) {
-        // JS allows new without (), but we don't.
-        throw new MiniJsParserError(this, "Parentheses are required for new");
-      }
-      return receiver;
-    }
-  }
-
-  Expression parsePostfix() {
-    Expression expression = parseCall();
-    String operator = lastToken;
-    if (lastCategory == SYMBOL && (acceptString("++") || acceptString("--"))) {
-      return new Postfix(operator, expression);
-    }
-    return expression;
-  }
-
-  Expression parseUnary() {
-    String operator = lastToken;
-    if (lastCategory == ALPHA) {
-     if (acceptString("typeof") || acceptString("void") ||
-         acceptString("delete")) {
-        return new Prefix(operator, parsePostfix());
-     }
-    } else if (lastCategory == SYMBOL) {
-      if (acceptString("~") || acceptString("-") || acceptString("++") ||
-          acceptString("--") || acceptString("+")) {
-        return new Prefix(operator, parsePostfix());
-      }
-    } else if (acceptString("!")) {
-      return new Prefix(operator, parsePostfix());
-    }
-    return parsePostfix();
-  }
-
-  Expression parseBinary() {
-    // Since we don't handle precedence we don't allow two different symbols
-    // without parentheses.
-    Expression lhs = parseUnary();
-    String firstSymbol = lastToken;
-    while (true) {
-      String symbol = lastToken;
-      if (!acceptCategory(SYMBOL)) return lhs;
-      if (!BINARY_OPERATORS.contains(symbol)) {
-        throw new MiniJsParserError(this, "Unknown binary operator");
-      }
-      if (symbol != firstSymbol) {
-        throw new MiniJsParserError(
-            this, "Mixed $firstSymbol and $symbol operators without ()");
-      }
-      Expression rhs = parseUnary();
-      if (symbol.endsWith("=")) {
-        // +=, -=, *= etc.
-        lhs = new Assignment.compound(lhs,
-                                      symbol.substring(0, symbol.length - 1),
-                                      rhs);
-      } else {
-        lhs = new Binary(symbol, lhs, rhs);
-      }
-    }
-  }
-
-  Expression parseRelation() {
-    Expression lhs = parseBinary();
-    String relation = lastToken;
-    // The lexer returns "=" as a relational operator because it looks a bit
-    // like ==, <=, etc.  But we don't want to handle it here (that would give
-    // it the wrong prescedence), so we just return if we see it.
-    if (relation == "=" || !acceptCategory(RELATION)) return lhs;
-    Expression rhs = parseBinary();
-    if (relation == "<<=" || relation == ">>=") {
-      return new Assignment.compound(lhs,
-                                     relation.substring(0, relation.length - 1),
-                                     rhs);
-    } else {
-      // Regular binary operation.
-      return new Binary(relation, lhs, rhs);
-    }
-  }
-
-  Expression parseConditional() {
-    Expression lhs = parseRelation();
-    if (!acceptCategory(QUERY)) return lhs;
-    Expression ifTrue = parseAssignment();
-    expectCategory(COLON);
-    Expression ifFalse = parseAssignment();
-    return new Conditional(lhs, ifTrue, ifFalse);
-  }
-
-
-  Expression parseAssignment() {
-    Expression lhs = parseConditional();
-    if (acceptString("=")) {
-      return new Assignment(lhs, parseAssignment());
-    }
-    return lhs;
-  }
-
-  Expression parseExpression() => parseAssignment();
-
-  Expression parseVarDeclarationOrExpression() {
-    if (acceptString("var")) {
-      var initialization = [];
-      do {
-        String variable = lastToken;
-        expectCategory(ALPHA);
-        Expression initializer = null;
-        if (acceptString("=")) {
-          initializer = parseExpression();
-        }
-        var declaration = new VariableDeclaration(variable);
-        initialization.add(
-            new VariableInitialization(declaration, initializer));
-      } while (acceptCategory(COMMA));
-      return new VariableDeclarationList(initialization);
-    } else {
-      return parseExpression();
-    }
-  }
-
-  Expression expression() {
-    Expression expression = parseVarDeclarationOrExpression();
-    if (lastCategory != NONE || position != src.length) {
-      throw new MiniJsParserError(
-          this, "Unparsed junk: ${categoryToString(lastCategory)}");
-    }
-    return expression;
-  }
-}
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
index 50433d4..4de74d2 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
@@ -642,6 +642,12 @@
   ClassElement jsFunctionClass;
   ClassElement jsNullClass;
   ClassElement jsBoolClass;
+
+  ClassElement jsIndexableClass;
+  ClassElement jsMutableArrayClass;
+  ClassElement jsFixedArrayClass;
+  ClassElement jsExtendableArrayClass;
+
   Element jsArrayLength;
   Element jsStringLength;
   Element jsArrayRemoveLast;
@@ -649,9 +655,14 @@
   Element jsStringSplit;
   Element jsStringConcat;
   Element jsStringToString;
+
+  ClassElement typeLiteralClass;
+  ClassElement mapLiteralClass;
+  ClassElement constMapLiteralClass;
+
   Element getInterceptorMethod;
   Element interceptedNames;
-  Element fixedLengthListConstructor;
+
   bool seenAnyClass = false;
 
   final Namer namer;
@@ -688,11 +699,16 @@
   final Map<String, Selector> oneShotInterceptors;
 
   /**
-   * The members of instantiated interceptor classes: maps a member
-   * name to the list of members that have that name. This map is used
-   * by the codegen to know whether a send must be intercepted or not.
+   * The members of instantiated interceptor classes: maps a member name to the
+   * list of members that have that name. This map is used by the codegen to
+   * know whether a send must be intercepted or not.
    */
   final Map<SourceString, Set<Element>> interceptedElements;
+  // TODO(sra): Not all methods in the Set always require an interceptor.  A
+  // method may be mixed into a true interceptor *and* a plain class. For the
+  // method to work on the interceptor class it needs to use the explicit
+  // receiver.  This constrains the call on a known plain receiver to pass the
+  // explicit receiver.  https://code.google.com/p/dart/issues/detail?id=8942
 
   /**
    * A map of specialized versions of the [getInterceptorMethod].
@@ -710,6 +726,11 @@
   final Set<ClassElement> interceptedClasses;
 
   /**
+   * Set of classes whose `operator ==` methods handle `null` themselves.
+   */
+  final Set<ClassElement> specialOperatorEqClasses = new Set<ClassElement>();
+
+  /**
    * Set of selectors that are used from within loops. Used by the
    * builder to allow speculative optimizations for functions without
    * loops themselves.
@@ -721,7 +742,7 @@
     return <CompilerTask>[builder, optimizer, generator, emitter];
   }
 
-  final RuntimeTypeInformation rti;
+  final RuntimeTypes rti;
 
   JavaScriptBackend(Compiler compiler, bool generateSourceMap, bool disableEval)
       : namer = determineNamer(compiler),
@@ -730,7 +751,7 @@
         usedInterceptors = new Set<Selector>(),
         oneShotInterceptors = new Map<String, Selector>(),
         interceptedElements = new Map<SourceString, Set<Element>>(),
-        rti = new RuntimeTypeInformation(compiler),
+        rti = new RuntimeTypes(compiler),
         specializedGetInterceptors =
             new Map<String, Collection<ClassElement>>(),
         interceptedClasses = new Set<ClassElement>(),
@@ -751,8 +772,9 @@
         new Namer(compiler);
   }
 
-  bool isInterceptorClass(Element element) {
+  bool isInterceptorClass(ClassElement element) {
     if (element == null) return false;
+    if (element.isNative()) return true;
     return interceptedClasses.contains(element);
   }
 
@@ -775,6 +797,16 @@
         && interceptedElements[element.name] != null;
   }
 
+  bool fieldHasInterceptedGetter(Element element) {
+    assert(element.isField());
+    return interceptedElements[element.name] != null;
+  }
+
+  bool fieldHasInterceptedSetter(Element element) {
+    assert(element.isField());
+    return interceptedElements[element.name] != null;
+  }
+
   bool isInterceptedName(SourceString name) {
     return interceptedElements[name] != null;
   }
@@ -794,12 +826,18 @@
       // determine if the given selector applies to them.
       Set<ClassElement> result = new Set<ClassElement>();
       for (Element element in intercepted) {
-        result.add(element.getEnclosingClass());
+        ClassElement classElement = element.getEnclosingClass();
+        result.add(classElement);
       }
       return result;
     });
   }
 
+  bool operatorEqHandlesNullArgument(FunctionElement operatorEqfunction) {
+    return specialOperatorEqClasses.contains(
+        operatorEqfunction.getEnclosingClass());
+  }
+
   void initializeHelperClasses() {
     getInterceptorMethod =
         compiler.findInterceptor(const SourceString('getInterceptor'));
@@ -817,7 +855,26 @@
       jsNullClass = compiler.findInterceptor(const SourceString('JSNull')),
       jsFunctionClass =
           compiler.findInterceptor(const SourceString('JSFunction')),
-      jsBoolClass = compiler.findInterceptor(const SourceString('JSBool'))];
+      jsBoolClass = compiler.findInterceptor(const SourceString('JSBool')),
+      jsMutableArrayClass =
+          compiler.findInterceptor(const SourceString('JSMutableArray')),
+      jsFixedArrayClass =
+          compiler.findInterceptor(const SourceString('JSFixedArray')),
+      jsExtendableArrayClass =
+          compiler.findInterceptor(const SourceString('JSExtendableArray'))];
+
+    jsIndexableClass =
+        compiler.findInterceptor(const SourceString('JSIndexable'));
+
+    // TODO(kasperl): Some tests do not define the special JSArray
+    // subclasses, so we check to see if they are defined before
+    // trying to resolve them.
+    if (jsFixedArrayClass != null) {
+      jsFixedArrayClass.ensureResolved(compiler);
+    }
+    if (jsExtendableArrayClass != null) {
+      jsExtendableArrayClass.ensureResolved(compiler);
+    }
 
     jsArrayClass.ensureResolved(compiler);
     jsArrayLength = compiler.lookupElementIn(
@@ -840,9 +897,20 @@
     for (ClassElement cls in classes) {
       if (cls != null) interceptedClasses.add(cls);
     }
+
+    typeLiteralClass = compiler.findHelper(const SourceString('TypeImpl'));
+    mapLiteralClass =
+        compiler.coreLibrary.find(const SourceString('LinkedHashMap'));
+    constMapLiteralClass =
+        compiler.findHelper(const SourceString('ConstantMap'));
+
+    specialOperatorEqClasses
+        ..add(jsNullClass)
+        ..add(jsNumberClass);
   }
 
-  void addInterceptors(ClassElement cls, Enqueuer enqueuer) {
+  void addInterceptorsForNativeClassMembers(
+      ClassElement cls, Enqueuer enqueuer) {
     if (enqueuer.isResolutionQueue) {
       cls.ensureResolved(compiler);
       cls.forEachMember((ClassElement classElement, Element member) {
@@ -852,7 +920,21 @@
         },
         includeSuperMembers: true);
     }
-    enqueuer.registerInstantiatedClass(cls);
+  }
+
+  void addInterceptors(ClassElement cls,
+                       Enqueuer enqueuer,
+                       TreeElements elements) {
+    if (enqueuer.isResolutionQueue) {
+      cls.ensureResolved(compiler);
+      cls.forEachMember((ClassElement classElement, Element member) {
+          Set<Element> set = interceptedElements.putIfAbsent(
+              member.name, () => new Set<Element>());
+          set.add(member);
+        },
+        includeSuperMembers: true);
+    }
+    enqueuer.registerInstantiatedClass(cls, elements);
   }
 
   void registerSpecializedGetInterceptor(Set<ClassElement> classes) {
@@ -877,7 +959,9 @@
     argumentTypes.registerDynamicInvocation(types, new Selector.noSuchMethod());
   }
 
-  void registerInstantiatedClass(ClassElement cls, Enqueuer enqueuer) {
+  void registerInstantiatedClass(ClassElement cls,
+                                 Enqueuer enqueuer,
+                                 TreeElements elements) {
     if (!seenAnyClass) {
       initializeNoSuchMethod();
       seenAnyClass = true;
@@ -901,37 +985,41 @@
         enqueuer.registerStaticUse(
             compiler.findHelper(const SourceString('iae')));
       } else if (cls == compiler.functionClass) {
-        enqueuer.registerInstantiatedClass(compiler.closureClass);
+        enqueuer.registerInstantiatedClass(compiler.closureClass, elements);
       } else if (cls == compiler.mapClass) {
         // The backend will use a literal list to initialize the entries
         // of the map.
-        enqueuer.registerInstantiatedClass(compiler.listClass);
-        enqueuer.registerInstantiatedClass(compiler.mapLiteralClass);
-        enqueueInResolution(getMapMaker());
+        enqueuer.registerInstantiatedClass(compiler.listClass, elements);
+        enqueuer.registerInstantiatedClass(mapLiteralClass, elements);
+        enqueueInResolution(getMapMaker(), elements);
       }
     }
     ClassElement result = null;
     if (cls == compiler.stringClass) {
-      addInterceptors(jsStringClass, enqueuer);
+      addInterceptors(jsStringClass, enqueuer, elements);
     } else if (cls == compiler.listClass) {
-      addInterceptors(jsArrayClass, enqueuer);
+      addInterceptors(jsArrayClass, enqueuer, elements);
+      enqueuer.registerInstantiatedClass(jsFixedArrayClass, elements);
+      enqueuer.registerInstantiatedClass(jsExtendableArrayClass, elements);
     } else if (cls == compiler.intClass) {
-      addInterceptors(jsIntClass, enqueuer);
-      addInterceptors(jsNumberClass, enqueuer);
+      addInterceptors(jsIntClass, enqueuer, elements);
+      addInterceptors(jsNumberClass, enqueuer, elements);
     } else if (cls == compiler.doubleClass) {
-      addInterceptors(jsDoubleClass, enqueuer);
-      addInterceptors(jsNumberClass, enqueuer);
+      addInterceptors(jsDoubleClass, enqueuer, elements);
+      addInterceptors(jsNumberClass, enqueuer, elements);
     } else if (cls == compiler.functionClass) {
-      addInterceptors(jsFunctionClass, enqueuer);
+      addInterceptors(jsFunctionClass, enqueuer, elements);
     } else if (cls == compiler.boolClass) {
-      addInterceptors(jsBoolClass, enqueuer);
+      addInterceptors(jsBoolClass, enqueuer, elements);
     } else if (cls == compiler.nullClass) {
-      addInterceptors(jsNullClass, enqueuer);
+      addInterceptors(jsNullClass, enqueuer, elements);
     } else if (cls == compiler.numClass) {
-      addInterceptors(jsIntClass, enqueuer);
-      addInterceptors(jsDoubleClass, enqueuer);
-      addInterceptors(jsNumberClass, enqueuer);
+      addInterceptors(jsIntClass, enqueuer, elements);
+      addInterceptors(jsDoubleClass, enqueuer, elements);
+      addInterceptors(jsNumberClass, enqueuer, elements);
     } else if (cls == compiler.mapClass) {
+    } else if (cls.isNative()) {
+      addInterceptorsForNativeClassMembers(cls, enqueuer);
     }
 
     if (compiler.enableTypeAssertions) {
@@ -939,7 +1027,7 @@
       cls.forEachLocalMember((Element member) {
         if (!member.isInstanceMember() || !member.isField()) return;
         DartType type = member.computeType(compiler);
-        enqueuer.registerIsCheck(type);
+        enqueuer.registerIsCheck(type, elements);
       });
     }
   }
@@ -948,17 +1036,12 @@
     return new JavaScriptItemCompilationContext();
   }
 
-  void addBackendRtiDependencies(World world) {
-    if (jsArrayClass != null) {
-      world.registerRtiDependency(jsArrayClass, compiler.listClass);
-    }
-  }
-
-  void enqueueHelpers(ResolutionEnqueuer world) {
+  void enqueueHelpers(ResolutionEnqueuer world, TreeElements elements) {
     jsIndexingBehaviorInterface =
         compiler.findHelper(const SourceString('JavaScriptIndexingBehavior'));
     if (jsIndexingBehaviorInterface != null) {
-      world.registerIsCheck(jsIndexingBehaviorInterface.computeType(compiler));
+      world.registerIsCheck(jsIndexingBehaviorInterface.computeType(compiler),
+                            elements);
     }
 
     if (compiler.enableTypeAssertions) {
@@ -971,54 +1054,66 @@
     }
   }
 
-  void registerStringInterpolation() {
-    enqueueInResolution(getStringInterpolationHelper());
+  onResolutionComplete() => rti.computeClassesNeedingRti();
+
+  void registerStringInterpolation(TreeElements elements) {
+    enqueueInResolution(getStringInterpolationHelper(), elements);
   }
 
-  void registerCatchStatement() {
-    enqueueInResolution(getExceptionUnwrapper());
+  void registerCatchStatement(TreeElements elements) {
+    enqueueInResolution(getExceptionUnwrapper(), elements);
   }
 
-  void registerThrow() {
-    enqueueInResolution(getThrowHelper());
+  void registerThrow(TreeElements elements) {
+    enqueueInResolution(getThrowHelper(), elements);
   }
 
-  void registerLazyField() {
-    enqueueInResolution(getCyclicThrowHelper());
+  void registerLazyField(TreeElements elements) {
+    enqueueInResolution(getCyclicThrowHelper(), elements);
   }
 
-  void registerTypeLiteral() {
-    enqueueInResolution(getCreateRuntimeType());
+  void registerTypeLiteral(TreeElements elements) {
+    enqueueInResolution(getCreateRuntimeType(), elements);
   }
 
-  void registerStackTraceInCatch() {
-    enqueueInResolution(getTraceFromException());
+  void registerStackTraceInCatch(TreeElements elements) {
+    enqueueInResolution(getTraceFromException(), elements);
   }
 
-  void registerSetRuntimeType() {
-    enqueueInResolution(getSetRuntimeTypeInfo());
+  void registerSetRuntimeType(TreeElements elements) {
+    enqueueInResolution(getSetRuntimeTypeInfo(), elements);
   }
 
-  void registerGetRuntimeTypeArgument() {
-    enqueueInResolution(getGetRuntimeTypeArgument());
+  void registerGetRuntimeTypeArgument(TreeElements elements) {
+    enqueueInResolution(getGetRuntimeTypeArgument(), elements);
   }
 
-  void registerRuntimeType() {
-    enqueueInResolution(getSetRuntimeTypeInfo());
-    enqueueInResolution(getGetRuntimeTypeInfo());
-    enqueueInResolution(getGetRuntimeTypeArgument());
-    compiler.enqueuer.resolution.registerInstantiatedClass(compiler.listClass);
+  void registerRuntimeType(TreeElements elements) {
+    enqueueInResolution(getSetRuntimeTypeInfo(), elements);
+    enqueueInResolution(getGetRuntimeTypeInfo(), elements);
+    enqueueInResolution(getGetRuntimeTypeArgument(), elements);
+    compiler.enqueuer.resolution.registerInstantiatedClass(
+        compiler.listClass, elements);
   }
 
-  void registerIsCheck(DartType type, Enqueuer world) {
+  void registerTypeVariableExpression(TreeElements elements) {
+    registerRuntimeType(elements);
+    enqueueInResolution(getRuntimeTypeToString(), elements);
+    enqueueInResolution(getCreateRuntimeType(), elements);
+  }
+
+  void registerIsCheck(DartType type, Enqueuer world, TreeElements elements) {
+    world.registerInstantiatedClass(compiler.boolClass, elements);
     bool isTypeVariable = type.kind == TypeKind.TYPE_VARIABLE;
     if (!type.isRaw || isTypeVariable) {
-      enqueueInResolution(getSetRuntimeTypeInfo());
-      enqueueInResolution(getGetRuntimeTypeInfo());
-      enqueueInResolution(getGetRuntimeTypeArgument());
-      enqueueInResolution(getCheckArguments());
-      if (isTypeVariable) enqueueInResolution(getGetObjectIsSubtype());
-      world.registerInstantiatedClass(compiler.listClass);
+      enqueueInResolution(getSetRuntimeTypeInfo(), elements);
+      enqueueInResolution(getGetRuntimeTypeInfo(), elements);
+      enqueueInResolution(getGetRuntimeTypeArgument(), elements);
+      enqueueInResolution(getCheckSubtype(), elements);
+      if (isTypeVariable) {
+        enqueueInResolution(getGetObjectIsSubtype(), elements);
+      }
+      world.registerInstantiatedClass(compiler.listClass, elements);
     }
     // [registerIsCheck] is also called for checked mode checks, so we
     // need to register checked mode helpers.
@@ -1029,48 +1124,104 @@
       e = getNativeCheckedModeHelper(type, typeCast: false);
       if (e != null) world.addToWorkList(e);
     }
+    if (type.element.isNative()) {
+      // We will neeed to add the "$is" and "$as" properties on the
+      // JavaScript object prototype, so we make sure
+      // [:defineProperty:] is compiled.
+      world.addToWorkList(
+          compiler.findHelper(const SourceString('defineProperty')));
+    }
   }
 
-  void registerAsCheck(DartType type) {
+  void registerAsCheck(DartType type, TreeElements elements) {
     Element e = getCheckedModeHelper(type, typeCast: true);
-    enqueueInResolution(e);
+    enqueueInResolution(e, elements);
     // We also need the native variant of the check (for DOM types).
     e = getNativeCheckedModeHelper(type, typeCast: true);
-    enqueueInResolution(e);
+    enqueueInResolution(e, elements);
   }
 
-  void registerThrowNoSuchMethod() {
-    enqueueInResolution(getThrowNoSuchMethod());
+  void registerThrowNoSuchMethod(TreeElements elements) {
+    enqueueInResolution(getThrowNoSuchMethod(), elements);
   }
 
-  void registerThrowRuntimeError() {
-    enqueueInResolution(getThrowRuntimeError());
+  void registerThrowRuntimeError(TreeElements elements) {
+    enqueueInResolution(getThrowRuntimeError(), elements);
   }
 
-  void registerAbstractClassInstantiation() {
-    enqueueInResolution(getThrowAbstractClassInstantiationError());
+  void registerAbstractClassInstantiation(TreeElements elements) {
+    enqueueInResolution(getThrowAbstractClassInstantiationError(), elements);
   }
 
-  void registerFallThroughError() {
-    enqueueInResolution(getFallThroughError());
+  void registerFallThroughError(TreeElements elements) {
+    enqueueInResolution(getFallThroughError(), elements);
   }
 
-  void registerSuperNoSuchMethod() {
-    enqueueInResolution(getCreateInvocationMirror());
+  void registerSuperNoSuchMethod(TreeElements elements) {
+    enqueueInResolution(getCreateInvocationMirror(), elements);
     enqueueInResolution(
-        compiler.objectClass.lookupLocalMember(Compiler.NO_SUCH_METHOD));
-    compiler.enqueuer.resolution.registerInstantiatedClass(compiler.listClass);
+        compiler.objectClass.lookupLocalMember(Compiler.NO_SUCH_METHOD),
+        elements);
+    compiler.enqueuer.resolution.registerInstantiatedClass(
+        compiler.listClass, elements);
   }
 
-  void enqueueInResolution(Element e) {
-    if (e != null) compiler.enqueuer.resolution.addToWorkList(e);
+  void registerRequiredType(DartType type, Element enclosingElement) {
+    /**
+     * If [argument] has type variables or is a type variable, this
+     * method registers a RTI dependency between the class where the
+     * type variable is defined (that is the enclosing class of the
+     * current element being resolved) and the class of [annotation].
+     * If the class of [annotation] requires RTI, then the class of
+     * the type variable does too.
+     */
+    void analyzeTypeArgument(DartType annotation, DartType argument) {
+      if (argument == null) return;
+      if (argument.element.isTypeVariable()) {
+        ClassElement enclosing = argument.element.getEnclosingClass();
+        assert(enclosing == enclosingElement.getEnclosingClass());
+        rti.registerRtiDependency(annotation.element, enclosing);
+      } else if (argument is InterfaceType) {
+        InterfaceType type = argument;
+        type.typeArguments.forEach((DartType argument) {
+          analyzeTypeArgument(annotation, argument);
+        });
+      }
+    }
+
+    if (type is InterfaceType) {
+      InterfaceType itf = type;
+      itf.typeArguments.forEach((DartType argument) {
+        analyzeTypeArgument(type, argument);
+      });
+    }
+    // TODO(ngeoffray): Also handle T a (in checked mode).
   }
 
-  void registerConstantMap() {
+  void registerClassUsingVariableExpression(ClassElement cls) {
+    rti.classesUsingTypeVariableExpression.add(cls);
+  }
+
+  bool needsRti(ClassElement cls) {
+    return rti.classesNeedingRti.contains(cls) || compiler.enabledRuntimeType;
+  }
+
+  void enqueueInResolution(Element e, TreeElements elements) {
+    if (e == null) return;
+    ResolutionEnqueuer enqueuer = compiler.enqueuer.resolution;
+    enqueuer.addToWorkList(e);
+    elements.registerDependency(e);
+  }
+
+  void registerConstantMap(TreeElements elements) {
     Element e = compiler.findHelper(const SourceString('ConstantMap'));
-    if (e != null) compiler.enqueuer.resolution.registerInstantiatedClass(e);
+    if (e != null) {
+      compiler.enqueuer.resolution.registerInstantiatedClass(e, elements);
+    }
     e = compiler.findHelper(const SourceString('ConstantProtoMap'));
-    if (e != null) compiler.enqueuer.resolution.registerInstantiatedClass(e);
+    if (e != null) {
+      compiler.enqueuer.resolution.registerInstantiatedClass(e, elements);
+    }
   }
 
   void codegen(CodegenWorkItem work) {
@@ -1462,8 +1613,12 @@
     return compiler.findHelper(const SourceString('getRuntimeTypeArgument'));
   }
 
-  Element getCheckArguments() {
-    return compiler.findHelper(const SourceString('checkArguments'));
+  Element getRuntimeTypeToString() {
+    return compiler.findHelper(const SourceString('runtimeTypeToString'));
+  }
+
+  Element getCheckSubtype() {
+    return compiler.findHelper(const SourceString('checkSubtype'));
   }
 
   Element getGetObjectIsSubtype() {
@@ -1502,4 +1657,23 @@
     generatedBailoutCode.remove(element);
     compiler.enqueuer.codegen.addToWorkList(element);
   }
+
+  bool isNullImplementation(ClassElement cls) {
+    return cls == jsNullClass;
+  }
+
+  ClassElement get intImplementation => jsIntClass;
+  ClassElement get doubleImplementation => jsDoubleClass;
+  ClassElement get numImplementation => jsNumberClass;
+  ClassElement get stringImplementation => jsStringClass;
+  ClassElement get listImplementation => jsArrayClass;
+  ClassElement get constListImplementation => jsArrayClass;
+  ClassElement get fixedListImplementation => jsFixedArrayClass;
+  ClassElement get growableListImplementation => jsExtendableArrayClass;
+  ClassElement get mapImplementation => mapLiteralClass;
+  ClassElement get constMapImplementation => constMapLiteralClass;
+  ClassElement get functionImplementation => jsFunctionClass;
+  ClassElement get typeImplementation => typeLiteralClass;
+  ClassElement get boolImplementation => jsBoolClass;
+  ClassElement get nullImplementation => jsNullClass;
 }
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
index 9f3ea2e..2597d91 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
@@ -143,6 +143,10 @@
   jsAst.Expression visitConstructed(ConstructedConstant constant) {
     return emitCanonicalVersion(constant);
   }
+
+  jsAst.Expression visitInterceptor(InterceptorConstant constant) {
+    return emitCanonicalVersion(constant);
+  }
 }
 
 /**
@@ -292,6 +296,13 @@
         [typeName]);
   }
 
+  jsAst.Expression visitInterceptor(InterceptorConstant constant) {
+    return new jsAst.PropertyAccess.field(
+        new jsAst.VariableUse(
+            getJsConstructor(constant.dispatchedType.element)),
+        'prototype');
+  }
+
   jsAst.Expression visitConstructed(ConstructedConstant constant) {
     return new jsAst.New(
         new jsAst.VariableUse(getJsConstructor(constant.type.element)),
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/constant_system_javascript.dart b/sdk/lib/_internal/compiler/implementation/js_backend/constant_system_javascript.dart
index fa5384f..1b4a0ff 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/constant_system_javascript.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/constant_system_javascript.dart
@@ -199,7 +199,7 @@
       double doubleValue = doubleResult.value;
       if (!doubleValue.isInfinite && !doubleValue.isNaN &&
           !constant.isMinusZero()) {
-        int intValue = doubleValue.toInt();
+        int intValue = doubleValue.truncate();
         if (intValue == doubleValue && integerFitsIntoDouble(intValue)) {
           return new IntConstant(intValue);
         }
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
index 227f850..d4df75d 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
@@ -69,6 +69,7 @@
   final List<ClassElement> regularClasses = <ClassElement>[];
   final List<ClassElement> deferredClasses = <ClassElement>[];
   final List<ClassElement> nativeClasses = <ClassElement>[];
+  final List<Selector> trivialNsmHandlers = <Selector>[];
 
   // TODO(ngeoffray): remove this field.
   Set<ClassElement> instantiatedClasses;
@@ -135,7 +136,7 @@
   }
 
   void addComment(String comment, CodeBuffer buffer) {
-    buffer.add(jsAst.prettyPrint(js.comment(comment), compiler));
+    buffer.write(jsAst.prettyPrint(js.comment(comment), compiler));
   }
 
   void computeRequiredTypeChecks() {
@@ -181,62 +182,82 @@
   String get lazyInitializerName
       => '${namer.isolateName}.\$lazy';
 
-  // Property name suffixes.  If the accessors are renaming then the format
-  // is <accessorName>:<fieldName><suffix>.  We use the suffix to know whether
-  // to look for the ':' separator in order to avoid doing the indexOf operation
-  // on every single property (they are quite rare).  None of these characters
-  // are legal in an identifier and they are related by bit patterns.
-  // setter          <          0x3c
-  // both            =          0x3d
-  // getter          >          0x3e
-  // renaming setter |          0x7c
-  // renaming both   }          0x7d
-  // renaming getter ~          0x7e
-  const SUFFIX_MASK = 0x3f;
-  const FIRST_SUFFIX_CODE = 0x3c;
-  const SETTER_CODE = 0x3c;
-  const GETTER_SETTER_CODE = 0x3d;
-  const GETTER_CODE = 0x3e;
-  const RENAMING_FLAG = 0x40;
-  String needsGetterCode(String variable) => '($variable & 3) > 0';
-  String needsSetterCode(String variable) => '($variable & 2) == 0';
-  String isRenaming(String variable) => '($variable & $RENAMING_FLAG) != 0';
+  // Compact field specifications.  The format of the field specification is
+  // <accessorName>:<fieldName><suffix> where the suffix and accessor name
+  // prefix are optional.  The suffix directs the generation of getter and
+  // setter methods.  Each of the getter and setter has two bits to determine
+  // the calling convention.  Setter listed below, getter is similar.
+  //
+  //     00: no setter
+  //     01: function(value) { this.field = value; }
+  //     10: function(receiver, value) { receiver.field = value; }
+  //     11: function(receiver, value) { this.field = value; }
+  //
+  // The suffix encodes 4 bits using three ASCII ranges of non-identifier
+  // characters.
+  static const FIELD_CODE_CHARACTERS = r"<=>?@{|}~%&'()*";
+  static const NO_FIELD_CODE = 0;
+  static const FIRST_FIELD_CODE = 1;
+  static const RANGE1_FIRST = 0x3c;   //  <=>?@    encodes 1..5
+  static const RANGE1_LAST = 0x40;
+  static const RANGE2_FIRST = 0x7b;   //  {|}~     encodes 6..9
+  static const RANGE2_LAST = 0x7e;
+  static const RANGE3_FIRST = 0x25;   //  %&'()*+  encodes 10..16
+  static const RANGE3_LAST = 0x2b;
 
   jsAst.FunctionDeclaration get generateAccessorFunction {
+    const RANGE1_SIZE = RANGE1_LAST - RANGE1_FIRST + 1;
+    const RANGE2_SIZE = RANGE2_LAST - RANGE2_FIRST + 1;
+    const RANGE1_ADJUST = - (FIRST_FIELD_CODE - RANGE1_FIRST);
+    const RANGE2_ADJUST = - (FIRST_FIELD_CODE + RANGE1_SIZE - RANGE2_FIRST);
+    const RANGE3_ADJUST =
+        - (FIRST_FIELD_CODE + RANGE1_SIZE + RANGE2_SIZE - RANGE3_FIRST);
+
+    String receiverParamName = compiler.enableMinification ? "r" : "receiver";
+    String valueParamName = compiler.enableMinification ? "v" : "value";
+
     // function generateAccessor(field, prototype) {
     jsAst.Fun fun = js.fun(['field', 'prototype'], [
       js['var len = field.length'],
-      js['var lastCharCode = field.charCodeAt(len - 1)'],
-      js['var needsAccessor = '
-                '(lastCharCode & $SUFFIX_MASK) >= $FIRST_SUFFIX_CODE'],
+      js['var code = field.charCodeAt(len - 1)'],
+      js['code = ((code >= $RANGE1_FIRST) && (code <= $RANGE1_LAST))'
+          '    ? code - $RANGE1_ADJUST'
+          '    : ((code >= $RANGE2_FIRST) && (code <= $RANGE2_LAST))'
+          '      ? code - $RANGE2_ADJUST'
+          '      : ((code >= $RANGE3_FIRST) && (code <= $RANGE3_LAST))'
+          '        ? code - $RANGE3_ADJUST'
+          '        : $NO_FIELD_CODE'],
 
       // if (needsAccessor) {
-      js.if_('needsAccessor', [
-        js['var needsGetter = ${needsGetterCode("lastCharCode")}'],
-        js['var needsSetter = ${needsSetterCode("lastCharCode")}'],
-        js['var renaming = ${isRenaming("lastCharCode")}'],
+      js.if_('code', [
+        js['var getterCode = code & 3'],
+        js['var setterCode = code >> 2'],
         js['var accessorName = field = field.substring(0, len - 1)'],
 
-        // if (renaming) {
-        js.if_('renaming', [
-          js['var divider = field.indexOf(":")'],
+        js['var divider = field.indexOf(":")'],
+        js.if_('divider > 0', [  // Colon never in first position.
           js['accessorName = field.substring(0, divider)'],
           js['field = field.substring(divider + 1)']
         ]),
 
         // if (needsGetter) {
-        js.if_('needsGetter', [
-          js['var getterString = "return this." + field'],
+        js.if_('getterCode', [
+          js['var args = (getterCode & 2) ? "$receiverParamName" : ""'],
+          js['var receiver = (getterCode & 1) ? "this" : "$receiverParamName"'],
+          js['var body = "return " + receiver + "." + field'],
           js['prototype["${namer.getterPrefix}" + accessorName] = '
-                 'new Function(getterString)']
+                 'new Function(args, body)']
         ]),
 
         // if (needsSetter) {
-        js.if_('needsSetter', [
-          // var setterString = "this." + field + " = v;";
-          js['var setterString = "this." + field + "$_=${_}v"'],
+        js.if_('setterCode', [
+          js['var args = (setterCode & 2)'
+              '  ? "$receiverParamName,${_}$valueParamName"'
+              '  : "$valueParamName"'],
+          js['var receiver = (setterCode & 1) ? "this" : "$receiverParamName"'],
+          js['var body = receiver + "." + field + "$_=$_$valueParamName"'],
           js['prototype["${namer.setterPrefix}" + accessorName] = '
-                 'new Function("v", setterString)']
+                 'new Function(args, body)']
         ]),
 
       ]),
@@ -277,9 +298,9 @@
         js['var body = ""'],
 
         // for (var i = 0; i < fields.length; i++) {
-        js.for_(js['var i = 0'], js['i < fields.length'], js['i++'], [
+        js.for_('var i = 0', 'i < fields.length', 'i++', [
           // if (i != 0) str += ", ";
-          js.if_(js['i != 0'], js['str += ", "']),
+          js.if_('i != 0', js['str += ", "']),
 
           js['var field = fields[i]'],
           js['field = generateAccessor(field, prototype)'],
@@ -332,6 +353,224 @@
     ];
   }
 
+  const MAX_MINIFIED_LENGTH_FOR_DIFF_ENCODING = 4;
+
+  // If we need fewer than this many noSuchMethod handlers we can save space by
+  // just emitting them in JS, rather than emitting the JS needed to generate
+  // them at run time.
+  const VERY_FEW_NO_SUCH_METHOD_HANDLERS = 10;
+
+  /**
+   * Adds (at runtime) the handlers to the Object class which catch calls to
+   * methods that the object does not have.  The handlers create an invocation
+   * mirror object.
+   *
+   * The current version only gives you the minified name when minifying (when
+   * not minifying this method is not called).
+   *
+   * In order to generate the noSuchMethod handlers we only need the minified
+   * name of the method.  We test the first character of the minified name to
+   * determine if it is a getter or a setter, and we use the arguments array at
+   * runtime to get the number of arguments and their values.  If the method
+   * involves named arguments etc. then we don't handle it here, but emit the
+   * handler method directly on the Object class.
+   *
+   * The minified names are mostly 1-4 character names, which we emit in sorted
+   * order (primary key is length, secondary ordering is lexicographic).  This
+   * gives an order like ... dD dI dX da ...
+   *
+   * Gzip is good with repeated text, but it can't diff-encode, so we do that
+   * for it.  We encode the minified names in a comma-separated string, but all
+   * the 1-4 character names are encoded before the first comma as a series of
+   * base 26 numbers.  The last digit of each number is lower case, the others
+   * are upper case, so 1 is "b" and 26 is "Ba".
+   *
+   * We think of the minified names as base 88 numbers using the ASCII
+   * characters from # to z.  The base 26 numbers each encode the delta from
+   * the previous minified name to the next.  So if there is a minified name
+   * called Df and the next is Dh, then they are 2971 and 2973 when thought of
+   * as base 88 numbers.  The difference is 2, which is "c" in lower-case-
+   * terminated base 26.
+   *
+   * The reason we don't encode long minified names with this method is that
+   * decoding the base 88 numbers would overflow JavaScript's puny integers.
+   *
+   * There are some selectors that have a special calling convention (because
+   * they are called with the receiver as the first argument).  They need a
+   * slightly different noSuchMethod handler, so we handle these first.
+   */
+  void addTrivialNsmHandlers(List<jsAst.Node> statements) {
+    if (trivialNsmHandlers.length == 0) return;
+    // Sort by calling convention, JS name length and by JS name.
+    trivialNsmHandlers.sort((a, b) {
+      bool aIsIntercepted = backend.isInterceptedName(a.name);
+      bool bIsIntercepted = backend.isInterceptedName(b.name);
+      if (aIsIntercepted != bIsIntercepted) return aIsIntercepted ? -1 : 1;
+      String aName = namer.invocationMirrorInternalName(a);
+      String bName = namer.invocationMirrorInternalName(b);
+      if (aName.length != bName.length) return aName.length - bName.length;
+      return aName.compareTo(bName);
+    });
+
+    // Find out how many selectors there are with the special calling
+    // convention.
+    int firstNormalSelector = trivialNsmHandlers.length;
+    for (int i = 0; i < trivialNsmHandlers.length; i++) {
+      if (!backend.isInterceptedName(trivialNsmHandlers[i].name)) {
+        firstNormalSelector = i;
+        break;
+      }
+    }
+
+    // Get the short names (JS names, perhaps minified).
+    Iterable<String> shorts = trivialNsmHandlers.map((selector) =>
+         namer.invocationMirrorInternalName(selector));
+    final diffShorts = <String>[];
+    var diffEncoding = new StringBuffer();
+
+    // Treat string as a number in base 88 with digits in ASCII order from # to
+    // z.  The short name sorting is based on length, and uses ASCII order for
+    // equal length strings so this means that names are ascending.  The hash
+    // character, #, is never given as input, but we need it because it's the
+    // implicit leading zero (otherwise we could not code names with leading
+    // dollar signs).
+    int fromBase88(String x) {
+      int answer = 0;
+      for (int i = 0; i < x.length; i++) {
+        int c = x.codeUnitAt(i);
+        // No support for Unicode minified identifiers in JS.
+        assert(c >= $$ && c <= $z);
+        answer *= 88;
+        answer += c - $HASH;
+      }
+      return answer;
+    }
+
+    // Big endian encoding, A = 0, B = 1...
+    // A lower case letter terminates the number.
+    String toBase26(int x) {
+      int c = x;
+      var encodingChars = <int>[];
+      encodingChars.add($a + (c % 26));
+      while (true) {
+        c ~/= 26;
+        if (c == 0) break;
+        encodingChars.add($A + (c % 26));
+      }
+      return new String.fromCharCodes(encodingChars.reversed.toList());
+    }
+
+    bool minify = compiler.enableMinification;
+    bool useDiffEncoding = minify && shorts.length > 30;
+
+    int previous = 0;
+    int nameCounter = 0;
+    for (String short in shorts) {
+      // Emit period that resets the diff base to zero when we switch to normal
+      // calling convention (this avoids the need to code negative diffs).
+      if (useDiffEncoding && nameCounter == firstNormalSelector) {
+        diffEncoding.write(".");
+        previous = 0;
+      }
+      if (short.length <= MAX_MINIFIED_LENGTH_FOR_DIFF_ENCODING &&
+          useDiffEncoding) {
+        int base63 = fromBase88(short);
+        int diff = base63 - previous;
+        previous = base63;
+        String base26Diff = toBase26(diff);
+        diffEncoding.write(base26Diff);
+      } else {
+        if (useDiffEncoding || diffEncoding.length != 0) {
+          diffEncoding.write(",");
+        }
+        diffEncoding.write(short);
+      }
+      nameCounter++;
+    }
+
+    // Startup code that loops over the method names and puts handlers on the
+    // Object class to catch noSuchMethod invocations.
+    ClassElement objectClass = compiler.objectClass;
+    String createInvocationMirror = namer.getName(
+        compiler.createInvocationMirrorElement);
+    String noSuchMethodName = namer.publicInstanceMethodNameByArity(
+        Compiler.NO_SUCH_METHOD, Compiler.NO_SUCH_METHOD_ARG_COUNT);
+    var type = 0;
+    if (useDiffEncoding) {
+      statements.addAll([
+        js['var objectClassObject = '
+           '        collectedClasses["${namer.getName(objectClass)}"],'
+           '    shortNames = "$diffEncoding".split(","),'
+           '    nameNumber = 0,'
+           '    diffEncodedString = shortNames[0],'
+           '    calculatedShortNames = [0, 1]'],  // 0, 1 are args for splice.
+        js.for_('var i = 0', 'i < diffEncodedString.length', 'i++', [
+          js['var codes = [],'
+             '    diff = 0,'
+             '    digit = diffEncodedString.charCodeAt(i)'],
+          js.if_('digit == ${$PERIOD}', [
+            js['nameNumber = 0'],
+            js['digit = diffEncodedString.charCodeAt(++i)']
+          ]),
+          js.while_('digit <= ${$Z}', [
+            js['diff *= 26'],
+            js['diff += (digit - ${$A})'],
+            js['digit = diffEncodedString.charCodeAt(++i)']
+          ]),
+          js['diff *= 26'],
+          js['diff += (digit - ${$a})'],
+          js['nameNumber += diff'],
+          js.for_('var remaining = nameNumber',
+                  'remaining > 0',
+                  'remaining = ((remaining / 88) | 0)', [
+            js['codes.unshift(${$HASH} + (remaining % 88))']
+          ]),
+          js['calculatedShortNames.push('
+             '    String.fromCharCode.apply(String, codes))']
+        ]),
+        js['shortNames.splice.apply(shortNames, calculatedShortNames)']
+      ]);
+    } else {
+      // No useDiffEncoding version.
+      Iterable<String> longs = trivialNsmHandlers.map((selector) =>
+             selector.invocationMirrorMemberName);
+      String longNamesConstant = minify ? "" :
+          ',longNames = "${longs.join(",")}".split(",")';
+      statements.add(
+        js['var objectClassObject = '
+           '        collectedClasses["${namer.getName(objectClass)}"],'
+           '    shortNames = "$diffEncoding".split(",")'
+           '    $longNamesConstant']);
+    }
+
+    String sliceOffset = '," + (j < $firstNormalSelector ? 1 : 0)';
+    if (firstNormalSelector == 0) sliceOffset = '"';
+    if (firstNormalSelector == shorts.length) sliceOffset = ', 1"';
+
+    String whatToPatch = nativeEmitter.handleNoSuchMethod ?
+                         "Object.prototype" :
+                         "objectClassObject";
+
+    statements.addAll([
+      js.for_('var j = 0', 'j < shortNames.length', 'j++', [
+        js['var type = 0'],
+        js['var short = shortNames[j]'],
+        js.if_('short[0] == "${namer.getterPrefix[0]}"', js['type = 1']),
+        js.if_('short[0] == "${namer.setterPrefix[0]}"', js['type = 2']),
+        js['$whatToPatch[short] = Function("'
+               'return this.$noSuchMethodName('
+                   'this,'
+                   '${namer.CURRENT_ISOLATE}.$createInvocationMirror(\'"'
+                       ' + ${minify ? "shortNames" : "longNames"}[j]'
+                       ' + "\',\'" + short + "\',"'
+                       ' + type'
+                       ' + ",Array.prototype.slice.call(arguments'
+                       '$sliceOffset'
+                       ' + "),[]))")']
+      ])
+    ]);
+  }
+
   jsAst.Fun get finishClassesFunction {
     // Class descriptions are collected in a JS object.
     // 'finishClasses' takes all collected descriptions and sets up
@@ -346,11 +585,7 @@
     // the object literal directly. For other engines we have to create a new
     // object and copy over the members.
 
-    // function(collectedClasses,
-    //          isolateProperties,
-    //          existingIsolateProperties) {
-    return js.fun(['collectedClasses', 'isolateProperties',
-                   'existingIsolateProperties'], [
+    List<jsAst.Node> statements = [
       js['var pendingClasses = {}'],
 
       js['var hasOwnProperty = Object.prototype.hasOwnProperty'],
@@ -358,7 +593,7 @@
       // for (var cls in collectedClasses) {
       js.forIn('cls', 'collectedClasses', [
         // if (hasOwnProperty.call(collectedClasses, cls)) {
-        js.if_(js['hasOwnProperty.call(collectedClasses, cls)'], [
+        js.if_('hasOwnProperty.call(collectedClasses, cls)', [
           js['var desc = collectedClasses[cls]'],
 
           /* The 'fields' are either a constructor function or a
@@ -370,7 +605,7 @@
           // var fields = desc[""], supr;
           js['var fields = desc[""], supr'],
 
-          js.if_(js['typeof fields == "string"'], [
+          js.if_('typeof fields == "string"', [
             js['var s = fields.split(";")'],
             js['supr = s[0]'],
             js['fields = s[1] == "" ? [] : s[1].split(",")'],
@@ -381,7 +616,7 @@
           js['isolateProperties[cls] = defineClass(cls, fields, desc)'],
 
           // if (supr) pendingClasses[cls] = supr;
-          js.if_(js['supr'], js['pendingClasses[cls] = supr'])
+          js.if_('supr', js['pendingClasses[cls] = supr'])
         ])
       ]),
 
@@ -389,10 +624,19 @@
 
       // function finishClass(cls) { ... }
       buildFinishClass(),
+    ];
 
+    addTrivialNsmHandlers(statements);
+
+    statements.add(
       // for (var cls in pendingClasses) finishClass(cls);
-      js.forIn('cls', 'pendingClasses', js['finishClass']('cls'))
-    ]);
+      js.forIn('cls', 'pendingClasses', js['finishClass(cls)'])
+    );
+    // function(collectedClasses,
+    //          isolateProperties,
+    //          existingIsolateProperties) {
+    return js.fun(['collectedClasses', 'isolateProperties',
+                   'existingIsolateProperties'], statements);
   }
 
   jsAst.FunctionDeclaration buildFinishClass() {
@@ -405,14 +649,18 @@
       js['var hasOwnProperty = Object.prototype.hasOwnProperty'],
 
       // if (hasOwnProperty.call(finishedClasses, cls)) return;
-      js.if_(js['hasOwnProperty.call(finishedClasses, cls)'],
+      js.if_('hasOwnProperty.call(finishedClasses, cls)',
              js.return_()),
 
       js['finishedClasses[cls] = true'],
+
       js['var superclass = pendingClasses[cls]'],
 
-      /* The superclass is only false (empty string) for Dart's Object class. */
-      js.if_(js['!superclass'], js.return_()),
+      // The superclass is only false (empty string) for Dart's Object class.
+      // The minifier together with noSuchMethod can put methods on the
+      // Object.prototype object, and they show through here, so we check that
+      // we have a string.
+      js.if_('!superclass || typeof superclass != "string"', js.return_()),
       js['finishClass(superclass)'],
       js['var constructor = isolateProperties[cls]'],
       js['var superConstructor = isolateProperties[superclass]'],
@@ -446,10 +694,10 @@
         js.forIn('member', 'prototype', [
           /* Short version of: if (member == '') */
           // if (!member) continue;
-          js.if_(js['!member'], new jsAst.Continue(null)),
+          js.if_('!member', new jsAst.Continue(null)),
 
           // if (hasOwnProperty.call(prototype, member)) {
-          js.if_(js['hasOwnProperty.call(prototype, member)'], [
+          js.if_('hasOwnProperty.call(prototype, member)', [
             js['newPrototype[member] = prototype[member]']
           ])
         ])
@@ -511,7 +759,7 @@
 
       // for (var staticName in isolateProperties) {
       js.forIn('staticName', 'isolateProperties', [
-        js.if_(js['hasOwnProperty.call(isolateProperties, staticName)'], [
+        js.if_('hasOwnProperty.call(isolateProperties, staticName)', [
           js['str += ("this." + staticName + "= properties." + staticName + '
                           '";\\n")']
         ])
@@ -558,7 +806,7 @@
 
         // try {
         js.try_([
-          js.if_(js['result === sentinelUndefined'], [
+          js.if_('result === sentinelUndefined', [
             js['$isolate[fieldName] = sentinelInProgress'],
 
             // try {
@@ -570,15 +818,15 @@
               // stack trace.
 
               // if (result === sentinelUndefined) {
-              js.if_(js['result === sentinelUndefined'], [
+              js.if_('result === sentinelUndefined', [
                 // if ($isolate[fieldName] === sentinelInProgress) {
-                js.if_(js['$isolate[fieldName] === sentinelInProgress'], [
+                js.if_('$isolate[fieldName] === sentinelInProgress', [
                   js['$isolate[fieldName] = null'],
                 ])
               ])
             ])
           ], /* else */ [
-            js.if_(js['result === sentinelInProgress'],
+            js.if_('result === sentinelInProgress',
               js['$cyclicThrow(staticName)']
             )
           ]),
@@ -618,7 +866,7 @@
 
   void emitFinishIsolateConstructorInvocation(CodeBuffer buffer) {
     String isolate = namer.isolateName;
-    buffer.add("$isolate = $finishIsolateConstructorName($isolate)$N");
+    buffer.write("$isolate = $finishIsolateConstructorName($isolate)$N");
   }
 
   /**
@@ -641,9 +889,9 @@
     }
     if (parameters.optionalParametersAreNamed
         && selector.namedArgumentCount == parameters.optionalParameterCount) {
-      // If the selector has the same number of named arguments as
-      // the element, we don't need to add a stub. The call site will
-      // hit the method directly.
+      // If the selector has the same number of named arguments as the element,
+      // we don't need to add a stub. The call site will hit the method
+      // directly.
       return;
     }
     ConstantHandler handler = compiler.constantHandler;
@@ -655,8 +903,7 @@
 
     bool isInterceptedMethod = backend.isInterceptedMethod(member);
 
-    // If the method is intercepted, we need to also pass
-    // the actual receiver.
+    // If the method is intercepted, we need to also pass the actual receiver.
     int extraArgumentCount = isInterceptedMethod ? 1 : 0;
     // Use '$receiver' to avoid clashes with other parameter names. Using
     // '$receiver' works because [:namer.safeName:] used for getting parameter
@@ -678,14 +925,16 @@
       argumentsBuffer[0] = js[receiverArgumentName];
     }
 
-    int indexOfLastOptionalArgumentInParameters = positionalArgumentCount - 1;
+    int optionalParameterStart = positionalArgumentCount + extraArgumentCount;
+    // Includes extra receiver argument when using interceptor convention
+    int indexOfLastOptionalArgumentInParameters = optionalParameterStart - 1;
+
     TreeElements elements =
         compiler.enqueuer.resolution.getCachedElements(member);
 
     parameters.orderedForEachParameter((Element element) {
       String jsName = backend.namer.safeName(element.name.slowToString());
       assert(jsName != receiverArgumentName);
-      int optionalParameterStart = positionalArgumentCount + extraArgumentCount;
       if (count < optionalParameterStart) {
         parametersBuffer[count] = new jsAst.Parameter(jsName);
         argumentsBuffer[count] = js[jsName];
@@ -721,7 +970,8 @@
     List body;
     if (member.hasFixedBackendName()) {
       body = nativeEmitter.generateParameterStubStatements(
-          member, invocationName, parametersBuffer, argumentsBuffer,
+          member, isInterceptedMethod, invocationName,
+          parametersBuffer, argumentsBuffer,
           indexOfLastOptionalArgumentInParameters);
     } else {
       body = [js.return_(js['this'][namer.getName(member)](argumentsBuffer))];
@@ -955,7 +1205,7 @@
     }
 
     void generateSubstitution(Element other, {bool emitNull: false}) {
-      RuntimeTypeInformation rti = backend.rti;
+      RuntimeTypes rti = backend.rti;
       // TODO(karlklose): support typedefs with variables.
       jsAst.Expression expression;
       bool needsNativeCheck = nativeEmitter.requiresNativeIsCheck(other);
@@ -988,23 +1238,10 @@
         emitNoSuchMethodHandlers(builder.addProperty);
       }
     }
-
-    if (backend.isInterceptorClass(classElement)
-        && classElement != compiler.objectClass) {
-      // We optimize the operator== on interceptor classes to
-      // just do a JavaScript double or triple equals.
-      String name = backend.namer.publicInstanceMethodNameByArity(
-          const SourceString('=='), 1);
-      Function kind = (classElement == backend.jsNullClass)
-          ? js.equals
-          : js.strictEquals;
-      builder.addProperty(name, js.fun(['receiver', 'a'],
-          js.block(js.return_(kind(js['receiver'], js['a'])))));
-    }
   }
 
   void emitRuntimeTypeSupport(CodeBuffer buffer) {
-    RuntimeTypeInformation rti = backend.rti;
+    RuntimeTypes rti = backend.rti;
     TypeChecks typeChecks = rti.getRequiredChecks();
 
     /// Classes that are not instantiated and native classes need a holder
@@ -1025,8 +1262,8 @@
       if (!needsHolder(cls)) return;
       String holder = namer.isolateAccess(cls);
       String name = namer.getName(cls);
-      buffer.add('$holder$_=$_{builtin\$cls:$_"$name"');
-      buffer.add('}$N');
+      buffer.write('$holder$_=$_{builtin\$cls:$_"$name"');
+      buffer.write('}$N');
     }
 
     // Create representation objects for classes that we do not have a class
@@ -1040,10 +1277,10 @@
     for (ClassElement cls in typeChecks) {
       String holder = namer.isolateAccess(cls);
       for (ClassElement check in typeChecks[cls]) {
-        buffer.add('$holder.${namer.operatorIs(check)}$_=${_}true$N');
+        buffer.write('$holder.${namer.operatorIs(check)}$_=${_}true$N');
         String body = rti.getSupertypeSubstitution(cls, check);
         if (body != null) {
-          buffer.add('$holder.${namer.substitutionName(check)}$_=${_}$body$N');
+          buffer.write('$holder.${namer.substitutionName(check)}$_=${_}$body$N');
         }
       };
     }
@@ -1125,9 +1362,6 @@
               && canGenerateCheckedSetter(member)) {
             needsCheckedSetter = true;
             needsSetter = false;
-          } else if (backend.isInterceptedMethod(member)) {
-            // The [addField] will take care of generating the setter.
-            needsSetter = false;
           }
         }
         // Getters and setters with suffixes will be generated dynamically.
@@ -1166,21 +1400,26 @@
 
   void generateGetter(Element member, String fieldName, String accessorName,
                       ClassBuilder builder) {
-    assert(!backend.isInterceptorClass(member));
     String getterName = namer.getterNameFromAccessorName(accessorName);
+    String receiver = backend.isInterceptorClass(member.getEnclosingClass())
+        ? 'receiver' : 'this';
+    List<String> args = backend.isInterceptedMethod(member)
+        ? ['receiver']
+        : [];
     builder.addProperty(getterName,
-        js.fun([], js.return_(js['this'][fieldName])));
+        js.fun(args, js.return_(js['$receiver.$fieldName'])));
   }
 
   void generateSetter(Element member, String fieldName, String accessorName,
                       ClassBuilder builder) {
-    assert(!backend.isInterceptorClass(member));
     String setterName = namer.setterNameFromAccessorName(accessorName);
+    String receiver = backend.isInterceptorClass(member.getEnclosingClass())
+        ? 'receiver' : 'this';
     List<String> args = backend.isInterceptedMethod(member)
         ? ['receiver', 'v']
         : ['v'];
     builder.addProperty(setterName,
-        js.fun(args, js['this'][fieldName].assign('v')));
+        js.fun(args, js[receiver][fieldName].assign('v')));
   }
 
   bool canGenerateCheckedSetter(Element member) {
@@ -1211,11 +1450,14 @@
     }
 
     String setterName = namer.setterNameFromAccessorName(accessorName);
+    String receiver = backend.isInterceptorClass(member.getEnclosingClass())
+        ? 'receiver' : 'this';
     List<String> args = backend.isInterceptedMethod(member)
         ? ['receiver', 'v']
         : ['v'];
     builder.addProperty(setterName,
-        js.fun(args, js['this'][fieldName].assign(js[helperName](arguments))));
+        js.fun(args,
+            js[receiver][fieldName].assign(js[helperName](arguments))));
   }
 
   void emitClassConstructor(ClassElement classElement, ClassBuilder builder) {
@@ -1230,7 +1472,7 @@
                        ClassBuilder builder,
                        { String superClass: "",
                          bool classIsNative: false }) {
-    bool isFirstField = true;
+    String separator = '';
     StringBuffer buffer = new StringBuffer();
     if (!classIsNative) {
       buffer.write('$superClass;');
@@ -1248,13 +1490,8 @@
       // constructors, so we don't need the fields unless we are generating
       // accessors at runtime.
       if (!classIsNative || needsAccessor) {
-        // Emit correct commas.
-        if (isFirstField) {
-          isFirstField = false;
-        } else {
-          buffer.write(',');
-        }
-        int flag = 0;
+        buffer.write(separator);
+        separator = ',';
         if (!needsAccessor) {
           // Emit field for constructor generation.
           assert(!classIsNative);
@@ -1267,15 +1504,31 @@
             buffer.write(':$name');
             // Only the native classes can have renaming accessors.
             assert(classIsNative);
-            flag = RENAMING_FLAG;
           }
-        }
-        if (needsGetter && needsSetter) {
-          buffer.writeCharCode(GETTER_SETTER_CODE + flag);
-        } else if (needsGetter) {
-          buffer.writeCharCode(GETTER_CODE + flag);
-        } else if (needsSetter) {
-          buffer.writeCharCode(SETTER_CODE + flag);
+
+          int getterCode = 0;
+          if (needsGetter) {
+            // 01:  function() { return this.field; }
+            // 10:  function(receiver) { return receiver.field; }
+            // 11:  function(receiver) { return this.field; }
+            getterCode += backend.fieldHasInterceptedGetter(member) ? 2 : 0;
+            getterCode += backend.isInterceptorClass(classElement) ? 0 : 1;
+            // TODO(sra): 'isInterceptorClass' might not be the correct test for
+            // methods forced to use the interceptor convention because the
+            // method's class was elsewhere mixed-in to an interceptor.
+            assert(getterCode != 0);
+          }
+          int setterCode = 0;
+          if (needsSetter) {
+            // 01:  function(value) { this.field = value; }
+            // 10:  function(receiver, value) { receiver.field = value; }
+            // 11:  function(receiver, value) { this.field = value; }
+            setterCode += backend.fieldHasInterceptedSetter(member) ? 2 : 0;
+            setterCode += backend.isInterceptorClass(classElement) ? 0 : 1;
+            assert(setterCode != 0);
+          }
+          int code = getterCode + (setterCode << 2);
+          buffer.write(FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE]);
         }
       }
     });
@@ -1300,13 +1553,6 @@
           assert(!needsSetter);
           generateCheckedSetter(member, name, accessorName, builder);
         }
-        if (backend.isInterceptedMethod(member)
-            && instanceFieldNeedsSetter(member)) {
-          // The caller of this method sets [needsSetter] as false
-          // when the setter is intercepted.
-          assert(!needsSetter);
-          generateSetter(member, name, accessorName, builder);
-        }
         if (!getterAndSetterCanBeImplementedByFieldSpec) {
           if (needsGetter) {
             generateGetter(member, name, accessorName, builder);
@@ -1353,12 +1599,16 @@
 
     jsAst.Expression init =
         js[classesCollector][className].assign(builder.toObjectInitializer());
-    buffer.add(jsAst.prettyPrint(init, compiler));
-    buffer.add('$N$n');
+    buffer.write(jsAst.prettyPrint(init, compiler));
+    buffer.write('$N$n');
   }
 
   bool get getterAndSetterCanBeImplementedByFieldSpec => true;
 
+  /// If this is true then we can generate the noSuchMethod handlers at startup
+  /// time, instead of them being emitted as part of the Object class.
+  bool get generateTrivialNsmHandlers => true;
+
   int _selectorRank(Selector selector) {
     int arity = selector.argumentCount * 3;
     if (selector.isGetter()) return arity + 2;
@@ -1398,7 +1648,7 @@
       emitSubstitution(cls);
     }
 
-    RuntimeTypeInformation rti = backend.rti;
+    RuntimeTypes rti = backend.rti;
     ClassElement superclass = cls.superclass;
 
     bool haveSameTypeVariables(ClassElement a, ClassElement b) {
@@ -1415,7 +1665,7 @@
       Set<ClassElement> emitted = new Set<ClassElement>();
       // TODO(karlklose): move the computation of these checks to
       // RuntimeTypeInformation.
-      if (compiler.world.needsRti(cls)) {
+      if (backend.needsRti(cls)) {
         emitSubstitution(superclass, emitNull: true);
         emitted.add(superclass);
       }
@@ -1527,14 +1777,12 @@
         }
     );
 
+    // Add interceptors referenced by constants.
     ConstantHandler handler = compiler.constantHandler;
     List<Constant> constants = handler.getConstantsForEmission();
     for (Constant constant in constants) {
-      if (constant is ConstructedConstant) {
-        Element element = constant.computeType(compiler).element;
-        if (backend.isInterceptorClass(element)) {
-          needed.add(element);
-        }
+      if (constant is InterceptorConstant) {
+        needed.add(constant.dispatchedType.element);
       }
     }
 
@@ -1560,12 +1808,12 @@
 
   void emitFinishClassesInvocationIfNecessary(CodeBuffer buffer) {
     if (needsDefineClass) {
-      buffer.add('$finishClassesName($classesCollector,'
-                 '$_$isolateProperties,'
-                 '${_}null)$N');
+      buffer.write('$finishClassesName($classesCollector,'
+                   '$_$isolateProperties,'
+                   '${_}null)$N');
 
       // Reset the map.
-      buffer.add("$classesCollector$_=${_}null$N$n");
+      buffer.write("$classesCollector$_=${_}null$N$n");
     }
   }
 
@@ -1574,8 +1822,8 @@
                           jsAst.Expression functionExpression) {
     jsAst.Expression assignment =
         js[isolateProperties][name].assign(functionExpression);
-    buffer.add(jsAst.prettyPrint(assignment, compiler));
-    buffer.add('$N$n');
+    buffer.write(jsAst.prettyPrint(assignment, compiler));
+    buffer.write('$N$n');
   }
 
   void emitStaticFunctions(CodeBuffer eagerBuffer) {
@@ -1609,12 +1857,12 @@
     }
   }
 
-  void emitStaticFunctionGetters(CodeBuffer buffer) {
+  void emitStaticFunctionGetters(CodeBuffer eagerBuffer) {
     Set<FunctionElement> functionsNeedingGetter =
         compiler.codegenWorld.staticFunctionsNeedingGetter;
     for (FunctionElement element in
              Elements.sortedByPosition(functionsNeedingGetter)) {
-      // TODO(ahe): Defer loading of these getters.
+      CodeBuffer buffer = bufferForElement(element, eagerBuffer);
 
       // The static function does not have the correct name. Since
       // [addParameterStubs] use the name to create its stubs we simply
@@ -1626,24 +1874,23 @@
       String staticName = namer.getName(element);
       String invocationName = namer.instanceMethodName(callElement);
       String fieldAccess = '$isolateProperties.$staticName';
-      buffer.add("$fieldAccess.$invocationName$_=$_$fieldAccess$N");
+      buffer.write("$fieldAccess.$invocationName$_=$_$fieldAccess$N");
 
       addParameterStubs(callElement, (String name, jsAst.Expression value) {
         jsAst.Expression assignment =
             js[isolateProperties][staticName][name].assign(value);
-        buffer.add(
-            jsAst.prettyPrint(assignment.toStatement(), compiler));
-        buffer.add('$N');
+        buffer.write(jsAst.prettyPrint(assignment.toStatement(), compiler));
+        buffer.write('$N');
       });
 
       // If a static function is used as a closure we need to add its name
       // in case it is used in spawnFunction.
       String fieldName = namer.STATIC_CLOSURE_NAME_NAME;
-      buffer.add('$fieldAccess.$fieldName$_=$_"$staticName"$N');
+      buffer.write('$fieldAccess.$fieldName$_=$_"$staticName"$N');
       getTypedefChecksOn(element.computeType(compiler)).forEach(
         (Element typedef) {
           String operator = namer.operatorIs(typedef);
-          buffer.add('$fieldAccess.$operator$_=${_}true$N');
+          buffer.write('$fieldAccess.$operator$_=${_}true$N');
         }
       );
     }
@@ -1729,7 +1976,8 @@
       }
 
       ClassElement closureClassElement = new ClosureClassElement(
-          new SourceString(name), compiler, member, member.getCompilationUnit());
+          null, new SourceString(name), compiler, member,
+          member.getCompilationUnit());
       String mangledName = namer.getName(closureClassElement);
       String superName = namer.getName(closureClassElement.superclass);
       needsClosureClass = true;
@@ -1883,8 +2131,8 @@
         jsAst.Expression init =
           js[isolateProperties][namer.getName(element)].assign(
               constantEmitter.referenceInInitializationContext(initialValue));
-        buffer.add(jsAst.prettyPrint(init, compiler));
-        buffer.add('$N');
+        buffer.write(jsAst.prettyPrint(init, compiler));
+        buffer.write('$N');
       });
     }
   }
@@ -1915,8 +2163,8 @@
           arguments.add(getter);
         }
         jsAst.Expression init = js[lazyInitializerName](arguments);
-        buffer.add(jsAst.prettyPrint(init, compiler));
-        buffer.add("$N");
+        buffer.write(jsAst.prettyPrint(init, compiler));
+        buffer.write("$N");
       }
     }
   }
@@ -1949,14 +2197,14 @@
           bufferForElement(constant.computeType(compiler).element, eagerBuffer);
       jsAst.Expression init = js[isolateProperties][name].assign(
           constantInitializerExpression(constant));
-      buffer.add(jsAst.prettyPrint(init, compiler));
-      buffer.add('$N');
+      buffer.write(jsAst.prettyPrint(init, compiler));
+      buffer.write('$N');
     }
   }
 
   void emitMakeConstantList(CodeBuffer buffer) {
-    buffer.add(namer.isolateName);
-    buffer.add(r'''.makeConstantList = function(list) {
+    buffer.write(namer.isolateName);
+    buffer.write(r'''.makeConstantList = function(list) {
   list.immutable$list = true;
   list.fixed$length = true;
   return list;
@@ -1983,6 +2231,29 @@
     }
   }
 
+  // Identify the noSuchMethod handlers that are so simple that we can
+  // generate them programatically.
+  bool isTrivialNsmHandler(
+      int type, List argNames, Selector selector, String internalName) {
+    if (!generateTrivialNsmHandlers) return false;
+    // Check for interceptor calling convention.
+    if (backend.isInterceptedName(selector.name)) {
+      // We can handle the calling convention used by intercepted names in the
+      // diff encoding, but we don't use that for non-minified code.
+      if (!compiler.enableMinification) return false;
+      String shortName = namer.invocationMirrorInternalName(selector);
+      if (shortName.length > MAX_MINIFIED_LENGTH_FOR_DIFF_ENCODING) {
+        return false;
+      }
+    }
+    // Check for named arguments.
+    if (argNames.length != 0) return false;
+    // Check for unexpected name (this doesn't really happen).
+    if (internalName.startsWith(namer.getterPrefix[0])) return type == 1;
+    if (internalName.startsWith(namer.setterPrefix[0])) return type == 2;
+    return type == 0;
+  }
+
   void emitNoSuchMethodHandlers(DefineStubFunction defineStub) {
     // Do not generate no such method handlers if there is no class.
     if (compiler.codegenWorld.instantiatedClasses.isEmpty) return;
@@ -1997,42 +2268,7 @@
 
     // Keep track of the JavaScript names we've already added so we
     // do not introduce duplicates (bad for code size).
-    Set<String> addedJsNames = new Set<String>();
-
-    jsAst.Expression generateMethod(String jsName, Selector selector) {
-      // Values match JSInvocationMirror in js-helper library.
-      int type = selector.invocationMirrorKind;
-      String methodName = selector.invocationMirrorMemberName;
-      List<jsAst.Parameter> parameters = <jsAst.Parameter>[];
-      CodeBuffer args = new CodeBuffer();
-      for (int i = 0; i < selector.argumentCount; i++) {
-        parameters.add(new jsAst.Parameter('\$$i'));
-      }
-
-      List<jsAst.Expression> argNames =
-          selector.getOrderedNamedArguments().map((SourceString name) =>
-              js.string(name.slowToString())).toList();
-
-      String internalName = namer.invocationMirrorInternalName(selector);
-
-      String createInvocationMirror = namer.getName(
-          compiler.createInvocationMirrorElement);
-
-      assert(backend.isInterceptedName(Compiler.NO_SUCH_METHOD));
-      jsAst.Expression expression = js['this.$noSuchMethodName'](
-          [js['this'],
-           js[namer.CURRENT_ISOLATE][createInvocationMirror]([
-               js.string(methodName),
-               js.string(internalName),
-               type,
-               new jsAst.ArrayInitializer.from(
-                   parameters.map((param) => js[param.name]).toList()),
-               new jsAst.ArrayInitializer.from(argNames)])]);
-      parameters = backend.isInterceptedName(selector.name)
-          ? ([new jsAst.Parameter('\$receiver')]..addAll(parameters))
-          : parameters;
-      return js.fun(parameters, js.return_(expression));
-    }
+    Map<String, Selector> addedJsNames = new Map<String, Selector>();
 
     void addNoSuchMethodHandlers(SourceString ignore, Set<Selector> selectors) {
       // Cache the object class and type.
@@ -2059,6 +2295,9 @@
         ClassElement receiverClass = objectClass;
         TypeMask mask = selector.mask;
         if (mask != null) {
+          // If the mask is empty it doesn't contain a noSuchMethod
+          // handler -- not even if it is nullable.
+          if (mask.isEmpty) continue;
           receiverClass = mask.base.element;
         }
 
@@ -2108,17 +2347,66 @@
             compiler.world.locateNoSuchMethodHolders(selector);
         if (holders.every(hasMatchingMember)) continue;
         String jsName = namer.invocationMirrorInternalName(selector);
-        if (!addedJsNames.contains(jsName)) {
-          jsAst.Expression method = generateMethod(jsName, selector);
-          defineStub(jsName, method);
-          addedJsNames.add(jsName);
-        }
+        addedJsNames[jsName] = selector;
       }
     }
 
     compiler.codegenWorld.invokedNames.forEach(addNoSuchMethodHandlers);
     compiler.codegenWorld.invokedGetters.forEach(addNoSuchMethodHandlers);
     compiler.codegenWorld.invokedSetters.forEach(addNoSuchMethodHandlers);
+
+    // Set flag used by generateMethod helper below.  If we have very few
+    // handlers we use defineStub for them all, rather than try to generate them
+    // at runtime.
+    bool haveVeryFewNoSuchMemberHandlers =
+        (addedJsNames.length < VERY_FEW_NO_SUCH_METHOD_HANDLERS);
+
+    jsAst.Expression generateMethod(String jsName, Selector selector) {
+      // Values match JSInvocationMirror in js-helper library.
+      int type = selector.invocationMirrorKind;
+      List<jsAst.Parameter> parameters = <jsAst.Parameter>[];
+      CodeBuffer args = new CodeBuffer();
+      for (int i = 0; i < selector.argumentCount; i++) {
+        parameters.add(new jsAst.Parameter('\$$i'));
+      }
+
+      List<jsAst.Expression> argNames =
+          selector.getOrderedNamedArguments().map((SourceString name) =>
+              js.string(name.slowToString())).toList();
+
+      String methodName = selector.invocationMirrorMemberName;
+      String internalName = namer.invocationMirrorInternalName(selector);
+      if (!haveVeryFewNoSuchMemberHandlers &&
+          isTrivialNsmHandler(type, argNames, selector, internalName)) {
+        trivialNsmHandlers.add(selector);
+        return null;
+      }
+
+      String createInvocationMirror = namer.getName(
+          compiler.createInvocationMirrorElement);
+
+      assert(backend.isInterceptedName(Compiler.NO_SUCH_METHOD));
+      jsAst.Expression expression = js['this.$noSuchMethodName'](
+          [js['this'],
+           js[namer.CURRENT_ISOLATE][createInvocationMirror]([
+               js.string(compiler.enableMinification ?
+                         internalName : methodName),
+               js.string(internalName),
+               type,
+               new jsAst.ArrayInitializer.from(
+                   parameters.map((param) => js[param.name]).toList()),
+               new jsAst.ArrayInitializer.from(argNames)])]);
+      parameters = backend.isInterceptedName(selector.name)
+          ? ([new jsAst.Parameter('\$receiver')]..addAll(parameters))
+          : parameters;
+      return js.fun(parameters, js.return_(expression));
+    }
+
+    for (String jsName in addedJsNames.keys.toList()..sort()) {
+      Selector selector = addedJsNames[jsName];
+      jsAst.Expression method = generateMethod(jsName, selector);
+      if (method != null) defineStub(jsName, method);
+    }
   }
 
   String buildIsolateSetup(CodeBuffer buffer,
@@ -2131,7 +2419,7 @@
     if (!compiler.codegenWorld.staticFunctionsNeedingGetter.contains(appMain)) {
       Selector selector = new Selector.callClosure(0);
       String invocationName = namer.invocationName(selector);
-      buffer.add("$mainAccess.$invocationName = $mainAccess$N");
+      buffer.write("$mainAccess.$invocationName = $mainAccess$N");
     }
     return "${namer.isolateAccess(isolateMain)}($mainAccess)";
   }
@@ -2148,7 +2436,7 @@
       mainCall = '${namer.isolateAccess(main)}()';
     }
     addComment('BEGIN invoke [main].', buffer);
-    buffer.add("""
+    buffer.write("""
 if (typeof document !== "undefined" && document.readyState !== "complete") {
   document.addEventListener("readystatechange", function () {
     if (document.readyState == "complete") {
@@ -2177,7 +2465,6 @@
       return js.return_(js[namer.isolateAccess(cls)]['prototype']);
     }
 
-    jsAst.VariableUse receiver = js['receiver'];
     /**
      * Build a JavaScrit AST node for doing a type check on
      * [cls]. [cls] must be an interceptor class.
@@ -2186,19 +2473,22 @@
       jsAst.Expression condition;
       assert(backend.isInterceptorClass(cls));
       if (cls == backend.jsBoolClass) {
-        condition = receiver.typeof.equals(js.string('boolean'));
+        condition = js['(typeof receiver) == "boolean"'];
       } else if (cls == backend.jsIntClass ||
                  cls == backend.jsDoubleClass ||
                  cls == backend.jsNumberClass) {
         throw 'internal error';
-      } else if (cls == backend.jsArrayClass) {
-        condition = receiver['constructor'].equals('Array');
+      } else if (cls == backend.jsArrayClass ||
+                 cls == backend.jsMutableArrayClass ||
+                 cls == backend.jsFixedArrayClass ||
+                 cls == backend.jsExtendableArrayClass) {
+        condition = js['receiver.constructor == Array'];
       } else if (cls == backend.jsStringClass) {
-        condition = receiver.typeof.equals(js.string('string'));
+        condition = js['(typeof receiver) == "string"'];
       } else if (cls == backend.jsNullClass) {
-        condition = receiver.equals(new jsAst.LiteralNull());
+        condition = js['receiver == null'];
       } else if (cls == backend.jsFunctionClass) {
-        condition = receiver.typeof.equals(js.string('function'));
+        condition = js['(typeof receiver) == "function"'];
       } else {
         throw 'internal error';
       }
@@ -2214,7 +2504,10 @@
     bool hasNumber = false;
     bool hasString = false;
     for (ClassElement cls in classes) {
-      if (cls == backend.jsArrayClass) hasArray = true;
+      if (cls == backend.jsArrayClass ||
+          cls == backend.jsMutableArrayClass ||
+          cls == backend.jsFixedArrayClass ||
+          cls == backend.jsExtendableArrayClass) hasArray = true;
       else if (cls == backend.jsBoolClass) hasBool = true;
       else if (cls == backend.jsDoubleClass) hasDouble = true;
       else if (cls == backend.jsFunctionClass) hasFunction = true;
@@ -2223,7 +2516,9 @@
       else if (cls == backend.jsNumberClass) hasNumber = true;
       else if (cls == backend.jsStringClass) hasString = true;
       else {
-        assert(cls == compiler.objectClass);
+        // TODO(sra): The set of classes includes classes mixed-in to
+        // interceptor classes.
+        // assert(cls == compiler.objectClass || cls.isNative());
       }
     }
     if (hasDouble) {
@@ -2244,7 +2539,7 @@
           hasDouble ? backend.jsDoubleClass : backend.jsNumberClass);
 
       if (hasInt) {
-        jsAst.Expression isInt = js['Math']['floor'](receiver).equals(receiver);
+        jsAst.Expression isInt = js['Math.floor(receiver) == receiver'];
         whenNumber = js.block([
             js.if_(isInt, buildReturnInterceptor(backend.jsIntClass)),
             returnNumberClass]);
@@ -2252,7 +2547,7 @@
         whenNumber = returnNumberClass;
       }
       block.statements.add(
-          js.if_(receiver.typeof.equals(js.string('number')),
+          js.if_('(typeof receiver) == "number"',
                  whenNumber));
     }
 
@@ -2265,7 +2560,7 @@
       // Returning "undefined" here will provoke a JavaScript
       // TypeError which is later identified as a null-error by
       // [unwrapException] in js_helper.dart.
-      block.statements.add(js.if_(receiver.equals(new jsAst.LiteralNull()),
+      block.statements.add(js.if_('receiver == null',
                                   js.return_(js.undefined())));
     }
     if (hasFunction) {
@@ -2279,12 +2574,12 @@
     if (hasArray) {
       block.statements.add(buildInterceptorCheck(backend.jsArrayClass));
     }
-    block.statements.add(js.return_(receiver));
+    block.statements.add(js.return_(js['receiver']));
 
-    buffer.add(jsAst.prettyPrint(
+    buffer.write(jsAst.prettyPrint(
         js[isolateProperties][key].assign(js.fun(['receiver'], block)),
         compiler));
-    buffer.add(N);
+    buffer.write(N);
   }
 
   /**
@@ -2321,13 +2616,7 @@
     }
 
     // Finally, sort the classes.
-    List<ClassElement> sortedClasses = neededClasses.toList();
-    sortedClasses.sort((ClassElement class1, ClassElement class2) {
-      // We sort by the ids of the classes. There is no guarantee that these
-      // ids are meaningful (or even deterministic), but in the current
-      // implementation they are increasing within a source file.
-      return class1.id - class2.id;
-    });
+    List<ClassElement> sortedClasses = Elements.sortedByPosition(neededClasses);
 
     // If we need noSuchMethod support, we run through all needed
     // classes to figure out if we need the support on any native
@@ -2358,22 +2647,6 @@
     }
   }
 
-  int _compareSelectors(Selector selector1, Selector selector2) {
-    int comparison = _compareSelectorNames(selector1, selector2);
-    if (comparison != 0) return comparison;
-
-    Set<ClassElement> classes1 = backend.getInterceptedClassesOn(selector1);
-    Set<ClassElement> classes2 = backend.getInterceptedClassesOn(selector2);
-    if (classes1.length != classes2.length) {
-      return classes1.length - classes2.length;
-    }
-    String getInterceptor1 =
-        namer.getInterceptorName(backend.getInterceptorMethod, classes1);
-    String getInterceptor2 =
-        namer.getInterceptorName(backend.getInterceptorMethod, classes2);
-    return Comparable.compare(getInterceptor1, getInterceptor2);
-  }
-
   // Optimize performance critical one shot interceptors.
   jsAst.Statement tryOptimizeOneShotInterceptor(Selector selector,
                                                 Set<ClassElement> classes) {
@@ -2405,7 +2678,7 @@
         //    }
         // :].
         List<jsAst.Statement> body = <jsAst.Statement>[];
-        body.add(js.if_(js['receiver'].equals(new jsAst.LiteralNull()),
+        body.add(js.if_('receiver == null',
                         js.return_(js['a0'].equals(new jsAst.LiteralNull()))));
         body.add(js.if_(
             isNotObject('receiver'),
@@ -2557,8 +2830,8 @@
       jsAst.PropertyAccess property =
           js[isolateProperties][name];
 
-      buffer.add(jsAst.prettyPrint(property.assign(function), compiler));
-      buffer.add(N);
+      buffer.write(jsAst.prettyPrint(property.assign(function), compiler));
+      buffer.write(N);
     }
   }
 
@@ -2584,8 +2857,8 @@
         backend.usedInterceptors.length,
         elements);
 
-    buffer.add(jsAst.prettyPrint(property.assign(array), compiler));
-    buffer.add(N);
+    buffer.write(jsAst.prettyPrint(property.assign(array), compiler));
+    buffer.write(N);
   }
 
   void emitInitFunction(CodeBuffer buffer) {
@@ -2598,7 +2871,7 @@
     );
     jsAst.FunctionDeclaration decl = new jsAst.FunctionDeclaration(
         new jsAst.VariableDeclaration('init'), fun);
-    buffer.add(jsAst.prettyPrint(decl, compiler).getText());
+    buffer.write(jsAst.prettyPrint(decl, compiler).getText());
   }
 
   String assembleProgram() {
@@ -2637,8 +2910,8 @@
         for (ClassElement element in nativeClasses) {
           nativeEmitter.generateNativeClass(element);
         }
-        nativeEmitter.assembleCode(nativeBuffer);
       }
+      nativeEmitter.assembleCode(nativeBuffer);
 
       // Might also create boundClosures.
       if (!regularClasses.isEmpty) {
@@ -2666,6 +2939,7 @@
 
       emitClosureClassIfNeeded(mainBuffer);
 
+      addComment('Bound closures', mainBuffer);
       // Now that we have emitted all classes, we know all the bound
       // closures that will be needed.
       for (jsAst.Node node in boundClosures) {
@@ -2724,9 +2998,10 @@
   void emitDeferredCode(CodeBuffer buffer) {
     if (buffer.isEmpty) return;
 
-    buffer.add(n);
+    buffer.write(n);
 
-    buffer.add('${namer.CURRENT_ISOLATE}$_=${_}old${namer.CURRENT_ISOLATE}$N');
+    buffer.write(
+        '${namer.CURRENT_ISOLATE}$_=${_}old${namer.CURRENT_ISOLATE}$N');
 
     String code = buffer.getText();
     compiler.outputProvider('part', 'js')
@@ -2738,17 +3013,17 @@
   void emitDeferredPreambleWhenEmpty(CodeBuffer buffer) {
     if (!buffer.isEmpty) return;
 
-    buffer.add(GENERATED_BY);
+    buffer.write(GENERATED_BY);
 
-    buffer.add('var old${namer.CURRENT_ISOLATE}$_='
-               '$_${namer.CURRENT_ISOLATE}$N');
+    buffer.write('var old${namer.CURRENT_ISOLATE}$_='
+                 '$_${namer.CURRENT_ISOLATE}$N');
 
     // TODO(ahe): This defines a lot of properties on the
     // Isolate.prototype object.  We know this will turn it into a
     // slow object in V8, so instead we should do something similar to
     // Isolate.$finishIsolateConstructor.
-    buffer.add('${namer.CURRENT_ISOLATE}$_='
-               '$_${namer.isolateName}.prototype$N$n');
+    buffer.write('${namer.CURRENT_ISOLATE}$_='
+                 '$_${namer.isolateName}.prototype$N$n');
   }
 
   String buildSourceMap(CodeBuffer buffer, SourceFile compiledFile) {
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter_no_eval.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter_no_eval.dart
index 52a237c..4d27f89 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter_no_eval.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter_no_eval.dart
@@ -11,6 +11,7 @@
       : super(compiler, namer, generateSourceMap);
 
   bool get getterAndSetterCanBeImplementedByFieldSpec => false;
+  bool get generateTrivialNsmHandlers => false;
 
   void emitSuper(String superName, ClassBuilder builder) {
     if (superName != '') {
@@ -115,7 +116,7 @@
           js.fun([], [
             js['var hasOwnProperty = Object.prototype.hasOwnProperty'],
             js.forIn('staticName', 'isolateProperties',
-              js.if_(js['hasOwnProperty.call(isolateProperties, staticName)'],
+              js.if_('hasOwnProperty.call(isolateProperties, staticName)',
                 js['this[staticName] = isolateProperties[staticName]'])),
             // Use the newly created object as prototype. In Chrome,
             // this creates a hidden class for the object and makes
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/minify_namer.dart b/sdk/lib/_internal/compiler/implementation/js_backend/minify_namer.dart
index e19a442..e459ba0 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/minify_namer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/minify_namer.dart
@@ -85,22 +85,24 @@
       if (_hasBannedPrefix(name)) usedInstanceNames.add(name.substring(1));
     }
 
-    // This list of popular instance variable names generated with:
-    // cat out.js |
-    // perl -ne '$_=~s/(?<![^a-z0-9_\$]\$)\.([a-z0-9_\$]+)/print("$1\n")/gei' |
-    // sort | uniq -c | sort -nr | head -40
-    // Removed: html, call*, hasOwnProperty.
+    // These popular names are present in most programs and deserve
+    // single character minified names.  We could determine the popular names
+    // individually per program, but that would mean that the output of the
+    // minifier was less stable from version to version of the program being
+    // minified.
     _populateSuggestedNames(
         suggestedInstanceNames,
         usedInstanceNames,
         const <String>[
-            r'$add', r'add$1', r'box_0', r'codeUnitAt$1', r'constructor',
-            r'current', r'$defineNativeClass', r'$eq', r'$ne',
+            r'$add', r'add$1', r'$and', r'codeUnitAt$1', r'$or',
+            r'current', r'$shr', r'$eq', r'$ne',
             r'getPrototypeOf', r'hasOwnProperty', r'$index', r'$indexSet',
-            r'$isJavaScriptIndexingBehavior', r'$isolateProperties',
+            r'$isJavaScriptIndexingBehavior', r'$xor',
             r'iterator', r'length', r'$lt', r'$gt', r'$le', r'$ge',
-            r'moveNext$0', r'node', r'on', r'prototype', r'push', r'self',
-            r'start', r'target', r'this_0', r'value', r'width', r'style']);
+            r'moveNext$0', r'node', r'on', r'$negate', r'push', r'self',
+            r'start', r'target', r'$shl', r'value', r'width', r'style',
+            r'noSuchMethod$1', r'$mul', r'$div', r'$sub', r'$not', r'$mod',
+            r'$tdiv']);
 
     _populateSuggestedNames(
         suggestedGlobalNames,
@@ -116,7 +118,7 @@
             r'List_List$from', r'Set_Set$from', r'toString', r'toInt', r'min',
             r'StringBuffer_StringBuffer', r'contains1', r'WhereIterable$',
             r'RangeError$value', r'JSString', r'JSNumber',
-            r'JSArray'
+            r'JSArray', r'createInvocationMirror'
             ]);
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
index 4ac6919..1d52f46 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
@@ -246,7 +246,14 @@
           longName = "C";
         }
       } else {
-        longName = "CONSTANT";
+        if (constant.isInterceptor()) {
+          InterceptorConstant interceptorConstant = constant;
+          String typeName =
+              interceptorConstant.dispatchedType.element.name.slowToString();
+          longName = typeName + '_methods';
+        } else {
+          longName = "CONSTANT";
+        }
       }
       result = getFreshName(longName, usedGlobalNames, suggestedGlobalNames,
                             ensureSafe: true);
@@ -442,11 +449,11 @@
     return '$getterPrefix$name';
   }
 
-  String getMappedGlobalName(String proposedName) {
+  String getMappedGlobalName(String proposedName, {bool ensureSafe: true}) {
     var newName = globalNameMap[proposedName];
     if (newName == null) {
       newName = getFreshName(proposedName, usedGlobalNames,
-                             suggestedGlobalNames, ensureSafe: true);
+                             suggestedGlobalNames, ensureSafe: ensureSafe);
       globalNameMap[proposedName] = newName;
     }
     return newName;
@@ -545,9 +552,16 @@
       if (cls == backend.jsBoolClass) return "b";
       return cls.name.slowToString();
     }
+    List<String> names = classes
+        .where((cls) => !cls.isNative())
+        .map(abbreviate)
+        .toList();
+    // There is one dispatch mechanism for all native classes.
+    if (classes.any((cls) => cls.isNative())) {
+      names.add("x");
+    }
     // Sort the names of the classes after abbreviating them to ensure
     // the suffix is stable and predictable for the suggested names.
-    List<String> names = classes.map(abbreviate).toList();
     names.sort();
     return names.join();
   }
@@ -564,8 +578,25 @@
 
   String getOneShotInterceptorName(Selector selector,
                                    Collection<ClassElement> classes) {
-    String suffix = getInterceptorSuffix(classes);
-    return getMappedGlobalName("${invocationName(selector)}\$$suffix");
+    // The one-shot name is a global name derived from the invocation name.  To
+    // avoid instability we would like the names to be unique and not clash with
+    // other global names.
+
+    String root = invocationName(selector);  // Is already safe.
+
+    if (classes.contains(compiler.objectClass)) {
+      // If the object class is in the set of intercepted classes, this is the
+      // most general specialization which uses the generic getInterceptor
+      // method.  To keep the name short, we add '$' only to distinguish from
+      // global getters or setters; operators and methods can't clash.
+      // TODO(sra): Find a way to get the simple name when Object is not in the
+      // set of classes for most general variant, e.g. "$lt$n" could be "$lt".
+      if (selector.isGetter() || selector.isSetter()) root = '$root\$';
+      return getMappedGlobalName(root, ensureSafe: false);
+    } else {
+      String suffix = getInterceptorSuffix(classes);
+      return getMappedGlobalName("$root\$$suffix", ensureSafe: false);
+    }
   }
 
   String getBailoutName(Element element) {
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
index 8e389bf..838c7a8 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
@@ -191,6 +191,7 @@
 
   List<jsAst.Statement> generateParameterStubStatements(
       Element member,
+      bool isInterceptedMethod,
       String invocationName,
       List<jsAst.Parameter> stubParameters,
       List<jsAst.Expression> argumentsBuffer,
@@ -211,6 +212,7 @@
     potentiallyConvertDartClosuresToJs(statements, member, stubParameters);
 
     String target;
+    jsAst.Expression receiver;
     List<jsAst.Expression> arguments;
 
     if (!nativeMethods.contains(member)) {
@@ -222,12 +224,18 @@
       // When calling a JS method, we call it with the native name, and only the
       // arguments up until the last one provided.
       target = member.fixedBackendName();
-      arguments = argumentsBuffer.getRange(
-          0, indexOfLastOptionalArgumentInParameters + 1);
+
+      if (isInterceptedMethod) {
+        receiver = argumentsBuffer[0];
+        arguments = argumentsBuffer.sublist(1,
+            indexOfLastOptionalArgumentInParameters + 1);
+      } else {
+        receiver = new jsAst.VariableUse('this');
+        arguments = argumentsBuffer.sublist(0,
+            indexOfLastOptionalArgumentInParameters + 1);
+      }
     }
-    statements.add(
-        new jsAst.Return(
-            new jsAst.VariableUse('this')[target](arguments)));
+    statements.add(new jsAst.Return(receiver[target](arguments)));
 
     if (!overriddenMethods.contains(member)) {
       // Call the method directly.
@@ -365,6 +373,7 @@
       walk(classElement);
 
       if (!subtags.isEmpty) {
+        subtags.sort();
         expressions.add(js.string(subtags.join('|')));
       }
       jsAst.Expression expression;
@@ -455,11 +464,6 @@
   }
 
   void assembleCode(CodeBuffer targetBuffer) {
-    if (nativeClasses.isEmpty) return;
-    emitDynamicDispatchMetadata();
-    targetBuffer.add('$defineNativeClassName = '
-                     '$defineNativeClassFunction$N$n');
-
     List<jsAst.Property> objectProperties = <jsAst.Property>[];
 
     void addProperty(String name, jsAst.Expression value) {
@@ -476,9 +480,13 @@
                Elements.sortedByPosition(emitter.checkedClasses)) {
         if (!requiresNativeIsCheck(element)) continue;
         if (element.isObject(compiler)) continue;
+        // Add function for the is-test.
         String name = backend.namer.operatorIs(element);
         addProperty(name,
             js.fun([], js.return_(js['false'])));
+        // Add a function for the (trivial) substitution.
+        addProperty(backend.namer.substitutionName(element),
+                    js.fun([], js.return_(js['null'])));
       }
     }
     emitIsChecks();
@@ -489,29 +497,35 @@
       return js.fun(['_'], js.return_(js['$functionName(this)']));
     }
 
-    // In order to have the toString method on every native class,
-    // we must patch the JS Object prototype with a helper method.
-    String toStringName = backend.namer.publicInstanceMethodNameByArity(
-        const SourceString('toString'), 0);
-    addProperty(toStringName, makeCallOnThis(toStringHelperName));
+    if (!nativeClasses.isEmpty) {
+      emitDynamicDispatchMetadata();
+      targetBuffer.add('$defineNativeClassName = '
+                       '$defineNativeClassFunction$N$n');
 
-    // Same as above, but for hashCode.
-    String hashCodeName =
-        backend.namer.publicGetterName(const SourceString('hashCode'));
-    addProperty(hashCodeName, makeCallOnThis(hashCodeHelperName));
+      // In order to have the toString method on every native class,
+      // we must patch the JS Object prototype with a helper method.
+      String toStringName = backend.namer.publicInstanceMethodNameByArity(
+          const SourceString('toString'), 0);
+      addProperty(toStringName, makeCallOnThis(toStringHelperName));
 
-    // Same as above, but for operator==.
-    String equalsName = backend.namer.publicInstanceMethodNameByArity(
-        const SourceString('=='), 1);
-    // Because we know the function is intercepted, we need an extra
-    // parameter.
-    addProperty(equalsName, js.fun(['_', 'a'],
-        js.return_(js['this === a'])));
+      // Same as above, but for hashCode.
+      String hashCodeName =
+          backend.namer.publicGetterName(const SourceString('hashCode'));
+      addProperty(hashCodeName, makeCallOnThis(hashCodeHelperName));
 
-    // If the native emitter has been asked to take care of the
-    // noSuchMethod handlers, we do that now.
-    if (handleNoSuchMethod) {
-      emitter.emitNoSuchMethodHandlers(addProperty);
+      // Same as above, but for operator==.
+      String equalsName = backend.namer.publicInstanceMethodNameByArity(
+          const SourceString('=='), 1);
+      // Because we know the function is intercepted, we need an extra
+      // parameter.
+      addProperty(equalsName, js.fun(['_', 'a'],
+          js.return_(js['this === a'])));
+
+      // If the native emitter has been asked to take care of the
+      // noSuchMethod handlers, we do that now.
+      if (handleNoSuchMethod) {
+        emitter.emitNoSuchMethodHandlers(addProperty);
+      }
     }
 
     // If we have any properties to add to Object.prototype, we run
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
index e893075..51be7e5 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
@@ -12,10 +12,24 @@
   Iterator<ClassElement> get iterator;
 }
 
-class RuntimeTypeInformation {
+class RuntimeTypes {
   final Compiler compiler;
+  final TypeRepresentationGenerator representationGenerator;
 
-  RuntimeTypeInformation(this.compiler);
+  final Map<ClassElement, Set<ClassElement>> rtiDependencies;
+  final Set<ClassElement> classesNeedingRti;
+  // The set of classes that use one of their type variables as expressions
+  // to get the runtime type.
+  final Set<ClassElement> classesUsingTypeVariableExpression;
+
+  JavaScriptBackend get backend => compiler.backend;
+
+  RuntimeTypes(Compiler compiler)
+      : this.compiler = compiler,
+        representationGenerator = new TypeRepresentationGenerator(compiler),
+        classesNeedingRti = new Set<ClassElement>(),
+        rtiDependencies = new Map<ClassElement, Set<ClassElement>>(),
+        classesUsingTypeVariableExpression = new Set<ClassElement>();
 
   /// Contains the classes of all arguments that have been used in
   /// instantiations and checks.
@@ -30,6 +44,76 @@
             element == compiler.listClass);
   }
 
+  void registerRtiDependency(Element element, Element dependency) {
+    // We're not dealing with typedef for now.
+    if (!element.isClass() || !dependency.isClass()) return;
+    Set<ClassElement> classes =
+        rtiDependencies.putIfAbsent(element, () => new Set<ClassElement>());
+    classes.add(dependency);
+  }
+
+  void computeClassesNeedingRti() {
+    // Find the classes that need runtime type information. Such
+    // classes are:
+    // (1) used in a is check with type variables,
+    // (2) dependencies of classes in (1),
+    // (3) subclasses of (2) and (3).
+    void potentiallyAddForRti(ClassElement cls) {
+      if (cls.typeVariables.isEmpty) return;
+      if (classesNeedingRti.contains(cls)) return;
+      classesNeedingRti.add(cls);
+
+      // TODO(ngeoffray): This should use subclasses, not subtypes.
+      Set<ClassElement> classes = compiler.world.subtypes[cls];
+      if (classes != null) {
+        classes.forEach((ClassElement sub) {
+          potentiallyAddForRti(sub);
+        });
+      }
+
+      Set<ClassElement> dependencies = rtiDependencies[cls];
+      if (dependencies != null) {
+        dependencies.forEach((ClassElement other) {
+          potentiallyAddForRti(other);
+        });
+      }
+    }
+
+    Set<ClassElement> classesUsingTypeVariableTests = new Set<ClassElement>();
+    compiler.resolverWorld.isChecks.forEach((DartType type) {
+      if (type.kind == TypeKind.TYPE_VARIABLE) {
+        TypeVariableElement variable = type.element;
+        classesUsingTypeVariableTests.add(variable.enclosingElement);
+      }
+    });
+    // Add is-checks that result from classes using type variables in checks.
+    compiler.resolverWorld.addImplicitChecks(classesUsingTypeVariableTests);
+    // Add the rti dependencies that are implicit in the way the backend
+    // generates code: when we create a new [List], we actually create
+    // a JSArray in the backend and we need to add type arguments to
+    // the calls of the list constructor whenever we determine that
+    // JSArray needs type arguments.
+    // TODO(karlklose): make this dependency visible from code.
+    if (backend.jsArrayClass != null) {
+      registerRtiDependency(backend.jsArrayClass, compiler.listClass);
+    }
+    // Compute the set of all classes that need runtime type information.
+    compiler.resolverWorld.isChecks.forEach((DartType type) {
+      if (type.kind == TypeKind.INTERFACE) {
+        InterfaceType itf = type;
+        if (!itf.isRaw) {
+          potentiallyAddForRti(itf.element);
+        }
+      } else if (type.kind == TypeKind.TYPE_VARIABLE) {
+        TypeVariableElement variable = type.element;
+        potentiallyAddForRti(variable.enclosingElement);
+      }
+    });
+    // Add the classes that need RTI because they use a type variable as
+    // expression.
+    classesUsingTypeVariableExpression.forEach(potentiallyAddForRti);
+  }
+
   TypeChecks cachedRequiredChecks;
 
   TypeChecks getRequiredChecks() {
@@ -63,15 +147,6 @@
       }
     }
 
-    // TODO(karlklose): remove this temporary fix: we need to add the classes
-    // used in substitutions to addArguments.
-    allArguments.addAll([compiler.intClass,
-                         compiler.boolClass,
-                         compiler.numClass,
-                         compiler.doubleClass,
-                         compiler.stringClass,
-                         compiler.listClass]);
-
     return cachedRequiredChecks = requiredChecks;
   }
 
@@ -83,29 +158,29 @@
    * the type arguments.
    */
   Set<ClassElement> getInstantiatedArguments() {
-    Set<ClassElement> instantiatedArguments = new Set<ClassElement>();
+    ArgumentCollector collector = new ArgumentCollector();
     for (DartType type in instantiatedTypes) {
-      addAllInterfaceTypeArguments(type, instantiatedArguments);
+      collector.collect(type);
       ClassElement cls = type.element;
-      for (DartType type in cls.allSupertypes) {
-        addAllInterfaceTypeArguments(type, instantiatedArguments);
+      for (DartType supertype in cls.allSupertypes) {
+        collector.collect(supertype);
       }
     }
-    for (ClassElement cls in instantiatedArguments.toList()) {
-      for (DartType type in cls.allSupertypes) {
-        addAllInterfaceTypeArguments(type, instantiatedArguments);
+    for (ClassElement cls in collector.classes.toList()) {
+      for (DartType supertype in cls.allSupertypes) {
+        collector.collect(supertype);
       }
     }
-    return instantiatedArguments;
+    return collector.classes;
   }
 
   /// Collects all type arguments used in is-checks.
   Set<ClassElement> getCheckedArguments() {
-    Set<ClassElement> checkedArguments = new Set<ClassElement>();
+    ArgumentCollector collector = new ArgumentCollector();
     for (DartType type in isChecks) {
-      addAllInterfaceTypeArguments(type, checkedArguments);
+      collector.collect(type);
     }
-    return checkedArguments;
+    return collector.classes;
   }
 
   Iterable<DartType> get isChecks {
@@ -116,28 +191,6 @@
     return compiler.codegenWorld.instantiatedTypes;
   }
 
-  void addAllInterfaceTypeArguments(DartType type, Set<ClassElement> classes) {
-    if (type is !InterfaceType) return;
-    for (DartType argument in type.typeArguments) {
-      forEachInterfaceType(argument, (InterfaceType t) {
-        ClassElement cls = t.element;
-        if (cls != compiler.dynamicClass) {
-          classes.add(cls);
-        }
-      });
-    }
-  }
-
-  void forEachInterfaceType(DartType type, f(InterfaceType type)) {
-    if (type.kind == TypeKind.INTERFACE) {
-      f(type);
-      InterfaceType interface = type;
-      for (DartType argument in interface.typeArguments) {
-        forEachInterfaceType(argument, f);
-      }
-    }
-  }
-
   /// Return the unique name for the element as an unquoted string.
   String getNameAsString(Element element) {
     JavaScriptBackend backend = compiler.backend;
@@ -212,17 +265,22 @@
    *     a list expression.
    */
   String getSupertypeSubstitution(ClassElement cls, ClassElement check,
-                                  {alwaysGenerateFunction: false}) {
+                                  {bool alwaysGenerateFunction: false}) {
     if (isTrivialSubstitution(cls, check)) return null;
 
     // TODO(karlklose): maybe precompute this value and store it in typeChecks?
+    bool usesTypeVariables = false;
+    String onVariable(TypeVariableType v) {
+      usesTypeVariables = true;
+      return v.toString();
+    };
     InterfaceType type = cls.computeType(compiler);
     InterfaceType target = type.asInstanceOf(check);
     String substitution = target.typeArguments
-        .map((type) => _getTypeRepresentation(type, (v) => v.toString()))
+        .map((type) => _getTypeRepresentation(type, onVariable))
         .join(', ');
     substitution = '[$substitution]';
-    if (cls.typeVariables.isEmpty && !alwaysGenerateFunction) {
+    if (!usesTypeVariables && !alwaysGenerateFunction) {
       return substitution;
     } else {
       String parameters = cls.typeVariables.toList().join(', ');
@@ -241,34 +299,7 @@
 
   // TODO(karlklose): rewrite to use js.Expressions.
   String _getTypeRepresentation(DartType type, String onVariable(variable)) {
-    StringBuffer builder = new StringBuffer();
-    void build(DartType part) {
-      if (part is TypeVariableType) {
-        builder.write(onVariable(part));
-      } else {
-        bool hasArguments = part is InterfaceType && !part.isRaw;
-        Element element = part.element;
-        if (element == compiler.dynamicClass) {
-          builder.write('null');
-        } else {
-          String name = getJsName(element);
-          if (!hasArguments) {
-            builder.write(name);
-          } else {
-            builder.write('[');
-            builder.write(name);
-            InterfaceType interface = part;
-            for (DartType argument in interface.typeArguments) {
-              builder.write(', ');
-              build(argument);
-            }
-            builder.write(']');
-          }
-        }
-      }
-    }
-    build(type);
-    return builder.toString();
+    return representationGenerator.getTypeRepresentation(type, onVariable);
   }
 
   static bool hasTypeArguments(DartType type) {
@@ -279,16 +310,125 @@
     return false;
   }
 
-  static int getTypeVariableIndex(TypeVariableType variable) {
-    ClassElement classElement = variable.element.getEnclosingClass();
+  static int getTypeVariableIndex(TypeVariableElement variable) {
+    ClassElement classElement = variable.getEnclosingClass();
     Link<DartType> variables = classElement.typeVariables;
     for (int index = 0; !variables.isEmpty;
          index++, variables = variables.tail) {
-      if (variables.head == variable) return index;
+      if (variables.head.element == variable) return index;
     }
   }
 }
 
+typedef String OnVariableCallback(TypeVariableType type);
+
+class TypeRepresentationGenerator extends DartTypeVisitor {
+  final Compiler compiler;
+  OnVariableCallback onVariable;
+  StringBuffer builder;
+
+  TypeRepresentationGenerator(Compiler this.compiler);
+
+  /**
+   * Creates a type representation for [type]. [onVariable] is called to provide
+   * the type representation for type variables.
+   */
+  String getTypeRepresentation(DartType type, OnVariableCallback onVariable) {
+    this.onVariable = onVariable;
+    builder = new StringBuffer();
+    visit(type);
+    String typeRepresentation = builder.toString();
+    builder = null;
+    this.onVariable = null;
+    return typeRepresentation;
+  }
+
+  String getJsName(Element element) {
+    JavaScriptBackend backend = compiler.backend;
+    Namer namer = backend.namer;
+    return namer.isolateAccess(element);
+  }
+
+  visit(DartType type) {
+    type.unalias(compiler).accept(this, null);
+  }
+
+  visitTypeVariableType(TypeVariableType type, _) {
+    builder.write(onVariable(type));
+  }
+
+  visitDynamicType(DynamicType type, _) {
+    builder.write('null');
+  }
+
+  visitInterfaceType(InterfaceType type, _) {
+    String name = getJsName(type.element);
+    if (type.isRaw) {
+      builder.write(name);
+    } else {
+      builder.write('[');
+      builder.write(name);
+      builder.write(', ');
+      visitList(type.typeArguments);
+      builder.write(']');
+    }
+  }
+
+  visitList(Link<DartType> types) {
+    bool first = true;
+    for (Link<DartType> link = types; !link.isEmpty; link = link.tail) {
+      if (!first) {
+        builder.write(', ');
+      }
+      visit(link.head);
+      first = false;
+    }
+  }
+
+  visitFunctionType(FunctionType type, _) {
+    builder.write('{func: true');
+    if (type.returnType.isVoid) {
+      builder.write(', retvoid: true');
+    } else if (!type.returnType.isDynamic) {
+      builder.write(', ret: ');
+      visit(type.returnType);
+    }
+    if (!type.parameterTypes.isEmpty) {
+      builder.write(', args: [');
+      visitList(type.parameterTypes);
+      builder.write(']');
+    }
+    if (!type.optionalParameterTypes.isEmpty) {
+      builder.write(', opt: [');
+      visitList(type.optionalParameterTypes);
+      builder.write(']');
+    }
+    if (!type.namedParameterTypes.isEmpty) {
+      builder.write(', named: {');
+      bool first = true;
+      Link<SourceString> names = type.namedParameters;
+      Link<DartType> types = type.namedParameterTypes;
+      while (!types.isEmpty) {
+        assert(!names.isEmpty);
+        if (!first) {
+          builder.write(', ');
+        }
+        builder.write('${names.head.slowToString()}: ');
+        visit(types.head);
+        first = false;
+        names = names.tail;
+        types = types.tail;
+      }
+      builder.write('}');
+    }
+    builder.write('}');
+  }
+
+  visitType(DartType type, _) {
+    compiler.internalError('Unexpected type: $type');
+  }
+}
+
 class TypeCheckMapping implements TypeChecks {
   final Map<ClassElement, Set<ClassElement>> map =
       new Map<ClassElement, Set<ClassElement>>();
@@ -309,9 +449,50 @@
     StringBuffer sb = new StringBuffer();
     for (ClassElement holder in this) {
       for (ClassElement check in [holder]) {
-        sb.add('${holder.name.slowToString()}.${check.name.slowToString()}, ');
+        sb.write('${holder.name.slowToString()}.'
+                 '${check.name.slowToString()}, ');
       }
     }
     return '[$sb]';
   }
 }
+
+class ArgumentCollector extends DartTypeVisitor {
+  final Set<ClassElement> classes = new Set<ClassElement>();
+
+  collect(DartType type) {
+    type.accept(this, false);
+  }
+
+  visit(DartType type) {
+    type.accept(this, true);
+  }
+
+  visitList(Link<DartType> types) {
+    for (Link<DartType> link = types; !link.isEmpty; link = link.tail) {
+      link.head.accept(this, true);
+    }
+  }
+
+  visitType(DartType type, _) {
+    // Do nothing.
+  }
+
+  visitDynamicType(DynamicType type, _) {
+    // Do not collect [:dynamic:].
+  }
+
+  visitInterfaceType(InterfaceType type, bool isTypeArgument) {
+    if (isTypeArgument) {
+      classes.add(type.element);
+    }
+    visitList(type.typeArguments);
+  }
+
+  visitFunctionType(FunctionType type, _) {
+    visit(type.returnType);
+    visitList(type.parameterTypes);
+    visitList(type.optionalParameterTypes);
+    visitList(type.namedParameterTypes);
+  }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/lib/async_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/async_patch.dart
index ade4c99..9d8b237e 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/async_patch.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/async_patch.dart
@@ -14,10 +14,17 @@
     return new TimerImpl(milliseconds, callback);
   }
 
-  patch factory Timer.repeating(Duration duration, void callback(Timer timer)) {
+  patch factory Timer.periodic(Duration duration, void callback(Timer timer)) {
     int milliseconds = duration.inMilliseconds;
     if (milliseconds < 0) milliseconds = 0;
-    return new TimerImpl.repeating(milliseconds, callback);
+    return new TimerImpl.periodic(milliseconds, callback);
+  }
+}
+
+patch class _AsyncRun {
+  patch static void _enqueueImmediate(void callback()) {
+    // TODO(9002): don't use the Timer to enqueue the immediate callback.
+    Timer.run(callback);
   }
 }
 
diff --git a/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart
index 1da20f6..f7e21aa 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart
@@ -193,9 +193,8 @@
 
 
 patch class String {
-  patch factory String.fromCharCodes(List<int> charCodes) {
+  patch factory String.fromCharCodes(Iterable<int> charCodes) {
     if (!isJsArray(charCodes)) {
-      if (charCodes is !List) throw new ArgumentError(charCodes);
       charCodes = new List.from(charCodes);
     }
     return Primitives.stringFromCharCodes(charCodes);
@@ -234,6 +233,10 @@
     _contents = Primitives.stringConcatUnchecked(_contents, str);
   }
 
+  patch void writeCharCode(int charCode) {
+    write(new String.fromCharCode(charCode));
+  }
+
   patch void clear() {
     _contents = "";
   }
@@ -248,19 +251,19 @@
     if (_arguments != null) {
       for (; i < _arguments.length; i++) {
         if (i > 0) {
-          sb.add(", ");
+          sb.write(", ");
         }
-        sb.add(Error.safeToString(_arguments[i]));
+        sb.write(Error.safeToString(_arguments[i]));
       }
     }
     if (_namedArguments != null) {
       _namedArguments.forEach((String key, var value) {
         if (i > 0) {
-          sb.add(", ");
+          sb.write(", ");
         }
-        sb.add(key);
-        sb.add(": ");
-        sb.add(Error.safeToString(value));
+        sb.write(key);
+        sb.write(": ");
+        sb.write(Error.safeToString(value));
         i++;
       });
     }
@@ -273,9 +276,9 @@
       sb = new StringBuffer();
       for (int i = 0; i < _existingArgumentNames.length; i++) {
         if (i > 0) {
-          sb.add(", ");
+          sb.write(", ");
         }
-        sb.add(_existingArgumentNames[i]);
+        sb.write(_existingArgumentNames[i]);
       }
       String formalParameters = sb.toString();
       return "NoSuchMethodError: incorrect number of arguments passed to "
@@ -296,4 +299,3 @@
     throw new UnsupportedError('stackTrace');
   }
 }
-
diff --git a/sdk/lib/_internal/compiler/implementation/lib/interceptors.dart b/sdk/lib/_internal/compiler/implementation/lib/interceptors.dart
index 5676e1d..f7c7cb8 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/interceptors.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/interceptors.dart
@@ -76,13 +76,29 @@
 
 /**
  * The interceptor class for [Null].
+ *
+ * This class defines implementations for *all* methods on [Object] since the
+ * the methods on Object assume the receiver is non-null.  This means that
+ * JSNull will always be in the interceptor set for methods defined on Object.
  */
 class JSNull implements Null {
   const JSNull();
 
+  bool operator ==(other) => identical(null, other);
+
   // Note: if you change this, also change the function [S].
   String toString() => 'null';
 
   int get hashCode => 0;
+
   Type get runtimeType => Null;
 }
+
+
+/**
+ * The supertype for JSString and JSArray. Used by the backend as to
+ * have a type mask that contains the primitive objects that we can
+ * use the [] operator on.
+ */
+class JSIndexable {
+}
diff --git a/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart
index ed10807..915b2f7 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart
@@ -53,6 +53,12 @@
   }
 }
 
+patch class FileSystemEntity {
+  patch static int _getType(String path, bool followLinks) {
+    throw new UnsupportedError("FileSystemEntity._getType");
+  }
+}
+
 patch class _File {
   patch static _exists(String path) {
     throw new UnsupportedError("File._exists");
@@ -60,6 +66,9 @@
   patch static _create(String path) {
     throw new UnsupportedError("File._create");
   }
+  patch static _createLink(String path, String target) {
+    throw new UnsupportedError("File._createLink");
+  }
   patch static _delete(String path) {
     throw new UnsupportedError("File._delete");
   }
@@ -235,3 +244,12 @@
     throw new UnsupportedError("_WindowsCodePageEncoder._encodeString");
   }
 }
+
+patch class _Filter {
+  patch static _Filter newZLibDeflateFilter(bool gzip, int level) {
+    throw new UnsupportedError("newZLibDeflateFilter");
+  }
+  patch static _Filter newZLibInflateFilter() {
+    throw new UnsupportedError("newZLibInflateFilter");
+  }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/lib/isolate_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/isolate_helper.dart
index 539e7b4..5b09ac9 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/isolate_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/isolate_helper.dart
@@ -1224,7 +1224,7 @@
 
   deserialize(x) {
     if (isPrimitive(x)) return x;
-    // TODO(floitsch): this should be new HashMap<int, var|Dynamic>()
+    // TODO(floitsch): this should be new HashMap<int, dynamic>()
     _deserialized = new HashMap();
     return _deserializeHelper(x);
   }
@@ -1318,7 +1318,7 @@
     }
   }
 
-  TimerImpl.repeating(int milliseconds, void callback(Timer timer))
+  TimerImpl.periodic(int milliseconds, void callback(Timer timer))
       : _once = false {
     if (hasTimer()) {
       _globalState.topEventLoop.activeTimerCount++;
@@ -1327,7 +1327,7 @@
                    convertDartClosureToJS(() { callback(this); }, 0),
                    milliseconds);
     } else {
-      throw new UnsupportedError("Repeating timer.");
+      throw new UnsupportedError("Periodic timer.");
     }
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/lib/isolate_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/isolate_patch.dart
index aab847a..2514d60 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/isolate_patch.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/isolate_patch.dart
@@ -18,6 +18,7 @@
 
   patch static SendPort spawnFunction(void topLevelFunction(),
       [bool UnhandledExceptionCallback(IsolateUnhandledException e)]) {
+    // TODO(9012): Don't ignore the UnhandledExceptionCallback.
     return IsolateNatives.spawnFunction(topLevelFunction);
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_array.dart b/sdk/lib/_internal/compiler/implementation/lib/js_array.dart
index 9b73f40..c86a14f 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_array.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_array.dart
@@ -10,7 +10,7 @@
  * actually use the receiver of the method, which is generated as an extra
  * argument added to each member.
  */
-class JSArray<E> implements List<E> {
+class JSArray<E> implements List<E>, JSIndexable {
   const JSArray();
 
   void add(E value) {
@@ -27,6 +27,15 @@
     return JS('var', r'#.splice(#, 1)[0]', this, index);
   }
 
+  void insert(int index, E value) {
+    if (index is !int) throw new ArgumentError(index);
+    if (index < 0 || index > length) {
+      throw new RangeError.value(index);
+    }
+    checkGrowable(this, 'insert');
+    JS('void', r'#.splice(#, 0, #)', this, index, value);
+  }
+
   E removeLast() {
     checkGrowable(this, 'removeLast');
     if (length == 0) throw new RangeError.value(-1);
@@ -51,14 +60,14 @@
     IterableMixinWorkaround.retainAll(this, elements);
   }
 
-  void removeMatching(bool test(E element)) {
+  void removeWhere(bool test(E element)) {
     // This could, and should, be optimized.
-    IterableMixinWorkaround.removeMatchingList(this, test);
+    IterableMixinWorkaround.removeWhereList(this, test);
   }
 
-  void retainMatching(bool test(E element)) {
-    IterableMixinWorkaround.removeMatchingList(this,
-                                               (E element) => !test(element));
+  void retainWhere(bool test(E element)) {
+    IterableMixinWorkaround.removeWhereList(this,
+                                            (E element) => !test(element));
   }
 
   Iterable<E> where(bool f(E element)) {
@@ -121,39 +130,46 @@
     return IterableMixinWorkaround.reduce(this, initialValue, combine);
   }
 
-  E firstMatching(bool test(E value), {E orElse()}) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  E firstWhere(bool test(E value), {E orElse()}) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  E lastMatching(bool test(E value), {E orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  E lastWhere(bool test(E value), {E orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  E singleMatching(bool test(E value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  E singleWhere(bool test(E value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   E elementAt(int index) {
     return this[index];
   }
 
-  List<E> getRange(int start, int length) {
-    // TODO(ngeoffray): Parameterize the return value.
-    if (0 == length) return [];
+  List<E> sublist(int start, [int end]) {
     checkNull(start); // TODO(ahe): This is not specified but co19 tests it.
-    checkNull(length); // TODO(ahe): This is not specified but co19 tests it.
     if (start is !int) throw new ArgumentError(start);
-    if (length is !int) throw new ArgumentError(length);
-    if (length < 0) throw new ArgumentError(length);
-    if (start < 0) throw new RangeError.value(start);
-    int end = start + length;
-    if (end > this.length) {
-      throw new RangeError.value(length);
+    if (start < 0 || start > length) {
+      throw new RangeError.range(start, 0, length);
     }
-    if (length < 0) throw new ArgumentError(length);
+    if (end == null) {
+      end = length;
+    } else {
+      if (end is !int) throw new ArgumentError(end);
+      if (end < start || end > length) {
+        throw new RangeError.range(end, start, length);
+      }
+    }
+    // TODO(ngeoffray): Parameterize the return value.
+    if (start == end) return [];
     return JS('=List', r'#.slice(#, #)', this, start, end);
   }
 
+
+  List<E> getRange(int start, int length) {
+    return sublist(start, start + length);
+  }
+
   void insertRange(int start, int length, [E initialValue]) {
     checkGrowable(this, 'insertRange');
     if (length == 0) {
@@ -302,3 +318,11 @@
     return IterableMixinWorkaround.asMapList(this);
   }
 }
+
+/**
+ * Dummy subclasses that allow the backend to track more precise
+ * information about arrays through their type.
+ */
+class JSMutableArray extends JSArray {}
+class JSFixedArray extends JSMutableArray {}
+class JSExtendableArray extends JSMutableArray {}
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
index f9a3af7..64c08a1 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
@@ -515,7 +515,7 @@
       // sort implementation, we use the JavaScript one instead.
       JS('void', '#.sort()', listOfNamedArguments);
       listOfNamedArguments.forEach((String name) {
-        buffer.add('\$$name');
+        buffer.write('\$$name');
         arguments.add(namedArguments[name]);
       });
     }
@@ -934,7 +934,7 @@
 getFallThroughError() => const FallThroughErrorImplementation();
 
 /**
- * Represents the type Dynamic. The compiler treats this specially.
+ * Represents the type dynamic. The compiler treats this specially.
  */
 abstract class Dynamic_ {
 }
@@ -1455,10 +1455,10 @@
     if (firstArgument) {
       firstArgument = false;
     } else {
-      buffer. add(', ');
+      buffer.write(', ');
     }
     var argument = types[index];
-    buffer.add(runtimeTypeToString(argument));
+    buffer.write(runtimeTypeToString(argument));
   }
   return buffer.toString();
 }
@@ -1476,6 +1476,8 @@
   return JS('var', r'#.apply(null, #)', function, arguments);
 }
 
+Object call(target, name) => JS('var', r'#[#]()', target, name);
+
 substitute(var substitution, var arguments) {
   if (isJsArray(substitution)) {
     arguments = substitution;
@@ -1486,6 +1488,34 @@
 }
 
 /**
+ * Perform a type check with arguments on the Dart object [object].
+ *
+ * Parameters:
+ * - [isField]: the name of the flag/function to check if the object
+ *   is of the correct class.
+ * - [checks]: the (JavaScript) list of type representations for the
+ *   arguments to check against.
+ * - [asField]: the name of the function that transforms the type
+ *   arguments of [objects] to an instance of the class that we check
+ *   against.
+ * - [native]: [:true:] if we need to use calls (for handling native
+ *   objects).
+ */
+bool checkSubtype(Object object, String isField, List checks, String asField,
+                  bool native) {
+  if (object == null) return false;
+  var arguments = getRuntimeTypeInfo(object);
+  if (isJsArray(object)) {
+    object = getInterceptor(object);
+  }
+  bool isSubclass = native ? call(object, isField) : getField(object, isField);
+  // When we read the field and it is not there, [isSubclass] will be [:null:].
+  if (isSubclass == null || !isSubclass) return false;
+  var substitution = native ? call(object, asField) : getField(object, asField);
+  return checkArguments(substitution, arguments, checks);
+}
+
+/**
  * Check that the types in the list [arguments] are subtypes of the types in
  * list [checks] (at the respective positions), possibly applying [substitution]
  * to the arguments before the check.
@@ -1549,7 +1579,6 @@
   return isSubtype(type, t);
 }
 
-
 /**
  * Check whether the type represented by [s] is a subtype of the type
  * represented by [t].
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_number.dart b/sdk/lib/_internal/compiler/implementation/lib/js_number.dart
index a8bfc13..527c4f5 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_number.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_number.dart
@@ -9,6 +9,9 @@
  * recognizes this class as an interceptor, and changes references to
  * [:this:] to actually use the receiver of the method, which is
  * generated as an extra argument added to each member.
+ *
+ * Note that none of the methods here delegate to a method defined on JSInt or
+ * JSDouble.  This is exploited in [tryComputeConstantInterceptor].
  */
 class JSNumber implements num {
   const JSNumber();
@@ -41,6 +44,11 @@
 
   bool get isNaN => JS('bool', r'isNaN(#)', this);
 
+  bool get isInfinite {
+    return JS('bool', r'# == Infinity', this)
+        || JS('bool', r'# == -Infinity', this);
+  }
+
   num remainder(num b) {
     checkNull(b); // TODO(ngeoffray): This is not specified but co19 tests it.
     if (b is! num) throw new ArgumentError(b);
@@ -52,20 +60,20 @@
   int toInt() {
     if (isNaN) throw new UnsupportedError('NaN');
     if (isInfinite) throw new UnsupportedError('Infinity');
-    num truncated = truncate();
+    num truncated = truncateToDouble();
     return JS('bool', r'# == -0.0', truncated) ? 0 : truncated;
   }
 
-  num ceil() => JS('num', r'Math.ceil(#)', this);
+  int truncate() => toInt();
+  int ceil() => ceilToDouble().toInt();
+  int floor() => floorToDouble().toInt();
+  int round() => roundToDouble().toInt();
 
-  num floor() => JS('num', r'Math.floor(#)', this);
+  double ceilToDouble() => JS('num', r'Math.ceil(#)', this);
 
-  bool get isInfinite {
-    return JS('bool', r'# == Infinity', this)
-      || JS('bool', r'# == -Infinity', this);
-  }
+  double floorToDouble() => JS('num', r'Math.floor(#)', this);
 
-  num round() {
+  double roundToDouble() {
     if (this < 0) {
       return JS('num', r'-Math.round(-#)', this);
     } else {
@@ -73,6 +81,8 @@
     }
   }
 
+  double truncateToDouble() => this < 0 ? ceilToDouble() : floorToDouble();
+
   num clamp(lowerLimit, upperLimit) {
     if (lowerLimit is! num) throw new ArgumentError(lowerLimit);
     if (upperLimit is! num) throw new ArgumentError(upperLimit);
@@ -86,8 +96,6 @@
 
   double toDouble() => this;
 
-  num truncate() => this < 0 ? ceil() : floor();
-
   String toStringAsFixed(int fractionDigits) {
     checkNum(fractionDigits);
     // TODO(floitsch): fractionDigits must be an integer.
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_string.dart b/sdk/lib/_internal/compiler/implementation/lib/js_string.dart
index c271e16..1b8fef0 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_string.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_string.dart
@@ -10,7 +10,7 @@
  * actually use the receiver of the method, which is generated as an extra
  * argument added to each member.
  */
-class JSString implements String {
+class JSString implements String, JSIndexable {
   const JSString();
 
   int codeUnitAt(int index) {
@@ -25,11 +25,13 @@
     return allMatchesInStringUnchecked(this, str);
   }
 
-  String concat(String other) {
+  String operator +(String other) {
     if (other is !String) throw new ArgumentError(other);
     return JS('String', r'# + #', this, other);
   }
 
+  String concat(String other) => this + other;
+
   bool endsWith(String other) {
     checkString(other);
     int otherLength = other.length;
diff --git a/sdk/lib/_internal/compiler/implementation/lib/string_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/string_helper.dart
index aa13997..1157f89 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/string_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/string_helper.dart
@@ -86,10 +86,10 @@
       } else {
         StringBuffer result = new StringBuffer();
         int length = receiver.length;
-        result.add(to);
+        result.write(to);
         for (int i = 0; i < length; i++) {
-          result.add(receiver[i]);
-          result.add(to);
+          result.write(receiver[i]);
+          result.write(to);
         }
         return result.toString();
       }
@@ -125,11 +125,11 @@
   StringBuffer buffer = new StringBuffer();
   int startIndex = 0;
   for (Match match in pattern.allMatches(receiver)) {
-    buffer.add(onNonMatch(receiver.substring(startIndex, match.start)));
-    buffer.add(onMatch(match));
+    buffer.write(onNonMatch(receiver.substring(startIndex, match.start)));
+    buffer.write(onMatch(match));
     startIndex = match.end;
   }
-  buffer.add(onNonMatch(receiver.substring(startIndex)));
+  buffer.write(onNonMatch(receiver.substring(startIndex)));
   return buffer.toString();
 }
 
@@ -138,9 +138,9 @@
   StringBuffer buffer = new StringBuffer();
   int length = receiver.length;
   int i = 0;
-  buffer.add(onNonMatch(""));
+  buffer.write(onNonMatch(""));
   while (i < length) {
-    buffer.add(onMatch(new StringMatch(i, receiver, "")));
+    buffer.write(onMatch(new StringMatch(i, receiver, "")));
     // Special case to avoid splitting a surrogate pair.
     int code = receiver.codeUnitAt(i);
     if ((code & ~0x3FF) == 0xD800 && length > i + 1) {
@@ -148,16 +148,16 @@
       code = receiver.codeUnitAt(i + 1);
       if ((code & ~0x3FF) == 0xDC00) {
         // Matching trailing surrogate.
-        buffer.add(onNonMatch(receiver.substring(i, i + 2)));
+        buffer.write(onNonMatch(receiver.substring(i, i + 2)));
         i += 2;
         continue;
       }
     }
-    buffer.add(onNonMatch(receiver[i]));
+    buffer.write(onNonMatch(receiver[i]));
     i++;
   }
-  buffer.add(onMatch(new StringMatch(i, receiver, "")));
-  buffer.add(onNonMatch(""));
+  buffer.write(onMatch(new StringMatch(i, receiver, "")));
+  buffer.write(onNonMatch(""));
   return buffer.toString();
 }
 
@@ -174,11 +174,11 @@
     if (position == -1) {
       break;
     }
-    buffer.add(onNonMatch(receiver.substring(startIndex, position)));
-    buffer.add(onMatch(new StringMatch(position, receiver, pattern)));
+    buffer.write(onNonMatch(receiver.substring(startIndex, position)));
+    buffer.write(onMatch(new StringMatch(position, receiver, pattern)));
     startIndex = position + patternLength;
   }
-  buffer.add(onNonMatch(receiver.substring(startIndex)));
+  buffer.write(onNonMatch(receiver.substring(startIndex)));
   return buffer.toString();
 }
 
diff --git a/sdk/lib/_internal/compiler/implementation/lib/typeddata_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/typeddata_patch.dart
new file mode 100644
index 0000000..8dd7bcc
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/lib/typeddata_patch.dart
@@ -0,0 +1,151 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This is an empty dummy patch file for the VM dart:typeddata library.
+// This is needed in order to be able to generate documentation for the
+// typeddata library.
+
+patch class Int8List {
+  patch factory Int8List(int length) {
+    throw new UnsupportedError('Int8List');
+  }
+
+  patch factory Int8List.view(ByteBuffer buffer,
+                              [int offsetInBytes = 0, int length]) {
+    throw new UnsupportedError('Int8List.view');
+  }
+}
+
+
+patch class Uint8List {
+  patch factory Uint8List(int length) {
+    throw new UnsupportedError('Uint8List');
+  }
+
+  patch factory Uint8List.view(ByteBuffer buffer,
+                               [int offsetInBytes = 0, int length]) {
+    throw new UnsupportedError('Uint8List.view');
+  }
+}
+
+
+patch class Uint8ClampedList {
+  patch factory Uint8ClampedList(int length) {
+    throw new UnsupportedError('Uint8ClampedList');
+  }
+
+  patch factory Uint8ClampedList.view(ByteBuffer buffer,
+                                      [int offsetInBytes = 0, int length]) {
+    throw new UnsupportedError('Uint8ClampedList.view');
+  }
+}
+
+
+patch class Int16List {
+  patch factory Int16List(int length) {
+    throw new UnsupportedError('Int16List');
+
+  }
+
+  patch factory Int16List.view(ByteBuffer buffer,
+                               [int offsetInBytes = 0, int length]) {
+    throw new UnsupportedError('Int16List.view');
+  }
+}
+
+
+patch class Uint16List {
+  patch factory Uint16List(int length) {
+    throw new UnsupportedError('Uint16List');
+  }
+
+  patch factory Uint16List.view(ByteBuffer buffer,
+                                [int offsetInBytes = 0, int length]) {
+    throw new UnsupportedError('Uint16List.view');
+  }
+}
+
+
+patch class Int32List {
+  patch factory Int32List(int length) {
+    throw new UnsupportedError('Int32List');
+  }
+
+  patch factory Int32List.view(ByteBuffer buffer,
+                               [int offsetInBytes = 0, int length]) {
+    throw new UnsupportedError('Int32List.view');
+  }
+}
+
+
+patch class Uint32List {
+  patch factory Uint32List(int length) {
+    throw new UnsupportedError('Uint32List');
+  }
+
+  patch factory Uint32List.view(ByteBuffer buffer,
+                                [int offsetInBytes = 0, int length]) {
+    throw new UnsupportedError('Uint32List.view');
+  }
+}
+
+
+patch class Int64List {
+  patch factory Int64List(int length) {
+    throw new UnsupportedError('Int64List');
+  }
+
+  patch factory Int64List.view(ByteBuffer buffer,
+                               [int offsetInBytes = 0, int length]) {
+    throw new UnsupportedError('Int64List.view');
+  }
+}
+
+
+patch class Uint64List {
+  patch factory Uint64List(int length) {
+    throw new UnsupportedError('Uint64List');
+  }
+
+  patch factory Uint64List.view(ByteBuffer buffer,
+                                [int offsetInBytes = 0, int length]) {
+    throw new UnsupportedError('Uint64List.view');
+  }
+}
+
+
+patch class Float32List {
+  patch factory Float32List(int length) {
+    throw new UnsupportedError('Float32List');
+  }
+
+  patch factory Float32List.view(ByteBuffer buffer,
+                                 [int offsetInBytes = 0, int length]) {
+    throw new UnsupportedError('Float32List.view');
+  }
+}
+
+
+patch class Float64List {
+  patch factory Float64List(int length) {
+    throw new UnsupportedError('Float64List');
+  }
+
+  patch factory Float64List.view(ByteBuffer buffer,
+                                 [int offsetInBytes = 0, int length]) {
+    throw new UnsupportedError('Float64List.view');
+  }
+}
+
+
+patch class ByteData {
+  patch factory ByteData(int length) {
+    throw new UnsupportedError('ByteData');
+  }
+
+  patch factory ByteData.view(ByteBuffer buffer,
+                              [int offsetInBytes = 0, int length]) {
+    throw new UnsupportedError('ByteData.view');
+  }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
index d18c2e1..569fd7e 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
@@ -6,10 +6,10 @@
 
 import 'dart:async';
 import 'dart:collection' show LinkedHashMap;
-import 'dart:io';
+import 'dart:io' show Path;
 import 'dart:uri';
 
-import '../../compiler.dart' as diagnostics;
+import '../../compiler.dart' as api;
 import '../elements/elements.dart';
 import '../resolution/resolution.dart' show ResolverTask, ResolverVisitor;
 import '../apiimpl.dart' show Compiler;
@@ -84,8 +84,6 @@
     // TODO(johnniwinther): We need a mirror on malformed types.
     return system.dynamicType;
   }
-  _diagnosticListener.internalError(
-      "Unexpected type $type of kind ${type.kind}");
   system.compiler.internalError("Unexpected type $type of kind ${type.kind}");
 }
 
@@ -193,113 +191,95 @@
   return newName;
 }
 
-DiagnosticListener get _diagnosticListener {
-  return const Dart2JsDiagnosticListener();
-}
-
-class Dart2JsDiagnosticListener implements DiagnosticListener {
-  const Dart2JsDiagnosticListener();
-
-  void cancel(String reason, {node, token, instruction, element}) {
-    print(reason);
-  }
-
-  void log(message) {
-    print(message);
-  }
-
-  void internalError(String message,
-                     {Node node, Token token, HInstruction instruction,
-                      Element element}) {
-    cancel('Internal error: $message', node: node, token: token,
-           instruction: instruction, element: element);
-  }
-
-  void internalErrorOnElement(Element element, String message) {
-    internalError(message, element: element);
-  }
-
-  SourceSpan spanFromSpannable(Node node, [Uri uri]) {
-    // TODO(johnniwinther): implement this.
-    throw 'unimplemented';
-  }
-
-  void reportMessage(SourceSpan span, Diagnostic message,
-                     diagnostics.Diagnostic kind) {
-    // TODO(johnniwinther): implement this.
-    throw 'unimplemented';
-  }
-
-  bool onDeprecatedFeature(Spannable span, String feature) {
-    // TODO(johnniwinther): implement this?
-    throw 'unimplemented';
-  }
-}
-
 //------------------------------------------------------------------------------
 // Compilation implementation
 //------------------------------------------------------------------------------
 
-// TODO(johnniwinther): Support client configurable handlers/providers.
-class Dart2JsCompilation implements Compilation {
-  Compiler _compiler;
-  final Uri cwd;
-  final SourceFileProvider provider;
+// TODO(johnniwinther): Support client configurable providers.
 
-  Dart2JsCompilation(Path script, Path libraryRoot,
-                     [Path packageRoot, List<String> opts = const <String>[]])
-      : cwd = getCurrentDirectory(),
-        provider = new SourceFileProvider() {
-    var handler = new FormattingDiagnosticHandler(provider);
-    var libraryUri = cwd.resolve('${libraryRoot}/');
-    var packageUri;
-    if (packageRoot != null) {
-      packageUri = cwd.resolve('${packageRoot}/');
-    } else {
-      packageUri = libraryUri;
-    }
-    _compiler = new Compiler(provider.readStringFromUri,
-                                 null,
-                                 handler.diagnosticHandler,
-                                 libraryUri, packageUri, opts);
-    var scriptUri = cwd.resolve(script.toString());
-    // TODO(johnniwinther): Detect file not found
-    _compiler.run(scriptUri);
+/**
+ * Returns a future that completes to a non-null String when [script]
+ * has been successfully compiled.
+ *
+ * TODO(johnniwinther): The method is deprecated but here to support [Path]
+ * which is used through dartdoc.
+ */
+Future<String> compile(Path script,
+                       Path libraryRoot,
+                       {Path packageRoot,
+                        List<String> options: const <String>[],
+                        api.DiagnosticHandler diagnosticHandler}) {
+  Uri cwd = getCurrentDirectory();
+  SourceFileProvider provider = new SourceFileProvider();
+  if (diagnosticHandler == null) {
+    diagnosticHandler =
+        new FormattingDiagnosticHandler(provider).diagnosticHandler;
   }
-
-  Dart2JsCompilation.library(List<Path> libraries, Path libraryRoot,
-                     [Path packageRoot, List<String> opts = const <String>[]])
-      : cwd = getCurrentDirectory(),
-        provider = new SourceFileProvider() {
-    var libraryUri = cwd.resolve('${libraryRoot}/');
-    var packageUri;
-    if (packageRoot != null) {
-      packageUri = cwd.resolve('${packageRoot}/');
-    } else {
-      packageUri = libraryUri;
-    }
-    opts = new List<String>.from(opts);
-    opts.add('--analyze-only');
-    opts.add('--analyze-all');
-    _compiler = new Compiler(provider.readStringFromUri,
-                                 null,
-                                 silentDiagnosticHandler,
-                                 libraryUri, packageUri, opts);
-    var librariesUri = <Uri>[];
-    for (Path library in libraries) {
-      librariesUri.add(cwd.resolve(library.toString()));
-      // TODO(johnniwinther): Detect file not found
-    }
-    _compiler.librariesToAnalyzeWhenRun = librariesUri;
-    _compiler.run(null);
+  Uri scriptUri = cwd.resolve(script.toString());
+  Uri libraryUri = cwd.resolve('${libraryRoot}/');
+  Uri packageUri = null;
+  if (packageRoot != null) {
+    packageUri = cwd.resolve('${packageRoot}/');
   }
-
-  MirrorSystem get mirrors => new Dart2JsMirrorSystem(_compiler);
-
-  Future<String> compileToJavaScript() =>
-      new Future<String>.immediate(_compiler.assembledCode);
+  return api.compile(scriptUri, libraryUri, packageUri,
+      provider.readStringFromUri, diagnosticHandler, options);
 }
 
+/**
+ * Analyzes set of libraries and provides a mirror system which can be used for
+ * static inspection of the source code.
+ */
+Future<MirrorSystem> analyze(List<Path> libraries,
+                             Path libraryRoot,
+                             {Path packageRoot,
+                              List<String> options: const <String>[],
+                              api.DiagnosticHandler diagnosticHandler}) {
+  Uri cwd = getCurrentDirectory();
+  SourceFileProvider provider = new SourceFileProvider();
+  if (diagnosticHandler == null) {
+    diagnosticHandler =
+        new FormattingDiagnosticHandler(provider).diagnosticHandler;
+  }
+  Uri libraryUri = cwd.resolve('${libraryRoot}/');
+  Uri packageUri = null;
+  if (packageRoot != null) {
+    packageUri = cwd.resolve('${packageRoot}/');
+  }
+  options = new List<String>.from(options);
+  options.add('--analyze-only');
+  options.add('--analyze-signatures-only');
+  options.add('--analyze-all');
+
+  bool compilationFailed = false;
+  void internalDiagnosticHandler(Uri uri, int begin, int end,
+                                 String message, api.Diagnostic kind) {
+    if (kind == api.Diagnostic.ERROR ||
+        kind == api.Diagnostic.CRASH) {
+      compilationFailed = true;
+    }
+    diagnosticHandler(uri, begin, end, message, kind);
+  }
+
+  // TODO(johnniwinther): Extract the following as an [analyze] method in
+  // [:compiler/compiler.dart:].
+  Compiler compiler = new Compiler(provider.readStringFromUri,
+                                   null,
+                                   internalDiagnosticHandler,
+                                   libraryUri, packageUri, options);
+  List<Uri> librariesUri = <Uri>[];
+  for (Path library in libraries) {
+    librariesUri.add(cwd.resolve(library.toString()));
+  }
+  compiler.librariesToAnalyzeWhenRun = librariesUri;
+  bool success = compiler.run(null);
+  if (success && !compilationFailed) {
+    return new Future<MirrorSystem>.immediate(
+        new Dart2JsMirrorSystem(compiler));
+  } else {
+    return new Future<MirrorSystem>.immediateError(
+        'Failed to create mirror system.');
+  }
+}
 
 //------------------------------------------------------------------------------
 // Dart2Js specific extensions of mirror interfaces
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart b/sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart
index 6f5189e..c2d6007 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart
@@ -5,51 +5,12 @@
 library mirrors;
 
 import 'dart:async';
-import 'dart:io';
 import 'dart:uri';
 
 // TODO(rnystrom): Use "package:" URL (#4968).
 import 'dart2js_mirror.dart';
 
 /**
- * [Compilation] encapsulates the compilation of a program.
- */
-abstract class Compilation {
-  /**
-   * Creates a new compilation which has [script] as its entry point.
-   */
-  factory Compilation(Path script,
-                      Path libraryRoot,
-                      [Path packageRoot,
-                       List<String> opts = const <String>[]]) {
-    return new Dart2JsCompilation(script, libraryRoot, packageRoot, opts);
-  }
-
-  /**
-   * Creates a new compilation which consists of a set of libraries, but which
-   * has no entry point. This compilation cannot generate output but can only
-   * be used for static inspection of the source code.
-   */
-  factory Compilation.library(List<Path> libraries,
-                              Path libraryRoot,
-                              [Path packageRoot,
-                               List<String> opts = const []]) {
-    return new Dart2JsCompilation.library(libraries, libraryRoot,
-                                          packageRoot, opts);
-  }
-
-  /**
-   * Returns the mirror system for this compilation.
-   */
-  final MirrorSystem mirrors;
-
-  /**
-   * Returns a future for the compiled JavaScript code.
-   */
-  Future<String> compileToJavaScript();
-}
-
-/**
  * The main interface for the whole mirror system.
  */
 abstract class MirrorSystem {
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart b/sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart
index d904089..2a2c1fe 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart
@@ -138,13 +138,13 @@
     for (int index = 0 ; index < lines.length ; index++) {
       String line = lines[index];
       if (index == 0) {
-        sb.add(line); // Add the first line unprocessed.
+        sb.write(line); // Add the first line unprocessed.
         continue;
       }
-      sb.add('\n');
+      sb.write('\n');
       match = _multiLineCommentLineStart.firstMatch(line);
       if (match != null) {
-        sb.add(match[1]);
+        sb.write(match[1]);
       } else if (index < lines.length-1 || !line.trim().isEmpty) {
         // Do not add the last line if it only contains white space.
         // This interprets cases like
@@ -152,7 +152,7 @@
         //      * Foo
         //      */
         // as "\nFoo\n" and not as "\nFoo\n     ".
-        sb.add(line);
+        sb.write(line);
       }
     }
     return sb.toString();
diff --git a/sdk/lib/_internal/compiler/implementation/native_handler.dart b/sdk/lib/_internal/compiler/implementation/native_handler.dart
index 0d5b232..00415f0 100644
--- a/sdk/lib/_internal/compiler/implementation/native_handler.dart
+++ b/sdk/lib/_internal/compiler/implementation/native_handler.dart
@@ -218,7 +218,8 @@
     pendingClasses.remove(classElement);
     registeredClasses.add(classElement);
 
-    world.registerInstantiatedClass(classElement);
+    // TODO(ahe): Is this really a global dependency?
+    world.registerInstantiatedClass(classElement, compiler.globalDependencies);
 
     // Also parse the node to know all its methods because otherwise it will
     // only be parsed if there is a call to one of its constructors.
@@ -316,32 +317,34 @@
   NativeBehavior getNativeBehaviorOf(Send node) => nativeBehaviors[node];
 
   processNativeBehavior(NativeBehavior behavior, cause) {
+    // TODO(ahe): Is this really a global dependency?
+    TreeElements elements = compiler.globalDependencies;
     bool allUsedBefore = unusedClasses.isEmpty;
     for (var type in behavior.typesInstantiated) {
       if (matchedTypeConstraints.contains(type)) continue;
       matchedTypeConstraints.add(type);
       if (type is SpecialType) {
         if (type == SpecialType.JsArray) {
-          world.registerInstantiatedClass(compiler.listClass);
+          world.registerInstantiatedClass(compiler.listClass, elements);
         } else if (type == SpecialType.JsObject) {
-          world.registerInstantiatedClass(compiler.objectClass);
+          world.registerInstantiatedClass(compiler.objectClass, elements);
         }
         continue;
       }
       if (type is InterfaceType) {
         if (type.element == compiler.intClass) {
-          world.registerInstantiatedClass(compiler.intClass);
+          world.registerInstantiatedClass(compiler.intClass, elements);
         } else if (type.element == compiler.doubleClass) {
-          world.registerInstantiatedClass(compiler.doubleClass);
+          world.registerInstantiatedClass(compiler.doubleClass, elements);
         } else if (type.element == compiler.numClass) {
-          world.registerInstantiatedClass(compiler.doubleClass);
-          world.registerInstantiatedClass(compiler.intClass);
+          world.registerInstantiatedClass(compiler.doubleClass, elements);
+          world.registerInstantiatedClass(compiler.intClass, elements);
         } else if (type.element == compiler.stringClass) {
-          world.registerInstantiatedClass(compiler.stringClass);
+          world.registerInstantiatedClass(compiler.stringClass, elements);
         } else if (type.element == compiler.nullClass) {
-          world.registerInstantiatedClass(compiler.nullClass);
+          world.registerInstantiatedClass(compiler.nullClass, elements);
         } else if (type.element == compiler.boolClass) {
-          world.registerInstantiatedClass(compiler.boolClass);
+          world.registerInstantiatedClass(compiler.boolClass, elements);
         }
       }
       assert(type is DartType);
@@ -546,6 +549,7 @@
       if (specString == '' || specString == 'var') {
         var behavior = new NativeBehavior();
         behavior.typesReturned.add(compiler.objectClass.computeType(compiler));
+        behavior.typesReturned.add(compiler.nullClass.computeType(compiler));
         return behavior;
       }
       var behavior = new NativeBehavior();
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index 1ff6f48..e6fd478 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -5,6 +5,12 @@
 part of resolution;
 
 abstract class TreeElements {
+  Element get currentElement;
+  Set<Node> get superUses;
+
+  /// A set of additional dependencies.  See [registerDependency] below.
+  Set<Element> get otherDependencies;
+
   Element operator[](Node node);
   Selector getSelector(Send send);
   Selector getGetterSelectorInComplexSendSet(SendSet node);
@@ -14,7 +20,10 @@
   Selector getCurrentSelector(ForIn node);
   DartType getType(Node node);
   bool isParameterChecked(Element element);
-  Set<Node> get superUses;
+
+  /// Register additional dependencies required by [currentElement].
+  /// For example, elements that are used by a backend.
+  void registerDependency(Element element);
 }
 
 class TreeElementMapping implements TreeElements {
@@ -22,8 +31,11 @@
   final Map<Spannable, Selector> selectors =
       new LinkedHashMap<Spannable, Selector>();
   final Map<Node, DartType> types = new LinkedHashMap<Node, DartType>();
-  final Set<Element> checkedParameters = new Set<Element>();
-  final Set<Node> superUses = new Set<Node>();
+  final Set<Element> checkedParameters = new LinkedHashSet<Element>();
+  final Set<Node> superUses = new LinkedHashSet<Node>();
+  final Set<Element> otherDependencies = new LinkedHashSet<Element>();
+  final int hashCode = ++hashCodeCounter;
+  static int hashCodeCounter = 0;
 
   TreeElementMapping(this.currentElement);
 
@@ -118,6 +130,12 @@
   bool isParameterChecked(Element element) {
     return checkedParameters.contains(element);
   }
+
+  void registerDependency(Element element) {
+    otherDependencies.add(element.implementation);
+  }
+
+  String toString() => 'TreeElementMapping($currentElement)';
 }
 
 class ResolverTask extends CompilerTask {
@@ -363,7 +381,9 @@
   }
 
   void visitBody(ResolverVisitor visitor, Statement body) {
-    visitor.visit(body);
+    if (!compiler.analyzeSignaturesOnly) {
+      visitor.visit(body);
+    }
   }
 
   void resolveConstructorImplementation(FunctionElement constructor,
@@ -434,13 +454,15 @@
             MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC);
     }
     ResolverVisitor visitor = visitorFor(element);
+    // TODO(johnniwinther): Avoid analyzing initializers if
+    // [Compiler.analyzeSignaturesOnly] is set.
     initializerDo(tree, visitor.visit);
 
     if (Elements.isStaticOrTopLevelField(element)) {
       if (tree.asSendSet() != null) {
         // TODO(ngeoffray): We could do better here by using the
         // constant handler to figure out if it's a lazy field or not.
-        compiler.backend.registerLazyField();
+        compiler.backend.registerLazyField(visitor.mapping);
       }
     }
 
@@ -1405,10 +1427,6 @@
       String stringValue = typeName.source.stringValue;
       if (identical(stringValue, 'void')) {
         return compiler.types.voidType.element;
-      } else if (identical(stringValue, 'Dynamic')) {
-        // TODO(aprelev@gmail.com): Remove deprecated Dynamic keyword support.
-        compiler.onDeprecatedFeature(typeName, 'Dynamic');
-        return compiler.dynamicClass;
       } else if (identical(stringValue, 'dynamic')) {
         return compiler.dynamicClass;
       } else {
@@ -1538,7 +1556,9 @@
         }
       } else if (element.isTypeVariable()) {
         if (enclosingElement.isInStaticMember()) {
-          compiler.backend.registerThrowRuntimeError();
+          compiler.backend.registerThrowRuntimeError(
+              // TODO(ahe): Get the TreeElements for the current element.
+              compiler.globalDependencies);
           compiler.reportWarning(node,
               MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER.message(
                   {'typeVariableName': node}));
@@ -1729,7 +1749,7 @@
           element = warnAndCreateErroneousElement(node, node.source,
                                                   MessageKind.CANNOT_RESOLVE,
                                                   {'name': node});
-          compiler.backend.registerThrowNoSuchMethod();
+          compiler.backend.registerThrowNoSuchMethod(mapping);
         }
       } else if (element.isErroneous()) {
         // Use the erroneous element.
@@ -1752,7 +1772,7 @@
     DartType type = resolveTypeAnnotation(node);
     if (type != null) {
       if (inCheckContext) {
-        compiler.enqueuer.resolution.registerIsCheck(type);
+        compiler.enqueuer.resolution.registerIsCheck(type, mapping);
       }
       return type.element;
     }
@@ -1817,8 +1837,13 @@
   }
 
   void setupFunction(FunctionExpression node, FunctionElement function) {
-    scope = new MethodScope(scope, function);
+    Element enclosingElement = function.enclosingElement;
+    if (node.modifiers.isStatic() &&
+        enclosingElement.kind != ElementKind.CLASS) {
+      compiler.reportErrorCode(node, MessageKind.ILLEGAL_STATIC);
+    }
 
+    scope = new MethodScope(scope, function);
     // Put the parameters in scope.
     FunctionSignature functionParameters =
         function.computeSignature(compiler);
@@ -1938,7 +1963,7 @@
     scope = oldScope;
     enclosingElement = previousEnclosingElement;
 
-    world.registerInstantiatedClass(compiler.functionClass);
+    world.registerInstantiatedClass(compiler.functionClass, mapping);
   }
 
   visitIf(If node) {
@@ -2005,7 +2030,7 @@
       }
       // TODO(johnniwinther): Ensure correct behavior if currentClass is a
       // patch.
-      target = currentClass.lookupSuperMember(name);
+      target = currentClass.lookupSuperSelector(selector);
       // [target] may be null which means invoking noSuchMethod on
       // super.
       if (target == null) {
@@ -2016,7 +2041,7 @@
         // call [:super.noSuchMethod:] that does a
         // [:InvocationMirror.invokeOn:].
         world.registerDynamicInvocation(selector.name, selector);
-        compiler.backend.registerSuperNoSuchMethod();
+        compiler.backend.registerSuperNoSuchMethod(mapping);
       }
     } else if (Elements.isUnresolved(resolvedReceiver)) {
       return null;
@@ -2034,7 +2059,7 @@
       }
       target = receiverClass.lookupLocalMember(name);
       if (target == null || target.isInstanceMember()) {
-        compiler.backend.registerThrowNoSuchMethod();
+        compiler.backend.registerThrowNoSuchMethod(mapping);
         // TODO(johnniwinther): With the simplified [TreeElements] invariant,
         // try to resolve injected elements if [currentClass] is in the patch
         // library of [receiverClass].
@@ -2053,7 +2078,7 @@
       PrefixElement prefix = resolvedReceiver;
       target = prefix.lookupLocalMember(name);
       if (Elements.isUnresolved(target)) {
-        compiler.backend.registerThrowNoSuchMethod();
+        compiler.backend.registerThrowNoSuchMethod(mapping);
         return warnAndCreateErroneousElement(
             node, name, MessageKind.NO_SUCH_LIBRARY_MEMBER,
             {'libraryName': prefix.name, 'memberName': name});
@@ -2168,13 +2193,18 @@
         AbstractFieldElement field = target;
         target = field.getter;
         if (target == null && !inInstanceContext) {
-          compiler.backend.registerThrowNoSuchMethod();
+          compiler.backend.registerThrowNoSuchMethod(mapping);
           target =
               warnAndCreateErroneousElement(node.selector, field.name,
                                             MessageKind.CANNOT_RESOLVE_GETTER);
         }
+      } else if (target.isTypeVariable()) {
+        ClassElement cls = target.getEnclosingClass();
+        assert(enclosingElement.getEnclosingClass() == cls);
+        compiler.backend.registerClassUsingVariableExpression(cls);
+        compiler.backend.registerTypeVariableExpression(mapping);
       } else if (target.impliesType() && !sendIsMemberAccess) {
-        compiler.backend.registerTypeLiteral();
+        compiler.backend.registerTypeLiteral(mapping);
       }
     }
 
@@ -2186,9 +2216,9 @@
         DartType type = resolveTypeTest(node.arguments.head);
         if (type != null) {
           if (operatorString == 'as') {
-            compiler.enqueuer.resolution.registerAsCheck(type);
+            compiler.enqueuer.resolution.registerAsCheck(type, mapping);
           } else {
-            compiler.enqueuer.resolution.registerIsCheck(type);
+            compiler.enqueuer.resolution.registerIsCheck(type, mapping);
           }
         }
         resolvedArguments = true;
@@ -2242,13 +2272,13 @@
     registerSend(selector, target);
     if (node.isPropertyAccess) {
       // It might be the closurization of a method.
-      world.registerInstantiatedClass(compiler.functionClass);
+      world.registerInstantiatedClass(compiler.functionClass, mapping);
     }
     return node.isPropertyAccess ? target : null;
   }
 
   void warnArgumentMismatch(Send node, Element target) {
-    compiler.backend.registerThrowNoSuchMethod();
+    compiler.backend.registerThrowNoSuchMethod(mapping);
     // TODO(karlklose): we can be more precise about the reason of the
     // mismatch.
     warning(node.argumentsNode, MessageKind.INVALID_ARGUMENTS,
@@ -2279,27 +2309,19 @@
         if (setter == null && !inInstanceContext) {
           setter = warnAndCreateErroneousElement(
               node.selector, field.name, MessageKind.CANNOT_RESOLVE_SETTER);
-          compiler.backend.registerThrowNoSuchMethod();
+          compiler.backend.registerThrowNoSuchMethod(mapping);
         }
         if (isComplex && getter == null && !inInstanceContext) {
           getter = warnAndCreateErroneousElement(
               node.selector, field.name, MessageKind.CANNOT_RESOLVE_GETTER);
-          compiler.backend.registerThrowNoSuchMethod();
+          compiler.backend.registerThrowNoSuchMethod(mapping);
         }
       } else if (target.impliesType()) {
-        compiler.backend.registerThrowNoSuchMethod();
+        compiler.backend.registerThrowNoSuchMethod(mapping);
       } else if (target.modifiers.isFinal() || target.modifiers.isConst()) {
         setter = warnAndCreateErroneousElement(
             node.selector, target.name, MessageKind.CANNOT_RESOLVE_SETTER);
-        compiler.backend.registerThrowNoSuchMethod();
-      } else if (isComplex && target.name == const SourceString('[]=')) {
-        getter = target.getEnclosingClass().lookupMember(
-            const SourceString('[]'));
-        if (getter == null) {
-          getter = warnAndCreateErroneousElement(
-              node, setter.name, MessageKind.CANNOT_RESOLVE_INDEX);
-          compiler.backend.registerThrowNoSuchMethod();
-        }
+        compiler.backend.registerThrowNoSuchMethod(mapping);
       }
     }
 
@@ -2320,6 +2342,15 @@
       }
       registerSend(getterSelector, getter);
       mapping.setGetterSelectorInComplexSendSet(node, getterSelector);
+      if (node.isSuperCall) {
+        getter = currentClass.lookupSuperSelector(getterSelector);
+        if (getter == null) {
+          target = warnAndCreateErroneousElement(
+              node, selector.name, MessageKind.NO_SUCH_SUPER_MEMBER,
+              {'className': currentClass, 'memberName': selector.name});
+          compiler.backend.registerSuperNoSuchMethod(mapping);
+        }
+      }
       useElement(node.selector, getter);
 
       // Make sure we include the + and - operators if we are using
@@ -2363,27 +2394,27 @@
   }
 
   visitLiteralInt(LiteralInt node) {
-    world.registerInstantiatedClass(compiler.intClass);
+    world.registerInstantiatedClass(compiler.intClass, mapping);
   }
 
   visitLiteralDouble(LiteralDouble node) {
-    world.registerInstantiatedClass(compiler.doubleClass);
+    world.registerInstantiatedClass(compiler.doubleClass, mapping);
   }
 
   visitLiteralBool(LiteralBool node) {
-    world.registerInstantiatedClass(compiler.boolClass);
+    world.registerInstantiatedClass(compiler.boolClass, mapping);
   }
 
   visitLiteralString(LiteralString node) {
-    world.registerInstantiatedClass(compiler.stringClass);
+    world.registerInstantiatedClass(compiler.stringClass, mapping);
   }
 
   visitLiteralNull(LiteralNull node) {
-    world.registerInstantiatedClass(compiler.nullClass);
+    world.registerInstantiatedClass(compiler.nullClass, mapping);
   }
 
   visitStringJuxtaposition(StringJuxtaposition node) {
-    world.registerInstantiatedClass(compiler.stringClass);
+    world.registerInstantiatedClass(compiler.stringClass, mapping);
     node.visitChildren(this);
   }
 
@@ -2439,14 +2470,14 @@
     }
     world.registerStaticUse(redirectionTarget);
     world.registerInstantiatedClass(
-        redirectionTarget.enclosingElement.declaration);
+        redirectionTarget.enclosingElement.declaration, mapping);
   }
 
   visitThrow(Throw node) {
     if (!inCatchBlock && node.expression == null) {
       error(node, MessageKind.THROW_WITHOUT_EXPRESSION);
     }
-    compiler.backend.registerThrow();
+    compiler.backend.registerThrow(mapping);
     visit(node.expression);
   }
 
@@ -2488,7 +2519,7 @@
     Selector callSelector = mapping.getSelector(node.send);
     if (!callSelector.applies(constructor, compiler)) {
       warnArgumentMismatch(node.send, constructor);
-      compiler.backend.registerThrowNoSuchMethod();
+      compiler.backend.registerThrowNoSuchMethod(mapping);
     }
     compiler.withCurrentElement(constructor, () {
       FunctionExpression tree = constructor.parseNode(compiler);
@@ -2500,7 +2531,7 @@
       // TODO(ngeoffray): Remove once we remove such support.
       world.registerStaticUse(constructor.declaration);
       world.registerInstantiatedClass(
-          constructor.getEnclosingClass().declaration);
+          constructor.getEnclosingClass().declaration, mapping);
       constructor = constructor.defaultImplementation;
     }
     // [constructor.defaultImplementation] might be the implementation element
@@ -2509,9 +2540,9 @@
     ClassElement cls = constructor.getEnclosingClass();
     // [cls] might be the implementation element and only declaration elements
     // may be registered.
-    world.registerInstantiatedType(mapping.getType(node));
+    world.registerInstantiatedType(mapping.getType(node), mapping);
     if (cls.isAbstract(compiler)) {
-      compiler.backend.registerAbstractClassInstantiation();
+      compiler.backend.registerAbstractClassInstantiation(mapping);
     }
     // [cls] might be the declaration element and we want to include injected
     // members.
@@ -2545,24 +2576,6 @@
     return result;
   }
 
-  void analyzeTypeArgument(DartType annotation, DartType argument) {
-    if (argument == null) return;
-    if (argument.element.isTypeVariable()) {
-      // Register a dependency between the class where the type
-      // variable is, and the annotation. If the annotation requires
-      // runtime type information, then the class of the type variable
-      // does too.
-      compiler.world.registerRtiDependency(
-          annotation.element,
-          argument.element.enclosingElement);
-    } else if (argument is InterfaceType) {
-      InterfaceType type = argument;
-      type.typeArguments.forEach((DartType argument) {
-        analyzeTypeArgument(type, argument);
-      });
-    }
-  }
-
   DartType resolveTypeAnnotation(TypeAnnotation node) {
     Function report = typeRequired ? error : warning;
     DartType type = typeResolver.resolveTypeAnnotation(
@@ -2570,16 +2583,10 @@
         onFailure: report, whenResolved: useType);
     if (type == null) return null;
     if (inCheckContext) {
-      compiler.enqueuer.resolution.registerIsCheck(type);
+      compiler.enqueuer.resolution.registerIsCheck(type, mapping);
     }
     if (typeRequired || inCheckContext) {
-      if (type is InterfaceType) {
-        InterfaceType itf = type;
-        itf.typeArguments.forEach((DartType argument) {
-          analyzeTypeArgument(type, argument);
-        });
-      }
-      // TODO(ngeoffray): Also handle T a (in checked mode).
+      compiler.backend.registerRequiredType(type, enclosingElement);
     }
     return type;
   }
@@ -2590,20 +2597,28 @@
   }
 
   visitLiteralList(LiteralList node) {
-    world.registerInstantiatedClass(compiler.listClass);
     NodeList arguments = node.typeArguments;
+    DartType typeArgument;
     if (arguments != null) {
       Link<Node> nodes = arguments.nodes;
       if (nodes.isEmpty) {
         error(arguments, MessageKind.MISSING_TYPE_ARGUMENT);
       } else {
-        resolveTypeRequired(nodes.head);
+        typeArgument = resolveTypeRequired(nodes.head);
         for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) {
           error(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
           resolveTypeRequired(nodes.head);
         }
       }
     }
+    DartType listType;
+    if (typeArgument != null) {
+      listType = new InterfaceType(compiler.listClass,
+                                   new Link<DartType>.fromList([typeArgument]));
+    } else {
+      listType = compiler.listClass.rawType;
+    }
+    world.registerInstantiatedType(listType, mapping);
     visit(node.elements);
   }
 
@@ -2612,8 +2627,8 @@
   }
 
   visitStringInterpolation(StringInterpolation node) {
-    world.registerInstantiatedClass(compiler.stringClass);
-    compiler.backend.registerStringInterpolation();
+    world.registerInstantiatedClass(compiler.stringClass, mapping);
+    compiler.backend.registerStringInterpolation(mapping);
     node.visitChildren(this);
   }
 
@@ -2758,9 +2773,9 @@
   }
 
   visitLiteralMap(LiteralMap node) {
-    world.registerInstantiatedClass(compiler.mapClass);
+    world.registerInstantiatedClass(compiler.mapClass, mapping);
     if (node.isConst()) {
-      compiler.backend.registerConstantMap();
+      compiler.backend.registerConstantMap(mapping);
     }
     node.visitChildren(this);
   }
@@ -2841,7 +2856,7 @@
     });
     // TODO(ngeoffray): We should check here instead of the SSA backend if
     // there might be an error.
-    compiler.backend.registerFallThroughError();
+    compiler.backend.registerFallThroughError(mapping);
   }
 
   visitSwitchCase(SwitchCase node) {
@@ -2865,7 +2880,7 @@
   }
 
   visitCatchBlock(CatchBlock node) {
-    compiler.backend.registerCatchStatement();
+    compiler.backend.registerCatchStatement(mapping);
     // Check that if catch part is present, then
     // it has one or two formal parameters.
     if (node.formals != null) {
@@ -2878,7 +2893,7 @@
             error(extra, MessageKind.EXTRA_CATCH_DECLARATION);
           }
         }
-        compiler.backend.registerStackTraceInCatch();
+        compiler.backend.registerStackTraceInCatch(mapping);
       }
 
       // Check that the formals aren't optional and that they have no
@@ -3423,7 +3438,8 @@
 
   SourceString visitIdentifier(Identifier node) {
     // The variable is initialized to null.
-    resolver.world.registerInstantiatedClass(compiler.nullClass);
+    resolver.world.registerInstantiatedClass(compiler.nullClass,
+                                             resolver.mapping);
     return node.source;
   }
 
@@ -3543,11 +3559,15 @@
     Element element;
     if (node.receiver != null) {
       element = visitSend(node);
-    } else if (node.selector.asIdentifier() != null) {
+    } else if (node.selector.asIdentifier() != null ||
+               node.selector.asFunctionExpression() != null) {
       Element variables = new VariableListElementX.node(currentDefinitions,
           ElementKind.VARIABLE_LIST, enclosingElement);
-      element = new VariableElementX(node.selector.asIdentifier().source,
-          variables, ElementKind.PARAMETER, node);
+      SourceString source = node.selector.asIdentifier() != null ?
+          node.selector.asIdentifier().source :
+          node.selector.asFunctionExpression().name.asIdentifier().source;
+      element = new VariableElementX(source, variables,
+          ElementKind.PARAMETER, node);
     }
     // Visit the value. The compile time constant handler will
     // make sure it's a compile time constant.
@@ -3662,9 +3682,9 @@
                                SourceString targetName, MessageKind kind,
                                Map arguments) {
     if (kind == MessageKind.CANNOT_FIND_CONSTRUCTOR) {
-      compiler.backend.registerThrowNoSuchMethod();
+      compiler.backend.registerThrowNoSuchMethod(resolver.mapping);
     } else {
-      compiler.backend.registerThrowRuntimeError();
+      compiler.backend.registerThrowRuntimeError(resolver.mapping);
     }
     if (inConstContext) {
       error(diagnosticNode, kind, arguments);
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart b/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart
index 130486c..d7f2ddf 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart
@@ -4,7 +4,7 @@
 
 library resolution;
 
-import 'dart:collection' show Queue, LinkedHashMap;
+import 'dart:collection' show Queue, LinkedHashMap, LinkedHashSet;
 
 import '../dart2jslib.dart' hide Diagnostic;
 import '../dart_types.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/byte_strings.dart b/sdk/lib/_internal/compiler/implementation/scanner/byte_strings.dart
index c9372bf..92fcdc5 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/byte_strings.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/byte_strings.dart
@@ -43,7 +43,7 @@
   }
 
   printOn(StringBuffer sb) {
-    sb.add(slowToString());
+    sb.write(slowToString());
   }
 
   bool get isEmpty => length == 0;
diff --git a/sdk/lib/_internal/compiler/implementation/source_file_provider.dart b/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
index fc4e9b2..f58d5ca 100644
--- a/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
+++ b/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
@@ -49,10 +49,6 @@
   }
 }
 
-void silentDiagnosticHandler(Uri uri, int begin, int end, String message,
-                             api.Diagnostic kind) {
-}
-
 class FormattingDiagnosticHandler {
   final SourceFileProvider provider;
   bool showWarnings = true;
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart b/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
index 78ecae6..e664654 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
@@ -123,16 +123,11 @@
     Element source = instruction.sourceElement;
     if (source != null) {
       DartType sourceType = source.computeType(compiler);
-      DartType speculatedType = speculativeType.computeType(compiler);
-      JavaScriptBackend backend = compiler.backend;
-      if (speculatedType != null) {
-        // Use the num type instead of JSNumber because JSNumber
-        // is not assignment compatible with int and double, but we
-        // still want to generate a type guard.
-        if (speculatedType.element == backend.jsNumberClass) {
-          speculatedType = compiler.numClass.computeType(compiler);
-        }
-        if (!compiler.types.isAssignable(speculatedType, sourceType)) {
+      if (!sourceType.isMalformed && !sourceType.isDynamic &&
+          sourceType.kind == TypeKind.INTERFACE) {
+        TypeMask sourceMask = new TypeMask.subtype(sourceType);
+        TypeMask speculatedMask = speculativeType.computeMask(compiler);
+        if (sourceMask.intersection(speculatedMask, compiler).isEmpty) {
           return false;
         }
       }
@@ -502,7 +497,7 @@
       if (info.initializer != null) {
         visitExpression(info.initializer);
       }
-      blocks.addLast(info.loopHeader);
+      blocks.add(info.loopHeader);
       if (!info.isDoWhile()) {
         visitExpression(info.condition);
       }
@@ -552,7 +547,7 @@
    */
   void visitStatements(HSubGraphBlockInformation info, {bool newFlow}) {
     SubGraph graph = info.subGraph;
-    if (newFlow) blocks.addLast(graph.start);
+    if (newFlow) blocks.add(graph.start);
     visitSubGraph(graph);
     if (newFlow) blocks.removeLast();
   }
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index 252afbd..86535df 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -237,31 +237,6 @@
     updateLocal(boxElement, newBox);
   }
 
-  HType cachedTypeOfThis;
-
-  HType getTypeOfThis() {
-    HType result = cachedTypeOfThis;
-    if (result == null) {
-      Element element = closureData.thisElement;
-      ClassElement cls = element.enclosingElement.getEnclosingClass();
-      Compiler compiler = builder.compiler;
-      // Use the raw type because we don't have the type context for the
-      // type parameters.
-      DartType type = cls.rawType;
-      if (compiler.world.isUsedAsMixin(cls)) {
-        // If the enclosing class is used as a mixin, [:this:] can be
-        // of the class that mixins the enclosing class. These two
-        // classes do not have a subclass relationship, so, for
-        // simplicity, we mark the type as an interface type.
-        result = new HType.nonNullSubtype(type, compiler);
-      } else {
-        result = new HType.nonNullSubclass(type, compiler);
-      }
-      cachedTypeOfThis = result;
-    }
-    return result;
-  }
-
   /**
    * Documentation wanted -- johnniwinther
    *
@@ -291,7 +266,7 @@
         builder.parameters[parameterElement] = parameter;
         directLocals[parameterElement] = parameter;
         parameter.instructionType =
-            new HType.inferredForElement(parameterElement, compiler);
+            new HType.inferredTypeForElement(parameterElement, compiler);
       });
     }
 
@@ -315,7 +290,7 @@
       // not have any thisElement if the closure was created inside a static
       // context.
       HThis thisInstruction = new HThis(
-          closureData.thisElement, getTypeOfThis());
+          closureData.thisElement, builder.getTypeOfThis());
       builder.graph.thisInstruction = thisInstruction;
       builder.graph.entry.addAtEntry(thisInstruction);
       directLocals[closureData.thisElement] = thisInstruction;
@@ -326,7 +301,7 @@
     // classes, or the same as [:this:] for non-intercepted classes.
     ClassElement cls = element.getEnclosingClass();
     if (builder.backend.isInterceptedMethod(element)) {
-      HType type = HType.UNKNOWN;
+      HType type = builder.getTypeOfThis();
       SourceString name = const SourceString('receiver');
       if (cls == builder.backend.jsArrayClass) {
         type = HType.READABLE_ARRAY;
@@ -346,11 +321,13 @@
         type = HType.UNKNOWN;
       } else if (cls != compiler.objectClass) {
         JavaScriptBackend backend = compiler.backend;
-        assert(!backend.isInterceptorClass(cls));
-        name = const SourceString('_');
+        if (!backend.isInterceptorClass(cls)) {
+          name = const SourceString('_');
+        }
       }
       Element parameter = new InterceptedElement(type, name, element);
       HParameterValue value = new HParameterValue(parameter);
+      builder.graph.explicitReceiverParameter = value;
       builder.graph.entry.addAfter(
           directLocals[closureData.thisElement], value);
       if (builder.backend.isInterceptorClass(cls.declaration)) {
@@ -415,6 +392,7 @@
       Element redirect = redirectionMapping[element];
       HInstruction receiver = readLocal(closureData.closureElement);
       HInstruction fieldGet = new HFieldGet(redirect, receiver);
+      fieldGet.instructionType = builder.getTypeOfCapturedVariable(element);
       builder.add(fieldGet);
       return fieldGet;
     } else if (isBoxed(element)) {
@@ -427,6 +405,7 @@
       assert(redirect.enclosingElement.isVariable());
       HInstruction box = readLocal(redirect.enclosingElement);
       HInstruction lookup = new HFieldGet(redirect, box);
+      lookup.instructionType = builder.getTypeOfCapturedVariable(element);
       builder.add(lookup);
       return lookup;
     } else {
@@ -441,7 +420,7 @@
   HInstruction readThis() {
     HInstruction res = readLocal(closureData.thisElement);
     if (res.instructionType == null) {
-      res.instructionType = getTypeOfThis();
+      res.instructionType = builder.getTypeOfThis();
     }
     return res;
   }
@@ -816,7 +795,7 @@
   LocalsHandler localsHandler;
   HInstruction rethrowableException;
   Map<Element, HInstruction> parameters;
-  final RuntimeTypeInformation rti;
+  final RuntimeTypes rti;
   HParameterValue lastAddedParameter;
 
   Map<TargetElement, JumpHandler> jumpTargets;
@@ -886,6 +865,39 @@
     return initialValue == null;
   }
 
+  HType cachedTypeOfThis;
+
+  HType getTypeOfThis() {
+    HType result = cachedTypeOfThis;
+    if (result == null) {
+      Element element = localsHandler.closureData.thisElement;
+      ClassElement cls = element.enclosingElement.getEnclosingClass();
+      // Use the raw type because we don't have the type context for the
+      // type parameters.
+      DartType type = cls.rawType;
+      if (compiler.world.isUsedAsMixin(cls)) {
+        // If the enclosing class is used as a mixin, [:this:] can be
+        // of the class that mixins the enclosing class. These two
+        // classes do not have a subclass relationship, so, for
+        // simplicity, we mark the type as an interface type.
+        result = new HType.nonNullSubtype(type, compiler);
+      } else {
+        result = new HType.nonNullSubclass(type, compiler);
+      }
+      cachedTypeOfThis = result;
+    }
+    return result;
+  }
+
+  Map<Element, HType> cachedTypesOfCapturedVariables =
+      new Map<Element, HType>();
+
+  HType getTypeOfCapturedVariable(Element element) {
+    return cachedTypesOfCapturedVariables.putIfAbsent(element, () {
+      return new HType.inferredTypeForElement(element, compiler);
+    });
+  }
+
   /**
    * Documentation wanted -- johnniwinther
    *
@@ -904,30 +916,37 @@
     // call sites do the null check.
     if (name == const SourceString('==')) {
       if (functionElement.getEnclosingClass() == compiler.objectClass) {
-        // We special case [Object.operator==] because we know the
-        // receiver is not null and therefore can just do an identity
-        // check on [:this:]. The interceptor classes have their own
-        // synthesized [:operator==:] method.
+        // We special case [Object.operator==] because we know the receiver is
+        // not null (that case goes via a call site check or the JSNull
+        // interceptor) and therefore can just do an identity check on `this`.
+
+        // TODO(sra): This method uses the explicit receiver calling convention
+        // so that interceptors may inherit it.  If we make all interceptors
+        // inherit from a common Interceptor class, we can switch back to the
+        // 'ignored receiver' convention.
         HInstruction parameter = parameters.values.first;
-        HIdentity identity = new HIdentity(graph.thisInstruction, parameter);
+        HIdentity identity =
+            new HIdentity(graph.explicitReceiverParameter, parameter);
         add(identity);
         HReturn ret = new HReturn(identity);
         close(ret).addSuccessor(graph.exit);
         return closeFunction();
       }
-      handleIf(
-          function,
-          () {
-            HParameterValue parameter = parameters.values.first;
-            push(new HIdentity(
-                parameter, graph.addConstantNull(constantSystem)));
-          },
-          () {
-            HReturn ret = new HReturn(
-                graph.addConstantBool(false, constantSystem));
-            close(ret).addSuccessor(graph.exit);
-          },
-          null);
+      if (!backend.operatorEqHandlesNullArgument(functionElement)) {
+        handleIf(
+            function,
+            () {
+              HParameterValue parameter = parameters.values.first;
+              push(new HIdentity(
+                  parameter, graph.addConstantNull(constantSystem)));
+            },
+            () {
+              HReturn ret = new HReturn(
+                  graph.addConstantBool(false, constantSystem));
+              close(ret).addSuccessor(graph.exit);
+            },
+            null);
+      }
     }
     function.body.accept(this);
     return closeFunction();
@@ -1040,7 +1059,7 @@
 
     if (function.isConstructor()) {
       ClassElement enclosing = function.getEnclosingClass();
-      if (compiler.world.needsRti(enclosing)) {
+      if (backend.needsRti(enclosing)) {
         assert(currentNode is NewExpression);
         InterfaceType type = elements.getType(currentNode);
         Link<DartType> typeVariable = enclosing.typeVariables;
@@ -1168,7 +1187,7 @@
                              Node callNode) {
     compiler.withCurrentElement(constructor, () {
       assert(invariant(constructor, constructor.isImplementation));
-      constructors.addLast(constructor);
+      constructors.add(constructor);
 
       List<HInstruction> compiledArguments = new List<HInstruction>();
       bool succeeded =
@@ -1186,12 +1205,12 @@
       }
 
       ClassElement superclass = constructor.getEnclosingClass();
-      if (compiler.world.needsRti(superclass)) {
+      if (backend.needsRti(superclass)) {
         // If [superclass] needs RTI, we have to give a value to its
         // type parameters. Those values are in the [supertype]
         // declaration of [subclass].
         ClassElement subclass = inlinedFromElement.getEnclosingClass();
-        DartType supertype = subclass.supertype;
+        InterfaceType supertype = subclass.supertype;
         Link<DartType> typeVariables = superclass.typeVariables;
         supertype.typeArguments.forEach((DartType argument) {
           localsHandler.updateLocal(typeVariables.head.element,
@@ -1435,7 +1454,7 @@
     add(newObject);
 
     // Create the runtime type information, if needed.
-    if (compiler.world.needsRti(classElement)) {
+    if (backend.needsRti(classElement)) {
       List<HInstruction> rtiInputs = <HInstruction>[];
       classElement.typeVariables.forEach((TypeVariableType typeVariable) {
         rtiInputs.add(localsHandler.readLocal(typeVariable.element));
@@ -1459,12 +1478,18 @@
 
 
       FunctionSignature functionSignature = body.computeSignature(compiler);
+      // Provide the parameters to the generative constructor body.
       functionSignature.orderedForEachParameter((parameter) {
-        // if [parameter] is boxed, it will be a field in the box passed as the
-        // last parameter. So no need to direclty pass it.
+        // If [parameter] is boxed, it will be a field in the box passed as the
+        // last parameter. So no need to directly pass it.
         if (!localsHandler.isBoxed(parameter)) {
           bodyCallInputs.add(localsHandler.readLocal(parameter));
         }
+      });
+
+      // Provide the parameter checks to the generative constructor
+      // body.
+      functionSignature.orderedForEachParameter((parameter) {
         // If [parameter] is checked, we pass the already computed
         // boolean to the constructor body.
         if (elements.isParameterChecked(parameter)) {
@@ -1475,7 +1500,7 @@
       });
 
       ClassElement currentClass = constructor.getEnclosingClass();
-      if (compiler.world.needsRti(currentClass)) {
+      if (backend.needsRti(currentClass)) {
         // If [currentClass] needs RTI, we add the type variables as
         // parameters of the generative constructor body.
         currentClass.typeVariables.forEach((DartType argument) {
@@ -1615,7 +1640,7 @@
     // method.
     var enclosing = element.enclosingElement;
     if ((element.isConstructor() || element.isGenerativeConstructorBody())
-        && compiler.world.needsRti(enclosing)) {
+        && backend.needsRti(enclosing)) {
       enclosing.typeVariables.forEach((TypeVariableType typeVariable) {
         HParameterValue param = addParameter(typeVariable.element);
         localsHandler.directLocals[typeVariable.element] = param;
@@ -2212,7 +2237,8 @@
     // TODO(ahe): This should be registered in codegen, not here.
     compiler.enqueuer.codegen.addToWorkList(callElement, elements);
     // TODO(ahe): This should be registered in codegen, not here.
-    compiler.enqueuer.codegen.registerInstantiatedClass(closureClassElement);
+    compiler.enqueuer.codegen.registerInstantiatedClass(
+        closureClassElement, work.resolutionTree);
     assert(!closureClassElement.hasLocalScopeMembers);
 
     List<HInstruction> capturedVariables = <HInstruction>[];
@@ -2567,8 +2593,14 @@
     push(result);
   }
 
-  HForeign createForeign(String code, HType type, List<HInstruction> inputs) {
-    return new HForeign(new LiteralDartString(code), type, inputs);
+  HForeign createForeign(String code,
+                         HType type,
+                         List<HInstruction> inputs,
+                         {bool isSideEffectFree: false}) {
+    return new HForeign(new LiteralDartString(code),
+                        type,
+                        inputs,
+                        isSideEffectFree: isSideEffectFree);
   }
 
   HInstruction getRuntimeTypeInfo(HInstruction target) {
@@ -2578,28 +2610,27 @@
 
   // TODO(karlklose): change construction of the representations to be GVN'able
   // (dartbug.com/7182).
-  List<HInstruction> buildTypeArgumentRepresentations(DartType type) {
+  HInstruction buildTypeArgumentRepresentations(DartType type) {
     // Compute the representation of the type arguments, including access
     // to the runtime type information for type variables as instructions.
-    HInstruction representations;
     if (type.kind == TypeKind.TYPE_VARIABLE) {
-      return <HInstruction>[addTypeVariableReference(type)];
+      return new HLiteralList(<HInstruction>[addTypeVariableReference(type)]);
     } else {
       assert(type.element.isClass());
-      List<HInstruction> arguments = <HInstruction>[];
       InterfaceType interface = type;
+      List<HInstruction> inputs = <HInstruction>[];
+      bool first = true;
+      List<String> templates = <String>[];
       for (DartType argument in interface.typeArguments) {
-        List<HInstruction> inputs = <HInstruction>[];
-        String template = rti.getTypeRepresentation(argument, (variable) {
+        templates.add(rti.getTypeRepresentation(argument, (variable) {
           HInstruction runtimeType = addTypeVariableReference(variable);
           inputs.add(runtimeType);
-        });
-        HInstruction representation =
-            createForeign(template, HType.READABLE_ARRAY, inputs);
-        add(representation);
-        arguments.add(representation);
+        }));
       }
-      return arguments;
+      String template = '[${templates.join(', ')}]';
+      HInstruction representation =
+        createForeign(template, HType.READABLE_ARRAY, inputs);
+      return representation;
     }
   }
 
@@ -2615,10 +2646,31 @@
     } else if (node.argumentsNode is Prefix) {
       visitUnary(node, op);
     } else if (const SourceString("is") == op.source) {
+      visitIsSend(node);
+    } else if (const SourceString("as") == op.source) {
       visit(node.receiver);
       HInstruction expression = pop();
       Node argument = node.arguments.head;
       TypeAnnotation typeAnnotation = argument.asTypeAnnotation();
+      DartType type = elements.getType(typeAnnotation);
+      HInstruction converted = expression.convertType(
+          compiler, type, HTypeConversion.CAST_TYPE_CHECK);
+      if (converted != expression) add(converted);
+      stack.add(converted);
+    } else {
+      visit(node.receiver);
+      visit(node.argumentsNode);
+      var right = pop();
+      var left = pop();
+      visitBinary(left, op, right, elements.getSelector(node), node);
+    }
+  }
+
+  void visitIsSend(Send node) {
+      Node argument = node.arguments.head;
+      visit(node.receiver);
+      HInstruction expression = pop();
+      TypeAnnotation typeAnnotation = argument.asTypeAnnotation();
       bool isNot = false;
       // TODO(ngeoffray): Duplicating pattern in resolver. We should
       // add a new kind of node.
@@ -2639,77 +2691,52 @@
 
       HInstruction instruction;
       if (type.kind == TypeKind.TYPE_VARIABLE) {
-        List<HInstruction> representations =
-            buildTypeArgumentRepresentations(type);
-        assert(representations.length == 1);
         HInstruction runtimeType = addTypeVariableReference(type);
         Element helper = backend.getGetObjectIsSubtype();
         HInstruction helperCall = new HStatic(helper);
         add(helperCall);
         List<HInstruction> inputs = <HInstruction>[helperCall, expression,
                                                    runtimeType];
-        instruction = new HInvokeStatic(inputs, HType.BOOLEAN);
-        add(instruction);
-        compiler.enqueuer.codegen.registerIsCheck(type);
-
-      } else if (RuntimeTypeInformation.hasTypeArguments(type)) {
-
-        void argumentsCheck() {
-          HInstruction typeInfo = getRuntimeTypeInfo(expression);
-          Element helper = backend.getCheckArguments();
-          HInstruction helperCall = new HStatic(helper);
-          add(helperCall);
-          List<HInstruction> representations =
-              buildTypeArgumentRepresentations(type);
-          Element element = type.element;
-          String substitution = backend.namer.substitutionName(element);
-          if (backend.emitter.nativeEmitter.requiresNativeIsCheck(element)) {
-            substitution = '$substitution()';
-          }
-          HInstruction fieldGet =
-              createForeign('#.$substitution', HType.UNKNOWN, [expression]);
-          HInstruction representationList = new HLiteralList(representations);
-          add(fieldGet);
-          add(representationList);
-          List<HInstruction> inputs = <HInstruction>[helperCall,
-                                                     fieldGet,
-                                                     typeInfo,
-                                                     representationList];
-          push(new HInvokeStatic(inputs, HType.UNKNOWN));
-        }
-
-        void classCheck() { push(new HIs(type, <HInstruction>[expression])); }
-
-        SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node);
-        branchBuilder.handleLogicalAndOr(classCheck, argumentsCheck,
-                                         isAnd: true);
-        instruction = pop();
+        HInstruction call = new HInvokeStatic(inputs, HType.BOOLEAN);
+        add(call);
+        instruction = new HIs(type, <HInstruction>[expression, call],
+                              HIs.VARIABLE_CHECK);
+      } else if (RuntimeTypes.hasTypeArguments(type)) {
+        Element element = type.element;
+        bool needsNativeCheck =
+            backend.emitter.nativeEmitter.requiresNativeIsCheck(element);
+        Element helper = backend.getCheckSubtype();
+        HInstruction helperCall = new HStatic(helper);
+        add(helperCall);
+        HInstruction representations =
+          buildTypeArgumentRepresentations(type);
+        add(representations);
+        HInstruction isFieldName =
+            addConstantString(node, backend.namer.operatorIs(element));
+        // TODO(karlklose): use [:null:] for [asField] if [element] does not
+        // have a subclass.
+        HInstruction asFieldName =
+            addConstantString(node, backend.namer.substitutionName(element));
+        HInstruction native =
+            graph.addConstantBool(needsNativeCheck, constantSystem);
+        List<HInstruction> inputs = <HInstruction>[helperCall,
+                                                   expression,
+                                                   isFieldName,
+                                                   representations,
+                                                   asFieldName,
+                                                   native];
+        HInstruction call = new HInvokeStatic(inputs, HType.BOOLEAN);
+        add(call);
+        instruction = new HIs(type, <HInstruction>[expression, call],
+                              HIs.COMPOUND_CHECK);
       } else {
-        instruction = new HIs(type, <HInstruction>[expression]);
-        add(instruction);
+        instruction = new HIs(type, <HInstruction>[expression], HIs.RAW_CHECK);
       }
       if (isNot) {
-        instruction = new HNot(instruction);
         add(instruction);
+        instruction = new HNot(instruction);
       }
-      stack.add(instruction);
-    } else if (const SourceString("as") == op.source) {
-      visit(node.receiver);
-      HInstruction expression = pop();
-      Node argument = node.arguments.head;
-      TypeAnnotation typeAnnotation = argument.asTypeAnnotation();
-      DartType type = elements.getType(typeAnnotation);
-      HInstruction converted = expression.convertType(
-          compiler, type, HTypeConversion.CAST_TYPE_CHECK);
-      if (converted != expression) add(converted);
-      stack.add(converted);
-    } else {
-      visit(node.receiver);
-      visit(node.argumentsNode);
-      var right = pop();
-      var left = pop();
-      visitBinary(left, op, right, elements.getSelector(node), node);
-    }
+      push(instruction);
   }
 
   void addDynamicSendArgumentsToList(Send node, List<HInstruction> list) {
@@ -2805,7 +2832,7 @@
     // because of the way inlining currently works that is hard to do
     // with re-evaluating the receiver.
     if (isThisSend(node)) {
-      HType receiverType = localsHandler.getTypeOfThis();
+      HType receiverType = getTypeOfThis();
       selector = receiverType.refine(selector, compiler);
     }
 
@@ -3046,16 +3073,19 @@
     }
   }
 
-  generateSuperNoSuchMethodSend(Send node) {
-    Selector selector = elements.getSelector(node);
+  generateSuperNoSuchMethodSend(Send node,
+                                Selector selector,
+                                List<HInstruction> arguments) {
     SourceString name = selector.name;
 
     ClassElement cls = currentElement.getEnclosingClass();
     Element element = cls.lookupSuperMember(Compiler.NO_SUCH_METHOD);
     if (element.enclosingElement.declaration != compiler.objectClass) {
       // Register the call as dynamic if [:noSuchMethod:] on the super class
-      // is _not_ the default implementation from [:Object:].
-      compiler.enqueuer.codegen.registerDynamicInvocation(name, selector);
+      // is _not_ the default implementation from [:Object:], in case
+      // the [:noSuchMethod:] implementation does an [:invokeOn:] on
+      // the invocation mirror.
+      compiler.enqueuer.codegen.registerSelectorUse(selector);
     }
     HStatic target = new HStatic(element);
     add(target);
@@ -3068,11 +3098,6 @@
         constantSystem.createString(new DartString.literal(internalName), node);
 
     Element createInvocationMirror = backend.getCreateInvocationMirror();
-
-    var arguments = new List<HInstruction>();
-    if (node.argumentsNode != null) {
-      addGenericSendArgumentsToList(node.arguments, arguments);
-    }
     var argumentsInstruction = new HLiteralList(arguments);
     add(argumentsInstruction);
 
@@ -3117,17 +3142,13 @@
     Selector selector = elements.getSelector(node);
     Element element = elements[node];
     if (Elements.isUnresolved(element)) {
-      return generateSuperNoSuchMethodSend(node);
+      List<HInstruction> arguments = <HInstruction>[];
+      if (!node.isPropertyAccess) {
+        addGenericSendArgumentsToList(node.arguments, arguments);
+      }
+      return generateSuperNoSuchMethodSend(node, selector, arguments);
     }
-    // TODO(5346): Try to avoid the need for calling [declaration] before
-    // creating an [HStatic].
-    HInstruction target = new HStatic(element.declaration);
-    HInstruction context = localsHandler.readThis();
-    add(target);
-    var inputs = <HInstruction>[target, context];
-    if (backend.isInterceptedMethod(element)) {
-      inputs.add(context);
-    }
+    List<HInstruction> inputs = buildSuperAccessorInputs(element);
     if (node.isPropertyAccess) {
       push(new HInvokeSuper(inputs));
     } else if (element.isFunction() || element.isGenerativeConstructor()) {
@@ -3142,7 +3163,7 @@
         push(new HInvokeSuper(inputs));
       }
     } else {
-      target = new HInvokeSuper(inputs);
+      HInstruction target = new HInvokeSuper(inputs);
       add(target);
       inputs = <HInstruction>[target];
       addDynamicSendArgumentsToList(node, inputs);
@@ -3152,6 +3173,31 @@
   }
 
   /**
+   * Generate code to extract the type arguments from the object, substitute
+   * them as an instance of the type we are testing against (if necessary), and
+   * extract the type argument by the index of the variable in the list of type
+   * variables for that class.
+   */
+  HInstruction readTypeVariable(ClassElement cls,
+                                TypeVariableElement variable) {
+    assert(currentElement.isInstanceMember());
+    int index = RuntimeTypes.getTypeVariableIndex(variable);
+    String substitutionNameString = backend.namer.substitutionName(cls);
+    HInstruction substitutionName = graph.addConstantString(
+        new LiteralDartString(substitutionNameString), null, constantSystem);
+    HInstruction target = localsHandler.readThis();
+    HInstruction substitution = createForeign('#[#]', HType.UNKNOWN,
+        <HInstruction>[target, substitutionName]);
+    add(substitution);
+    pushInvokeHelper3(backend.getGetRuntimeTypeArgument(),
+                      target,
+                      substitution,
+                      graph.addConstantInt(index, constantSystem),
+                      HType.UNKNOWN);
+    return pop();
+  }
+
+  /**
    * Helper to create an instruction that gets the value of a type variable.
    */
   HInstruction addTypeVariableReference(TypeVariableType type) {
@@ -3161,30 +3207,15 @@
       member = closureClass.methodElement;
       member = member.getOutermostEnclosingMemberOrTopLevel();
     }
-    if (member.isConstructor() || member.isGenerativeConstructorBody()) {
+    if (member.isConstructor()
+        || member.isGenerativeConstructorBody()
+        || member.isField()) {
       // The type variable is stored in a parameter of the method.
       return localsHandler.readLocal(type.element);
     } else if (member.isInstanceMember()) {
-      // The type variable is stored on the object.  Generate code to extract
-      // the type arguments from the object, substitute them as an instance
-      // of the type we are testing against (if necessary), and extract the
-      // type argument by the index of the variable in the list of type
-      // variables for that class.
-      int index = RuntimeTypeInformation.getTypeVariableIndex(type);
-      HInstruction thisObject = localsHandler.readThis();
-      String substitutionNameString =
-          backend.namer.substitutionName(member.getEnclosingClass());
-      HInstruction substitutionName = graph.addConstantString(
-          new LiteralDartString(substitutionNameString), null, constantSystem);
-      HInstruction substitution = createForeign('#[#]', HType.UNKNOWN,
-          <HInstruction>[thisObject, substitutionName]);
-      add(substitution);
-      pushInvokeHelper3(backend.getGetRuntimeTypeArgument(),
-                        thisObject,
-                        substitution,
-                        graph.addConstantInt(index, constantSystem),
-                        HType.UNKNOWN);
-      return pop();
+      // The type variable is stored on the object.
+      return readTypeVariable(member.getEnclosingClass(),
+                              type.element);
     } else {
       // TODO(ngeoffray): Match the VM behavior and throw an
       // exception at runtime.
@@ -3213,7 +3244,8 @@
       inputs.add(addTypeVariableReference(variable));
     });
 
-    HInstruction result = createForeign(template, HType.STRING, inputs);
+    HInstruction result = createForeign(
+        template, HType.STRING, inputs, isSideEffectFree: true);
     add(result);
     return result;
   }
@@ -3221,7 +3253,7 @@
   void handleListConstructor(InterfaceType type,
                              Node currentNode,
                              HInstruction newObject) {
-    if (!compiler.world.needsRti(type.element)) return;
+    if (!backend.needsRti(type.element)) return;
     if (!type.isRaw) {
       List<HInstruction> inputs = <HInstruction>[];
       type.typeArguments.forEach((DartType argument) {
@@ -3234,7 +3266,7 @@
   void callSetRuntimeTypeInfo(ClassElement element,
                               List<HInstruction> rtiInputs,
                               HInstruction newObject) {
-    if (!compiler.world.needsRti(element) || element.typeVariables.isEmpty) {
+    if (!backend.needsRti(element) || element.typeVariables.isEmpty) {
       return;
     }
 
@@ -3261,13 +3293,14 @@
     bool isListConstructor = false;
     computeType(element) {
       Element originalElement = elements[node];
-      if (identical(originalElement.getEnclosingClass(), compiler.listClass)) {
+      if (Elements.isFixedListConstructorCall(
+              originalElement, node, compiler)) {
         isListConstructor = true;
-        if (node.arguments.isEmpty) {
-          return HType.EXTENDABLE_ARRAY;
-        } else {
-          return HType.MUTABLE_ARRAY;
-        }
+        return HType.FIXED_ARRAY;
+      } else if (Elements.isGrowableListConstructorCall(
+                    originalElement, node, compiler)) {
+        isListConstructor = true;
+        return HType.EXTENDABLE_ARRAY;
       } else if (element.isGenerativeConstructor()) {
         ClassElement cls = element.getEnclosingClass();
         return new HType.nonNullExact(cls.thisType, compiler);
@@ -3304,7 +3337,7 @@
       generateAbstractClassInstantiationError(node, cls.name.slowToString());
       return;
     }
-    if (compiler.world.needsRti(cls)) {
+    if (backend.needsRti(cls)) {
       Link<DartType> typeVariable = cls.typeVariables;
       type.typeArguments.forEach((DartType argument) {
         inputs.add(analyzeTypeArgument(argument, node));
@@ -3326,7 +3359,7 @@
     // not know about the type argument. Therefore we special case
     // this constructor to have the setRuntimeTypeInfo called where
     // the 'new' is done.
-    if (isListConstructor && compiler.world.needsRti(compiler.listClass)) {
+    if (isListConstructor && backend.needsRti(compiler.listClass)) {
       handleListConstructor(type, node, newInstance);
     }
   }
@@ -3377,7 +3410,8 @@
       }
 
       HInvokeStatic instruction = new HInvokeStatic(inputs, HType.UNKNOWN);
-      HType returnType = new HType.inferredForElement(element, compiler);
+      HType returnType =
+          new HType.inferredReturnTypeForElement(element, compiler);
       if (returnType.isUnknown()) {
         // TODO(ngeoffray): Only do this if knowing the return type is
         // useful.
@@ -3410,8 +3444,12 @@
       Constant constant = handler.compileNodeWithDefinitions(node, elements);
       stack.add(graph.addConstant(constant));
     } else if (element.isTypeVariable()) {
-      // TODO(6248): implement support for type variables.
-      compiler.unimplemented('first class type for type variable', node: node);
+      HInstruction value =
+          addTypeVariableReference(element.computeType(compiler));
+      pushInvokeHelper1(backend.getRuntimeTypeToString(),
+                        value, HType.STRING);
+      pushInvokeHelper1(backend.getCreateRuntimeType(),
+                        pop(), HType.UNKNOWN);
     } else {
       internalError('unexpected element kind $element', node: node);
     }
@@ -3579,6 +3617,38 @@
     return new HInvokeDynamicMethod(selector, inputs, isIntercepted);
   }
 
+  void handleComplexOperatorSend(SendSet node,
+                                 HInstruction receiver,
+                                 Link<Node> arguments) {
+    HInstruction rhs;
+    if (node.isPrefix || node.isPostfix) {
+      rhs = graph.addConstantInt(1, constantSystem);
+    } else {
+      visit(arguments.head);
+      assert(arguments.tail.isEmpty);
+      rhs = pop();
+    }
+    visitBinary(receiver, node.assignmentOperator, rhs,
+                elements.getOperatorSelectorInComplexSendSet(node), node);
+  }
+
+  List<HInstruction> buildSuperAccessorInputs(Element element) {
+    List<HInstruction> inputs = <HInstruction>[];
+    if (Elements.isUnresolved(element)) return inputs;
+    // TODO(5346): Try to avoid the need for calling [declaration] before
+    // creating an [HStatic].
+    HInstruction target = new HStatic(element.declaration);
+    add(target);
+    inputs.add(target);
+    HInstruction context = localsHandler.readThis();
+    inputs.add(context);
+    if (backend.isInterceptedMethod(element)) {
+      inputs.add(context);
+    }
+    return inputs;
+  }
+
+
   visitSendSet(SendSet node) {
     Element element = elements[node];
     if (!Elements.isUnresolved(element) && element.impliesType()) {
@@ -3589,19 +3659,54 @@
     }
     Operator op = node.assignmentOperator;
     if (node.isSuperCall) {
+      HInstruction result;
+      List<HInstruction> setterInputs = buildSuperAccessorInputs(element);
+      if (identical(node.assignmentOperator.source.stringValue, '=')) {
+        addDynamicSendArgumentsToList(node, setterInputs);
+        result = setterInputs.last;
+      } else {
+        Element getter = elements[node.selector];
+        List<HInstruction> getterInputs = buildSuperAccessorInputs(getter);
+        Link<Node> arguments = node.arguments;
+        if (node.isIndex) {
+          // If node is of the from [:super.foo[0] += 2:], the send has
+          // two arguments: the index and the left hand side. We get
+          // the index and add it as input of the getter and the
+          // setter.
+          visit(arguments.head);
+          arguments = arguments.tail;
+          HInstruction index = pop();
+          getterInputs.add(index);
+          setterInputs.add(index);
+        }
+        HInstruction getterInstruction;
+        if (Elements.isUnresolved(getter)) {
+          generateSuperNoSuchMethodSend(
+              node,
+              elements.getGetterSelectorInComplexSendSet(node),
+              getterInputs);
+          getterInstruction = pop();
+        } else {
+          getterInstruction = new HInvokeSuper(getterInputs);
+          add(getterInstruction);
+        }
+        handleComplexOperatorSend(node, getterInstruction, arguments);
+        setterInputs.add(pop());
+
+        if (node.isPostfix) {
+          result = getterInstruction;
+        } else {
+          result = setterInputs.last;
+        }
+      }
       if (Elements.isUnresolved(element)) {
-        return generateSuperNoSuchMethodSend(node);
+        generateSuperNoSuchMethodSend(
+            node, elements.getSelector(node), setterInputs);
+        pop();
+      } else {
+        add(new HInvokeSuper(setterInputs, isSetter: true));
       }
-      HInstruction target = new HStatic(element);
-      HInstruction context = localsHandler.readThis();
-      add(target);
-      var inputs = <HInstruction>[target, context];
-      addDynamicSendArgumentsToList(node, inputs);
-      if (!identical(node.assignmentOperator.source.stringValue, '=')) {
-        compiler.unimplemented('complex super assignment',
-                               node: node.assignmentOperator);
-      }
-      push(new HInvokeSuper(inputs, isSetter: true));
+      stack.add(result);
     } else if (node.isIndex) {
       if (const SourceString("=") == op.source) {
         // TODO(kasperl): We temporarily disable inlining because the
@@ -3613,36 +3718,32 @@
       } else {
         visit(node.receiver);
         HInstruction receiver = pop();
-        visit(node.argumentsNode);
-        HInstruction value;
+        Link<Node> arguments = node.arguments;
         HInstruction index;
-        // Compound assignments are considered as being prefix.
-        bool isCompoundAssignment = op.source.stringValue.endsWith('=');
-        bool isPrefix = !node.isPostfix;
-        if (isCompoundAssignment) {
-          value = pop();
+        if (node.isIndex) {
+          visit(arguments.head);
+          arguments = arguments.tail;
           index = pop();
-        } else {
-          index = pop();
-          value = graph.addConstantInt(1, constantSystem);
         }
 
-        HInvokeDynamicMethod left = buildInvokeDynamic(
+        HInvokeDynamicMethod getterInstruction = buildInvokeDynamic(
             node,
             elements.getGetterSelectorInComplexSendSet(node),
             receiver,
             <HInstruction>[index]);
-        add(left);
-        visitBinary(left, op, value,
-                    elements.getOperatorSelectorInComplexSendSet(node), node);
-        value = pop();
+        add(getterInstruction);
+
+        handleComplexOperatorSend(node, getterInstruction, arguments);
+        HInstruction value = pop();
+
         HInvokeDynamicMethod assign = buildInvokeDynamic(
             node, elements.getSelector(node), receiver, [index, value]);
         add(assign);
-        if (isPrefix) {
-          stack.add(value);
+
+        if (node.isPostfix) {
+          stack.add(getterInstruction);
         } else {
-          stack.add(left);
+          stack.add(value);
         }
       }
     } else if (const SourceString("=") == op.source) {
@@ -3657,8 +3758,6 @@
       assert(const SourceString("++") == op.source ||
              const SourceString("--") == op.source ||
              node.assignmentOperator.source.stringValue.endsWith("="));
-      bool isCompoundAssignment = !node.arguments.isEmpty;
-      bool isPrefix = !node.isPostfix;  // Compound assignments are prefix.
 
       // [receiver] is only used if the node is an instance send.
       HInstruction receiver = null;
@@ -3669,28 +3768,20 @@
       } else {
         generateGetter(node, elements[node.selector]);
       }
-      HInstruction left = pop();
-      HInstruction right;
-      if (isCompoundAssignment) {
-        visit(node.argumentsNode);
-        right = pop();
-      } else {
-        right = graph.addConstantInt(1, constantSystem);
-      }
-      visitBinary(left, op, right,
-                  elements.getOperatorSelectorInComplexSendSet(node), node);
-      HInstruction operation = pop();
-      assert(operation != null);
+      HInstruction getterInstruction = pop();
+      handleComplexOperatorSend(node, getterInstruction, node.arguments);
+      HInstruction value = pop();
+      assert(value != null);
       if (Elements.isInstanceSend(node, elements)) {
         assert(receiver != null);
-        generateInstanceSetterWithCompiledReceiver(node, receiver, operation);
+        generateInstanceSetterWithCompiledReceiver(node, receiver, value);
       } else {
         assert(receiver == null);
-        generateSetter(node, element, operation);
+        generateSetter(node, element, value);
       }
-      if (!isPrefix) {
+      if (node.isPostfix) {
         pop();
-        stack.add(left);
+        stack.add(getterInstruction);
       }
     }
   }
@@ -4042,16 +4133,14 @@
          !link.isEmpty;
          link = link.tail) {
       visit(link.head);
-      inputs.addLast(pop());
-      inputs.addLast(pop());
+      inputs.add(pop());
+      inputs.add(pop());
     }
     HLiteralList keyValuePairs = new HLiteralList(inputs);
     add(keyValuePairs);
-    DartType mapType = compiler.mapLiteralClass.computeType(compiler);
-    // TODO(ngeoffray): Use the actual implementation type of a map
-    // literal.
-    pushInvokeHelper1(backend.getMapMaker(), keyValuePairs,
-        new HType.nonNullSubtype(mapType, compiler));
+    HType mapType = new HType.nonNullSubtype(
+        backend.mapLiteralClass.computeType(compiler), compiler);
+    pushInvokeHelper1(backend.getMapMaker(), keyValuePairs, mapType);
   }
 
   visitLiteralMapEntry(LiteralMapEntry node) {
@@ -4483,8 +4572,10 @@
                 graph.addConstantBool(true, constantSystem);
             stack.add(condition);
           } else {
-            HInstruction condition =
-                new HIs(type, <HInstruction>[unwrappedException]);
+            // TODO(karlkose): support type arguments here.
+            HInstruction condition = new HIs(type,
+                                             <HInstruction>[unwrappedException],
+                                             HIs.RAW_CHECK);
             push(condition);
           }
         } else {
@@ -4502,8 +4593,9 @@
             if (type == null) {
               compiler.cancel('Catch with unresolved type', node: catchBlock);
             }
-            condition =
-                new HIs(type, <HInstruction>[unwrappedException], nullOk: true);
+            // TODO(karlkose): support type arguments here.
+            condition = new HIs(type, <HInstruction>[unwrappedException],
+                                HIs.RAW_CHECK, nullOk: true);
             push(condition);
           }
         }
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
index f2fe22c..473756c 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
@@ -79,10 +79,8 @@
         // arguments, the emitter will generate stubs to handle them,
         // and needs to know if the method is overridden.
         nativeEmitter.overriddenMethods.add(element);
-        StringBuffer buffer = new StringBuffer();
-        body =
-            nativeEmitter.generateMethodBodyWithPrototypeCheckForElement(
-                element, codegen.body, codegen.parameters);
+        body = nativeEmitter.generateMethodBodyWithPrototypeCheckForElement(
+                  element, codegen.body, codegen.parameters);
       } else {
         body = codegen.body;
       }
@@ -1526,7 +1524,8 @@
           methodName = 'split';
           // Split returns a List, so we make sure the backend knows the
           // list class is instantiated.
-          world.registerInstantiatedClass(compiler.listClass);
+          world.registerInstantiatedClass(
+              compiler.listClass, work.resolutionTree);
         } else if (target == backend.jsStringConcat) {
           push(new js.Binary('+', object, arguments[0]), node);
           return;
@@ -1625,7 +1624,6 @@
     if (target != null) {
       // If we know we're calling a specific method, register that
       // method only.
-      assert(selector.mask != null);
       world.registerDynamicInvocationOf(target, selector);
     } else {
       SourceString name = node.selector.name;
@@ -1647,7 +1645,8 @@
   void registerGetter(HInvokeDynamic node) {
     Selector selector = getOptimizedSelectorFor(node, node.selector);
     world.registerDynamicGetter(selector.name, selector);
-    world.registerInstantiatedClass(compiler.functionClass);
+    world.registerInstantiatedClass(
+        compiler.functionClass, work.resolutionTree);
     registerInvoke(node, selector);
   }
 
@@ -1739,8 +1738,7 @@
   visitFieldSet(HFieldSet node) {
     Element element = node.element;
     String name = _fieldPropertyName(element);
-    DartType type = node.receiver.instructionType.computeType(compiler);
-    if (type != null && !identical(type.kind, TypeKind.MALFORMED_TYPE)) {
+    if (!node.receiver.instructionType.isUnknown()) {
       // Field setters in the generative constructor body are handled in a
       // step "SsaConstructionFieldTypes" in the ssa optimizer.
       if (!work.element.isGenerativeConstructorBody()) {
@@ -1770,12 +1768,13 @@
   }
 
   void registerForeignType(HType type) {
+    // TODO(kasperl): This looks shaky. It makes sense if the type is
+    // exact, but otherwise we should be registering more types as
+    // instantiated. We should find a way of using something along the
+    // lines of the NativeEnqueuerBase.processNativeBehavior method.
+    if (type.isUnknown()) return;
     DartType dartType = type.computeType(compiler);
-    if (dartType == null) {
-      assert(type == HType.UNKNOWN);
-      return;
-    }
-    world.registerInstantiatedClass(dartType.element);
+    world.registerInstantiatedClass(dartType.element, work.resolutionTree);
   }
 
   visitForeign(HForeign node) {
@@ -1835,11 +1834,14 @@
     assert(isGenerateAtUseSite(node));
     generateConstant(node.constant);
     DartType type = node.constant.computeType(compiler);
-    if (node.constant is ConstructedConstant) {
+    if (node.constant is ConstructedConstant ||
+        node.constant is InterceptorConstant) {
       ConstantHandler handler = compiler.constantHandler;
-      handler.registerCompileTimeConstant(node.constant);
+      handler.registerCompileTimeConstant(node.constant, work.resolutionTree);
     }
-    world.registerInstantiatedClass(type.element);
+    if (node.constant is! InterceptorConstant) {
+      world.registerInstantiatedClass(type.element, work.resolutionTree);
+    }
   }
 
   visitNot(HNot node) {
@@ -2048,7 +2050,8 @@
       if (instr is !HInvokeStatic) {
         backend.registerNonCallStaticUse(node);
         if (node.element.isFunction()) {
-          world.registerInstantiatedClass(compiler.functionClass);
+          world.registerInstantiatedClass(
+              compiler.functionClass, work.resolutionTree);
         }
       } else if (instr.target != node) {
         backend.registerNonCallStaticUse(node);
@@ -2059,7 +2062,7 @@
     ClassElement cls = element.getEnclosingClass();
     if (element.isGenerativeConstructor()
         || (element.isFactoryConstructor() && cls == compiler.listClass)) {
-      world.registerInstantiatedClass(cls);
+      world.registerInstantiatedClass(cls, work.resolutionTree);
     }
     push(new js.VariableUse(backend.namer.isolateAccess(node.element)));
   }
@@ -2115,7 +2118,8 @@
   }
 
   void visitLiteralList(HLiteralList node) {
-    world.registerInstantiatedClass(compiler.listClass);
+    world.registerInstantiatedClass(
+        compiler.listClass, work.resolutionTree);
     generateArrayLiteral(node);
   }
 
@@ -2249,7 +2253,7 @@
   void checkType(HInstruction input, DartType type, {bool negative: false}) {
     assert(invariant(input, !type.isMalformed,
                      message: 'Attempt to check malformed type $type'));
-    world.registerIsCheck(type);
+    world.registerIsCheck(type, work.resolutionTree);
     Element element = type.element;
     use(input);
     js.PropertyAccess field =
@@ -2311,68 +2315,70 @@
 
   void visitIs(HIs node) {
     DartType type = node.typeExpression;
-    world.registerIsCheck(type);
-    Element element = type.element;
-    if (identical(element.kind, ElementKind.TYPE_VARIABLE)) {
-      compiler.unimplemented("visitIs for type variables",
-                             instruction: node.expression);
-    }
-    LibraryElement coreLibrary = compiler.coreLibrary;
-    ClassElement objectClass = compiler.objectClass;
+    world.registerIsCheck(type, work.resolutionTree);
     HInstruction input = node.expression;
 
-    if (identical(element, objectClass) ||
-        identical(element, compiler.dynamicClass)) {
-      // The constant folder also does this optimization, but we make
-      // it safe by assuming it may have not run.
-      push(newLiteralBool(true), node);
-    } else if (element == compiler.stringClass) {
-      checkString(input, '===');
-      attachLocationToLast(node);
-    } else if (element == compiler.doubleClass) {
-      checkDouble(input, '===');
-      attachLocationToLast(node);
-    } else if (element == compiler.numClass) {
-      checkNum(input, '===');
-      attachLocationToLast(node);
-    } else if (element == compiler.boolClass) {
-      checkBool(input, '===');
-      attachLocationToLast(node);
-    } else if (element == compiler.functionClass) {
-      checkFunction(input, type);
-      attachLocationToLast(node);
-    } else if (element == compiler.intClass) {
-      // The is check in the code tells us that it might not be an
-      // int. So we do a typeof first to avoid possible
-      // deoptimizations on the JS engine due to the Math.floor check.
-      checkNum(input, '===');
-      js.Expression numTest = pop();
-      checkBigInt(input, '===');
-      push(new js.Binary('&&', numTest, pop()), node);
-    } else if (Elements.isNumberOrStringSupertype(element, compiler)) {
-      handleNumberOrStringSupertypeCheck(input, type);
-      attachLocationToLast(node);
-    } else if (Elements.isStringOnlySupertype(element, compiler)) {
-      handleStringSupertypeCheck(input, type);
-      attachLocationToLast(node);
-    } else if (identical(element, compiler.listClass)
-               || Elements.isListSupertype(element, compiler)) {
-      handleListOrSupertypeCheck(input, type);
-      attachLocationToLast(node);
-    } else if (element.isTypedef()) {
-      checkNonNull(input);
-      js.Expression nullTest = pop();
-      checkType(input, type);
-      push(new js.Binary('&&', nullTest, pop()));
-      attachLocationToLast(node);
-    } else if (input.canBePrimitive(compiler) || input.canBeNull()) {
-      checkObject(input, '===');
-      js.Expression objectTest = pop();
-      checkType(input, type);
-      push(new js.Binary('&&', objectTest, pop()), node);
+    if (node.isVariableCheck || node.isCompoundCheck) {
+      use(node.checkCall);
     } else {
-      checkType(input, type);
-      attachLocationToLast(node);
+      assert(node.isRawCheck);
+      LibraryElement coreLibrary = compiler.coreLibrary;
+      ClassElement objectClass = compiler.objectClass;
+      Element element = type.element;
+
+      if (identical(element, objectClass) ||
+          identical(element, compiler.dynamicClass)) {
+        // The constant folder also does this optimization, but we make
+        // it safe by assuming it may have not run.
+        push(newLiteralBool(true), node);
+      } else if (element == compiler.stringClass) {
+        checkString(input, '===');
+        attachLocationToLast(node);
+      } else if (element == compiler.doubleClass) {
+        checkDouble(input, '===');
+        attachLocationToLast(node);
+      } else if (element == compiler.numClass) {
+        checkNum(input, '===');
+        attachLocationToLast(node);
+      } else if (element == compiler.boolClass) {
+        checkBool(input, '===');
+        attachLocationToLast(node);
+      } else if (element == compiler.functionClass) {
+        checkFunction(input, type);
+        attachLocationToLast(node);
+      } else if (element == compiler.intClass) {
+        // The is check in the code tells us that it might not be an
+        // int. So we do a typeof first to avoid possible
+        // deoptimizations on the JS engine due to the Math.floor check.
+        checkNum(input, '===');
+        js.Expression numTest = pop();
+        checkBigInt(input, '===');
+        push(new js.Binary('&&', numTest, pop()), node);
+      } else if (Elements.isNumberOrStringSupertype(element, compiler)) {
+        handleNumberOrStringSupertypeCheck(input, type);
+        attachLocationToLast(node);
+      } else if (Elements.isStringOnlySupertype(element, compiler)) {
+        handleStringSupertypeCheck(input, type);
+        attachLocationToLast(node);
+      } else if (identical(element, compiler.listClass)
+                 || Elements.isListSupertype(element, compiler)) {
+        handleListOrSupertypeCheck(input, type);
+        attachLocationToLast(node);
+      } else if (element.isTypedef()) {
+        checkNonNull(input);
+        js.Expression nullTest = pop();
+        checkType(input, type);
+        push(new js.Binary('&&', nullTest, pop()));
+        attachLocationToLast(node);
+      } else if (input.canBePrimitive(compiler) || input.canBeNull()) {
+        checkObject(input, '===');
+        js.Expression objectTest = pop();
+        checkType(input, type);
+        push(new js.Binary('&&', objectTest, pop()), node);
+      } else {
+        checkType(input, type);
+        attachLocationToLast(node);
+      }
     }
     if (node.nullOk) {
       checkNull(input);
@@ -2382,15 +2388,11 @@
 
   void visitTypeConversion(HTypeConversion node) {
     if (node.isChecked) {
-      DartType type = node.instructionType.computeType(compiler);
-      Element element = type.element;
-      world.registerIsCheck(type);
-
       if (node.isArgumentTypeCheck) {
-        if (element == backend.jsIntClass) {
+        if (node.isInteger()) {
           checkInt(node.checkedInput, '!==');
         } else {
-          assert(element == backend.jsNumberClass);
+          assert(node.isNumber());
           checkNum(node.checkedInput, '!==');
         }
         js.Expression test = pop();
@@ -2403,7 +2405,17 @@
         pushStatement(new js.If.noElse(test, body), node);
         return;
       }
+
       assert(node.isCheckedModeCheck || node.isCastTypeCheck);
+      DartType type = node.typeExpression;
+      world.registerIsCheck(type, work.resolutionTree);
+
+      // TODO(kasperl): For now, we ignore type checks against type
+      // variables. This is clearly wrong.
+      if (type.kind == TypeKind.TYPE_VARIABLE) {
+        use(node.checkedInput);
+        return;
+      }
 
       FunctionElement helperElement;
       if (node.isBooleanConversionCheck) {
@@ -2425,7 +2437,7 @@
         // 2 arguments implies that the method is either [propertyTypeCheck]
         // or [propertyTypeCast].
         assert(!type.isMalformed);
-        String additionalArgument = backend.namer.operatorIs(element);
+        String additionalArgument = backend.namer.operatorIs(type.element);
         arguments.add(js.string(additionalArgument));
       } else if (parameterCount == 3) {
         // 3 arguments implies that the method is [malformedTypeCheck].
@@ -2621,7 +2633,7 @@
 
   String pushLabel() {
     String label = 'L${labelId++}';
-    labels.addLast(label);
+    labels.add(label);
     return label;
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart b/sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart
index 234e7ab..9e61f1b 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart
@@ -86,7 +86,7 @@
                                    Compiler compiler) {
     HInstruction index = instruction.inputs[2];
     if (input == instruction.inputs[1] &&
-        (index.isTypeUnknown() || index.isNumber())) {
+        index.instructionType.canBePrimitiveNumber(compiler)) {
       return HType.MUTABLE_ARRAY;
     }
     // The index should be an int when the receiver is a string or array.
@@ -114,7 +114,7 @@
                                    Compiler compiler) {
     HInstruction index = instruction.inputs[2];
     if (input == instruction.inputs[1] &&
-        (index.isTypeUnknown() || index.isNumber())) {
+        index.instructionType.canBePrimitiveNumber(compiler)) {
       return HType.INDEXABLE_PRIMITIVE;
     }
     // The index should be an int when the receiver is a string or array.
@@ -480,7 +480,7 @@
     // is desired, then numbers are incorrect, though.
     if (propagatedType.isUnknown() || propagatedType.isBoolean()) {
       HInstruction left = instruction.inputs[1];
-      if (left.isTypeUnknown() || left.isNumber()) {
+      if (left.instructionType.canBePrimitiveNumber(compiler)) {
         return HType.NUMBER;
       }
     }
@@ -507,7 +507,6 @@
                                    Compiler compiler) {
     HInstruction left = instruction.inputs[1];
     HInstruction right = instruction.inputs[2];
-    HType propagatedType = instruction.instructionType;
     if (input == left && right.instructionType.isUseful()) {
       // All our useful types have 'identical' semantics. But we don't want to
       // speculatively test for all possible types. Therefore we try to match
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index d7acb32..cf77fd6 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -120,6 +120,8 @@
   HBasicBlock entry;
   HBasicBlock exit;
   HThis thisInstruction;
+  /// Receiver parameter, set for methods using interceptor calling convention.
+  HParameterValue explicitReceiverParameter;
   bool isRecursiveMethod = false;
   bool calledInLoop = false;
   final List<HBasicBlock> blocks;
@@ -167,10 +169,12 @@
     if (constant.isList()) return HType.READABLE_ARRAY;
     if (constant.isFunction()) return HType.UNKNOWN;
     if (constant.isSentinel()) return HType.UNKNOWN;
-    ObjectConstant objectConstant = constant;
+    // TODO(sra): What is the type of the prototype of an interceptor?
+    if (constant.isInterceptor()) return HType.UNKNOWN;
     // TODO(kasperl): This seems a bit fishy, but we do not have the
     // compiler at hand so we cannot use the usual HType factory
     // methods. At some point this should go away.
+    ObjectConstant objectConstant = constant;
     TypeMask mask = new TypeMask.nonNullExact(objectConstant.type);
     return new HBoundedType(mask);
   }
@@ -882,7 +886,6 @@
   bool isNumber() => instructionType.isNumber();
   bool isNumberOrNull() => instructionType.isNumberOrNull();
   bool isString() => instructionType.isString();
-  bool isTypeUnknown() => instructionType.isUnknown();
   bool isIndexablePrimitive() => instructionType.isIndexablePrimitive();
   bool isPrimitive() => instructionType.isPrimitive();
   bool canBeNull() => instructionType.canBeNull();
@@ -1109,23 +1112,19 @@
     return false;
   }
 
-
   HInstruction convertType(Compiler compiler, DartType type, int kind) {
     if (type == null) return this;
     if (identical(type.element, compiler.dynamicClass)) return this;
     if (identical(type.element, compiler.objectClass)) return this;
-
-    // If the original can't be null, type conversion also can't produce null.
-    bool canBeNull = instructionType.canBeNull();
-    HType convertedType = new HType.subtype(type, compiler);
-
-    // No need to convert if we know the instruction has
-    // [convertedType] as a bound.
-    if (instructionType == convertedType) {
-      return this;
+    if (type.isMalformed || type.kind != TypeKind.INTERFACE) {
+      return new HTypeConversion(type, kind, HType.UNKNOWN, this);
+    } else if (kind == HTypeConversion.BOOLEAN_CONVERSION_CHECK) {
+      // Boolean conversion checks work on non-nullable booleans.
+      return new HTypeConversion(type, kind, HType.BOOLEAN, this);
+    } else {
+      HType subtype = new HType.subtype(type, compiler);
+      return new HTypeConversion(type, kind, subtype, this);
     }
-
-    return new HTypeConversion(convertedType, this, kind);
   }
 
     /**
@@ -1460,8 +1459,7 @@
     }
   }
 
-  // TODO(ngeoffray): Only if input can be null.
-  bool canThrow() => true;
+  bool canThrow() => receiver.canBeNull();
 
   accept(HVisitor visitor) => visitor.visitFieldGet(this);
 
@@ -1480,8 +1478,7 @@
     setChangesInstanceProperty();
   }
 
-  // TODO(ngeoffray): Only if input can be null.
-  bool canThrow() => true;
+  bool canThrow() => receiver.canBeNull();
 
   HInstruction get value => inputs[1];
   accept(HVisitor visitor) => visitor.visitFieldSet(this);
@@ -1515,14 +1512,18 @@
 class HForeign extends HInstruction {
   final DartString code;
   final bool isStatement;
+  final bool isSideEffectFree;
 
   HForeign(this.code,
            HType type,
            List<HInstruction> inputs,
-           {this.isStatement: false})
+           {this.isStatement: false,
+            this.isSideEffectFree: false})
       : super(inputs) {
-    setAllSideEffects();
-    setDependsOnSomething();
+    if (!isSideEffectFree) {
+      setAllSideEffects();
+      setDependsOnSomething();
+    }
     instructionType = type;
   }
 
@@ -1532,7 +1533,7 @@
   accept(HVisitor visitor) => visitor.visitForeign(this);
 
   bool isJsStatement() => isStatement;
-  bool canThrow() => true;
+  bool canThrow() => !isSideEffectFree;
 }
 
 class HForeignNew extends HForeign {
@@ -2152,34 +2153,54 @@
   HInstruction get value => inputs[2];
 }
 
+// TODO(karlklose): use this class to represent type conversions as well.
 class HIs extends HInstruction {
+  /// A check against a raw type: 'o is int', 'o is A'.
+  static const int RAW_CHECK = 0;
+  /// A check against a type with type arguments: 'o is List<int>', 'o is C<T>'.
+  static const int COMPOUND_CHECK = 1;
+  /// A check against a single type variable: 'o is T'.
+  static const int VARIABLE_CHECK = 2;
+
   final DartType typeExpression;
   final bool nullOk;
+  final int kind;
 
-  HIs(this.typeExpression, List<HInstruction> inputs, {this.nullOk: false})
-     : super(inputs) {
+  HIs(this.typeExpression, List<HInstruction> inputs, this.kind,
+      {this.nullOk: false}) : super(inputs) {
+    assert(kind >= RAW_CHECK && kind <= VARIABLE_CHECK);
     setUseGvn();
     instructionType = HType.BOOLEAN;
   }
 
   HInstruction get expression => inputs[0];
-  HInstruction get checkCall => inputs[1];
 
-  bool hasArgumentsCheck() => inputs.length > 1;
+  HInstruction get checkCall {
+    assert(kind == VARIABLE_CHECK || kind == COMPOUND_CHECK);
+    return inputs[1];
+  }
+
+  bool get isRawCheck => kind == RAW_CHECK;
+  bool get isVariableCheck => kind == VARIABLE_CHECK;
+  bool get isCompoundCheck => kind == COMPOUND_CHECK;
 
   accept(HVisitor visitor) => visitor.visitIs(this);
 
   toString() => "$expression is $typeExpression";
 
   int typeCode() => HInstruction.IS_TYPECODE;
+
   bool typeEquals(HInstruction other) => other is HIs;
+
   bool dataEquals(HIs other) {
     return typeExpression == other.typeExpression
-        && nullOk == other.nullOk;
+        && nullOk == other.nullOk
+        && kind == other.kind;
   }
 }
 
 class HTypeConversion extends HCheck {
+  final DartType typeExpression;
   final int kind;
 
   static const int NO_CHECK = 0;
@@ -2188,23 +2209,17 @@
   static const int CAST_TYPE_CHECK = 3;
   static const int BOOLEAN_CONVERSION_CHECK = 4;
 
-  HTypeConversion(HType type, HInstruction input, [this.kind = NO_CHECK])
+  HTypeConversion(this.typeExpression, this.kind,
+                  HType type, HInstruction input)
       : super(<HInstruction>[input]) {
-    assert(type != null);
     sourceElement = input.sourceElement;
     instructionType = type;
   }
-  HTypeConversion.checkedModeCheck(HType type, HInstruction input)
-      : this(type, input, CHECKED_MODE_CHECK);
-  HTypeConversion.argumentTypeCheck(HType type, HInstruction input)
-      : this(type, input, ARGUMENT_TYPE_CHECK);
-  HTypeConversion.castCheck(HType type, HInstruction input)
-      : this(type, input, CAST_TYPE_CHECK);
-
 
   bool get isChecked => kind != NO_CHECK;
   bool get isCheckedModeCheck {
-    return kind == CHECKED_MODE_CHECK || kind == BOOLEAN_CONVERSION_CHECK;
+    return kind == CHECKED_MODE_CHECK
+        || kind == BOOLEAN_CONVERSION_CHECK;
   }
   bool get isArgumentTypeCheck => kind == ARGUMENT_TYPE_CHECK;
   bool get isCastTypeCheck => kind == CAST_TYPE_CHECK;
@@ -2218,8 +2233,11 @@
 
   int typeCode() => HInstruction.TYPE_CONVERSION_TYPECODE;
   bool typeEquals(HInstruction other) => other is HTypeConversion;
+
   bool dataEquals(HTypeConversion other) {
-    return instructionType == other.instructionType && kind == other.kind;
+    return kind == other.kind
+        && typeExpression == other.typeExpression
+        && instructionType == other.instructionType;
   }
 }
 
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
index 7a41583..08f565a 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
@@ -183,8 +183,12 @@
     HInstruction input = inputs[0];
     HType type = input.instructionType;
     if (type.isBoolean()) return input;
-    // All values !== true are boolified to false.
-    if (!type.isBooleanOrNull() && !type.isUnknown()) {
+    // All values that cannot be 'true' are boolified to false.
+    DartType booleanType = backend.jsBoolClass.computeType(compiler);
+    TypeMask mask = type.computeMask(compiler);
+    // TODO(kasperl): Get rid of the null check here once all HTypes
+    // have a proper mask.
+    if (mask != null && !mask.contains(booleanType, compiler)) {
       return graph.addConstantBool(false, constantSystem);
     }
     return node;
@@ -306,7 +310,7 @@
         // bounds check will become explicit, so we won't need this
         // optimization.
         HInvokeDynamicMethod result = new HInvokeDynamicMethod(
-            node.selector, node.inputs.getRange(1, node.inputs.length - 1));
+            node.selector, node.inputs.sublist(1));
         result.element = target;
         return result;
       }
@@ -322,8 +326,8 @@
     if (node is !HOneShotInterceptor
         && interceptor.isConstant()
         && selector.isCall()) {
-      DartType type = interceptor.instructionType.computeType(compiler);
-      ClassElement cls = type.element;
+      assert(interceptor.constant.isInterceptor());
+      ClassElement cls = interceptor.constant.dispatchedType.element;
       Element target = cls.lookupSelector(selector);
       if (target != null && selector.applies(target, compiler)) {
         node.element = target;
@@ -332,30 +336,6 @@
     return node;
   }
 
-  bool isFixedSizeListConstructor(HInvokeStatic node) {
-    Element element = node.target.element;
-    if (backend.fixedLengthListConstructor == null) {
-      backend.fixedLengthListConstructor =
-        compiler.listClass.lookupConstructor(
-            new Selector.callConstructor(const SourceString(""),
-                                         compiler.listClass.getLibrary()));
-    }
-    // TODO(ngeoffray): checking if the second input is an integer
-    // should not be necessary but it currently makes it easier for
-    // other optimizations to reason on a fixed length constructor
-    // that we know takes an int.
-    return element == backend.fixedLengthListConstructor
-        && node.inputs.length == 2
-        && node.inputs[1].isInteger();
-  }
-
-  HInstruction visitInvokeStatic(HInvokeStatic node) {
-    if (isFixedSizeListConstructor(node)) {
-      node.instructionType = HType.FIXED_ARRAY;
-    }
-    return node;
-  }
-
   HInstruction visitInvokeDynamicMethod(HInvokeDynamicMethod node) {
     if (node.isCallOnInterceptor) return handleInterceptorCall(node);
     HType receiverType = node.receiver.instructionType;
@@ -435,7 +415,8 @@
     HType leftType = left.instructionType;
     HType rightType = right.instructionType;
 
-    // We don't optimize on numbers to preserve the runtime semantics.
+    // Intersection of int and double return conflicting, so
+    // we don't optimize on numbers to preserve the runtime semantics.
     if (!(left.isNumberOrNull() && right.isNumberOrNull()) &&
         leftType.intersection(rightType, compiler).isConflicting()) {
       return graph.addConstantBool(false, constantSystem);
@@ -480,9 +461,10 @@
   HInstruction visitIs(HIs node) {
     DartType type = node.typeExpression;
     Element element = type.element;
-    if (element.isTypeVariable()) {
-      compiler.unimplemented("visitIs for type variables");
-    } if (element.isTypedef()) {
+
+    if (!node.isRawCheck) {
+      return node;
+    } else if (element.isTypedef()) {
       return node;
     }
 
@@ -536,15 +518,18 @@
       } else {
         return graph.addConstantBool(false, constantSystem);
       }
-    // TODO(karlklose): remove the hasTypeArguments check.
+    // Wee need the [:hasTypeArguments:] check because we don't have
+    // the notion of generics in the backend. For example, [:this:] in
+    // a class [:A<T>:], is currently always considered to have the
+    // raw type.
     } else if (expressionType.isUseful()
                && !expressionType.canBeNull()
-               && !RuntimeTypeInformation.hasTypeArguments(type)) {
-      DartType receiverType = expressionType.computeType(compiler);
+               && !RuntimeTypes.hasTypeArguments(type)) {
+      var receiverType = expressionType.computeType(compiler);
       if (receiverType != null) {
         if (!receiverType.isMalformed &&
             !type.isMalformed &&
-            compiler.types.isSubtype(receiverType, type)) {
+            compiler.types.isSubtype(receiverType.element.rawType, type)) {
           return graph.addConstantBool(true, constantSystem);
         } else if (expressionType.isExact()) {
           return graph.addConstantBool(false, constantSystem);
@@ -556,16 +541,12 @@
 
   HInstruction visitTypeConversion(HTypeConversion node) {
     HInstruction value = node.inputs[0];
-    DartType type = node.instructionType.computeType(compiler);
-    if (identical(type.element, compiler.dynamicClass)
-        || identical(type.element, compiler.objectClass)) {
-      return value;
-    }
-    if (value.instructionType.canBeNull() && node.isBooleanConversionCheck) {
-      return node;
-    }
-    HType combinedType =
-        value.instructionType.intersection(node.instructionType, compiler);
+    DartType type = node.typeExpression;
+    if (type != null && !type.isRaw) return node;
+    HType convertedType = node.instructionType;
+    if (convertedType.isUnknown()) return node;
+    HType combinedType = value.instructionType.intersection(
+        convertedType, compiler);
     return (combinedType == value.instructionType) ? value : node;
   }
 
@@ -582,7 +563,14 @@
         // Try to recognize the length getter with input
         // [:new List(int):].
         HInvokeStatic call = node.receiver;
-        if (isFixedSizeListConstructor(call)) {
+        Element element = call.target.element;
+        // TODO(ngeoffray): checking if the second input is an integer
+        // should not be necessary but it currently makes it easier for
+        // other optimizations to reason about a fixed length constructor
+        // that we know takes an int.
+        if (element == compiler.unnamedListConstructor
+            && call.inputs.length == 2
+            && call.inputs[1].isInteger()) {
           return call.inputs[1];
         }
       }
@@ -598,28 +586,27 @@
     if (field == null) return node;
 
     Modifiers modifiers = field.modifiers;
-    bool isFinalOrConst = modifiers.isFinal() || modifiers.isConst();
+    bool isAssignable = !(modifiers.isFinal() || modifiers.isConst());
     if (!compiler.resolverWorld.hasInvokedSetter(field, compiler)) {
       // If no setter is ever used for this field it is only initialized in the
       // initializer list.
-      isFinalOrConst = true;
+      isAssignable = false;
+    }
+    if (field.isNative()) {
+      // Some native fields are views of data that may be changed by operations.
+      // E.g. node.firstChild depends on parentNode.removeBefore(n1, n2).
+      // TODO(sra): Refine the effect classification so that native effects are
+      // distinct from ordinary Dart effects.
+      isAssignable = true;
     }
     HFieldGet result = new HFieldGet(
-        field, node.inputs[0], isAssignable: !isFinalOrConst);
-
-    // Some native fields are views of data that may be changed by operations.
-    // E.g. node.firstChild depends on parentNode.removeBefore(n1, n2).
-    // TODO(sra): Refine the effect classification so that native effects are
-    // distinct from ordinary Dart effects.
-    if (field.isNative()) {
-      result.setDependsOnSomething();
-    }
+        field, node.inputs[0], isAssignable: isAssignable);
 
     if (field.getEnclosingClass().isNative()) {
       result.instructionType =
           new HType.subtype(field.computeType(compiler), compiler);
     } else {
-      HType type = new HType.inferredForElement(field, compiler);
+      HType type = new HType.inferredTypeForElement(field, compiler);
       if (type.isUnknown()) {
         type = backend.optimisticFieldType(field);
         if (type != null) {
@@ -676,11 +663,8 @@
     // return the object (the [:getInterceptor:] method would have
     // returned the object).
     HType type = node.receiver.instructionType;
-    if (!type.canBePrimitive(compiler)) {
-      if (!(type.canBeNull()
-            && node.interceptedClasses.contains(compiler.objectClass))) {
-        return node.receiver;
-      }
+    if (canUseSelfForInterceptor(type, node.interceptedClasses)) {
+      return node.receiver;
     }
     HInstruction constant = tryComputeConstantInterceptor(
         node.inputs[0], node.interceptedClasses);
@@ -689,6 +673,29 @@
     return constant;
   }
 
+  bool canUseSelfForInterceptor(HType receiverType,
+                                Set<ClassElement> interceptedClasses) {
+    if (receiverType.canBePrimitive(compiler)) {
+      // Primitives always need interceptors.
+      return false;
+    }
+    if (receiverType.canBeNull()
+        && interceptedClasses.contains(backend.jsNullClass)) {
+      // Need the JSNull interceptor.
+      return false;
+    }
+
+    // [interceptedClasses] is sparse - it is just the classes that define some
+    // intercepted method.  Their subclasses (that inherit the method) are
+    // implicit, so we have to extend them.
+
+    TypeMask receiverMask = receiverType.computeMask(compiler);
+    return interceptedClasses
+        .where((cls) => cls != compiler.objectClass)
+        .map((cls) => new TypeMask.subclass(cls.rawType))
+        .every((mask) => receiverMask.intersection(mask, compiler).isEmpty);
+  }
+
   HInstruction tryComputeConstantInterceptor(HInstruction input,
                                              Set<ClassElement> intercepted) {
     HType type = input.instructionType;
@@ -706,10 +713,11 @@
     } else if (type.isNull()) {
       constantInterceptor = backend.jsNullClass;
     } else if (type.isNumber()) {
-      // If the method being intercepted is not defined in [int] or
-      // [double] we can safely use the number interceptor.
-      if (!intercepted.contains(compiler.intClass)
-          && !intercepted.contains(compiler.doubleClass)) {
+      // If the method being intercepted is not defined in [int] or [double] we
+      // can safely use the number interceptor.  This is because none of the
+      // [int] or [double] methods are called from a method defined on [num].
+      if (!intercepted.contains(backend.jsIntClass)
+          && !intercepted.contains(backend.jsDoubleClass)) {
         constantInterceptor = backend.jsNumberClass;
       }
     }
@@ -719,8 +727,8 @@
       return graph.thisInstruction;
     }
 
-    Constant constant = new ConstructedConstant(
-        constantInterceptor.computeType(compiler), <Constant>[]);
+    Constant constant = new InterceptorConstant(
+        constantInterceptor.computeType(compiler));
     return graph.addConstant(constant);
   }
 
@@ -1266,7 +1274,8 @@
     Set<HInstruction> dominatedUsers = input.dominatedUsers(dominator.first);
     if (dominatedUsers.isEmpty) return;
 
-    HTypeConversion newInput = new HTypeConversion(convertedType, input);
+    HTypeConversion newInput = new HTypeConversion(
+        null, HTypeConversion.NO_CHECK, convertedType, input);
     dominator.addBefore(dominator.first, newInput);
     dominatedUsers.forEach((HInstruction user) {
       user.changeUse(input, newInput);
@@ -1274,13 +1283,16 @@
   }
 
   void visitIs(HIs instruction) {
-    HInstruction input = instruction.expression;
-    HType convertedType = new HType.nonNullSubtype(
-        instruction.typeExpression, compiler);
+    DartType type = instruction.typeExpression;
+    Element element = type.element;
+    if (!instruction.isRawCheck) {
+      return;
+    } else if (element.isTypedef()) {
+      return;
+    }
 
     List<HInstruction> ifUsers = <HInstruction>[];
     List<HInstruction> notIfUsers = <HInstruction>[];
-
     for (HInstruction user in instruction.usedBy) {
       if (user is HIf) {
         ifUsers.add(user);
@@ -1293,6 +1305,8 @@
 
     if (ifUsers.isEmpty && notIfUsers.isEmpty) return;
 
+    HType convertedType = new HType.nonNullSubtype(type, compiler);
+    HInstruction input = instruction.expression;
     for (HIf ifUser in ifUsers) {
       changeUsesDominatedBy(ifUser.thenBlock, input, convertedType);
       // TODO(ngeoffray): Also change uses for the else block on a HType
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart b/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
index fd4884c..b2d7a07 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
@@ -348,8 +348,7 @@
     String name = invoke.selector.name.slowToString();
     String target = "($kind) $receiver.$name";
     int offset = HInvoke.ARGUMENTS_OFFSET;
-    List arguments =
-        invoke.inputs.getRange(offset, invoke.inputs.length - offset);
+    List arguments = invoke.inputs.sublist(offset);
     return visitGenericInvoke("Invoke", target, arguments);
   }
 
@@ -363,16 +362,14 @@
   String visitInvokeStatic(HInvokeStatic invoke) {
     String target = temporaryId(invoke.target);
     int offset = HInvoke.ARGUMENTS_OFFSET;
-    List arguments =
-        invoke.inputs.getRange(offset, invoke.inputs.length - offset);
+    List arguments = invoke.inputs.sublist(offset);
     return visitGenericInvoke("Invoke", target, arguments);
   }
 
   String visitInvokeSuper(HInvokeSuper invoke) {
     String target = temporaryId(invoke.target);
     int offset = HInvoke.ARGUMENTS_OFFSET + 1;
-    List arguments =
-        invoke.inputs.getRange(offset, invoke.inputs.length - offset);
+    List arguments = invoke.inputs.sublist(offset);
     return visitGenericInvoke("Invoke super", target, arguments);
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types.dart b/sdk/lib/_internal/compiler/implementation/ssa/types.dart
index 0c0ad12..62e632d 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/types.dart
@@ -13,15 +13,12 @@
    * primitive type.
    */
   factory HType.fromMask(TypeMask mask, Compiler compiler) {
-    Element element = mask.base.element;
-    if (element.kind == ElementKind.TYPE_VARIABLE) {
-      // TODO(ngeoffray): Can we do better here?
-      DartType base = compiler.objectClass.computeType(compiler);
-      mask = new TypeMask.internal(base, mask.flags);
-      return new HBoundedType(mask);
+    bool isNullable = mask.isNullable;
+    if (mask.isEmpty) {
+      return isNullable ? HType.NULL : HType.CONFLICTING;
     }
 
-    bool isNullable = mask.isNullable;
+    Element element = mask.base.element;
     JavaScriptBackend backend = compiler.backend;
     if (element == compiler.intClass || element == backend.jsIntClass) {
       return isNullable ? HType.INTEGER_OR_NULL : HType.INTEGER;
@@ -37,13 +34,26 @@
     } else if (element == compiler.boolClass
                || element == backend.jsBoolClass) {
       return isNullable ? HType.BOOLEAN_OR_NULL : HType.BOOLEAN;
-    } else if (element == compiler.nullClass
-               || element == backend.jsNullClass) {
-      return HType.NULL;
-    } else if (element == backend.jsArrayClass) {
-      return isNullable
-          ? HType.READABLE_ARRAY.union(HType.NULL, compiler)
-          : HType.READABLE_ARRAY;
+    }
+
+    // TODO(kasperl): A lot of the code in the system currently
+    // expects the top type to be 'unknown'. I'll rework this.
+    if (element == compiler.objectClass || element == compiler.dynamicClass) {
+      return isNullable ? HType.UNKNOWN : HType.NON_NULL;
+    }
+
+    if (!isNullable) {
+      if (element == backend.jsIndexableClass) {
+        return HType.INDEXABLE_PRIMITIVE;
+      } else if (element == backend.jsArrayClass) {
+        return HType.READABLE_ARRAY;
+      } else if (element == backend.jsMutableArrayClass) {
+        return HType.MUTABLE_ARRAY;
+      } else if (element == backend.jsFixedArrayClass) {
+        return HType.FIXED_ARRAY;
+      } else if (element == backend.jsExtendableArrayClass) {
+        return HType.EXTENDABLE_ARRAY;
+      }
     }
     return new HBoundedType(mask);
   }
@@ -78,44 +88,31 @@
     return new HType.fromMask(mask, compiler);
   }
 
-  factory HType.fromBaseType(BaseType baseType, Compiler compiler) {
-    if (!baseType.isClass()) return HType.UNKNOWN;
-    ClassBaseType classBaseType = baseType;
-    ClassElement cls = classBaseType.element;
-    // Special case the list and map classes that are used as types
-    // for literals in the type inferrer.
-    if (cls == compiler.listClass) {
-      return HType.READABLE_ARRAY;
-    } else if (cls == compiler.mapClass) {
-      // TODO(ngeoffray): get the actual implementation of a map
-      // literal.
-      return new HType.nonNullSubtype(
-          compiler.mapLiteralClass.computeType(compiler), compiler);
-    } else {
-      return new HType.nonNullExact(
-          cls.computeType(compiler), compiler);
-    }
+  factory HType.fromInferredType(TypeMask mask, Compiler compiler) {
+    if (mask == null) return HType.UNKNOWN;
+    return new HType.fromMask(mask, compiler);
   }
 
-  factory HType.fromInferredType(ConcreteType concreteType, Compiler compiler) {
-    if (concreteType == null) return HType.UNKNOWN;
-    HType ssaType = HType.CONFLICTING;
-    for (BaseType baseType in concreteType.baseTypes) {
-      ssaType = ssaType.union(
-          new HType.fromBaseType(baseType, compiler), compiler);
-    }
-    if (ssaType.isConflicting()) return HType.UNKNOWN;
-    return ssaType;
+  factory HType.inferredReturnTypeForElement(
+      Element element, Compiler compiler) {
+    return new HType.fromInferredType(
+        compiler.typesTask.getGuaranteedReturnTypeOfElement(element),
+        compiler);
   }
 
-  factory HType.inferredForElement(Element element, Compiler compiler) {
+  factory HType.inferredTypeForElement(Element element, Compiler compiler) {
     return new HType.fromInferredType(
         compiler.typesTask.getGuaranteedTypeOfElement(element),
         compiler);
   }
 
-  factory HType.inferredForNode(
-      Element owner, Node node, Compiler compiler) {
+  factory HType.inferredTypeForSelector(Selector selector, Compiler compiler) {
+    return new HType.fromInferredType(
+        compiler.typesTask.getGuaranteedTypeOfSelector(selector),
+        compiler);
+  }
+
+  factory HType.inferredForNode(Element owner, Node node, Compiler compiler) {
     return new HType.fromInferredType(
         compiler.typesTask.getGuaranteedTypeOfNode(owner, node),
         compiler);
@@ -129,6 +126,8 @@
           compiler.objectClass.computeType(compiler), compiler);
     } else if (type == native.SpecialType.JsArray) {
       return HType.READABLE_ARRAY;
+    } else if (type.element == compiler.nullClass) {
+      return HType.NULL;
     } else {
       return new HType.nonNullSubclass(type, compiler);
     }
@@ -147,28 +146,9 @@
     return ssaType;
   }
 
-  factory HType.readableArrayOrNull(Compiler compiler) {
-    return new HBoundedType(
-        READABLE_ARRAY.computeMask(compiler).nullable());
-  }
-
-  factory HType.mutableArrayOrNull(Compiler compiler) {
-    return new HBoundedType(
-        MUTABLE_ARRAY.computeMask(compiler).nullable());
-  }
-
-  factory HType.fixedArrayOrNull(Compiler compiler) {
-    return new HBoundedType(
-        FIXED_ARRAY.computeMask(compiler).nullable());
-  }
-
-  factory HType.extendableArrayOrNull(Compiler compiler) {
-    return new HBoundedType(
-        EXTENDABLE_ARRAY.computeMask(compiler).nullable());
-  }
-
   static const HType CONFLICTING = const HConflictingType();
   static const HType UNKNOWN = const HUnknownType();
+  static const HType NON_NULL = const HNonNullType();
   static const HType BOOLEAN = const HBooleanType();
   static const HType NUMBER = const HNumberType();
   static const HType INTEGER = const HIntegerType();
@@ -224,16 +204,14 @@
   TypeMask computeMask(Compiler compiler);
 
   Selector refine(Selector selector, Compiler compiler) {
-    TypeMask mask = computeMask(compiler);
     // TODO(kasperl): Should we check if the refinement really is more
     // specialized than the starting point?
-    if (mask == null || mask.base.isMalformed) return selector;
+    TypeMask mask = computeMask(compiler);
     return new TypedSelector(mask, selector);
   }
 
   // TODO(kasperl): Try to get rid of these.
   DartType computeType(Compiler compiler);
-  bool isTop(Compiler compiler) => false;
 
   /**
    * The intersection of two types is the intersection of its values. For
@@ -248,7 +226,12 @@
    * An intersection with [UNKNOWN] returns the non-UNKNOWN type. An
    * intersection with [CONFLICTING] returns [CONFLICTING].
    */
-  HType intersection(HType other, Compiler compiler);
+  HType intersection(HType other, Compiler compiler) {
+    TypeMask mask = computeMask(compiler);
+    TypeMask otherMask = other.computeMask(compiler);
+    TypeMask intersection = mask.intersection(otherMask, compiler);
+    return new HType.fromMask(intersection, compiler);
+  }
 
   /**
    * The union of two types is the union of its values. For example:
@@ -262,7 +245,12 @@
    * A union with [UNKNOWN] returns [UNKNOWN].
    * A union of [CONFLICTING] with any other types returns the other type.
    */
-  HType union(HType other, Compiler compiler);
+  HType union(HType other, Compiler compiler) {
+    TypeMask mask = computeMask(compiler);
+    TypeMask otherMask = other.computeMask(compiler);
+    TypeMask union = mask.union(otherMask, compiler);
+    return new HType.fromMask(union, compiler);
+  }
 }
 
 /** Used to represent [HType.UNKNOWN] and [HType.CONFLICTING]. */
@@ -270,27 +258,52 @@
   final String name;
   const HAnalysisType(this.name);
   String toString() => name;
-
-  DartType computeType(Compiler compiler) => null;
-  TypeMask computeMask(Compiler compiler) => null;
 }
 
 class HUnknownType extends HAnalysisType {
   const HUnknownType() : super("unknown");
   bool canBePrimitive(Compiler compiler) => true;
   bool canBeNull() => true;
+  bool canBePrimitiveNumber(Compiler compiler) => true;
+  bool canBePrimitiveString(Compiler compiler) => true;
+  bool canBePrimitiveArray(Compiler compiler) => true;
 
-  HType union(HType other, Compiler compiler) => this;
-  HType intersection(HType other, Compiler compiler) => other;
+  DartType computeType(Compiler compiler) {
+    return compiler.objectClass.computeType(compiler);
+  }
+
+  TypeMask computeMask(Compiler compiler) {
+    return new TypeMask.subclass(computeType(compiler));
+  }
+}
+
+class HNonNullType extends HAnalysisType {
+  const HNonNullType() : super("non-null");
+  bool canBePrimitive(Compiler compiler) => true;
+  bool canBeNull() => false;
+  bool canBePrimitiveNumber(Compiler compiler) => true;
+  bool canBePrimitiveString(Compiler compiler) => true;
+  bool canBePrimitiveArray(Compiler compiler) => true;
+
+  DartType computeType(Compiler compiler) {
+    return compiler.objectClass.computeType(compiler);
+  }
+
+  TypeMask computeMask(Compiler compiler) {
+    return new TypeMask.nonNullSubclass(computeType(compiler));
+  }
 }
 
 class HConflictingType extends HAnalysisType {
   const HConflictingType() : super("conflicting");
   bool canBePrimitive(Compiler compiler) => true;
-  bool canBeNull() => true;
+  bool canBeNull() => false;
 
-  HType union(HType other, Compiler compiler) => other;
-  HType intersection(HType other, Compiler compiler) => this;
+  DartType computeType(Compiler compiler) => null;
+
+  TypeMask computeMask(Compiler compiler) {
+    return new TypeMask.nonNullEmpty();
+  }
 }
 
 abstract class HPrimitiveType extends HType {
@@ -298,7 +311,6 @@
   bool isPrimitive() => true;
   bool canBePrimitive(Compiler compiler) => true;
   bool isPrimitiveOrNull() => true;
-  bool isExact() => true;
 }
 
 class HNullType extends HPrimitiveType {
@@ -306,6 +318,7 @@
   bool canBeNull() => true;
   bool isNull() => true;
   String toString() => 'null type';
+  bool isExact() => true;
 
   DartType computeType(Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
@@ -313,28 +326,7 @@
   }
 
   TypeMask computeMask(Compiler compiler) {
-    return new TypeMask.exact(computeType(compiler));
-  }
-
-  HType union(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.NULL;
-    if (other.isUnknown()) return HType.UNKNOWN;
-    if (other.isString()) return HType.STRING_OR_NULL;
-    if (other.isInteger()) return HType.INTEGER_OR_NULL;
-    if (other.isDouble()) return HType.DOUBLE_OR_NULL;
-    if (other.isNumber()) return HType.NUMBER_OR_NULL;
-    if (other.isBoolean()) return HType.BOOLEAN_OR_NULL;
-    // TODO(ngeoffray): Deal with the type of null more generally.
-    if (other.isReadableArray()) return other.union(this, compiler);
-    if (!other.canBeNull()) return HType.UNKNOWN;
-    return other;
-  }
-
-  HType intersection(HType other, Compiler compiler) {
-    if (other.isUnknown()) return HType.NULL;
-    if (other.isConflicting()) return HType.CONFLICTING;
-    if (!other.canBeNull()) return HType.CONFLICTING;
-    return HType.NULL;
+    return new TypeMask.empty();
   }
 }
 
@@ -358,27 +350,6 @@
   TypeMask computeMask(Compiler compiler) {
     return new TypeMask.exact(computeType(compiler));
   }
-
-  HType union(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.BOOLEAN_OR_NULL;
-    if (other.isUnknown()) return HType.UNKNOWN;
-    if (other.isBooleanOrNull()) return HType.BOOLEAN_OR_NULL;
-    if (other.isBoolean()) return HType.BOOLEAN_OR_NULL;
-    if (other.isNull()) return HType.BOOLEAN_OR_NULL;
-    return HType.UNKNOWN;
-  }
-
-  HType intersection(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.CONFLICTING;
-    if (other.isUnknown()) return HType.BOOLEAN_OR_NULL;
-    if (other.isBoolean()) return HType.BOOLEAN;
-    if (other.isBooleanOrNull()) return HType.BOOLEAN_OR_NULL;
-    if (other.isTop(compiler)) {
-      return other.canBeNull() ? this : HType.BOOLEAN;
-    }
-    if (other.canBeNull()) return HType.NULL;
-    return HType.CONFLICTING;
-  }
 }
 
 class HBooleanType extends HPrimitiveType {
@@ -386,6 +357,7 @@
   bool isBoolean() => true;
   bool isBooleanOrNull() => true;
   String toString() => "boolean";
+  bool isExact() => true;
 
   DartType computeType(Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
@@ -395,30 +367,13 @@
   TypeMask computeMask(Compiler compiler) {
     return new TypeMask.nonNullExact(computeType(compiler));
   }
-
-  HType union(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.BOOLEAN;
-    if (other.isUnknown()) return HType.UNKNOWN;
-    if (other.isBoolean()) return HType.BOOLEAN;
-    if (other.isBooleanOrNull()) return HType.BOOLEAN_OR_NULL;
-    if (other.isNull()) return HType.BOOLEAN_OR_NULL;
-    return HType.UNKNOWN;
-  }
-
-  HType intersection(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.CONFLICTING;
-    if (other.isUnknown()) return HType.BOOLEAN;
-    if (other.isBooleanOrNull()) return HType.BOOLEAN;
-    if (other.isBoolean()) return HType.BOOLEAN;
-    return HType.CONFLICTING;
-  }
 }
 
 class HNumberOrNullType extends HPrimitiveOrNullType {
   const HNumberOrNullType();
   bool isNumberOrNull() => true;
   String toString() => "number or null";
-  bool isExact() => false;
+  bool canBePrimitiveNumber(Compiler compiler) => true;
 
   DartType computeType(Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
@@ -428,31 +383,6 @@
   TypeMask computeMask(Compiler compiler) {
     return new TypeMask.subclass(computeType(compiler));
   }
-
-  HType union(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.NUMBER_OR_NULL;
-    if (other.isUnknown()) return HType.UNKNOWN;
-    if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL;
-    if (other.isNumber()) return HType.NUMBER_OR_NULL;
-    if (other.isNull()) return HType.NUMBER_OR_NULL;
-    return HType.UNKNOWN;
-  }
-
-  HType intersection(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.CONFLICTING;
-    if (other.isUnknown()) return HType.NUMBER_OR_NULL;
-    if (other.isInteger()) return HType.INTEGER;
-    if (other.isDouble()) return HType.DOUBLE;
-    if (other.isNumber()) return HType.NUMBER;
-    if (other.isIntegerOrNull()) return HType.INTEGER_OR_NULL;
-    if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL;
-    if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL;
-    if (other.isTop(compiler)) {
-      return other.canBeNull() ? this : HType.NUMBER;
-    }
-    if (other.canBeNull()) return HType.NULL;
-    return HType.CONFLICTING;
-  }
 }
 
 class HNumberType extends HPrimitiveType {
@@ -460,7 +390,7 @@
   bool isNumber() => true;
   bool isNumberOrNull() => true;
   String toString() => "number";
-  bool isExact() => false;
+  bool canBePrimitiveNumber(Compiler compiler) => true;
 
   DartType computeType(Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
@@ -470,25 +400,6 @@
   TypeMask computeMask(Compiler compiler) {
     return new TypeMask.nonNullSubclass(computeType(compiler));
   }
-
-  HType union(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.NUMBER;
-    if (other.isUnknown()) return HType.UNKNOWN;
-    if (other.isNumber()) return HType.NUMBER;
-    if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL;
-    if (other.isNull()) return HType.NUMBER_OR_NULL;
-    return HType.UNKNOWN;
-  }
-
-  HType intersection(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.CONFLICTING;
-    if (other.isUnknown()) return HType.NUMBER;
-    if (other.isNumber()) return other;
-    if (other.isIntegerOrNull()) return HType.INTEGER;
-    if (other.isDoubleOrNull()) return HType.DOUBLE;
-    if (other.isNumberOrNull()) return HType.NUMBER;
-    return HType.CONFLICTING;
-  }
 }
 
 class HIntegerOrNullType extends HNumberOrNullType {
@@ -504,33 +415,6 @@
   TypeMask computeMask(Compiler compiler) {
     return new TypeMask.exact(computeType(compiler));
   }
-
-  HType union(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.INTEGER_OR_NULL;
-    if (other.isUnknown()) return HType.UNKNOWN;
-    if (other.isIntegerOrNull()) return HType.INTEGER_OR_NULL;
-    if (other.isInteger()) return HType.INTEGER_OR_NULL;
-    if (other.isNumber()) return HType.NUMBER_OR_NULL;
-    if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL;
-    if (other.isNull()) return HType.INTEGER_OR_NULL;
-    return HType.UNKNOWN;
-  }
-
-  HType intersection(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.CONFLICTING;
-    if (other.isUnknown()) return HType.INTEGER_OR_NULL;
-    if (other.isInteger()) return HType.INTEGER;
-    if (other.isIntegerOrNull()) return HType.INTEGER_OR_NULL;
-    if (other.isDouble()) return HType.CONFLICTING;
-    if (other.isDoubleOrNull()) return HType.NULL;
-    if (other.isNumber()) return HType.INTEGER;
-    if (other.isNumberOrNull()) return HType.INTEGER_OR_NULL;
-    if (other.isTop(compiler)) {
-      return other.canBeNull() ? this : HType.INTEGER;
-    }
-    if (other.canBeNull()) return HType.NULL;
-    return HType.CONFLICTING;
-  }
 }
 
 class HIntegerType extends HNumberType {
@@ -538,6 +422,7 @@
   bool isInteger() => true;
   bool isIntegerOrNull() => true;
   String toString() => "integer";
+  bool isExact() => true;
 
   DartType computeType(Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
@@ -547,29 +432,6 @@
   TypeMask computeMask(Compiler compiler) {
     return new TypeMask.nonNullExact(computeType(compiler));
   }
-
-  HType union(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.INTEGER;
-    if (other.isUnknown()) return HType.UNKNOWN;
-    if (other.isInteger()) return HType.INTEGER;
-    if (other.isIntegerOrNull()) return HType.INTEGER_OR_NULL;
-    if (other.isNumber()) return HType.NUMBER;
-    if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL;
-    if (other.isNull()) return HType.INTEGER_OR_NULL;
-    return HType.UNKNOWN;
-  }
-
-  HType intersection(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.CONFLICTING;
-    if (other.isUnknown()) return HType.INTEGER;
-    if (other.isIntegerOrNull()) return HType.INTEGER;
-    if (other.isInteger()) return HType.INTEGER;
-    if (other.isDouble()) return HType.CONFLICTING;
-    if (other.isDoubleOrNull()) return HType.CONFLICTING;
-    if (other.isNumber()) return HType.INTEGER;
-    if (other.isNumberOrNull()) return HType.INTEGER;
-    return HType.CONFLICTING;
-  }
 }
 
 class HDoubleOrNullType extends HNumberOrNullType {
@@ -585,33 +447,6 @@
   TypeMask computeMask(Compiler compiler) {
     return new TypeMask.exact(computeType(compiler));
   }
-
-  HType union(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.DOUBLE_OR_NULL;
-    if (other.isUnknown()) return HType.UNKNOWN;
-    if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL;
-    if (other.isDouble()) return HType.DOUBLE_OR_NULL;
-    if (other.isNumber()) return HType.NUMBER_OR_NULL;
-    if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL;
-    if (other.isNull()) return HType.DOUBLE_OR_NULL;
-    return HType.UNKNOWN;
-  }
-
-  HType intersection(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.CONFLICTING;
-    if (other.isUnknown()) return HType.DOUBLE_OR_NULL;
-    if (other.isInteger()) return HType.CONFLICTING;
-    if (other.isIntegerOrNull()) return HType.NULL;
-    if (other.isDouble()) return HType.DOUBLE;
-    if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL;
-    if (other.isNumber()) return HType.DOUBLE;
-    if (other.isNumberOrNull()) return HType.DOUBLE_OR_NULL;
-    if (other.isTop(compiler)) {
-      return other.canBeNull() ? this : HType.DOUBLE;
-    }
-    if (other.canBeNull()) return HType.NULL;
-    return HType.CONFLICTING;
-  }
 }
 
 class HDoubleType extends HNumberType {
@@ -619,6 +454,7 @@
   bool isDouble() => true;
   bool isDoubleOrNull() => true;
   String toString() => "double";
+  bool isExact() => true;
 
   DartType computeType(Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
@@ -628,29 +464,6 @@
   TypeMask computeMask(Compiler compiler) {
     return new TypeMask.nonNullExact(computeType(compiler));
   }
-
-  HType union(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.DOUBLE;
-    if (other.isUnknown()) return HType.UNKNOWN;
-    if (other.isDouble()) return HType.DOUBLE;
-    if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL;
-    if (other.isNumber()) return HType.NUMBER;
-    if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL;
-    if (other.isNull()) return HType.DOUBLE_OR_NULL;
-    return HType.UNKNOWN;
-  }
-
-  HType intersection(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.CONFLICTING;
-    if (other.isUnknown()) return HType.DOUBLE;
-    if (other.isIntegerOrNull()) return HType.CONFLICTING;
-    if (other.isInteger()) return HType.CONFLICTING;
-    if (other.isDouble()) return HType.DOUBLE;
-    if (other.isDoubleOrNull()) return HType.DOUBLE;
-    if (other.isNumber()) return HType.DOUBLE;
-    if (other.isNumberOrNull()) return HType.DOUBLE;
-    return HType.CONFLICTING;
-  }
 }
 
 class HIndexablePrimitiveType extends HPrimitiveType {
@@ -659,37 +472,12 @@
   String toString() => "indexable";
 
   DartType computeType(Compiler compiler) {
-    // TODO(ngeoffray): Represent union types.
-    return null;
+    JavaScriptBackend backend = compiler.backend;
+    return backend.jsIndexableClass.computeType(compiler);
   }
 
   TypeMask computeMask(Compiler compiler) {
-    // TODO(ngeoffray): Represent union types.
-    return null;
-  }
-
-  HType union(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.INDEXABLE_PRIMITIVE;
-    if (other.isUnknown()) return HType.UNKNOWN;
-    if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE;
-    if (other.canBePrimitiveString(compiler)) {
-      // TODO(ngeoffray): Represent union types.
-      return HType.UNKNOWN;
-    }
-    if (other.canBePrimitiveArray(compiler)) {
-      // TODO(ngeoffray): Represent union types.
-      return HType.UNKNOWN;
-    }
-    return HType.UNKNOWN;
-  }
-
-  HType intersection(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.CONFLICTING;
-    if (other.isUnknown()) return HType.INDEXABLE_PRIMITIVE;
-    if (other.isIndexablePrimitive()) return other;
-    if (other.canBePrimitiveString(compiler)) return HType.STRING;
-    if (other.canBePrimitiveArray(compiler)) return HType.READABLE_ARRAY;
-    return HType.CONFLICTING;
+    return new TypeMask.nonNullSubtype(computeType(compiler));
   }
 }
 
@@ -697,6 +485,7 @@
   const HStringOrNullType();
   bool isStringOrNull() => true;
   String toString() => "String or null";
+  bool canBePrimitiveString(Compiler compiler) => true;
 
   DartType computeType(Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
@@ -706,45 +495,6 @@
   TypeMask computeMask(Compiler compiler) {
     return new TypeMask.exact(computeType(compiler));
   }
-
-  HType union(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.STRING_OR_NULL;
-    if (other.isUnknown()) return HType.UNKNOWN;
-    if (other.isString()) return HType.STRING_OR_NULL;
-    if (other.isStringOrNull()) return HType.STRING_OR_NULL;
-    if (other.isIndexablePrimitive()) {
-      // We don't have a type that represents the nullable indexable
-      // primitive.
-      return HType.UNKNOWN;
-    }
-    if (other.canBePrimitiveString(compiler)) {
-      if (other.canBeNull()) {
-        return other;
-      } else {
-        TypeMask otherMask = other.computeMask(compiler);
-        return new HType.fromMask(otherMask.nullable(), compiler);
-      }
-    }
-    if (other.isNull()) return HType.STRING_OR_NULL;
-    return HType.UNKNOWN;
-  }
-
-  HType intersection(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.CONFLICTING;
-    if (other.isUnknown()) return HType.STRING_OR_NULL;
-    if (other.isString()) return HType.STRING;
-    if (other.isStringOrNull()) return HType.STRING_OR_NULL;
-    if (other.isArray()) return HType.CONFLICTING;
-    if (other.isIndexablePrimitive()) return HType.STRING;
-    if (other.canBePrimitiveString(compiler)) {
-      return other.canBeNull() ? HType.STRING_OR_NULL : HType.STRING;
-    }
-    if (other.isTop(compiler)) {
-      return other.canBeNull() ? this : HType.STRING;
-    }
-    if (other.canBeNull()) return HType.NULL;
-    return HType.CONFLICTING;
-  }
 }
 
 class HStringType extends HIndexablePrimitiveType {
@@ -752,6 +502,8 @@
   bool isString() => true;
   bool isStringOrNull() => true;
   String toString() => "String";
+  bool isExact() => true;
+  bool canBePrimitiveString(Compiler compiler) => true;
 
   DartType computeType(Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
@@ -761,62 +513,21 @@
   TypeMask computeMask(Compiler compiler) {
     return new TypeMask.nonNullExact(computeType(compiler));
   }
-
-  HType union(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.STRING;
-    if (other.isUnknown()) return HType.UNKNOWN;
-    if (other.isString()) return HType.STRING;
-    if (other.isStringOrNull()) return HType.STRING_OR_NULL;
-    if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE;
-    if (other.canBePrimitiveString(compiler)) return other;
-    if (other.isNull()) return HType.STRING_OR_NULL;
-    return HType.UNKNOWN;
-  }
-
-  HType intersection(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.CONFLICTING;
-    if (other.isUnknown()) return HType.STRING;
-    if (other.isString()) return HType.STRING;
-    if (other.isArray()) return HType.CONFLICTING;
-    if (other.isIndexablePrimitive()) return HType.STRING;
-    if (other.isStringOrNull()) return HType.STRING;
-    if (other.canBePrimitiveString(compiler)) return HType.STRING;
-    return HType.CONFLICTING;
-  }
 }
 
 class HReadableArrayType extends HIndexablePrimitiveType {
   const HReadableArrayType();
   bool isReadableArray() => true;
   String toString() => "readable array";
+  bool canBePrimitiveArray(Compiler compiler) => true;
 
   DartType computeType(Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
-    return backend.jsArrayClass.rawType;
+    return backend.jsArrayClass.computeType(compiler);
   }
 
   TypeMask computeMask(Compiler compiler) {
-    return new TypeMask.nonNullExact(computeType(compiler));
-  }
-
-  HType union(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.READABLE_ARRAY;
-    if (other.isUnknown()) return HType.UNKNOWN;
-    if (other.isReadableArray()) return HType.READABLE_ARRAY;
-    if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE;
-    if (other.canBePrimitiveArray(compiler)) return other;
-    if (other.isNull()) return new HType.readableArrayOrNull(compiler);
-    return HType.UNKNOWN;
-  }
-
-  HType intersection(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.CONFLICTING;
-    if (other.isUnknown()) return HType.READABLE_ARRAY;
-    if (other.isString()) return HType.CONFLICTING;
-    if (other.isReadableArray()) return other;
-    if (other.isIndexablePrimitive()) return HType.READABLE_ARRAY;
-    if (other.canBePrimitiveArray(compiler)) return HType.READABLE_ARRAY;
-    return HType.CONFLICTING;
+    return new TypeMask.nonNullSubclass(computeType(compiler));
   }
 }
 
@@ -825,25 +536,13 @@
   bool isMutableArray() => true;
   String toString() => "mutable array";
 
-  HType union(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.MUTABLE_ARRAY;
-    if (other.isUnknown()) return HType.UNKNOWN;
-    if (other.isMutableArray()) return HType.MUTABLE_ARRAY;
-    if (other.isReadableArray()) return HType.READABLE_ARRAY;
-    if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE;
-    if (other.canBePrimitiveArray(compiler)) return other;
-    if (other.isNull()) return new HType.mutableArrayOrNull(compiler);
-    return HType.UNKNOWN;
+  DartType computeType(Compiler compiler) {
+    JavaScriptBackend backend = compiler.backend;
+    return backend.jsMutableArrayClass.computeType(compiler);
   }
 
-  HType intersection(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.CONFLICTING;
-    if (other.isUnknown()) return HType.MUTABLE_ARRAY;
-    if (other.isMutableArray()) return other;
-    if (other.isString()) return HType.CONFLICTING;
-    if (other.isIndexablePrimitive()) return HType.MUTABLE_ARRAY;
-    if (other.canBePrimitiveArray(compiler)) return HType.MUTABLE_ARRAY;
-    return HType.CONFLICTING;
+  TypeMask computeMask(Compiler compiler) {
+    return new TypeMask.nonNullSubclass(computeType(compiler));
   }
 }
 
@@ -851,28 +550,15 @@
   const HFixedArrayType();
   bool isFixedArray() => true;
   String toString() => "fixed array";
+  bool isExact() => true;
 
-  HType union(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.FIXED_ARRAY;
-    if (other.isUnknown()) return HType.UNKNOWN;
-    if (other.isFixedArray()) return HType.FIXED_ARRAY;
-    if (other.isMutableArray()) return HType.MUTABLE_ARRAY;
-    if (other.isReadableArray()) return HType.READABLE_ARRAY;
-    if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE;
-    if (other.canBePrimitiveArray(compiler)) return other;
-    if (other.isNull()) return new HType.fixedArrayOrNull(compiler);
-    return HType.UNKNOWN;
+  DartType computeType(Compiler compiler) {
+    JavaScriptBackend backend = compiler.backend;
+    return backend.jsFixedArrayClass.computeType(compiler);
   }
 
-  HType intersection(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.CONFLICTING;
-    if (other.isUnknown()) return HType.FIXED_ARRAY;
-    if (other.isFixedArray()) return HType.FIXED_ARRAY;
-    if (other.isExtendableArray()) return HType.CONFLICTING;
-    if (other.isString()) return HType.CONFLICTING;
-    if (other.isIndexablePrimitive()) return HType.FIXED_ARRAY;
-    if (other.canBePrimitiveArray(compiler)) return HType.FIXED_ARRAY;
-    return HType.CONFLICTING;
+  TypeMask computeMask(Compiler compiler) {
+    return new TypeMask.nonNullExact(computeType(compiler));
   }
 }
 
@@ -880,28 +566,15 @@
   const HExtendableArrayType();
   bool isExtendableArray() => true;
   String toString() => "extendable array";
+  bool isExact() => true;
 
-  HType union(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.EXTENDABLE_ARRAY;
-    if (other.isUnknown()) return HType.UNKNOWN;
-    if (other.isExtendableArray()) return HType.EXTENDABLE_ARRAY;
-    if (other.isMutableArray()) return HType.MUTABLE_ARRAY;
-    if (other.isReadableArray()) return HType.READABLE_ARRAY;
-    if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE;
-    if (other.canBePrimitiveArray(compiler)) return other;
-    if (other.isNull()) return new HType.extendableArrayOrNull(compiler);
-    return HType.UNKNOWN;
+  DartType computeType(Compiler compiler) {
+    JavaScriptBackend backend = compiler.backend;
+    return backend.jsExtendableArrayClass.computeType(compiler);
   }
 
-  HType intersection(HType other, Compiler compiler) {
-    if (other.isConflicting()) return HType.CONFLICTING;
-    if (other.isUnknown()) return HType.EXTENDABLE_ARRAY;
-    if (other.isExtendableArray()) return HType.EXTENDABLE_ARRAY;
-    if (other.isString()) return HType.CONFLICTING;
-    if (other.isFixedArray()) return HType.CONFLICTING;
-    if (other.isIndexablePrimitive()) return HType.EXTENDABLE_ARRAY;
-    if (other.canBePrimitiveArray(compiler)) return HType.EXTENDABLE_ARRAY;
-    return HType.CONFLICTING;
+  TypeMask computeMask(Compiler compiler) {
+    return new TypeMask.nonNullExact(computeType(compiler));
   }
 }
 
@@ -910,7 +583,6 @@
   const HBoundedType(this.mask);
 
   bool isExact() => mask.isExact;
-  bool isTop(Compiler compiler) => mask.containsAll(compiler);
 
   bool canBeNull() => mask.isNullable;
 
@@ -928,8 +600,12 @@
 
   bool canBePrimitiveArray(Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
-    DartType jsArrayType = backend.jsArrayClass.computeType(compiler);
-    return mask.contains(jsArrayType, compiler);
+    DartType jsArrayType = backend.jsArrayClass.rawType;
+    DartType jsFixedArrayType = backend.jsFixedArrayClass.rawType;
+    DartType jsExtendableArrayType = backend.jsExtendableArrayClass.rawType;
+    return mask.contains(jsArrayType, compiler)
+        || mask.contains(jsFixedArrayType, compiler)
+        || mask.contains(jsExtendableArrayType, compiler);
   }
 
   bool canBePrimitiveString(Compiler compiler) {
@@ -947,64 +623,6 @@
     return mask == bounded.mask;
   }
 
-  HType intersection(HType other, Compiler compiler) {
-    if (this == other) return this;
-    if (other.isConflicting()) return HType.CONFLICTING;
-    if (isTop(compiler)) return other;
-    if (other.isNull()) return canBeNull() ? HType.NULL : HType.CONFLICTING;
-
-    if (canBePrimitiveArray(compiler)) {
-      if (other.isArray()) return other;
-      if (other.isStringOrNull()) {
-        return other.isString() ? HType.CONFLICTING : HType.NULL;
-      }
-      if (other.isIndexablePrimitive()) return HType.READABLE_ARRAY;
-    }
-
-    if (canBePrimitiveString(compiler)) {
-      if (other.isArray()) return HType.CONFLICTING;
-      if (other.isString()) return HType.STRING;
-      if (other.isStringOrNull()) {
-        return canBeNull() ? HType.STRING_OR_NULL : HType.STRING;
-      }
-      if (other.isIndexablePrimitive()) return HType.STRING;
-    }
-
-    TypeMask otherMask = other.computeMask(compiler);
-    if (otherMask != null) {
-      TypeMask intersection = mask.intersection(otherMask, compiler.types);
-      if (intersection != null) {
-        if (intersection == mask) return this;
-        return new HType.fromMask(intersection, compiler);
-      }
-    }
-    if (other.isUnknown()) return this;
-    if (other.canBeNull() && canBeNull()) return HType.NULL;
-    return HType.CONFLICTING;
-  }
-
-  HType union(HType other, Compiler compiler) {
-    if (this == other) return this;
-    if (isTop(compiler)) return this;
-    if (other.isNull()) {
-      if (canBeNull()) {
-        return this;
-      } else {
-        return new HType.fromMask(mask.nullable(), compiler);
-      }
-    }
-
-    TypeMask otherMask = other.computeMask(compiler);
-    if (otherMask != null) {
-      TypeMask union = mask.union(otherMask, compiler.types);
-      if (union == null) return HType.UNKNOWN;
-      if (union == mask) return this;
-      return new HType.fromMask(union, compiler);
-    }
-    if (other.isConflicting()) return this;
-    return HType.UNKNOWN;
-  }
-
   String toString() {
     return 'BoundedType(mask=$mask)';
   }
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart b/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
index 4f1f4c98..e5c38cd 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
@@ -129,18 +129,7 @@
     int receiverIndex = instruction.isInterceptorCall ? 1 : 0;
     HType receiverType = instruction.inputs[receiverIndex].instructionType;
     Selector refined = receiverType.refine(instruction.selector, compiler);
-    // TODO(kasperl): Ask the type inferrer about the type of the
-    // selector not the individual elements. This is basically code
-    // lifted out of the inferrer. Not good.
-    HType type = HType.CONFLICTING;
-    DartType functionType = compiler.functionClass.computeType(compiler);
-    for (Element each in compiler.world.allFunctions.filter(refined)) {
-      HType inferred = (refined.isGetter() && each.isFunction())
-          ? new HType.nonNullExact(functionType, compiler)
-          : new HType.inferredForElement(each, compiler);
-      type = type.union(inferred, compiler);
-      if (type.isUnknown()) break;
-    }
+    HType type = new HType.inferredTypeForSelector(refined, compiler);
     if (type.isUseful()) return type;
     return instruction.specializer.computeTypeFromInputTypes(
         instruction, compiler);
@@ -184,8 +173,8 @@
   }
 
   void convertInput(HInstruction instruction, HInstruction input, HType type) {
-    HTypeConversion converted =
-        new HTypeConversion.argumentTypeCheck(type, input);
+    HTypeConversion converted = new HTypeConversion(
+        null, HTypeConversion.ARGUMENT_TYPE_CHECK, type, input);
     instruction.block.addBefore(instruction, converted);
     Set<HInstruction> dominatedUsers = input.dominatedUsers(instruction);
     for (HInstruction user in dominatedUsers) {
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/value_range_analyzer.dart b/sdk/lib/_internal/compiler/implementation/ssa/value_range_analyzer.dart
index e8f3d55..151e3a7 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/value_range_analyzer.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/value_range_analyzer.dart
@@ -40,10 +40,6 @@
     return new NegateValue(value, this);
   }
 
-  Range newRange(Value low, Value up) {
-    return new Range(low, up, this);
-  }
-
   Range newUnboundRange() {
     return new Range.unbound(this);
   }
@@ -427,7 +423,10 @@
   final Value lower;
   final Value upper;
   final ValueRangeInfo info;
-  Range(this.lower, this.upper, this.info);
+  Range(this.lower, this.upper, this.info) {
+    assert(lower != const UnknownValue());
+    assert(upper != const UnknownValue());
+  }
 
   Range.unbound(info) : this(const MinIntValue(), const MaxIntValue(), info);
 
@@ -460,7 +459,7 @@
       else if (other.upper is IntValue) up = other.upper;
       else up = upper;
     }
-    return info.newRange(low, up);
+    return info.newNormalizedRange(low, up);
   }
 
   Range operator +(Range other) {
@@ -480,7 +479,7 @@
         && other.isSingleValue
         && lower is IntValue
         && other.lower is IntValue) {
-      return info.newRange(lower & other.lower, upper & other.upper);
+      return info.newNormalizedRange(lower & other.lower, upper & other.upper);
     }
     if (isPositive && other.isPositive) {
       Value up = upper.min(other.upper);
@@ -492,11 +491,11 @@
         // or b & a.
         if (up is! IntValue && upper != other.upper) up = const MaxIntValue();
       }
-      return info.newRange(info.intZero, up);
+      return info.newNormalizedRange(info.intZero, up);
     } else if (isPositive) {
-      return info.newRange(info.intZero, upper);
+      return info.newNormalizedRange(info.intZero, upper);
     } else if (other.isPositive) {
-      return info.newRange(info.intZero, other.upper);
+      return info.newNormalizedRange(info.intZero, other.upper);
     } else {
       return info.newUnboundRange();
     }
@@ -598,7 +597,7 @@
   Range visitParameterValue(HParameterValue parameter) {
     if (!parameter.isInteger()) return info.newUnboundRange();
     Value value = info.newInstructionValue(parameter);
-    return info.newRange(value, value);
+    return info.newNormalizedRange(value, value);
   }
 
   Range visitPhi(HPhi phi) {
@@ -625,7 +624,7 @@
     if (!constant.isInteger()) return info.newUnboundRange();
     IntConstant constantInt = constant.constant;
     Value value = info.newIntValue(constantInt.value);
-    return info.newRange(value, value);
+    return info.newNormalizedRange(value, value);
   }
 
   Range visitFieldGet(HFieldGet fieldGet) {
@@ -638,7 +637,7 @@
     // put the zero value as the lower bound of this range. This
     // allows to easily remove the second bound check in the following
     // expression: a[1] + a[0].
-    return info.newRange(info.intZero, value);
+    return info.newNormalizedRange(info.intZero, value);
   }
 
   Range visitBoundsCheck(HBoundsCheck check) {
@@ -681,7 +680,7 @@
       if (low != const UnknownValue()) {
         HInstruction instruction =
             createRangeConversion(next, check.length);
-        ranges[instruction] = info.newRange(low, lengthRange.upper);
+        ranges[instruction] = info.newNormalizedRange(low, lengthRange.upper);
       }
     }
 
@@ -689,7 +688,7 @@
       // Update the range of the index if using the maximum index
       // narrows it.
       Range newIndexRange = indexRange.intersection(
-          info.newRange(info.intZero, maxIndex));
+          info.newNormalizedRange(info.intZero, maxIndex));
       if (indexRange == newIndexRange) return indexRange;
       HInstruction instruction = createRangeConversion(next, check.index);
       ranges[instruction] = newIndexRange;
@@ -757,9 +756,9 @@
     Range tryComputeRange(HInstruction instruction) {
       Range range = ranges[instruction];
       if (range.isPositive) {
-        return info.newRange(info.intZero, range.upper);
+        return info.newNormalizedRange(info.intZero, range.upper);
       } else if (range.isNegative) {
-        return info.newRange(range.lower, info.intZero);
+        return info.newNormalizedRange(range.lower, info.intZero);
       }
       return info.newUnboundRange();
     }
@@ -812,15 +811,15 @@
                                 Range rightRange) {
     Range range;
     if (operation == const LessOperation()) {
-      range = info.newRange(
+      range = info.newNormalizedRange(
           const MinIntValue(), rightRange.upper - info.intOne);
     } else if (operation == const LessEqualOperation()) {
-      range = info.newRange(const MinIntValue(), rightRange.upper);
+      range = info.newNormalizedRange(const MinIntValue(), rightRange.upper);
     } else if (operation == const GreaterOperation()) {
-      range = info.newRange(
+      range = info.newNormalizedRange(
           rightRange.lower + info.intOne, const MaxIntValue());
     } else if (operation == const GreaterEqualOperation()) {
-      range = info.newRange(rightRange.lower, const MaxIntValue());
+      range = info.newNormalizedRange(rightRange.lower, const MaxIntValue());
     } else {
       range = info.newUnboundRange();
     }
@@ -906,9 +905,9 @@
     if (range == null) return info.newUnboundRange();
     Range initial = ranges[loopPhi.inputs[0]];
     if (range.isPositive) {
-      return info.newRange(initial.lower, const MaxIntValue());
+      return info.newNormalizedRange(initial.lower, const MaxIntValue());
     } else if (range.isNegative) {
-      return info.newRange(const MinIntValue(), initial.upper);
+      return info.newNormalizedRange(const MinIntValue(), initial.upper);
     }
     return info.newUnboundRange();
   }
@@ -918,9 +917,9 @@
     if (range == null) return info.newUnboundRange();
     Range initial = ranges[loopPhi.inputs[0]];
     if (range.isPositive) {
-      return info.newRange(const MinIntValue(), initial.upper);
+      return info.newNormalizedRange(const MinIntValue(), initial.upper);
     } else if (range.isNegative) {
-      return info.newRange(initial.lower, const MaxIntValue());
+      return info.newNormalizedRange(initial.lower, const MaxIntValue());
     }
     return info.newUnboundRange();
   }
@@ -970,7 +969,7 @@
     // update does not have a range.
     if (other.isConstant()) {
       Value value = info.newIntValue(other.constant.value);
-      return info.newRange(value, value);
+      return info.newNormalizedRange(value, value);
     }
     return null;
   }
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart b/sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart
index c1243d2..f0552e8 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart
@@ -546,7 +546,7 @@
       // in this block can match a phi with the same name in the
       // successor block.
       if (temporaryIndex != 0 && regexp.hasMatch(ownName)) {
-        freeTemporaryNames.addLast(ownName);
+        freeTemporaryNames.add(ownName);
       }
       usedNames.remove(ownName);
     }
diff --git a/sdk/lib/_internal/compiler/implementation/tools/mini_parser.dart b/sdk/lib/_internal/compiler/implementation/tools/mini_parser.dart
index ea56771..9f0ee08 100644
--- a/sdk/lib/_internal/compiler/implementation/tools/mini_parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/tools/mini_parser.dart
@@ -36,7 +36,7 @@
   MyOptions options = new MyOptions();
 
   void printStats() {
-    int kb = (charCount / 1024).round().toInt();
+    int kb = (charCount / 1024).round();
     String stats =
         '$classCount classes (${kb}Kb) in ${stopwatch.elapsedMilliseconds}ms';
     if (errorCount != 0) {
diff --git a/sdk/lib/_internal/compiler/implementation/tree/dartstring.dart b/sdk/lib/_internal/compiler/implementation/tree/dartstring.dart
index 70e2d69..2166f7d 100644
--- a/sdk/lib/_internal/compiler/implementation/tree/dartstring.dart
+++ b/sdk/lib/_internal/compiler/implementation/tree/dartstring.dart
@@ -124,7 +124,7 @@
 
   String slowToString() {
     if (toStringCache != null) return toStringCache;
-    toStringCache = left.slowToString().concat(right.slowToString());
+    toStringCache = left.slowToString() + right.slowToString();
     return toStringCache;
   }
   SourceString get source => new StringWrapper(slowToString());
diff --git a/sdk/lib/_internal/compiler/implementation/tree/nodes.dart b/sdk/lib/_internal/compiler/implementation/tree/nodes.dart
index 1b3b455..7bd2eba1 100644
--- a/sdk/lib/_internal/compiler/implementation/tree/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/tree/nodes.dart
@@ -199,6 +199,8 @@
 
   bool isValidBreakTarget() => false;
   bool isValidContinueTarget() => false;
+  bool isThis() => false;
+  bool isSuper() => false;
 }
 
 class ClassNode extends Node {
@@ -355,9 +357,7 @@
   }
 
   bool get isSuperCall {
-    return receiver != null &&
-           receiver.asIdentifier() != null &&
-           receiver.asIdentifier().isSuper();
+    return receiver != null && receiver.isSuper();
   }
   bool get isOperator => selector is Operator;
   bool get isPropertyAccess => argumentsNode == null;
@@ -2036,22 +2036,16 @@
 
 class Initializers {
   static bool isSuperConstructorCall(Send node) {
-    return (node.receiver == null &&
-            node.selector.asIdentifier() != null &&
-            node.selector.asIdentifier().isSuper()) ||
+    return (node.receiver == null && node.selector.isSuper()) ||
            (node.receiver != null &&
-            node.receiver.asIdentifier() != null &&
-            node.receiver.asIdentifier().isSuper() &&
+            node.receiver.isSuper() &&
             node.selector.asIdentifier() != null);
   }
 
   static bool isConstructorRedirect(Send node) {
-    return (node.receiver == null &&
-            node.selector.asIdentifier() != null &&
-            node.selector.asIdentifier().isThis()) ||
+    return (node.receiver == null && node.selector.isThis()) ||
            (node.receiver != null &&
-            node.receiver.asIdentifier() != null &&
-            node.receiver.asIdentifier().isThis() &&
+            node.receiver.isThis() &&
             node.selector.asIdentifier() != null);
   }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/tree_validator.dart b/sdk/lib/_internal/compiler/implementation/tree_validator.dart
index 6a3b93f..ce3809e 100644
--- a/sdk/lib/_internal/compiler/implementation/tree_validator.dart
+++ b/sdk/lib/_internal/compiler/implementation/tree_validator.dart
@@ -42,7 +42,9 @@
     final arguments = node.arguments;
 
     expect(node, arguments != null);
-    expect(node, selector is Identifier, 'selector is not assignable');
+    expect(node,
+           selector is Identifier || selector is FunctionExpression,
+           'selector is not assignable');
     if (identical(name, '++') || identical(name, '--')) {
       expect(node, node.assignmentOperator is Operator);
       if (node.isIndex) {
diff --git a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
index 8fde89a..f116845 100644
--- a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
@@ -65,7 +65,7 @@
  */
 class NullBaseType implements BaseType {
   const NullBaseType();
-  bool operator ==(BaseType other) => other is NullBaseType;
+  bool operator ==(BaseType other) => identical(other, this);
   int get hashCode => 1;
   bool isClass() => false;
   bool isUnknown() => false;
@@ -78,29 +78,34 @@
  * concrete type.
  */
 abstract class ConcreteType {
-  factory ConcreteType.empty() {
-    return new UnionType(new Set<BaseType>());
+  ConcreteType();
+
+  factory ConcreteType.empty(int maxConcreteTypeSize,
+                             BaseTypes classBaseTypes) {
+    return new UnionType(maxConcreteTypeSize, classBaseTypes,
+                         new Set<BaseType>());
   }
 
   /**
    * The singleton constituted of the unknown base type is the unknown concrete
    * type.
    */
-  factory ConcreteType.singleton(int maxConcreteTypeSize, BaseType baseType) {
+  factory ConcreteType.singleton(int maxConcreteTypeSize,
+                                 BaseTypes classBaseTypes, BaseType baseType) {
     if (baseType.isUnknown() || maxConcreteTypeSize < 1) {
       return const UnknownConcreteType();
     }
     Set<BaseType> singletonSet = new Set<BaseType>();
     singletonSet.add(baseType);
-    return new UnionType(singletonSet);
+    return new UnionType(maxConcreteTypeSize, classBaseTypes, singletonSet);
   }
 
   factory ConcreteType.unknown() {
     return const UnknownConcreteType();
   }
 
-  ConcreteType union(int maxConcreteTypeSize, ConcreteType other);
-  bool isUnkown();
+  ConcreteType union(ConcreteType other);
+  bool isUnknown();
   bool isEmpty();
   Set<BaseType> get baseTypes;
 
@@ -116,13 +121,13 @@
  */
 class UnknownConcreteType implements ConcreteType {
   const UnknownConcreteType();
-  bool isUnkown() => true;
+  bool isUnknown() => true;
   bool isEmpty() => false;
   bool operator ==(ConcreteType other) => identical(this, other);
   Set<BaseType> get baseTypes =>
       new Set<BaseType>.from([const UnknownBaseType()]);
   int get hashCode => 0;
-  ConcreteType union(int maxConcreteTypeSize, ConcreteType other) => this;
+  ConcreteType union(ConcreteType other) => this;
   ClassElement getUniqueType() => null;
   toString() => "unknown";
 }
@@ -131,15 +136,18 @@
  * An immutable set of base types, like [: {int, bool} :].
  */
 class UnionType implements ConcreteType {
+  final int maxConcreteTypeSize;
+  final BaseTypes classBaseTypes;
+
   final Set<BaseType> baseTypes;
 
   /**
    * The argument should NOT be mutated later. Do not call directly, use
    * ConcreteType.singleton instead.
    */
-  UnionType(this.baseTypes);
+  UnionType(this.maxConcreteTypeSize, this.classBaseTypes, this.baseTypes);
 
-  bool isUnkown() => false;
+  bool isUnknown() => false;
   bool isEmpty() => baseTypes.isEmpty;
 
   bool operator ==(ConcreteType other) {
@@ -156,20 +164,29 @@
     return result;
   }
 
-  // TODO(polux): Collapse {num, int, ...}, {num, double, ...} and
-  // {int, double,...} into {num, ...} as an optimization. It will require
-  // UnionType to know about these class elements, which is cumbersome because
-  // there are no nested classes. We need factory methods instead.
-  ConcreteType union(int maxConcreteTypeSize, ConcreteType other) {
-    if (other.isUnkown()) {
+  ConcreteType union(ConcreteType other) {
+    if (other.isUnknown()) {
       return const UnknownConcreteType();
     }
     UnionType otherUnion = other;  // cast
     Set<BaseType> newBaseTypes = new Set<BaseType>.from(baseTypes);
     newBaseTypes.addAll(otherUnion.baseTypes);
+
+    // normalize {int, float}, {int, num} or {float, num} into num
+    // TODO(polux): generalize this to all types when we extend the concept of
+    //     "concrete type" to other abstract classes than num
+    if (newBaseTypes.contains(classBaseTypes.numBaseType) ||
+        (newBaseTypes.contains(classBaseTypes.intBaseType)
+            && newBaseTypes.contains(classBaseTypes.doubleBaseType))) {
+      newBaseTypes.remove(classBaseTypes.intBaseType);
+      newBaseTypes.remove(classBaseTypes.doubleBaseType);
+      newBaseTypes.add(classBaseTypes.numBaseType);
+    }
+
+    // widen big types to dynamic
     return newBaseTypes.length > maxConcreteTypeSize
         ? const UnknownConcreteType()
-        : new UnionType(newBaseTypes);
+        : new UnionType(maxConcreteTypeSize, classBaseTypes, newBaseTypes);
   }
 
   ClassElement getUniqueType() {
@@ -339,7 +356,7 @@
       if (element == null) {
         newMap[element] = type;
       } else {
-        newMap[element] = inferrer.union(currentType, type);
+        newMap[element] = currentType.union(type);
       }
     });
     return new ConcreteTypesEnvironment.of(inferrer, newMap, typeOfThis);
@@ -367,6 +384,36 @@
     return result;
   }
 
+  /**
+   * Returns true if and only if the environment is compatible with [signature].
+   */
+  bool matches(FunctionSignature signature) {
+    Types types = inferrer.compiler.types;
+    bool paramMatches(ConcreteType concrete, VariableElement parameter) {
+      DartType parameterType = parameter.variables.type;
+      if (parameterType.isDynamic || parameterType.isRaw) {
+        return true;
+      }
+      for (BaseType baseType in concrete.baseTypes) {
+        if (baseType.isUnknown()) return false;
+        if (baseType.isNull()) continue;
+        ClassBaseType classType = baseType;
+        if (!types.isSubtype(new InterfaceType(classType.element),
+                             parameterType)) return false;
+      }
+      return true;
+    }
+    for (VariableElement param in signature.requiredParameters) {
+      ConcreteType concrete = environment[param];
+      if (concrete == null || !paramMatches(concrete, param)) return false;
+    }
+    for (VariableElement param in signature.optionalParameters) {
+      ConcreteType concrete = environment[param];
+      if (concrete != null && !paramMatches(concrete, param)) return false;
+    }
+    return true;
+  }
+
   String toString() => "{ this: $typeOfThis, env: ${environment.toString()} }";
 }
 
@@ -374,12 +421,16 @@
  * A work item for the type inference queue.
  */
 class InferenceWorkItem {
-  FunctionElement method;
+  Element methodOrField;
   ConcreteTypesEnvironment environment;
-  InferenceWorkItem(this.method, this.environment);
+  InferenceWorkItem(this.methodOrField, this.environment);
 
-  toString() => "{ method = ${method.name.slowToString()}, "
-                "environment = $environment }";
+  toString() {
+    final elementType = methodOrField.isField() ? "field" : "method";
+    final elementRepresentation = methodOrField.name.slowToString();
+    return "{ $elementType = $elementRepresentation"
+           ", environment = $environment }";
+  }
 }
 
 /**
@@ -425,6 +476,9 @@
    */
   FunctionElement listConstructor;
 
+  /// The small set of corelib classes whose annotations we trust.
+  Set<ClassElement> trustedClasses;
+
   /**
    * A cache from (function x argument base types) to concrete types,
    * used to memoize [analyzeMonoSend]. Another way of seeing [cache] is as a
@@ -434,6 +488,15 @@
    */
   final Map<FunctionElement, Map<ConcreteTypesEnvironment, ConcreteType>> cache;
 
+  /**
+   * An ad-hoc cache that overrides the computed cache for very specific cases
+   * like [:int + {int}:] where we know better than the type annotations of
+   * [:int:] (which we trust as a special case already).
+   */
+  final Map<FunctionElement, Map<ConcreteTypesEnvironment, ConcreteType>>
+      adHocRules;
+
+
   /** A map from expressions to their inferred concrete types. */
   final Map<Node, ConcreteType> inferredTypes;
 
@@ -443,11 +506,17 @@
   /** The work queue consumed by [analyzeMain]. */
   final Queue<InferenceWorkItem> workQueue;
 
-  /** [: callers[f] :] is the list of [: f :]'s possible callers. */
-  final Map<FunctionElement, Set<FunctionElement>> callers;
+  /**
+   * [:callers[f]:] is the list of [:f:]'s possible callers or fields
+   * whose initialization is a call to [:f:].
+   */
+  final Map<FunctionElement, Set<Element>> callers;
 
-  /** [: readers[field] :] is the list of [: field :]'s possible readers. */
-  final Map<Element, Set<FunctionElement>> readers;
+  /**
+   * [:readers[field]:] is the list of [:field:]'s possible readers or fields
+   * whose initialization is a read of [:field:].
+   */
+  final Map<Element, Set<Element>> readers;
 
   /// The set of classes encountered so far.
   final Set<ClassElement> seenClasses;
@@ -471,46 +540,46 @@
       : this.compiler = compiler,
         cache = new Map<FunctionElement,
             Map<ConcreteTypesEnvironment, ConcreteType>>(),
+        adHocRules = new Map<FunctionElement,
+            Map<ConcreteTypesEnvironment, ConcreteType>>(),
         inferredTypes = new Map<Node, ConcreteType>(),
         inferredFieldTypes = new Map<Element, ConcreteType>(),
         inferredParameterTypes = new Map<VariableElement, ConcreteType>(),
         workQueue = new Queue<InferenceWorkItem>(),
-        callers = new Map<FunctionElement, Set<FunctionElement>>(),
-        readers = new Map<Element, Set<FunctionElement>>(),
-        listElementType = new ConcreteType.empty(),
+        callers = new Map<FunctionElement, Set<Element>>(),
+        readers = new Map<Element, Set<Element>>(),
         seenClasses = new Set<ClassElement>(),
         dynamicCallers = new Map<SourceString, Set<FunctionElement>>() {
     unknownConcreteType = new ConcreteType.unknown();
-    emptyConcreteType = new ConcreteType.empty();
   }
 
   /**
-   * Populates [cache] with ad hoc rules like:
+   * Populates [adHocRules] with ad hoc rules who know better than the corelib
+   * type annotations for types whose type annotations we trust, like:
    *
-   *     {int} + {int}    -> {int}
-   *     {int} + {double} -> {num}
-   *     {int} + {num}    -> {double}
+   *     {int}    + {int}    -> {int}
+   *     {double} + {double} -> {double}
    *     ...
    */
-  populateCacheWithBuiltinRules() {
+  populateAdHocRules() {
     // Builds the environment that would be looked up if we were to analyze
-    // o.method(arg) where o has concrete type {receiverType} and arg has
-    // concrete type {argumentType}.
+    // o.method(arg) where o has concrete type {receiverType} and arg have
+    // concrete types {argumentTypes}.
     ConcreteTypesEnvironment makeEnvironment(BaseType receiverType,
                                              FunctionElement method,
-                                             BaseType argumentType) {
+                                             List<BaseType> argumentTypes) {
       ArgumentsTypes argumentsTypes = new ArgumentsTypes(
-          [singletonConcreteType(argumentType)],
+          argumentTypes.map((type) => singletonConcreteType(type)).toList(),
           new Map());
       Map<Element, ConcreteType> argumentMap =
           associateArguments(method, argumentsTypes);
       return new ConcreteTypesEnvironment.of(this, argumentMap, receiverType);
     }
 
-    // Adds the rule {receiverType}.method({argumentType}) -> {returnType}
+    // Adds the rule {receiverType}.method({arg1}, ..., {argn}) -> {returnType}
     // to cache.
     void rule(ClassBaseType receiverType, String method,
-              BaseType argumentType, BaseType returnType) {
+              List<BaseType> argumentTypes, BaseType returnType) {
       // The following line shouldn't be needed but the mock compiler doesn't
       // resolve num for some reason.
       receiverType.element.ensureResolved(compiler);
@@ -518,31 +587,23 @@
           receiverType.element.lookupMember(new SourceString(method))
               .implementation;
       ConcreteTypesEnvironment environment =
-          makeEnvironment(receiverType, methodElement, argumentType);
+          makeEnvironment(receiverType, methodElement, argumentTypes);
       Map<ConcreteTypesEnvironment, ConcreteType> map =
-          cache.containsKey(methodElement)
-              ? cache[methodElement]
+          adHocRules.containsKey(methodElement)
+              ? adHocRules[methodElement]
               : new Map<ConcreteTypesEnvironment, ConcreteType>();
       map[environment] = singletonConcreteType(returnType);
-      cache[methodElement] = map;
+      adHocRules[methodElement] = map;
     }
 
     // The hardcoded typing rules.
     final ClassBaseType int = baseTypes.intBaseType;
     final ClassBaseType double = baseTypes.doubleBaseType;
-    final ClassBaseType num = baseTypes.numBaseType;
+
     for (String method in ['+', '*', '-']) {
-      rule(int, method, int, int);
-      rule(int, method, double, num);
-      rule(int, method, num, num);
-
-      rule(double, method, double, double);
-      rule(double, method, int, num);
-      rule(double, method, num, num);
-
-      rule(num, method, int, num);
-      rule(num, method, double, num);
-      rule(num, method, num, num);
+      for (ClassBaseType type in [int, double]) {
+        rule(type, method, [type], type);
+      }
     }
   }
 
@@ -556,12 +617,8 @@
 
   /** Creates a singleton concrete type containing [baseType]. */
   ConcreteType singletonConcreteType(BaseType baseType) {
-    return new ConcreteType.singleton(compiler.maxConcreteTypeSize, baseType);
-  }
-
-  /** Returns the union of its two arguments */
-  ConcreteType union(ConcreteType concreteType1, ConcreteType concreteType2) {
-    return concreteType1.union(compiler.maxConcreteTypeSize, concreteType2);
+    return new ConcreteType.singleton(compiler.maxConcreteTypeSize, baseTypes,
+                                      baseType);
   }
 
   /**
@@ -587,7 +644,7 @@
     ConcreteType currentType = inferredTypes[node];
     inferredTypes[node] = (currentType == null)
         ? type
-        : union(currentType, type);
+        : currentType.union(type);
   }
 
   /**
@@ -595,7 +652,14 @@
    */
   ConcreteType getFieldType(Element field) {
     ConcreteType result = inferredFieldTypes[field];
-    return (result == null) ? emptyConcreteType : result;
+    if (result != null) {
+      return result;
+    } else {
+      // field is a toplevel variable, we trigger its analysis because no object
+      // creation is never going to trigger it
+      result = analyzeFieldInitialization(field);
+      return (result == null) ? emptyConcreteType : result;
+    }
   }
 
   /**
@@ -605,27 +669,20 @@
   void augmentFieldType(Element field, ConcreteType type) {
     ConcreteType oldType = inferredFieldTypes[field];
     ConcreteType newType = (oldType != null)
-        ? union(oldType, type)
+        ? oldType.union(type)
         : type;
     if (oldType != newType) {
       inferredFieldTypes[field] = newType;
       final fieldReaders = readers[field];
       if (fieldReaders != null) {
-        for (final reader in fieldReaders) {
-          final readerInstances = cache[reader];
-          if (readerInstances != null) {
-            readerInstances.forEach((environment, _) {
-              workQueue.addLast(new InferenceWorkItem(reader, environment));
-            });
-          }
-        }
+        fieldReaders.forEach(invalidate);
       }
     }
   }
 
   /// Augment the inferred type of elements stored in Lists.
   void augmentListElementType(ConcreteType type) {
-    ConcreteType newType = union(listElementType, type);
+    ConcreteType newType = listElementType.union(type);
     if (newType != listElementType) {
       invalidateCallers(listIndex);
       listElementType = newType;
@@ -639,7 +696,7 @@
   void augmentParameterType(VariableElement parameter, ConcreteType type) {
     ConcreteType oldType = inferredParameterTypes[parameter];
     inferredParameterTypes[parameter] =
-        (oldType == null) ? type : union(oldType, type);
+        (oldType == null) ? type : oldType.union(type);
   }
 
   /// Augments the set of classes encountered so far.
@@ -659,12 +716,12 @@
   /**
    * Add [caller] to the set of [callee]'s callers.
    */
-  void addCaller(FunctionElement callee, FunctionElement caller) {
-    Set<FunctionElement> current = callers[callee];
+  void addCaller(FunctionElement callee, Element caller) {
+    Set<Element> current = callers[callee];
     if (current != null) {
       current.add(caller);
     } else {
-      Set<FunctionElement> newSet = new Set<FunctionElement>();
+      Set<Element> newSet = new Set<Element>();
       newSet.add(caller);
       callers[callee] = newSet;
     }
@@ -687,12 +744,12 @@
   /**
    * Add [reader] to the set of [field]'s readers.
    */
-  void addReader(Element field, FunctionElement reader) {
-    Set<FunctionElement> current = readers[field];
+  void addReader(Element field, Element reader) {
+    Set<Element> current = readers[field];
     if (current != null) {
       current.add(reader);
     } else {
-      Set<FunctionElement> newSet = new Set<FunctionElement>();
+      Set<Element> newSet = new Set<Element>();
       newSet.add(reader);
       readers[field] = newSet;
     }
@@ -702,41 +759,99 @@
    * Add callers of [function] to the workqueue.
    */
   void invalidateCallers(FunctionElement function) {
-    Set<FunctionElement> methodCallers = callers[function];
+    Set<Element> methodCallers = callers[function];
     if (methodCallers == null) return;
-    for (FunctionElement caller in methodCallers) {
+    for (Element caller in methodCallers) {
       invalidate(caller);
     }
   }
 
   /**
-   * Add all instances of method to the workqueue.
+   * Add all instances of [methodOrField] to the workqueue.
    */
-  void invalidate(FunctionElement method) {
-    Map<ConcreteTypesEnvironment, ConcreteType> instances = cache[method];
-    if (instances != null) {
-      instances.forEach((environment, _) {
-        workQueue.addLast(
-            new InferenceWorkItem(method, environment));
-      });
+  void invalidate(Element methodOrField) {
+    if (methodOrField.isField()) {
+      workQueue.addLast(new InferenceWorkItem(
+          methodOrField, new ConcreteTypesEnvironment(this)));
+    } else {
+      Map<ConcreteTypesEnvironment, ConcreteType> instances =
+          cache[methodOrField];
+      if (instances != null) {
+        instances.forEach((environment, _) {
+          workQueue.addLast(
+              new InferenceWorkItem(methodOrField, environment));
+        });
+      }
     }
   }
 
   // -- query --
 
+  TypeMask fromClassBaseTypeToTypeMask(ClassBaseType baseType) {
+    ClassBaseType classBaseType = baseType;
+    ClassElement cls = classBaseType.element;
+    return new TypeMask.nonNullExact(cls.rawType);
+  }
+
+  /**
+   * Returns the [TypeMask] representation of [concreteType]. Returns [:null:]
+   * if and only if [:concreteType.isUnknown():].
+   */
+  TypeMask fromConcreteToTypeMask(ConcreteType concreteType) {
+    if (concreteType == null) return null;
+    TypeMask typeMask;
+    bool nullable = false;
+    for (BaseType baseType in concreteType.baseTypes) {
+      if (baseType.isUnknown()) {
+        return null;
+      } else if (baseType.isNull()) {
+        nullable = true;
+      } else {
+        TypeMask current = fromClassBaseTypeToTypeMask(baseType);
+        typeMask = typeMask == null
+            ? current
+            : typeMask.union(current, compiler);
+      }
+    }
+    return nullable
+        ? typeMask == null ? null : typeMask.nullable()
+        : typeMask;
+  }
+
   /**
    * Get the inferred concrete type of [node].
    */
-  ConcreteType getConcreteTypeOfNode(Element owner, Node node) {
-    return inferredTypes[node];
+  TypeMask getTypeOfNode(Element owner, Node node) {
+    return fromConcreteToTypeMask(inferredTypes[node]);
   }
 
   /**
    * Get the inferred concrete type of [element].
    */
-  ConcreteType getConcreteTypeOfElement(Element element) {
+  TypeMask getTypeOfElement(Element element) {
     if (!element.isParameter()) return null;
-    return inferredParameterTypes[element];
+    return fromConcreteToTypeMask(inferredParameterTypes[element]);
+  }
+
+  /**
+   * Get the inferred concrete return type of [element].
+   */
+  TypeMask getReturnTypeOfElement(Element element) {
+    if (!element.isFunction()) return null;
+    Map<ConcreteTypesEnvironment, ConcreteType> templates = cache[element];
+    if (templates == null) return null;
+    ConcreteType returnType = emptyConcreteType;
+    templates.forEach((_, concreteType) {
+      returnType = returnType.union(concreteType);
+    });
+    return fromConcreteToTypeMask(returnType);
+  }
+
+  /**
+   * Get the inferred concrete type of [selector].
+   */
+  TypeMask getTypeOfSelector(Selector selector) {
+    return null;
   }
 
   // --- analysis ---
@@ -762,8 +877,8 @@
     ConcreteTypeCartesianProduct product =
         new ConcreteTypeCartesianProduct(this, receiverType, argumentMap);
     for (ConcreteTypesEnvironment environment in product) {
-      result = union(result,
-                     getMonomorphicSendReturnType(function, environment));
+      result =
+          result.union(getMonomorphicSendReturnType(function, environment));
     }
     return result;
   }
@@ -878,6 +993,57 @@
   }
 
   /**
+   * Computes the type of a call to the magic 'JS' function.
+   */
+  ConcreteType getNativeCallReturnType(Send node) {
+    native.NativeBehavior nativeBehavior =
+        compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node);
+    if (nativeBehavior == null) return unknownConcreteType;
+    List typesReturned = nativeBehavior.typesReturned;
+    if (typesReturned.isEmpty) return unknownConcreteType;
+
+    ConcreteType result = singletonConcreteType(const NullBaseType());
+    for (final type in typesReturned) {
+      var concreteType;
+
+      // TODO(polux): track native types
+      if (type == native.SpecialType.JsObject) {
+        return unknownConcreteType;
+      } else if (type == native.SpecialType.JsArray) {
+        concreteType = singletonConcreteType(baseTypes.listBaseType);
+
+      // at this point, we know that type is not a SpecialType and thus has to
+      // be a DartType
+      } else if (type.element == compiler.objectClass) {
+        // We don't want to return all the subtypes of object here.
+        return unknownConcreteType;
+      } else if (type.element == compiler.stringClass){
+        concreteType = singletonConcreteType(baseTypes.stringBaseType);
+      } else if (type.element == compiler.intClass) {
+        concreteType = singletonConcreteType(baseTypes.intBaseType);
+      } else if (type.element == compiler.doubleClass) {
+        concreteType = singletonConcreteType(baseTypes.doubleBaseType);
+      } else if (type.element == compiler.numClass) {
+        concreteType = singletonConcreteType(baseTypes.numBaseType);
+      } else if (type.element == compiler.boolClass) {
+        concreteType = singletonConcreteType(baseTypes.boolBaseType);
+      } else {
+        Set<ClassElement> subtypes = compiler.world.subtypes[type.element];
+        if (subtypes == null) continue;
+        concreteType = emptyConcreteType;
+        for (ClassElement subtype in subtypes) {
+          concreteType = concreteType.union(
+              singletonConcreteType(new ClassBaseType(subtype)));
+        }
+      }
+
+      result = result.union(concreteType);
+      if (result.isUnknown()) return result;
+    }
+    return result;
+  }
+
+  /**
    * Handles external methods that cannot be cached because they depend on some
    * other state of [ConcreteTypesInferrer] like [:List#[]:] and
    * [:List#[]=:]. Returns null if [function] and [environment] don't form a
@@ -885,14 +1051,24 @@
    */
   ConcreteType getSpecialCaseReturnType(FunctionElement function,
                                         ConcreteTypesEnvironment environment) {
-    if (function.name == const SourceString('JS')) {
-      // TODO(polux): trust the type once we handle generic types
-      return unknownConcreteType;
+    Map<ConcreteTypesEnvironment, ConcreteType> template = adHocRules[function];
+    if (template != null) {
+      ConcreteType result = template[environment];
+      if (result != null) return result;
+    }
+    if (trustedClasses.contains(function.enclosingElement)) {
+      FunctionSignature signature = function.functionSignature;
+      if (environment.matches(signature)) {
+        return singletonConcreteType(
+            new ClassBaseType(signature.returnType.element));
+      } else {
+        return null;
+      }
     } else if (function == listIndex) {
       ConcreteType indexType = environment.lookupType(
           listIndex.functionSignature.requiredParameters.head);
       if (!indexType.baseTypes.contains(baseTypes.intBaseType)) {
-        return new ConcreteType.empty();
+        return emptyConcreteType;
       }
       return listElementType;
     } else if (function == listIndexSet) {
@@ -900,20 +1076,30 @@
           listIndexSet.functionSignature.requiredParameters;
       ConcreteType indexType = environment.lookupType(parameters.head);
       if (!indexType.baseTypes.contains(baseTypes.intBaseType)) {
-        return new ConcreteType.empty();
+        return emptyConcreteType;
       }
       ConcreteType elementType = environment.lookupType(parameters.tail.head);
       augmentListElementType(elementType);
-      return new ConcreteType.empty();
+      return emptyConcreteType;
     }
     return null;
   }
 
-  ConcreteType analyze(FunctionElement element,
+  /**
+   * [element] must be either a field with an initializing expression,
+   * a generative constructor or a function.
+   */
+  ConcreteType analyze(Element element,
                        ConcreteTypesEnvironment environment) {
-    return element.isGenerativeConstructor()
-        ? analyzeConstructor(element, environment)
-        : analyzeMethod(element, environment);
+    if (element.isGenerativeConstructor()) {
+      return analyzeConstructor(element, environment);
+    } else if (element.isField()) {
+      analyzeFieldInitialization(element);
+      return emptyConcreteType;
+    } else {
+      assert(element is FunctionElement);
+      return analyzeMethod(element, environment);
+    }
   }
 
   ConcreteType analyzeMethod(FunctionElement element,
@@ -934,15 +1120,36 @@
     }
   }
 
-  ConcreteType analyzeConstructor(FunctionElement element,
-                                  ConcreteTypesEnvironment environment) {
-    ClassElement enclosingClass = element.enclosingElement;
-    augmentSeenClasses(enclosingClass);
-    FunctionExpression tree = compiler.parser.parse(element);
+  /**
+   * Analyzes the initialization of a field. Returns [:null:] if and only if
+   * [element] has no initialization expression.
+   */
+  ConcreteType analyzeFieldInitialization(VariableElement element) {
     TreeElements elements =
         compiler.enqueuer.resolution.resolvedElements[element];
-    Visitor visitor =
-        new TypeInferrerVisitor(elements, element, this, environment);
+    Visitor visitor = new TypeInferrerVisitor(elements, element, this,
+        new ConcreteTypesEnvironment(this));
+    Node tree = element.parseNode(compiler);
+    ConcreteType type = initializerDo(tree, (node) => node.accept(visitor));
+    if (type != null) {
+      augmentFieldType(element, type);
+    }
+    return type;
+  }
+
+  ConcreteType analyzeConstructor(FunctionElement element,
+                                  ConcreteTypesEnvironment environment) {
+    Set<Element> uninitializedFields = new Set<Element>();
+
+    // initialize fields
+    ClassElement enclosingClass = element.enclosingElement;
+    augmentSeenClasses(enclosingClass);
+    enclosingClass.forEachInstanceField((_, VariableElement field) {
+      ConcreteType type = analyzeFieldInitialization(field);
+      if (type == null) {
+        uninitializedFields.add(field);
+      }
+    }, includeSuperMembers: false);
 
     // handle initializing formals
     element.functionSignature.forEachParameter((param) {
@@ -950,21 +1157,36 @@
         FieldParameterElement fieldParam = param;
         augmentFieldType(fieldParam.fieldElement,
             environment.lookupType(param));
+        uninitializedFields.remove(fieldParam.fieldElement);
       }
     });
 
     // analyze initializers, including a possible call to super or a redirect
+    FunctionExpression tree = compiler.parser.parse(element);
+    TreeElements elements =
+        compiler.enqueuer.resolution.resolvedElements[element];
+    Visitor visitor =
+        new TypeInferrerVisitor(elements, element, this, environment);
+
     bool foundSuperOrRedirect = false;
     if (tree.initializers != null) {
       // we look for a possible call to super in the initializer list
       for (final init in tree.initializers) {
         init.accept(visitor);
+        SendSet sendSet = init.asSendSet();
         if (init.asSendSet() == null) {
           foundSuperOrRedirect = true;
+        } else {
+          uninitializedFields.remove(elements[init]);
         }
       }
     }
 
+    // set uninitialized fields to null
+    for (VariableElement field in uninitializedFields) {
+      augmentFieldType(field, singletonConcreteType(const NullBaseType()));
+    }
+
     // if no call to super or redirect has been found, call the default
     // constructor (if the current class is not Object).
     if (!foundSuperOrRedirect) {
@@ -998,7 +1220,7 @@
           listConstructor.functionSignature.optionalParameters;
       ConcreteType lengthType = environment.lookupType(parameters.head);
       if (lengthType.baseTypes.contains(baseTypes.intBaseType)) {
-        augmentListElementType(singletonConcreteType(new NullBaseType()));
+        augmentListElementType(singletonConcreteType(const NullBaseType()));
       }
       return singletonConcreteType(baseTypes.listBaseType);
     }
@@ -1017,6 +1239,11 @@
         compiler.listClass.lookupConstructor(
             new Selector.callConstructor(const SourceString(''),
                                          compiler.listClass.getLibrary()));
+    trustedClasses = new Set.from([compiler.intClass, compiler.doubleClass,
+                                  compiler.numClass]);
+    emptyConcreteType = new ConcreteType.empty(compiler.maxConcreteTypeSize,
+                                               baseTypes);
+    listElementType = emptyConcreteType;
   }
 
   /**
@@ -1026,17 +1253,19 @@
   bool analyzeMain(Element element) {
     initialize();
     cache[element] = new Map<ConcreteTypesEnvironment, ConcreteType>();
-    populateCacheWithBuiltinRules();
+    populateAdHocRules();
     try {
       workQueue.addLast(
           new InferenceWorkItem(element, new ConcreteTypesEnvironment(this)));
       while (!workQueue.isEmpty) {
         InferenceWorkItem item = workQueue.removeFirst();
-        ConcreteType concreteType = analyze(item.method, item.environment);
-        var template = cache[item.method];
+        ConcreteType concreteType =
+            analyze(item.methodOrField, item.environment);
+        if (item.methodOrField.isField()) continue;
+        var template = cache[item.methodOrField];
         if (template[item.environment] == concreteType) continue;
         template[item.environment] = concreteType;
-        invalidateCallers(item.method);
+        invalidateCallers(item.methodOrField);
       }
       return true;
     } on CancelTypeInferenceException catch(e) {
@@ -1111,12 +1340,12 @@
 class TypeInferrerVisitor extends ResolvedVisitor<ConcreteType> {
   final ConcreteTypesInferrer inferrer;
 
-  final FunctionElement currentMethod;
+  final Element currentMethodOrField;
   ConcreteTypesEnvironment environment;
   Node lastSeenNode;
 
-  TypeInferrerVisitor(TreeElements elements, this.currentMethod, this.inferrer,
-                      this.environment)
+  TypeInferrerVisitor(TreeElements elements, this.currentMethodOrField,
+                      this.inferrer, this.environment)
       : super(elements);
 
   ArgumentsTypes analyzeArguments(Link<Node> arguments) {
@@ -1227,7 +1456,7 @@
     ConcreteType elseType = node.hasElsePart ? analyze(node.elsePart)
                                              : inferrer.emptyConcreteType;
     environment = environment.join(snapshot);
-    return inferrer.union(thenType, elseType);
+    return thenType.union(elseType);
   }
 
   ConcreteType visitLoop(Loop node) {
@@ -1274,8 +1503,8 @@
       // since this is a sendSet we ignore non-fields
     }
 
-    if (receiverType.isUnkown()) {
-      inferrer.addDynamicCaller(name, currentMethod);
+    if (receiverType.isUnknown()) {
+      inferrer.addDynamicCaller(name, currentMethodOrField);
       for (Element member in inferrer.getMembersByName(name)) {
         if (!(member.isField() || member.isAbstractField())) continue;
         Element cls = member.getEnclosingClass();
@@ -1394,19 +1623,19 @@
 
   ConcreteType visitNewExpression(NewExpression node) {
     Element constructor = elements[node.send];
-    inferrer.addCaller(constructor, currentMethod);
+    inferrer.addCaller(constructor, currentMethodOrField);
     ClassElement cls = constructor.enclosingElement;
     return inferrer.getSendReturnType(constructor, cls,
                                       analyzeArguments(node.send.arguments));
   }
 
   ConcreteType visitLiteralList(LiteralList node) {
-    ConcreteType elementsType = new ConcreteType.empty();
+    ConcreteType elementsType = inferrer.emptyConcreteType;
     // We compute the union of the types of the list literal's elements.
     for (Link<Node> link = node.elements.nodes;
          !link.isEmpty;
          link = link.tail) {
-      elementsType = inferrer.union(elementsType, analyze(link.head));
+      elementsType = elementsType.union(analyze(link.head));
     }
     inferrer.augmentListElementType(elementsType);
     inferrer.augmentSeenClasses(inferrer.compiler.listClass);
@@ -1418,7 +1647,7 @@
     // The concrete type of a sequence of statements is the union of the
     // statement's types.
     for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) {
-      type = inferrer.union(type, analyze(link.head));
+      type = type.union(analyze(link.head));
     }
     return type;
   }
@@ -1476,7 +1705,7 @@
     analyze(node.condition);
     ConcreteType thenType = analyze(node.thenExpression);
     ConcreteType elseType = analyze(node.elseExpression);
-    return inferrer.union(thenType, elseType);
+    return thenType.union(elseType);
   }
 
   ConcreteType visitModifiers(Modifiers node) {
@@ -1577,13 +1806,13 @@
   }
 
   ConcreteType analyzeFieldRead(Element field) {
-    inferrer.addReader(field, currentMethod);
+    inferrer.addReader(field, currentMethodOrField);
     return inferrer.getFieldType(field);
   }
 
   ConcreteType analyzeGetterSend(ClassElement receiverType,
                                  FunctionElement getter) {
-      inferrer.addCaller(getter, currentMethod);
+      inferrer.addCaller(getter, currentMethodOrField);
       return inferrer.getSendReturnType(getter,
                                         receiverType,
                                         new ArgumentsTypes([], new Map()));
@@ -1614,21 +1843,20 @@
       ConcreteType result = inferrer.emptyConcreteType;
       void augmentResult(ClassElement baseReceiverType, Element member) {
         if (member.isField()) {
-          result = inferrer.union(result, analyzeFieldRead(member));
+          result = result.union(analyzeFieldRead(member));
         } else if (member.isAbstractField()){
           // call to a getter
           AbstractFieldElement abstractField = member;
-          result = inferrer.union(
-              result,
+          result = result.union(
               analyzeGetterSend(baseReceiverType, abstractField.getter));
         }
         // since this is a get we ignore non-fields
       }
 
       ConcreteType receiverType = analyze(node.receiver);
-      if (receiverType.isUnkown()) {
+      if (receiverType.isUnknown()) {
         SourceString name = node.selector.asIdentifier().source;
-        inferrer.addDynamicCaller(name, currentMethod);
+        inferrer.addDynamicCaller(name, currentMethodOrField);
         List<Element> members = inferrer.getMembersByName(name);
         for (Element member in members) {
           if (!(member.isField() || member.isAbstractField())) continue;
@@ -1661,8 +1889,8 @@
                                   ArgumentsTypes argumentsTypes) {
     ConcreteType result = inferrer.emptyConcreteType;
 
-    if (receiverType.isUnkown()) {
-      inferrer.addDynamicCaller(canonicalizedMethodName, currentMethod);
+    if (receiverType.isUnknown()) {
+      inferrer.addDynamicCaller(canonicalizedMethodName, currentMethodOrField);
       List<Element> methods =
           inferrer.getMembersByName(canonicalizedMethodName);
       for (Element element in methods) {
@@ -1670,10 +1898,9 @@
         // that are closures.
         if (!element.isFunction()) continue;
         FunctionElement method = element;
-        inferrer.addCaller(method, currentMethod);
+        inferrer.addCaller(method, currentMethodOrField);
         Element cls = method.enclosingElement;
-        result = inferrer.union(
-            result,
+        result = result.union(
             inferrer.getSendReturnType(method, cls, argumentsTypes));
       }
 
@@ -1685,9 +1912,8 @@
           FunctionElement method = cls.lookupMember(canonicalizedMethodName);
           if (method != null) {
             method = method.implementation;
-            inferrer.addCaller(method, currentMethod);
-            result = inferrer.union(
-                result,
+            inferrer.addCaller(method, currentMethodOrField);
+            result = result.union(
                 inferrer.getSendReturnType(method, cls, argumentsTypes));
           }
         }
@@ -1708,7 +1934,7 @@
     ConcreteType receiverType = (node.receiver != null)
         ? analyze(node.receiver)
         : inferrer.singletonConcreteType(
-            new ClassBaseType(currentMethod.getEnclosingClass()));
+            new ClassBaseType(currentMethodOrField.getEnclosingClass()));
     SourceString name =
         canonicalizeMethodName(node.selector.asIdentifier().source);
     ArgumentsTypes argumentsTypes = analyzeArguments(node.arguments);
@@ -1729,8 +1955,11 @@
   }
 
   ConcreteType visitStaticSend(Send node) {
+    if (elements.getSelector(node).name == const SourceString('JS')) {
+      return inferrer.getNativeCallReturnType(node);
+    }
     Element element = elements[node].implementation;
-    inferrer.addCaller(element, currentMethod);
+    inferrer.addCaller(element, currentMethodOrField);
     return inferrer.getSendReturnType(element, null,
         analyzeArguments(node.arguments));
   }
diff --git a/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
index 6373921..b6bf919 100644
--- a/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
@@ -4,13 +4,19 @@
 
 library simple_types_inferrer;
 
-import '../closure.dart' show ClosureClassMap;
-import '../native_handler.dart' as native;
+import '../closure.dart' show ClosureClassMap, ClosureScope;
+import '../dart_types.dart' show DartType, FunctionType;
 import '../elements/elements.dart';
-import '../dart2jslib.dart';
+import '../native_handler.dart' as native;
 import '../tree/tree.dart';
 import '../util/util.dart' show Link;
-import 'types.dart' show TypesInferrer, ConcreteType, ClassBaseType;
+import 'types.dart' show TypesInferrer, TypeMask;
+
+// BUG(8802): There's a bug in the analyzer that makes the re-export
+// of Selector from dart2jslib.dart fail. For now, we work around that
+// by importing universe.dart explicitly and disabling the re-export.
+import '../dart2jslib.dart' hide Selector;
+import '../universe/universe.dart' show Selector, TypedSelector;
 
 /**
  * A work queue that ensures there are no duplicates, and adds and
@@ -19,11 +25,11 @@
 class WorkSet<E extends Element> {
   final List<E> queue = new List<E>();
   final Set<E> elementsInQueue = new Set<E>();
-  
+
   void add(E element) {
     element = element.implementation;
     if (elementsInQueue.contains(element)) return;
-    queue.addLast(element);
+    queue.add(element);
     elementsInQueue.add(element);
   }
 
@@ -34,6 +40,8 @@
   }
 
   bool get isEmpty => queue.isEmpty;
+
+  int get length => queue.length;
 }
 
 /**
@@ -44,8 +52,8 @@
    * Maps a final field to a map from generative constructor to the
    * inferred type of the field in that generative constructor.
    */
-  final Map<Element, Map<Element, Element>> typesOfFinalFields =
-      new Map<Element, Map<Element, Element>>();
+  final Map<Element, Map<Element, TypeMask>> typesOfFinalFields =
+      new Map<Element, Map<Element, TypeMask>>();
 
   /**
    * The number of generative constructors that need to be visited
@@ -62,16 +70,16 @@
    * Records that the generative [constructor] has inferred [type]
    * for the final [field].
    */
-  void recordFinalFieldType(Element constructor, Element field, Element type) {
-    Map<Element, Element> typesFor = typesOfFinalFields.putIfAbsent(
-        field, () => new Map<Element, Element>());
+  void recordFinalFieldType(Element constructor, Element field, TypeMask type) {
+    Map<Element, TypeMask> typesFor = typesOfFinalFields.putIfAbsent(
+        field, () => new Map<Element, TypeMask>());
     typesFor[constructor] = type;
   }
 
   /**
    * Records that [constructor] has been analyzed. If not at 0,
    * decrement [constructorsToVisitCount].
-   */ 
+   */
   void doneAnalyzingGenerativeConstructor(Element constructor) {
     if (constructorsToVisitCount != 0) constructorsToVisitCount--;
   }
@@ -83,6 +91,22 @@
   bool get isDone => constructorsToVisitCount == 0;
 }
 
+/**
+ * A sentinel type mask class used by the inferrer for the give up
+ * type, and the dynamic type.
+ */
+class SentinelTypeMask extends TypeMask {
+  final String name;
+
+  SentinelTypeMask(this.name) : super(null, 0, false);
+
+  bool operator==(other) {
+    return identical(this, other);
+  }
+
+  String toString() => '$name sentinel type mask';
+}
+
 class SimpleTypesInferrer extends TypesInferrer {
   /**
    * Maps an element to its callers.
@@ -93,8 +117,20 @@
   /**
    * Maps an element to its return type.
    */
-  final Map<Element, Element> returnTypeOf =
-      new Map<Element, Element>();
+  final Map<Element, TypeMask> returnTypeOf =
+      new Map<Element, TypeMask>();
+
+  /**
+   * Maps an element to its type.
+   */
+  final Map<Element, TypeMask> typeOf = new Map<Element, TypeMask>();
+
+  /**
+   * Maps an element to its assignments and the types inferred at
+   * these assignments.
+   */
+  final Map<Element, Map<Node, TypeMask>> typeOfFields =
+      new Map<Element, Map<Node, TypeMask>>();
 
   /**
    * Maps an element to the number of times this type inferrer
@@ -120,10 +156,33 @@
   final int MAX_ANALYSIS_COUNT_PER_ELEMENT = 5;
 
   /**
-   * Sentinal used by the inferrer to notify that it gave up finding a type
+   * Sentinel used by the inferrer to notify that it gave up finding a type
    * on a specific element.
    */
-  Element giveUpType;
+  final TypeMask giveUpType = new SentinelTypeMask('give up');
+  bool isGiveUpType(TypeMask type) => identical(type, giveUpType);
+
+  /**
+   * Sentinel used by the inferrer to notify that it does not know
+   * the type of a specific element.
+   */
+  final TypeMask dynamicType = new SentinelTypeMask('dynamic');
+  bool isDynamicType(TypeMask type) => identical(type, dynamicType);
+
+  TypeMask nullType;
+  TypeMask intType;
+  TypeMask doubleType;
+  TypeMask numType;
+  TypeMask boolType;
+  TypeMask functionType;
+  TypeMask listType;
+  TypeMask constListType;
+  TypeMask fixedListType;
+  TypeMask growableListType;
+  TypeMask mapType;
+  TypeMask constMapType;
+  TypeMask stringType;
+  TypeMask typeType;
 
   final Compiler compiler;
 
@@ -132,6 +191,17 @@
   // Number of re-analysis.
   int recompiles = 0;
 
+  /**
+   * Set to [true] when the analysis has analyzed all elements in the
+   * world.
+   */
+  bool hasAnalyzedAll = false;
+
+  /**
+   * The number of elements in the world.
+   */
+  int numberOfElementsToAnalyze;
+
   SimpleTypesInferrer(this.compiler);
 
   /**
@@ -139,10 +209,7 @@
    * resolver found as reachable. Returns whether it succeeded.
    */
   bool analyzeMain(Element element) {
-    // We use the given element as the sentinel. This is a temporary
-    // situation as long as this inferrer is using [ClassElement] for
-    // expressing types.
-    giveUpType = element;
+    initializeTypes();
     buildWorkQueue();
     int analyzed = 0;
     compiler.progress.reset();
@@ -164,13 +231,11 @@
       if (wasAnalyzed) {
         recomputeWatch.stop();
       }
+      checkAnalyzedAll();
       if (!changed) continue;
       // If something changed during the analysis of [element],
       // put back callers of it in the work list.
-      Set<Element> methodCallers = callersOf[element];
-      if (methodCallers != null) {
-        methodCallers.forEach(enqueueAgain);
-      }
+      enqueueCallersOf(element);
     } while (!workSet.isEmpty);
     dump();
     clear();
@@ -180,25 +245,32 @@
   /**
    * Query method after the analysis to know the type of [element].
    */
-  getConcreteTypeOfElement(element) {
+  TypeMask getReturnTypeOfElement(Element element) {
     return getTypeIfValuable(returnTypeOf[element]);
   }
 
-  getTypeIfValuable(returnType) {
-    if (returnType == null
-        || returnType == compiler.dynamicClass
-        || returnType == giveUpType) {
+  TypeMask getTypeOfElement(Element element) {
+    return getTypeIfValuable(typeOf[element]);
+  }
+
+  TypeMask getTypeOfSelector(Selector selector) {
+    return getTypeIfValuable(typeOfSelector(selector));
+  }
+
+  TypeMask getTypeIfValuable(TypeMask returnType) {
+    if (isDynamicType(returnType)
+        || isGiveUpType(returnType)
+        || returnType == nullType) {
       return null;
     }
-    return new ConcreteType.singleton(
-        compiler.maxConcreteTypeSize, new ClassBaseType(returnType));
+    return returnType;
   }
 
   /**
    * Query method after the analysis to know the type of [node],
    * defined in the context of [owner].
    */
-  getConcreteTypeOfNode(Element owner, Node node) {
+  TypeMask getTypeOfNode(Element owner, Node node) {
     var elements = compiler.enqueuer.resolution.resolvedElements[owner];
     // TODO(ngeoffray): Not sure why the resolver would put a null
     // mapping.
@@ -209,20 +281,34 @@
     if (selector == null || selector.isSetter() || selector.isIndexSet()) {
       return null;
     }
-    return getTypeIfValuable(returnTypeOfSelector(selector));
+    return getTypeIfValuable(typeOfSelector(selector));
+  }
+
+  void checkAnalyzedAll() {
+    if (hasAnalyzedAll) return;
+    if (analyzeCount.length != numberOfElementsToAnalyze) return;
+    hasAnalyzedAll = true;
+    // If we have analyzed all the world, we know all assigments to
+    // fields and can therefore infer a type for them.
+    typeOfFields.keys.forEach(updateNonFinalFieldType);
   }
 
   /**
    * Enqueues [e] in the work queue if it is valuable.
    */
   void enqueueAgain(Element e) {
-    Element returnType = returnTypeOf[e];
-    // If we have found a type for [e], no need to re-analyze it.
-    if (returnType != compiler.dynamicClass) return;
+    TypeMask type = e.isField() ? typeOf[e] : returnTypeOf[e];
     if (analyzeCount[e] > MAX_ANALYSIS_COUNT_PER_ELEMENT) return;
     workSet.add(e);
   }
 
+  void enqueueCallersOf(Element element) {
+    Set<Element> methodCallers = callersOf[element];
+    if (methodCallers != null) {
+      methodCallers.forEach(enqueueAgain);
+    }
+  }
+
   /**
    * Builds the initial work queue by adding all resolved elements in
    * the work queue, ordered by the number of selectors they use. This
@@ -244,7 +330,7 @@
             length, () => new Set<Element>());
         set.add(element);
     });
-    
+
     // This iteration assumes the [WorkSet] is LIFO.
     for (int i = max; i >= 0; i--) {
       Set<Element> set = methodSizes[i];
@@ -252,6 +338,7 @@
         set.forEach((e) { workSet.add(e); });
       }
     }
+    numberOfElementsToAnalyze = workSet.length;
 
     // Build the [classInfoForFinalFields] map by iterating over all
     // seen classes and counting the number of their generative
@@ -262,27 +349,81 @@
     compiler.enqueuer.resolution.seenClasses.forEach((ClassElement cls) {
       int constructorCount = 0;
       cls.forEachMember((_, member) {
-        if (member.isGenerativeConstructor()) constructorCount++;
+        if (member.isGenerativeConstructor()
+            && compiler.enqueuer.resolution.isProcessed(member)) {
+          constructorCount++;
+        }
       });
       classInfoForFinalFields[cls.implementation] =
           new ClassInfoForFinalFields(constructorCount);
     });
   }
 
+  // TODO(ngeoffray): Get rid of this method. Unit tests don't always
+  // ensure these classes are resolved.
+  rawTypeOf(ClassElement cls) {
+    cls.ensureResolved(compiler);
+    assert(cls.rawType != null);
+    return cls.rawType;
+  }
+
+  void initializeTypes() {
+    nullType = new TypeMask.empty();
+
+    Backend backend = compiler.backend;
+    intType = new TypeMask.nonNullExact(
+        rawTypeOf(backend.intImplementation));
+    doubleType = new TypeMask.nonNullExact(
+        rawTypeOf(backend.doubleImplementation));
+    numType = new TypeMask.nonNullSubclass(
+        rawTypeOf(backend.numImplementation));
+    stringType = new TypeMask.nonNullExact(
+        rawTypeOf(backend.stringImplementation));
+    boolType = new TypeMask.nonNullExact(
+        rawTypeOf(backend.boolImplementation));
+
+    listType = new TypeMask.nonNullExact(
+        rawTypeOf(backend.listImplementation));
+    constListType = new TypeMask.nonNullExact(
+        rawTypeOf(backend.constListImplementation));
+    fixedListType = new TypeMask.nonNullExact(
+        rawTypeOf(backend.fixedListImplementation));
+    growableListType = new TypeMask.nonNullExact(
+        rawTypeOf(backend.growableListImplementation));
+
+    mapType = new TypeMask.nonNullSubtype(
+        rawTypeOf(backend.mapImplementation));
+    constMapType = new TypeMask.nonNullSubtype(
+        rawTypeOf(backend.constMapImplementation));
+
+    functionType = new TypeMask.nonNullSubtype(
+        rawTypeOf(backend.functionImplementation));
+    typeType = new TypeMask.nonNullExact(
+        rawTypeOf(backend.typeImplementation));
+  }
+
   dump() {
     int interestingTypes = 0;
     int giveUpTypes = 0;
-    returnTypeOf.forEach((Element method, Element type) {
-      if (type == giveUpType) {
+    returnTypeOf.forEach((Element element, TypeMask type) {
+      if (isGiveUpType(type)) {
         giveUpTypes++;
-      } else if (type != compiler.nullClass && type != compiler.dynamicClass) {
+      } else if (type != nullType && !isDynamicType(type)) {
         interestingTypes++;
       }
     });
+    typeOf.forEach((Element element, TypeMask type) {
+      if (isGiveUpType(type)) {
+        giveUpTypes++;
+      } else if (type != nullType && !isDynamicType(type)) {
+        interestingTypes++;
+      }
+    });
+
     compiler.log('Type inferrer re-analyzed methods $recompiles times '
                  'in ${recomputeWatch.elapsedMilliseconds} ms.');
     compiler.log('Type inferrer found $interestingTypes interesting '
-                 'return types and gave up on $giveUpTypes methods.');
+                 'types and gave up on $giveUpTypes elements.');
   }
 
   /**
@@ -292,12 +433,13 @@
     callersOf.clear();
     analyzeCount.clear();
     classInfoForFinalFields.clear();
+    typeOfFields.clear();
   }
 
   bool analyze(Element element) {
     SimpleTypeInferrerVisitor visitor =
         new SimpleTypeInferrerVisitor(element, compiler, this);
-    Element returnType = visitor.run();
+    TypeMask returnType = visitor.run();
     if (analyzeCount.containsKey(element)) {
       analyzeCount[element]++;
     } else {
@@ -307,80 +449,152 @@
       // We always know the return type of a generative constructor.
       return false;
     } else if (element.isField()) {
+      Node node = element.parseNode(compiler);
       if (element.modifiers.isFinal() || element.modifiers.isConst()) {
-        if (element.parseNode(compiler).asSendSet() != null) {
-          // If [element] is final and has an initializer, we record
-          // the inferred type.
-          return recordReturnType(element, returnType);
+        // If [element] is final and has an initializer, we record
+        // the inferred type.
+        if (node.asSendSet() != null) {
+          return recordType(element, returnType);
         }
+        return false;
+      } else if (node.asSendSet() == null) {
+        // Only update types of static fields if there is no
+        // assignment. Instance fields are dealt with in the constructor.
+        if (Elements.isStaticOrTopLevelField(element)) {
+          recordNonFinalFieldElementType(node, element, returnType);
+        }
+        return false;
+      } else {
+        recordNonFinalFieldElementType(node, element, returnType);
+        // [recordNonFinalFieldElementType] takes care of re-enqueuing
+        // users of the field.
+        return false;
       }
-      // We don't record anything for non-final fields.
-      return false;
     } else {
       return recordReturnType(element, returnType);
     }
   }
 
+  bool recordType(Element analyzedElement, TypeMask type) {
+    return internalRecordType(analyzedElement, type, typeOf);
+  }
+
   /**
    * Records [returnType] as the return type of [analyzedElement].
    * Returns whether the new type is worth recompiling the callers of
    * [analyzedElement].
    */
-  bool recordReturnType(analyzedElement, returnType) {
-    assert(returnType != null);
-    Element existing = returnTypeOf[analyzedElement];
-    Element newType = existing == compiler.dynamicClass
-        ? returnType // Previous analysis did not find any type.
-        : computeLUB(existing, returnType);
-    returnTypeOf[analyzedElement] = newType;
+  bool recordReturnType(Element analyzedElement, TypeMask returnType) {
+    return internalRecordType(analyzedElement, returnType, returnTypeOf);
+  }
+
+  bool isNativeElement(Element element) {
+    if (element.isNative()) return true;
+    return element.isMember()
+        && element.getEnclosingClass().isNative()
+        && element.isField();
+  }
+
+  bool internalRecordType(Element analyzedElement,
+                          TypeMask newType,
+                          Map<Element, TypeMask> types) {
+    // Fields and native methods of native classes are handled
+    // specially when querying for their type or return type.
+    if (isNativeElement(analyzedElement)) return false;
+    assert(newType != null);
+    TypeMask existing = types[analyzedElement];
+    types[analyzedElement] = newType;
     // If the return type is useful, say it has changed.
     return existing != newType
-        && newType != compiler.dynamicClass
-        && newType != compiler.nullClass;
+        && !isDynamicType(newType)
+        && newType != nullType;
   }
 
   /**
-   * Returns the return type of [element]. Returns [:Dynamic:] if
+   * Returns the return type of [element]. Returns [:dynamic:] if
    * [element] has not been analyzed yet.
    */
-  ClassElement returnTypeOfElement(Element element) {
+  TypeMask returnTypeOfElement(Element element) {
     element = element.implementation;
-    if (element.isGenerativeConstructor()) return element.getEnclosingClass();
-    Element returnType = returnTypeOf[element];
-    if (returnType == null || returnType == giveUpType) {
-      return compiler.dynamicClass;
+    if (element.isGenerativeConstructor()) {
+      return returnTypeOf.putIfAbsent(element, () {
+        return new TypeMask.nonNullExact(
+            rawTypeOf(element.getEnclosingClass()));
+      });
+    } else if (element.isNative()) {
+      return returnTypeOf.putIfAbsent(element, () {
+        // Only functions are native.
+        FunctionType functionType = element.computeType(compiler);
+        DartType returnType = functionType.returnType;
+        return returnType.isVoid
+            ? nullType
+            : new TypeMask.subtype(returnType.asRaw());
+      });
+    }
+    TypeMask returnType = returnTypeOf[element];
+    if (returnType == null || isGiveUpType(returnType)) {
+      return dynamicType;
     }
     assert(returnType != null);
     return returnType;
   }
 
   /**
-   * Returns the union of the return types of all elements that match
+   * Returns the type of [element]. Returns [:dynamic:] if
+   * [element] has not been analyzed yet.
+   */
+  TypeMask typeOfElement(Element element) {
+    element = element.implementation;
+    if (isNativeElement(element) && element.isField()) {
+      return typeOf.putIfAbsent(element, () {
+        return new TypeMask.subtype(element.computeType(compiler).asRaw());
+      });
+    }
+    TypeMask type = typeOf[element];
+    if (type == null || isGiveUpType(type)) {
+      return dynamicType;
+    }
+    assert(type != null);
+    return type;
+  }
+
+  /**
+   * Returns the union of the types of all elements that match
    * the called [selector].
    */
-  ClassElement returnTypeOfSelector(Selector selector) {
-    ClassElement result;
+  TypeMask typeOfSelector(Selector selector) {
+    // Bailout for closure calls. We're not tracking types of
+    // closures.
+    if (selector.isClosureCall()) return dynamicType;
+
+    TypeMask result;
     iterateOverElements(selector, (Element element) {
       assert(element.isImplementation);
-      Element cls;
-      if (element.isFunction() && selector.isGetter()) {
-        cls = compiler.functionClass;
+      TypeMask type;
+      if (selector.isGetter()) {
+        if (element.isFunction()) {
+          type = functionType;
+        } else if (element.isField()) {
+          type = typeOf[element];
+        } else if (element.isGetter()) {
+          type = returnTypeOf[element];
+        }
       } else {
-        cls = returnTypeOf[element];
+        type = returnTypeOf[element];
       }
-      if (cls == null
-          || cls == compiler.dynamicClass
-          || cls == giveUpType
-          || (cls != result && result != null)) {
-        result = compiler.dynamicClass;
+      if (type == null
+          || isDynamicType(type)
+          || isGiveUpType(type)
+          || (type != result && result != null)) {
+        result = dynamicType;
         return false;
       } else {
-        result = cls;
+        result = type;
         return true;
       }
     });
     if (result == null) {
-      result = compiler.dynamicClass;
+      result = dynamicType;
     }
     return result;
   }
@@ -402,20 +616,10 @@
     assert(isNotClosure(caller));
     if (analyzeCount.containsKey(caller)) return;
     callee = callee.implementation;
-    Set<Element> callers = callersOf.putIfAbsent(
-        callee, () => new Set<Element>());
-    callers.add(caller);
+    addCaller(caller, callee);
   }
 
-  /**
-   * Registers that [caller] accesses [callee] through a property
-   * access.
-   */
-  void registerGetterOnElement(Element caller,
-                               Element callee) {
-    assert(isNotClosure(caller));
-    if (analyzeCount.containsKey(caller)) return;
-    callee = callee.implementation;
+  void addCaller(Element caller, Element callee) {
     Set<Element> callers = callersOf.putIfAbsent(
         callee, () => new Set<Element>());
     callers.add(caller);
@@ -432,25 +636,7 @@
     if (analyzeCount.containsKey(caller)) return;
     iterateOverElements(selector, (Element element) {
       assert(element.isImplementation);
-      Set<Element> callers = callersOf.putIfAbsent(
-          element, () => new Set<Element>());
-      callers.add(caller);
-      return true;
-    });
-  }
-
-  /**
-   * Registers that [caller] accesses an element matching [selector]
-   * through a property access.
-   */
-  void registerGetterOnSelector(Element caller, Selector selector) {
-    assert(isNotClosure(caller));
-    if (analyzeCount.containsKey(caller)) return;
-    iterateOverElements(selector, (Element element) {
-      assert(element.isImplementation);
-      Set<Element> callers = callersOf.putIfAbsent(
-          element, () => new Set<Element>());
-      callers.add(caller);
+      registerCalledElement(caller, element, arguments);
       return true;
     });
   }
@@ -479,10 +665,60 @@
   }
 
   /**
+   * Records an assignment to [selector] with the given
+   * [argumentType]. This method iterates over fields that match
+   * [selector] and update their type.
+   */
+  void recordNonFinalFieldSelectorType(Node node,
+                                       Selector selector,
+                                       TypeMask argumentType) {
+    iterateOverElements(selector, (Element element) {
+      if (element.isField()) {
+        recordNonFinalFieldElementType(node, element, argumentType);
+      }
+      return true;
+    });
+  }
+
+  /**
+   * Records an assignment to [element] with the given
+   * [argumentType].
+   */
+  void recordNonFinalFieldElementType(Node node,
+                                      Element element,
+                                      TypeMask argumentType) {
+    Map<Node, TypeMask> map =
+        typeOfFields.putIfAbsent(element, () => new Map<Node, TypeMask>());
+    map[node] = argumentType;
+    // If we have analyzed all elements, we can update the type of the
+    // field right away.
+    if (hasAnalyzedAll) updateNonFinalFieldType(element);
+  }
+
+  /**
+   * Computes the type of [element], based on all assignments we have
+   * collected on that [element]. This method can only be called after
+   * we have analyzed all elements in the world.
+   */
+  void updateNonFinalFieldType(Element element) {
+    assert(hasAnalyzedAll);
+
+    TypeMask fieldType;
+    typeOfFields[element].forEach((_, TypeMask mask) {
+      fieldType = computeLUB(fieldType, mask);
+    });
+
+    // If the type of [element] has changed, re-analyze its users.
+    if (recordType(element, fieldType)) {
+      enqueueCallersOf(element);
+    }
+  }
+
+  /**
    * Records in [classInfoForFinalFields] that [constructor] has
    * inferred [type] for the final [field].
    */
-  void recordFinalFieldType(Element constructor, Element field, Element type) {
+  void recordFinalFieldType(Element constructor, Element field, TypeMask type) {
     // If the field is being set at its declaration site, it is not
     // being tracked in the [classInfoForFinalFields] map.
     if (constructor == field) return;
@@ -502,23 +738,23 @@
     ClassInfoForFinalFields info = classInfoForFinalFields[cls.implementation];
     info.doneAnalyzingGenerativeConstructor(constructor);
     if (info.isDone) {
-      updateFieldTypes(info);
+      updateFinalFieldsType(info);
     }
   }
 
   /**
    * Updates types of final fields listed in [info].
    */
-  void updateFieldTypes(ClassInfoForFinalFields info) {
+  void updateFinalFieldsType(ClassInfoForFinalFields info) {
     assert(info.isDone);
     info.typesOfFinalFields.forEach((Element field,
-                                     Map<Element, Element> types) {
+                                     Map<Element, TypeMask> types) {
       assert(field.modifiers.isFinal());
-      Element fieldType;
-      types.forEach((_, type) {
+      TypeMask fieldType;
+      types.forEach((_, TypeMask type) {
         fieldType = computeLUB(fieldType, type);
       });
-      returnTypeOf[field] = fieldType;
+      recordType(field, fieldType);
     });
   }
 
@@ -526,31 +762,23 @@
    * Returns the least upper bound between [firstType] and
    * [secondType].
    */
-  Element computeLUB(Element firstType, Element secondType) {
-    bool isNumber(type) {
-      return type == compiler.numClass
-          || type == compiler.doubleClass
-          || type == compiler.intClass;
-    }
+  TypeMask computeLUB(TypeMask firstType, TypeMask secondType) {
     assert(secondType != null);
     if (firstType == null) {
       return secondType;
-    } else if (firstType == giveUpType) {
+    } else if (isGiveUpType(firstType)) {
       return firstType;
-    } else if (secondType == compiler.dynamicClass) {
+    } else if (isGiveUpType(secondType)) {
       return secondType;
-    } else if (firstType == compiler.dynamicClass) {
+    } else if (isDynamicType(secondType)) {
+      return secondType;
+    } else if (isDynamicType(firstType)) {
       return firstType;
-    } else if (firstType != secondType) {
-      if (isNumber(firstType) && isNumber(secondType)) {
-        // The JavaScript backend knows how to deal with numbers.
-        return compiler.numClass;
-      }
-      // TODO(ngeoffray): Actually compute the least upper bound.
-      return giveUpType;
     } else {
-      assert(firstType == secondType);
-      return firstType;
+      TypeMask union = firstType.union(secondType, compiler);
+      // TODO(kasperl): If the union isn't nullable it seems wasteful
+      // to give up. Fix that.
+      return union.containsAll(compiler) ? giveUpType : union;
     }
   }
 }
@@ -559,8 +787,8 @@
  * Placeholder for inferred arguments types on sends.
  */
 class ArgumentsTypes {
-  final List<Element> positional;
-  final Map<Identifier, Element> named;
+  final List<TypeMask> positional;
+  final Map<Identifier, TypeMask> named;
   ArgumentsTypes(this.positional, this.named);
   int get length => positional.length + named.length;
   toString() => "{ positional = $positional, named = $named }";
@@ -571,39 +799,52 @@
  */
 class LocalsHandler {
   final SimpleTypesInferrer inferrer;
-  final Map<Element, Element> locals;
-  final Set<Element> captured;
+  final Map<Element, TypeMask> locals;
+  final Set<Element> capturedAndBoxed;
+  final Map<Element, TypeMask> fieldsInitializedInConstructor;
   final bool inTryBlock;
+  bool isThisExposed;
+  bool seenReturn = false;
 
   LocalsHandler(this.inferrer)
-      : locals = new Map<Element, Element>(),
-        captured = new Set<Element>(),
-        inTryBlock = false;
+      : locals = new Map<Element, TypeMask>(),
+        capturedAndBoxed = new Set<Element>(),
+        fieldsInitializedInConstructor = new Map<Element, TypeMask>(),
+        inTryBlock = false,
+        isThisExposed = true;
   LocalsHandler.from(LocalsHandler other, {bool inTryBlock: false})
-      : locals = new Map<Element, Element>.from(other.locals),
-        captured = new Set<Element>.from(other.captured),
+      : locals = new Map<Element, TypeMask>.from(other.locals),
+        capturedAndBoxed = new Set<Element>.from(other.capturedAndBoxed),
+        fieldsInitializedInConstructor = new Map<Element, TypeMask>.from(
+            other.fieldsInitializedInConstructor),
         inTryBlock = other.inTryBlock || inTryBlock,
-        inferrer = other.inferrer;
+        inferrer = other.inferrer,
+        isThisExposed = other.isThisExposed;
 
-  Element use(Element local) {
+  TypeMask use(Element local) {
+    if (capturedAndBoxed.contains(local)) {
+      return inferrer.typeOfElement(local);
+    }
     return locals[local];
   }
 
-  void update(Element local, Element type) {
+  void update(Element local, TypeMask type) {
     assert(type != null);
-    if (captured.contains(local) || inTryBlock) {
-      // If a local is captured or is set in a try block, we compute the
-      // LUB of its assignments. We don't know if an assignment in a try block
-      // will be executed, so all assigments in a try block are
-      // potential types after we have left the try block.
+    if (capturedAndBoxed.contains(local) || inTryBlock) {
+      // If a local is captured and boxed, or is set in a try block,
+      // we compute the LUB of its assignments.
+      //
+      // We don't know if an assignment in a try block
+      // will be executed, so all assigments in that block are
+      // potential types after we have left it.
       type = inferrer.computeLUB(locals[local], type);
-      if (type == inferrer.giveUpType) type = inferrer.compiler.dynamicClass;
+      if (inferrer.isGiveUpType(type)) type = inferrer.dynamicType;
     }
     locals[local] = type;
   }
 
-  void setCaptured(Element local) {
-    captured.add(local);
+  void setCapturedAndBoxed(Element local) {
+    capturedAndBoxed.add(local);
   }
 
   /**
@@ -614,18 +855,21 @@
     bool changed = false;
     List<Element> toRemove = <Element>[];
     // Iterating over a map and just updating its entries is OK.
-    locals.forEach((local, oldType) {
-      Element otherType = other.locals[local];
+    locals.forEach((Element local, TypeMask oldType) {
+      TypeMask otherType = other.locals[local];
       if (otherType == null) {
-        // If [local] is not in the other map, we know it is not a
-        // local we want to keep. For example, in an if/else, we don't
-        // want to keep variables declared in the if or in the else
-        // branch at the merge point.
-        toRemove.add(local);
+        if (!capturedAndBoxed.contains(local)) {
+          // If [local] is not in the other map and is not captured
+          // and boxed, we know it is not a
+          // local we want to keep. For example, in an if/else, we don't
+          // want to keep variables declared in the if or in the else
+          // branch at the merge point.
+          toRemove.add(local);
+        }
         return;
       }
-      var type = inferrer.computeLUB(oldType, otherType);
-      if (type == inferrer.giveUpType) type = inferrer.compiler.dynamicClass;
+      TypeMask type = inferrer.computeLUB(oldType, otherType);
+      if (inferrer.isGiveUpType(type)) type = inferrer.dynamicType;
       if (type != oldType) changed = true;
       locals[local] = type;
     });
@@ -635,23 +879,63 @@
       locals.remove(element);
     });
 
-    // Update the locals that are captured.
-    other.captured.forEach((Element element) {
-      if (locals.containsKey(element)) {
-        captured.add(element);
+    // Update the locals that are captured and boxed. We
+    // unconditionally add them to [this] because we register the type
+    // of boxed variables after analyzing all closures.
+    other.capturedAndBoxed.forEach((Element element) {
+      capturedAndBoxed.add(element);
+      // If [element] is not in our [locals], we need to update it.
+      // Otherwise, we have already computed the LUB of it.
+      if (locals[element] == null) {
+        locals[element] = other.locals[element];
       }
     });
+
+    // Merge instance fields initialized in both handlers. This is
+    // only relevant for generative constructors.
+    toRemove = <Element>[];
+    // Iterate over the map in [:this:]. The map in [other] may
+    // contain different fields, but if this map does not contain it,
+    // then we know the field can be null and we don't need to track
+    // it.
+    fieldsInitializedInConstructor.forEach((Element element, TypeMask type) {
+      TypeMask otherType = other.fieldsInitializedInConstructor[element];
+      if (otherType == null) {
+        toRemove.add(element);
+      } else {
+        fieldsInitializedInConstructor[element] =
+            inferrer.computeLUB(type, otherType);
+      }
+    });
+    // Remove fields that were not initialized in [other].
+    toRemove.forEach((Element element) {
+      fieldsInitializedInConstructor.remove(element);
+    });
+    isThisExposed = isThisExposed || other.isThisExposed;
+    seenReturn = seenReturn && other.seenReturn;
+
     return changed;
   }
+
+  void updateField(Element element, TypeMask type) {
+    if (isThisExposed) return;
+    fieldsInitializedInConstructor[element] = type;
+  }
 }
 
-class SimpleTypeInferrerVisitor extends ResolvedVisitor {
+class SimpleTypeInferrerVisitor extends ResolvedVisitor<TypeMask> {
   final Element analyzedElement;
   final Element outermostElement;
   final SimpleTypesInferrer inferrer;
   final Compiler compiler;
   LocalsHandler locals;
-  Element returnType;
+  TypeMask returnType;
+
+  bool visitingInitializers = false;
+  bool isConstructorRedirect = false;
+
+  bool get isThisExposed => locals.isThisExposed;
+  void set isThisExposed(value) { locals.isThisExposed = value; }
 
   SimpleTypeInferrerVisitor.internal(TreeElements mapping,
                                      this.analyzedElement,
@@ -676,294 +960,554 @@
         elements, element, outermostElement, inferrer, compiler, handler);
   }
 
-  Element run() {
-    var node = analyzedElement.implementation.parseNode(compiler);
+  TypeMask run() {
+    var node = analyzedElement.parseNode(compiler);
+    if (analyzedElement.isField() && node.asSendSet() == null) {
+      // Eagerly bailout, because computing the closure data only
+      // works for functions and field assignments.
+      return inferrer.nullType;
+    }
+    // Update the locals that are boxed in [locals]. These locals will
+    // be handled specially, in that we are computing their LUB at
+    // each update, and reading them yields the type that was found in a
+    // previous analysis ouf [outermostElement].
+    ClosureClassMap closureData =
+        compiler.closureToClassMapper.computeClosureToClassMapping(
+            analyzedElement, node, elements);
+    ClosureScope scopeData = closureData.capturingScopes[node];
+    if (scopeData != null) {
+      scopeData.capturedVariableMapping.forEach((Element variable, _) {
+        locals.setCapturedAndBoxed(variable);
+      });
+    }
     if (analyzedElement.isField()) {
-      returnType = visit(node);
+      returnType = visit(node.asSendSet().arguments.head);
     } else if (analyzedElement.isGenerativeConstructor()) {
       FunctionElement function = analyzedElement;
       FunctionSignature signature = function.computeSignature(compiler);
       signature.forEachParameter((element) {
         // We don't track argument types yet, so just set the fields
         // and parameters as dynamic.
-        if (element.kind == ElementKind.FIELD_PARAMETER
-            && element.modifiers.isFinal()) {
-          inferrer.recordFinalFieldType(
-              analyzedElement, element.fieldElement, compiler.dynamicClass);
+        if (element.kind == ElementKind.FIELD_PARAMETER) {
+          if (element.fieldElement.modifiers.isFinal()) {
+            inferrer.recordFinalFieldType(
+                analyzedElement, element.fieldElement, inferrer.dynamicType);
+          } else {
+            inferrer.recordNonFinalFieldElementType(
+                element.parseNode(compiler),
+                element.fieldElement,
+                inferrer.dynamicType);
+          }
         } else {
-          locals.update(element, compiler.dynamicClass);
+          locals.update(element, inferrer.dynamicType);
         }
       });
+      visitingInitializers = true;
+      isThisExposed = false;
       visit(node.initializers);
+      visitingInitializers = false;
       visit(node.body);
+      ClassElement cls = analyzedElement.getEnclosingClass();
+      if (!isConstructorRedirect) {
+        // Iterate over all instance fields, and give a null type to
+        // fields that we haven't initialized for sure.
+        cls.forEachInstanceField((_, field) {
+          if (field.modifiers.isFinal()) return;
+          TypeMask type = locals.fieldsInitializedInConstructor[field];
+          if (type == null && field.parseNode(compiler).asSendSet() == null) {
+            inferrer.recordNonFinalFieldElementType(
+                node, field, inferrer.nullType);
+          }
+        });
+      }
       inferrer.doneAnalyzingGenerativeConstructor(analyzedElement);
-      returnType = analyzedElement.getEnclosingClass();
+      returnType = new TypeMask.nonNullExact(inferrer.rawTypeOf(cls));
     } else if (analyzedElement.isNative()) {
       // Native methods do not have a body, and we currently just say
       // they return dynamic.
-      returnType = compiler.dynamicClass;
+      returnType = inferrer.dynamicType;
     } else {
       FunctionElement function = analyzedElement;
       FunctionSignature signature = function.computeSignature(compiler);
       signature.forEachParameter((element) {
         // We don't track argument types yet, so just set the
         // parameters as dynamic.
-        locals.update(element, compiler.dynamicClass);
+        locals.update(element, inferrer.dynamicType);
       });
       visit(node.body);
       if (returnType == null) {
         // No return in the body.
-        returnType = compiler.nullClass;
+        returnType = inferrer.nullType;
+      } else if (!locals.seenReturn) {
+        // We haven't seen returns on all branches. So the method may
+        // also return null.
+        returnType = returnType.nullable();
       }
     }
+
+    if (analyzedElement == outermostElement) {
+      bool changed = false;
+      locals.capturedAndBoxed.forEach((Element local) {
+        if (inferrer.recordType(local, locals.locals[local])) {
+          changed = true;
+        }
+      });
+      // TODO(ngeoffray): Re-analyze method if [changed]?
+    }
+
     return returnType;
   }
 
-  recordReturnType(ClassElement cls) {
-    returnType = inferrer.computeLUB(returnType, cls);
+  TypeMask _thisType;
+  TypeMask get thisType {
+    if (_thisType != null) return _thisType;
+    ClassElement cls = outermostElement.getEnclosingClass();
+    if (compiler.world.isUsedAsMixin(cls)) {
+      return _thisType = new TypeMask.nonNullSubtype(inferrer.rawTypeOf(cls));
+    } else if (compiler.world.hasAnySubclass(cls)) {
+      return _thisType = new TypeMask.nonNullSubclass(inferrer.rawTypeOf(cls));
+    } else {
+      return _thisType = new TypeMask.nonNullExact(inferrer.rawTypeOf(cls));
+    }
   }
 
-  visitNode(Node node) {
+  TypeMask _superType;
+  TypeMask get superType {
+    if (_superType != null) return _superType;
+    return _superType = new TypeMask.nonNullExact(
+        inferrer.rawTypeOf(outermostElement.getEnclosingClass().superclass));
+  }
+
+  void recordReturnType(TypeMask type) {
+    returnType = inferrer.computeLUB(returnType, type);
+  }
+
+  TypeMask visitNode(Node node) {
     node.visitChildren(this);
-    return compiler.dynamicClass;
+    return inferrer.dynamicType;
   }
 
-  visitNewExpression(NewExpression node) {
+  TypeMask visitNewExpression(NewExpression node) {
     return node.send.accept(this);
   }
 
-  visit(Node node) {
-    return node == null ? compiler.dynamicClass : node.accept(this);
+  TypeMask visit(Node node) {
+    return node == null ? inferrer.dynamicType : node.accept(this);
   }
 
-  visitFunctionExpression(FunctionExpression node) {
-    // Fetch the closure data of [node] and mark all locals that are
-    // captured by [node] to be captured in the locals handler.
-    compiler.closureToClassMapper.computeClosureToClassMapping(
-        outermostElement, outermostElement.parseNode(compiler), elements);
-    ClosureClassMap nestedClosureData =
-        compiler.closureToClassMapper.getMappingForNestedFunction(node);
-
-    nestedClosureData.forEachCapturedVariable((variable) {
-      locals.setCaptured(variable);
-    });
+  TypeMask visitFunctionExpression(FunctionExpression node) {
+    Element element = elements[node];
     // We don't put the closure in the work queue of the
     // inferrer, because it will share information with its enclosing
     // method, like for example the types of local variables.
     LocalsHandler closureLocals = new LocalsHandler.from(locals);
     SimpleTypeInferrerVisitor visitor = new SimpleTypeInferrerVisitor(
-        elements[node], compiler, inferrer, closureLocals);
+        element, compiler, inferrer, closureLocals);
     visitor.run();
-    // Do not register the runtime type, because the analysis may be
-    // invalidated due to updates on locals.
-    // TODO(ngeoffray): Track return types of closures.
-    // The closure may have updated the type of locals.
-    locals.merge(closureLocals);
-    return compiler.functionClass;
+    inferrer.recordReturnType(element, visitor.returnType);
+    locals.merge(visitor.locals);
+
+    // Record the types of captured non-boxed variables. Types of
+    // these variables may already be there, because of an analysis of
+    // a previous closure. Note that analyzing the same closure multiple
+    // times closure will refine the type of those variables, therefore
+    // [:inferrer.typeOf[variable]:] is not necessarilly null, nor the
+    // same as [newType].
+    ClosureClassMap nestedClosureData =
+        compiler.closureToClassMapper.getMappingForNestedFunction(node);
+    nestedClosureData.forEachNonBoxedCapturedVariable((Element variable) {
+      // The type may be null for instance contexts (this and type
+      // parameters), as well as captured argument checks.
+      if (locals.locals[variable] == null) return;
+      inferrer.recordType(variable, locals.locals[variable]);
+      assert(!inferrer.isGiveUpType(inferrer.typeOf[variable]));
+    });
+
+    return inferrer.functionType;
   }
 
-  visitFunctionDeclaration(FunctionDeclaration node) {
-    locals.update(elements[node], compiler.functionClass);
+  TypeMask visitFunctionDeclaration(FunctionDeclaration node) {
+    locals.update(elements[node], inferrer.functionType);
     return visit(node.function);
   }
 
-
-  visitLiteralString(LiteralString node) {
-    return compiler.stringClass;
+  TypeMask visitLiteralString(LiteralString node) {
+    return inferrer.stringType;
   }
 
-  visitStringInterpolation(StringInterpolation node) {
-    return compiler.stringClass;
+  TypeMask visitStringInterpolation(StringInterpolation node) {
+    node.visitChildren(this);
+    return inferrer.stringType;
   }
 
-  visitStringJuxtaposition(StringJuxtaposition node) {
-    return compiler.stringClass;
+  TypeMask visitStringJuxtaposition(StringJuxtaposition node) {
+    node.visitChildren(this);
+    return inferrer.stringType;
   }
 
-  visitLiteralBool(LiteralBool node) {
-    return compiler.boolClass;
+  TypeMask visitLiteralBool(LiteralBool node) {
+    return inferrer.boolType;
   }
 
-  visitLiteralDouble(LiteralDouble node) {
-    return compiler.doubleClass;
+  TypeMask visitLiteralDouble(LiteralDouble node) {
+    return inferrer.doubleType;
   }
 
-  visitLiteralInt(LiteralInt node) {
-    return compiler.intClass;
+  TypeMask visitLiteralInt(LiteralInt node) {
+    return inferrer.intType;
   }
 
-  visitLiteralList(LiteralList node) {
-    return compiler.listClass;
+  TypeMask visitLiteralList(LiteralList node) {
+    node.visitChildren(this);
+    return node.isConst()
+        ? inferrer.constListType
+        : inferrer.growableListType;
   }
 
-  visitLiteralMap(LiteralMap node) {
-    return compiler.mapClass;
+  TypeMask visitLiteralMap(LiteralMap node) {
+    node.visitChildren(this);
+    return node.isConst()
+        ? inferrer.constMapType
+        : inferrer.mapType;
   }
 
-  visitLiteralNull(LiteralNull node) {
-    return compiler.nullClass;
+  TypeMask visitLiteralNull(LiteralNull node) {
+    return inferrer.nullType;
   }
 
-  visitTypeReferenceSend(Send node) {
-    return compiler.typeClass;
+  TypeMask visitTypeReferenceSend(Send node) {
+    return inferrer.typeType;
   }
 
-  visitSendSet(SendSet node) {
+  bool isThisOrSuper(Node node) => node.isThis() || node.isSuper();
+
+  void checkIfExposesThis(Selector selector) {
+    if (isThisExposed) return;
+    inferrer.iterateOverElements(selector, (element) {
+      if (element.isField()) {
+        if (!selector.isSetter()
+            && element.getEnclosingClass() ==
+                    outermostElement.getEnclosingClass()
+            && !element.modifiers.isFinal()
+            && locals.fieldsInitializedInConstructor[element] == null
+            && element.parseNode(compiler).asSendSet() == null) {
+          // If the field is being used before this constructor
+          // actually had a chance to initialize it, say it can be
+          // null.
+          inferrer.recordNonFinalFieldElementType(
+              analyzedElement.parseNode(compiler), element, inferrer.nullType);
+        }
+        // Accessing a field does not expose [:this:].
+        return true;
+      }
+      // TODO(ngeoffray): We could do better here if we knew what we
+      // are calling does not expose this.
+      isThisExposed = true;
+      return false;
+    });
+  }
+
+  TypeMask visitSendSet(SendSet node) {
     Element element = elements[node];
     if (!Elements.isUnresolved(element) && element.impliesType()) {
       node.visitChildren(this);
-      return compiler.dynamicClass;
+      return inferrer.dynamicType;
     }
 
-    Operator op = node.assignmentOperator;
-    if (node.isSuperCall) {
-      // [: super.foo = 42 :] or [: super.foo++ :] or [: super.foo += 1 :].
-      node.visitChildren(this);
-      return compiler.dynamicClass;
+    Selector getterSelector =
+        elements.getGetterSelectorInComplexSendSet(node);
+    Selector operatorSelector =
+        elements.getOperatorSelectorInComplexSendSet(node);
+    Selector setterSelector = elements.getSelector(node);
+
+    String op = node.assignmentOperator.source.stringValue;
+    bool isIncrementOrDecrement = op == '++' || op == '--';
+
+    TypeMask receiverType;
+    bool isCallOnThis = false;
+    if (node.receiver == null
+        && element != null
+        && element.isInstanceMember()) {
+      receiverType = thisType;
+      isCallOnThis = true;
+    } else {
+      receiverType = visit(node.receiver);
+      isCallOnThis = node.receiver != null && isThisOrSuper(node.receiver);
+    }
+
+    TypeMask rhsType;
+    TypeMask indexType;
+
+    if (isIncrementOrDecrement) {
+      rhsType = inferrer.intType;
+      if (node.isIndex) indexType = visit(node.arguments.head);
     } else if (node.isIndex) {
-      if (const SourceString("=") == op.source) {
-        // [: foo[0] = 42 :]
-        visit(node.receiver);
-        Element returnType;
-        for (Node argument in node.arguments) {
-          returnType = argument.accept(this);
+      indexType = visit(node.arguments.head);
+      rhsType = visit(node.arguments.tail.head);
+    } else {
+      rhsType = visit(node.arguments.head);
+    }
+
+    if (!visitingInitializers && !isThisExposed) {
+      for (Node node in node.arguments) {
+        if (isThisOrSuper(node)) {
+          isThisExposed = true;
+          break;
         }
-        return returnType;
+      }
+      if (!isThisExposed && isCallOnThis) {
+        checkIfExposesThis(new TypedSelector(receiverType, setterSelector));
+      }
+    }
+
+    if (node.isIndex) {
+      if (op == '=') {
+        // [: foo[0] = 42 :]
+        handleDynamicSend(
+            node,
+            setterSelector,
+            receiverType,
+            new ArgumentsTypes([indexType, rhsType], null));
+        return rhsType;
       } else {
         // [: foo[0] += 42 :] or [: foo[0]++ :].
-        node.visitChildren(this);
-        return compiler.dynamicClass;
-      }
-    } else if (const SourceString("=") == op.source) {
-      // [: foo = 42 :] or [: foo.bar = 42 :].
-      if (element == null) {
-        visit(node.receiver);
-      }
-      Link<Node> link = node.arguments;
-      assert(!link.isEmpty && link.tail.isEmpty);
-      Element type = link.head.accept(this);
+        TypeMask getterType = handleDynamicSend(
+            node,
+            getterSelector,
+            receiverType,
+            new ArgumentsTypes([indexType], null));
+        TypeMask returnType = handleDynamicSend(
+            node,
+            operatorSelector,
+            getterType,
+            new ArgumentsTypes([rhsType], null));
+        handleDynamicSend(
+            node,
+            setterSelector,
+            receiverType,
+            new ArgumentsTypes([indexType, returnType], null));
 
-      if (!Elements.isUnresolved(element)) {
-        if (element.isField() && element.modifiers.isFinal()) {
-          inferrer.recordFinalFieldType(outermostElement, element, type);
-        } else if (element.isVariable()) {
-          locals.update(element, type);
+        if (node.isPostfix) {
+          return getterType;
+        } else {
+          return returnType;
         }
       }
-      return type;
+    } else if (op == '=') {
+      // [: foo = 42 :] or [: foo.bar = 42 :].
+      ArgumentsTypes arguments =  new ArgumentsTypes([rhsType], null);
+      if (Elements.isStaticOrTopLevelField(element)) {
+        if (element.isSetter()) {
+          inferrer.registerCalledElement(outermostElement, element, arguments);
+        } else {
+          assert(element.isField());
+          inferrer.recordNonFinalFieldElementType(node, element, rhsType);
+        }
+      } else if (Elements.isUnresolved(element) || element.isSetter()) {
+        handleDynamicSend(node, setterSelector, receiverType, arguments);
+      } else if (element.isField()) {
+        if (element.modifiers.isFinal()) {
+          inferrer.recordFinalFieldType(outermostElement, element, rhsType);
+        } else {
+          locals.updateField(element, rhsType);
+          if (visitingInitializers) {
+            inferrer.recordNonFinalFieldElementType(node, element, rhsType);
+          } else {
+            handleDynamicSend(node, setterSelector, receiverType, arguments);
+          }
+        }
+      } else if (Elements.isLocal(element)) {
+        locals.update(element, rhsType);
+      }
+      return rhsType;
     } else {
       // [: foo++ :] or [: foo += 1 :].
-      assert(const SourceString("++") == op.source ||
-             const SourceString("--") == op.source ||
-             node.assignmentOperator.source.stringValue.endsWith("="));
-      node.visitChildren(this);
-      return compiler.dynamicClass;
+      TypeMask getterType;
+      TypeMask newType;
+      ArgumentsTypes operatorArguments = new ArgumentsTypes([rhsType], null);
+      if (Elements.isStaticOrTopLevelField(element)) {
+        Element getterElement = elements[node.selector];
+        getterType = getterElement.isField()
+            ? inferrer.typeOfElement(element)
+            : inferrer.returnTypeOfElement(element);
+        if (getterElement.isGetter()) {
+          inferrer.registerCalledElement(outermostElement, getterElement, null);
+        }
+        newType = handleDynamicSend(
+            node, operatorSelector, getterType, operatorArguments);
+        if (element.isField()) {
+          inferrer.recordNonFinalFieldElementType(node, element, newType);
+        } else {
+          assert(element.isSetter());
+          inferrer.registerCalledElement(
+              outermostElement, element, new ArgumentsTypes([newType], null));
+        }
+      } else if (Elements.isUnresolved(element) || element.isSetter()) {
+        getterType = handleDynamicSend(
+            node, getterSelector, receiverType, null);
+        newType = handleDynamicSend(
+            node, operatorSelector, getterType, operatorArguments);
+        handleDynamicSend(node, setterSelector, receiverType,
+                          new ArgumentsTypes([newType], null));
+      } else if (element.isField()) {
+        assert(!element.modifiers.isFinal());
+        getterType = inferrer.dynamicType; // The type of the field.
+        newType = handleDynamicSend(
+            node, operatorSelector, getterType, operatorArguments);
+        handleDynamicSend(node, setterSelector, receiverType,
+                          new ArgumentsTypes([newType], null));
+      } else if (Elements.isLocal(element)) {
+        getterType = locals.use(element);
+        newType = handleDynamicSend(
+            node, operatorSelector, getterType, operatorArguments);
+        locals.update(element, newType);
+      } else {
+        // Bogus SendSet, for example [: myMethod += 42 :].
+        getterType = inferrer.dynamicType;
+        newType = handleDynamicSend(
+            node, operatorSelector, getterType, operatorArguments);
+      }
+
+      if (node.isPostfix) {
+        return getterType;
+      } else {
+        return newType;
+      }
     }
   }
 
-  visitIdentifier(Identifier node) {
-    if (node.isThis() || node.isSuper()) {
-      // TODO(ngeoffray): Represent subclasses.
-      return compiler.dynamicClass;
+  TypeMask visitIdentifier(Identifier node) {
+    if (node.isThis()) {
+      return thisType;
+    } else if (node.isSuper()) {
+      return superType;
     }
-    return compiler.dynamicClass;
+    return inferrer.dynamicType;
   }
 
-  visitSuperSend(Send node) {
+  TypeMask visitSuperSend(Send node) {
     Element element = elements[node];
     if (Elements.isUnresolved(element)) {
-      return compiler.dynamicClass;
+      return inferrer.dynamicType;
     }
     Selector selector = elements.getSelector(node);
+    // TODO(ngeoffray): We could do better here if we knew what we
+    // are calling does not expose this.
+    isThisExposed = true;
     if (node.isPropertyAccess) {
-      inferrer.registerGetterOnElement(outermostElement, element);
-      return inferrer.returnTypeOfElement(element);
+      inferrer.registerCalledElement(outermostElement, element, null);
+      return inferrer.typeOfElement(element);
     } else if (element.isFunction()) {
       ArgumentsTypes arguments = analyzeArguments(node.arguments);
       inferrer.registerCalledElement(outermostElement, element, arguments);
       return inferrer.returnTypeOfElement(element);
     } else {
+      analyzeArguments(node.arguments);
       // Closure call on a getter. We don't have function types yet,
-      // so we just return [:Dynamic:].
-      return compiler.dynamicClass;
+      // so we just return [:dynamic:].
+      return inferrer.dynamicType;
     }
   }
 
-  visitStaticSend(Send node) {
-    Element element = elements[node];
-    if (Elements.isUnresolved(element)) {
-      return compiler.dynamicClass;
+  TypeMask visitStaticSend(Send node) {
+    if (visitingInitializers && Initializers.isConstructorRedirect(node)) {
+      isConstructorRedirect = true;
     }
+    Element element = elements[node];
     if (element.isForeign(compiler)) {
       return handleForeignSend(node);
     }
     ArgumentsTypes arguments = analyzeArguments(node.arguments);
+    if (Elements.isUnresolved(element)
+        || element.isGetter()
+        || element.isField()) {
+      if (element.isGetter()) {
+        inferrer.registerCalledElement(outermostElement, element, null);
+      }
+      return inferrer.dynamicType;
+    }
+
+    Selector selector = elements.getSelector(node);
     inferrer.registerCalledElement(outermostElement, element, arguments);
-    return inferrer.returnTypeOfElement(element);
+    if (Elements.isGrowableListConstructorCall(element, node, compiler)) {
+      return inferrer.growableListType;
+    } else if (Elements.isFixedListConstructorCall(element, node, compiler)) {
+      return inferrer.fixedListType;
+    } else {
+      return inferrer.returnTypeOfElement(element);
+    }
   }
 
-  handleForeignSend(Send node) {
+  TypeMask handleForeignSend(Send node) {
     node.visitChildren(this);
     Selector selector = elements.getSelector(node);
     SourceString name = selector.name;
     if (name == const SourceString('JS')) {
       native.NativeBehavior nativeBehavior =
           compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node);
-      if (nativeBehavior == null) return compiler.dynamicClass;
+      if (nativeBehavior == null) return inferrer.dynamicType;
       List typesReturned = nativeBehavior.typesReturned;
-      if (typesReturned.isEmpty) return compiler.dynamicClass;
-      ClassElement returnType;
+      if (typesReturned.isEmpty) return inferrer.dynamicType;
+      TypeMask returnType;
       for (var type in typesReturned) {
-        ClassElement mappedType;
+        TypeMask mappedType;
         if (type == native.SpecialType.JsObject) {
-          mappedType = compiler.objectClass;
+          mappedType = new TypeMask.nonNullExact(
+              inferrer.rawTypeOf(compiler.objectClass));
         } else if (type == native.SpecialType.JsArray) {
-          mappedType = compiler.listClass;
+          mappedType = inferrer.listType;
+        } else if (type.element == compiler.stringClass) {
+          mappedType = inferrer.stringType;
+        } else if (type.element == compiler.intClass) {
+          mappedType = inferrer.intType;
+        } else if (type.element == compiler.doubleClass) {
+          mappedType = inferrer.doubleType;
+        } else if (type.element == compiler.numClass) {
+          mappedType = inferrer.numType;
+        } else if (type.element == compiler.boolClass) {
+          mappedType = inferrer.boolType;
+        } else if (type.element == compiler.nullClass) {
+          mappedType = inferrer.nullType;
+        } else if (compiler.world.hasAnySubclass(type.element)) {
+          mappedType = new TypeMask.nonNullSubclass(
+              inferrer.rawTypeOf(type.element));
+        } else if (compiler.world.hasAnySubtype(type.element)) {
+          mappedType = new TypeMask.nonNullSubtype(
+              inferrer.rawTypeOf(type.element));
         } else {
-          mappedType = type.element;
-          // For primitive types, we know how to handle them here and
-          // in the backend.
-          if (mappedType != compiler.stringClass
-              && mappedType != compiler.intClass
-              && mappedType != compiler.doubleClass
-              && mappedType != compiler.boolClass
-              && mappedType != compiler.numClass) {
-            Set<ClassElement> subtypes = compiler.world.subtypes[mappedType];
-            // TODO(ngeoffray): Handle subtypes and subclasses.
-            if (subtypes != null && !subtypes.isEmpty) {
-              return compiler.dynamicClass;
-            }
-          }
+          mappedType = new TypeMask.nonNullExact(
+              inferrer.rawTypeOf(type.element));
         }
-        if (returnType == null) {
-          returnType = mappedType;
-        } else {
-          return compiler.dynamicClass;
-        }
+        returnType = inferrer.computeLUB(returnType, mappedType);
       }
       return returnType;
-    } else if (name == const SourceString('JS_OPERATOR_IS_PREFIX')) {
-      return compiler.stringClass;
+    } else if (name == const SourceString('JS_OPERATOR_IS_PREFIX')
+               || name == const SourceString('JS_OPERATOR_AS_PREFIX')) {
+      return inferrer.stringType;
     } else {
-      return compiler.dynamicClass;
+      return inferrer.dynamicType;
     }
   }
 
-  analyzeArguments(Link<Node> arguments) {
-    List<ClassElement> positional = [];
-    Map<Identifier, ClassElement> named = new Map<Identifier, ClassElement>();
-    for (Node argument in arguments) {
+  ArgumentsTypes analyzeArguments(Link<Node> arguments) {
+    List<TypeMask> positional = [];
+    Map<Identifier, TypeMask> named = new Map<Identifier, TypeMask>();
+    for (var argument in arguments) {
       NamedArgument namedArgument = argument.asNamedArgument();
       if (namedArgument != null) {
-        named[namedArgument.name] = namedArgument.expression.accept(this);
+        argument = namedArgument.expression;
+        named[namedArgument.name] = argument.accept(this);
       } else {
         positional.add(argument.accept(this));
       }
+      // TODO(ngeoffray): We could do better here if we knew what we
+      // are calling does not expose this.
+      isThisExposed = isThisExposed || argument.isThis();
     }
     return new ArgumentsTypes(positional, named);
   }
 
-  visitOperatorSend(Send node) {
+  TypeMask visitOperatorSend(Send node) {
     Operator op = node.selector;
     if (const SourceString("[]") == op.source) {
       return visitDynamicSend(node);
@@ -974,26 +1518,26 @@
       visit(node.arguments.head);
       saved.merge(locals);
       locals = saved;
-      return compiler.boolClass;
+      return inferrer.boolType;
     } else if (const SourceString("!") == op.source) {
       node.visitChildren(this);
-      return compiler.boolClass;
+      return inferrer.boolType;
     } else if (const SourceString("is") == op.source) {
       node.visitChildren(this);
-      return compiler.boolClass;
+      return inferrer.boolType;
     } else if (const SourceString("as") == op.source) {
       node.visitChildren(this);
-      return compiler.dynamicClass;
+      return inferrer.dynamicType;
     } else if (node.isParameterCheck) {
       node.visitChildren(this);
-      return compiler.boolClass;
+      return inferrer.boolType;
     } else if (node.argumentsNode is Prefix) {
       // Unary operator.
       return visitDynamicSend(node);
     } else if (const SourceString('===') == op.source
                || const SourceString('!==') == op.source) {
       node.visitChildren(this);
-      return compiler.boolClass;
+      return inferrer.boolType;
     } else {
       // Binary operator.
       return visitDynamicSend(node);
@@ -1006,88 +1550,134 @@
   // to avoid confusing the [ResolvedVisitor].
   visitTypeAnnotation(TypeAnnotation node) {}
 
-  visitGetterSend(Send node) {
+  TypeMask visitGetterSend(Send node) {
     Element element = elements[node];
     if (Elements.isStaticOrTopLevelField(element)) {
-      inferrer.registerGetterOnElement(outermostElement, element);
-      return inferrer.returnTypeOfElement(element);
+      inferrer.registerCalledElement(outermostElement, element, null);
+      return inferrer.typeOfElement(element);
     } else if (Elements.isInstanceSend(node, elements)) {
-      ClassElement receiverType;
-      if (node.receiver == null) {
-        receiverType = outermostElement.getEnclosingClass();
-      } else {
-        receiverType = node.receiver.accept(this);
-      }
-      Selector selector = elements.getSelector(node);
-      inferrer.registerGetterOnSelector(outermostElement, selector);
-      return inferrer.returnTypeOfSelector(selector);
+      return visitDynamicSend(node);
     } else if (Elements.isStaticOrTopLevelFunction(element)) {
       inferrer.registerGetFunction(outermostElement, element);
-      return compiler.functionClass;
+      return inferrer.functionType;
     } else if (Elements.isErroneousElement(element)) {
-      return compiler.dynamicClass;
+      return inferrer.dynamicType;
     } else if (Elements.isLocal(element)) {
       assert(locals.use(element) != null);
       return locals.use(element);
     } else {
       node.visitChildren(this);
-      return compiler.dynamicClass;
+      return inferrer.dynamicType;
     }
   }
 
-  visitClosureSend(Send node) {
+  TypeMask visitClosureSend(Send node) {
     node.visitChildren(this);
-    return compiler.dynamicClass;
-  }
-
-  visitDynamicSend(Send node) {
-    ClassElement receiverType;
-    if (node.receiver == null) {
-      receiverType = outermostElement.getEnclosingClass();
-    } else {
-      receiverType = node.receiver.accept(this);
+    Element element = elements[node];
+    if (element != null && element.isFunction()) {
+      assert(Elements.isLocal(element));
+      // This only works for function statements. We need a
+      // more sophisticated type system with function types to support
+      // more.
+      return inferrer.returnTypeOfElement(element);
     }
-    ArgumentsTypes arguments = analyzeArguments(node.arguments);
-    Selector selector = elements.getSelector(node);
+    return inferrer.dynamicType;
+  }
+
+  TypeMask handleDynamicSend(Node node,
+                             Selector selector,
+                             TypeMask receiver,
+                             ArgumentsTypes arguments) {
+    if (!inferrer.isDynamicType(receiver)) {
+      selector = new TypedSelector(receiver, selector);
+    }
     inferrer.registerCalledSelector(outermostElement, selector, arguments);
-    return inferrer.returnTypeOfSelector(selector);
+    if (selector.isSetter()) {
+      inferrer.recordNonFinalFieldSelectorType(
+          node, selector, arguments.positional[0]);
+      // We return null to prevent using a type for a called setter.
+      // The return type is the right hand side of the setter.
+      return null;
+    }
+    return inferrer.typeOfSelector(selector);
   }
 
-  visitReturn(Return node) {
-    Node expression = node.expression;
-    recordReturnType(expression == null
-        ? compiler.nullClass
-        : expression.accept(this));
+  TypeMask visitDynamicSend(Send node) {
+    Element element = elements[node];
+    TypeMask receiverType;
+    bool isCallOnThis = false;
+    if (node.receiver == null) {
+      isCallOnThis = true;
+      receiverType = thisType;
+    } else {
+      Node receiver = node.receiver;
+      isCallOnThis = isThisOrSuper(receiver);
+      receiverType = visit(receiver);
+    }
+
+    Selector selector = elements.getSelector(node);
+    if (!isThisExposed && isCallOnThis) {
+      checkIfExposesThis(new TypedSelector(receiverType, selector));
+    }
+
+    ArgumentsTypes arguments = node.isPropertyAccess
+        ? null
+        : analyzeArguments(node.arguments);
+    return handleDynamicSend(node, selector, receiverType, arguments);
   }
 
-  visitConditional(Conditional node) {
+  TypeMask visitReturn(Return node) {
+    if (node.isRedirectingFactoryBody) {
+      Element element = elements[node.expression];
+      if (Elements.isErroneousElement(element)) {
+        recordReturnType(inferrer.dynamicType);
+      } else {
+        element = element.implementation;
+        // Call [:addCaller:] directly and not
+        // [:registerCalledElement:] because we should actually pass
+        // the parameters.
+        inferrer.addCaller(analyzedElement, element);
+        recordReturnType(inferrer.returnTypeOfElement(element));
+      }
+    } else {
+      Node expression = node.expression;
+      recordReturnType(expression == null
+          ? inferrer.nullType
+          : expression.accept(this));
+    }
+    locals.seenReturn = true;
+    return inferrer.dynamicType;
+  }
+
+  TypeMask visitConditional(Conditional node) {
     node.condition.accept(this);
     LocalsHandler saved = new LocalsHandler.from(locals);
-    Element firstType = node.thenExpression.accept(this);
+    TypeMask firstType = node.thenExpression.accept(this);
     LocalsHandler thenLocals = locals;
     locals = saved;
-    Element secondType = node.elseExpression.accept(this);
+    TypeMask secondType = node.elseExpression.accept(this);
     locals.merge(thenLocals);
-    Element type = inferrer.computeLUB(firstType, secondType);
-    if (type == inferrer.giveUpType) type = compiler.dynamicClass;
+    TypeMask type = inferrer.computeLUB(firstType, secondType);
+    if (inferrer.isGiveUpType(type)) type = inferrer.dynamicType;
     return type;
   }
 
-  visitVariableDefinitions(VariableDefinitions node) {
+  TypeMask visitVariableDefinitions(VariableDefinitions node) {
     for (Link<Node> link = node.definitions.nodes;
          !link.isEmpty;
          link = link.tail) {
       Node definition = link.head;
       if (definition is Identifier) {
-        locals.update(elements[definition], compiler.nullClass);
+        locals.update(elements[definition], inferrer.nullType);
       } else {
         assert(definition.asSendSet() != null);
         visit(definition);
       }
     }
+    return inferrer.dynamicType;
   }
 
-  visitIf(If node) {
+  TypeMask visitIf(If node) {
     visit(node.condition);
     LocalsHandler saved = new LocalsHandler.from(locals);
     visit(node.thenPart);
@@ -1095,10 +1685,10 @@
     locals = saved;
     visit(node.elsePart);
     locals.merge(thenLocals);
-    return compiler.dynamicClass;
+    return inferrer.dynamicType;
   }
 
-  visitWhile(While node) {
+  TypeMask visitWhile(While node) {
     bool changed = false;
     do {
       LocalsHandler saved = new LocalsHandler.from(locals);
@@ -1107,11 +1697,10 @@
       changed = saved.merge(locals);
       locals = saved;
     } while (changed);
-
-    return compiler.dynamicClass;
+    return inferrer.dynamicType;
   }
 
-  visitDoWhile(DoWhile node) {
+ TypeMask visitDoWhile(DoWhile node) {
     bool changed = false;
     do {
       LocalsHandler saved = new LocalsHandler.from(locals);
@@ -1120,11 +1709,10 @@
       changed = saved.merge(locals);
       locals = saved;
     } while (changed);
-
-    return compiler.dynamicClass;
+    return inferrer.dynamicType;
   }
 
-  visitFor(For node) {
+  TypeMask visitFor(For node) {
     bool changed = false;
     visit(node.initializer);
     do {
@@ -1135,13 +1723,22 @@
       changed = saved.merge(locals);
       locals = saved;
     } while (changed);
-
-    return compiler.dynamicClass;
+    return inferrer.dynamicType;
   }
 
-  visitForIn(ForIn node) {
+  TypeMask visitForIn(ForIn node) {
     bool changed = false;
     visit(node.expression);
+    if (!isThisExposed && node.expression.isThis()) {
+      Selector iteratorSelector = elements.getIteratorSelector(node);
+      checkIfExposesThis(new TypedSelector(thisType, iteratorSelector));
+      TypeMask iteratorType = inferrer.typeOfSelector(iteratorSelector);
+
+      checkIfExposesThis(
+          new TypedSelector(iteratorType, elements.getMoveNextSelector(node)));
+      checkIfExposesThis(
+          new TypedSelector(iteratorType, elements.getCurrentSelector(node)));
+    }
     Element variable;
     if (node.declaredIdentifier.asSend() != null) {
       variable = elements[node.declaredIdentifier];
@@ -1150,18 +1747,17 @@
       VariableDefinitions variableDefinitions = node.declaredIdentifier;
       variable = elements[variableDefinitions.definitions.nodes.head];
     }
-    locals.update(variable, compiler.dynamicClass);
+    locals.update(variable, inferrer.dynamicType);
     do {
       LocalsHandler saved = new LocalsHandler.from(locals);
       visit(node.body);
       changed = saved.merge(locals);
       locals = saved;
     } while (changed);
-
-    return compiler.dynamicClass;
+    return inferrer.dynamicType;
   }
 
-  visitTryStatement(TryStatement node) {
+  TypeMask visitTryStatement(TryStatement node) {
     LocalsHandler saved = locals;
     locals = new LocalsHandler.from(locals, inTryBlock: true);
     visit(node.tryBlock);
@@ -1174,9 +1770,15 @@
       locals = saved;
     }
     visit(node.finallyBlock);
+    return inferrer.dynamicType;
   }
 
-  internalError(String reason, {Node node}) {
+  TypeMask visitThrow(Throw node) {
+    node.visitChildren(this);
+    locals.seenReturn = true;
+  }
+
+  void internalError(String reason, {Node node}) {
     compiler.internalError(reason, node: node);
   }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
index 5d4720d..7af109b 100644
--- a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
@@ -5,17 +5,16 @@
 part of types;
 
 /**
- * A type mask represents a set of concrete types, but the operations
- * on it are not guaranteed to be precise. When computing the union of
- * two masks you may get a mask that is too wide (like a common
- * superclass instead of a proper union type) and when computing the
- * intersection of two masks you may get a mask that is too narrow.
+ * A type mask represents a set of contained classes, but the
+ * operations on it are not guaranteed to be precise and they may
+ * yield conservative answers that contain too many classes.
  */
 class TypeMask {
 
-  static const int EXACT    = 0;
-  static const int SUBCLASS = 1;
-  static const int SUBTYPE  = 2;
+  static const int EMPTY    = 0;
+  static const int EXACT    = 1;
+  static const int SUBCLASS = 2;
+  static const int SUBTYPE  = 3;
 
   final DartType base;
   final int flags;
@@ -23,24 +22,45 @@
   TypeMask(DartType base, int kind, bool isNullable)
       : this.internal(base, (kind << 1) | (isNullable ? 1 : 0));
 
-  const TypeMask.exact(DartType base)
+  TypeMask.empty()
+      : this.internal(null, (EMPTY << 1) | 1);
+  TypeMask.exact(DartType base)
       : this.internal(base, (EXACT << 1) | 1);
-  const TypeMask.subclass(DartType base)
+  TypeMask.subclass(DartType base)
       : this.internal(base, (SUBCLASS << 1) | 1);
-  const TypeMask.subtype(DartType base)
+  TypeMask.subtype(DartType base)
       : this.internal(base, (SUBTYPE << 1) | 1);
 
-  const TypeMask.nonNullExact(DartType base)
+  TypeMask.nonNullEmpty()
+      : this.internal(null, EMPTY << 1);
+  TypeMask.nonNullExact(DartType base)
       : this.internal(base, EXACT << 1);
-  const TypeMask.nonNullSubclass(DartType base)
+  TypeMask.nonNullSubclass(DartType base)
       : this.internal(base, SUBCLASS << 1);
-  const TypeMask.nonNullSubtype(DartType base)
+  TypeMask.nonNullSubtype(DartType base)
       : this.internal(base, SUBTYPE << 1);
 
-  const TypeMask.internal(this.base, this.flags);
+  TypeMask.internal(DartType base, this.flags)
+      : this.base = transformBase(base);
 
-  bool get isNullable => (flags & 1) != 0;
+  // TODO(kasperl): We temporarily transform the base to be the raw
+  // variant of the type. Long term, we're going to keep the class
+  // element corresponding to the type in the mask instead.
+  static DartType transformBase(DartType base) {
+    if (base == null) {
+      return null;
+    } else if (base.kind != TypeKind.INTERFACE) {
+      assert(base.kind == TypeKind.INTERFACE);
+      return null;
+    } else {
+      assert(!base.isMalformed);
+      return base.asRaw();
+    }
+  }
+
+  bool get isEmpty => (flags >> 1) == EMPTY;
   bool get isExact => (flags >> 1) == EXACT;
+  bool get isNullable => (flags & 1) != 0;
 
   // TODO(kasperl): Get rid of these. They should not be a visible
   // part of the implementation because they make it hard to add
@@ -48,6 +68,8 @@
   bool get isSubclass => (flags >> 1) == SUBCLASS;
   bool get isSubtype => (flags >> 1) == SUBTYPE;
 
+  DartType get exactType => isExact ? base : null;
+
   /**
    * Returns a nullable variant of [this] type mask.
    */
@@ -56,54 +78,60 @@
   }
 
   /**
+   * Returns a non-nullable variant of [this] type mask.
+   */
+  TypeMask nonNullable() {
+    return isNullable ? new TypeMask.internal(base, flags & ~1) : this;
+  }
+
+  /**
    * Returns whether or not this type mask contains the given type.
    */
   bool contains(DartType type, Compiler compiler) {
-    // TODO(kasperl): Do this error handling earlier.
-    if (base.kind != TypeKind.INTERFACE) return false;
-    assert(type.kind == TypeKind.INTERFACE);
-    // Compare the interface types.
-    ClassElement baseElement = base.element;
-    ClassElement typeElement = type.element;
-    if (isExact) {
-      return identical(baseElement, typeElement);
+    if (isEmpty) {
+      return false;
+    } else if (identical(base.element, type.element)) {
+      return true;
+    } else if (isExact) {
+      return false;
     } else if (isSubclass) {
-      return typeElement.isSubclassOf(baseElement);
+      return isSubclassOf(type, base, compiler);
     } else {
       assert(isSubtype);
-      Set<ClassElement> subtypes = compiler.world.subtypes[baseElement];
-      return subtypes != null ? subtypes.contains(typeElement) : false;
+      return isSubtypeOf(type, base, compiler);
     }
   }
 
-  // TODO(kasperl): Try to get rid of this method. It shouldn't really
-  // be necessary.
+  /**
+   * Returns whether or not this type mask contains all types.
+   */
   bool containsAll(Compiler compiler) {
-    // TODO(kasperl): Do this error handling earlier.
-    if (base.kind != TypeKind.INTERFACE) return false;
-    // TODO(kasperl): Should we take nullability into account here?
-    if (isExact) return false;
-    ClassElement baseElement = base.element;
-    return identical(baseElement, compiler.objectClass)
-        || identical(baseElement, compiler.dynamicClass);
+    if (isEmpty || isExact) return false;
+    return identical(base.element, compiler.objectClass)
+        || identical(base.element, compiler.dynamicClass);
   }
 
-  // TODO(kasperl): This implementation is a bit sketchy, but it
-  // behaves the same as the old implementation on HType. The plan is
-  // to extend this and add proper testing of it.
-  TypeMask union(TypeMask other, Types types) {
-    // TODO(kasperl): Add subclass handling.
-    if (base == other.base) {
-      return unionSame(other, types);
-    } else if (types.isSubtype(other.base, base)) {
-      return unionSubtype(other, types);
-    } else if (types.isSubtype(base, other.base)) {
-      return other.unionSubtype(this, types);
+  TypeMask union(TypeMask other, Compiler compiler) {
+    if (isEmpty) {
+      return isNullable ? other.nullable() : other;
+    } else if (other.isEmpty) {
+      return other.isNullable ? nullable() : this;
+    } else if (base == other.base) {
+      return unionSame(other, compiler);
+    } else if (isSubclassOf(other.base, base, compiler)) {
+      return unionSubclass(other, compiler);
+    } else if (isSubclassOf(base, other.base, compiler)) {
+      return other.unionSubclass(this, compiler);
+    } else if (isSubtypeOf(other.base, base, compiler)) {
+      return unionSubtype(other, compiler);
+    } else if (isSubtypeOf(base, other.base, compiler)) {
+      return other.unionSubtype(this, compiler);
+    } else {
+      return unionDisjoint(other, compiler);
     }
-    return null;
   }
 
-  TypeMask unionSame(TypeMask other, Types types) {
+  TypeMask unionSame(TypeMask other, Compiler compiler) {
     assert(base == other.base);
     // The two masks share the base type, so we must chose the least
     // constraining kind (the highest) of the two. If either one of
@@ -120,8 +148,29 @@
     }
   }
 
-  TypeMask unionSubtype(TypeMask other, Types types) {
-    assert(types.isSubtype(other.base, base));
+  TypeMask unionSubclass(TypeMask other, Compiler compiler) {
+    assert(isSubclassOf(other.base, base, compiler));
+    int combined;
+    if (isExact && other.isExact) {
+      // Since the other mask is a subclass of this mask, we need the
+      // resulting union to be a subclass too. If either one of the
+      // masks are nullable the result should be nullable too.
+      combined = (SUBCLASS << 1) | ((flags | other.flags) & 1);
+    } else {
+      // Both masks are at least subclass masks, so we pick the least
+      // constraining kind (the highest) of the two. If either one of
+      // the masks are nullable the result should be nullable too.
+      combined = (flags > other.flags)
+          ? flags | (other.flags & 1)
+          : other.flags | (flags & 1);
+    }
+    return (flags != combined)
+        ? new TypeMask.internal(base, combined)
+        : this;
+  }
+
+  TypeMask unionSubtype(TypeMask other, Compiler compiler) {
+    assert(isSubtypeOf(other.base, base, compiler));
     // Since the other mask is a subtype of this mask, we need the
     // resulting union to be a subtype too. If either one of the masks
     // are nullable the result should be nullable too.
@@ -131,44 +180,196 @@
         : this;
   }
 
-  // TODO(kasperl): This implementation is a bit sketchy, but it
-  // behaves the same as the old implementation on HType. The plan is
-  // to extend this and add proper testing of it.
-  TypeMask intersection(TypeMask other, Types types) {
+  TypeMask unionDisjoint(TypeMask other, Compiler compiler) {
+    assert(base != other.base);
+    assert(!isSubtypeOf(base, other.base, compiler));
+    assert(!isSubtypeOf(other.base, base, compiler));
+    // If either type mask is a subtype type mask, we cannot use a
+    // subclass type mask to represent their union.
+    bool useSubclass = !isSubtype && !other.isSubtype;
+    // Compute the common supertypes of the two types.
+    ClassElement thisElement = base.element;
+    ClassElement otherElement = other.base.element;
+    Iterable<ClassElement> candidates =
+        compiler.world.commonSupertypesOf(thisElement, otherElement);
+    if (candidates.isEmpty) {
+      // TODO(kasperl): Get rid of this check. It can only happen when
+      // at least one of the two base types is 'unseen'.
+      return new TypeMask(compiler.objectClass.rawType,
+                          SUBCLASS,
+                          isNullable || other.isNullable);
+    }
+    // Compute the best candidate and its kind.
+    ClassElement bestElement;
+    int bestKind;
+    int bestSize;
+    for (ClassElement candidate in candidates) {
+      Set<ClassElement> subclasses = useSubclass
+          ? compiler.world.subclasses[candidate]
+          : null;
+      int size;
+      int kind;
+      if (subclasses != null &&
+          subclasses.contains(thisElement) &&
+          subclasses.contains(otherElement)) {
+        // If both [this] and [other] are subclasses of the supertype,
+        // then we prefer to construct a subclass type mask because it
+        // will always be at least as small as the corresponding
+        // subtype type mask.
+        kind = SUBCLASS;
+        size = subclasses.length;
+        assert(size <= compiler.world.subtypes[candidate].length);
+      } else {
+        kind = SUBTYPE;
+        size = compiler.world.subtypes[candidate].length;
+      }
+      // Update the best candidate if the new one is better.
+      if (bestElement == null || size < bestSize) {
+        bestElement = candidate;
+        bestSize = size;
+        bestKind = kind;
+      }
+    }
+    return new TypeMask(bestElement.computeType(compiler),
+                        bestKind,
+                        isNullable || other.isNullable);
+  }
+
+  TypeMask intersection(TypeMask other, Compiler compiler) {
+    if (isEmpty) {
+      return other.isNullable ? this : nonNullable();
+    } else if (other.isEmpty) {
+      return isNullable ? other : other.nonNullable();
+    } else if (base == other.base) {
+      return intersectionSame(other, compiler);
+    } else if (isSubclassOf(other.base, base, compiler)) {
+      return intersectionSubclass(other, compiler);
+    } else if (isSubclassOf(base, other.base, compiler)) {
+      return other.intersectionSubclass(this, compiler);
+    } else if (isSubtypeOf(other.base, base, compiler)) {
+      return intersectionSubtype(other, compiler);
+    } else if (isSubtypeOf(base, other.base, compiler)) {
+      return other.intersectionSubtype(this, compiler);
+    } else {
+      return intersectionDisjoint(other, compiler);
+    }
+  }
+
+  TypeMask intersectionSame(TypeMask other, Compiler compiler) {
+    assert(base == other.base);
+    // The two masks share the base type, so we must chose the most
+    // constraining kind (the lowest) of the two. Only if both masks
+    // are nullable, will the result be nullable too.
     int combined = (flags < other.flags)
         ? flags & ((other.flags & 1) | ~1)
         : other.flags & ((flags & 1) | ~1);
-    if (base == other.base) {
-      if (flags == combined) {
-        return this;
-      } else if (other.flags == combined) {
-        return other;
-      } else {
-        return new TypeMask.internal(base, combined);
-      }
-    } else if (types.isSubtype(other.base, base)) {
-      if (other.flags == combined) {
-        return other;
-      } else {
-        return new TypeMask.internal(other.base, combined);
-      }
-    } else if (types.isSubtype(base, other.base)) {
-      if (flags == combined) {
-        return this;
-      } else {
-        return new TypeMask.internal(base, combined);
-      }
+    if (flags == combined) {
+      return this;
+    } else if (other.flags == combined) {
+      return other;
+    } else {
+      return new TypeMask.internal(base, combined);
     }
-    return null;
+  }
+
+  TypeMask intersectionSubclass(TypeMask other, Compiler compiler) {
+    assert(isSubclassOf(other.base, base, compiler));
+    // If this mask isn't at least a subclass mask, then the
+    // intersection with the other mask is empty.
+    if (isExact) return intersectionEmpty(other);
+    // Only the other mask puts constraints on the intersection mask,
+    // so base the combined flags on the other mask. Only if both
+    // masks are nullable, will the result be nullable too.
+    int combined = other.flags & ((flags & 1) | ~1);
+    if (other.flags == combined) {
+      return other;
+    } else {
+      return new TypeMask.internal(other.base, combined);
+    }
+  }
+
+  TypeMask intersectionSubtype(TypeMask other, Compiler compiler) {
+    assert(isSubtypeOf(other.base, base, compiler));
+    // If this mask isn't a subtype mask, then the intersection with
+    // the other mask is empty.
+    if (!isSubtype) return intersectionEmpty(other);
+    // Only the other mask puts constraints on the intersection mask,
+    // so base the combined flags on the other mask. Only if both
+    // masks are nullable, will the result be nullable too.
+    int combined = other.flags & ((flags & 1) | ~1);
+    if (other.flags == combined) {
+      return other;
+    } else {
+      return new TypeMask.internal(other.base, combined);
+    }
+  }
+
+  TypeMask intersectionDisjoint(TypeMask other, Compiler compiler) {
+    assert(base != other.base);
+    assert(!isSubtypeOf(base, other.base, compiler));
+    assert(!isSubtypeOf(other.base, base, compiler));
+    // If one of the masks are exact or if both of them are subclass
+    // masks, then the intersection is empty.
+    if (isExact || other.isExact) return intersectionEmpty(other);
+    if (isSubclass && other.isSubclass) return intersectionEmpty(other);
+    assert(isSubtype || other.isSubtype);
+    int kind = (isSubclass || other.isSubclass) ? SUBCLASS : SUBTYPE;
+    // Compute the set of classes that are contained in both type masks.
+    Set<ClassElement> common = commonContainedClasses(this, other, compiler);
+    if (common == null || common.isEmpty) return intersectionEmpty(other);
+    // Narrow down the candidates by only looking at common classes
+    // that do not have a superclass or supertype that will be a
+    // better candidate.
+    Iterable<ClassElement> candidates = common.where((ClassElement each) {
+      bool containsSuperclass = common.contains(each.supertype.element);
+      // If the superclass is also a candidate, then we don't want to
+      // deal with this class. If we're only looking for a subclass we
+      // know we don't have to look at the list of interfaces because
+      // they can never be in the common set.
+      if (containsSuperclass || kind == SUBCLASS) return !containsSuperclass;
+      // Run through the direct supertypes of the class. If the common
+      // set contains the direct supertype of the class, we ignore the
+      // the class because the supertype is a better candidate.
+      for (Link link = each.interfaces; !link.isEmpty; link = link.tail) {
+        if (common.contains(link.head.element)) return false;
+      }
+      return true;
+    });
+    // Run through the list of candidates and compute the union. The
+    // result will only be nullable if both masks are nullable.
+    int combined = (kind << 1) | (flags & other.flags & 1);
+    TypeMask result;
+    for (ClassElement each in candidates) {
+      TypeMask mask = new TypeMask.internal(each.rawType, combined);
+      result = (result == null) ? mask : result.union(mask, compiler);
+    }
+    return result;
+  }
+
+  TypeMask intersectionEmpty(TypeMask other) {
+    return new TypeMask(null, EMPTY, isNullable && other.isNullable);
+  }
+
+  Set<ClassElement> containedClasses(Compiler compiler) {
+    ClassElement element = base.element;
+    if (isExact) {
+      return new Set<ClassElement>()..add(element);
+    } else if (isSubclass) {
+      return compiler.world.subclasses[element];
+    } else {
+      assert(isSubtype);
+      return compiler.world.subtypes[element];
+    }
   }
 
   bool operator ==(var other) {
     if (other is !TypeMask) return false;
     TypeMask otherMask = other;
-    return (base == otherMask.base) && (flags == otherMask.flags);
+    return (flags == otherMask.flags) && (base == otherMask.base);
   }
 
   String toString() {
+    if (isEmpty) return isNullable ? '[null]' : '[empty]';
     StringBuffer buffer = new StringBuffer();
     if (isNullable) buffer.write('null|');
     if (isExact) buffer.write('exact=');
@@ -177,4 +378,36 @@
     buffer.write(base.element.name.slowToString());
     return "[$buffer]";
   }
+
+  static bool isSubclassOf(DartType x, DartType y, Compiler compiler) {
+    ClassElement xElement = x.element;
+    ClassElement yElement = y.element;
+    Set<ClassElement> subclasses = compiler.world.subclasses[yElement];
+    return (subclasses != null) ? subclasses.contains(xElement) : false;
+  }
+
+  static bool isSubtypeOf(DartType x, DartType y, Compiler compiler) {
+    ClassElement xElement = x.element;
+    ClassElement yElement = y.element;
+    Set<ClassElement> subtypes = compiler.world.subtypes[yElement];
+    return (subtypes != null) ? subtypes.contains(xElement) : false;
+  }
+
+  static Set<ClassElement> commonContainedClasses(TypeMask x, TypeMask y,
+                                                  Compiler compiler) {
+    Set<ClassElement> xSubset = x.containedClasses(compiler);
+    if (xSubset == null) return null;
+    Set<ClassElement> ySubset = y.containedClasses(compiler);
+    if (ySubset == null) return null;
+    Set<ClassElement> smallSet, largeSet;
+    if (xSubset.length <= ySubset.length) {
+      smallSet = xSubset;
+      largeSet = ySubset;
+    } else {
+      smallSet = ySubset;
+      largeSet = xSubset;
+    }
+    var result = smallSet.where((ClassElement each) => largeSet.contains(each));
+    return result.toSet();
+  }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/types/types.dart b/sdk/lib/_internal/compiler/implementation/types/types.dart
index 8b03838..c23390a 100644
--- a/sdk/lib/_internal/compiler/implementation/types/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/types.dart
@@ -10,6 +10,7 @@
 import '../js_backend/js_backend.dart' show JavaScriptBackend;
 import '../tree/tree.dart';
 import '../elements/elements.dart';
+import '../native_handler.dart' as native;
 import '../util/util.dart';
 import '../universe/universe.dart';
 import 'simple_types_inferrer.dart' show SimpleTypesInferrer;
@@ -25,8 +26,10 @@
  */
 abstract class TypesInferrer {
   analyzeMain(Element element);
-  getConcreteTypeOfElement(Element element);
-  getConcreteTypeOfNode(Element owner, Node node);
+  TypeMask getReturnTypeOfElement(Element element);
+  TypeMask getTypeOfElement(Element element);
+  TypeMask getTypeOfNode(Element owner, Node node);
+  TypeMask getTypeOfSelector(Selector selector);
 }
 
 /**
@@ -74,13 +77,13 @@
   }
 
   /**
-   * Return the (inferred) guaranteed concrete type of [element] or null.
+   * Return the (inferred) guaranteed type of [element] or null.
    */
-  ConcreteType getGuaranteedTypeOfElement(Element element) {
+  TypeMask getGuaranteedTypeOfElement(Element element) {
     return measure(() {
       if (typesInferrer != null) {
-        ConcreteType guaranteedType = typesInferrer
-            .getConcreteTypeOfElement(element);
+        TypeMask guaranteedType =
+            typesInferrer .getTypeOfElement(element);
         if (guaranteedType != null) return guaranteedType;
       }
       if (!element.isParameter()) return null;
@@ -94,8 +97,7 @@
       for (Element parameter in signature.requiredParameters) {
         if (types.isEmpty) return null;
         if (element == parameter) {
-          return new ConcreteType.singleton(compiler.maxConcreteTypeSize,
-                                            new ClassBaseType(types.head));
+          return new TypeMask.nonNullExact(types.head.computeType(compiler));
         }
         types = types.tail;
       }
@@ -103,14 +105,38 @@
     });
   }
 
-  /**
-   * Return the (inferred) guaranteed concrete type of [node] or null.
-   * [node] must be an AST node of [owner].
-   */
-  ConcreteType getGuaranteedTypeOfNode(owner, node) {
+  TypeMask getGuaranteedReturnTypeOfElement(Element element) {
     return measure(() {
       if (typesInferrer != null) {
-        return typesInferrer.getConcreteTypeOfNode(owner, node);
+        TypeMask guaranteedType =
+            typesInferrer.getReturnTypeOfElement(element);
+        if (guaranteedType != null) return guaranteedType;
+      }
+      return null;
+    });
+  }
+
+  /**
+   * Return the (inferred) guaranteed type of [node] or null.
+   * [node] must be an AST node of [owner].
+   */
+  TypeMask getGuaranteedTypeOfNode(owner, node) {
+    return measure(() {
+      if (typesInferrer != null) {
+        return typesInferrer.getTypeOfNode(owner, node);
+      }
+      return null;
+    });
+  }
+
+  /**
+   * Return the (inferred) guaranteed type of [selector] or null.
+   * [node] must be an AST node of [owner].
+   */
+  TypeMask getGuaranteedTypeOfSelector(Selector selector) {
+    return measure(() {
+      if (typesInferrer != null) {
+        return typesInferrer.getTypeOfSelector(selector);
       }
       return null;
     });
@@ -134,12 +160,12 @@
 
   ConcreteTypeInferencer(TypesTask task, this.elements)
     : this.task = task,
-      this.boolClass = task.compiler.boolClass,
-      this.doubleClass = task.compiler.doubleClass,
-      this.intClass = task.compiler.intClass,
-      this.listClass = task.compiler.listClass,
-      this.nullClass = task.compiler.nullClass,
-      this.stringClass = task.compiler.stringClass,
+      this.boolClass = task.compiler.backend.boolImplementation,
+      this.doubleClass = task.compiler.backend.doubleImplementation,
+      this.intClass = task.compiler.backend.intImplementation,
+      this.listClass = task.compiler.backend.listImplementation,
+      this.nullClass = task.compiler.backend.nullImplementation,
+      this.stringClass = task.compiler.backend.stringImplementation,
       this.concreteTypes = new Map<Node, ClassElement>();
 
   visitNode(Node node) => node.visitChildren(this);
diff --git a/sdk/lib/_internal/compiler/implementation/universe/universe.dart b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
index ecc1c34..4dbd9a8 100644
--- a/sdk/lib/_internal/compiler/implementation/universe/universe.dart
+++ b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
@@ -459,7 +459,7 @@
               selector.argumentCount,
               selector.namedArguments) {
     // Invariant: Typed selector can not be based on a malformed type.
-    assert(!identical(mask.base.kind, TypeKind.MALFORMED_TYPE));
+    assert(mask.isEmpty || !identical(mask.base.kind, TypeKind.MALFORMED_TYPE));
     assert(asUntyped.mask == null);
   }
 
@@ -479,13 +479,19 @@
    * invoked on an instance of [cls].
    */
   bool hasElementIn(ClassElement cls, Element element) {
-    return cls.lookupSelector(this) == element;
+    // Use the [:implementation] of [cls] in case [element]
+    // is in the patch class. Also use [:implementation:] of [element]
+    // because our function set only stores declarations.
+    Element result = cls.implementation.lookupSelector(this);
+    return result == null
+        ? false
+        : result.implementation == element.implementation;
   }
 
   bool appliesUnnamed(Element element, Compiler compiler) {
     assert(sameNameHack(element, compiler));
-    // [TypedSelector] are only used when compiling.
-    assert(compiler.phase == Compiler.PHASE_COMPILING);
+    // [TypedSelector] are only used after resolution.
+    assert(compiler.phase > Compiler.PHASE_RESOLVING);
     if (!element.isMember()) return false;
 
     // A closure can be called through any typed selector:
@@ -498,6 +504,12 @@
       return appliesUntyped(element, compiler);
     }
 
+    if (mask.isEmpty) {
+      if (!mask.isNullable) return false;
+      return hasElementIn(compiler.backend.nullImplementation, element)
+          && appliesUntyped(element, compiler);
+    }
+
     // TODO(kasperl): Can't we just avoid creating typed selectors
     // based of function types?
     Element self = mask.base.element;
@@ -507,7 +519,9 @@
       return false;
     }
 
-    if (mask.isExact) {
+    if (mask.isNullable && compiler.backend.isNullImplementation(other)) {
+      return appliesUntyped(element, compiler);
+    } else if (mask.isExact) {
       return hasElementIn(self, element) && appliesUntyped(element, compiler);
     } else if (mask.isSubclass) {
       return (hasElementIn(self, element)
diff --git a/sdk/lib/_internal/compiler/implementation/util/util.dart b/sdk/lib/_internal/compiler/implementation/util/util.dart
index 0c94d40..9d4056a 100644
--- a/sdk/lib/_internal/compiler/implementation/util/util.dart
+++ b/sdk/lib/_internal/compiler/implementation/util/util.dart
@@ -37,36 +37,36 @@
 
 /// Writes the characters of [string] on [buffer].  The characters
 /// are escaped as suitable for JavaScript and JSON.  [buffer] is
-/// anything which supports [:add:] and [:addCharCode:], for example,
+/// anything which supports [:write:] and [:writeCharCode:], for example,
 /// [StringBuffer].  Note that JS supports \xnn and \unnnn whereas JSON only
 /// supports the \unnnn notation.  Therefore we use the \unnnn notation.
 void writeJsonEscapedCharsOn(String string, buffer) {
   void addCodeUnitEscaped(var buffer, int code) {
     assert(code < 0x10000);
-    buffer.add(r'\u');
+    buffer.write(r'\u');
     if (code < 0x1000) {
-      buffer.add('0');
+      buffer.write('0');
       if (code < 0x100) {
-        buffer.add('0');
+        buffer.write('0');
         if (code < 0x10) {
-          buffer.add('0');
+          buffer.write('0');
         }
       }
     }
-    buffer.add(code.toRadixString(16));
+    buffer.write(code.toRadixString(16));
   }
 
   void writeEscapedOn(String string, var buffer) {
     for (int i = 0; i < string.length; i++) {
       int code = string.codeUnitAt(i);
       if (code == $DQ) {
-        buffer.add(r'\"');
+        buffer.write(r'\"');
       } else if (code == $TAB) {
-        buffer.add(r'\t');
+        buffer.write(r'\t');
       } else if (code == $LF) {
-        buffer.add(r'\n');
+        buffer.write(r'\n');
       } else if (code == $CR) {
-        buffer.add(r'\r');
+        buffer.write(r'\r');
       } else if (code == $DEL) {
         addCodeUnitEscaped(buffer, $DEL);
       } else if (code == $LS) {
@@ -76,7 +76,7 @@
       } else if (code == $PS) {
         addCodeUnitEscaped(buffer, $PS);  // 0x2029.
       } else if (code == $BACKSLASH) {
-        buffer.add(r'\\');
+        buffer.write(r'\\');
       } else {
         if (code < 0x20) {
           addCodeUnitEscaped(buffer, code);
@@ -85,7 +85,7 @@
           // everything above 0x7f because that means we don't have to worry
           // about whether the web server serves it up as Latin1 or UTF-8.
         } else if (code < 0x7f) {
-          buffer.addCharCode(code);
+          buffer.writeCharCode(code);
         } else {
           // This will output surrogate pairs in the form \udxxx\udyyy, rather
           // than the more logical \u{zzzzzz}.  This should work in JavaScript
@@ -105,5 +105,5 @@
       return;
     }
   }
-  buffer.add(string);
+  buffer.write(string);
 }
diff --git a/sdk/lib/_internal/compiler/implementation/warnings.dart b/sdk/lib/_internal/compiler/implementation/warnings.dart
index 36c1933..2e377a4 100644
--- a/sdk/lib/_internal/compiler/implementation/warnings.dart
+++ b/sdk/lib/_internal/compiler/implementation/warnings.dart
@@ -389,6 +389,10 @@
   static const DEFERRED_LIBRARY_NAME_MISMATCH = const MessageKind(
       'Error: Library name mismatch "#{expectedName}" != "#{actualName}".');
 
+  static const ILLEGAL_STATIC = const MessageKind(
+      "Error: Modifier static is only allowed on functions declared in"
+      " a class.");
+
   static const COMPILER_CRASHED = const MessageKind(
       "Error: The compiler crashed when compiling this element.");
 
diff --git a/sdk/lib/_internal/compiler/implementation/world.dart b/sdk/lib/_internal/compiler/implementation/world.dart
index a09f629..ff5d6a9 100644
--- a/sdk/lib/_internal/compiler/implementation/world.dart
+++ b/sdk/lib/_internal/compiler/implementation/world.dart
@@ -6,20 +6,25 @@
 
 class World {
   final Compiler compiler;
-  final Map<ClassElement, Set<ClassElement>> subtypes;
   final Map<ClassElement, Set<MixinApplicationElement>> mixinUses;
   final Map<ClassElement, Set<ClassElement>> typesImplementedBySubclasses;
-  final Set<ClassElement> classesNeedingRti;
-  final Map<ClassElement, Set<ClassElement>> rtiDependencies;
   final FullFunctionSet allFunctions;
 
+  // We keep track of subtype and subclass relationships in four
+  // distinct sets to make class hierarchy analysis faster.
+  final Map<ClassElement, Set<ClassElement>> subclasses =
+      new Map<ClassElement, Set<ClassElement>>();
+  final Map<ClassElement, Set<ClassElement>> superclasses =
+      new Map<ClassElement, Set<ClassElement>>();
+  final Map<ClassElement, Set<ClassElement>> subtypes =
+      new Map<ClassElement, Set<ClassElement>>();
+  final Map<ClassElement, Set<ClassElement>> supertypes =
+      new Map<ClassElement, Set<ClassElement>>();
+
   World(Compiler compiler)
-      : subtypes = new Map<ClassElement, Set<ClassElement>>(),
-        mixinUses = new Map<ClassElement, Set<MixinApplicationElement>>(),
+      : mixinUses = new Map<ClassElement, Set<MixinApplicationElement>>(),
         typesImplementedBySubclasses =
             new Map<ClassElement, Set<ClassElement>>(),
-        classesNeedingRti = new Set<ClassElement>(),
-        rtiDependencies = new Map<ClassElement, Set<ClassElement>>(),
         allFunctions = new FullFunctionSet(compiler),
         this.compiler = compiler;
 
@@ -31,18 +36,28 @@
       }
 
       for (DartType type in cls.allSupertypes) {
-        Set<Element> subtypesOfCls =
-          subtypes.putIfAbsent(type.element, () => new Set<ClassElement>());
-        subtypesOfCls.add(cls);
+        Set<Element> supertypesOfClass =
+            supertypes.putIfAbsent(cls, () => new Set<ClassElement>());
+        Set<Element> subtypesOfSupertype =
+            subtypes.putIfAbsent(type.element, () => new Set<ClassElement>());
+        supertypesOfClass.add(type.element);
+        subtypesOfSupertype.add(cls);
       }
 
       // Walk through the superclasses, and record the types
       // implemented by that type on the superclasses.
       DartType type = cls.supertype;
       while (type != null) {
+        Set<Element> superclassesOfClass =
+            superclasses.putIfAbsent(cls, () => new Set<ClassElement>());
+        Set<Element> subclassesOfSuperclass =
+            subclasses.putIfAbsent(type.element, () => new Set<ClassElement>());
+        superclassesOfClass.add(type.element);
+        subclassesOfSuperclass.add(cls);
+
         Set<Element> typesImplementedBySubclassesOfCls =
-          typesImplementedBySubclasses.putIfAbsent(
-              type.element, () => new Set<ClassElement>());
+            typesImplementedBySubclasses.putIfAbsent(
+                type.element, () => new Set<ClassElement>());
         for (DartType current in cls.allSupertypes) {
           typesImplementedBySubclassesOfCls.add(current.element);
         }
@@ -56,61 +71,22 @@
     // they also need RTI, so that a constructor passes the type
     // variables to the super constructor.
     compiler.enqueuer.resolution.seenClasses.forEach(addSubtypes);
+  }
 
-    // Find the classes that need runtime type information. Such
-    // classes are:
-    // (1) used in a is check with type variables,
-    // (2) dependencies of classes in (1),
-    // (3) subclasses of (2) and (3).
-
-    void potentiallyAddForRti(ClassElement cls) {
-      if (cls.typeVariables.isEmpty) return;
-      if (classesNeedingRti.contains(cls)) return;
-      classesNeedingRti.add(cls);
-
-      // TODO(ngeoffray): This should use subclasses, not subtypes.
-      Set<ClassElement> classes = subtypes[cls];
-      if (classes != null) {
-        classes.forEach((ClassElement sub) {
-          potentiallyAddForRti(sub);
-        });
-      }
-
-      Set<ClassElement> dependencies = rtiDependencies[cls];
-      if (dependencies != null) {
-        dependencies.forEach((ClassElement other) {
-          potentiallyAddForRti(other);
-        });
-      }
+  Iterable<ClassElement> commonSupertypesOf(ClassElement x, ClassElement y) {
+    Set<ClassElement> xSet = supertypes[x];
+    if (xSet == null) return const <ClassElement>[];
+    Set<ClassElement> ySet = supertypes[y];
+    if (ySet == null) return const <ClassElement>[];
+    Set<ClassElement> smallSet, largeSet;
+    if (xSet.length <= ySet.length) {
+      smallSet = xSet;
+      largeSet = ySet;
+    } else {
+      smallSet = ySet;
+      largeSet = xSet;
     }
-
-    Set<ClassElement> classesUsingTypeVariableTests = new Set<ClassElement>();
-    compiler.resolverWorld.isChecks.forEach((DartType type) {
-      if (type.kind == TypeKind.TYPE_VARIABLE) {
-        TypeVariableElement variable = type.element;
-        classesUsingTypeVariableTests.add(variable.enclosingElement);
-      }
-    });
-    // Add is-checks that result from classes using type variables in checks.
-    compiler.resolverWorld.addImplicitChecks(classesUsingTypeVariableTests);
-    // Add the rti dependencies that are implicit in the way the backend
-    // generates code: when we create a new [List], we actually create
-    // a JSArray in the backend and we need to add type arguments to
-    // the calls of the list constructor whenever we determine that
-    // JSArray needs type arguments.
-    compiler.backend.addBackendRtiDependencies(this);
-    // Compute the set of all classes that need runtime type information.
-    compiler.resolverWorld.isChecks.forEach((DartType type) {
-      if (type.kind == TypeKind.INTERFACE) {
-        InterfaceType itf = type;
-        if (!itf.isRaw) {
-          potentiallyAddForRti(itf.element);
-        }
-      } else if (type.kind == TypeKind.TYPE_VARIABLE) {
-        TypeVariableElement variable = type.element;
-        potentiallyAddForRti(variable.enclosingElement);
-      }
-    });
+    return smallSet.where((ClassElement each) => largeSet.contains(each));
   }
 
   void registerMixinUse(MixinApplicationElement mixinApplication,
@@ -126,16 +102,14 @@
     return uses != null && !uses.isEmpty;
   }
 
-  void registerRtiDependency(Element element, Element dependency) {
-    // We're not dealing with typedef for now.
-    if (!element.isClass() || !dependency.isClass()) return;
-    Set<ClassElement> classes =
-        rtiDependencies.putIfAbsent(element, () => new Set<ClassElement>());
-    classes.add(dependency);
+  bool hasAnySubclass(ClassElement cls) {
+    Set<ClassElement> classes = subclasses[cls];
+    return classes != null && !classes.isEmpty;
   }
 
-  bool needsRti(ClassElement cls) {
-    return classesNeedingRti.contains(cls) || compiler.enabledRuntimeType;
+  bool hasAnySubtype(ClassElement cls) {
+    Set<ClassElement> classes = subtypes[cls];
+    return classes != null && !classes.isEmpty;
   }
 
   bool hasAnyUserDefinedGetter(Selector selector) {
diff --git a/sdk/lib/_internal/compiler/samples/leap/leap_leg.dart b/sdk/lib/_internal/compiler/samples/leap/leap_leg.dart
index 3969f90..137c236 100644
--- a/sdk/lib/_internal/compiler/samples/leap/leap_leg.dart
+++ b/sdk/lib/_internal/compiler/samples/leap/leap_leg.dart
@@ -142,28 +142,28 @@
 
       FunctionType ft = fe.computeType(compiler);
 
-      sb.add("<div>${indentation}");
+      sb.write("<div>${indentation}");
       ft.returnType.name.printOn(sb);
-      sb.add(" ");
+      sb.write(" ");
       fe.name.printOn(sb);
-      sb.add("(");
+      sb.write("(");
       ft.parameterTypes.printOn(sb, ", ");
-      sb.add(");</div>");
+      sb.write(");</div>");
 
     }
 
     void printField(FieldElement fe, [String indentation = ""]) {
-      sb.add("<div>${indentation}var ");
+      sb.write("<div>${indentation}var ");
       fe.name.printOn(sb);
-      sb.add(";</div>");
+      sb.write(";</div>");
     }
 
     void printClass(ClassElement ce) {
       ce.parseNode(compiler);
 
-      sb.add("<div>class ");
+      sb.write("<div>class ");
       ce.name.printOn(sb);
-      sb.add(" {");
+      sb.write(" {");
 
       for (Element e in ce.members.reverse()) {
         switch(e.kind) {
@@ -178,7 +178,7 @@
           break;
         }
       }
-      sb.add("}</div>");
+      sb.write("}</div>");
     }
 
     for (Element c in e.topLevelElements.reverse()) {
diff --git a/sdk/lib/_internal/dartdoc/bin/dartdoc.dart b/sdk/lib/_internal/dartdoc/bin/dartdoc.dart
old mode 100755
new mode 100644
index 092da33..3c906bf
--- a/sdk/lib/_internal/dartdoc/bin/dartdoc.dart
+++ b/sdk/lib/_internal/dartdoc/bin/dartdoc.dart
@@ -16,12 +16,14 @@
  */
 library dartdoc;
 
-import 'dart:io';
 import 'dart:async';
+import 'dart:io';
+
+import '../lib/dartdoc.dart';
 
 // TODO(rnystrom): Use "package:" URL (#4968).
-import '../lib/dartdoc.dart';
 import '../../../../../pkg/args/lib/args.dart';
+import '../../../../../pkg/pathos/lib/path.dart' as path;
 
 /**
  * Run this from the `lib/_internal/dartdoc` directory.
@@ -136,7 +138,7 @@
               allLibs.add(lib);
             }
           }
-          dartdoc.excludedLibraries = allLibs;
+          dartdoc.includedLibraries = allLibs;
         }
       }, allowMultiple: true);
 
@@ -210,20 +212,48 @@
   }
 
   if (pkgPath == null) {
-    pkgPath = entrypoints[0].directoryPath.append('packages/');
+    // Check if there's a `packages` directory in the entry point directory.
+    var script = path.normalize(path.absolute(entrypoints[0].toNativePath()));
+    var dir = path.join(path.dirname(script), 'packages/');
+    if (new Directory(dir).existsSync()) {
+      // TODO(amouravski): convert all of dartdoc to use pathos.
+      pkgPath = new Path(dir);
+    } else {
+      // If there is not, then check if the entrypoint is somewhere in a `lib`
+      // directory.
+      dir = path.dirname(script);
+      var parts = path.split(dir);
+      var libDir = parts.lastIndexOf('lib');
+      if (libDir > 0) {
+        pkgPath = new Path(path.join(path.joinAll(parts.take(libDir)),
+              'packages'));
+      }
+    }
   }
 
   cleanOutputDirectory(dartdoc.outputDir);
 
-  dartdoc.documentLibraries(entrypoints, libPath, pkgPath);
-
-  Future compiled = compileScript(dartdoc.mode, dartdoc.outputDir, libPath);
-  Future filesCopied = copyDirectory(scriptDir.append('../static'),
-                                     dartdoc.outputDir);
-
-  Future.wait([compiled, filesCopied]).then((_) {
-    dartdoc.cleanup();
-    print('Documented ${dartdoc.totalLibraries} libraries, '
-          '${dartdoc.totalTypes} types, and ${dartdoc.totalMembers} members.');
-  });
+  // Start the analysis and documentation.
+  dartdoc.documentLibraries(entrypoints, libPath, pkgPath)
+    .then((_) {
+      print('Copying static files...');
+      Future.wait([
+        // Prepare the dart2js script code and copy static resources.
+        // TODO(amouravski): move compileScript out and pre-generate the client
+        // scripts. This takes a long time and the js hardly ever changes.
+        compileScript(dartdoc.mode, dartdoc.outputDir, libPath),
+        copyDirectory(scriptDir.append('../static'), dartdoc.outputDir)
+      ]);
+    })
+    .then((_) {
+      print(dartdoc.status);
+      if (dartdoc.totals == 0) {
+        exit(1);
+      }
+    })
+    .catchError((e) {
+        print('Error: generation failed: ${e.error}');
+        exit(1);
+    })
+    .whenComplete(() => dartdoc.cleanup());
 }
diff --git a/sdk/lib/_internal/dartdoc/lib/dartdoc.dart b/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
index e02d513..83b0f28 100644
--- a/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
+++ b/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
@@ -18,20 +18,22 @@
 
 import 'dart:async';
 import 'dart:io';
+import 'dart:json' as json;
 import 'dart:math';
 import 'dart:uri';
-import 'dart:json' as json;
 
+import 'classify.dart';
+import 'markdown.dart' as md;
+import 'universe_serializer.dart';
+
+import 'src/dartdoc/nav.dart';
+import 'src/json_serializer.dart' as json_serializer;
+
+// TODO(rnystrom): Use "package:" URL (#4968).
+import '../../compiler/implementation/mirrors/dart2js_mirror.dart' as dart2js;
 import '../../compiler/implementation/mirrors/mirrors.dart';
 import '../../compiler/implementation/mirrors/mirrors_util.dart';
-import '../../compiler/implementation/mirrors/dart2js_mirror.dart' as dart2js;
-import 'classify.dart';
-import 'universe_serializer.dart';
-import 'markdown.dart' as md;
-import 'src/json_serializer.dart' as json_serializer;
-import '../../compiler/implementation/scanner/scannerlib.dart' as dart2js;
 import '../../libraries.dart';
-import 'src/dartdoc/nav.dart';
 
 part 'src/dartdoc/utils.dart';
 
@@ -119,29 +121,26 @@
           fromFile.openRead().pipe(toFile.openWrite());
         }
       },
-      onDone: () => completer.complete(true));
+      onDone: () => completer.complete(),
+      onError: (e) => completer.completeError(e.error, e.stackTrace));
   return completer.future;
 }
 
 /**
  * Compiles the dartdoc client-side code to JavaScript using Dart2js.
  */
-Future<bool> compileScript(int mode, Path outputDir, Path libPath) {
+Future compileScript(int mode, Path outputDir, Path libPath) {
+  print('Compiling client JavaScript...');
   var clientScript = (mode == MODE_STATIC) ? 'static' : 'live-nav';
   var dartPath = libPath.append(
       'lib/_internal/dartdoc/lib/src/client/client-$clientScript.dart');
   var jsPath = outputDir.append('client-$clientScript.js');
 
-  var completer = new Completer<bool>();
-  var compilation = new Compilation(
-      dartPath, libPath, null, const <String>['--categories=Client,Server']);
-  Future<String> result = compilation.compileToJavaScript();
-  result.then((jsCode) {
-    writeString(new File.fromPath(jsPath), jsCode);
-    completer.complete(true);
-  });
-  result.catchError((e) => completer.completeError(e.error, e.stackTrace));
-  return completer.future;
+  return dart2js.compile(dartPath, libPath,
+      options: const <String>['--categories=Client,Server'])
+    .then((jsCode) {
+      writeString(new File.fromPath(jsPath), jsCode);
+    });
 }
 
 /**
@@ -290,6 +289,39 @@
   int get totalTypes => _totalTypes;
   int get totalMembers => _totalMembers;
 
+  // Check if the compilation has started and finished.
+  bool _started = false;
+  bool _finished = false;
+
+  /**
+   * Prints the status of dartdoc.
+   *
+   * Prints whether dartdoc is running, whether dartdoc has finished
+   * succesfully or not, and how many libraries, types, and members were
+   * documented.
+   */
+  String get status {
+    // TODO(amouravski): Make this more full featured and remove all other
+    // prints and put them under verbose flag.
+    if (!_started) {
+      return 'Documentation has not yet started.';
+    } else if (!_finished) {
+      return 'Documentation in progress -- documented $_statisticsSummary so far.';
+    } else {
+      if (totals == 0) {
+        return 'Documentation complete -- warning: nothing was documented!';
+      } else {
+        return 'Documentation complete -- documented $_statisticsSummary.';
+      }
+    }
+  }
+
+  int get totals => totalLibraries + totalTypes + totalMembers;
+
+  String get _statisticsSummary =>
+      '${totalLibraries} libraries, ${totalTypes} types, and '
+      '${totalMembers} members';
+
   static const List<String> COMPILER_OPTIONS =
       const <String>['--preserve-comments', '--categories=Client,Server'];
 
@@ -364,29 +396,35 @@
     var content = '';
     for (int i = 0; i < footerItems.length; i++) {
       if (i > 0) {
-        content = content.concat('\n');
+        content += '\n';
       }
-      content = content.concat('<div>${footerItems[i]}</div>');
+      content += '<div>${footerItems[i]}</div>';
     }
     return content;
   }
 
-  void documentEntryPoint(Path entrypoint, Path libPath, Path pkgPath) {
-    final compilation = new Compilation(entrypoint, libPath, pkgPath,
-        COMPILER_OPTIONS);
-    _document(compilation);
+  Future documentEntryPoint(Path entrypoint, Path libPath, Path pkgPath) {
+    return documentLibraries(<Path>[entrypoint], libPath, pkgPath);
   }
 
-  void documentLibraries(List<Path> libraryList, Path libPath, Path pkgPath) {
-    final compilation = new Compilation.library(libraryList, libPath, pkgPath,
-        COMPILER_OPTIONS);
-    _document(compilation);
+  Future documentLibraries(List<Path> libraryList, Path libPath, Path pkgPath) {
+    // TODO(amouravski): make all of these print statements into logging
+    // statements.
+    print('Analyzing libraries...');
+    return dart2js.analyze(libraryList, libPath, packageRoot: pkgPath,
+        options: COMPILER_OPTIONS)
+      .then((MirrorSystem mirrors) {
+        print('Generating documentation...');
+        _document(mirrors);
+      });
   }
 
-  void _document(Compilation compilation) {
+  void _document(MirrorSystem mirrors) {
+    _started = true;
+
     // Sort the libraries by name (not key).
     _sortedLibraries = new List<LibraryMirror>.from(
-        compilation.mirrors.libraries.values.where(shouldIncludeLibrary));
+        mirrors.libraries.values.where(shouldIncludeLibrary));
     _sortedLibraries.sort((x, y) {
       return displayName(x).toUpperCase().compareTo(
           displayName(y).toUpperCase());
@@ -442,8 +480,10 @@
     packageManifest.location = revision;
     write(json_serializer.serialize(packageManifest));
     endFile();
+
+    _finished = true;
   }
-  
+
   MdnComment lookupMdnComment(Mirror mirror) => null;
 
   void startFile(String path) {
@@ -578,7 +618,7 @@
         <title>$title / $mainTitle</title>
         <link rel="stylesheet" type="text/css"
             href="${relativePath('styles.css')}">
-        <link href="http://fonts.googleapis.com/css?family=Open+Sans:400,600,700,800" rel="stylesheet" type="text/css">
+        <link href="//fonts.googleapis.com/css?family=Open+Sans:400,600,700,800" rel="stylesheet" type="text/css">
         <link rel="shortcut icon" href="${relativePath('favicon.ico')}">
         ''');
   }
@@ -825,7 +865,7 @@
     // Look for a comment for the entire library.
     final comment = getLibraryComment(library);
     if (comment != null) {
-      writeln('<div class="doc">${markdownFromComment(comment)}</div>');
+      writeln('<div class="doc">${comment.html}</div>');
     }
 
     // Document the top-level members.
@@ -1521,15 +1561,9 @@
     write(')');
   }
 
-  String markdownFromComment(DocComment comment) {
-    return md.markdownToHtml(comment.text,
-        inlineSyntaxes: dartdocSyntaxes,
-        linkResolver: dartdocResolver);
-  }
-
   void docComment(ContainerMirror host, DocComment comment) {
     if (comment != null) {
-      var html = markdownFromComment(comment);
+      var html = comment.html;
 
       if (comment.inheritedFrom != null) {
         writeln('<div class="inherited">');
@@ -1598,7 +1632,8 @@
       }
     }
     if (comment == null) return null;
-    return new DocComment(comment, inheritedFrom);
+    return new DocComment(comment, inheritedFrom, dartdocSyntaxes,
+        dartdocResolver);
   }
 
   /**
@@ -1671,7 +1706,7 @@
   annotateType(ContainerMirror enclosingType,
                TypeMirror type,
                [String paramName = null]) {
-    // Don't bother explicitly displaying Dynamic.
+    // Don't bother explicitly displaying dynamic.
     if (type.isDynamic) {
       if (paramName != null) write(paramName);
       return;
@@ -1701,7 +1736,7 @@
       return;
     }
     if (type.isDynamic) {
-      // Do not generate links for Dynamic.
+      // Do not generate links for dynamic.
       write('dynamic');
       return;
     }
@@ -1988,17 +2023,26 @@
 
 class DocComment {
   final String text;
+  md.Resolver dartdocResolver;
+  List<md.InlineSyntax> dartdocSyntaxes;
 
   /**
    * Non-null if the comment is inherited from another declaration.
    */
   final ClassMirror inheritedFrom;
 
-  DocComment(this.text, [this.inheritedFrom = null]) {
+  DocComment(this.text, [this.inheritedFrom = null, this.dartdocSyntaxes,
+      this.dartdocResolver]) {
     assert(text != null && !text.trim().isEmpty);
   }
 
   String toString() => text;
+
+  String get html {
+    return md.markdownToHtml(text,
+        inlineSyntaxes: dartdocSyntaxes,
+        linkResolver: dartdocResolver);
+  }
 }
 
 class MdnComment implements DocComment {
diff --git a/sdk/lib/_internal/dartdoc/lib/src/client/client-live-nav.dart b/sdk/lib/_internal/dartdoc/lib/src/client/client-live-nav.dart
index a5b04d6..6d0948c 100644
--- a/sdk/lib/_internal/dartdoc/lib/src/client/client-live-nav.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/client/client-live-nav.dart
@@ -37,14 +37,14 @@
   final html = new StringBuffer();
   for (Map libraryInfo in libraries) {
     String libraryName = libraryInfo[NAME];
-    html.add('<h2><div class="icon-library"></div>');
+    html.write('<h2><div class="icon-library"></div>');
     if (currentLibrary == libraryName && currentType == null) {
-      html.add('<strong>${md.escapeHtml(libraryName)}</strong>');
+      html.write('<strong>${md.escapeHtml(libraryName)}</strong>');
     } else {
       final url = getLibraryUrl(libraryName);
-      html.add('<a href="$url">${md.escapeHtml(libraryName)}</a>');
+      html.write('<a href="$url">${md.escapeHtml(libraryName)}</a>');
     }
-    html.add('</h2>');
+    html.write('</h2>');
 
     // Only list the types for the current library.
     if (currentLibrary == libraryName && libraryInfo.containsKey(TYPES)) {
@@ -75,24 +75,24 @@
   if (types.length == 0 && exceptions.length == 0) return;
 
   writeType(String icon, Map typeInfo) {
-    html.add('<li>');
+    html.write('<li>');
     if (currentType == typeInfo[NAME]) {
-      html.add(
+      html.write(
           '<div class="icon-$icon"></div><strong>${getTypeName(typeInfo)}</strong>');
     } else {
-      html.add(
+      html.write(
           '''
           <a href="${getTypeUrl(currentLibrary, typeInfo)}">
             <div class="icon-$icon"></div>${getTypeName(typeInfo)}
           </a>
           ''');
     }
-    html.add('</li>');
+    html.write('</li>');
   }
 
-  html.add('<ul class="icon">');
+  html.write('<ul class="icon">');
   types.forEach((typeInfo) =>
       writeType(kindToString(typeInfo[KIND]), typeInfo));
   exceptions.forEach((typeInfo) => writeType('exception', typeInfo));
-  html.add('</ul>');
+  html.write('</ul>');
 }
diff --git a/sdk/lib/_internal/dartdoc/lib/src/client/dropdown.dart b/sdk/lib/_internal/dartdoc/lib/src/client/dropdown.dart
index b5e877a..8101f5d 100644
--- a/sdk/lib/_internal/dartdoc/lib/src/client/dropdown.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/client/dropdown.dart
@@ -78,7 +78,7 @@
     if (results.length >= 10) {
       var row = table.insertRow(table.rows.length);
       row.innerHtml = '<tr><td>+ ${results.length-10} more.</td></tr>';
-      results = results.getRange(0, 10);
+      results = results.sublist(0, 10);
     }
   }
   dropdown.children = elements;
@@ -360,4 +360,4 @@
   searchInput.onReset.listen(updateDropDown);
   searchInput.onFocus.listen((event) => showDropDown());
   searchInput.onBlur.listen((event) => hideDropDown());
-}
\ No newline at end of file
+}
diff --git a/sdk/lib/_internal/dartdoc/lib/src/client/search.dart b/sdk/lib/_internal/dartdoc/lib/src/client/search.dart
index 9686755..9c439e9 100644
--- a/sdk/lib/_internal/dartdoc/lib/src/client/search.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/client/search.dart
@@ -112,40 +112,40 @@
     row.onClick.listen(clickHandler);
     row.onMouseUp.listen((event) => hideDropDownSuspend = false);
     var sb = new StringBuffer();
-    sb.add('<td class="drop-down-link-td">');
-    sb.add('<table class="drop-down-table"><tr><td colspan="2">');
+    sb.write('<td class="drop-down-link-td">');
+    sb.write('<table class="drop-down-table"><tr><td colspan="2">');
     if (kind == GETTER) {
-      sb.add('get ');
+      sb.write('get ');
     } else if (kind == SETTER) {
-      sb.add('set ');
+      sb.write('set ');
     }
-    sb.add(match.toHtml());
+    sb.write(match.toHtml());
     if (kind == CLASS || kind == INTERFACE || kind == TYPEDEF) {
-      sb.add(args);
+      sb.write(args);
     } else if (kind == CONSTRUCTOR || kind == METHOD) {
       if (noargs) {
-        sb.add("()");
+        sb.write("()");
       } else {
-        sb.add('(...)');
+        sb.write('(...)');
       }
     }
-    sb.add('</td></tr><tr><td class="drop-down-link-kind">');
-    sb.add(kindToString(kind));
+    sb.write('</td></tr><tr><td class="drop-down-link-kind">');
+    sb.write(kindToString(kind));
     if (prefix != null) {
-      sb.add(' in ');
-      sb.add(prefix.toHtml());
-      sb.add(args);
+      sb.write(' in ');
+      sb.write(prefix.toHtml());
+      sb.write(args);
     } else if (type != null) {
-      sb.add(' in ');
-      sb.add(type);
-      sb.add(args);
+      sb.write(' in ');
+      sb.write(type);
+      sb.write(args);
     }
 
-    sb.add('</td><td class="drop-down-link-library">');
+    sb.write('</td><td class="drop-down-link-library">');
     if (library != null) {
-      sb.add('library $library');
+      sb.write('library $library');
     }
-    sb.add('</td></tr></table></td>');
+    sb.write('</td></tr></table></td>');
     row.innerHtml = sb.toString();
   }
 }
diff --git a/sdk/lib/_internal/dartdoc/lib/src/dartdoc/utils.dart b/sdk/lib/_internal/dartdoc/lib/src/dartdoc/utils.dart
index d7595bd..e8cae41 100644
--- a/sdk/lib/_internal/dartdoc/lib/src/dartdoc/utils.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/dartdoc/utils.dart
@@ -68,7 +68,7 @@
 String joinWithCommas(List<String> items, [String conjunction = 'and']) {
   if (items.length == 1) return items[0];
   if (items.length == 2) return "${items[0]} $conjunction ${items[1]}";
-  return '${items.getRange(0, items.length - 1).join(', ')}'
+  return '${items.take(items.length - 1).join(', ')}'
     ', $conjunction ${items[items.length - 1]}';
 }
 
diff --git a/sdk/lib/_internal/dartdoc/lib/src/markdown/inline_parser.dart b/sdk/lib/_internal/dartdoc/lib/src/markdown/inline_parser.dart
index 5faebf2..26c9484 100644
--- a/sdk/lib/_internal/dartdoc/lib/src/markdown/inline_parser.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/markdown/inline_parser.dart
@@ -387,8 +387,7 @@
     int index = parser._stack.indexOf(this);
 
     // Remove the unmatched children.
-    final unmatchedTags = parser._stack.getRange(index + 1,
-        parser._stack.length - index - 1);
+    final unmatchedTags = parser._stack.sublist(index + 1);
     parser._stack.removeRange(index + 1, parser._stack.length - index - 1);
 
     // Flatten them out onto this tag.
diff --git a/sdk/lib/_internal/dartdoc/lib/universe_serializer.dart b/sdk/lib/_internal/dartdoc/lib/universe_serializer.dart
index ea87229..b88c9ea 100755
--- a/sdk/lib/_internal/dartdoc/lib/universe_serializer.dart
+++ b/sdk/lib/_internal/dartdoc/lib/universe_serializer.dart
@@ -8,11 +8,14 @@
  */
 library universe_serializer;
 
+import 'dartdoc.dart';
+
+// TODO(rnystrom): Use "package:" URL (#4968).
+import '../../../../../pkg/pathos/lib/path.dart' as path;
+import '../../compiler/implementation/mirrors/dart2js_mirror.dart' as dart2js;
 import '../../compiler/implementation/mirrors/mirrors.dart';
 import '../../compiler/implementation/mirrors/mirrors_util.dart';
-import '../../compiler/implementation/mirrors/dart2js_mirror.dart' as dart2js;
 import '../../libraries.dart';
-import 'dartdoc.dart';
 
 String _stripUri(String uri) {
   String prefix = "/dart/";
@@ -40,7 +43,7 @@
   final String id;
   /** Raw text of the comment associated with the Element if any. */
   final String comment;
-  /** Raw html comment for the Element from MDN. */ 
+  /** Raw html comment for the Element from MDN. */
   String mdnCommentHtml;
   /**
    * The URL to the page on MDN that content was pulled from for the current
@@ -136,7 +139,7 @@
    * or implemented by classes in this library.
    */
   List<LibraryElement> dependencies;
-  
+
   /**
    * Construct a LibraryElement from a [mirror].
    *
@@ -197,21 +200,30 @@
       // TODO(jacobr): this is a hack. Remove once these libraries are removed
       // from the sdk.
       var uri = mirror.uri;
-      var path = uri.path;
-      var pattern = new RegExp(r'[\\/]dart[\\/]pkg[\\/]([^\\/]+)[\\/]lib[\\/](.+)$');
-      var match = pattern.firstMatch(path);
-      var package;
-      if (match != null) {
-        package = match.group(1);
-        path = match.group(2);
+      var uriPath = uri.path;
+
+      var parts = path.split(uriPath);
+
+      // Find either pkg/ or packages/
+      var pkgDir = parts.lastIndexOf('pkg');
+      var packageDir = parts.lastIndexOf('packages');
+
+      if (pkgDir >= 0) {
+        packageDir = pkgDir;
       }
-      // TODO(jacobr): add a second pattern for a more typical pub environment.
-      if (package != null) {
-        return 'package:$package/$path';
-      } else {
+
+      var libDir = parts.lastIndexOf('lib');
+      var rest = parts.sublist(libDir + 1);
+
+      // If there's no lib, we can't find the package.
+      if (libDir < 0 || libDir < packageDir) {
         // TODO(jacobr): this is a lousy fallback.
-        print("Unable to determine package for $path.");
+        print("Unable to determine package for $uriPath.");
         return mirror.uri.toString();
+      } else if (packageDir >= 0 && rest.length >= 1) {
+        // For URI: foo/bar/packages/widget/lib/sprocket.dart will return:
+        // 'package:widget/sprocket.dart'
+        return 'package:${parts[packageDir + 1]}/${rest.join('/')}';
       }
     } else {
       return mirror.uri.toString();
@@ -253,7 +265,7 @@
   List<Reference> interfaces;
   /** Whether the class implements or extends [Error] or [Exception]. */
   bool isThrowable;
-  
+
   /**
    * Constructs a [ClassElement] from a [ClassMirror].
    *
@@ -393,7 +405,7 @@
    * Returns the initialized field, if this parameter is an initializing formal.
    */
   final Reference initializedField;
-  
+
   ParameterElement(ParameterMirror mirror)
       : super(mirror, 'param', mirror.simpleName, mirror.simpleName, null,
           null),
@@ -402,7 +414,7 @@
         defaultValue = mirror.defaultValue,
         isNamed = _optionalBool(mirror.isNamed),
         initializedField = _optionalReference(mirror.initializedField) {
-              
+
     if (mirror.type is FunctionTypeMirror) {
       addChild(new FunctionTypeElement(mirror.type));
     }
@@ -411,7 +423,7 @@
 
 class FunctionTypeElement extends Element {
   final Reference returnType;
- 
+
   FunctionTypeElement(FunctionTypeMirror mirror)
       : super(mirror, 'functiontype', mirror.simpleName, mirror.simpleName, null, null),
         returnType = _optionalReference(mirror.returnType) {
@@ -431,7 +443,7 @@
 class TypeParameterElement extends Element {
   /**
    * Upper bound for the parameter.
-   * 
+   *
    * In the following code sample, [:Bar:] is an upper bound:
    * [: class Bar<T extends Foo> { } :]
    */
@@ -505,7 +517,7 @@
       }
     }
   }
-  
+
   // TODO(jacobr): compute the referenceId correctly for the general case so
   // that this method can work with all element types not just LibraryElements.
   Reference.fromElement(LibraryElement e) : name = e.name, refId = e.id;
diff --git a/sdk/lib/_internal/dartdoc/test/dartdoc_test.dart b/sdk/lib/_internal/dartdoc/test/dartdoc_test.dart
index 18d44cc..e588aa5 100644
--- a/sdk/lib/_internal/dartdoc/test/dartdoc_test.dart
+++ b/sdk/lib/_internal/dartdoc/test/dartdoc_test.dart
@@ -17,7 +17,15 @@
 // TODO(rnystrom): Better path to unittest.
 import '../../../../../pkg/unittest/lib/unittest.dart';
 
+// Pretty test config with --human
+import '../../../../../utils/tests/pub/command_line_config.dart';
+
 main() {
+  // Use the human-friendly config.
+  if (new Options().arguments.contains('--human')) {
+    configure(new CommandLineConfiguration());
+  }
+
   group('countOccurrences', () {
     test('empty text returns 0', () {
       expect(dd.countOccurrences('', 'needle'), equals(0));
@@ -198,26 +206,40 @@
 
   group('integration tests', () {
     test('no entrypoints', () {
-      expect(_runDartdoc([], exitCode: 1), completes);
+      _testRunDartDoc([], (result) {
+            expect(result.exitCode, 1);
+          });
     });
 
-    test('library with no packages', () {
-      expect(_runDartdoc(
-          [new Path('test/test_files/other_place/'
-              'no_package_test_file.dart').toNativePath()]),
-        completes);
+    test('entrypoint in lib', () {
+      _testRunDartDoc(['test_files/lib/no_package_test_file.dart'], (result) {
+        expect(result.exitCode, 0);
+        _expectDocumented(result.stdout, libCount: 1, typeCount: 1, memberCount: 0);
+      });
     });
 
-    test('library with packages', () {
-      expect(_runDartdoc(
-          [new Path('test/test_files/'
-              'package_test_file.dart').toNativePath()]),
-        completes);
+    test('entrypoint somewhere with packages locally', () {
+      _testRunDartDoc(['test_files/package_test_file.dart'], (result) {
+        expect(result.exitCode, 0);
+        _expectDocumented(result.stdout, libCount: 1, typeCount: 1, memberCount: 0);
+      });
+    });
+
+    test('file does not exist', () {
+      _testRunDartDoc(['test_files/this_file_does_not_exist.dart'], (result) {
+        expect(result.exitCode, 1);
+      });
     });
   });
 }
 
-Future _runDartdoc(List<String> arguments, {int exitCode: 0}) {
+void _testRunDartDoc(List<String> libraryPaths, void eval(ProcessResult)) {
+  expect(_runDartdoc(libraryPaths).then(eval), completes);
+}
+
+/// Runs dartdoc with the libraryPaths provided, and completes to dartdoc's
+/// ProcessResult.
+Future<ProcessResult> _runDartdoc(List<String> libraryPaths) {
   var dartBin = new Options().executable;
 
   var dir = path.absolute(new Options().script);
@@ -227,15 +249,48 @@
     }
     dir = path.dirname(dir);
   }
-
   var dartdoc = path.join(path.absolute(dir), 'bin/dartdoc.dart');
-  arguments.insertRange(0, 1, dartdoc);
-  return Process.run(dartBin, arguments)
-      .then((result) {
-        expect(result.exitCode, exitCode);
-      });
+
+  final runArgs = [dartdoc];
+
+  // Turn relative libraryPaths to absolute ones.
+  runArgs.addAll(libraryPaths
+      .map((e) => path.join(dd.scriptDir.toNativePath(), e)));
+
+  return Process.run(dartBin, runArgs);
 }
 
+final _dartdocCompletionRegExp =
+  new RegExp(r'Documentation complete -- documented (\d+) libraries, (\d+) types, and (\d+) members\.');
+
+void _expectDocumented(String output, { int libCount, int typeCount,
+  int memberCount}) {
+
+  final completionMatches = _dartdocCompletionRegExp.allMatches(output)
+      .toList();
+
+  expect(completionMatches, hasLength(1),
+      reason: 'dartdoc output should contain one summary');
+
+  final completionMatch = completionMatches.single;
+
+  if(libCount != null) {
+    expect(int.parse(completionMatch[1]), libCount,
+        reason: 'expected library count');
+  }
+
+  if(typeCount != null) {
+    expect(int.parse(completionMatch[2]), typeCount,
+        reason: 'expected type count');
+  }
+
+  if(memberCount != null) {
+    expect(int.parse(completionMatch[3]), memberCount,
+        reason: 'expected member count');
+  }
+}
+
+
 validateDartdocMarkdown(String description, String markdown,
     String html) {
   var dartdoc = new dd.Dartdoc();
diff --git a/sdk/lib/_internal/dartdoc/test/test_files/other_place/no_package_test_file.dart b/sdk/lib/_internal/dartdoc/test/test_files/lib/no_package_test_file.dart
similarity index 94%
rename from sdk/lib/_internal/dartdoc/test/test_files/other_place/no_package_test_file.dart
rename to sdk/lib/_internal/dartdoc/test/test_files/lib/no_package_test_file.dart
index da52a19..99a30ba 100644
--- a/sdk/lib/_internal/dartdoc/test/test_files/other_place/no_package_test_file.dart
+++ b/sdk/lib/_internal/dartdoc/test/test_files/lib/no_package_test_file.dart
@@ -1,5 +1,5 @@
 library no_package_test;
 
 class NoPackageTestFile {
-  
+
 }
diff --git a/sdk/lib/_internal/libraries.dart b/sdk/lib/_internal/libraries.dart
index b8146bb..2c5891c 100644
--- a/sdk/lib/_internal/libraries.dart
+++ b/sdk/lib/_internal/libraries.dart
@@ -89,6 +89,10 @@
       category: "Server",
       dart2jsPatchPath: "_internal/compiler/implementation/lib/scalarlist_patch.dart"),
 
+  "typeddata": const LibraryInfo(
+      "typeddata/typeddata.dart",
+      dart2jsPatchPath: "_internal/compiler/implementation/lib/typeddata_patch.dart"),
+
   "svg": const LibraryInfo(
         "svg/dartium/svg_dartium.dart",
         category: "Client",
@@ -152,7 +156,8 @@
 
   /**
    * The category in which the library should appear in the editor
-   * (e.g. "Common", "Client", "Server", ...).
+   * (e.g. "Shared", "Client", "Server", ...).
+   * If a category is not specified it defaults to "Shared".
    */
   final String category;
 
diff --git a/sdk/lib/async/async.dart b/sdk/lib/async/async.dart
index d6144af..c447440 100644
--- a/sdk/lib/async/async.dart
+++ b/sdk/lib/async/async.dart
@@ -7,6 +7,7 @@
 part 'async_error.dart';
 part 'collection_sink.dart';
 part 'deferred_load.dart';
+part 'event_loop.dart';
 part 'future.dart';
 part 'future_impl.dart';
 part 'stream.dart';
diff --git a/sdk/lib/async/async_sources.gypi b/sdk/lib/async/async_sources.gypi
index 7fdd956..a10ee93 100644
--- a/sdk/lib/async/async_sources.gypi
+++ b/sdk/lib/async/async_sources.gypi
@@ -10,6 +10,7 @@
     'async_error.dart',
     'collection_sink.dart',
     'deferred_load.dart',
+    'event_loop.dart',
     'future.dart',
     'future_impl.dart',
     'stream.dart',
diff --git a/sdk/lib/async/collection_sink.dart b/sdk/lib/async/collection_sink.dart
index a023fd1..ad3dda5 100644
--- a/sdk/lib/async/collection_sink.dart
+++ b/sdk/lib/async/collection_sink.dart
@@ -7,8 +7,9 @@
 typedef void _CollectionSinkCallback<T>(Collection<T> collection);
 typedef void _CollectionSinkErrorCallback(AsyncError error);
 
-/** StreamSink that stores incoming data in a collection. */
-class CollectionSink<T> implements StreamSink<T> {
+/** EventSink that stores incoming data in a collection. */
+class CollectionSink<T> extends StreamSink<T> {
+  // TODO(8997): Implement EventSink instead.
   final Collection<T> collection;
   final _CollectionSinkCallback<T> _callback;
   final _CollectionSinkErrorCallback _errorCallback;
@@ -33,8 +34,8 @@
     collection.add(value);
   }
 
-  void signalError(AsyncError error) {
-    if (_isClosed) throw new StateError("Singalling error on closed sink");
+  void addError(AsyncError error) {
+    if (_isClosed) throw new StateError("Adding error to closed sink");
     if (_errorCallback != null) _errorCallback(error);
   }
 
diff --git a/sdk/lib/async/event_loop.dart b/sdk/lib/async/event_loop.dart
new file mode 100644
index 0000000..3ceccd2
--- /dev/null
+++ b/sdk/lib/async/event_loop.dart
@@ -0,0 +1,73 @@
+// 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.
+
+part of dart.async;
+
+typedef void _AsyncCallback();
+
+bool _callbacksAreEnqueued = false;
+List<_AsyncCallback> _asyncCallbacks = <_AsyncCallback>[];
+
+void _asyncRunCallback() {
+  // As long as we are iterating over the registered callbacks we don't
+  // unset the [_callbacksAreEnqueued] boolean.
+  while (!_asyncCallbacks.isEmpty) {
+    List callbacks = _asyncCallbacks;
+    // The callbacks we execute can register new callbacks. This means that
+    // the for-loop below could grow the list if we don't replace it here.
+    _asyncCallbacks = <_AsyncCallback>[];
+    for (int i = 0; i < callbacks.length; i++) {
+      Function callback = callbacks[i];
+      callbacks[i] = null;
+      try {
+        callback();
+      } catch (e) {
+        i++;  // Skip current callback.
+        List remainingCallbacks = callbacks.sublist(i);
+        List newCallbacks = _asyncCallbacks;
+        _asyncCallbacks = <_AsyncCallback>[];
+        _asyncCallbacks.addAll(remainingCallbacks);
+        _asyncCallbacks.addAll(newCallbacks);
+        _AsyncRun._enqueueImmediate(_asyncRunCallback);
+        throw;
+      }
+    }
+  }
+  // Any new callback must register a callback function now.
+  _callbacksAreEnqueued = false;
+}
+
+/**
+ * Runs the given [callback] asynchronously.
+ *
+ * Callbacks registered through this function are always executed in order and
+ * are guaranteed to run before other asynchronous events (like [Timer] events,
+ * or DOM events).
+ *
+ * Warning: it is possible to starve the DOM by registering asynchronous
+ * callbacks through this method. For example the following program will
+ * run the callbacks without ever giving the Timer callback a chance to execute:
+ *
+ *     Timer.run(() { print("executed"); });  // Will never be executed;
+ *     foo() {
+ *       asyncRun(foo);  // Schedules [foo] in front of other events.
+ *     }
+ *     main() {
+ *       foo();
+ *     }
+ */
+void runAsync(void callback()) {
+  // Optimizing a group of Timer.run callbacks to be executed in the
+  // same Timer callback.
+  _asyncCallbacks.add(callback);
+  if (!_callbacksAreEnqueued) {
+    _AsyncRun._enqueueImmediate(_asyncRunCallback);
+    _callbacksAreEnqueued = true;
+  }
+}
+
+class _AsyncRun {
+  /** Enqueues the given callback before any other event in the event-loop. */
+  external static void _enqueueImmediate(void callback());
+}
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index 185ce2a..759f9c7 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -68,7 +68,7 @@
         stream._close();
       },
       onError: (error) {
-        stream._signalError(error);
+        stream._addError(error);
         stream._close();
       });
     return stream;
@@ -83,6 +83,67 @@
   }
 
   /**
+   * Creates a stream that repeatedly emits events at [period] intervals.
+   *
+   * The event values are computed by invoking [computation]. The argument to
+   * this callback is an integer that starts with 0 and is incremented for
+   * every event.
+   *
+   * If [computation] is omitted the event values will all be `null`.
+   */
+  factory Stream.periodic(Duration period,
+                          [T computation(int computationCount)]) {
+    if (computation == null) computation = ((i) => null);
+
+    Timer timer;
+    int computationCount = 0;
+    StreamController<T> controller;
+    // Counts the time that the Stream was running (and not paused).
+    Stopwatch watch = new Stopwatch();
+
+    void sendEvent() {
+      watch.reset();
+      T data = computation(computationCount++);
+      controller.add(data);
+    }
+
+    void startPeriodicTimer() {
+      assert(timer == null);
+      timer = new Timer.periodic(period, (Timer timer) {
+        sendEvent();
+      });
+    }
+
+    controller = new StreamController<T>(
+        onPauseStateChange: () {
+          if (controller.isPaused) {
+            timer.cancel();
+            timer = null;
+            watch.stop();
+          } else {
+            assert(timer == null);
+            Duration elapsed = watch.elapsed;
+            watch.start();
+            timer = new Timer(period - elapsed, () {
+              timer = null;
+              startPeriodicTimer();
+              sendEvent();
+            });
+          }
+        },
+        onSubscriptionStateChange: () {
+          if (controller.hasSubscribers) {
+            watch.start();
+            startPeriodicTimer();
+          } else {
+            if (timer != null) timer.cancel();
+            timer = null;
+          }
+        });
+    return controller.stream;
+  }
+
+  /**
    * Reports whether this stream is a broadcast stream.
    */
   bool get isBroadcast => false;
@@ -214,13 +275,13 @@
   }
 
   // Deprecated method, previously called 'pipe', retained for compatibility.
-  Future pipeInto(StreamSink<T> sink,
+  Future pipeInto(EventSink<T> sink,
                   {void onError(AsyncError error),
                    bool unsubscribeOnError}) {
     _FutureImpl<T> result = new _FutureImpl<T>();
     this.listen(
         sink.add,
-        onError: sink.signalError,
+        onError: sink.addError,
         onDone: () {
           sink.close();
           result._setValue(null);
@@ -350,6 +411,8 @@
    * be a [Comparator]).
    *
    * If [compare] is omitted, it defaults to [Comparable.compare].
+   *
+   * *Deprecated*. Use [reduce] with a binary min method if needed.
    */
   Future<T> min([int compare(T a, T b)]) {
     if (compare == null) {
@@ -394,6 +457,8 @@
    * be a [Comparator]).
    *
    * If [compare] is omitted, it defaults to [Comparable.compare].
+   *
+   * *Deprecated*. Use [reduce] with a binary max method if needed.
    */
   Future<T> max([int compare(T a, T b)]) {
     if (compare == null)  {
@@ -643,7 +708,7 @@
    * with no [defaultValue] function provided, the future will receive an
    * error.
    */
-  Future<T> firstMatching(bool test(T value), {T defaultValue()}) {
+  Future<T> firstWhere(bool test(T value), {T defaultValue()}) {
     _FutureImpl<T> future = new _FutureImpl<T>();
     StreamSubscription subscription;
     subscription = this.listen(
@@ -677,11 +742,11 @@
   /**
    * Finds the last element in this stream matching [test].
    *
-   * As [firstMatching], except that the last matching element is found.
+   * As [firstWhere], except that the last matching element is found.
    * That means that the result cannot be provided before this stream
    * is done.
    */
-  Future<T> lastMatching(bool test(T value), {T defaultValue()}) {
+  Future<T> lastWhere(bool test(T value), {T defaultValue()}) {
     _FutureImpl<T> future = new _FutureImpl<T>();
     T result = null;
     bool foundResult = false;
@@ -724,7 +789,7 @@
    * Like [lastMatch], except that it is an error if more than one
    * matching element occurs in the stream.
    */
-  Future<T> singleMatching(bool test(T value)) {
+  Future<T> singleWhere(bool test(T value)) {
     _FutureImpl<T> future = new _FutureImpl<T>();
     T result = null;
     bool foundResult = false;
@@ -844,15 +909,28 @@
 
 
 /**
- * An interface that abstracts sending events into a [Stream].
+ * *Deprecated*. Use [EventSink] instead.
  */
-abstract class StreamSink<T> {
+abstract class StreamSink<T> extends EventSink<T>{
+  /* TODO(8997): Remove class.*/
+  /** *Deprecated*. Use [EventSink.addError] instead.*/
+  void signalError(AsyncError errorEvent) { addError(errorEvent); }
+}
+
+
+/**
+ * An interface that abstracts creation or handling of [Stream] events.
+ */
+abstract class EventSink<T> {
+  /** Create a data event */
   void add(T event);
-  /** Signal an async error to the receivers of this sink's values. */
-  void signalError(AsyncError errorEvent);
+  /** Create an async error. */
+  void addError(AsyncError errorEvent);
+  /** Request a stream to close. */
   void close();
 }
 
+
 /** [Stream] wrapper that only exposes the [Stream] interface. */
 class StreamView<T> extends Stream<T> {
   Stream<T> _stream;
@@ -873,15 +951,16 @@
 }
 
 /**
- * [StreamSink] wrapper that only exposes the [StreamSink] interface.
+ * [EventSink] wrapper that only exposes the [EventSink] interface.
  */
-class StreamSinkView<T> implements StreamSink<T> {
-  final StreamSink<T> _sink;
+class EventSinkView<T> extends StreamSink<T> {
+  // TODO(8997): Implment EventSink instead.
+  final EventSink<T> _sink;
 
-  StreamSinkView(this._sink);
+  EventSinkView(this._sink);
 
   void add(T value) { _sink.add(value); }
-  void signalError(AsyncError error) { _sink.signalError(error); }
+  void addError(AsyncError error) { _sink.addError(error); }
   void close() { _sink.close(); }
 }
 
@@ -916,16 +995,16 @@
    * Example use:
    *
    *     stringStream.transform(new StreamTransformer<String, String>(
-   *         handleData: (Strung value, StreamSink<String> sink) {
+   *         handleData: (Strung value, EventSink<String> sink) {
    *           sink.add(value);
    *           sink.add(value);  // Duplicate the incoming events.
    *         }));
    *
    */
   factory StreamTransformer({
-      void handleData(S data, StreamSink<T> sink),
-      void handleError(AsyncError error, StreamSink<T> sink),
-      void handleDone(StreamSink<T> sink)}) {
+      void handleData(S data, EventSink<T> sink),
+      void handleError(AsyncError error, EventSink<T> sink),
+      void handleDone(EventSink<T> sink)}) {
     return new _StreamTransformerImpl<S, T>(handleData,
                                             handleError,
                                             handleDone);
@@ -950,7 +1029,7 @@
  * An example that duplicates all data events:
  *
  *     class DoubleTransformer<T> extends StreamEventTransformerBase<T, T> {
- *       void handleData(T data, StreamSink<T> sink) {
+ *       void handleData(T data, EventSink<T> sink) {
  *         sink.add(value);
  *         sink.add(value);
  *       }
@@ -974,7 +1053,7 @@
    * The method may generate any number of events on the sink, but should
    * not throw.
    */
-  void handleData(S event, StreamSink<T> sink) {
+  void handleData(S event, EventSink<T> sink) {
     var data = event;
     sink.add(data);
   }
@@ -985,8 +1064,8 @@
    * The method may generate any number of events on the sink, but should
    * not throw.
    */
-  void handleError(AsyncError error, StreamSink<T> sink) {
-    sink.signalError(error);
+  void handleError(AsyncError error, EventSink<T> sink) {
+    sink.addError(error);
   }
 
   /**
@@ -995,7 +1074,7 @@
    * The method may generate any number of events on the sink, but should
    * not throw.
    */
-  void handleDone(StreamSink<T> sink){
+  void handleDone(EventSink<T> sink){
     sink.close();
   }
 }
@@ -1029,15 +1108,15 @@
 
 class _EventTransformStreamSubscription<S, T>
     extends _BaseStreamSubscription<T>
-    implements _StreamOutputSink<T> {
+    implements _EventOutputSink<T> {
   /** The transformer used to transform events. */
   final StreamEventTransformer<S, T> _transformer;
   /** Whether to unsubscribe when emitting an error. */
   final bool _unsubscribeOnError;
   /** Source of incoming events. */
   StreamSubscription<S> _subscription;
-  /** Cached StreamSink wrapper for this class. */
-  StreamSink<T> _sink;
+  /** Cached EventSink wrapper for this class. */
+  EventSink<T> _sink;
 
   _EventTransformStreamSubscription(Stream<S> source,
                                     this._transformer,
@@ -1046,7 +1125,7 @@
                                     void onDone(),
                                     this._unsubscribeOnError)
       : super(onData, onError, onDone) {
-    _sink = new _StreamOutputSinkWrapper<T>(this);
+    _sink = new _EventOutputSinkWrapper<T>(this);
     _subscription = source.listen(_handleData,
                                   onError: _handleError,
                                   onDone: _handleDone);
@@ -1092,7 +1171,7 @@
     }
   }
 
-  // StreamOutputSink interface.
+  // EventOutputSink interface.
   void _sendData(T data) {
     _onData(data);
   }
@@ -1111,11 +1190,12 @@
   }
 }
 
-class _StreamOutputSinkWrapper<T> implements StreamSink<T> {
-  _StreamOutputSink _sink;
-  _StreamOutputSinkWrapper(this._sink);
+/* TODO(8997): Implement EventSink instead, */
+class _EventOutputSinkWrapper<T> extends StreamSink<T> {
+  _EventOutputSink _sink;
+  _EventOutputSinkWrapper(this._sink);
 
-  void add(T data) => _sink._sendData(data);
-  void signalError(AsyncError error) => _sink._sendError(error);
-  void close() => _sink._sendDone();
+  void add(T data) { _sink._sendData(data); }
+  void addError(AsyncError error) { _sink._sendError(error); }
+  void close() { _sink._sendDone(); }
 }
diff --git a/sdk/lib/async/stream_controller.dart b/sdk/lib/async/stream_controller.dart
index 9ea10f5..5097da6 100644
--- a/sdk/lib/async/stream_controller.dart
+++ b/sdk/lib/async/stream_controller.dart
@@ -46,7 +46,8 @@
  * the stream at all, and won't trigger callbacks. From the controller's point
  * of view, the stream is completely inert when has completed.
  */
-class StreamController<T> implements StreamSink<T> {
+class StreamController<T> extends StreamSink<T> {
+  // TODO(8997): Implement EventSink instead.
   final _StreamImpl<T> stream;
 
   /**
@@ -85,9 +86,9 @@
                                                 onPauseStateChange);
 
   /**
-   * Returns a view of this object that only exposes the [StreamSink] interface.
+   * Returns a view of this object that only exposes the [EventSink] interface.
    */
-  StreamSink<T> get sink => new StreamSinkView<T>(this);
+  EventSink<T> get sink => new EventSinkView<T>(this);
 
   /**
    * Whether the stream is closed for adding more events.
@@ -120,14 +121,14 @@
    * If a subscription has requested to be unsubscribed on errors,
    * it will be unsubscribed after receiving this event.
    */
-  void signalError(Object error, [Object stackTrace]) {
+  void addError(Object error, [Object stackTrace]) {
     AsyncError asyncError;
     if (error is AsyncError) {
       asyncError = error;
     } else {
       asyncError = new AsyncError(error, stackTrace);
     }
-    stream._signalError(asyncError);
+    stream._addError(asyncError);
   }
 
   /**
@@ -148,11 +149,23 @@
   _MultiControllerStream(this._subscriptionHandler, this._pauseHandler);
 
   void _onSubscriptionStateChange() {
-    if (_subscriptionHandler != null) _subscriptionHandler();
+    if (_subscriptionHandler != null) {
+      try {
+        _subscriptionHandler();
+      } catch (e, s) {
+        new AsyncError(e, s).throwDelayed();
+      }
+    }
   }
 
   void _onPauseStateChange() {
-    if (_pauseHandler != null) _pauseHandler();
+    if (_pauseHandler != null) {
+      try {
+        _pauseHandler();
+      } catch (e, s) {
+        new AsyncError(e, s).throwDelayed();
+      }
+    }
   }
 }
 
@@ -163,10 +176,22 @@
   _SingleControllerStream(this._subscriptionHandler, this._pauseHandler);
 
   void _onSubscriptionStateChange() {
-    if (_subscriptionHandler != null) _subscriptionHandler();
+    if (_subscriptionHandler != null) {
+      try {
+        _subscriptionHandler();
+      } catch (e, s) {
+        new AsyncError(e, s).throwDelayed();
+      }
+    }
   }
 
   void _onPauseStateChange() {
-    if (_pauseHandler != null) _pauseHandler();
+    if (_pauseHandler != null) {
+      try {
+        _pauseHandler();
+      } catch (e, s) {
+        new AsyncError(e, s).throwDelayed();
+      }
+    }
   }
 }
diff --git a/sdk/lib/async/stream_impl.dart b/sdk/lib/async/stream_impl.dart
index ccaa506..1563abd 100644
--- a/sdk/lib/async/stream_impl.dart
+++ b/sdk/lib/async/stream_impl.dart
@@ -66,7 +66,7 @@
   /**
    * List of pending events.
    *
-   * If events are added to the stream (using [_add], [_signalError] or [_done])
+   * If events are added to the stream (using [_add], [_addError] or [_done])
    * while the stream is paused, or while another event is firing, events will
    * stored here.
    * Also supports scheduling the events for later execution.
@@ -94,7 +94,7 @@
   }
 
   // ------------------------------------------------------------------
-  // StreamSink interface-like methods for sending events into the stream.
+  // EventSink interface-like methods for sending events into the stream.
   // It's the responsibility of the caller to ensure that the stream is not
   // paused when adding events. If the stream is paused, the events will be
   // queued, but it's better to not send events at all.
@@ -123,7 +123,7 @@
    * If a subscription has requested to be unsubscribed on errors,
    * it will be unsubscribed after receiving this event.
    */
-  void _signalError(AsyncError error) {
+  void _addError(AsyncError error) {
     if (_isClosed) throw new StateError("Sending on closed stream");
     if (!_mayFireState) {
       // Not the time to send events.
@@ -562,7 +562,7 @@
  *
  * The user interface of [_SingleStreamImpl] are the following methods:
  * * [_add]: Add a data event to the stream.
- * * [_signalError]: Add an error event to the stream.
+ * * [_addError]: Add an error event to the stream.
  * * [_close]: Request to close the stream.
  * * [_onSubscriberStateChange]: Called when receiving the first subscriber or
  *                               when losing the last subscriber.
@@ -676,7 +676,7 @@
  *
  * The user interface of [_MultiStreamImpl] are the following methods:
  * * [_add]: Add a data event to the stream.
- * * [_signalError]: Add an error event to the stream.
+ * * [_addError]: Add an error event to the stream.
  * * [_close]: Request to close the stream.
  * * [_onSubscriptionStateChange]: Called when receiving the first subscriber or
  *                                 when losing the last subscriber.
@@ -841,7 +841,7 @@
     throw new UnsupportedError("Cannot inject events into generated stream");
   }
 
-  void _signalError(AsyncError value) {
+  void _addError(AsyncError value) {
     throw new UnsupportedError("Cannot inject events into generated stream");
   }
 
@@ -1098,14 +1098,14 @@
 }
 
 /** Abstract type for an internal interface for sending events. */
-abstract class _StreamOutputSink<T> {
+abstract class _EventOutputSink<T> {
   _sendData(T data);
   _sendError(AsyncError error);
   _sendDone();
 }
 
 abstract class _StreamListener<T> extends _InternalLink
-                                  implements _StreamOutputSink<T> {
+                                  implements _EventOutputSink<T> {
   final _StreamImpl _source;
   int _state = _LISTENER_UNSUBSCRIBED;
 
@@ -1332,7 +1332,7 @@
     if (_hasSubscribers) {
       assert(_subscription == null);
       _subscription = _source.listen(this._add,
-                                     onError: this._signalError,
+                                     onError: this._addError,
                                      onDone: this._close);
     } else {
       // TODO(lrn): Check why this can happen.
diff --git a/sdk/lib/async/stream_pipe.dart b/sdk/lib/async/stream_pipe.dart
index aaa34b0..69210ec 100644
--- a/sdk/lib/async/stream_pipe.dart
+++ b/sdk/lib/async/stream_pipe.dart
@@ -74,16 +74,16 @@
 
   // Override the following methods in subclasses to change the behavior.
 
-  void _handleData(S data, _StreamOutputSink<T> sink) {
+  void _handleData(S data, _EventOutputSink<T> sink) {
     var outputData = data;
     sink._sendData(outputData);
   }
 
-  void _handleError(AsyncError error, _StreamOutputSink<T> sink) {
+  void _handleError(AsyncError error, _EventOutputSink<T> sink) {
     sink._sendError(error);
   }
 
-  void _handleDone(_StreamOutputSink<T> sink) {
+  void _handleDone(_EventOutputSink<T> sink) {
     sink._sendDone();
   }
 }
@@ -136,7 +136,7 @@
  * Abstract superclass for subscriptions that forward to other subscriptions.
  */
 class _ForwardingStreamSubscription<S, T>
-    extends _BaseStreamSubscription<T> implements _StreamOutputSink<T> {
+    extends _BaseStreamSubscription<T> implements _EventOutputSink<T> {
   final _ForwardingStream<S, T> _stream;
   final bool _unsubscribeOnError;
 
@@ -179,7 +179,7 @@
     _subscription = null;
   }
 
-  // _StreamOutputSink interface. Sends data to this subscription.
+  // _EventOutputSink interface. Sends data to this subscription.
 
   void _sendData(T data) {
     _onData(data);
@@ -233,7 +233,7 @@
   _WhereStream(Stream<T> source, bool test(T value))
       : _test = test, super(source);
 
-  void _handleData(T inputEvent, _StreamOutputSink<T> sink) {
+  void _handleData(T inputEvent, _EventOutputSink<T> sink) {
     bool satisfies;
     try {
       satisfies = _test(inputEvent);
@@ -259,7 +259,7 @@
   _MapStream(Stream<S> source, T transform(S event))
       : this._transform = transform, super(source);
 
-  void _handleData(S inputEvent, _StreamOutputSink<T> sink) {
+  void _handleData(S inputEvent, _EventOutputSink<T> sink) {
     T outputEvent;
     try {
       outputEvent = _transform(inputEvent);
@@ -280,7 +280,7 @@
   _ExpandStream(Stream<S> source, Iterable<T> expand(S event))
       : this._expand = expand, super(source);
 
-  void _handleData(S inputEvent, _StreamOutputSink<T> sink) {
+  void _handleData(S inputEvent, _EventOutputSink<T> sink) {
     try {
       for (T value in _expand(inputEvent)) {
         sink._sendData(value);
@@ -310,7 +310,7 @@
                     bool test(error))
       : this._transform = transform, this._test = test, super(source);
 
-  void _handleError(AsyncError error, _StreamOutputSink<T> sink) {
+  void _handleError(AsyncError error, _EventOutputSink<T> sink) {
     bool matches = true;
     if (_test != null) {
       try {
@@ -344,7 +344,7 @@
     if (count is! int) throw new ArgumentError(count);
   }
 
-  void _handleData(T inputEvent, _StreamOutputSink<T> sink) {
+  void _handleData(T inputEvent, _EventOutputSink<T> sink) {
     if (_remaining > 0) {
       sink._sendData(inputEvent);
       _remaining -= 1;
@@ -364,7 +364,7 @@
   _TakeWhileStream(Stream<T> source, bool test(T value))
       : this._test = test, super(source);
 
-  void _handleData(T inputEvent, _StreamOutputSink<T> sink) {
+  void _handleData(T inputEvent, _EventOutputSink<T> sink) {
     bool satisfies;
     try {
       satisfies = _test(inputEvent);
@@ -392,7 +392,7 @@
     if (count is! int || count < 0) throw new ArgumentError(count);
   }
 
-  void _handleData(T inputEvent, _StreamOutputSink<T> sink) {
+  void _handleData(T inputEvent, _EventOutputSink<T> sink) {
     if (_remaining > 0) {
       _remaining--;
       return;
@@ -408,7 +408,7 @@
   _SkipWhileStream(Stream<T> source, bool test(T value))
       : this._test = test, super(source);
 
-  void _handleData(T inputEvent, _StreamOutputSink<T> sink) {
+  void _handleData(T inputEvent, _EventOutputSink<T> sink) {
     if (_hasFailed) {
       sink._sendData(inputEvent);
     }
@@ -439,7 +439,7 @@
   _DistinctStream(Stream<T> source, bool equals(T a, T b))
       : _equals = equals, super(source);
 
-  void _handleData(T inputEvent, _StreamOutputSink<T> sink) {
+  void _handleData(T inputEvent, _EventOutputSink<T> sink) {
     if (identical(_previous, _SENTINEL)) {
       _previous = inputEvent;
       return sink._sendData(inputEvent);
@@ -465,35 +465,26 @@
 
 // Stream transformations and event transformations.
 
-typedef void _TransformDataHandler<S, T>(S data, StreamSink<T> sink);
-typedef void _TransformErrorHandler<T>(AsyncError data, StreamSink<T> sink);
-typedef void _TransformDoneHandler<T>(StreamSink<T> sink);
+typedef void _TransformDataHandler<S, T>(S data, EventSink<T> sink);
+typedef void _TransformErrorHandler<T>(AsyncError data, EventSink<T> sink);
+typedef void _TransformDoneHandler<T>(EventSink<T> sink);
 
 /** Default data handler forwards all data. */
-void _defaultHandleData(var data, StreamSink sink) {
+void _defaultHandleData(var data, EventSink sink) {
   sink.add(data);
 }
 
 /** Default error handler forwards all errors. */
-void _defaultHandleError(AsyncError error, StreamSink sink) {
-  sink.signalError(error);
+void _defaultHandleError(AsyncError error, EventSink sink) {
+  sink.addError(error);
 }
 
 /** Default done handler forwards done. */
-void _defaultHandleDone(StreamSink sink) {
+void _defaultHandleDone(EventSink sink) {
   sink.close();
 }
 
 
-/** Creates a [StreamSink] from a [_StreamImpl]'s input methods. */
-class _StreamImplSink<T> implements StreamSink<T> {
-  _StreamImpl<T> _target;
-  _StreamImplSink(this._target);
-  void add(T data) { _target._add(data); }
-  void signalError(AsyncError error) { _target._signalError(error); }
-  void close() { _target._close(); }
-}
-
 /**
  * A [StreamTransformer] that modifies stream events.
  *
@@ -511,9 +502,9 @@
   final _TransformErrorHandler<T> _handleError;
   final _TransformDoneHandler<T> _handleDone;
 
-  _StreamTransformerImpl(void handleData(S data, StreamSink<T> sink),
-                         void handleError(AsyncError data, StreamSink<T> sink),
-                         void handleDone(StreamSink<T> sink))
+  _StreamTransformerImpl(void handleData(S data, EventSink<T> sink),
+                         void handleError(AsyncError data, EventSink<T> sink),
+                         void handleDone(EventSink<T> sink))
       : this._handleData  = (handleData == null  ? _defaultHandleData
                                                  : handleData),
         this._handleError = (handleError == null ? _defaultHandleError
@@ -521,15 +512,15 @@
         this._handleDone  = (handleDone == null  ? _defaultHandleDone
                                                  : handleDone);
 
-  void handleData(S data, StreamSink<T> sink) {
+  void handleData(S data, EventSink<T> sink) {
     _handleData(data, sink);
   }
 
-  void handleError(AsyncError error, StreamSink<T> sink) {
+  void handleError(AsyncError error, EventSink<T> sink) {
     _handleError(error, sink);
   }
 
-  void handleDone(StreamSink<T> sink) {
+  void handleDone(EventSink<T> sink) {
     _handleDone(sink);
   }
 }
diff --git a/sdk/lib/async/timer.dart b/sdk/lib/async/timer.dart
index 7ed5d5a..33bbb47 100644
--- a/sdk/lib/async/timer.dart
+++ b/sdk/lib/async/timer.dart
@@ -36,8 +36,8 @@
    * The [callback] is invoked repeatedly with [duration] intervals until
    * canceled. A negative duration is treated similar to a duration of 0.
    */
-  external factory Timer.repeating(Duration duration,
-                                   void callback(Timer timer));
+  external factory Timer.periodic(Duration duration,
+                                  void callback(Timer timer));
 
   /**
    * Runs the given [callback] asynchronously as soon as possible.
@@ -59,7 +59,9 @@
           } catch (e) {
             List newCallbacks = _runCallbacks;
             _runCallbacks = [];
-            _runCallbacks.addAll(runCallbacks.skip(i + 1));
+            i++;  // Skip the current;
+            _runCallbacks.addAll(
+                runCallbacks.sublist(i));
             _runCallbacks.addAll(newCallbacks);
             throw;
           }
diff --git a/sdk/lib/collection/collections.dart b/sdk/lib/collection/collections.dart
index 09a0778..5d84317 100644
--- a/sdk/lib/collection/collections.dart
+++ b/sdk/lib/collection/collections.dart
@@ -74,13 +74,13 @@
     } else {
       setToRemove = elementsToRemove.toSet();
     }
-    collection.removeMatching(setToRemove.contains);
+    collection.removeWhere(setToRemove.contains);
   }
 
   /**
    * Simple implemenation for [Collection.retainAll].
    *
-   * This implementation assumes that [Collecton.retainMatching] on [collection]
+   * This implementation assumes that [Collecton.retainWhere] on [collection]
    * is efficient.
    */
   static void retainAll(Collection collection, Iterable elementsToRetain) {
@@ -94,16 +94,16 @@
       collection.clear();
       return;
     }
-    collection.retainMatching(lookup.contains);
+    collection.retainWhere(lookup.contains);
   }
 
   /**
-   * Simple implemenation for [Collection.removeMatching].
+   * Simple implemenation for [Collection.removeWhere].
    *
    * This implementation assumes that [Collecton.removeAll] on [collection] is
    * efficient.
    */
-  static void removeMatching(Collection collection, bool test(var element)) {
+  static void removeWhere(Collection collection, bool test(var element)) {
     List elementsToRemove = [];
     for (var element in collection) {
       if (test(element)) elementsToRemove.add(element);
@@ -118,7 +118,7 @@
    * to the [test] function. First the elements to retain are found, and then
    * the original list is updated to contain those elements.
    */
-  static void removeMatchingList(List list, bool test(var element)) {
+  static void removeWhereList(List list, bool test(var element)) {
     List retained = [];
     int length = list.length;
     for (int i = 0; i < length; i++) {
@@ -138,12 +138,12 @@
   }
 
   /**
-   * Simple implemenation for [Collection.retainMatching].
+   * Simple implemenation for [Collection.retainWhere].
    *
    * This implementation assumes that [Collecton.removeAll] on [collection] is
    * efficient.
    */
-  static void retainMatching(Collection collection, bool test(var element)) {
+  static void retainWhere(Collection collection, bool test(var element)) {
     List elementsToRemove = [];
     for (var element in collection) {
       if (!test(element)) elementsToRemove.add(element);
@@ -209,7 +209,7 @@
     return result;
   }
 
-  static dynamic firstMatching(Iterable iterable,
+  static dynamic firstWhere(Iterable iterable,
                                bool test(dynamic value),
                                dynamic orElse()) {
     for (dynamic element in iterable) {
@@ -219,9 +219,9 @@
     throw new StateError("No matching element");
   }
 
-  static dynamic lastMatching(Iterable iterable,
-                              bool test(dynamic value),
-                              dynamic orElse()) {
+  static dynamic lastWhere(Iterable iterable,
+                           bool test(dynamic value),
+                           dynamic orElse()) {
     dynamic result = null;
     bool foundMatching = false;
     for (dynamic element in iterable) {
@@ -235,9 +235,9 @@
     throw new StateError("No matching element");
   }
 
-  static dynamic lastMatchingInList(List list,
-                                    bool test(dynamic value),
-                                    dynamic orElse()) {
+  static dynamic lastWhereList(List list,
+                               bool test(dynamic value),
+                               dynamic orElse()) {
     // TODO(floitsch): check that arguments are of correct type?
     for (int i = list.length - 1; i >= 0; i--) {
       dynamic element = list[i];
@@ -247,7 +247,7 @@
     throw new StateError("No matching element");
   }
 
-  static dynamic singleMatching(Iterable iterable, bool test(dynamic value)) {
+  static dynamic singleWhere(Iterable iterable, bool test(dynamic value)) {
     dynamic result = null;
     bool foundMatching = false;
     for (dynamic element in iterable) {
@@ -279,13 +279,13 @@
     StringBuffer buffer = new StringBuffer();
     if (separator == null || separator == "") {
       do {
-        buffer.add("${iterator.current}");
+        buffer.write("${iterator.current}");
       } while (iterator.moveNext());
     } else {
-      buffer.add("${iterator.current}");
+      buffer.write("${iterator.current}");
       while (iterator.moveNext()) {
-        buffer.add(separator);
-        buffer.add("${iterator.current}");
+        buffer.write(separator);
+        buffer.write("${iterator.current}");
       }
     }
     return buffer.toString();
@@ -297,13 +297,13 @@
     StringBuffer buffer = new StringBuffer();
     if (separator == null || separator == "") {
       for (int i = 0; i < list.length; i++) {
-        buffer.add("${list[i]}");
+        buffer.write("${list[i]}");
       }
     } else {
-      buffer.add("${list[0]}");
+      buffer.write("${list[0]}");
       for (int i = 1; i < list.length; i++) {
-        buffer.add(separator);
-        buffer.add("${list[i]}");
+        buffer.write(separator);
+        buffer.write("${list[i]}");
       }
     }
     return buffer.toString();
@@ -369,13 +369,6 @@
                            List from, int startFrom) {
     if (length == 0) return;
 
-    // TODO(floitsch): decide what to do with these checks. Currently copied
-    // since that was the old behavior of dart2js, and some co19 tests rely on
-    // it.
-    if (start is! int) throw new ArgumentError(start);
-    if (length is! int) throw new ArgumentError(length);
-    if (from is! List) throw new ArgumentError(from);
-    if (startFrom is! int) throw new ArgumentError(startFrom);
     if (length < 0) throw new ArgumentError(length);
     if (start < 0) throw new RangeError.value(start);
     if (start + length > list.length) {
@@ -388,6 +381,46 @@
   static Map<int, dynamic> asMapList(List l) {
     return new ListMapView(l);
   }
+
+  static bool setContainsAll(Set set, Iterable other) {
+    for (var element in other) {
+      if (!set.contains(element)) return false;
+    }
+    return true;
+  }
+
+  static Set setIntersection(Set set, Set other, Set result) {
+    Set smaller;
+    Set larger;
+    if (set.length < other.length) {
+      smaller = set;
+      larger = other;
+    } else {
+      smaller = other;
+      larger = set;
+    }
+    for (var element in smaller) {
+      if (larger.contains(element)) {
+        result.add(element);
+      }
+    }
+    return result;
+  }
+
+  static Set setUnion(Set set, Set other, Set result) {
+    result.addAll(set);
+    result.addAll(other);
+    return result;
+  }
+
+  static Set setDifference(Set set, Set other, Set result) {
+    for (var element in set) {
+      if (!other.contains(element)) {
+        result.add(element);
+      }
+    }
+    return result;
+  }
 }
 
 class Collections {
diff --git a/sdk/lib/collection/hash_set.dart b/sdk/lib/collection/hash_set.dart
index 6908029..ca32220 100644
--- a/sdk/lib/collection/hash_set.dart
+++ b/sdk/lib/collection/hash_set.dart
@@ -55,7 +55,7 @@
     IterableMixinWorkaround.retainAll(this, objectsToRetain);
   }
 
-  void _filterMatching(bool test(E element), bool removeMatching) {
+  void _filterWhere(bool test(E element), bool removeMatching) {
     int entrySize = _table._entrySize;
     int length = _table._table.length;
     for (int offset =  0; offset < length; offset += entrySize) {
@@ -73,12 +73,12 @@
     _table._checkCapacity();
   }
 
-  void removeMatching(bool test(E element)) {
-    _filterMatching(test, true);
+  void removeWhere(bool test(E element)) {
+    _filterWhere(test, true);
   }
 
-  void retainMatching(bool test(E element)) {
-    _filterMatching(test, false);
+  void retainWhere(bool test(E element)) {
+    _filterWhere(test, false);
   }
 
   void clear() {
@@ -86,32 +86,33 @@
   }
 
   // Set.
-  bool isSubsetOf(Collection<E> collection) {
+  bool isSubsetOf(Collection<E> other) {
+    // Deprecated, and using old signature.
     Set otherSet;
-    if (collection is Set) {
-      otherSet = collection;
+    if (other is Set) {
+      otherSet = other;
     } else {
-      otherSet = collection.toSet();
+      otherSet = other.toSet();
     }
-    return otherSet.containsAll(this);
+    return IterableMixinWorkaround.setContainsAll(otherSet, this);
   }
 
-  bool containsAll(Collection<E> collection) {
-    for (E element in collection) {
-      if (!this.contains(element)) return false;
-    }
-    return true;
+  bool containsAll(Iterable<E> other) {
+    return IterableMixinWorkaround.setContainsAll(this, other);
   }
 
-  Set<E> intersection(Collection<E> other) {
-    Set<E> result = new HashSet<E>();
-    for (E element in other) {
-      if (this.contains(element)) {
-        result.add(element);
-      }
-    }
-    return result;
+  Set<E> intersection(Set<E> other) {
+    return IterableMixinWorkaround.setIntersection(
+        this, other, new HashSet<E>());
   }
 
-  String toString() =>  Collections.collectionToString(this);
+  Set<E> union(Set<E> other) {
+    return IterableMixinWorkaround.setUnion(this, other, new HashSet<E>());
+  }
+
+  Set<E> difference(Set<E> other) {
+    return IterableMixinWorkaround.setDifference(this, other, new HashSet<E>());
+  }
+
+  String toString() => Collections.collectionToString(this);
 }
diff --git a/sdk/lib/collection/linked_hash_set.dart b/sdk/lib/collection/linked_hash_set.dart
index 7fc0653..8a4d566 100644
--- a/sdk/lib/collection/linked_hash_set.dart
+++ b/sdk/lib/collection/linked_hash_set.dart
@@ -97,7 +97,7 @@
     IterableMixinWorkaround.retainAll(this, objectsToRemove);
   }
 
-  void _filterMatching(bool test(E element), bool removeMatching) {
+  void _filterWhere(bool test(E element), bool removeMatching) {
     int entrySize = _table._entrySize;
     int length = _table._table.length;
     int offset = _table._next(_LinkedHashTable._HEAD_OFFSET);
@@ -115,12 +115,12 @@
     _table._checkCapacity();
   }
 
-  void removeMatching(bool test(E element)) {
-    _filterMatching(test, true);
+  void removeWhere(bool test(E element)) {
+    _filterWhere(test, true);
   }
 
-  void retainMatching(bool test(E element)) {
-    _filterMatching(test, false);
+  void retainWhere(bool test(E element)) {
+    _filterWhere(test, false);
   }
 
   void clear() {
@@ -128,31 +128,34 @@
   }
 
   // Set.
-  bool isSubsetOf(Collection<E> collection) {
+  bool isSubsetOf(Collection<E> other) {
+    // Deprecated, and using old signature.
     Set otherSet;
-    if (collection is Set) {
-      otherSet = collection;
+    if (other is Set) {
+      otherSet = other;
     } else {
-      otherSet = collection.toSet();
+      otherSet = other.toSet();
     }
-    return otherSet.containsAll(this);
+    return IterableMixinWorkaround.setContainsAll(otherSet, this);
   }
 
-  bool containsAll(Collection<E> collection) {
-    for (E element in collection) {
-      if (!this.contains(element)) return false;
-    }
-    return true;
+  bool containsAll(Iterable<E> other) {
+    return IterableMixinWorkaround.setContainsAll(this, other);
   }
 
-  Set<E> intersection(Collection<E> other) {
-    Set<E> result = new LinkedHashSet<E>();
-    for (E element in other) {
-      if (this.contains(element)) {
-        result.add(element);
-      }
-    }
-    return result;
+  Set<E> intersection(Set<E> other) {
+    return IterableMixinWorkaround.setIntersection(
+        this, other, new LinkedHashSet<E>());
+  }
+
+  Set<E> union(Set<E> other) {
+    return IterableMixinWorkaround.setUnion(
+        this, other, new LinkedHashSet<E>());
+  }
+
+  Set<E> difference(Set<E> other) {
+    return IterableMixinWorkaround.setDifference(
+        this, other, new LinkedHashSet<E>());
   }
 
   String toString() => Collections.collectionToString(this);
diff --git a/sdk/lib/collection/queue.dart b/sdk/lib/collection/queue.dart
index 975939a..c6cca9f 100644
--- a/sdk/lib/collection/queue.dart
+++ b/sdk/lib/collection/queue.dart
@@ -162,6 +162,7 @@
  */
 class DoubleLinkedQueue<E> extends Collection<E> implements Queue<E> {
   _DoubleLinkedQueueEntrySentinel<E> _sentinel;
+  int _elementCount = 0;
 
   DoubleLinkedQueue() {
     _sentinel = new _DoubleLinkedQueueEntrySentinel<E>();
@@ -175,30 +176,40 @@
     return list;
   }
 
+  int get length => _elementCount;
+
   void addLast(E value) {
     _sentinel.prepend(value);
+    _elementCount++;
   }
 
   void addFirst(E value) {
     _sentinel.append(value);
+    _elementCount++;
   }
 
   void add(E value) {
-    addLast(value);
+    _sentinel.prepend(value);
+    _elementCount++;
   }
 
   void addAll(Iterable<E> iterable) {
-    for (final e in iterable) {
-      add(e);
+    for (final E value in iterable) {
+      _sentinel.prepend(value);
+      _elementCount++;
     }
   }
 
   E removeLast() {
-    return _sentinel._previous.remove();
+    E result = _sentinel._previous.remove();
+    _elementCount--;
+    return result;
   }
 
   E removeFirst() {
-    return _sentinel._next.remove();
+    E result = _sentinel._next.remove();
+    _elementCount--;
+    return result;
   }
 
   void remove(Object o) {
@@ -206,6 +217,7 @@
     while (!identical(entry, _sentinel)) {
       if (entry.element == o) {
         entry.remove();
+        _elementCount--;
         return;
       }
       entry = entry._next;
@@ -213,27 +225,29 @@
   }
 
   void removeAll(Iterable elements) {
-    // Use this method when remove is slow and removeMatching more efficient.
+    // Use this method when remove is slow and removeWhere more efficient.
     IterableMixinWorkaround.removeAllList(this, elements);
   }
 
-  void removeMatching(bool test(E element)) {
+  void removeWhere(bool test(E element)) {
     DoubleLinkedQueueEntry<E> entry = firstEntry();
     while (!identical(entry, _sentinel)) {
       DoubleLinkedQueueEntry<E> next = entry._next;
       if (test(entry.element)) {
         entry.remove();
+        _elementCount--;
       }
       entry = next;
     }
   }
 
-  void retainMatching(bool test(E element)) {
+  void retainWhere(bool test(E element)) {
     DoubleLinkedQueueEntry<E> entry = firstEntry();
     while (!identical(entry, _sentinel)) {
       DoubleLinkedQueueEntry<E> next = entry._next;
       if (!test(entry.element)) {
         entry.remove();
+        _elementCount--;
       }
       entry = next;
     }
@@ -270,6 +284,7 @@
   void clear() {
     _sentinel._next = _sentinel;
     _sentinel._previous = _sentinel;
+    _elementCount = 0;
   }
 
   void forEachEntry(void f(DoubleLinkedQueueEntry<E> element)) {
@@ -327,7 +342,7 @@
  *
  * The structure is efficient for any queue or stack usage.
  *
- * Collection operations like [removeAll] and [removeMatching] are very
+ * Collection operations like [removeAll] and [removeWhere] are very
  * inefficient. If those are needed, use a [DoubleLinkedQueue] instead.
  */
 class ListQueue<E> extends Collection<E> implements Queue<E>{
@@ -474,7 +489,7 @@
     IterableMixinWorkaround.retainAll(this, objectsToRetain);
   }
 
-  void _filterMatching(bool test(E element), bool removeMatching) {
+  void _filterWhere(bool test(E element), bool removeMatching) {
     int index = _head;
     int modificationCount = _modificationCount;
     int i = _head;
@@ -497,8 +512,8 @@
    * This method is inefficient since it works by repeatedly removing single
    * elements, each of which can take linear time.
    */
-  void removeMatching(bool test(E element)) {
-    _filterMatching(test, true);
+  void removeWhere(bool test(E element)) {
+    _filterWhere(test, true);
   }
 
   /**
@@ -507,8 +522,8 @@
    * This method is inefficient since it works by repeatedly removing single
    * elements, each of which can take linear time.
    */
-  void retainMatching(bool test(E element)) {
-    _filterMatching(test, false);
+  void retainWhere(bool test(E element)) {
+    _filterWhere(test, false);
   }
 
   void clear() {
diff --git a/sdk/lib/collection/splay_tree.dart b/sdk/lib/collection/splay_tree.dart
index 53707f1..5a5db4d 100644
--- a/sdk/lib/collection/splay_tree.dart
+++ b/sdk/lib/collection/splay_tree.dart
@@ -36,13 +36,11 @@
  */
 abstract class _SplayTree<K> {
   // The root node of the splay tree. It will contain either the last
-  // element inserted, or the last element looked up.
+  // element inserted or the last element looked up.
   _SplayTreeNode<K> _root;
 
-  // The dummy node used when performing a splay on the tree. It is a
-  // local field of the class to avoid allocating a node each time a
-  // splay is performed.
-  // TODO(lrn); Should it be a getter backed by a static instead?
+  // The dummy node used when performing a splay on the tree. Reusing it
+  // avoids allocating a node each time a splay is performed.
   _SplayTreeNode<K> _dummy = new _SplayTreeNode<K>(null);
 
   // Number of elements in the splay tree.
@@ -136,6 +134,34 @@
     return comp;
   }
 
+  // Emulates splaying with a key that is smaller than any in the tree.
+  // After this, the smallest element in the tree is the root.
+  void _splayMin() {
+    assert(_root != null);
+    _SplayTreeNode current = _root;
+    while (current.left != null) {
+      _SplayTreeNode left = current.left;
+      current.left = left.right;
+      left.right = current;
+      current = left;
+    }
+    _root = current;
+  }
+
+  // Emulates splaying with a key that is greater than any in the tree.
+  // After this, the largest element in the tree is the root.
+  void _splayMax() {
+    assert(_root != null);
+    _SplayTreeNode current = _root;
+    while (current.right != null) {
+      _SplayTreeNode right = current.right;
+      current.right = right.left;
+      right.left = current;
+      current = right;
+    }
+    _root = current;
+  }
+
   _SplayTreeNode _remove(K key) {
     if (_root == null) return null;
     int comp = _splay(key);
@@ -186,26 +212,14 @@
 
   _SplayTreeNode get _first {
     if (_root == null) return null;
-    _SplayTreeNode<K> node = _root;
-    while (node.left != null) {
-      node = node.left;
-    }
-    // Maybe implement a splay-method that can splay the minimum without
-    // performing comparisons.
-    _splay(node.key);
-    return node;
+    _splayMin();
+    return _root;
   }
 
   _SplayTreeNode get _last {
     if (_root == null) return null;
-    _SplayTreeNode<K> node = _root;
-    while (node.right != null) {
-      node = node.right;
-    }
-    // Maybe implement a splay-method that can splay the minimum without
-    // performing comparisons.
-    _splay(node.key);
-    return node;
+    _splayMax();
+    return _root;
   }
 
   void _clear() {
@@ -224,11 +238,11 @@
  * Keys of the map are compared using the `compare` function passed in
  * the constructor. If that is omitted, the objects are assumed to be
  * [Comparable], and are compared using their [Comparable.compareTo]
- * method.
+ * method. This also means that `null` is *not* allowed as a key.
  */
 class SplayTreeMap<K, V> extends _SplayTree<K> implements Map<K, V> {
   // TODO(ngeoffray): Restore type when feature is implemented in dart2js
-  // checked mode. http://dartbug.com/7733  
+  // checked mode. http://dartbug.com/7733
   Function /* Comparator<K> */_comparator;
 
   SplayTreeMap([int compare(K key1, K key2)])
@@ -239,6 +253,7 @@
   SplayTreeMap._internal();
 
   V operator [](K key) {
+    if (key == null) throw new ArgumentError(key);
     if (_root != null) {
       int comp = _splay(key);
       if (comp == 0) return _root.value;
@@ -246,13 +261,15 @@
     return null;
   }
 
-  V remove(K key) {
+  V remove(Object key) {
+    if (key is! K) return null;
     _SplayTreeMapNode root = _remove(key);
     if (root != null) return root.value;
     return null;
   }
 
   void operator []=(K key, V value) {
+    if (key == null) throw new ArgumentError(key);
     // Splay on the key to move the last node on the search path for
     // the key to the root of the tree.
     int comp = _splay(key);
@@ -265,6 +282,7 @@
 
 
   V putIfAbsent(K key, V ifAbsent()) {
+    if (key == null) throw new ArgumentError(key);
     int comp = _splay(key);
     if (comp == 0) return _root.value;
     int modificationCount = _modificationCount;
@@ -311,12 +329,17 @@
 
   bool containsValue(V value) {
     bool found = false;
+    int initialSplayCount = _splayCount;
     bool visit(_SplayTreeNode node) {
-      if (node == null) return false;
-      if (node.value == value) return true;
-      // TODO(lrn): Do we want to handle the case where node.value.operator==
-      // modifies the map?
-      return visit(node.left) || visit(node.right);
+      while (node != null) {
+        if (node.value == value) return true;
+        if (initialSplayCount != _splayCount) {
+          throw new ConcurrentModificationError(this);
+        }
+        if (node.right != null && visit(node.right)) return true;
+        node = node.left;
+      }
+      return false;
     }
     return visit(_root);
   }
@@ -333,16 +356,16 @@
    * Get the first key in the map. Returns [null] if the map is empty.
    */
   K firstKey() {
-    _SplayTreeNode node = _first;
-    return (node == null) ? null : node.key;
+    if (_root == null) return null;
+    return _first.key;
   }
 
   /**
    * Get the last key in the map. Returns [null] if the map is empty.
    */
   K lastKey() {
-    _SplayTreeNode node = _last;
-    return (node == null) ? null : node.key;
+    if (_root == null) return null;
+    return _last.key;
   }
 
   /**
@@ -350,6 +373,7 @@
    * [null] if no key was not found.
    */
   K lastKeyBefore(K key) {
+    if (key == null) throw new ArgumentError(key);
     if (_root == null) return null;
     int comp = _splay(key);
     if (comp < 0) return _root.key;
@@ -366,6 +390,7 @@
    * [null] if no key was not found.
    */
   K firstKeyAfter(K key) {
+    if (key == null) throw new ArgumentError(key);
     if (_root == null) return null;
     int comp = _splay(key);
     if (comp > 0) return _root.key;
diff --git a/sdk/lib/core/collection.dart b/sdk/lib/core/collection.dart
index 7222b06..0f772d8 100644
--- a/sdk/lib/core/collection.dart
+++ b/sdk/lib/core/collection.dart
@@ -72,8 +72,8 @@
    *
    * An elements [:e:] satisfies [test] if [:test(e):] is true.
    */
-  void removeMatching(bool test(E element)) {
-    IterableMixinWorkaround.removeMatching(this, test);
+  void removeWhere(bool test(E element)) {
+    IterableMixinWorkaround.removeWhere(this, test);
   }
 
   /**
@@ -81,14 +81,14 @@
    *
    * An elements [:e:] satisfies [test] if [:test(e):] is true.
    */
-  void retainMatching(bool test(E element)) {
-    IterableMixinWorkaround.retainMatching(this, test);
+  void retainWhere(bool test(E element)) {
+    IterableMixinWorkaround.retainWhere(this, test);
   }
 
   /**
    * Removes all elements of this collection.
    */
   void clear() {
-    IterableMixinWorkaround.removeMatching(this, (E e) => true);
+    IterableMixinWorkaround.removeWhere(this, (E e) => true);
   }
 }
diff --git a/sdk/lib/core/comparable.dart b/sdk/lib/core/comparable.dart
index ee92df9..21161df 100644
--- a/sdk/lib/core/comparable.dart
+++ b/sdk/lib/core/comparable.dart
@@ -13,6 +13,7 @@
  * smaller than the former).
  *
  * A [Comparator] function represents such a total ordering by returning
+ *
  * * a negative integer if [a] is smaller than [b],
  * * zero if [a] is equal to [b], and
  * * a positive integer if [a] is greater than [b].
diff --git a/sdk/lib/core/core.dart b/sdk/lib/core/core.dart
index 7163244..dd6ee8f 100644
--- a/sdk/lib/core/core.dart
+++ b/sdk/lib/core/core.dart
@@ -27,7 +27,6 @@
 part "map.dart";
 part "num.dart";
 part "object.dart";
-part "options.dart";
 part "pattern.dart";
 part "print.dart";
 part "regexp.dart";
diff --git a/sdk/lib/core/corelib_sources.gypi b/sdk/lib/core/corelib_sources.gypi
index e0e350b..290b507 100644
--- a/sdk/lib/core/corelib_sources.gypi
+++ b/sdk/lib/core/corelib_sources.gypi
@@ -26,7 +26,6 @@
     'list.dart',
     'num.dart',
     'object.dart',
-    'options.dart',
     'pattern.dart',
     'print.dart',
     'regexp.dart',
diff --git a/sdk/lib/core/date_time.dart b/sdk/lib/core/date_time.dart
index 38d179e..5b26fc8 100644
--- a/sdk/lib/core/date_time.dart
+++ b/sdk/lib/core/date_time.dart
@@ -5,101 +5,6 @@
 part of dart.core;
 
 /**
- * Deprecated class. Please use [DateTime] instead.
- */
-@deprecated
-abstract class Date implements Comparable<Date> {
-  // Weekday constants that are returned by [weekday] method:
-  static const int MON = 1;
-  static const int TUE = 2;
-  static const int WED = 3;
-  static const int THU = 4;
-  static const int FRI = 5;
-  static const int SAT = 6;
-  static const int SUN = 7;
-  static const int DAYS_IN_WEEK = 7;
-
-  // Month constants that are returned by the [month] getter.
-  static const int JAN = 1;
-  static const int FEB = 2;
-  static const int MAR = 3;
-  static const int APR = 4;
-  static const int MAY = 5;
-  static const int JUN = 6;
-  static const int JUL = 7;
-  static const int AUG = 8;
-  static const int SEP = 9;
-  static const int OCT = 10;
-  static const int NOV = 11;
-  static const int DEC = 12;
-
-  factory Date(int year,
-               [int month = 1,
-                int day = 1,
-                int hour = 0,
-                int minute = 0,
-                int second = 0,
-                int millisecond = 0]) {
-    return new DateTime(year, month, day, hour, minute, second, millisecond);
-  }
-
-  factory Date.utc(int year,
-                   [int month = 1,
-                    int day = 1,
-                    int hour = 0,
-                    int minute = 0,
-                    int second = 0,
-                    int millisecond = 0]) {
-    return
-        new DateTime.utc(year, month, day, hour, minute, second, millisecond);
-  }
-
-  factory Date.now() => new DateTime.now();
-
-  factory Date.fromString(String formattedString)
-      => DateTime.parse(formattedString);
-
-  factory Date.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch,
-                                          {bool isUtc: false}) {
-    return new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
-                                                   isUtc: isUtc);
-  }
-
-  bool operator ==(DateTime other);
-  bool operator <(DateTime other);
-  bool operator <=(DateTime other);
-  bool operator >(DateTime other);
-  bool operator >=(DateTime other);
-
-
-  DateTime toLocal();
-  DateTime toUtc();
-
-  String get timeZoneName;
-  Duration get timeZoneOffset;
-
-  int get year;
-  int get month;
-  int get day;
-  int get hour;
-  int get minute;
-  int get second;
-  int get millisecond;
-
-  int get weekday;
-
-  int get millisecondsSinceEpoch;
-
-  bool get isUtc;
-
-  String toString();
-
-  DateTime add(Duration duration);
-  DateTime subtract(Duration duration);
-  Duration difference(DateTime other);
-}
-
-/**
  * A DateTime object represents a point in time.
  *
  * It can represent time values that are at a distance of at most
@@ -108,7 +13,7 @@
  *
  * Also see [Stopwatch] for means to measure time-spans.
  */
-class DateTime implements Date {
+class DateTime {
   // Weekday constants that are returned by [weekday] method:
   static const int MON = 1;
   static const int TUE = 2;
@@ -230,7 +135,7 @@
       int minute = parseIntOrZero(match[5]);
       int second = parseIntOrZero(match[6]);
       bool addOneMillisecond = false;
-      int millisecond = (parseDoubleOrZero(match[7]) * 1000).round().toInt();
+      int millisecond = (parseDoubleOrZero(match[7]) * 1000).round();
       if (millisecond == 1000) {
         addOneMillisecond = true;
         millisecond = 999;
diff --git a/sdk/lib/core/double.dart b/sdk/lib/core/double.dart
index 0b3417f..58bb3dd 100644
--- a/sdk/lib/core/double.dart
+++ b/sdk/lib/core/double.dart
@@ -45,7 +45,7 @@
    * Truncating division operator.
    *
    * The result of the truncating division [:a ~/ b:] is equivalent to
-   * [:(a / b).truncate().toInt():].
+   * [:(a / b).truncate():].
    */
   int operator ~/(num other);
 
@@ -56,24 +56,66 @@
   double abs();
 
   /**
-   * Returns the integer value closest to this [double].
+   * Returns the integer closest to `this`.
+   *
+   * Rounds away from zero when there is no closest integer:
+   *  [:(3.5).round() == 4:] and [:(-3.5).round() == -4:].
+   *
+   * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
+   */
+  int round();
+
+  /**
+   * Returns the greatest integer no greater than `this`.
+   *
+   * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
+   */
+  int floor();
+
+  /**
+   * Returns the least integer no smaller than `this`.
+   *
+   * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
+   */
+  int ceil();
+
+  /**
+   * Returns the integer obtained by discarding any fractional
+   * digits from `this`.
+   *
+   * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
+   */
+  int truncate();
+
+  /**
+   * Returns the integer value, as a double, closest to `this`.
    *
    * Rounds away from zero when there is no closest integer:
    *  [:(3.5).round() == 4:] and [:(-3.5).round() == -4:].
    */
-  double round();
-
-  /** Returns the greatest integer value no greater than this [double]. */
-  double floor();
-
-  /** Returns the least integer value that is no smaller than this [double]. */
-  double ceil();
+  double roundToDouble();
 
   /**
-   * Returns the integer value obtained by discarding any fractional
-   * digits from this [double].
+   * Returns the greatest integer value no greater than `this`.
+   *
+   * The result is a double.
    */
-  double truncate();
+  double floorToDouble();
+
+  /**
+   * Returns the least integer value no smaller than `this`.
+   *
+   * The result is a double.
+   */
+  double ceilToDouble();
+
+  /**
+   * Returns the integer obtained by discarding any fractional
+   * digits from `this`.
+   *
+   * The result is a double.
+   */
+  double truncateToDouble();
 
   /**
    * Provide a representation of this [double] value.
diff --git a/sdk/lib/core/expect.dart b/sdk/lib/core/expect.dart
index bf9053a..0302d3d 100644
--- a/sdk/lib/core/expect.dart
+++ b/sdk/lib/core/expect.dart
@@ -252,20 +252,20 @@
     StringBuffer sb = new StringBuffer("Expect.setEquals($msg) fails");
     // Report any missing items.
     if (!missingSet.isEmpty) {
-      sb.add('\nExpected collection does not contain: ');
+      sb.write('\nExpected collection does not contain: ');
     }
 
     for (final val in missingSet) {
-      sb.add('$val ');
+      sb.write('$val ');
     }
 
     // Report any extra items.
     if (!extraSet.isEmpty) {
-      sb.add('\nExpected collection should not contain: ');
+      sb.write('\nExpected collection should not contain: ');
     }
 
     for (final val in extraSet) {
-      sb.add('$val ');
+      sb.write('$val ');
     }
     _fail(sb.toString());
   }
diff --git a/sdk/lib/core/int.dart b/sdk/lib/core/int.dart
index 2262574..4518b7b 100644
--- a/sdk/lib/core/int.dart
+++ b/sdk/lib/core/int.dart
@@ -49,10 +49,10 @@
   /** Returns the absolute value of this integer. */
   int abs();
 
-  /** Returns [this]. */
+  /** Returns `this`. */
   int round();
 
-  /** Returns [this]. */
+  /** Returns `this`. */
   int floor();
 
   /** Returns [this]. */
@@ -61,6 +61,18 @@
   /** Returns [this]. */
   int truncate();
 
+  /** Returns `this.toDouble()`. */
+  double roundToDouble();
+
+  /** Returns `this.toDouble()`. */
+  double floorToDouble();
+
+  /** Returns `this.toDouble()`. */
+  double ceilToDouble();
+
+  /** Returns `this.toDouble()`. */
+  double truncateToDouble();
+
   /**
    * Returns a representation of this [int] value.
    *
diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart
index c6e09a1..604c4a8 100644
--- a/sdk/lib/core/iterable.dart
+++ b/sdk/lib/core/iterable.dart
@@ -133,13 +133,13 @@
     StringBuffer buffer = new StringBuffer();
     if (separator == null || separator == "") {
       do {
-        buffer.add("${iterator.current}");
+        buffer.write("${iterator.current}");
       } while (iterator.moveNext());
     } else {
-      buffer.add("${iterator.current}");
+      buffer.write("${iterator.current}");
       while (iterator.moveNext()) {
-        buffer.add(separator);
-        buffer.add("${iterator.current}");
+        buffer.write(separator);
+        buffer.write("${iterator.current}");
       }
     }
     return buffer.toString();
@@ -185,7 +185,10 @@
    *
    * The [compare] function must be a proper [Comparator<T>]. If a function is
    * not provided, [compare] defaults to [Comparable.compare].
+   *
+   * *Deprecated*. Use [reduce] with a binary min method if needed.
    */
+  @deprecated
   E min([int compare(E a, E b)]) {
     if (compare == null) compare = Comparable.compare;
     Iterator it = iterator;
@@ -208,7 +211,10 @@
    *
    * The [compare] function must be a proper [Comparator<T>]. If a function is
    * not provided, [compare] defaults to [Comparable.compare].
+   *
+   * *Deprecated*. Use [reduce] with a binary max method if needed.
    */
+  @deprecated
   E max([int compare(E a, E b)]) {
     if (compare == null) compare = Comparable.compare;
     Iterator it = iterator;
@@ -323,7 +329,7 @@
    * returned. By default, when [orElse] is `null`, a [StateError] is
    * thrown.
    */
-  E firstMatching(bool test(E value), { E orElse() }) {
+  E firstWhere(bool test(E value), { E orElse() }) {
     // TODO(floitsch): check that arguments are of correct type?
     for (E element in this) {
       if (test(element)) return element;
@@ -339,7 +345,7 @@
    * returned. By default, when [orElse] is [:null:], a [StateError] is
    * thrown.
    */
-  E lastMatching(bool test(E value), {E orElse()}) {
+  E lastWhere(bool test(E value), {E orElse()}) {
     // TODO(floitsch): check that arguments are of correct type?
     E result = null;
     bool foundMatching = false;
@@ -358,7 +364,7 @@
    * Returns the single element that satisfies [f]. If no or more than one
    * element match then a [StateError] is thrown.
    */
-  E singleMatching(bool test(E value)) {
+  E singleWhere(bool test(E value)) {
     // TODO(floitsch): check that argument is of correct type?
     E result = null;
     bool foundMatching = false;
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index 560f08f..58d6139 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -7,7 +7,7 @@
 /**
  * A [List] is an indexable collection with a length.
  *
- * A `List` implementation can be choose not to support all methods
+ * A `List` implementation can choose not to support all methods
  * of the `List` interface.
  *
  * The most common list types are:
@@ -52,6 +52,7 @@
   /**
    * *Deprecated*: Use `new List(count)` instead.
    */
+  @deprecated
   factory List.fixedLength(int count, { E fill }) {
     List<E> result = new List(count);
     if (fill != null) {
@@ -192,7 +193,18 @@
   void clear();
 
   /**
-   * Removes the element at position[index] from the list.
+   * Inserts the element at position [index] in the list.
+   *
+   * This increases the length of the list by one and shifts all later elements
+   * towards the end of the list.
+   *
+   * It is an error if the [index] does not point inside the list or at the
+   * position after the last element.
+   */
+  void insert(int index, E element);
+
+  /**
+   * Removes the element at position [index] from the list.
    *
    * This reduces the length of the list by one and moves all later elements
    * down by one position.
@@ -213,13 +225,19 @@
   E removeLast();
 
   /**
-   * Returns a new list containing [length] elements from the list,
-   * starting at  [start].
-   * Returns an empty list if [length] is 0.
-   * Throws an [ArgumentError] if [length] is negative.
-   * Throws an [RangeError] if [start] or
-   * [:start + length - 1:] are out of range.
+   * Returns a new list containing the elemenst from [start] to [end].
+   *
+   * If [end] is omitted, the [length] of the list is used.
+   *
+   * It is an error if [start] or [end] are not list indices for this list,
+   * or if [end] is before [start].
    */
+  List<E> sublist(int start, [int end]);
+
+  /**
+   * *Deprecated*. Use [sublist] instead.
+   */
+  @deprecated
   List<E> getRange(int start, int length);
 
   /**
diff --git a/sdk/lib/core/num.dart b/sdk/lib/core/num.dart
index 439022f..3551fc6 100644
--- a/sdk/lib/core/num.dart
+++ b/sdk/lib/core/num.dart
@@ -26,11 +26,12 @@
   /**
    * Truncating division operator.
    *
-   * The result of the truncating division [:a ~/ b:] is equivalent to
-   * [:(a / b).truncate().toInt():].
+   * If either operand is a [double] then the result of the truncating division
+   * [:a ~/ b:] is equivalent to [:(a / b).truncate().toInt():].
+   *
+   * If both operands are [int]s then [:a ~/ b:] performs the truncating
+   * integer division.
    */
-  // TODO(floitsch): this is currently not true: bignum1 / bignum2 will return
-  // NaN, whereas bignum1 ~/ bignum2 will give the correct result.
   int operator ~/(num other);
 
   /** Negate operator. */
@@ -60,30 +61,74 @@
   /** Returns the absolute value of this [num]. */
   num abs();
 
-  /** Returns the greatest integer value no greater than this [num]. */
-  num floor();
-
-  /** Returns the least integer value that is no smaller than this [num]. */
-  num ceil();
-
   /**
-   * Returns the integer value closest to this [num].
+   * Returns the integer closest to `this`.
    *
    * Rounds away from zero when there is no closest integer:
    *  [:(3.5).round() == 4:] and [:(-3.5).round() == -4:].
+   *
+   * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
    */
-  num round();
+  int round();
 
   /**
-   * Returns the integer value obtained by discarding any fractional
-   * digits from this [num].
+   * Returns the greatest integer no greater than `this`.
+   *
+   * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
    */
-  num truncate();
+  int floor();
+
+  /**
+   * Returns the least integer no smaller than `this`.
+   *
+   * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
+   */
+  int ceil();
+
+  /**
+   * Returns the integer obtained by discarding any fractional
+   * digits from `this`.
+   *
+   * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
+   */
+  int truncate();
+
+  /**
+   * Returns the integer value closest to `this`.
+   *
+   * Rounds away from zero when there is no closest integer:
+   *  [:(3.5).round() == 4:] and [:(-3.5).round() == -4:].
+   *
+   * The result is a double.
+   */
+  double roundToDouble();
+
+  /**
+   * Returns the greatest integer value no greater than `this`.
+   *
+   * The result is a double.
+   */
+  double floorToDouble();
+
+  /**
+   * Returns the least integer value no smaller than `this`.
+   *
+   * The result is a double.
+   */
+  double ceilToDouble();
+
+  /**
+   * Returns the integer obtained by discarding any fractional
+   * digits from `this`.
+   *
+   * The result is a double.
+   */
+  double truncateToDouble();
 
   /**
    * Clamps [this] to be in the range [lowerLimit]-[upperLimit]. The comparison
    * is done using [compareTo] and therefore takes [:-0.0:] into account.
-   * It also implies that [double.NaN] is treated as the maximal double value.
+   * It also implies that [double.NAN] is treated as the maximal double value.
    */
   num clamp(num lowerLimit, num upperLimit);
 
diff --git a/sdk/lib/core/set.dart b/sdk/lib/core/set.dart
index 7977986..8856d41 100644
--- a/sdk/lib/core/set.dart
+++ b/sdk/lib/core/set.dart
@@ -35,22 +35,33 @@
   bool remove(Object value);
 
   /**
-   * Returns true if [collection] contains all the elements of this
-   * collection.
+   * Returns true if [other] contains all the elements of this Set.
+   *
+   * *Deprecated*. Use `other.containsAll(thisSet)` instead if [other]
+   * is a Set, and convert `other` to a Set if it isn't.
    */
-  bool isSubsetOf(Collection<E> collection);
+  @deprecated
+  bool isSubsetOf(Iterable<E> other);
 
   /**
-   * Returns true if this collection contains all the elements of
-   * [collection].
+   * Returns true if this Set contains all the elements of [other].
    */
-  bool containsAll(Collection<E> collection);
+  bool containsAll(Iterable<E> other);
 
   /**
-   * Returns a new set which is the intersection between this set and
-   * the given collection.
+   * Returns a new set which is the intersection between this set and [other].
    */
-  Set<E> intersection(Collection<E> other);
+  Set<E> intersection(Set<E> other);
+
+  /**
+   * Returns a new set which contains all the elements of this set and [other].
+   */
+  Set<E> union(Set<E> other);
+
+  /**
+   * Returns a new set with the the elements of this that are not in [other].
+   */
+  Set<E> difference(Set<E> other);
 
   /**
    * Removes all elements in the set.
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index d780314..34aafd1 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.dart
@@ -43,7 +43,7 @@
   }
 
   /**
-   * Gets the character (as [String]) at the given [index].
+   * Gets the character (as a single-code-unit [String]) at the given [index].
    *
    * The returned string represents exactly one UTF-16 code unit which may be
    * half of a surrogate pair. For example the Unicode character for a
@@ -84,17 +84,18 @@
   /**
    * Returns whether the two strings are equal.
    *
-   * This method compares each individual code unit of the strings. It does not
-   * check for Unicode equivalence. For example the two following strings both
-   * represent the string "Amélie" but, due to their different encoding will
-   * not return equal.
+   * This method compares each individual code unit of the strings.
+   * Equivalently (for strings that are well-formed UTF-16) it compares each
+   * individual rune (code point).  It does not check for Unicode equivalence.
+   * For example the two following strings both represent the string "Amélie"
+   * but, due to their different encoding will not return equal.
    *
    *     "Am\xe9lie"
    *     "Ame\u{301}lie"
    *
-   * In the first string the "é" is encoded as a single unicode code unit,
-   * whereas the second string encodes it as "e" with the combining
-   * accent character "◌́".
+   * In the first string the "é" is encoded as a single unicode code unit (also
+   * a single rune), whereas the second string encodes it as "e" with the
+   * combining accent character "◌́".
    */
   bool operator ==(var other);
 
@@ -135,6 +136,12 @@
    *     var strings = ['foo', 'bar', 'geez'];
    *     var concatenated = strings.join();
    */
+  String operator +(String other);
+
+  /**
+   * *Deprecated* Use [operator+] instead.
+   */
+  @deprecated
   String concat(String other);
 
   /**
@@ -264,7 +271,7 @@
 }
 
 /**
- * The runes of a [String].
+ * The runes (integer Unicode code points) of a [String].
  */
 class Runes extends Iterable<int> {
   final String string;
@@ -300,7 +307,9 @@
   return 0x10000 + ((start & 0x3FF) << 10) + (end & 0x3FF);
 }
 
-/** [Iterator] for reading Unicode code points out of a Dart string. */
+/** [Iterator] for reading runes (integer Unicode code points) out of a Dart
+  * string.
+  */
 class RuneIterator implements BidirectionalIterator<int> {
   /** String being iterated. */
   final String string;
@@ -391,7 +400,9 @@
     _currentCodePoint = null;
   }
 
-  /** The rune starting at the current position in the string. */
+  /** The rune (integer Unicode code point) starting at the current position in
+   *  the string.
+   */
   int get current => _currentCodePoint;
 
   /**
@@ -405,7 +416,7 @@
    * A string containing the current rune.
    *
    * For runes outside the basic multilingual plane, this will be
-   * a two-character String.
+   * a String of length 2, containing two code units.
    *
    * Returns null if [current] is null.
    */
diff --git a/sdk/lib/core/string_buffer.dart b/sdk/lib/core/string_buffer.dart
index 07d3277..50bb51c 100644
--- a/sdk/lib/core/string_buffer.dart
+++ b/sdk/lib/core/string_buffer.dart
@@ -23,56 +23,24 @@
   /** Returns whether the buffer is empty. This is a constant-time operation. */
   bool get isEmpty => length == 0;
 
-  /**
-   * Converts [obj] to a string and adds it to the buffer.
-   *
-   * *Deprecated*. Use [write] instead.
-   */
-  @deprecated
-  void add(Object obj) => write(obj);
-
+  /// Adds the contents of [obj], converted to a string, to the buffer.
   external void write(Object obj);
 
+  /// Adds the string representation of [charCode] to the buffer.
+  external void writeCharCode(int charCode);
+
   void writeAll(Iterable objects) {
     for (Object obj in objects) write(obj);
   }
 
-  void writeln(Object obj) {
+  void writeln([Object obj = ""]) {
     write(obj);
     write("\n");
   }
 
   /**
-   * Adds the string representation of [charCode] to the buffer.
-   *
-   * *Deprecated* Use [writeCharCode] instead.
-   */
-  @deprecated
-  void addCharCode(int charCode) {
-    writeCharCode(charCode);
-  }
-
-  /// Adds the string representation of [charCode] to the buffer.
-  void writeCharCode(int charCode) {
-    write(new String.fromCharCode(charCode));
-  }
-
-  /**
-   * Adds all items in [objects] to the buffer.
-   *
-   * *Deprecated*. Use [writeAll] instead.
-   */
-  @deprecated
-  void addAll(Iterable objects) {
-    for (Object obj in objects) write(obj);
-  }
-
-  /**
    * Clears the string buffer.
-   *
-   * *Deprecated*.
    */
-  @deprecated
   external void clear();
 
   /// Returns the contents of buffer as a concatenated string.
diff --git a/sdk/lib/core/string_sink.dart b/sdk/lib/core/string_sink.dart
index 04650f7..1e1647e 100644
--- a/sdk/lib/core/string_sink.dart
+++ b/sdk/lib/core/string_sink.dart
@@ -21,7 +21,7 @@
    * Converts [obj] to a String by invoking `toString` and adds the result to
    * `this`. Then adds a new line.
    */
-  void writeln(Object obj);
+  void writeln([Object obj = ""]);
 
   /**
    * Writes the [charCode] to `this`.
diff --git a/sdk/lib/crypto/crypto_base.dart b/sdk/lib/crypto/crypto_base.dart
index 4231718..d1666b5 100644
--- a/sdk/lib/crypto/crypto_base.dart
+++ b/sdk/lib/crypto/crypto_base.dart
@@ -17,7 +17,7 @@
  * If multiple instances of a given Hash is needed the [newInstance]
  * method can provide a new instance.
  */
-// TODO(floitsch): make Hash implement Sink, StreamSink or similar.
+// TODO(floitsch): make Hash implement Sink, EventSink or similar.
 abstract class Hash {
   /**
    * Add a list of bytes to the hash computation.
@@ -74,7 +74,7 @@
  * The [add] method is used to add data to the message. The [digest] and
  * [close] methods are used to extract the message authentication code.
  */
-// TODO(floitsch): make Hash implement Sink, StreamSink or similar.
+// TODO(floitsch): make Hash implement Sink, EventSink or similar.
 abstract class HMAC {
   /**
    * Create an [HMAC] object from a [Hash] and a key.
diff --git a/sdk/lib/crypto/crypto_utils.dart b/sdk/lib/crypto/crypto_utils.dart
index 32096f1..4c09dff 100644
--- a/sdk/lib/crypto/crypto_utils.dart
+++ b/sdk/lib/crypto/crypto_utils.dart
@@ -7,12 +7,12 @@
 class _LineWrappingStringBuffer {
   _LineWrappingStringBuffer(int this._lineLength) : _sb = new StringBuffer();
 
-  void add(String s) {
+  void write(String s) {
     if (_lineLength != null && _currentLineLength == _lineLength) {
-      _sb.add('\r\n');
+      _sb.write('\r\n');
       _currentLineLength = 0;
     }
-    _sb.add(s);
+    _sb.write(s);
     _currentLineLength++;
   }
 
@@ -27,7 +27,7 @@
   static String bytesToHex(List<int> bytes) {
     var result = new StringBuffer();
     for (var part in bytes) {
-      result.add('${part < 16 ? '0' : ''}${part.toRadixString(16)}');
+      result.write('${part < 16 ? '0' : ''}${part.toRadixString(16)}');
     }
     return result.toString();
   }
@@ -49,26 +49,26 @@
       var b0 = bytes[i] & 0xff;
       var b1 = bytes[i + 1] & 0xff;
       var b2 = bytes[i + 2] & 0xff;
-      result.add(table[b0 >> 2]);
-      result.add(table[((b0 << 4) | (b1 >> 4)) & 0x3f]);
-      result.add(table[((b1 << 2) | (b2 >> 6)) & 0x3f]);
-      result.add(table[b2 & 0x3f]);
+      result.write(table[b0 >> 2]);
+      result.write(table[((b0 << 4) | (b1 >> 4)) & 0x3f]);
+      result.write(table[((b1 << 2) | (b2 >> 6)) & 0x3f]);
+      result.write(table[b2 & 0x3f]);
     }
 
     // Deal with the last non-full block if any and add padding '='.
     if (i == bytes.length - 1) {
       var b0 = bytes[i] & 0xff;
-      result.add(table[b0 >> 2]);
-      result.add(table[(b0 << 4) & 0x3f]);
-      result.add('=');
-      result.add('=');
+      result.write(table[b0 >> 2]);
+      result.write(table[(b0 << 4) & 0x3f]);
+      result.write('=');
+      result.write('=');
     } else if (i == bytes.length - 2) {
       var b0 = bytes[i] & 0xff;
       var b1 = bytes[i + 1] & 0xff;
-      result.add(table[b0 >> 2]);
-      result.add(table[((b0 << 4) | (b1 >> 4)) & 0x3f]);
-      result.add(table[(b1 << 2) & 0x3f]);
-      result.add('=');
+      result.write(table[b0 >> 2]);
+      result.write(table[((b0 << 4) | (b1 >> 4)) & 0x3f]);
+      result.write(table[(b1 << 2) & 0x3f]);
+      result.write('=');
     }
 
     return result.toString();
diff --git a/sdk/lib/crypto/hash_utils.dart b/sdk/lib/crypto/hash_utils.dart
index d0b13cf..4188c52 100644
--- a/sdk/lib/crypto/hash_utils.dart
+++ b/sdk/lib/crypto/hash_utils.dart
@@ -116,8 +116,7 @@
         _bytesToChunk(_pendingData, index);
         _updateHash(_currentChunk);
       }
-      var remaining = len - index;
-      _pendingData = _pendingData.getRange(index, remaining);
+      _pendingData = _pendingData.sublist(index, len);
     }
   }
 
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 32c8ac9..999a588 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -462,7 +462,9 @@
 
   @DomName('ArrayBufferView.buffer')
   @DocsEditable
-  final ArrayBuffer buffer;
+  @Creates('ArrayBuffer')
+  @Returns('ArrayBuffer|Null')
+  final dynamic buffer;
 
   @DomName('ArrayBufferView.byteLength')
   @DocsEditable
@@ -887,7 +889,7 @@
 
 
 @DomName('HTMLCanvasElement')
-class CanvasElement extends Element native "*HTMLCanvasElement" {
+class CanvasElement extends Element implements CanvasImageSource native "*HTMLCanvasElement" {
 
   @DomName('HTMLCanvasElement.HTMLCanvasElement')
   @DocsEditable
@@ -1197,9 +1199,10 @@
   @Experimental
   List lineDash;
 
+  @JSName('arc')
   @DomName('CanvasRenderingContext2D.arc')
   @DocsEditable
-  void arc(num x, num y, num radius, num startAngle, num endAngle, bool anticlockwise) native;
+  void $dom_arc(num x, num y, num radius, num startAngle, num endAngle, bool anticlockwise) native;
 
   @DomName('CanvasRenderingContext2D.arcTo')
   @DocsEditable
@@ -1261,9 +1264,10 @@
   @DocsEditable
   CanvasGradient createRadialGradient(num x0, num y0, num r0, num x1, num y1, num r1) native;
 
+  @JSName('drawImage')
   @DomName('CanvasRenderingContext2D.drawImage')
   @DocsEditable
-  void drawImage(canvas_OR_image_OR_video, num sx_OR_x, num sy_OR_y, [num sw_OR_width, num height_OR_sh, num dx, num dy, num dw, num dh]) native;
+  void $dom_drawImage(canvas_OR_image_OR_video, num sx_OR_x, num sy_OR_y, [num sw_OR_width, num height_OR_sh, num dx, num dy, num dw, num dh]) native;
 
   @DomName('CanvasRenderingContext2D.fill')
   @DocsEditable
@@ -1473,6 +1477,107 @@
     this.strokeStyle = 'hsla($h, $s%, $l%, $a)';
   }
 
+  @DomName('CanvasRenderingContext2D.arc')
+  void arc(num x,  num y,  num radius,  num startAngle, num endAngle,
+      [bool anticlockwise = false]) {
+    $dom_arc(x, y, radius, startAngle, endAngle, anticlockwise);
+  }
+
+  /**
+   * Draws an image from a CanvasImageSource to this canvas.
+   *
+   * The entire image from [source] will be drawn to this context with its top
+   * left corner at the point ([destinationX], [destinationY]). If the image is
+   * larger than canvas will allow, the image will be cropped to fit the
+   * available space.
+   *
+   *     CanvasElement canvas = new CanvasElement(width: 600, height: 600);
+   *     CanvasRenderingContext2D ctx = canvas.context2d;
+   *     ImageElement img = document.query('img');
+   *
+   *     ctx.drawImage(img, 100, 100);
+   *
+   *     VideoElement video = document.query('video');
+   *     ctx.drawImage(video, 0, 0);
+   *
+   *     CanvasElement otherCanvas = document.query('canvas');
+   *     otherCanvas.width = 100;
+   *     otherCanvas.height = 100;
+   *     ctx.drawImage(otherCanvas, 590, 590); // will get cropped
+   *
+   * See also:
+   *
+   *   * [CanvasImageSource] for more information on what data is retrieved
+   * from [source].
+   *   * [drawImage](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
+   * from the WHATWG.
+   */
+  @DomName('CanvasRenderingContext2D.drawImage')
+  void drawImage(CanvasImageSource source, num destinationX, num destinationY) {
+    $dom_drawImage(source, destinationX, destinationY);
+  }
+
+  /**
+   * Draws an image from a CanvasImageSource to an area of this canvas.
+   *
+   * The image will be drawn to an area of this canvas defined by
+   * [destinationRect]. If [sourceRect] is not provided, then
+   * the entire rectangular image from [source] will be drawn to this context.
+   * If the dimensions of [source] or [sourceRect]
+   * differ from [destinationRect], then the image will be scaled to fit.
+   * If the image is larger than canvas
+   * will allow, the image will be cropped to fit the available space.
+   *
+   *     CanvasElement canvas = new CanvasElement(width: 600, height: 600);
+   *     CanvasRenderingContext2D ctx = canvas.context2d;
+   *     ImageElement img = document.query('img');
+   *     img.width = 100;
+   *     img.height = 100;
+   *
+   *     // Scale the image to 20x20.
+   *     ctx.drawImageAtScale(img, new Rect(50, 50, 20, 20));
+   *
+   *     VideoElement video = document.query('video');
+   *     video.width = 100;
+   *     video.height = 100;
+   *     // Take the middle 20x20 pixels from the video and stretch them.
+   *     ctx.drawImageAtScale(video, new Rect(50, 50, 100, 100),
+   *         sourceRect: new Rect(40, 40, 20, 20));
+   *
+   *     // Draw the top 100x20 pixels from the otherCanvas.
+   *     CanvasElement otherCanvas = document.query('canvas');
+   *     ctx.drawImageAtScale(otherCanvas, new Rect(0, 0, 100, 20),
+   *         sourceRect: new Rect(0, 0, 100, 20));
+   *
+   * See also:
+   *
+   *   * [CanvasImageSource] for more information on what data is retrieved
+   * from [source].
+   *   * [drawImage](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
+   * from the WHATWG.
+   */
+  @DomName('CanvasRenderingContext2D.drawImage')
+  void drawImageAtScale(CanvasImageSource source, Rect destinationRect,
+      {Rect sourceRect}) {
+    if (sourceRect == null) {
+      $dom_drawImage(source,
+          destinationRect.left,
+          destinationRect.top,
+          destinationRect.width,
+          destinationRect.height);
+    } else {
+      $dom_drawImage(source,
+          sourceRect.left,
+          sourceRect.top,
+          sourceRect.width,
+          sourceRect.height,
+          destinationRect.left,
+          destinationRect.top,
+          destinationRect.width,
+          destinationRect.height);
+    }
+  }
+
   @DomName('CanvasRenderingContext2D.lineDashOffset')
   num get lineDashOffset => JS('num',
       '#.lineDashOffset || #.webkitLineDashOffset', this, this);
@@ -1525,39 +1630,6 @@
 
 
 @DocsEditable
-@DomName('ClientRect')
-class ClientRect native "*ClientRect" {
-
-  @DomName('ClientRect.bottom')
-  @DocsEditable
-  final num bottom;
-
-  @DomName('ClientRect.height')
-  @DocsEditable
-  final num height;
-
-  @DomName('ClientRect.left')
-  @DocsEditable
-  final num left;
-
-  @DomName('ClientRect.right')
-  @DocsEditable
-  final num right;
-
-  @DomName('ClientRect.top')
-  @DocsEditable
-  final num top;
-
-  @DomName('ClientRect.width')
-  @DocsEditable
-  final num width;
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
-@DocsEditable
 @DomName('CloseEvent')
 class CloseEvent extends Event native "*CloseEvent" {
 
@@ -1724,7 +1796,7 @@
 
 @DocsEditable
 @DomName('HTMLContentElement')
-@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@SupportedBrowser(SupportedBrowser.CHROME, '26')
 @Experimental
 class ContentElement extends Element native "*HTMLContentElement" {
 
@@ -1824,7 +1896,9 @@
 
   @DomName('Crypto.getRandomValues')
   @DocsEditable
-  ArrayBufferView getRandomValues(ArrayBufferView array) native;
+  @Creates('ArrayBufferView')
+  @Returns('ArrayBufferView|Null')
+  dynamic getRandomValues(/*ArrayBufferView*/ array) native;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -1859,6 +1933,8 @@
 
 @DocsEditable
 @DomName('CSSHostRule')
+@SupportedBrowser(SupportedBrowser.CHROME, '26')
+@Experimental
 class CssHostRule extends CssRule native "*CSSHostRule" {
 
   @DomName('CSSHostRule.cssRules')
@@ -2226,11 +2302,11 @@
   @JSName('getRGBColorValue')
   @DomName('CSSPrimitiveValue.getRGBColorValue')
   @DocsEditable
-  RgbColor getRgbColorValue() native;
+  CssRgbColor getRgbColorValue() native;
 
   @DomName('CSSPrimitiveValue.getRectValue')
   @DocsEditable
-  Rect getRectValue() native;
+  CssRect getRectValue() native;
 
   @DomName('CSSPrimitiveValue.getStringValue')
   @DocsEditable
@@ -2250,6 +2326,52 @@
 
 
 @DocsEditable
+@DomName('Rect')
+class CssRect native "*Rect" {
+
+  @DomName('Rect.bottom')
+  @DocsEditable
+  final CssPrimitiveValue bottom;
+
+  @DomName('Rect.left')
+  @DocsEditable
+  final CssPrimitiveValue left;
+
+  @DomName('Rect.right')
+  @DocsEditable
+  final CssPrimitiveValue right;
+
+  @DomName('Rect.top')
+  @DocsEditable
+  final CssPrimitiveValue top;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable
+@DomName('RGBColor')
+class CssRgbColor native "*RGBColor" {
+
+  @DomName('RGBColor.blue')
+  @DocsEditable
+  final CssPrimitiveValue blue;
+
+  @DomName('RGBColor.green')
+  @DocsEditable
+  final CssPrimitiveValue green;
+
+  @DomName('RGBColor.red')
+  @DocsEditable
+  final CssPrimitiveValue red;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable
 @DomName('CSSRule')
 class CssRule native "*CSSRule" {
 
@@ -2296,41 +2418,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-String _cachedBrowserPrefix;
-
-String get _browserPrefix {
-  if (_cachedBrowserPrefix == null) {
-    if (_Device.isFirefox) {
-      _cachedBrowserPrefix = '-moz-';
-    } else if (_Device.isIE) {
-      _cachedBrowserPrefix = '-ms-';
-    } else if (_Device.isOpera) {
-      _cachedBrowserPrefix = '-o-';
-    } else {
-      _cachedBrowserPrefix = '-webkit-';
-    }
-  }
-  return _cachedBrowserPrefix;
-}
-
-String _cachedBrowserPropertyPrefix;
-
-/// Prefix as used for JS property names.
-String get _browserPropertyPrefix {
-  if (_cachedBrowserPropertyPrefix == null) {
-    if (_Device.isFirefox) {
-      _cachedBrowserPropertyPrefix = 'moz';
-    } else if (_Device.isIE) {
-      _cachedBrowserPropertyPrefix = 'ms';
-    } else if (_Device.isOpera) {
-      _cachedBrowserPropertyPrefix = 'o';
-    } else {
-      _cachedBrowserPropertyPrefix = 'webkit';
-    }
-  }
-  return _cachedBrowserPropertyPrefix;
-}
-
 @DomName('CSSStyleDeclaration')
 class CssStyleDeclaration native "*CSSStyleDeclaration" {
   factory CssStyleDeclaration() => _CssStyleDeclarationFactoryProvider.createCssStyleDeclaration();
@@ -2404,153 +2491,153 @@
     if (JS('bool', '"transition" in document.body.style')) {
       return true;
     }
-    var propertyName = '${_browserPropertyPrefix}Transition';
+    var propertyName = '${Device.propertyPrefix}Transition';
     return JS('bool', '# in document.body.style', propertyName);
   }
 
   // TODO(jacobr): generate this list of properties using the existing script.
   /** Gets the value of "align-content" */
   String get alignContent =>
-    getPropertyValue('${_browserPrefix}align-content');
+    getPropertyValue('${Device.cssPrefix}align-content');
 
   /** Sets the value of "align-content" */
   void set alignContent(String value) {
-    setProperty('${_browserPrefix}align-content', value, '');
+    setProperty('${Device.cssPrefix}align-content', value, '');
   }
 
   /** Gets the value of "align-items" */
   String get alignItems =>
-    getPropertyValue('${_browserPrefix}align-items');
+    getPropertyValue('${Device.cssPrefix}align-items');
 
   /** Sets the value of "align-items" */
   void set alignItems(String value) {
-    setProperty('${_browserPrefix}align-items', value, '');
+    setProperty('${Device.cssPrefix}align-items', value, '');
   }
 
   /** Gets the value of "align-self" */
   String get alignSelf =>
-    getPropertyValue('${_browserPrefix}align-self');
+    getPropertyValue('${Device.cssPrefix}align-self');
 
   /** Sets the value of "align-self" */
   void set alignSelf(String value) {
-    setProperty('${_browserPrefix}align-self', value, '');
+    setProperty('${Device.cssPrefix}align-self', value, '');
   }
 
   /** Gets the value of "animation" */
   String get animation =>
-    getPropertyValue('${_browserPrefix}animation');
+    getPropertyValue('${Device.cssPrefix}animation');
 
   /** Sets the value of "animation" */
   void set animation(String value) {
-    setProperty('${_browserPrefix}animation', value, '');
+    setProperty('${Device.cssPrefix}animation', value, '');
   }
 
   /** Gets the value of "animation-delay" */
   String get animationDelay =>
-    getPropertyValue('${_browserPrefix}animation-delay');
+    getPropertyValue('${Device.cssPrefix}animation-delay');
 
   /** Sets the value of "animation-delay" */
   void set animationDelay(String value) {
-    setProperty('${_browserPrefix}animation-delay', value, '');
+    setProperty('${Device.cssPrefix}animation-delay', value, '');
   }
 
   /** Gets the value of "animation-direction" */
   String get animationDirection =>
-    getPropertyValue('${_browserPrefix}animation-direction');
+    getPropertyValue('${Device.cssPrefix}animation-direction');
 
   /** Sets the value of "animation-direction" */
   void set animationDirection(String value) {
-    setProperty('${_browserPrefix}animation-direction', value, '');
+    setProperty('${Device.cssPrefix}animation-direction', value, '');
   }
 
   /** Gets the value of "animation-duration" */
   String get animationDuration =>
-    getPropertyValue('${_browserPrefix}animation-duration');
+    getPropertyValue('${Device.cssPrefix}animation-duration');
 
   /** Sets the value of "animation-duration" */
   void set animationDuration(String value) {
-    setProperty('${_browserPrefix}animation-duration', value, '');
+    setProperty('${Device.cssPrefix}animation-duration', value, '');
   }
 
   /** Gets the value of "animation-fill-mode" */
   String get animationFillMode =>
-    getPropertyValue('${_browserPrefix}animation-fill-mode');
+    getPropertyValue('${Device.cssPrefix}animation-fill-mode');
 
   /** Sets the value of "animation-fill-mode" */
   void set animationFillMode(String value) {
-    setProperty('${_browserPrefix}animation-fill-mode', value, '');
+    setProperty('${Device.cssPrefix}animation-fill-mode', value, '');
   }
 
   /** Gets the value of "animation-iteration-count" */
   String get animationIterationCount =>
-    getPropertyValue('${_browserPrefix}animation-iteration-count');
+    getPropertyValue('${Device.cssPrefix}animation-iteration-count');
 
   /** Sets the value of "animation-iteration-count" */
   void set animationIterationCount(String value) {
-    setProperty('${_browserPrefix}animation-iteration-count', value, '');
+    setProperty('${Device.cssPrefix}animation-iteration-count', value, '');
   }
 
   /** Gets the value of "animation-name" */
   String get animationName =>
-    getPropertyValue('${_browserPrefix}animation-name');
+    getPropertyValue('${Device.cssPrefix}animation-name');
 
   /** Sets the value of "animation-name" */
   void set animationName(String value) {
-    setProperty('${_browserPrefix}animation-name', value, '');
+    setProperty('${Device.cssPrefix}animation-name', value, '');
   }
 
   /** Gets the value of "animation-play-state" */
   String get animationPlayState =>
-    getPropertyValue('${_browserPrefix}animation-play-state');
+    getPropertyValue('${Device.cssPrefix}animation-play-state');
 
   /** Sets the value of "animation-play-state" */
   void set animationPlayState(String value) {
-    setProperty('${_browserPrefix}animation-play-state', value, '');
+    setProperty('${Device.cssPrefix}animation-play-state', value, '');
   }
 
   /** Gets the value of "animation-timing-function" */
   String get animationTimingFunction =>
-    getPropertyValue('${_browserPrefix}animation-timing-function');
+    getPropertyValue('${Device.cssPrefix}animation-timing-function');
 
   /** Sets the value of "animation-timing-function" */
   void set animationTimingFunction(String value) {
-    setProperty('${_browserPrefix}animation-timing-function', value, '');
+    setProperty('${Device.cssPrefix}animation-timing-function', value, '');
   }
 
   /** Gets the value of "app-region" */
   String get appRegion =>
-    getPropertyValue('${_browserPrefix}app-region');
+    getPropertyValue('${Device.cssPrefix}app-region');
 
   /** Sets the value of "app-region" */
   void set appRegion(String value) {
-    setProperty('${_browserPrefix}app-region', value, '');
+    setProperty('${Device.cssPrefix}app-region', value, '');
   }
 
   /** Gets the value of "appearance" */
   String get appearance =>
-    getPropertyValue('${_browserPrefix}appearance');
+    getPropertyValue('${Device.cssPrefix}appearance');
 
   /** Sets the value of "appearance" */
   void set appearance(String value) {
-    setProperty('${_browserPrefix}appearance', value, '');
+    setProperty('${Device.cssPrefix}appearance', value, '');
   }
 
   /** Gets the value of "aspect-ratio" */
   String get aspectRatio =>
-    getPropertyValue('${_browserPrefix}aspect-ratio');
+    getPropertyValue('${Device.cssPrefix}aspect-ratio');
 
   /** Sets the value of "aspect-ratio" */
   void set aspectRatio(String value) {
-    setProperty('${_browserPrefix}aspect-ratio', value, '');
+    setProperty('${Device.cssPrefix}aspect-ratio', value, '');
   }
 
   /** Gets the value of "backface-visibility" */
   String get backfaceVisibility =>
-    getPropertyValue('${_browserPrefix}backface-visibility');
+    getPropertyValue('${Device.cssPrefix}backface-visibility');
 
   /** Sets the value of "backface-visibility" */
   void set backfaceVisibility(String value) {
-    setProperty('${_browserPrefix}backface-visibility', value, '');
+    setProperty('${Device.cssPrefix}backface-visibility', value, '');
   }
 
   /** Gets the value of "background" */
@@ -2591,11 +2678,11 @@
 
   /** Gets the value of "background-composite" */
   String get backgroundComposite =>
-    getPropertyValue('${_browserPrefix}background-composite');
+    getPropertyValue('${Device.cssPrefix}background-composite');
 
   /** Sets the value of "background-composite" */
   void set backgroundComposite(String value) {
-    setProperty('${_browserPrefix}background-composite', value, '');
+    setProperty('${Device.cssPrefix}background-composite', value, '');
   }
 
   /** Gets the value of "background-image" */
@@ -2681,11 +2768,11 @@
 
   /** Gets the value of "blend-mode" */
   String get blendMode =>
-    getPropertyValue('${_browserPrefix}blend-mode');
+    getPropertyValue('${Device.cssPrefix}blend-mode');
 
   /** Sets the value of "blend-mode" */
   void set blendMode(String value) {
-    setProperty('${_browserPrefix}blend-mode', value, '');
+    setProperty('${Device.cssPrefix}blend-mode', value, '');
   }
 
   /** Gets the value of "border" */
@@ -2699,74 +2786,74 @@
 
   /** Gets the value of "border-after" */
   String get borderAfter =>
-    getPropertyValue('${_browserPrefix}border-after');
+    getPropertyValue('${Device.cssPrefix}border-after');
 
   /** Sets the value of "border-after" */
   void set borderAfter(String value) {
-    setProperty('${_browserPrefix}border-after', value, '');
+    setProperty('${Device.cssPrefix}border-after', value, '');
   }
 
   /** Gets the value of "border-after-color" */
   String get borderAfterColor =>
-    getPropertyValue('${_browserPrefix}border-after-color');
+    getPropertyValue('${Device.cssPrefix}border-after-color');
 
   /** Sets the value of "border-after-color" */
   void set borderAfterColor(String value) {
-    setProperty('${_browserPrefix}border-after-color', value, '');
+    setProperty('${Device.cssPrefix}border-after-color', value, '');
   }
 
   /** Gets the value of "border-after-style" */
   String get borderAfterStyle =>
-    getPropertyValue('${_browserPrefix}border-after-style');
+    getPropertyValue('${Device.cssPrefix}border-after-style');
 
   /** Sets the value of "border-after-style" */
   void set borderAfterStyle(String value) {
-    setProperty('${_browserPrefix}border-after-style', value, '');
+    setProperty('${Device.cssPrefix}border-after-style', value, '');
   }
 
   /** Gets the value of "border-after-width" */
   String get borderAfterWidth =>
-    getPropertyValue('${_browserPrefix}border-after-width');
+    getPropertyValue('${Device.cssPrefix}border-after-width');
 
   /** Sets the value of "border-after-width" */
   void set borderAfterWidth(String value) {
-    setProperty('${_browserPrefix}border-after-width', value, '');
+    setProperty('${Device.cssPrefix}border-after-width', value, '');
   }
 
   /** Gets the value of "border-before" */
   String get borderBefore =>
-    getPropertyValue('${_browserPrefix}border-before');
+    getPropertyValue('${Device.cssPrefix}border-before');
 
   /** Sets the value of "border-before" */
   void set borderBefore(String value) {
-    setProperty('${_browserPrefix}border-before', value, '');
+    setProperty('${Device.cssPrefix}border-before', value, '');
   }
 
   /** Gets the value of "border-before-color" */
   String get borderBeforeColor =>
-    getPropertyValue('${_browserPrefix}border-before-color');
+    getPropertyValue('${Device.cssPrefix}border-before-color');
 
   /** Sets the value of "border-before-color" */
   void set borderBeforeColor(String value) {
-    setProperty('${_browserPrefix}border-before-color', value, '');
+    setProperty('${Device.cssPrefix}border-before-color', value, '');
   }
 
   /** Gets the value of "border-before-style" */
   String get borderBeforeStyle =>
-    getPropertyValue('${_browserPrefix}border-before-style');
+    getPropertyValue('${Device.cssPrefix}border-before-style');
 
   /** Sets the value of "border-before-style" */
   void set borderBeforeStyle(String value) {
-    setProperty('${_browserPrefix}border-before-style', value, '');
+    setProperty('${Device.cssPrefix}border-before-style', value, '');
   }
 
   /** Gets the value of "border-before-width" */
   String get borderBeforeWidth =>
-    getPropertyValue('${_browserPrefix}border-before-width');
+    getPropertyValue('${Device.cssPrefix}border-before-width');
 
   /** Sets the value of "border-before-width" */
   void set borderBeforeWidth(String value) {
-    setProperty('${_browserPrefix}border-before-width', value, '');
+    setProperty('${Device.cssPrefix}border-before-width', value, '');
   }
 
   /** Gets the value of "border-bottom" */
@@ -2843,56 +2930,56 @@
 
   /** Gets the value of "border-end" */
   String get borderEnd =>
-    getPropertyValue('${_browserPrefix}border-end');
+    getPropertyValue('${Device.cssPrefix}border-end');
 
   /** Sets the value of "border-end" */
   void set borderEnd(String value) {
-    setProperty('${_browserPrefix}border-end', value, '');
+    setProperty('${Device.cssPrefix}border-end', value, '');
   }
 
   /** Gets the value of "border-end-color" */
   String get borderEndColor =>
-    getPropertyValue('${_browserPrefix}border-end-color');
+    getPropertyValue('${Device.cssPrefix}border-end-color');
 
   /** Sets the value of "border-end-color" */
   void set borderEndColor(String value) {
-    setProperty('${_browserPrefix}border-end-color', value, '');
+    setProperty('${Device.cssPrefix}border-end-color', value, '');
   }
 
   /** Gets the value of "border-end-style" */
   String get borderEndStyle =>
-    getPropertyValue('${_browserPrefix}border-end-style');
+    getPropertyValue('${Device.cssPrefix}border-end-style');
 
   /** Sets the value of "border-end-style" */
   void set borderEndStyle(String value) {
-    setProperty('${_browserPrefix}border-end-style', value, '');
+    setProperty('${Device.cssPrefix}border-end-style', value, '');
   }
 
   /** Gets the value of "border-end-width" */
   String get borderEndWidth =>
-    getPropertyValue('${_browserPrefix}border-end-width');
+    getPropertyValue('${Device.cssPrefix}border-end-width');
 
   /** Sets the value of "border-end-width" */
   void set borderEndWidth(String value) {
-    setProperty('${_browserPrefix}border-end-width', value, '');
+    setProperty('${Device.cssPrefix}border-end-width', value, '');
   }
 
   /** Gets the value of "border-fit" */
   String get borderFit =>
-    getPropertyValue('${_browserPrefix}border-fit');
+    getPropertyValue('${Device.cssPrefix}border-fit');
 
   /** Sets the value of "border-fit" */
   void set borderFit(String value) {
-    setProperty('${_browserPrefix}border-fit', value, '');
+    setProperty('${Device.cssPrefix}border-fit', value, '');
   }
 
   /** Gets the value of "border-horizontal-spacing" */
   String get borderHorizontalSpacing =>
-    getPropertyValue('${_browserPrefix}border-horizontal-spacing');
+    getPropertyValue('${Device.cssPrefix}border-horizontal-spacing');
 
   /** Sets the value of "border-horizontal-spacing" */
   void set borderHorizontalSpacing(String value) {
-    setProperty('${_browserPrefix}border-horizontal-spacing', value, '');
+    setProperty('${Device.cssPrefix}border-horizontal-spacing', value, '');
   }
 
   /** Gets the value of "border-image" */
@@ -3041,38 +3128,38 @@
 
   /** Gets the value of "border-start" */
   String get borderStart =>
-    getPropertyValue('${_browserPrefix}border-start');
+    getPropertyValue('${Device.cssPrefix}border-start');
 
   /** Sets the value of "border-start" */
   void set borderStart(String value) {
-    setProperty('${_browserPrefix}border-start', value, '');
+    setProperty('${Device.cssPrefix}border-start', value, '');
   }
 
   /** Gets the value of "border-start-color" */
   String get borderStartColor =>
-    getPropertyValue('${_browserPrefix}border-start-color');
+    getPropertyValue('${Device.cssPrefix}border-start-color');
 
   /** Sets the value of "border-start-color" */
   void set borderStartColor(String value) {
-    setProperty('${_browserPrefix}border-start-color', value, '');
+    setProperty('${Device.cssPrefix}border-start-color', value, '');
   }
 
   /** Gets the value of "border-start-style" */
   String get borderStartStyle =>
-    getPropertyValue('${_browserPrefix}border-start-style');
+    getPropertyValue('${Device.cssPrefix}border-start-style');
 
   /** Sets the value of "border-start-style" */
   void set borderStartStyle(String value) {
-    setProperty('${_browserPrefix}border-start-style', value, '');
+    setProperty('${Device.cssPrefix}border-start-style', value, '');
   }
 
   /** Gets the value of "border-start-width" */
   String get borderStartWidth =>
-    getPropertyValue('${_browserPrefix}border-start-width');
+    getPropertyValue('${Device.cssPrefix}border-start-width');
 
   /** Sets the value of "border-start-width" */
   void set borderStartWidth(String value) {
-    setProperty('${_browserPrefix}border-start-width', value, '');
+    setProperty('${Device.cssPrefix}border-start-width', value, '');
   }
 
   /** Gets the value of "border-style" */
@@ -3140,11 +3227,11 @@
 
   /** Gets the value of "border-vertical-spacing" */
   String get borderVerticalSpacing =>
-    getPropertyValue('${_browserPrefix}border-vertical-spacing');
+    getPropertyValue('${Device.cssPrefix}border-vertical-spacing');
 
   /** Sets the value of "border-vertical-spacing" */
   void set borderVerticalSpacing(String value) {
-    setProperty('${_browserPrefix}border-vertical-spacing', value, '');
+    setProperty('${Device.cssPrefix}border-vertical-spacing', value, '');
   }
 
   /** Gets the value of "border-width" */
@@ -3167,92 +3254,92 @@
 
   /** Gets the value of "box-align" */
   String get boxAlign =>
-    getPropertyValue('${_browserPrefix}box-align');
+    getPropertyValue('${Device.cssPrefix}box-align');
 
   /** Sets the value of "box-align" */
   void set boxAlign(String value) {
-    setProperty('${_browserPrefix}box-align', value, '');
+    setProperty('${Device.cssPrefix}box-align', value, '');
   }
 
   /** Gets the value of "box-decoration-break" */
   String get boxDecorationBreak =>
-    getPropertyValue('${_browserPrefix}box-decoration-break');
+    getPropertyValue('${Device.cssPrefix}box-decoration-break');
 
   /** Sets the value of "box-decoration-break" */
   void set boxDecorationBreak(String value) {
-    setProperty('${_browserPrefix}box-decoration-break', value, '');
+    setProperty('${Device.cssPrefix}box-decoration-break', value, '');
   }
 
   /** Gets the value of "box-direction" */
   String get boxDirection =>
-    getPropertyValue('${_browserPrefix}box-direction');
+    getPropertyValue('${Device.cssPrefix}box-direction');
 
   /** Sets the value of "box-direction" */
   void set boxDirection(String value) {
-    setProperty('${_browserPrefix}box-direction', value, '');
+    setProperty('${Device.cssPrefix}box-direction', value, '');
   }
 
   /** Gets the value of "box-flex" */
   String get boxFlex =>
-    getPropertyValue('${_browserPrefix}box-flex');
+    getPropertyValue('${Device.cssPrefix}box-flex');
 
   /** Sets the value of "box-flex" */
   void set boxFlex(String value) {
-    setProperty('${_browserPrefix}box-flex', value, '');
+    setProperty('${Device.cssPrefix}box-flex', value, '');
   }
 
   /** Gets the value of "box-flex-group" */
   String get boxFlexGroup =>
-    getPropertyValue('${_browserPrefix}box-flex-group');
+    getPropertyValue('${Device.cssPrefix}box-flex-group');
 
   /** Sets the value of "box-flex-group" */
   void set boxFlexGroup(String value) {
-    setProperty('${_browserPrefix}box-flex-group', value, '');
+    setProperty('${Device.cssPrefix}box-flex-group', value, '');
   }
 
   /** Gets the value of "box-lines" */
   String get boxLines =>
-    getPropertyValue('${_browserPrefix}box-lines');
+    getPropertyValue('${Device.cssPrefix}box-lines');
 
   /** Sets the value of "box-lines" */
   void set boxLines(String value) {
-    setProperty('${_browserPrefix}box-lines', value, '');
+    setProperty('${Device.cssPrefix}box-lines', value, '');
   }
 
   /** Gets the value of "box-ordinal-group" */
   String get boxOrdinalGroup =>
-    getPropertyValue('${_browserPrefix}box-ordinal-group');
+    getPropertyValue('${Device.cssPrefix}box-ordinal-group');
 
   /** Sets the value of "box-ordinal-group" */
   void set boxOrdinalGroup(String value) {
-    setProperty('${_browserPrefix}box-ordinal-group', value, '');
+    setProperty('${Device.cssPrefix}box-ordinal-group', value, '');
   }
 
   /** Gets the value of "box-orient" */
   String get boxOrient =>
-    getPropertyValue('${_browserPrefix}box-orient');
+    getPropertyValue('${Device.cssPrefix}box-orient');
 
   /** Sets the value of "box-orient" */
   void set boxOrient(String value) {
-    setProperty('${_browserPrefix}box-orient', value, '');
+    setProperty('${Device.cssPrefix}box-orient', value, '');
   }
 
   /** Gets the value of "box-pack" */
   String get boxPack =>
-    getPropertyValue('${_browserPrefix}box-pack');
+    getPropertyValue('${Device.cssPrefix}box-pack');
 
   /** Sets the value of "box-pack" */
   void set boxPack(String value) {
-    setProperty('${_browserPrefix}box-pack', value, '');
+    setProperty('${Device.cssPrefix}box-pack', value, '');
   }
 
   /** Gets the value of "box-reflect" */
   String get boxReflect =>
-    getPropertyValue('${_browserPrefix}box-reflect');
+    getPropertyValue('${Device.cssPrefix}box-reflect');
 
   /** Sets the value of "box-reflect" */
   void set boxReflect(String value) {
-    setProperty('${_browserPrefix}box-reflect', value, '');
+    setProperty('${Device.cssPrefix}box-reflect', value, '');
   }
 
   /** Gets the value of "box-shadow" */
@@ -3302,11 +3389,11 @@
 
   /** Gets the value of "clip-path" */
   String get clipPath =>
-    getPropertyValue('${_browserPrefix}clip-path');
+    getPropertyValue('${Device.cssPrefix}clip-path');
 
   /** Sets the value of "clip-path" */
   void set clipPath(String value) {
-    setProperty('${_browserPrefix}clip-path', value, '');
+    setProperty('${Device.cssPrefix}clip-path', value, '');
   }
 
   /** Gets the value of "color" */
@@ -3320,137 +3407,137 @@
 
   /** Gets the value of "color-correction" */
   String get colorCorrection =>
-    getPropertyValue('${_browserPrefix}color-correction');
+    getPropertyValue('${Device.cssPrefix}color-correction');
 
   /** Sets the value of "color-correction" */
   void set colorCorrection(String value) {
-    setProperty('${_browserPrefix}color-correction', value, '');
+    setProperty('${Device.cssPrefix}color-correction', value, '');
   }
 
   /** Gets the value of "column-axis" */
   String get columnAxis =>
-    getPropertyValue('${_browserPrefix}column-axis');
+    getPropertyValue('${Device.cssPrefix}column-axis');
 
   /** Sets the value of "column-axis" */
   void set columnAxis(String value) {
-    setProperty('${_browserPrefix}column-axis', value, '');
+    setProperty('${Device.cssPrefix}column-axis', value, '');
   }
 
   /** Gets the value of "column-break-after" */
   String get columnBreakAfter =>
-    getPropertyValue('${_browserPrefix}column-break-after');
+    getPropertyValue('${Device.cssPrefix}column-break-after');
 
   /** Sets the value of "column-break-after" */
   void set columnBreakAfter(String value) {
-    setProperty('${_browserPrefix}column-break-after', value, '');
+    setProperty('${Device.cssPrefix}column-break-after', value, '');
   }
 
   /** Gets the value of "column-break-before" */
   String get columnBreakBefore =>
-    getPropertyValue('${_browserPrefix}column-break-before');
+    getPropertyValue('${Device.cssPrefix}column-break-before');
 
   /** Sets the value of "column-break-before" */
   void set columnBreakBefore(String value) {
-    setProperty('${_browserPrefix}column-break-before', value, '');
+    setProperty('${Device.cssPrefix}column-break-before', value, '');
   }
 
   /** Gets the value of "column-break-inside" */
   String get columnBreakInside =>
-    getPropertyValue('${_browserPrefix}column-break-inside');
+    getPropertyValue('${Device.cssPrefix}column-break-inside');
 
   /** Sets the value of "column-break-inside" */
   void set columnBreakInside(String value) {
-    setProperty('${_browserPrefix}column-break-inside', value, '');
+    setProperty('${Device.cssPrefix}column-break-inside', value, '');
   }
 
   /** Gets the value of "column-count" */
   String get columnCount =>
-    getPropertyValue('${_browserPrefix}column-count');
+    getPropertyValue('${Device.cssPrefix}column-count');
 
   /** Sets the value of "column-count" */
   void set columnCount(String value) {
-    setProperty('${_browserPrefix}column-count', value, '');
+    setProperty('${Device.cssPrefix}column-count', value, '');
   }
 
   /** Gets the value of "column-gap" */
   String get columnGap =>
-    getPropertyValue('${_browserPrefix}column-gap');
+    getPropertyValue('${Device.cssPrefix}column-gap');
 
   /** Sets the value of "column-gap" */
   void set columnGap(String value) {
-    setProperty('${_browserPrefix}column-gap', value, '');
+    setProperty('${Device.cssPrefix}column-gap', value, '');
   }
 
   /** Gets the value of "column-progression" */
   String get columnProgression =>
-    getPropertyValue('${_browserPrefix}column-progression');
+    getPropertyValue('${Device.cssPrefix}column-progression');
 
   /** Sets the value of "column-progression" */
   void set columnProgression(String value) {
-    setProperty('${_browserPrefix}column-progression', value, '');
+    setProperty('${Device.cssPrefix}column-progression', value, '');
   }
 
   /** Gets the value of "column-rule" */
   String get columnRule =>
-    getPropertyValue('${_browserPrefix}column-rule');
+    getPropertyValue('${Device.cssPrefix}column-rule');
 
   /** Sets the value of "column-rule" */
   void set columnRule(String value) {
-    setProperty('${_browserPrefix}column-rule', value, '');
+    setProperty('${Device.cssPrefix}column-rule', value, '');
   }
 
   /** Gets the value of "column-rule-color" */
   String get columnRuleColor =>
-    getPropertyValue('${_browserPrefix}column-rule-color');
+    getPropertyValue('${Device.cssPrefix}column-rule-color');
 
   /** Sets the value of "column-rule-color" */
   void set columnRuleColor(String value) {
-    setProperty('${_browserPrefix}column-rule-color', value, '');
+    setProperty('${Device.cssPrefix}column-rule-color', value, '');
   }
 
   /** Gets the value of "column-rule-style" */
   String get columnRuleStyle =>
-    getPropertyValue('${_browserPrefix}column-rule-style');
+    getPropertyValue('${Device.cssPrefix}column-rule-style');
 
   /** Sets the value of "column-rule-style" */
   void set columnRuleStyle(String value) {
-    setProperty('${_browserPrefix}column-rule-style', value, '');
+    setProperty('${Device.cssPrefix}column-rule-style', value, '');
   }
 
   /** Gets the value of "column-rule-width" */
   String get columnRuleWidth =>
-    getPropertyValue('${_browserPrefix}column-rule-width');
+    getPropertyValue('${Device.cssPrefix}column-rule-width');
 
   /** Sets the value of "column-rule-width" */
   void set columnRuleWidth(String value) {
-    setProperty('${_browserPrefix}column-rule-width', value, '');
+    setProperty('${Device.cssPrefix}column-rule-width', value, '');
   }
 
   /** Gets the value of "column-span" */
   String get columnSpan =>
-    getPropertyValue('${_browserPrefix}column-span');
+    getPropertyValue('${Device.cssPrefix}column-span');
 
   /** Sets the value of "column-span" */
   void set columnSpan(String value) {
-    setProperty('${_browserPrefix}column-span', value, '');
+    setProperty('${Device.cssPrefix}column-span', value, '');
   }
 
   /** Gets the value of "column-width" */
   String get columnWidth =>
-    getPropertyValue('${_browserPrefix}column-width');
+    getPropertyValue('${Device.cssPrefix}column-width');
 
   /** Sets the value of "column-width" */
   void set columnWidth(String value) {
-    setProperty('${_browserPrefix}column-width', value, '');
+    setProperty('${Device.cssPrefix}column-width', value, '');
   }
 
   /** Gets the value of "columns" */
   String get columns =>
-    getPropertyValue('${_browserPrefix}columns');
+    getPropertyValue('${Device.cssPrefix}columns');
 
   /** Sets the value of "columns" */
   void set columns(String value) {
-    setProperty('${_browserPrefix}columns', value, '');
+    setProperty('${Device.cssPrefix}columns', value, '');
   }
 
   /** Gets the value of "content" */
@@ -3491,11 +3578,11 @@
 
   /** Gets the value of "dashboard-region" */
   String get dashboardRegion =>
-    getPropertyValue('${_browserPrefix}dashboard-region');
+    getPropertyValue('${Device.cssPrefix}dashboard-region');
 
   /** Sets the value of "dashboard-region" */
   void set dashboardRegion(String value) {
-    setProperty('${_browserPrefix}dashboard-region', value, '');
+    setProperty('${Device.cssPrefix}dashboard-region', value, '');
   }
 
   /** Gets the value of "direction" */
@@ -3527,74 +3614,74 @@
 
   /** Gets the value of "filter" */
   String get filter =>
-    getPropertyValue('${_browserPrefix}filter');
+    getPropertyValue('${Device.cssPrefix}filter');
 
   /** Sets the value of "filter" */
   void set filter(String value) {
-    setProperty('${_browserPrefix}filter', value, '');
+    setProperty('${Device.cssPrefix}filter', value, '');
   }
 
   /** Gets the value of "flex" */
   String get flex =>
-    getPropertyValue('${_browserPrefix}flex');
+    getPropertyValue('${Device.cssPrefix}flex');
 
   /** Sets the value of "flex" */
   void set flex(String value) {
-    setProperty('${_browserPrefix}flex', value, '');
+    setProperty('${Device.cssPrefix}flex', value, '');
   }
 
   /** Gets the value of "flex-basis" */
   String get flexBasis =>
-    getPropertyValue('${_browserPrefix}flex-basis');
+    getPropertyValue('${Device.cssPrefix}flex-basis');
 
   /** Sets the value of "flex-basis" */
   void set flexBasis(String value) {
-    setProperty('${_browserPrefix}flex-basis', value, '');
+    setProperty('${Device.cssPrefix}flex-basis', value, '');
   }
 
   /** Gets the value of "flex-direction" */
   String get flexDirection =>
-    getPropertyValue('${_browserPrefix}flex-direction');
+    getPropertyValue('${Device.cssPrefix}flex-direction');
 
   /** Sets the value of "flex-direction" */
   void set flexDirection(String value) {
-    setProperty('${_browserPrefix}flex-direction', value, '');
+    setProperty('${Device.cssPrefix}flex-direction', value, '');
   }
 
   /** Gets the value of "flex-flow" */
   String get flexFlow =>
-    getPropertyValue('${_browserPrefix}flex-flow');
+    getPropertyValue('${Device.cssPrefix}flex-flow');
 
   /** Sets the value of "flex-flow" */
   void set flexFlow(String value) {
-    setProperty('${_browserPrefix}flex-flow', value, '');
+    setProperty('${Device.cssPrefix}flex-flow', value, '');
   }
 
   /** Gets the value of "flex-grow" */
   String get flexGrow =>
-    getPropertyValue('${_browserPrefix}flex-grow');
+    getPropertyValue('${Device.cssPrefix}flex-grow');
 
   /** Sets the value of "flex-grow" */
   void set flexGrow(String value) {
-    setProperty('${_browserPrefix}flex-grow', value, '');
+    setProperty('${Device.cssPrefix}flex-grow', value, '');
   }
 
   /** Gets the value of "flex-shrink" */
   String get flexShrink =>
-    getPropertyValue('${_browserPrefix}flex-shrink');
+    getPropertyValue('${Device.cssPrefix}flex-shrink');
 
   /** Sets the value of "flex-shrink" */
   void set flexShrink(String value) {
-    setProperty('${_browserPrefix}flex-shrink', value, '');
+    setProperty('${Device.cssPrefix}flex-shrink', value, '');
   }
 
   /** Gets the value of "flex-wrap" */
   String get flexWrap =>
-    getPropertyValue('${_browserPrefix}flex-wrap');
+    getPropertyValue('${Device.cssPrefix}flex-wrap');
 
   /** Sets the value of "flex-wrap" */
   void set flexWrap(String value) {
-    setProperty('${_browserPrefix}flex-wrap', value, '');
+    setProperty('${Device.cssPrefix}flex-wrap', value, '');
   }
 
   /** Gets the value of "float" */
@@ -3608,20 +3695,20 @@
 
   /** Gets the value of "flow-from" */
   String get flowFrom =>
-    getPropertyValue('${_browserPrefix}flow-from');
+    getPropertyValue('${Device.cssPrefix}flow-from');
 
   /** Sets the value of "flow-from" */
   void set flowFrom(String value) {
-    setProperty('${_browserPrefix}flow-from', value, '');
+    setProperty('${Device.cssPrefix}flow-from', value, '');
   }
 
   /** Gets the value of "flow-into" */
   String get flowInto =>
-    getPropertyValue('${_browserPrefix}flow-into');
+    getPropertyValue('${Device.cssPrefix}flow-into');
 
   /** Sets the value of "flow-into" */
   void set flowInto(String value) {
-    setProperty('${_browserPrefix}flow-into', value, '');
+    setProperty('${Device.cssPrefix}flow-into', value, '');
   }
 
   /** Gets the value of "font" */
@@ -3644,20 +3731,20 @@
 
   /** Gets the value of "font-feature-settings" */
   String get fontFeatureSettings =>
-    getPropertyValue('${_browserPrefix}font-feature-settings');
+    getPropertyValue('${Device.cssPrefix}font-feature-settings');
 
   /** Sets the value of "font-feature-settings" */
   void set fontFeatureSettings(String value) {
-    setProperty('${_browserPrefix}font-feature-settings', value, '');
+    setProperty('${Device.cssPrefix}font-feature-settings', value, '');
   }
 
   /** Gets the value of "font-kerning" */
   String get fontKerning =>
-    getPropertyValue('${_browserPrefix}font-kerning');
+    getPropertyValue('${Device.cssPrefix}font-kerning');
 
   /** Sets the value of "font-kerning" */
   void set fontKerning(String value) {
-    setProperty('${_browserPrefix}font-kerning', value, '');
+    setProperty('${Device.cssPrefix}font-kerning', value, '');
   }
 
   /** Gets the value of "font-size" */
@@ -3671,20 +3758,20 @@
 
   /** Gets the value of "font-size-delta" */
   String get fontSizeDelta =>
-    getPropertyValue('${_browserPrefix}font-size-delta');
+    getPropertyValue('${Device.cssPrefix}font-size-delta');
 
   /** Sets the value of "font-size-delta" */
   void set fontSizeDelta(String value) {
-    setProperty('${_browserPrefix}font-size-delta', value, '');
+    setProperty('${Device.cssPrefix}font-size-delta', value, '');
   }
 
   /** Gets the value of "font-smoothing" */
   String get fontSmoothing =>
-    getPropertyValue('${_browserPrefix}font-smoothing');
+    getPropertyValue('${Device.cssPrefix}font-smoothing');
 
   /** Sets the value of "font-smoothing" */
   void set fontSmoothing(String value) {
-    setProperty('${_browserPrefix}font-smoothing', value, '');
+    setProperty('${Device.cssPrefix}font-smoothing', value, '');
   }
 
   /** Gets the value of "font-stretch" */
@@ -3716,11 +3803,11 @@
 
   /** Gets the value of "font-variant-ligatures" */
   String get fontVariantLigatures =>
-    getPropertyValue('${_browserPrefix}font-variant-ligatures');
+    getPropertyValue('${Device.cssPrefix}font-variant-ligatures');
 
   /** Sets the value of "font-variant-ligatures" */
   void set fontVariantLigatures(String value) {
-    setProperty('${_browserPrefix}font-variant-ligatures', value, '');
+    setProperty('${Device.cssPrefix}font-variant-ligatures', value, '');
   }
 
   /** Gets the value of "font-weight" */
@@ -3734,38 +3821,38 @@
 
   /** Gets the value of "grid-column" */
   String get gridColumn =>
-    getPropertyValue('${_browserPrefix}grid-column');
+    getPropertyValue('${Device.cssPrefix}grid-column');
 
   /** Sets the value of "grid-column" */
   void set gridColumn(String value) {
-    setProperty('${_browserPrefix}grid-column', value, '');
+    setProperty('${Device.cssPrefix}grid-column', value, '');
   }
 
   /** Gets the value of "grid-columns" */
   String get gridColumns =>
-    getPropertyValue('${_browserPrefix}grid-columns');
+    getPropertyValue('${Device.cssPrefix}grid-columns');
 
   /** Sets the value of "grid-columns" */
   void set gridColumns(String value) {
-    setProperty('${_browserPrefix}grid-columns', value, '');
+    setProperty('${Device.cssPrefix}grid-columns', value, '');
   }
 
   /** Gets the value of "grid-row" */
   String get gridRow =>
-    getPropertyValue('${_browserPrefix}grid-row');
+    getPropertyValue('${Device.cssPrefix}grid-row');
 
   /** Sets the value of "grid-row" */
   void set gridRow(String value) {
-    setProperty('${_browserPrefix}grid-row', value, '');
+    setProperty('${Device.cssPrefix}grid-row', value, '');
   }
 
   /** Gets the value of "grid-rows" */
   String get gridRows =>
-    getPropertyValue('${_browserPrefix}grid-rows');
+    getPropertyValue('${Device.cssPrefix}grid-rows');
 
   /** Sets the value of "grid-rows" */
   void set gridRows(String value) {
-    setProperty('${_browserPrefix}grid-rows', value, '');
+    setProperty('${Device.cssPrefix}grid-rows', value, '');
   }
 
   /** Gets the value of "height" */
@@ -3779,56 +3866,56 @@
 
   /** Gets the value of "highlight" */
   String get highlight =>
-    getPropertyValue('${_browserPrefix}highlight');
+    getPropertyValue('${Device.cssPrefix}highlight');
 
   /** Sets the value of "highlight" */
   void set highlight(String value) {
-    setProperty('${_browserPrefix}highlight', value, '');
+    setProperty('${Device.cssPrefix}highlight', value, '');
   }
 
   /** Gets the value of "hyphenate-character" */
   String get hyphenateCharacter =>
-    getPropertyValue('${_browserPrefix}hyphenate-character');
+    getPropertyValue('${Device.cssPrefix}hyphenate-character');
 
   /** Sets the value of "hyphenate-character" */
   void set hyphenateCharacter(String value) {
-    setProperty('${_browserPrefix}hyphenate-character', value, '');
+    setProperty('${Device.cssPrefix}hyphenate-character', value, '');
   }
 
   /** Gets the value of "hyphenate-limit-after" */
   String get hyphenateLimitAfter =>
-    getPropertyValue('${_browserPrefix}hyphenate-limit-after');
+    getPropertyValue('${Device.cssPrefix}hyphenate-limit-after');
 
   /** Sets the value of "hyphenate-limit-after" */
   void set hyphenateLimitAfter(String value) {
-    setProperty('${_browserPrefix}hyphenate-limit-after', value, '');
+    setProperty('${Device.cssPrefix}hyphenate-limit-after', value, '');
   }
 
   /** Gets the value of "hyphenate-limit-before" */
   String get hyphenateLimitBefore =>
-    getPropertyValue('${_browserPrefix}hyphenate-limit-before');
+    getPropertyValue('${Device.cssPrefix}hyphenate-limit-before');
 
   /** Sets the value of "hyphenate-limit-before" */
   void set hyphenateLimitBefore(String value) {
-    setProperty('${_browserPrefix}hyphenate-limit-before', value, '');
+    setProperty('${Device.cssPrefix}hyphenate-limit-before', value, '');
   }
 
   /** Gets the value of "hyphenate-limit-lines" */
   String get hyphenateLimitLines =>
-    getPropertyValue('${_browserPrefix}hyphenate-limit-lines');
+    getPropertyValue('${Device.cssPrefix}hyphenate-limit-lines');
 
   /** Sets the value of "hyphenate-limit-lines" */
   void set hyphenateLimitLines(String value) {
-    setProperty('${_browserPrefix}hyphenate-limit-lines', value, '');
+    setProperty('${Device.cssPrefix}hyphenate-limit-lines', value, '');
   }
 
   /** Gets the value of "hyphens" */
   String get hyphens =>
-    getPropertyValue('${_browserPrefix}hyphens');
+    getPropertyValue('${Device.cssPrefix}hyphens');
 
   /** Sets the value of "hyphens" */
   void set hyphens(String value) {
-    setProperty('${_browserPrefix}hyphens', value, '');
+    setProperty('${Device.cssPrefix}hyphens', value, '');
   }
 
   /** Gets the value of "image-orientation" */
@@ -3860,11 +3947,11 @@
 
   /** Gets the value of "justify-content" */
   String get justifyContent =>
-    getPropertyValue('${_browserPrefix}justify-content');
+    getPropertyValue('${Device.cssPrefix}justify-content');
 
   /** Sets the value of "justify-content" */
   void set justifyContent(String value) {
-    setProperty('${_browserPrefix}justify-content', value, '');
+    setProperty('${Device.cssPrefix}justify-content', value, '');
   }
 
   /** Gets the value of "left" */
@@ -3887,47 +3974,47 @@
 
   /** Gets the value of "line-align" */
   String get lineAlign =>
-    getPropertyValue('${_browserPrefix}line-align');
+    getPropertyValue('${Device.cssPrefix}line-align');
 
   /** Sets the value of "line-align" */
   void set lineAlign(String value) {
-    setProperty('${_browserPrefix}line-align', value, '');
+    setProperty('${Device.cssPrefix}line-align', value, '');
   }
 
   /** Gets the value of "line-box-contain" */
   String get lineBoxContain =>
-    getPropertyValue('${_browserPrefix}line-box-contain');
+    getPropertyValue('${Device.cssPrefix}line-box-contain');
 
   /** Sets the value of "line-box-contain" */
   void set lineBoxContain(String value) {
-    setProperty('${_browserPrefix}line-box-contain', value, '');
+    setProperty('${Device.cssPrefix}line-box-contain', value, '');
   }
 
   /** Gets the value of "line-break" */
   String get lineBreak =>
-    getPropertyValue('${_browserPrefix}line-break');
+    getPropertyValue('${Device.cssPrefix}line-break');
 
   /** Sets the value of "line-break" */
   void set lineBreak(String value) {
-    setProperty('${_browserPrefix}line-break', value, '');
+    setProperty('${Device.cssPrefix}line-break', value, '');
   }
 
   /** Gets the value of "line-clamp" */
   String get lineClamp =>
-    getPropertyValue('${_browserPrefix}line-clamp');
+    getPropertyValue('${Device.cssPrefix}line-clamp');
 
   /** Sets the value of "line-clamp" */
   void set lineClamp(String value) {
-    setProperty('${_browserPrefix}line-clamp', value, '');
+    setProperty('${Device.cssPrefix}line-clamp', value, '');
   }
 
   /** Gets the value of "line-grid" */
   String get lineGrid =>
-    getPropertyValue('${_browserPrefix}line-grid');
+    getPropertyValue('${Device.cssPrefix}line-grid');
 
   /** Sets the value of "line-grid" */
   void set lineGrid(String value) {
-    setProperty('${_browserPrefix}line-grid', value, '');
+    setProperty('${Device.cssPrefix}line-grid', value, '');
   }
 
   /** Gets the value of "line-height" */
@@ -3941,11 +4028,11 @@
 
   /** Gets the value of "line-snap" */
   String get lineSnap =>
-    getPropertyValue('${_browserPrefix}line-snap');
+    getPropertyValue('${Device.cssPrefix}line-snap');
 
   /** Sets the value of "line-snap" */
   void set lineSnap(String value) {
-    setProperty('${_browserPrefix}line-snap', value, '');
+    setProperty('${Device.cssPrefix}line-snap', value, '');
   }
 
   /** Gets the value of "list-style" */
@@ -3986,29 +4073,29 @@
 
   /** Gets the value of "locale" */
   String get locale =>
-    getPropertyValue('${_browserPrefix}locale');
+    getPropertyValue('${Device.cssPrefix}locale');
 
   /** Sets the value of "locale" */
   void set locale(String value) {
-    setProperty('${_browserPrefix}locale', value, '');
+    setProperty('${Device.cssPrefix}locale', value, '');
   }
 
   /** Gets the value of "logical-height" */
   String get logicalHeight =>
-    getPropertyValue('${_browserPrefix}logical-height');
+    getPropertyValue('${Device.cssPrefix}logical-height');
 
   /** Sets the value of "logical-height" */
   void set logicalHeight(String value) {
-    setProperty('${_browserPrefix}logical-height', value, '');
+    setProperty('${Device.cssPrefix}logical-height', value, '');
   }
 
   /** Gets the value of "logical-width" */
   String get logicalWidth =>
-    getPropertyValue('${_browserPrefix}logical-width');
+    getPropertyValue('${Device.cssPrefix}logical-width');
 
   /** Sets the value of "logical-width" */
   void set logicalWidth(String value) {
-    setProperty('${_browserPrefix}logical-width', value, '');
+    setProperty('${Device.cssPrefix}logical-width', value, '');
   }
 
   /** Gets the value of "margin" */
@@ -4022,38 +4109,38 @@
 
   /** Gets the value of "margin-after" */
   String get marginAfter =>
-    getPropertyValue('${_browserPrefix}margin-after');
+    getPropertyValue('${Device.cssPrefix}margin-after');
 
   /** Sets the value of "margin-after" */
   void set marginAfter(String value) {
-    setProperty('${_browserPrefix}margin-after', value, '');
+    setProperty('${Device.cssPrefix}margin-after', value, '');
   }
 
   /** Gets the value of "margin-after-collapse" */
   String get marginAfterCollapse =>
-    getPropertyValue('${_browserPrefix}margin-after-collapse');
+    getPropertyValue('${Device.cssPrefix}margin-after-collapse');
 
   /** Sets the value of "margin-after-collapse" */
   void set marginAfterCollapse(String value) {
-    setProperty('${_browserPrefix}margin-after-collapse', value, '');
+    setProperty('${Device.cssPrefix}margin-after-collapse', value, '');
   }
 
   /** Gets the value of "margin-before" */
   String get marginBefore =>
-    getPropertyValue('${_browserPrefix}margin-before');
+    getPropertyValue('${Device.cssPrefix}margin-before');
 
   /** Sets the value of "margin-before" */
   void set marginBefore(String value) {
-    setProperty('${_browserPrefix}margin-before', value, '');
+    setProperty('${Device.cssPrefix}margin-before', value, '');
   }
 
   /** Gets the value of "margin-before-collapse" */
   String get marginBeforeCollapse =>
-    getPropertyValue('${_browserPrefix}margin-before-collapse');
+    getPropertyValue('${Device.cssPrefix}margin-before-collapse');
 
   /** Sets the value of "margin-before-collapse" */
   void set marginBeforeCollapse(String value) {
-    setProperty('${_browserPrefix}margin-before-collapse', value, '');
+    setProperty('${Device.cssPrefix}margin-before-collapse', value, '');
   }
 
   /** Gets the value of "margin-bottom" */
@@ -4067,29 +4154,29 @@
 
   /** Gets the value of "margin-bottom-collapse" */
   String get marginBottomCollapse =>
-    getPropertyValue('${_browserPrefix}margin-bottom-collapse');
+    getPropertyValue('${Device.cssPrefix}margin-bottom-collapse');
 
   /** Sets the value of "margin-bottom-collapse" */
   void set marginBottomCollapse(String value) {
-    setProperty('${_browserPrefix}margin-bottom-collapse', value, '');
+    setProperty('${Device.cssPrefix}margin-bottom-collapse', value, '');
   }
 
   /** Gets the value of "margin-collapse" */
   String get marginCollapse =>
-    getPropertyValue('${_browserPrefix}margin-collapse');
+    getPropertyValue('${Device.cssPrefix}margin-collapse');
 
   /** Sets the value of "margin-collapse" */
   void set marginCollapse(String value) {
-    setProperty('${_browserPrefix}margin-collapse', value, '');
+    setProperty('${Device.cssPrefix}margin-collapse', value, '');
   }
 
   /** Gets the value of "margin-end" */
   String get marginEnd =>
-    getPropertyValue('${_browserPrefix}margin-end');
+    getPropertyValue('${Device.cssPrefix}margin-end');
 
   /** Sets the value of "margin-end" */
   void set marginEnd(String value) {
-    setProperty('${_browserPrefix}margin-end', value, '');
+    setProperty('${Device.cssPrefix}margin-end', value, '');
   }
 
   /** Gets the value of "margin-left" */
@@ -4112,11 +4199,11 @@
 
   /** Gets the value of "margin-start" */
   String get marginStart =>
-    getPropertyValue('${_browserPrefix}margin-start');
+    getPropertyValue('${Device.cssPrefix}margin-start');
 
   /** Sets the value of "margin-start" */
   void set marginStart(String value) {
-    setProperty('${_browserPrefix}margin-start', value, '');
+    setProperty('${Device.cssPrefix}margin-start', value, '');
   }
 
   /** Gets the value of "margin-top" */
@@ -4130,236 +4217,236 @@
 
   /** Gets the value of "margin-top-collapse" */
   String get marginTopCollapse =>
-    getPropertyValue('${_browserPrefix}margin-top-collapse');
+    getPropertyValue('${Device.cssPrefix}margin-top-collapse');
 
   /** Sets the value of "margin-top-collapse" */
   void set marginTopCollapse(String value) {
-    setProperty('${_browserPrefix}margin-top-collapse', value, '');
+    setProperty('${Device.cssPrefix}margin-top-collapse', value, '');
   }
 
   /** Gets the value of "marquee" */
   String get marquee =>
-    getPropertyValue('${_browserPrefix}marquee');
+    getPropertyValue('${Device.cssPrefix}marquee');
 
   /** Sets the value of "marquee" */
   void set marquee(String value) {
-    setProperty('${_browserPrefix}marquee', value, '');
+    setProperty('${Device.cssPrefix}marquee', value, '');
   }
 
   /** Gets the value of "marquee-direction" */
   String get marqueeDirection =>
-    getPropertyValue('${_browserPrefix}marquee-direction');
+    getPropertyValue('${Device.cssPrefix}marquee-direction');
 
   /** Sets the value of "marquee-direction" */
   void set marqueeDirection(String value) {
-    setProperty('${_browserPrefix}marquee-direction', value, '');
+    setProperty('${Device.cssPrefix}marquee-direction', value, '');
   }
 
   /** Gets the value of "marquee-increment" */
   String get marqueeIncrement =>
-    getPropertyValue('${_browserPrefix}marquee-increment');
+    getPropertyValue('${Device.cssPrefix}marquee-increment');
 
   /** Sets the value of "marquee-increment" */
   void set marqueeIncrement(String value) {
-    setProperty('${_browserPrefix}marquee-increment', value, '');
+    setProperty('${Device.cssPrefix}marquee-increment', value, '');
   }
 
   /** Gets the value of "marquee-repetition" */
   String get marqueeRepetition =>
-    getPropertyValue('${_browserPrefix}marquee-repetition');
+    getPropertyValue('${Device.cssPrefix}marquee-repetition');
 
   /** Sets the value of "marquee-repetition" */
   void set marqueeRepetition(String value) {
-    setProperty('${_browserPrefix}marquee-repetition', value, '');
+    setProperty('${Device.cssPrefix}marquee-repetition', value, '');
   }
 
   /** Gets the value of "marquee-speed" */
   String get marqueeSpeed =>
-    getPropertyValue('${_browserPrefix}marquee-speed');
+    getPropertyValue('${Device.cssPrefix}marquee-speed');
 
   /** Sets the value of "marquee-speed" */
   void set marqueeSpeed(String value) {
-    setProperty('${_browserPrefix}marquee-speed', value, '');
+    setProperty('${Device.cssPrefix}marquee-speed', value, '');
   }
 
   /** Gets the value of "marquee-style" */
   String get marqueeStyle =>
-    getPropertyValue('${_browserPrefix}marquee-style');
+    getPropertyValue('${Device.cssPrefix}marquee-style');
 
   /** Sets the value of "marquee-style" */
   void set marqueeStyle(String value) {
-    setProperty('${_browserPrefix}marquee-style', value, '');
+    setProperty('${Device.cssPrefix}marquee-style', value, '');
   }
 
   /** Gets the value of "mask" */
   String get mask =>
-    getPropertyValue('${_browserPrefix}mask');
+    getPropertyValue('${Device.cssPrefix}mask');
 
   /** Sets the value of "mask" */
   void set mask(String value) {
-    setProperty('${_browserPrefix}mask', value, '');
+    setProperty('${Device.cssPrefix}mask', value, '');
   }
 
   /** Gets the value of "mask-attachment" */
   String get maskAttachment =>
-    getPropertyValue('${_browserPrefix}mask-attachment');
+    getPropertyValue('${Device.cssPrefix}mask-attachment');
 
   /** Sets the value of "mask-attachment" */
   void set maskAttachment(String value) {
-    setProperty('${_browserPrefix}mask-attachment', value, '');
+    setProperty('${Device.cssPrefix}mask-attachment', value, '');
   }
 
   /** Gets the value of "mask-box-image" */
   String get maskBoxImage =>
-    getPropertyValue('${_browserPrefix}mask-box-image');
+    getPropertyValue('${Device.cssPrefix}mask-box-image');
 
   /** Sets the value of "mask-box-image" */
   void set maskBoxImage(String value) {
-    setProperty('${_browserPrefix}mask-box-image', value, '');
+    setProperty('${Device.cssPrefix}mask-box-image', value, '');
   }
 
   /** Gets the value of "mask-box-image-outset" */
   String get maskBoxImageOutset =>
-    getPropertyValue('${_browserPrefix}mask-box-image-outset');
+    getPropertyValue('${Device.cssPrefix}mask-box-image-outset');
 
   /** Sets the value of "mask-box-image-outset" */
   void set maskBoxImageOutset(String value) {
-    setProperty('${_browserPrefix}mask-box-image-outset', value, '');
+    setProperty('${Device.cssPrefix}mask-box-image-outset', value, '');
   }
 
   /** Gets the value of "mask-box-image-repeat" */
   String get maskBoxImageRepeat =>
-    getPropertyValue('${_browserPrefix}mask-box-image-repeat');
+    getPropertyValue('${Device.cssPrefix}mask-box-image-repeat');
 
   /** Sets the value of "mask-box-image-repeat" */
   void set maskBoxImageRepeat(String value) {
-    setProperty('${_browserPrefix}mask-box-image-repeat', value, '');
+    setProperty('${Device.cssPrefix}mask-box-image-repeat', value, '');
   }
 
   /** Gets the value of "mask-box-image-slice" */
   String get maskBoxImageSlice =>
-    getPropertyValue('${_browserPrefix}mask-box-image-slice');
+    getPropertyValue('${Device.cssPrefix}mask-box-image-slice');
 
   /** Sets the value of "mask-box-image-slice" */
   void set maskBoxImageSlice(String value) {
-    setProperty('${_browserPrefix}mask-box-image-slice', value, '');
+    setProperty('${Device.cssPrefix}mask-box-image-slice', value, '');
   }
 
   /** Gets the value of "mask-box-image-source" */
   String get maskBoxImageSource =>
-    getPropertyValue('${_browserPrefix}mask-box-image-source');
+    getPropertyValue('${Device.cssPrefix}mask-box-image-source');
 
   /** Sets the value of "mask-box-image-source" */
   void set maskBoxImageSource(String value) {
-    setProperty('${_browserPrefix}mask-box-image-source', value, '');
+    setProperty('${Device.cssPrefix}mask-box-image-source', value, '');
   }
 
   /** Gets the value of "mask-box-image-width" */
   String get maskBoxImageWidth =>
-    getPropertyValue('${_browserPrefix}mask-box-image-width');
+    getPropertyValue('${Device.cssPrefix}mask-box-image-width');
 
   /** Sets the value of "mask-box-image-width" */
   void set maskBoxImageWidth(String value) {
-    setProperty('${_browserPrefix}mask-box-image-width', value, '');
+    setProperty('${Device.cssPrefix}mask-box-image-width', value, '');
   }
 
   /** Gets the value of "mask-clip" */
   String get maskClip =>
-    getPropertyValue('${_browserPrefix}mask-clip');
+    getPropertyValue('${Device.cssPrefix}mask-clip');
 
   /** Sets the value of "mask-clip" */
   void set maskClip(String value) {
-    setProperty('${_browserPrefix}mask-clip', value, '');
+    setProperty('${Device.cssPrefix}mask-clip', value, '');
   }
 
   /** Gets the value of "mask-composite" */
   String get maskComposite =>
-    getPropertyValue('${_browserPrefix}mask-composite');
+    getPropertyValue('${Device.cssPrefix}mask-composite');
 
   /** Sets the value of "mask-composite" */
   void set maskComposite(String value) {
-    setProperty('${_browserPrefix}mask-composite', value, '');
+    setProperty('${Device.cssPrefix}mask-composite', value, '');
   }
 
   /** Gets the value of "mask-image" */
   String get maskImage =>
-    getPropertyValue('${_browserPrefix}mask-image');
+    getPropertyValue('${Device.cssPrefix}mask-image');
 
   /** Sets the value of "mask-image" */
   void set maskImage(String value) {
-    setProperty('${_browserPrefix}mask-image', value, '');
+    setProperty('${Device.cssPrefix}mask-image', value, '');
   }
 
   /** Gets the value of "mask-origin" */
   String get maskOrigin =>
-    getPropertyValue('${_browserPrefix}mask-origin');
+    getPropertyValue('${Device.cssPrefix}mask-origin');
 
   /** Sets the value of "mask-origin" */
   void set maskOrigin(String value) {
-    setProperty('${_browserPrefix}mask-origin', value, '');
+    setProperty('${Device.cssPrefix}mask-origin', value, '');
   }
 
   /** Gets the value of "mask-position" */
   String get maskPosition =>
-    getPropertyValue('${_browserPrefix}mask-position');
+    getPropertyValue('${Device.cssPrefix}mask-position');
 
   /** Sets the value of "mask-position" */
   void set maskPosition(String value) {
-    setProperty('${_browserPrefix}mask-position', value, '');
+    setProperty('${Device.cssPrefix}mask-position', value, '');
   }
 
   /** Gets the value of "mask-position-x" */
   String get maskPositionX =>
-    getPropertyValue('${_browserPrefix}mask-position-x');
+    getPropertyValue('${Device.cssPrefix}mask-position-x');
 
   /** Sets the value of "mask-position-x" */
   void set maskPositionX(String value) {
-    setProperty('${_browserPrefix}mask-position-x', value, '');
+    setProperty('${Device.cssPrefix}mask-position-x', value, '');
   }
 
   /** Gets the value of "mask-position-y" */
   String get maskPositionY =>
-    getPropertyValue('${_browserPrefix}mask-position-y');
+    getPropertyValue('${Device.cssPrefix}mask-position-y');
 
   /** Sets the value of "mask-position-y" */
   void set maskPositionY(String value) {
-    setProperty('${_browserPrefix}mask-position-y', value, '');
+    setProperty('${Device.cssPrefix}mask-position-y', value, '');
   }
 
   /** Gets the value of "mask-repeat" */
   String get maskRepeat =>
-    getPropertyValue('${_browserPrefix}mask-repeat');
+    getPropertyValue('${Device.cssPrefix}mask-repeat');
 
   /** Sets the value of "mask-repeat" */
   void set maskRepeat(String value) {
-    setProperty('${_browserPrefix}mask-repeat', value, '');
+    setProperty('${Device.cssPrefix}mask-repeat', value, '');
   }
 
   /** Gets the value of "mask-repeat-x" */
   String get maskRepeatX =>
-    getPropertyValue('${_browserPrefix}mask-repeat-x');
+    getPropertyValue('${Device.cssPrefix}mask-repeat-x');
 
   /** Sets the value of "mask-repeat-x" */
   void set maskRepeatX(String value) {
-    setProperty('${_browserPrefix}mask-repeat-x', value, '');
+    setProperty('${Device.cssPrefix}mask-repeat-x', value, '');
   }
 
   /** Gets the value of "mask-repeat-y" */
   String get maskRepeatY =>
-    getPropertyValue('${_browserPrefix}mask-repeat-y');
+    getPropertyValue('${Device.cssPrefix}mask-repeat-y');
 
   /** Sets the value of "mask-repeat-y" */
   void set maskRepeatY(String value) {
-    setProperty('${_browserPrefix}mask-repeat-y', value, '');
+    setProperty('${Device.cssPrefix}mask-repeat-y', value, '');
   }
 
   /** Gets the value of "mask-size" */
   String get maskSize =>
-    getPropertyValue('${_browserPrefix}mask-size');
+    getPropertyValue('${Device.cssPrefix}mask-size');
 
   /** Sets the value of "mask-size" */
   void set maskSize(String value) {
-    setProperty('${_browserPrefix}mask-size', value, '');
+    setProperty('${Device.cssPrefix}mask-size', value, '');
   }
 
   /** Gets the value of "max-height" */
@@ -4373,20 +4460,20 @@
 
   /** Gets the value of "max-logical-height" */
   String get maxLogicalHeight =>
-    getPropertyValue('${_browserPrefix}max-logical-height');
+    getPropertyValue('${Device.cssPrefix}max-logical-height');
 
   /** Sets the value of "max-logical-height" */
   void set maxLogicalHeight(String value) {
-    setProperty('${_browserPrefix}max-logical-height', value, '');
+    setProperty('${Device.cssPrefix}max-logical-height', value, '');
   }
 
   /** Gets the value of "max-logical-width" */
   String get maxLogicalWidth =>
-    getPropertyValue('${_browserPrefix}max-logical-width');
+    getPropertyValue('${Device.cssPrefix}max-logical-width');
 
   /** Sets the value of "max-logical-width" */
   void set maxLogicalWidth(String value) {
-    setProperty('${_browserPrefix}max-logical-width', value, '');
+    setProperty('${Device.cssPrefix}max-logical-width', value, '');
   }
 
   /** Gets the value of "max-width" */
@@ -4418,20 +4505,20 @@
 
   /** Gets the value of "min-logical-height" */
   String get minLogicalHeight =>
-    getPropertyValue('${_browserPrefix}min-logical-height');
+    getPropertyValue('${Device.cssPrefix}min-logical-height');
 
   /** Sets the value of "min-logical-height" */
   void set minLogicalHeight(String value) {
-    setProperty('${_browserPrefix}min-logical-height', value, '');
+    setProperty('${Device.cssPrefix}min-logical-height', value, '');
   }
 
   /** Gets the value of "min-logical-width" */
   String get minLogicalWidth =>
-    getPropertyValue('${_browserPrefix}min-logical-width');
+    getPropertyValue('${Device.cssPrefix}min-logical-width');
 
   /** Sets the value of "min-logical-width" */
   void set minLogicalWidth(String value) {
-    setProperty('${_browserPrefix}min-logical-width', value, '');
+    setProperty('${Device.cssPrefix}min-logical-width', value, '');
   }
 
   /** Gets the value of "min-width" */
@@ -4454,11 +4541,11 @@
 
   /** Gets the value of "nbsp-mode" */
   String get nbspMode =>
-    getPropertyValue('${_browserPrefix}nbsp-mode');
+    getPropertyValue('${Device.cssPrefix}nbsp-mode');
 
   /** Sets the value of "nbsp-mode" */
   void set nbspMode(String value) {
-    setProperty('${_browserPrefix}nbsp-mode', value, '');
+    setProperty('${Device.cssPrefix}nbsp-mode', value, '');
   }
 
   /** Gets the value of "opacity" */
@@ -4472,11 +4559,11 @@
 
   /** Gets the value of "order" */
   String get order =>
-    getPropertyValue('${_browserPrefix}order');
+    getPropertyValue('${Device.cssPrefix}order');
 
   /** Sets the value of "order" */
   void set order(String value) {
-    setProperty('${_browserPrefix}order', value, '');
+    setProperty('${Device.cssPrefix}order', value, '');
   }
 
   /** Gets the value of "orientation" */
@@ -4553,11 +4640,11 @@
 
   /** Gets the value of "overflow-scrolling" */
   String get overflowScrolling =>
-    getPropertyValue('${_browserPrefix}overflow-scrolling');
+    getPropertyValue('${Device.cssPrefix}overflow-scrolling');
 
   /** Sets the value of "overflow-scrolling" */
   void set overflowScrolling(String value) {
-    setProperty('${_browserPrefix}overflow-scrolling', value, '');
+    setProperty('${Device.cssPrefix}overflow-scrolling', value, '');
   }
 
   /** Gets the value of "overflow-wrap" */
@@ -4598,20 +4685,20 @@
 
   /** Gets the value of "padding-after" */
   String get paddingAfter =>
-    getPropertyValue('${_browserPrefix}padding-after');
+    getPropertyValue('${Device.cssPrefix}padding-after');
 
   /** Sets the value of "padding-after" */
   void set paddingAfter(String value) {
-    setProperty('${_browserPrefix}padding-after', value, '');
+    setProperty('${Device.cssPrefix}padding-after', value, '');
   }
 
   /** Gets the value of "padding-before" */
   String get paddingBefore =>
-    getPropertyValue('${_browserPrefix}padding-before');
+    getPropertyValue('${Device.cssPrefix}padding-before');
 
   /** Sets the value of "padding-before" */
   void set paddingBefore(String value) {
-    setProperty('${_browserPrefix}padding-before', value, '');
+    setProperty('${Device.cssPrefix}padding-before', value, '');
   }
 
   /** Gets the value of "padding-bottom" */
@@ -4625,11 +4712,11 @@
 
   /** Gets the value of "padding-end" */
   String get paddingEnd =>
-    getPropertyValue('${_browserPrefix}padding-end');
+    getPropertyValue('${Device.cssPrefix}padding-end');
 
   /** Sets the value of "padding-end" */
   void set paddingEnd(String value) {
-    setProperty('${_browserPrefix}padding-end', value, '');
+    setProperty('${Device.cssPrefix}padding-end', value, '');
   }
 
   /** Gets the value of "padding-left" */
@@ -4652,11 +4739,11 @@
 
   /** Gets the value of "padding-start" */
   String get paddingStart =>
-    getPropertyValue('${_browserPrefix}padding-start');
+    getPropertyValue('${Device.cssPrefix}padding-start');
 
   /** Sets the value of "padding-start" */
   void set paddingStart(String value) {
-    setProperty('${_browserPrefix}padding-start', value, '');
+    setProperty('${Device.cssPrefix}padding-start', value, '');
   }
 
   /** Gets the value of "padding-top" */
@@ -4706,38 +4793,38 @@
 
   /** Gets the value of "perspective" */
   String get perspective =>
-    getPropertyValue('${_browserPrefix}perspective');
+    getPropertyValue('${Device.cssPrefix}perspective');
 
   /** Sets the value of "perspective" */
   void set perspective(String value) {
-    setProperty('${_browserPrefix}perspective', value, '');
+    setProperty('${Device.cssPrefix}perspective', value, '');
   }
 
   /** Gets the value of "perspective-origin" */
   String get perspectiveOrigin =>
-    getPropertyValue('${_browserPrefix}perspective-origin');
+    getPropertyValue('${Device.cssPrefix}perspective-origin');
 
   /** Sets the value of "perspective-origin" */
   void set perspectiveOrigin(String value) {
-    setProperty('${_browserPrefix}perspective-origin', value, '');
+    setProperty('${Device.cssPrefix}perspective-origin', value, '');
   }
 
   /** Gets the value of "perspective-origin-x" */
   String get perspectiveOriginX =>
-    getPropertyValue('${_browserPrefix}perspective-origin-x');
+    getPropertyValue('${Device.cssPrefix}perspective-origin-x');
 
   /** Sets the value of "perspective-origin-x" */
   void set perspectiveOriginX(String value) {
-    setProperty('${_browserPrefix}perspective-origin-x', value, '');
+    setProperty('${Device.cssPrefix}perspective-origin-x', value, '');
   }
 
   /** Gets the value of "perspective-origin-y" */
   String get perspectiveOriginY =>
-    getPropertyValue('${_browserPrefix}perspective-origin-y');
+    getPropertyValue('${Device.cssPrefix}perspective-origin-y');
 
   /** Sets the value of "perspective-origin-y" */
   void set perspectiveOriginY(String value) {
-    setProperty('${_browserPrefix}perspective-origin-y', value, '');
+    setProperty('${Device.cssPrefix}perspective-origin-y', value, '');
   }
 
   /** Gets the value of "pointer-events" */
@@ -4760,11 +4847,11 @@
 
   /** Gets the value of "print-color-adjust" */
   String get printColorAdjust =>
-    getPropertyValue('${_browserPrefix}print-color-adjust');
+    getPropertyValue('${Device.cssPrefix}print-color-adjust');
 
   /** Sets the value of "print-color-adjust" */
   void set printColorAdjust(String value) {
-    setProperty('${_browserPrefix}print-color-adjust', value, '');
+    setProperty('${Device.cssPrefix}print-color-adjust', value, '');
   }
 
   /** Gets the value of "quotes" */
@@ -4778,38 +4865,38 @@
 
   /** Gets the value of "region-break-after" */
   String get regionBreakAfter =>
-    getPropertyValue('${_browserPrefix}region-break-after');
+    getPropertyValue('${Device.cssPrefix}region-break-after');
 
   /** Sets the value of "region-break-after" */
   void set regionBreakAfter(String value) {
-    setProperty('${_browserPrefix}region-break-after', value, '');
+    setProperty('${Device.cssPrefix}region-break-after', value, '');
   }
 
   /** Gets the value of "region-break-before" */
   String get regionBreakBefore =>
-    getPropertyValue('${_browserPrefix}region-break-before');
+    getPropertyValue('${Device.cssPrefix}region-break-before');
 
   /** Sets the value of "region-break-before" */
   void set regionBreakBefore(String value) {
-    setProperty('${_browserPrefix}region-break-before', value, '');
+    setProperty('${Device.cssPrefix}region-break-before', value, '');
   }
 
   /** Gets the value of "region-break-inside" */
   String get regionBreakInside =>
-    getPropertyValue('${_browserPrefix}region-break-inside');
+    getPropertyValue('${Device.cssPrefix}region-break-inside');
 
   /** Sets the value of "region-break-inside" */
   void set regionBreakInside(String value) {
-    setProperty('${_browserPrefix}region-break-inside', value, '');
+    setProperty('${Device.cssPrefix}region-break-inside', value, '');
   }
 
   /** Gets the value of "region-overflow" */
   String get regionOverflow =>
-    getPropertyValue('${_browserPrefix}region-overflow');
+    getPropertyValue('${Device.cssPrefix}region-overflow');
 
   /** Sets the value of "region-overflow" */
   void set regionOverflow(String value) {
-    setProperty('${_browserPrefix}region-overflow', value, '');
+    setProperty('${Device.cssPrefix}region-overflow', value, '');
   }
 
   /** Gets the value of "resize" */
@@ -4832,47 +4919,47 @@
 
   /** Gets the value of "rtl-ordering" */
   String get rtlOrdering =>
-    getPropertyValue('${_browserPrefix}rtl-ordering');
+    getPropertyValue('${Device.cssPrefix}rtl-ordering');
 
   /** Sets the value of "rtl-ordering" */
   void set rtlOrdering(String value) {
-    setProperty('${_browserPrefix}rtl-ordering', value, '');
+    setProperty('${Device.cssPrefix}rtl-ordering', value, '');
   }
 
   /** Gets the value of "shape-inside" */
   String get shapeInside =>
-    getPropertyValue('${_browserPrefix}shape-inside');
+    getPropertyValue('${Device.cssPrefix}shape-inside');
 
   /** Sets the value of "shape-inside" */
   void set shapeInside(String value) {
-    setProperty('${_browserPrefix}shape-inside', value, '');
+    setProperty('${Device.cssPrefix}shape-inside', value, '');
   }
 
   /** Gets the value of "shape-margin" */
   String get shapeMargin =>
-    getPropertyValue('${_browserPrefix}shape-margin');
+    getPropertyValue('${Device.cssPrefix}shape-margin');
 
   /** Sets the value of "shape-margin" */
   void set shapeMargin(String value) {
-    setProperty('${_browserPrefix}shape-margin', value, '');
+    setProperty('${Device.cssPrefix}shape-margin', value, '');
   }
 
   /** Gets the value of "shape-outside" */
   String get shapeOutside =>
-    getPropertyValue('${_browserPrefix}shape-outside');
+    getPropertyValue('${Device.cssPrefix}shape-outside');
 
   /** Sets the value of "shape-outside" */
   void set shapeOutside(String value) {
-    setProperty('${_browserPrefix}shape-outside', value, '');
+    setProperty('${Device.cssPrefix}shape-outside', value, '');
   }
 
   /** Gets the value of "shape-padding" */
   String get shapePadding =>
-    getPropertyValue('${_browserPrefix}shape-padding');
+    getPropertyValue('${Device.cssPrefix}shape-padding');
 
   /** Sets the value of "shape-padding" */
   void set shapePadding(String value) {
-    setProperty('${_browserPrefix}shape-padding', value, '');
+    setProperty('${Device.cssPrefix}shape-padding', value, '');
   }
 
   /** Gets the value of "size" */
@@ -4922,11 +5009,11 @@
 
   /** Gets the value of "tap-highlight-color" */
   String get tapHighlightColor =>
-    getPropertyValue('${_browserPrefix}tap-highlight-color');
+    getPropertyValue('${Device.cssPrefix}tap-highlight-color');
 
   /** Sets the value of "tap-highlight-color" */
   void set tapHighlightColor(String value) {
-    setProperty('${_browserPrefix}tap-highlight-color', value, '');
+    setProperty('${Device.cssPrefix}tap-highlight-color', value, '');
   }
 
   /** Gets the value of "text-align" */
@@ -4940,20 +5027,20 @@
 
   /** Gets the value of "text-align-last" */
   String get textAlignLast =>
-    getPropertyValue('${_browserPrefix}text-align-last');
+    getPropertyValue('${Device.cssPrefix}text-align-last');
 
   /** Sets the value of "text-align-last" */
   void set textAlignLast(String value) {
-    setProperty('${_browserPrefix}text-align-last', value, '');
+    setProperty('${Device.cssPrefix}text-align-last', value, '');
   }
 
   /** Gets the value of "text-combine" */
   String get textCombine =>
-    getPropertyValue('${_browserPrefix}text-combine');
+    getPropertyValue('${Device.cssPrefix}text-combine');
 
   /** Sets the value of "text-combine" */
   void set textCombine(String value) {
-    setProperty('${_browserPrefix}text-combine', value, '');
+    setProperty('${Device.cssPrefix}text-combine', value, '');
   }
 
   /** Gets the value of "text-decoration" */
@@ -4967,74 +5054,74 @@
 
   /** Gets the value of "text-decoration-line" */
   String get textDecorationLine =>
-    getPropertyValue('${_browserPrefix}text-decoration-line');
+    getPropertyValue('${Device.cssPrefix}text-decoration-line');
 
   /** Sets the value of "text-decoration-line" */
   void set textDecorationLine(String value) {
-    setProperty('${_browserPrefix}text-decoration-line', value, '');
+    setProperty('${Device.cssPrefix}text-decoration-line', value, '');
   }
 
   /** Gets the value of "text-decoration-style" */
   String get textDecorationStyle =>
-    getPropertyValue('${_browserPrefix}text-decoration-style');
+    getPropertyValue('${Device.cssPrefix}text-decoration-style');
 
   /** Sets the value of "text-decoration-style" */
   void set textDecorationStyle(String value) {
-    setProperty('${_browserPrefix}text-decoration-style', value, '');
+    setProperty('${Device.cssPrefix}text-decoration-style', value, '');
   }
 
   /** Gets the value of "text-decorations-in-effect" */
   String get textDecorationsInEffect =>
-    getPropertyValue('${_browserPrefix}text-decorations-in-effect');
+    getPropertyValue('${Device.cssPrefix}text-decorations-in-effect');
 
   /** Sets the value of "text-decorations-in-effect" */
   void set textDecorationsInEffect(String value) {
-    setProperty('${_browserPrefix}text-decorations-in-effect', value, '');
+    setProperty('${Device.cssPrefix}text-decorations-in-effect', value, '');
   }
 
   /** Gets the value of "text-emphasis" */
   String get textEmphasis =>
-    getPropertyValue('${_browserPrefix}text-emphasis');
+    getPropertyValue('${Device.cssPrefix}text-emphasis');
 
   /** Sets the value of "text-emphasis" */
   void set textEmphasis(String value) {
-    setProperty('${_browserPrefix}text-emphasis', value, '');
+    setProperty('${Device.cssPrefix}text-emphasis', value, '');
   }
 
   /** Gets the value of "text-emphasis-color" */
   String get textEmphasisColor =>
-    getPropertyValue('${_browserPrefix}text-emphasis-color');
+    getPropertyValue('${Device.cssPrefix}text-emphasis-color');
 
   /** Sets the value of "text-emphasis-color" */
   void set textEmphasisColor(String value) {
-    setProperty('${_browserPrefix}text-emphasis-color', value, '');
+    setProperty('${Device.cssPrefix}text-emphasis-color', value, '');
   }
 
   /** Gets the value of "text-emphasis-position" */
   String get textEmphasisPosition =>
-    getPropertyValue('${_browserPrefix}text-emphasis-position');
+    getPropertyValue('${Device.cssPrefix}text-emphasis-position');
 
   /** Sets the value of "text-emphasis-position" */
   void set textEmphasisPosition(String value) {
-    setProperty('${_browserPrefix}text-emphasis-position', value, '');
+    setProperty('${Device.cssPrefix}text-emphasis-position', value, '');
   }
 
   /** Gets the value of "text-emphasis-style" */
   String get textEmphasisStyle =>
-    getPropertyValue('${_browserPrefix}text-emphasis-style');
+    getPropertyValue('${Device.cssPrefix}text-emphasis-style');
 
   /** Sets the value of "text-emphasis-style" */
   void set textEmphasisStyle(String value) {
-    setProperty('${_browserPrefix}text-emphasis-style', value, '');
+    setProperty('${Device.cssPrefix}text-emphasis-style', value, '');
   }
 
   /** Gets the value of "text-fill-color" */
   String get textFillColor =>
-    getPropertyValue('${_browserPrefix}text-fill-color');
+    getPropertyValue('${Device.cssPrefix}text-fill-color');
 
   /** Sets the value of "text-fill-color" */
   void set textFillColor(String value) {
-    setProperty('${_browserPrefix}text-fill-color', value, '');
+    setProperty('${Device.cssPrefix}text-fill-color', value, '');
   }
 
   /** Gets the value of "text-indent" */
@@ -5093,11 +5180,11 @@
 
   /** Gets the value of "text-orientation" */
   String get textOrientation =>
-    getPropertyValue('${_browserPrefix}text-orientation');
+    getPropertyValue('${Device.cssPrefix}text-orientation');
 
   /** Sets the value of "text-orientation" */
   void set textOrientation(String value) {
-    setProperty('${_browserPrefix}text-orientation', value, '');
+    setProperty('${Device.cssPrefix}text-orientation', value, '');
   }
 
   /** Gets the value of "text-overflow" */
@@ -5165,11 +5252,11 @@
 
   /** Gets the value of "text-security" */
   String get textSecurity =>
-    getPropertyValue('${_browserPrefix}text-security');
+    getPropertyValue('${Device.cssPrefix}text-security');
 
   /** Sets the value of "text-security" */
   void set textSecurity(String value) {
-    setProperty('${_browserPrefix}text-security', value, '');
+    setProperty('${Device.cssPrefix}text-security', value, '');
   }
 
   /** Gets the value of "text-shadow" */
@@ -5183,38 +5270,38 @@
 
   /** Gets the value of "text-size-adjust" */
   String get textSizeAdjust =>
-    getPropertyValue('${_browserPrefix}text-size-adjust');
+    getPropertyValue('${Device.cssPrefix}text-size-adjust');
 
   /** Sets the value of "text-size-adjust" */
   void set textSizeAdjust(String value) {
-    setProperty('${_browserPrefix}text-size-adjust', value, '');
+    setProperty('${Device.cssPrefix}text-size-adjust', value, '');
   }
 
   /** Gets the value of "text-stroke" */
   String get textStroke =>
-    getPropertyValue('${_browserPrefix}text-stroke');
+    getPropertyValue('${Device.cssPrefix}text-stroke');
 
   /** Sets the value of "text-stroke" */
   void set textStroke(String value) {
-    setProperty('${_browserPrefix}text-stroke', value, '');
+    setProperty('${Device.cssPrefix}text-stroke', value, '');
   }
 
   /** Gets the value of "text-stroke-color" */
   String get textStrokeColor =>
-    getPropertyValue('${_browserPrefix}text-stroke-color');
+    getPropertyValue('${Device.cssPrefix}text-stroke-color');
 
   /** Sets the value of "text-stroke-color" */
   void set textStrokeColor(String value) {
-    setProperty('${_browserPrefix}text-stroke-color', value, '');
+    setProperty('${Device.cssPrefix}text-stroke-color', value, '');
   }
 
   /** Gets the value of "text-stroke-width" */
   String get textStrokeWidth =>
-    getPropertyValue('${_browserPrefix}text-stroke-width');
+    getPropertyValue('${Device.cssPrefix}text-stroke-width');
 
   /** Sets the value of "text-stroke-width" */
   void set textStrokeWidth(String value) {
-    setProperty('${_browserPrefix}text-stroke-width', value, '');
+    setProperty('${Device.cssPrefix}text-stroke-width', value, '');
   }
 
   /** Gets the value of "text-transform" */
@@ -5282,56 +5369,56 @@
 
   /** Gets the value of "transform" */
   String get transform =>
-    getPropertyValue('${_browserPrefix}transform');
+    getPropertyValue('${Device.cssPrefix}transform');
 
   /** Sets the value of "transform" */
   void set transform(String value) {
-    setProperty('${_browserPrefix}transform', value, '');
+    setProperty('${Device.cssPrefix}transform', value, '');
   }
 
   /** Gets the value of "transform-origin" */
   String get transformOrigin =>
-    getPropertyValue('${_browserPrefix}transform-origin');
+    getPropertyValue('${Device.cssPrefix}transform-origin');
 
   /** Sets the value of "transform-origin" */
   void set transformOrigin(String value) {
-    setProperty('${_browserPrefix}transform-origin', value, '');
+    setProperty('${Device.cssPrefix}transform-origin', value, '');
   }
 
   /** Gets the value of "transform-origin-x" */
   String get transformOriginX =>
-    getPropertyValue('${_browserPrefix}transform-origin-x');
+    getPropertyValue('${Device.cssPrefix}transform-origin-x');
 
   /** Sets the value of "transform-origin-x" */
   void set transformOriginX(String value) {
-    setProperty('${_browserPrefix}transform-origin-x', value, '');
+    setProperty('${Device.cssPrefix}transform-origin-x', value, '');
   }
 
   /** Gets the value of "transform-origin-y" */
   String get transformOriginY =>
-    getPropertyValue('${_browserPrefix}transform-origin-y');
+    getPropertyValue('${Device.cssPrefix}transform-origin-y');
 
   /** Sets the value of "transform-origin-y" */
   void set transformOriginY(String value) {
-    setProperty('${_browserPrefix}transform-origin-y', value, '');
+    setProperty('${Device.cssPrefix}transform-origin-y', value, '');
   }
 
   /** Gets the value of "transform-origin-z" */
   String get transformOriginZ =>
-    getPropertyValue('${_browserPrefix}transform-origin-z');
+    getPropertyValue('${Device.cssPrefix}transform-origin-z');
 
   /** Sets the value of "transform-origin-z" */
   void set transformOriginZ(String value) {
-    setProperty('${_browserPrefix}transform-origin-z', value, '');
+    setProperty('${Device.cssPrefix}transform-origin-z', value, '');
   }
 
   /** Gets the value of "transform-style" */
   String get transformStyle =>
-    getPropertyValue('${_browserPrefix}transform-style');
+    getPropertyValue('${Device.cssPrefix}transform-style');
 
   /** Sets the value of "transform-style" */
   void set transformStyle(String value) {
-    setProperty('${_browserPrefix}transform-style', value, '');
+    setProperty('${Device.cssPrefix}transform-style', value, '');
   }
 
   /** Gets the value of "transition" */
@@ -5340,7 +5427,7 @@
   @SupportedBrowser(SupportedBrowser.IE, '10')
   @SupportedBrowser(SupportedBrowser.SAFARI)
   String get transition =>
-    getPropertyValue('${_browserPrefix}transition');
+    getPropertyValue('${Device.cssPrefix}transition');
 
   /** Sets the value of "transition" */
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -5348,43 +5435,43 @@
   @SupportedBrowser(SupportedBrowser.IE, '10')
   @SupportedBrowser(SupportedBrowser.SAFARI)
   void set transition(String value) {
-    setProperty('${_browserPrefix}transition', value, '');
+    setProperty('${Device.cssPrefix}transition', value, '');
   }
 
   /** Gets the value of "transition-delay" */
   String get transitionDelay =>
-    getPropertyValue('${_browserPrefix}transition-delay');
+    getPropertyValue('${Device.cssPrefix}transition-delay');
 
   /** Sets the value of "transition-delay" */
   void set transitionDelay(String value) {
-    setProperty('${_browserPrefix}transition-delay', value, '');
+    setProperty('${Device.cssPrefix}transition-delay', value, '');
   }
 
   /** Gets the value of "transition-duration" */
   String get transitionDuration =>
-    getPropertyValue('${_browserPrefix}transition-duration');
+    getPropertyValue('${Device.cssPrefix}transition-duration');
 
   /** Sets the value of "transition-duration" */
   void set transitionDuration(String value) {
-    setProperty('${_browserPrefix}transition-duration', value, '');
+    setProperty('${Device.cssPrefix}transition-duration', value, '');
   }
 
   /** Gets the value of "transition-property" */
   String get transitionProperty =>
-    getPropertyValue('${_browserPrefix}transition-property');
+    getPropertyValue('${Device.cssPrefix}transition-property');
 
   /** Sets the value of "transition-property" */
   void set transitionProperty(String value) {
-    setProperty('${_browserPrefix}transition-property', value, '');
+    setProperty('${Device.cssPrefix}transition-property', value, '');
   }
 
   /** Gets the value of "transition-timing-function" */
   String get transitionTimingFunction =>
-    getPropertyValue('${_browserPrefix}transition-timing-function');
+    getPropertyValue('${Device.cssPrefix}transition-timing-function');
 
   /** Sets the value of "transition-timing-function" */
   void set transitionTimingFunction(String value) {
-    setProperty('${_browserPrefix}transition-timing-function', value, '');
+    setProperty('${Device.cssPrefix}transition-timing-function', value, '');
   }
 
   /** Gets the value of "unicode-bidi" */
@@ -5407,29 +5494,29 @@
 
   /** Gets the value of "user-drag" */
   String get userDrag =>
-    getPropertyValue('${_browserPrefix}user-drag');
+    getPropertyValue('${Device.cssPrefix}user-drag');
 
   /** Sets the value of "user-drag" */
   void set userDrag(String value) {
-    setProperty('${_browserPrefix}user-drag', value, '');
+    setProperty('${Device.cssPrefix}user-drag', value, '');
   }
 
   /** Gets the value of "user-modify" */
   String get userModify =>
-    getPropertyValue('${_browserPrefix}user-modify');
+    getPropertyValue('${Device.cssPrefix}user-modify');
 
   /** Sets the value of "user-modify" */
   void set userModify(String value) {
-    setProperty('${_browserPrefix}user-modify', value, '');
+    setProperty('${Device.cssPrefix}user-modify', value, '');
   }
 
   /** Gets the value of "user-select" */
   String get userSelect =>
-    getPropertyValue('${_browserPrefix}user-select');
+    getPropertyValue('${Device.cssPrefix}user-select');
 
   /** Sets the value of "user-select" */
   void set userSelect(String value) {
-    setProperty('${_browserPrefix}user-select', value, '');
+    setProperty('${Device.cssPrefix}user-select', value, '');
   }
 
   /** Gets the value of "user-zoom" */
@@ -5515,38 +5602,38 @@
 
   /** Gets the value of "wrap" */
   String get wrap =>
-    getPropertyValue('${_browserPrefix}wrap');
+    getPropertyValue('${Device.cssPrefix}wrap');
 
   /** Sets the value of "wrap" */
   void set wrap(String value) {
-    setProperty('${_browserPrefix}wrap', value, '');
+    setProperty('${Device.cssPrefix}wrap', value, '');
   }
 
   /** Gets the value of "wrap-flow" */
   String get wrapFlow =>
-    getPropertyValue('${_browserPrefix}wrap-flow');
+    getPropertyValue('${Device.cssPrefix}wrap-flow');
 
   /** Sets the value of "wrap-flow" */
   void set wrapFlow(String value) {
-    setProperty('${_browserPrefix}wrap-flow', value, '');
+    setProperty('${Device.cssPrefix}wrap-flow', value, '');
   }
 
   /** Gets the value of "wrap-through" */
   String get wrapThrough =>
-    getPropertyValue('${_browserPrefix}wrap-through');
+    getPropertyValue('${Device.cssPrefix}wrap-through');
 
   /** Sets the value of "wrap-through" */
   void set wrapThrough(String value) {
-    setProperty('${_browserPrefix}wrap-through', value, '');
+    setProperty('${Device.cssPrefix}wrap-through', value, '');
   }
 
   /** Gets the value of "writing-mode" */
   String get writingMode =>
-    getPropertyValue('${_browserPrefix}writing-mode');
+    getPropertyValue('${Device.cssPrefix}writing-mode');
 
   /** Sets the value of "writing-mode" */
   void set writingMode(String value) {
-    setProperty('${_browserPrefix}writing-mode', value, '');
+    setProperty('${Device.cssPrefix}writing-mode', value, '');
   }
 
   /** Gets the value of "z-index" */
@@ -5847,9 +5934,20 @@
   @DocsEditable
   Blob getAsFile() native;
 
+  @JSName('getAsString')
   @DomName('DataTransferItem.getAsString')
   @DocsEditable
-  void getAsString([StringCallback callback]) native;
+  void _getAsString([_StringCallback callback]) native;
+
+  @JSName('getAsString')
+  @DomName('DataTransferItem.getAsString')
+  @DocsEditable
+  Future<String> getAsString() {
+    var completer = new Completer<String>();
+    _getAsString(
+        (value) { completer.complete(value); });
+    return completer.future;
+  }
 
   @JSName('webkitGetAsEntry')
   @DomName('DataTransferItem.webkitGetAsEntry')
@@ -5895,7 +5993,7 @@
 
   @DomName('DataView.DataView')
   @DocsEditable
-  factory DataView(ArrayBuffer buffer, [int byteOffset, int byteLength]) {
+  factory DataView(/*ArrayBuffer*/ buffer, [int byteOffset, int byteLength]) {
     if (?byteLength) {
       return DataView._create_1(buffer, byteOffset, byteLength);
     }
@@ -6101,83 +6199,117 @@
 
   @DomName('DirectoryEntry.getDirectory')
   @DocsEditable
-  void getDirectory(String path, {Map options, EntryCallback successCallback, ErrorCallback errorCallback}) {
+  void _getDirectory(String path, {Map options, _EntryCallback successCallback, _ErrorCallback errorCallback}) {
     if (?errorCallback) {
       var options_1 = convertDartToNative_Dictionary(options);
-      _getDirectory_1(path, options_1, successCallback, errorCallback);
+      __getDirectory_1(path, options_1, successCallback, errorCallback);
       return;
     }
     if (?successCallback) {
       var options_2 = convertDartToNative_Dictionary(options);
-      _getDirectory_2(path, options_2, successCallback);
+      __getDirectory_2(path, options_2, successCallback);
       return;
     }
     if (?options) {
       var options_3 = convertDartToNative_Dictionary(options);
-      _getDirectory_3(path, options_3);
+      __getDirectory_3(path, options_3);
       return;
     }
-    _getDirectory_4(path);
+    __getDirectory_4(path);
     return;
   }
   @JSName('getDirectory')
   @DomName('DirectoryEntry.getDirectory')
   @DocsEditable
-  void _getDirectory_1(path, options, EntryCallback successCallback, ErrorCallback errorCallback) native;
+  void __getDirectory_1(path, options, _EntryCallback successCallback, _ErrorCallback errorCallback) native;
   @JSName('getDirectory')
   @DomName('DirectoryEntry.getDirectory')
   @DocsEditable
-  void _getDirectory_2(path, options, EntryCallback successCallback) native;
+  void __getDirectory_2(path, options, _EntryCallback successCallback) native;
   @JSName('getDirectory')
   @DomName('DirectoryEntry.getDirectory')
   @DocsEditable
-  void _getDirectory_3(path, options) native;
+  void __getDirectory_3(path, options) native;
   @JSName('getDirectory')
   @DomName('DirectoryEntry.getDirectory')
   @DocsEditable
-  void _getDirectory_4(path) native;
+  void __getDirectory_4(path) native;
+
+  @JSName('getDirectory')
+  @DomName('DirectoryEntry.getDirectory')
+  @DocsEditable
+  Future<Entry> getDirectory(String path, {Map options}) {
+    var completer = new Completer<Entry>();
+    _getDirectory(path, options : options,
+        successCallback : (value) { completer.complete(value); },
+        errorCallback : (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
   @DomName('DirectoryEntry.getFile')
   @DocsEditable
-  void getFile(String path, {Map options, EntryCallback successCallback, ErrorCallback errorCallback}) {
+  void _getFile(String path, {Map options, _EntryCallback successCallback, _ErrorCallback errorCallback}) {
     if (?errorCallback) {
       var options_1 = convertDartToNative_Dictionary(options);
-      _getFile_1(path, options_1, successCallback, errorCallback);
+      __getFile_1(path, options_1, successCallback, errorCallback);
       return;
     }
     if (?successCallback) {
       var options_2 = convertDartToNative_Dictionary(options);
-      _getFile_2(path, options_2, successCallback);
+      __getFile_2(path, options_2, successCallback);
       return;
     }
     if (?options) {
       var options_3 = convertDartToNative_Dictionary(options);
-      _getFile_3(path, options_3);
+      __getFile_3(path, options_3);
       return;
     }
-    _getFile_4(path);
+    __getFile_4(path);
     return;
   }
   @JSName('getFile')
   @DomName('DirectoryEntry.getFile')
   @DocsEditable
-  void _getFile_1(path, options, EntryCallback successCallback, ErrorCallback errorCallback) native;
+  void __getFile_1(path, options, _EntryCallback successCallback, _ErrorCallback errorCallback) native;
   @JSName('getFile')
   @DomName('DirectoryEntry.getFile')
   @DocsEditable
-  void _getFile_2(path, options, EntryCallback successCallback) native;
+  void __getFile_2(path, options, _EntryCallback successCallback) native;
   @JSName('getFile')
   @DomName('DirectoryEntry.getFile')
   @DocsEditable
-  void _getFile_3(path, options) native;
+  void __getFile_3(path, options) native;
   @JSName('getFile')
   @DomName('DirectoryEntry.getFile')
   @DocsEditable
-  void _getFile_4(path) native;
+  void __getFile_4(path) native;
 
+  @JSName('getFile')
+  @DomName('DirectoryEntry.getFile')
+  @DocsEditable
+  Future<Entry> getFile(String path, {Map options}) {
+    var completer = new Completer<Entry>();
+    _getFile(path, options : options,
+        successCallback : (value) { completer.complete(value); },
+        errorCallback : (error) { completer.completeError(error); });
+    return completer.future;
+  }
+
+  @JSName('removeRecursively')
   @DomName('DirectoryEntry.removeRecursively')
   @DocsEditable
-  void removeRecursively(VoidCallback successCallback, [ErrorCallback errorCallback]) native;
+  void _removeRecursively(VoidCallback successCallback, [_ErrorCallback errorCallback]) native;
+
+  @JSName('removeRecursively')
+  @DomName('DirectoryEntry.removeRecursively')
+  @DocsEditable
+  Future removeRecursively() {
+    var completer = new Completer();
+    _removeRecursively(
+        () { completer.complete(); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -6227,9 +6359,21 @@
 @DomName('DirectoryReader')
 class DirectoryReader native "*DirectoryReader" {
 
+  @JSName('readEntries')
   @DomName('DirectoryReader.readEntries')
   @DocsEditable
-  void readEntries(EntriesCallback successCallback, [ErrorCallback errorCallback]) native;
+  void _readEntries(_EntriesCallback successCallback, [_ErrorCallback errorCallback]) native;
+
+  @JSName('readEntries')
+  @DomName('DirectoryReader.readEntries')
+  @DocsEditable
+  Future<List<Entry>> readEntries() {
+    var completer = new Completer<List<Entry>>();
+    _readEntries(
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -6527,32 +6671,27 @@
   @DocsEditable
   CanvasRenderingContext $dom_getCssCanvasContext(String contextId, String name, int width, int height) native;
 
-  @JSName('getElementById')
-  /// Deprecated: use query("#$elementId") instead.
   @DomName('Document.getElementById')
   @DocsEditable
-  Element $dom_getElementById(String elementId) native;
+  Element getElementById(String elementId) native;
 
-  @JSName('getElementsByClassName')
   @DomName('Document.getElementsByClassName')
   @DocsEditable
   @Returns('NodeList')
   @Creates('NodeList')
-  List<Node> $dom_getElementsByClassName(String tagname) native;
+  List<Node> getElementsByClassName(String tagname) native;
 
-  @JSName('getElementsByName')
   @DomName('Document.getElementsByName')
   @DocsEditable
   @Returns('NodeList')
   @Creates('NodeList')
-  List<Node> $dom_getElementsByName(String elementName) native;
+  List<Node> getElementsByName(String elementName) native;
 
-  @JSName('getElementsByTagName')
   @DomName('Document.getElementsByTagName')
   @DocsEditable
   @Returns('NodeList')
   @Creates('NodeList')
-  List<Node> $dom_getElementsByTagName(String tagname) native;
+  List<Node> getElementsByTagName(String tagname) native;
 
   @DomName('Document.queryCommandEnabled')
   @DocsEditable
@@ -6575,10 +6714,24 @@
   String queryCommandValue(String command) native;
 
   @JSName('querySelector')
-  /// Deprecated: renamed to the shorter name [query].
+  /**
+ * Finds the first descendant element of this document that matches the
+ * specified group of selectors.
+ *
+ * Unless your webpage contains multiple documents, the top-level query
+ * method behaves the same as this method, so you should use it instead to
+ * save typing a few characters.
+ *
+ * [selectors] should be a string using CSS selector syntax.
+ *     var element1 = document.query('.className');
+ *     var element2 = document.query('#id');
+ *
+ * For details about CSS selector syntax, see the
+ * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
+ */
   @DomName('Document.querySelector')
   @DocsEditable
-  Element $dom_querySelector(String selectors) native;
+  Element query(String selectors) native;
 
   @JSName('querySelectorAll')
   /// Deprecated: use query("#$elementId") instead.
@@ -6813,30 +6966,6 @@
 
 
   /**
-   * Finds the first descendant element of this document that matches the
-   * specified group of selectors.
-   *
-   * Unless your webpage contains multiple documents, the top-level query
-   * method behaves the same as this method, so you should use it instead to
-   * save typing a few characters.
-   *
-   * [selectors] should be a string using CSS selector syntax.
-   *     var element1 = document.query('.className');
-   *     var element2 = document.query('#id');
-   *
-   * For details about CSS selector syntax, see the
-   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
-   */
-  Element query(String selectors) {
-    // It is fine for our RegExp to detect element id query selectors to have
-    // false negatives but not false positives.
-    if (new RegExp("^#[_a-zA-Z]\\w*\$").hasMatch(selectors)) {
-      return $dom_getElementById(selectors.substring(1));
-    }
-    return $dom_querySelector(selectors);
-  }
-
-  /**
    * Finds all descendant elements of this document that match the specified
    * group of selectors.
    *
@@ -6851,26 +6980,7 @@
    * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
    */
   List<Element> queryAll(String selectors) {
-    if (new RegExp("""^\\[name=["'][^'"]+['"]\\]\$""").hasMatch(selectors)) {
-      final mutableMatches = $dom_getElementsByName(
-          selectors.substring(7,selectors.length - 2));
-      int len = mutableMatches.length;
-      final copyOfMatches = new List<Element>(len);
-      for (int i = 0; i < len; ++i) {
-        copyOfMatches[i] = mutableMatches[i];
-      }
-      return new _FrozenElementList._wrap(copyOfMatches);
-    } else if (new RegExp("^[*a-zA-Z0-9]+\$").hasMatch(selectors)) {
-      final mutableMatches = $dom_getElementsByTagName(selectors);
-      int len = mutableMatches.length;
-      final copyOfMatches = new List<Element>(len);
-      for (int i = 0; i < len; ++i) {
-        copyOfMatches[i] = mutableMatches[i];
-      }
-      return new _FrozenElementList._wrap(copyOfMatches);
-    } else {
-      return new _FrozenElementList._wrap($dom_querySelectorAll(selectors));
-    }
+    return new _FrozenElementList._wrap($dom_querySelectorAll(selectors));
   }
 }
 // Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
@@ -6915,7 +7025,7 @@
 
   String get innerHtml {
     final e = new Element.tag("div");
-    e.nodes.add(this.clone(true));
+    e.append(this.clone(true));
     return e.innerHtml;
   }
 
@@ -6933,19 +7043,11 @@
   }
 
   /**
-   * Adds the specified element after the last child of this
-   * document fragment.
-   */
-  void append(Element element) {
-    this.children.add(element);
-  }
-
-  /**
    * Adds the specified text as a text node after the last child of this
    * document fragment.
    */
   void appendText(String text) {
-    this.nodes.add(new Text(text));
+    this.append(new Text(text));
   }
 
 
@@ -6954,7 +7056,7 @@
    * last child of this document fragment.
    */
   void appendHtml(String text) {
-    this.nodes.add(new DocumentFragment.html(text));
+    this.append(new DocumentFragment.html(text));
   }
 
 
@@ -7027,10 +7129,10 @@
     var errorName = JS('String', '#.name', this);
     // Although Safari nightly has updated the name to SecurityError, Safari 5
     // and 6 still return SECURITY_ERR.
-    if (_Device.isWebKit && errorName == 'SECURITY_ERR') return 'SecurityError';
+    if (Device.isWebKit && errorName == 'SECURITY_ERR') return 'SecurityError';
     // Chrome release still uses old string, remove this line when Chrome stable
     // also prints out SyntaxError.
-    if (_Device.isWebKit && errorName == 'SYNTAX_ERR') return 'SyntaxError';
+    if (Device.isWebKit && errorName == 'SYNTAX_ERR') return 'SyntaxError';
     return errorName;
   }
 
@@ -7172,16 +7274,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  DomMimeType firstMatching(bool test(DomMimeType value), { DomMimeType orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  DomMimeType firstWhere(bool test(DomMimeType value), { DomMimeType orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  DomMimeType lastMatching(bool test(DomMimeType value), {DomMimeType orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  DomMimeType lastWhere(bool test(DomMimeType value), {DomMimeType orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  DomMimeType singleMatching(bool test(DomMimeType value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  DomMimeType singleWhere(bool test(DomMimeType value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   DomMimeType elementAt(int index) {
@@ -7249,6 +7351,10 @@
   DomMimeType max([int compare(DomMimeType a, DomMimeType b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, DomMimeType element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   DomMimeType removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -7269,11 +7375,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(DomMimeType element)) {
+  void removeWhere(bool test(DomMimeType element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(DomMimeType element)) {
+  void retainWhere(bool test(DomMimeType element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -7289,8 +7395,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<DomMimeType> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <DomMimeType>[]);
+  }
+
   List<DomMimeType> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <DomMimeType>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, DomMimeType> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<DomMimeType> mixins.
 
@@ -7428,16 +7542,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  DomPlugin firstMatching(bool test(DomPlugin value), { DomPlugin orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  DomPlugin firstWhere(bool test(DomPlugin value), { DomPlugin orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  DomPlugin lastMatching(bool test(DomPlugin value), {DomPlugin orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  DomPlugin lastWhere(bool test(DomPlugin value), {DomPlugin orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  DomPlugin singleMatching(bool test(DomPlugin value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  DomPlugin singleWhere(bool test(DomPlugin value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   DomPlugin elementAt(int index) {
@@ -7505,6 +7619,10 @@
   DomPlugin max([int compare(DomPlugin a, DomPlugin b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, DomPlugin element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   DomPlugin removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -7525,11 +7643,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(DomPlugin element)) {
+  void removeWhere(bool test(DomPlugin element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(DomPlugin element)) {
+  void retainWhere(bool test(DomPlugin element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -7545,8 +7663,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<DomPlugin> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <DomPlugin>[]);
+  }
+
   List<DomPlugin> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <DomPlugin>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, DomPlugin> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<DomPlugin> mixins.
 
@@ -7791,16 +7917,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  String firstMatching(bool test(String value), { String orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  String firstWhere(bool test(String value), { String orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  String lastMatching(bool test(String value), {String orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  String lastWhere(bool test(String value), {String orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  String singleMatching(bool test(String value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  String singleWhere(bool test(String value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   String elementAt(int index) {
@@ -7868,6 +7994,10 @@
   String max([int compare(String a, String b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, String element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   String removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -7888,11 +8018,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(String element)) {
+  void removeWhere(bool test(String element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(String element)) {
+  void retainWhere(bool test(String element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -7908,8 +8038,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<String> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <String>[]);
+  }
+
   List<String> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <String>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, String> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<String> mixins.
 
@@ -8058,16 +8196,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Element firstMatching(bool test(Element value), {Element orElse()}) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Element firstWhere(bool test(Element value), {Element orElse()}) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Element lastMatching(bool test(Element value), {Element orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Element lastWhere(bool test(Element value), {Element orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Element singleMatching(bool test(Element value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Element singleWhere(bool test(Element value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Element elementAt(int index) {
@@ -8092,7 +8230,7 @@
   }
 
   Element add(Element value) {
-    _element.$dom_appendChild(value);
+    _element.append(value);
     return value;
   }
 
@@ -8106,7 +8244,7 @@
     }
 
     for (Element element in iterable) {
-      _element.$dom_appendChild(element);
+      _element.append(element);
     }
   }
 
@@ -8144,12 +8282,12 @@
     IterableMixinWorkaround.retainAll(this, elements);
   }
 
-  void removeMatching(bool test(Element element)) {
-    IterableMixinWorkaround.removeMatching(this, test);
+  void removeWhere(bool test(Element element)) {
+    IterableMixinWorkaround.removeWhere(this, test);
   }
 
-  void retainMatching(bool test(Element element)) {
-    IterableMixinWorkaround.retainMatching(this, test);
+  void retainWhere(bool test(Element element)) {
+    IterableMixinWorkaround.retainWhere(this, test);
   }
 
   void removeRange(int start, int rangeLength) {
@@ -8160,9 +8298,13 @@
     throw new UnimplementedError();
   }
 
+  List sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return new _FrozenElementList._wrap(Lists.getRange(this, start, end, []));
+  }
+
   List getRange(int start, int rangeLength) =>
-    new _FrozenElementList._wrap(Lists.getRange(this, start, rangeLength,
-        []));
+      sublist(start, start + rangeLength);
 
   int indexOf(Element element, [int start = 0]) {
     return Lists.indexOf(this, element, start, this.length);
@@ -8173,6 +8315,17 @@
     return Lists.lastIndexOf(this, element, start);
   }
 
+  void insert(int index, Element element) {
+    if (index < 0 || index > length) {
+      throw new RangeError.range(index, 0, length);
+    }
+    if (index == length) {
+      _element.append(element);
+    } else {
+      throw new UnimplementedError("insert on ElementLists");
+    }
+  }
+
   void clear() {
     // It is unclear if we want to keep non element nodes?
     _element.text = '';
@@ -8219,6 +8372,10 @@
   Element max([int compare(Element a, Element b)]) {
     return IterableMixinWorkaround.max(this, compare);
   }
+
+  Map<int, Element> asMap() {
+    return IterableMixinWorkaround.asMapList(this);
+  }
 }
 
 // TODO(jacobr): this is an inefficient implementation but it is hard to see
@@ -8297,16 +8454,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Element firstMatching(bool test(Element value), {Element orElse()}) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Element firstWhere(bool test(Element value), {Element orElse()}) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Element lastMatching(bool test(Element value), {Element orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Element lastWhere(bool test(Element value), {Element orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Element singleMatching(bool test(Element value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Element singleWhere(bool test(Element value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Element elementAt(int index) {
@@ -8366,8 +8523,12 @@
     throw new UnsupportedError('');
   }
 
+  List<Element> sublist(int start, [int end]) {
+    return new _FrozenElementList._wrap(_nodeList.sublist(start, end));
+  }
+
   List<Element> getRange(int start, int rangeLength) =>
-    new _FrozenElementList._wrap(_nodeList.getRange(start, rangeLength));
+      sublist(start, start + rangeLength);
 
   int indexOf(Element element, [int start = 0]) =>
     _nodeList.indexOf(element, start);
@@ -8399,11 +8560,11 @@
     throw new UnsupportedError('');
   }
 
-  void removeMatching(bool test(Element element)) {
+  void removeWhere(bool test(Element element)) {
     throw new UnsupportedError('');
   }
 
-  void retainMatching(bool test(Element element)) {
+  void retainWhere(bool test(Element element)) {
     throw new UnsupportedError('');
   }
 
@@ -8420,6 +8581,10 @@
   Element max([int compare(Element a, Element b)]) {
     return IterableMixinWorkaround.max(this, compare);
   }
+
+  Map<int, Element> asMap() {
+    return IterableMixinWorkaround.asMapList(this);
+  }
 }
 
 class _FrozenElementListIterator implements Iterator<Element> {
@@ -8568,25 +8733,6 @@
   }
 
   /**
-   * Finds the first descendant element of this element that matches the
-   * specified group of selectors.
-   *
-   * [selectors] should be a string using CSS selector syntax.
-   *
-   *     // Gets the first descendant with the class 'classname'
-   *     var element = element.query('.className');
-   *     // Gets the element with id 'id'
-   *     var element = element.query('#id');
-   *     // Gets the first descendant [ImageElement]
-   *     var img = element.query('img');
-   *
-   * See also:
-   *
-   * * [CSS Selectors](http://docs.webplatform.org/wiki/css/selectors)
-   */
-  Element query(String selectors) => $dom_querySelector(selectors);
-
-  /**
    * Finds all descendent elements of this element that match the specified
    * group of selectors.
    *
@@ -8683,12 +8829,37 @@
     return window.$dom_getComputedStyle(this, pseudoElement);
   }
 
-  /**
-   * Adds the specified element to after the last child of this element.
-   */
-  void append(Element e) {
-    this.children.add(e);
-  }
+  @deprecated
+  int get clientHeight => client.height;
+  @deprecated
+  int get clientLeft => client.left;
+  @deprecated
+  int get clientTop => client.top;
+  @deprecated
+  int get clientWidth => client.width;
+
+  @DomName('Element.clientHeight')
+  @DomName('Element.clientLeft')
+  @DomName('Element.clientTop')
+  @DomName('Element.clientWidth')
+  Rect get client => new Rect($dom_clientLeft, $dom_clientTop, $dom_clientWidth,
+      $dom_clientHeight);
+
+  @deprecated
+  int get offsetHeight => offset.height;
+  @deprecated
+  int get offsetLeft => offset.left;
+  @deprecated
+  int get offsetTop => offset.top;
+  @deprecated
+  int get offsetWidth => offset.width;
+
+  @DomName('Element.offsetHeight')
+  @DomName('Element.offsetLeft')
+  @DomName('Element.offsetTop')
+  @DomName('Element.offsetWidth')
+  Rect get offset => new Rect($dom_offsetLeft, $dom_offsetTop, $dom_offsetWidth,
+      $dom_offsetHeight);
 
   /**
    * Adds the specified text as a text node after the last child of this
@@ -8797,9 +8968,9 @@
 
   static String _determineTransitionEventType(EventTarget e) {
     // Unfortunately the normal 'ontransitionend' style checks don't work here.
-    if (_Device.isWebKit) {
+    if (Device.isWebKit) {
       return 'webkitTransitionEnd';
-    } else if (_Device.isOpera) {
+    } else if (Device.isOpera) {
       return 'oTransitionEnd';
     }
     return 'transitionend';
@@ -8890,7 +9061,7 @@
         this.insertBefore(node, first);
         break;
       case 'beforeend':
-        this.nodes.add(node);
+        this.append(node);
         break;
       case 'afterend':
         this.parentNode.insertBefore(node, this.nextNode);
@@ -9196,21 +9367,25 @@
   @DocsEditable
   String $dom_className;
 
+  @JSName('clientHeight')
   @DomName('Element.clientHeight')
   @DocsEditable
-  final int clientHeight;
+  final int $dom_clientHeight;
 
+  @JSName('clientLeft')
   @DomName('Element.clientLeft')
   @DocsEditable
-  final int clientLeft;
+  final int $dom_clientLeft;
 
+  @JSName('clientTop')
   @DomName('Element.clientTop')
   @DocsEditable
-  final int clientTop;
+  final int $dom_clientTop;
 
+  @JSName('clientWidth')
   @DomName('Element.clientWidth')
   @DocsEditable
-  final int clientWidth;
+  final int $dom_clientWidth;
 
   @JSName('firstElementChild')
   @DomName('Element.firstElementChild')
@@ -9226,25 +9401,29 @@
   @DocsEditable
   final Element nextElementSibling;
 
+  @JSName('offsetHeight')
   @DomName('Element.offsetHeight')
   @DocsEditable
-  final int offsetHeight;
+  final int $dom_offsetHeight;
 
+  @JSName('offsetLeft')
   @DomName('Element.offsetLeft')
   @DocsEditable
-  final int offsetLeft;
+  final int $dom_offsetLeft;
 
   @DomName('Element.offsetParent')
   @DocsEditable
   final Element offsetParent;
 
+  @JSName('offsetTop')
   @DomName('Element.offsetTop')
   @DocsEditable
-  final int offsetTop;
+  final int $dom_offsetTop;
 
+  @JSName('offsetWidth')
   @DomName('Element.offsetWidth')
   @DocsEditable
-  final int offsetWidth;
+  final int $dom_offsetWidth;
 
   @DomName('Element.previousElementSibling')
   @DocsEditable
@@ -9310,20 +9489,19 @@
 
   @DomName('Element.getBoundingClientRect')
   @DocsEditable
-  ClientRect getBoundingClientRect() native;
+  Rect getBoundingClientRect() native;
 
   @DomName('Element.getClientRects')
   @DocsEditable
   @Returns('_ClientRectList')
   @Creates('_ClientRectList')
-  List<ClientRect> getClientRects() native;
+  List<Rect> getClientRects() native;
 
-  @JSName('getElementsByClassName')
   @DomName('Element.getElementsByClassName')
   @DocsEditable
   @Returns('NodeList')
   @Creates('NodeList')
-  List<Node> $dom_getElementsByClassName(String name) native;
+  List<Node> getElementsByClassName(String name) native;
 
   @JSName('getElementsByTagName')
   @DomName('Element.getElementsByTagName')
@@ -9343,9 +9521,26 @@
   bool $dom_hasAttributeNS(String namespaceURI, String localName) native;
 
   @JSName('querySelector')
+  /**
+ * Finds the first descendant element of this element that matches the
+ * specified group of selectors.
+ *
+ * [selectors] should be a string using CSS selector syntax.
+ *
+ *     // Gets the first descendant with the class 'classname'
+ *     var element = element.query('.className');
+ *     // Gets the element with id 'id'
+ *     var element = element.query('#id');
+ *     // Gets the first descendant [ImageElement]
+ *     var img = element.query('img');
+ *
+ * See also:
+ *
+ * * [CSS Selectors](http://docs.webplatform.org/wiki/css/selectors)
+ */
   @DomName('Element.querySelector')
   @DocsEditable
-  Element $dom_querySelector(String selectors) native;
+  Element query(String selectors) native;
 
   @JSName('querySelectorAll')
   @DomName('Element.querySelectorAll')
@@ -9664,7 +9859,7 @@
     final match = _START_TAG_REGEXP.firstMatch(html);
     if (match != null) {
       tag = match.group(1).toLowerCase();
-      if (_Device.isIE && _TABLE_TAGS.containsKey(tag)) {
+      if (Device.isIE && _TABLE_TAGS.containsKey(tag)) {
         return _createTableForIE(html, tag);
       }
       parentTag = _CUSTOM_PARENT_TAG_MAP[tag];
@@ -9707,7 +9902,8 @@
     switch (tag) {
       case 'td':
       case 'th':
-        element = _singleNode(_singleNode(table.rows).cells);
+        TableRowElement row = _singleNode(table.rows);
+        element = _singleNode(row.cells);
         break;
       case 'tr':
         element = _singleNode(table.rows);
@@ -9848,7 +10044,7 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void EntriesCallback(List<Entry> entries);
+typedef void _EntriesCallback(List<Entry> entries);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -9878,25 +10074,85 @@
   @DocsEditable
   final String name;
 
+  @JSName('copyTo')
   @DomName('Entry.copyTo')
   @DocsEditable
-  void copyTo(DirectoryEntry parent, [String name, EntryCallback successCallback, ErrorCallback errorCallback]) native;
+  void _copyTo(DirectoryEntry parent, {String name, _EntryCallback successCallback, _ErrorCallback errorCallback}) native;
 
+  @JSName('copyTo')
+  @DomName('Entry.copyTo')
+  @DocsEditable
+  Future<Entry> copyTo(DirectoryEntry parent, {String name}) {
+    var completer = new Completer<Entry>();
+    _copyTo(parent, name : name,
+        successCallback : (value) { completer.complete(value); },
+        errorCallback : (error) { completer.completeError(error); });
+    return completer.future;
+  }
+
+  @JSName('getMetadata')
   @DomName('Entry.getMetadata')
   @DocsEditable
-  void getMetadata(MetadataCallback successCallback, [ErrorCallback errorCallback]) native;
+  void _getMetadata(MetadataCallback successCallback, [_ErrorCallback errorCallback]) native;
 
+  @JSName('getMetadata')
+  @DomName('Entry.getMetadata')
+  @DocsEditable
+  Future<Metadata> getMetadata() {
+    var completer = new Completer<Metadata>();
+    _getMetadata(
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
+
+  @JSName('getParent')
   @DomName('Entry.getParent')
   @DocsEditable
-  void getParent([EntryCallback successCallback, ErrorCallback errorCallback]) native;
+  void _getParent([_EntryCallback successCallback, _ErrorCallback errorCallback]) native;
 
+  @JSName('getParent')
+  @DomName('Entry.getParent')
+  @DocsEditable
+  Future<Entry> getParent() {
+    var completer = new Completer<Entry>();
+    _getParent(
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
+
+  @JSName('moveTo')
   @DomName('Entry.moveTo')
   @DocsEditable
-  void moveTo(DirectoryEntry parent, [String name, EntryCallback successCallback, ErrorCallback errorCallback]) native;
+  void _moveTo(DirectoryEntry parent, {String name, _EntryCallback successCallback, _ErrorCallback errorCallback}) native;
 
+  @JSName('moveTo')
+  @DomName('Entry.moveTo')
+  @DocsEditable
+  Future<Entry> moveTo(DirectoryEntry parent, {String name}) {
+    var completer = new Completer<Entry>();
+    _moveTo(parent, name : name,
+        successCallback : (value) { completer.complete(value); },
+        errorCallback : (error) { completer.completeError(error); });
+    return completer.future;
+  }
+
+  @JSName('remove')
   @DomName('Entry.remove')
   @DocsEditable
-  void remove(VoidCallback successCallback, [ErrorCallback errorCallback]) native;
+  void _remove(VoidCallback successCallback, [_ErrorCallback errorCallback]) native;
+
+  @JSName('remove')
+  @DomName('Entry.remove')
+  @DocsEditable
+  Future remove() {
+    var completer = new Completer();
+    _remove(
+        () { completer.complete(); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
   @JSName('toURL')
   @DomName('Entry.toURL')
@@ -9910,7 +10166,7 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void EntryCallback(Entry entry);
+typedef void _EntryCallback(Entry entry);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -9972,7 +10228,7 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void ErrorCallback(FileError error);
+typedef void _ErrorCallback(FileError error);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -10139,18 +10395,6 @@
   @DocsEditable
   void stopPropagation() native;
 
-
-  /**
-   * Checks to see if the event class is supported by the current platform.
-   */
-  static bool _isTypeSupported(String eventType) {
-    // Browsers throw for unsupported event names.
-    try {
-      var e = document.$dom_createEvent(eventType);
-      return e is Event;
-    } catch (_) { }
-    return false;
-  }
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -10350,6 +10594,83 @@
 
 
 @DocsEditable
+@DomName('EXTDrawBuffers')
+class ExtDrawBuffers native "*EXTDrawBuffers" {
+
+  static const int COLOR_ATTACHMENT0_EXT = 0x8CE0;
+
+  static const int COLOR_ATTACHMENT10_EXT = 0x8CEA;
+
+  static const int COLOR_ATTACHMENT11_EXT = 0x8CEB;
+
+  static const int COLOR_ATTACHMENT12_EXT = 0x8CEC;
+
+  static const int COLOR_ATTACHMENT13_EXT = 0x8CED;
+
+  static const int COLOR_ATTACHMENT14_EXT = 0x8CEE;
+
+  static const int COLOR_ATTACHMENT15_EXT = 0x8CEF;
+
+  static const int COLOR_ATTACHMENT1_EXT = 0x8CE1;
+
+  static const int COLOR_ATTACHMENT2_EXT = 0x8CE2;
+
+  static const int COLOR_ATTACHMENT3_EXT = 0x8CE3;
+
+  static const int COLOR_ATTACHMENT4_EXT = 0x8CE4;
+
+  static const int COLOR_ATTACHMENT5_EXT = 0x8CE5;
+
+  static const int COLOR_ATTACHMENT6_EXT = 0x8CE6;
+
+  static const int COLOR_ATTACHMENT7_EXT = 0x8CE7;
+
+  static const int COLOR_ATTACHMENT8_EXT = 0x8CE8;
+
+  static const int COLOR_ATTACHMENT9_EXT = 0x8CE9;
+
+  static const int DRAW_BUFFER0_EXT = 0x8825;
+
+  static const int DRAW_BUFFER10_EXT = 0x882F;
+
+  static const int DRAW_BUFFER11_EXT = 0x8830;
+
+  static const int DRAW_BUFFER12_EXT = 0x8831;
+
+  static const int DRAW_BUFFER13_EXT = 0x8832;
+
+  static const int DRAW_BUFFER14_EXT = 0x8833;
+
+  static const int DRAW_BUFFER15_EXT = 0x8834;
+
+  static const int DRAW_BUFFER1_EXT = 0x8826;
+
+  static const int DRAW_BUFFER2_EXT = 0x8827;
+
+  static const int DRAW_BUFFER3_EXT = 0x8828;
+
+  static const int DRAW_BUFFER4_EXT = 0x8829;
+
+  static const int DRAW_BUFFER5_EXT = 0x882A;
+
+  static const int DRAW_BUFFER6_EXT = 0x882B;
+
+  static const int DRAW_BUFFER7_EXT = 0x882C;
+
+  static const int DRAW_BUFFER8_EXT = 0x882D;
+
+  static const int DRAW_BUFFER9_EXT = 0x882E;
+
+  static const int MAX_COLOR_ATTACHMENTS_EXT = 0x8CDF;
+
+  static const int MAX_DRAW_BUFFERS_EXT = 0x8824;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable
 @DomName('EXTTextureFilterAnisotropic')
 class ExtTextureFilterAnisotropic native "*EXTTextureFilterAnisotropic" {
 
@@ -10444,7 +10765,7 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void FileCallback(File file);
+typedef void _FileCallback(File file);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -10454,13 +10775,37 @@
 @DomName('FileEntry')
 class FileEntry extends Entry native "*FileEntry" {
 
+  @JSName('createWriter')
   @DomName('FileEntry.createWriter')
   @DocsEditable
-  void createWriter(FileWriterCallback successCallback, [ErrorCallback errorCallback]) native;
+  void _createWriter(_FileWriterCallback successCallback, [_ErrorCallback errorCallback]) native;
 
+  @JSName('createWriter')
+  @DomName('FileEntry.createWriter')
+  @DocsEditable
+  Future<FileWriter> createWriter() {
+    var completer = new Completer<FileWriter>();
+    _createWriter(
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
+
+  @JSName('file')
   @DomName('FileEntry.file')
   @DocsEditable
-  void file(FileCallback successCallback, [ErrorCallback errorCallback]) native;
+  void _file(_FileCallback successCallback, [_ErrorCallback errorCallback]) native;
+
+  @JSName('file')
+  @DomName('FileEntry.file')
+  @DocsEditable
+  Future<File> file() {
+    var completer = new Completer<File>();
+    _file(
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -10638,16 +10983,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  File firstMatching(bool test(File value), { File orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  File firstWhere(bool test(File value), { File orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  File lastMatching(bool test(File value), {File orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  File lastWhere(bool test(File value), {File orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  File singleMatching(bool test(File value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  File singleWhere(bool test(File value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   File elementAt(int index) {
@@ -10715,6 +11060,10 @@
   File max([int compare(File a, File b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, File element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   File removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -10735,11 +11084,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(File element)) {
+  void removeWhere(bool test(File element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(File element)) {
+  void retainWhere(bool test(File element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -10755,8 +11104,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<File> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <File>[]);
+  }
+
   List<File> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <File>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, File> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<File> mixins.
 
@@ -10900,7 +11257,9 @@
 
   @DomName('FileReaderSync.readAsArrayBuffer')
   @DocsEditable
-  ArrayBuffer readAsArrayBuffer(Blob blob) native;
+  @Creates('ArrayBuffer')
+  @Returns('ArrayBuffer|Null')
+  dynamic readAsArrayBuffer(Blob blob) native;
 
   @DomName('FileReaderSync.readAsBinaryString')
   @DocsEditable
@@ -10944,7 +11303,7 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void FileSystemCallback(FileSystem fileSystem);
+typedef void _FileSystemCallback(FileSystem fileSystem);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -11080,7 +11439,7 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void FileWriterCallback(FileWriter fileWriter);
+typedef void _FileWriterCallback(FileWriter fileWriter);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -11197,16 +11556,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  num firstMatching(bool test(num value), { num orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  num firstWhere(bool test(num value), { num orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  num lastMatching(bool test(num value), {num orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  num lastWhere(bool test(num value), {num orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  num singleMatching(bool test(num value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  num singleWhere(bool test(num value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   num elementAt(int index) {
@@ -11274,6 +11633,10 @@
   num max([int compare(num a, num b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, num element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   num removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -11294,11 +11657,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(num element)) {
+  void removeWhere(bool test(num element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(num element)) {
+  void retainWhere(bool test(num element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -11314,8 +11677,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<num> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <num>[]);
+  }
+
   List<num> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <num>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, num> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<num> mixins.
 
@@ -11326,7 +11697,9 @@
 
   @DomName('Float32Array.subarray')
   @DocsEditable
-  Float32Array subarray(int start, [int end]) native;
+  @Returns('Float32Array')
+  @Creates('Float32Array')
+  List<double> subarray(int start, [int end]) native;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -11415,16 +11788,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  num firstMatching(bool test(num value), { num orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  num firstWhere(bool test(num value), { num orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  num lastMatching(bool test(num value), {num orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  num lastWhere(bool test(num value), {num orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  num singleMatching(bool test(num value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  num singleWhere(bool test(num value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   num elementAt(int index) {
@@ -11492,6 +11865,10 @@
   num max([int compare(num a, num b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, num element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   num removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -11512,11 +11889,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(num element)) {
+  void removeWhere(bool test(num element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(num element)) {
+  void retainWhere(bool test(num element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -11532,8 +11909,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<num> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <num>[]);
+  }
+
   List<num> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <num>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, num> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<num> mixins.
 
@@ -11544,7 +11929,9 @@
 
   @DomName('Float64Array.subarray')
   @DocsEditable
-  Float64Array subarray(int start, [int end]) native;
+  @Returns('Float64Array')
+  @Creates('Float64Array')
+  List<double> subarray(int start, [int end]) native;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -11750,7 +12137,7 @@
                 controller.add(_ensurePosition(position));
               },
               (error) {
-                controller.signalError(error);
+                controller.addError(error);
               },
               options);
         } else {
@@ -11772,6 +12159,7 @@
     return new _GeopositionWrapper(domPosition);
   }
 
+
   @JSName('clearWatch')
   @DomName('Geolocation.clearWatch')
   @DocsEditable
@@ -11856,7 +12244,7 @@
   }
 
   /// Checks if this type is supported on the current platform.
-  static bool get supported => Event._isTypeSupported('HashChangeEvent');
+  static bool get supported => Device.isEventTypeSupported('HashChangeEvent');
 
   @JSName('newURL')
   @DomName('HashChangeEvent.newURL')
@@ -12052,16 +12440,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Node firstMatching(bool test(Node value), { Node orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Node firstWhere(bool test(Node value), { Node orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Node lastMatching(bool test(Node value), {Node orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Node lastWhere(bool test(Node value), {Node orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Node singleMatching(bool test(Node value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Node singleWhere(bool test(Node value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Node elementAt(int index) {
@@ -12129,6 +12517,10 @@
   Node max([int compare(Node a, Node b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, Node element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   Node removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -12149,11 +12541,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(Node element)) {
+  void removeWhere(bool test(Node element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(Node element)) {
+  void retainWhere(bool test(Node element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -12169,8 +12561,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<Node> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <Node>[]);
+  }
+
   List<Node> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Node>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, Node> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<Node> mixins.
 
@@ -12261,16 +12661,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Node firstMatching(bool test(Node value), { Node orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Node firstWhere(bool test(Node value), { Node orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Node lastMatching(bool test(Node value), {Node orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Node lastWhere(bool test(Node value), {Node orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Node singleMatching(bool test(Node value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Node singleWhere(bool test(Node value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Node elementAt(int index) {
@@ -12338,6 +12738,10 @@
   Node max([int compare(Node a, Node b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, Node element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   Node removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -12358,11 +12762,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(Node element)) {
+  void removeWhere(bool test(Node element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(Node element)) {
+  void retainWhere(bool test(Node element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -12378,8 +12782,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<Node> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <Node>[]);
+  }
+
   List<Node> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Node>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, Node> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<Node> mixins.
 
@@ -12648,7 +13060,7 @@
     if (method == null) {
       method = 'GET';
     }
-    xhr.open(method, url, true);
+    xhr.open(method, url, async: true);
 
     if (withCredentials != null) {
       xhr.withCredentials = withCredentials;
@@ -12936,7 +13348,7 @@
    */
   @DomName('XMLHttpRequest.open')
   @DocsEditable
-  void open(String method, String url, [bool async, String user, String password]) native;
+  void open(String method, String url, {bool async, String user, String password}) native;
 
   /**
    * Specify a particular MIME type (such as `text/xml`) desired for the
@@ -13079,7 +13491,7 @@
 class HttpRequestProgressEvent extends ProgressEvent native "*XMLHttpRequestProgressEvent" {
 
   /// Checks if this type is supported on the current platform.
-  static bool get supported => Event._isTypeSupported('XMLHttpRequestProgressEvent');
+  static bool get supported => Device.isEventTypeSupported('XMLHttpRequestProgressEvent');
 
   @DomName('XMLHttpRequestProgressEvent.position')
   @DocsEditable
@@ -13232,9 +13644,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-@DocsEditable
 @DomName('HTMLImageElement')
-class ImageElement extends Element native "*HTMLImageElement" {
+class ImageElement extends Element implements CanvasImageSource native "*HTMLImageElement" {
 
   @DomName('HTMLImageElement.HTMLImageElement')
   @DocsEditable
@@ -13301,6 +13712,7 @@
   @DomName('HTMLImageElement.y')
   @DocsEditable
   final int y;
+
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -13591,7 +14003,7 @@
 
   @DomName('HTMLInputElement.setRangeText')
   @DocsEditable
-  void setRangeText(String replacement, [int start, int end, String selectionMode]) native;
+  void setRangeText(String replacement, {int start, int end, String selectionMode}) native;
 
   @DomName('HTMLInputElement.setSelectionRange')
   @DocsEditable
@@ -14253,16 +14665,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  int firstMatching(bool test(int value), { int orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  int firstWhere(bool test(int value), { int orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  int lastMatching(bool test(int value), {int orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  int lastWhere(bool test(int value), {int orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  int singleMatching(bool test(int value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  int singleWhere(bool test(int value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   int elementAt(int index) {
@@ -14330,6 +14742,10 @@
   int max([int compare(int a, int b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, int element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -14350,11 +14766,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(int element)) {
+  void removeWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(int element)) {
+  void retainWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -14370,8 +14786,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <int>[]);
+  }
+
   List<int> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <int>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, int> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<int> mixins.
 
@@ -14382,7 +14806,9 @@
 
   @DomName('Int16Array.subarray')
   @DocsEditable
-  Int16Array subarray(int start, [int end]) native;
+  @Returns('Int16Array')
+  @Creates('Int16Array')
+  List<int> subarray(int start, [int end]) native;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -14471,16 +14897,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  int firstMatching(bool test(int value), { int orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  int firstWhere(bool test(int value), { int orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  int lastMatching(bool test(int value), {int orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  int lastWhere(bool test(int value), {int orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  int singleMatching(bool test(int value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  int singleWhere(bool test(int value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   int elementAt(int index) {
@@ -14548,6 +14974,10 @@
   int max([int compare(int a, int b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, int element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -14568,11 +14998,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(int element)) {
+  void removeWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(int element)) {
+  void retainWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -14588,8 +15018,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <int>[]);
+  }
+
   List<int> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <int>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, int> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<int> mixins.
 
@@ -14600,7 +15038,9 @@
 
   @DomName('Int32Array.subarray')
   @DocsEditable
-  Int32Array subarray(int start, [int end]) native;
+  @Returns('Int32Array')
+  @Creates('Int32Array')
+  List<int> subarray(int start, [int end]) native;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -14689,16 +15129,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  int firstMatching(bool test(int value), { int orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  int firstWhere(bool test(int value), { int orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  int lastMatching(bool test(int value), {int orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  int lastWhere(bool test(int value), {int orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  int singleMatching(bool test(int value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  int singleWhere(bool test(int value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   int elementAt(int index) {
@@ -14766,6 +15206,10 @@
   int max([int compare(int a, int b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, int element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -14786,11 +15230,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(int element)) {
+  void removeWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(int element)) {
+  void retainWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -14806,8 +15250,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <int>[]);
+  }
+
   List<int> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <int>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, int> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<int> mixins.
 
@@ -14818,7 +15270,9 @@
 
   @DomName('Int8Array.subarray')
   @DocsEditable
-  Int8Array subarray(int start, [int end]) native;
+  @Returns('Int8Array')
+  @Creates('Int8Array')
+  List<int> subarray(int start, [int end]) native;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -15834,7 +16288,9 @@
 
   @DomName('MediaKeyEvent.initData')
   @DocsEditable
-  final Uint8Array initData;
+  @Returns('Uint8Array')
+  @Creates('Uint8Array')
+  final List<int> initData;
 
   @DomName('MediaKeyEvent.keySystem')
   @DocsEditable
@@ -15842,7 +16298,9 @@
 
   @DomName('MediaKeyEvent.message')
   @DocsEditable
-  final Uint8Array message;
+  @Returns('Uint8Array')
+  @Creates('Uint8Array')
+  final List<int> message;
 
   @DomName('MediaKeyEvent.sessionId')
   @DocsEditable
@@ -16100,7 +16558,7 @@
 class MediaStreamEvent extends Event native "*MediaStreamEvent" {
 
   /// Checks if this type is supported on the current platform.
-  static bool get supported => Event._isTypeSupported('MediaStreamEvent');
+  static bool get supported => Device.isEventTypeSupported('MediaStreamEvent');
 
   @DomName('MediaStreamEvent.stream')
   @DocsEditable
@@ -16187,7 +16645,7 @@
 class MediaStreamTrackEvent extends Event native "*MediaStreamTrackEvent" {
 
   /// Checks if this type is supported on the current platform.
-  static bool get supported => Event._isTypeSupported('MediaStreamTrackEvent');
+  static bool get supported => Device.isEventTypeSupported('MediaStreamTrackEvent');
 
   @DomName('MediaStreamTrackEvent.track')
   @DocsEditable
@@ -16523,13 +16981,15 @@
   @DocsEditable
   final int button;
 
+  @JSName('clientX')
   @DomName('MouseEvent.clientX')
   @DocsEditable
-  final int clientX;
+  final int $dom_clientX;
 
+  @JSName('clientY')
   @DomName('MouseEvent.clientY')
   @DocsEditable
-  final int clientY;
+  final int $dom_clientY;
 
   @DomName('MouseEvent.ctrlKey')
   @DocsEditable
@@ -16555,13 +17015,15 @@
   @Returns('EventTarget|=Object')
   final dynamic _get_relatedTarget;
 
+  @JSName('screenX')
   @DomName('MouseEvent.screenX')
   @DocsEditable
-  final int screenX;
+  final int $dom_screenX;
 
+  @JSName('screenY')
   @DomName('MouseEvent.screenY')
   @DocsEditable
-  final int screenY;
+  final int $dom_screenY;
 
   @DomName('MouseEvent.shiftKey')
   @DocsEditable
@@ -16577,7 +17039,7 @@
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental
-  final int movementX;
+  final int $dom_webkitMovementX;
 
   @JSName('webkitMovementY')
   @DomName('MouseEvent.webkitMovementY')
@@ -16585,7 +17047,7 @@
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental
-  final int movementY;
+  final int $dom_webkitMovementY;
 
   @DomName('MouseEvent.initMouseEvent')
   @DocsEditable
@@ -16600,18 +17062,46 @@
   void _$dom_initMouseEvent_1(type, canBubble, cancelable, Window view, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget) native;
 
 
-  // TODO(amouravski): Move this documentation out of thise template files and
-  // put it into docs.json. Remember to add @DomName here.
+  @deprecated
+  int get clientX => client.x;
+  @deprecated
+  int get clientY => client.y;
+  @deprecated
+  int get offsetX => offset.x;
+  @deprecated
+  int get offsetY => offset.y;
+  @deprecated
+  int get movementX => movement.x;
+  @deprecated
+  int get movementY => movement.y;
+  @deprecated
+  int get screenX => screen.x;
+  @deprecated
+  int get screenY => screen.y;
+
+  @DomName('MouseEvent.clientX')
+  @DomName('MouseEvent.clientY')
+  Point get client => new Point($dom_clientX, $dom_clientY);
+
+  @DomName('MouseEvent.movementX')
+  @DomName('MouseEvent.movementY')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  Point get movement => new Point($dom_webkitMovementX, $dom_webkitMovementY);
+
   /**
-   * The X coordinate of the mouse pointer in target node coordinates.
+   * The coordinates of the mouse pointer in target node coordinates.
    *
    * This value may vary between platforms if the target node moves
    * after the event has fired or if the element has CSS transforms affecting
    * it.
    */
-  int get offsetX {
-  if (JS('bool', '!!#.offsetX', this)) {
-      return JS('int', '#.offsetX', this);
+  Point get offset {
+    if (JS('bool', '!!#.offsetX', this)) {
+      var x = JS('int', '#.offsetX', this);
+      var y = JS('int', '#.offsetX', this);
+      return new Point(x, y);
     } else {
       // Firefox does not support offsetX.
       var target = this.target;
@@ -16619,30 +17109,14 @@
         throw new UnsupportedError(
             'offsetX is only supported on elements');
       }
-      return this.clientX - this.target.getBoundingClientRect().left;
+      return (this.client -
+          this.target.getBoundingClientRect().topLeft).toInt();
     }
   }
 
-  /**
-   * The Y coordinate of the mouse pointer in target node coordinates.
-   *
-   * This value may vary between platforms if the target node moves
-   * after the event has fired or if the element has CSS transforms affecting
-   * it.
-   */
-  int get offsetY {
-    if (JS('bool', '!!#.offsetY', this)) {
-      return JS('int', '#.offsetY', this);
-    } else {
-      // Firefox does not support offsetY.
-      var target = this.target;
-      if (!(target is Element)) {
-        throw new UnsupportedError(
-            'offsetY is only supported on elements');
-      }
-      return this.clientY - this.target.getBoundingClientRect().top;
-    }
-  }
+  @DomName('MouseEvent.screenX')
+  @DomName('MouseEvent.screenY')
+  Point get screen => new Point($dom_screenX, $dom_screenY);
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -17061,12 +17535,12 @@
 
 
   Node get first {
-    Node result = JS('Node', '#.firstChild', _this);
+    Node result = JS('Node|Null', '#.firstChild', _this);
     if (result == null) throw new StateError("No elements");
     return result;
   }
   Node get last {
-    Node result = JS('Node', '#.lastChild', _this);
+    Node result = JS('Node|Null', '#.lastChild', _this);
     if (result == null) throw new StateError("No elements");
     return result;
   }
@@ -17074,7 +17548,7 @@
     int l = this.length;
     if (l == 0) throw new StateError("No elements");
     if (l > 1) throw new StateError("More than one element");
-    return JS('Node', '#.firstChild', _this);
+    return JS('Node|Null', '#.firstChild', _this);
   }
 
   Node min([int compare(Node a, Node b)]) {
@@ -17086,26 +17560,38 @@
   }
 
   void add(Node value) {
-    _this.$dom_appendChild(value);
+    _this.append(value);
   }
 
   void addLast(Node value) {
-    _this.$dom_appendChild(value);
+    _this.append(value);
   }
 
 
   void addAll(Iterable<Node> iterable) {
     if (iterable is _ChildNodeListLazy) {
-      if (iterable._this != _this) {
+      if (!identical(iterable._this, _this)) {
         // Optimized route for copying between nodes.
         for (var i = 0, len = iterable.length; i < len; ++i) {
-          _this.$dom_appendChild(iterable[0]);
+          // Should use $dom_firstChild, Bug 8886.
+          _this.append(iterable[0]);
         }
       }
       return;
     }
     for (Node node in iterable) {
-      _this.$dom_appendChild(node);
+      _this.append(node);
+    }
+  }
+
+  void insert(int index, Node node) {
+    if (index < 0 || index > length) {
+      throw new RangeError.range(index, 0, length);
+    }
+    if (index == length) {
+      _this.append(node);
+    } else {
+      this_.insertBefore(node, this[index]);
     }
   }
 
@@ -17140,12 +17626,12 @@
     IterableMixinWorkaround.retainAll(this, elements);
   }
 
-  void removeMatching(bool test(Node node)) {
-    IterableMixinWorkaround.removeMatching(this, test);
+  void removeWhere(bool test(Node node)) {
+    IterableMixinWorkaround.removeWhere(this, test);
   }
 
-  void retainMatching(bool test(Node node)) {
-    IterableMixinWorkaround.retainMatching(this, test);
+  void retainWhere(bool test(Node node)) {
+    IterableMixinWorkaround.retainWhere(this, test);
   }
 
   void clear() {
@@ -17213,16 +17699,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Node firstMatching(bool test(Node value), {Node orElse()}) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Node firstWhere(bool test(Node value), {Node orElse()}) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Node lastMatching(bool test(Node value), {Node orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Node lastWhere(bool test(Node value), {Node orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Node singleMatching(bool test(Node value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Node singleWhere(bool test(Node value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Node elementAt(int index) {
@@ -17258,8 +17744,13 @@
     throw new UnsupportedError(
         "Cannot insertRange on immutable List.");
   }
+  List<Node> sublist(int start, [int end]) {
+    if (end == null) end == length;
+    return Lists.getRange(this, start, end, <Node>[]);
+  }
+
   List<Node> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Node>[]);
+      sublist(start, start + rangeLength);
 
   // -- end List<Node> mixins.
 
@@ -17273,6 +17764,8 @@
   }
 
   Node operator[](int index) => _this.$dom_childNodes[index];
+
+  Map<int, Node> asMap() => IterableMixinWorkaround.asMapList(this);
 }
 
 @DomName('Node')
@@ -17287,7 +17780,7 @@
     List copy = new List.from(value);
     text = '';
     for (Node node in copy) {
-      $dom_appendChild(node);
+      append(node);
     }
   }
 
@@ -17318,6 +17811,112 @@
     return this;
   }
 
+  /**
+   * Inserts all of the nodes into this node directly before refChild.
+   *
+   * See also:
+   *
+   * * [insertBefore]
+   */
+  Node insertAllBefore(Iterable<Node> newNodes, Node refChild) {
+    if (newNodes is _ChildNodeListLazy) {
+      if (identical(newNodes._this, this)) {
+        throw new ArgumentError(newNodes);
+      }
+
+      // Optimized route for copying between nodes.
+      for (var i = 0, len = newNodes.length; i < len; ++i) {
+        // Should use $dom_firstChild, Bug 8886.
+        this.insertBefore(newNodes[0], refChild);
+      }
+    } else {
+      for (var node in newNodes) {
+        this.insertBefore(node, refChild);
+      }
+    }
+  }
+
+  // Note that this may either be the locally set model or a cached value
+  // of the inherited model. This is cached to minimize model change
+  // notifications.
+  @Creates('Null')
+  var _model;
+  bool _hasLocalModel;
+  StreamController<Node> _modelChangedStream;
+
+  /**
+   * The data model which is inherited through the tree.
+   *
+   * Setting this will propagate the value to all descendant nodes. If the
+   * model is not set on this node then it will be inherited from ancestor
+   * nodes.
+   *
+   * Currently this does not support propagation through Shadow DOMs.
+   *
+   * [clearModel] must be used to remove the model property from this node
+   * and have the model inherit from ancestor nodes.
+   */
+  @Experimental
+  get model {
+    // If we have a change handler then we've cached the model locally.
+    if (_modelChangedStream != null) {
+      return _model;
+    }
+    // Otherwise start looking up the tree.
+    for (var node = this; node != null; node = node.parentNode) {
+      if (node._hasLocalModel == true) {
+        return node._model;
+      }
+    }
+    return null;
+  }
+
+  @Experimental
+  void set model(value) {
+    var changed = model != value;
+    _model = value;
+    _hasLocalModel = true;
+    _ModelTreeObserver.initialize();
+
+    if (changed) {
+      if (_modelChangedStream != null) {
+        _modelChangedStream.add(this);
+      }
+      // Propagate new model to all descendants.
+      _ModelTreeObserver.propagateModel(this, value, false);
+    }
+  }
+
+  /**
+   * Clears the locally set model and makes this model be inherited from parent
+   * nodes.
+   */
+  @Experimental
+  void clearModel() {
+    if (_hasLocalModel == true) {
+      _hasLocalModel = false;
+
+      // Propagate new model to all descendants.
+      if (parentNode != null) {
+        _ModelTreeObserver.propagateModel(this, parentNode.model, false);
+      } else {
+        _ModelTreeObserver.propagateModel(this, null, false);
+      }
+    }
+  }
+
+  /**
+   * Get a stream of models, whenever the model changes.
+   */
+  Stream<Node> get onModelChanged {
+    if (_modelChangedStream == null) {
+      // Ensure the model is cached locally to minimize change notifications.
+      _model = model;
+      _modelChangedStream = new StreamController.broadcast();
+    }
+    return _modelChangedStream.stream;
+  }
+
 
   @JSName('childNodes')
   @DomName('Node.childNodes')
@@ -17391,7 +17990,7 @@
   @JSName('appendChild')
   @DomName('Node.appendChild')
   @DocsEditable
-  Node $dom_appendChild(Node newChild) native;
+  Node append(Node newChild) native;
 
   @JSName('cloneNode')
   @DomName('Node.cloneNode')
@@ -17593,16 +18192,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Node firstMatching(bool test(Node value), { Node orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Node firstWhere(bool test(Node value), { Node orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Node lastMatching(bool test(Node value), {Node orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Node lastWhere(bool test(Node value), {Node orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Node singleMatching(bool test(Node value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Node singleWhere(bool test(Node value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Node elementAt(int index) {
@@ -17670,6 +18269,10 @@
   Node max([int compare(Node a, Node b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, Node element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   Node removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -17690,11 +18293,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(Node element)) {
+  void removeWhere(bool test(Node element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(Node element)) {
+  void retainWhere(bool test(Node element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -17710,8 +18313,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<Node> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <Node>[]);
+  }
+
   List<Node> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Node>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, Node> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<Node> mixins.
 
@@ -17811,9 +18422,20 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
 
+  @JSName('requestPermission')
   @DomName('Notification.requestPermission')
   @DocsEditable
-  static void requestPermission(NotificationPermissionCallback callback) native;
+  static void _requestPermission([_NotificationPermissionCallback callback]) native;
+
+  @JSName('requestPermission')
+  @DomName('Notification.requestPermission')
+  @DocsEditable
+  static Future<String> requestPermission() {
+    var completer = new Completer<String>();
+    _requestPermission(
+        (value) { completer.complete(value); });
+    return completer.future;
+  }
 
   @DomName('Notification.show')
   @DocsEditable
@@ -17868,9 +18490,20 @@
   @DocsEditable
   Notification createNotification(String iconUrl, String title, String body) native;
 
+  @JSName('requestPermission')
   @DomName('NotificationCenter.requestPermission')
   @DocsEditable
-  void requestPermission(VoidCallback callback) native;
+  void _requestPermission([VoidCallback callback]) native;
+
+  @JSName('requestPermission')
+  @DomName('NotificationCenter.requestPermission')
+  @DocsEditable
+  Future requestPermission() {
+    var completer = new Completer();
+    _requestPermission(
+        () { completer.complete(); });
+    return completer.future;
+  }
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -17879,7 +18512,7 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void NotificationPermissionCallback(String permission);
+typedef void _NotificationPermissionCallback(String permission);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -18011,6 +18644,15 @@
 
 
 @DocsEditable
+@DomName('OESTextureHalfFloat')
+class OesTextureHalfFloat native "*OESTextureHalfFloat" {
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable
 @DomName('OESVertexArrayObject')
 class OesVertexArrayObject native "*OESVertexArrayObject" {
 
@@ -18623,7 +19265,7 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void RtcErrorCallback(String errorInformation);
+typedef void _RtcErrorCallback(String errorInformation);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -18631,7 +19273,7 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void RtcSessionDescriptionCallback(RtcSessionDescription sdp);
+typedef void _RtcSessionDescriptionCallback(RtcSessionDescription sdp);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -18747,13 +19389,13 @@
 
   @DomName('Range.getBoundingClientRect')
   @DocsEditable
-  ClientRect getBoundingClientRect() native;
+  Rect getBoundingClientRect() native;
 
   @DomName('Range.getClientRects')
   @DocsEditable
   @Returns('_ClientRectList')
   @Creates('_ClientRectList')
-  List<ClientRect> getClientRects() native;
+  List<Rect> getClientRects() native;
 
   @DomName('Range.insertNode')
   @DocsEditable
@@ -18841,31 +19483,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.
 
-
-@DocsEditable
-@DomName('Rect')
-class Rect native "*Rect" {
-
-  @DomName('Rect.bottom')
-  @DocsEditable
-  final CssPrimitiveValue bottom;
-
-  @DomName('Rect.left')
-  @DocsEditable
-  final CssPrimitiveValue left;
-
-  @DomName('Rect.right')
-  @DocsEditable
-  final CssPrimitiveValue right;
-
-  @DomName('Rect.top')
-  @DocsEditable
-  final CssPrimitiveValue top;
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
 // WARNING: Do not edit - generated code.
 
 
@@ -18876,27 +19493,6 @@
 
 
 @DocsEditable
-@DomName('RGBColor')
-class RgbColor native "*RGBColor" {
-
-  @DomName('RGBColor.blue')
-  @DocsEditable
-  final CssPrimitiveValue blue;
-
-  @DomName('RGBColor.green')
-  @DocsEditable
-  final CssPrimitiveValue green;
-
-  @DomName('RGBColor.red')
-  @DocsEditable
-  final CssPrimitiveValue red;
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
-@DocsEditable
 @DomName('RTCDataChannel')
 class RtcDataChannel extends EventTarget native "*RTCDataChannel" {
 
@@ -19038,7 +19634,7 @@
 class RtcPeerConnection extends EventTarget native "*RTCPeerConnection" {
   factory RtcPeerConnection(Map rtcIceServers, [Map mediaConstraints]) {
     var constructorName = JS('RtcPeerConnection', 'window[#]',
-        '${_browserPropertyPrefix}RTCPeerConnection');
+        '${Device.propertyPrefix}RTCPeerConnection');
     if (?mediaConstraints) {
       return JS('RtcPeerConnection', 'new #(#,#)', constructorName,
           convertDartToNative_SerializedScriptValue(rtcIceServers),
@@ -19050,17 +19646,17 @@
   }
 
   /**
-   * Checks if Real Time Communication (RTC) APIs are supported and enabled on 
+   * Checks if Real Time Communication (RTC) APIs are supported and enabled on
    * the current platform.
    */
   static bool get supported {
     // Currently in Firefox some of the RTC elements are defined but throw an
-    // error unless the user has specifically enabled them in their 
+    // error unless the user has specifically enabled them in their
     // about:config. So we have to construct an element to actually test if RTC
     // is supported at at the given time.
     try {
       var c = new RtcPeerConnection({"iceServers": [ {"url":"stun:foo.com"}]});
-      return c is RtcPeerConnection; 
+      return c is RtcPeerConnection;
     } catch (_) {}
     return false;
   }
@@ -19156,23 +19752,34 @@
 
   @DomName('RTCPeerConnection.createAnswer')
   @DocsEditable
-  void createAnswer(RtcSessionDescriptionCallback successCallback, [RtcErrorCallback failureCallback, Map mediaConstraints]) {
+  void _createAnswer(_RtcSessionDescriptionCallback successCallback, [_RtcErrorCallback failureCallback, Map mediaConstraints]) {
     if (?mediaConstraints) {
       var mediaConstraints_1 = convertDartToNative_Dictionary(mediaConstraints);
-      _createAnswer_1(successCallback, failureCallback, mediaConstraints_1);
+      __createAnswer_1(successCallback, failureCallback, mediaConstraints_1);
       return;
     }
-    _createAnswer_2(successCallback, failureCallback);
+    __createAnswer_2(successCallback, failureCallback);
     return;
   }
   @JSName('createAnswer')
   @DomName('RTCPeerConnection.createAnswer')
   @DocsEditable
-  void _createAnswer_1(RtcSessionDescriptionCallback successCallback, RtcErrorCallback failureCallback, mediaConstraints) native;
+  void __createAnswer_1(_RtcSessionDescriptionCallback successCallback, _RtcErrorCallback failureCallback, mediaConstraints) native;
   @JSName('createAnswer')
   @DomName('RTCPeerConnection.createAnswer')
   @DocsEditable
-  void _createAnswer_2(RtcSessionDescriptionCallback successCallback, RtcErrorCallback failureCallback) native;
+  void __createAnswer_2(_RtcSessionDescriptionCallback successCallback, _RtcErrorCallback failureCallback) native;
+
+  @JSName('createAnswer')
+  @DomName('RTCPeerConnection.createAnswer')
+  @DocsEditable
+  Future<RtcSessionDescription> createAnswer([Map mediaConstraints]) {
+    var completer = new Completer<RtcSessionDescription>();
+    _createAnswer(mediaConstraints,
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
   @JSName('createDTMFSender')
   @DomName('RTCPeerConnection.createDTMFSender')
@@ -19199,23 +19806,34 @@
 
   @DomName('RTCPeerConnection.createOffer')
   @DocsEditable
-  void createOffer(RtcSessionDescriptionCallback successCallback, [RtcErrorCallback failureCallback, Map mediaConstraints]) {
+  void _createOffer(_RtcSessionDescriptionCallback successCallback, [_RtcErrorCallback failureCallback, Map mediaConstraints]) {
     if (?mediaConstraints) {
       var mediaConstraints_1 = convertDartToNative_Dictionary(mediaConstraints);
-      _createOffer_1(successCallback, failureCallback, mediaConstraints_1);
+      __createOffer_1(successCallback, failureCallback, mediaConstraints_1);
       return;
     }
-    _createOffer_2(successCallback, failureCallback);
+    __createOffer_2(successCallback, failureCallback);
     return;
   }
   @JSName('createOffer')
   @DomName('RTCPeerConnection.createOffer')
   @DocsEditable
-  void _createOffer_1(RtcSessionDescriptionCallback successCallback, RtcErrorCallback failureCallback, mediaConstraints) native;
+  void __createOffer_1(_RtcSessionDescriptionCallback successCallback, _RtcErrorCallback failureCallback, mediaConstraints) native;
   @JSName('createOffer')
   @DomName('RTCPeerConnection.createOffer')
   @DocsEditable
-  void _createOffer_2(RtcSessionDescriptionCallback successCallback, RtcErrorCallback failureCallback) native;
+  void __createOffer_2(_RtcSessionDescriptionCallback successCallback, _RtcErrorCallback failureCallback) native;
+
+  @JSName('createOffer')
+  @DomName('RTCPeerConnection.createOffer')
+  @DocsEditable
+  Future<RtcSessionDescription> createOffer([Map mediaConstraints]) {
+    var completer = new Completer<RtcSessionDescription>();
+    _createOffer(mediaConstraints,
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
   @DomName('RTCPeerConnection.dispatchEvent')
   @DocsEditable
@@ -19242,13 +19860,37 @@
   @DocsEditable
   void removeStream(MediaStream stream) native;
 
+  @JSName('setLocalDescription')
   @DomName('RTCPeerConnection.setLocalDescription')
   @DocsEditable
-  void setLocalDescription(RtcSessionDescription description, [VoidCallback successCallback, RtcErrorCallback failureCallback]) native;
+  void _setLocalDescription(RtcSessionDescription description, [VoidCallback successCallback, _RtcErrorCallback failureCallback]) native;
 
+  @JSName('setLocalDescription')
+  @DomName('RTCPeerConnection.setLocalDescription')
+  @DocsEditable
+  Future setLocalDescription(RtcSessionDescription description) {
+    var completer = new Completer();
+    _setLocalDescription(description,
+        () { completer.complete(); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
+
+  @JSName('setRemoteDescription')
   @DomName('RTCPeerConnection.setRemoteDescription')
   @DocsEditable
-  void setRemoteDescription(RtcSessionDescription description, [VoidCallback successCallback, RtcErrorCallback failureCallback]) native;
+  void _setRemoteDescription(RtcSessionDescription description, [VoidCallback successCallback, _RtcErrorCallback failureCallback]) native;
+
+  @JSName('setRemoteDescription')
+  @DomName('RTCPeerConnection.setRemoteDescription')
+  @DocsEditable
+  Future setRemoteDescription(RtcSessionDescription description) {
+    var completer = new Completer();
+    _setRemoteDescription(description,
+        () { completer.complete(); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
   @DomName('RTCPeerConnection.updateIce')
   @DocsEditable
@@ -19453,7 +20095,7 @@
   @DocsEditable
   final String tone;
 }
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -19463,20 +20105,31 @@
 class Screen native "*Screen" {
 
   @DomName('Screen.availHeight')
-  @DocsEditable
-  final int availHeight;
+  @DomName('Screen.availLeft')
+  @DomName('Screen.availTop')
+  @DomName('Screen.availWidth')
+  Rect get available => new Rect($dom_availLeft, $dom_availTop, $dom_availWidth,
+      $dom_availHeight);
 
+  @JSName('availHeight')
+  @DomName('Screen.availHeight')
+  @DocsEditable
+  final int $dom_availHeight;
+
+  @JSName('availLeft')
   @DomName('Screen.availLeft')
   @DocsEditable
-  final int availLeft;
+  final int $dom_availLeft;
 
+  @JSName('availTop')
   @DomName('Screen.availTop')
   @DocsEditable
-  final int availTop;
+  final int $dom_availTop;
 
+  @JSName('availWidth')
   @DomName('Screen.availWidth')
   @DocsEditable
-  final int availWidth;
+  final int $dom_availWidth;
 
   @DomName('Screen.colorDepth')
   @DocsEditable
@@ -19725,7 +20378,7 @@
 
 @DocsEditable
 @DomName('HTMLShadowElement')
-@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@SupportedBrowser(SupportedBrowser.CHROME, '26')
 @Experimental
 class ShadowElement extends Element native "*HTMLShadowElement" {
 
@@ -19748,7 +20401,7 @@
 
 
 @DomName('ShadowRoot')
-@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@SupportedBrowser(SupportedBrowser.CHROME, '26')
 @Experimental
 class ShadowRoot extends DocumentFragment native "*ShadowRoot" {
 
@@ -19778,24 +20431,21 @@
   @DocsEditable
   Element elementFromPoint(int x, int y) native;
 
-  @JSName('getElementById')
   @DomName('ShadowRoot.getElementById')
   @DocsEditable
-  Element $dom_getElementById(String elementId) native;
+  Element getElementById(String elementId) native;
 
-  @JSName('getElementsByClassName')
   @DomName('ShadowRoot.getElementsByClassName')
   @DocsEditable
   @Returns('NodeList')
   @Creates('NodeList')
-  List<Node> $dom_getElementsByClassName(String className) native;
+  List<Node> getElementsByClassName(String className) native;
 
-  @JSName('getElementsByTagName')
   @DomName('ShadowRoot.getElementsByTagName')
   @DocsEditable
   @Returns('NodeList')
   @Creates('NodeList')
-  List<Node> $dom_getElementsByTagName(String tagName) native;
+  List<Node> getElementsByTagName(String tagName) native;
 
   @DomName('ShadowRoot.getSelection')
   @DocsEditable
@@ -19947,16 +20597,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  SourceBuffer firstMatching(bool test(SourceBuffer value), { SourceBuffer orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  SourceBuffer firstWhere(bool test(SourceBuffer value), { SourceBuffer orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  SourceBuffer lastMatching(bool test(SourceBuffer value), {SourceBuffer orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  SourceBuffer lastWhere(bool test(SourceBuffer value), {SourceBuffer orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  SourceBuffer singleMatching(bool test(SourceBuffer value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  SourceBuffer singleWhere(bool test(SourceBuffer value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   SourceBuffer elementAt(int index) {
@@ -20024,6 +20674,10 @@
   SourceBuffer max([int compare(SourceBuffer a, SourceBuffer b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, SourceBuffer element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   SourceBuffer removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -20044,11 +20698,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(SourceBuffer element)) {
+  void removeWhere(bool test(SourceBuffer element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(SourceBuffer element)) {
+  void retainWhere(bool test(SourceBuffer element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -20064,8 +20718,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<SourceBuffer> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <SourceBuffer>[]);
+  }
+
   List<SourceBuffer> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <SourceBuffer>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, SourceBuffer> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<SourceBuffer> mixins.
 
@@ -20229,16 +20891,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  SpeechGrammar firstMatching(bool test(SpeechGrammar value), { SpeechGrammar orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  SpeechGrammar firstWhere(bool test(SpeechGrammar value), { SpeechGrammar orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  SpeechGrammar lastMatching(bool test(SpeechGrammar value), {SpeechGrammar orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  SpeechGrammar lastWhere(bool test(SpeechGrammar value), {SpeechGrammar orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  SpeechGrammar singleMatching(bool test(SpeechGrammar value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  SpeechGrammar singleWhere(bool test(SpeechGrammar value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   SpeechGrammar elementAt(int index) {
@@ -20306,6 +20968,10 @@
   SpeechGrammar max([int compare(SpeechGrammar a, SpeechGrammar b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, SpeechGrammar element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   SpeechGrammar removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -20326,11 +20992,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(SpeechGrammar element)) {
+  void removeWhere(bool test(SpeechGrammar element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(SpeechGrammar element)) {
+  void retainWhere(bool test(SpeechGrammar element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -20346,8 +21012,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<SpeechGrammar> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <SpeechGrammar>[]);
+  }
+
   List<SpeechGrammar> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <SpeechGrammar>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, SpeechGrammar> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<SpeechGrammar> mixins.
 
@@ -20809,13 +21483,37 @@
 
   static const int TEMPORARY = 0;
 
+  @JSName('queryUsageAndQuota')
   @DomName('StorageInfo.queryUsageAndQuota')
   @DocsEditable
-  void queryUsageAndQuota(int storageType, [StorageInfoUsageCallback usageCallback, StorageInfoErrorCallback errorCallback]) native;
+  void _queryUsageAndQuota(int storageType, [_StorageInfoUsageCallback usageCallback, _StorageInfoErrorCallback errorCallback]) native;
 
+  @JSName('queryUsageAndQuota')
+  @DomName('StorageInfo.queryUsageAndQuota')
+  @DocsEditable
+  Future<int> queryUsageAndQuota(int storageType) {
+    var completer = new Completer<int>();
+    _queryUsageAndQuota(storageType,
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
+
+  @JSName('requestQuota')
   @DomName('StorageInfo.requestQuota')
   @DocsEditable
-  void requestQuota(int storageType, int newQuotaInBytes, [StorageInfoQuotaCallback quotaCallback, StorageInfoErrorCallback errorCallback]) native;
+  void _requestQuota(int storageType, int newQuotaInBytes, [StorageInfoQuotaCallback quotaCallback, _StorageInfoErrorCallback errorCallback]) native;
+
+  @JSName('requestQuota')
+  @DomName('StorageInfo.requestQuota')
+  @DocsEditable
+  Future<int> requestQuota(int storageType, int newQuotaInBytes) {
+    var completer = new Completer<int>();
+    _requestQuota(storageType, newQuotaInBytes,
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -20824,7 +21522,7 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void StorageInfoErrorCallback(DomException error);
+typedef void _StorageInfoErrorCallback(DomException error);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -20840,7 +21538,7 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void StorageInfoUsageCallback(int currentUsageInBytes, int currentQuotaInBytes);
+typedef void _StorageInfoUsageCallback(int currentUsageInBytes, int currentQuotaInBytes);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -20848,7 +21546,7 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void StringCallback(String data);
+typedef void _StringCallback(String data);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -21609,16 +22307,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  TextTrackCue firstMatching(bool test(TextTrackCue value), { TextTrackCue orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  TextTrackCue firstWhere(bool test(TextTrackCue value), { TextTrackCue orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  TextTrackCue lastMatching(bool test(TextTrackCue value), {TextTrackCue orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  TextTrackCue lastWhere(bool test(TextTrackCue value), {TextTrackCue orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  TextTrackCue singleMatching(bool test(TextTrackCue value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  TextTrackCue singleWhere(bool test(TextTrackCue value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   TextTrackCue elementAt(int index) {
@@ -21686,6 +22384,10 @@
   TextTrackCue max([int compare(TextTrackCue a, TextTrackCue b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, TextTrackCue element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   TextTrackCue removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -21706,11 +22408,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(TextTrackCue element)) {
+  void removeWhere(bool test(TextTrackCue element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(TextTrackCue element)) {
+  void retainWhere(bool test(TextTrackCue element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -21726,8 +22428,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<TextTrackCue> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <TextTrackCue>[]);
+  }
+
   List<TextTrackCue> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <TextTrackCue>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, TextTrackCue> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<TextTrackCue> mixins.
 
@@ -21816,16 +22526,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  TextTrack firstMatching(bool test(TextTrack value), { TextTrack orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  TextTrack firstWhere(bool test(TextTrack value), { TextTrack orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  TextTrack lastMatching(bool test(TextTrack value), {TextTrack orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  TextTrack lastWhere(bool test(TextTrack value), {TextTrack orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  TextTrack singleMatching(bool test(TextTrack value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  TextTrack singleWhere(bool test(TextTrack value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   TextTrack elementAt(int index) {
@@ -21893,6 +22603,10 @@
   TextTrack max([int compare(TextTrack a, TextTrack b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, TextTrack element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   TextTrack removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -21913,11 +22627,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(TextTrack element)) {
+  void removeWhere(bool test(TextTrack element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(TextTrack element)) {
+  void retainWhere(bool test(TextTrack element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -21933,8 +22647,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<TextTrack> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <TextTrack>[]);
+  }
+
   List<TextTrack> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <TextTrack>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, TextTrack> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<TextTrack> mixins.
 
@@ -22011,33 +22733,39 @@
 @DomName('Touch')
 class Touch native "*Touch" {
 
+  @JSName('clientX')
   @DomName('Touch.clientX')
   @DocsEditable
-  final int clientX;
+  final int $dom_clientX;
 
+  @JSName('clientY')
   @DomName('Touch.clientY')
   @DocsEditable
-  final int clientY;
+  final int $dom_clientY;
 
   @DomName('Touch.identifier')
   @DocsEditable
   final int identifier;
 
+  @JSName('pageX')
   @DomName('Touch.pageX')
   @DocsEditable
-  final int pageX;
+  final int $dom_pageX;
 
+  @JSName('pageY')
   @DomName('Touch.pageY')
   @DocsEditable
-  final int pageY;
+  final int $dom_pageY;
 
+  @JSName('screenX')
   @DomName('Touch.screenX')
   @DocsEditable
-  final int screenX;
+  final int $dom_screenX;
 
+  @JSName('screenY')
   @DomName('Touch.screenY')
   @DocsEditable
-  final int screenY;
+  final int $dom_screenY;
 
   EventTarget get target => _convertNativeToDart_EventTarget(this._get_target);
   @JSName('target')
@@ -22078,6 +22806,19 @@
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental
   final num rotationAngle;
+
+
+  @DomName('Touch.clientX')
+  @DomName('Touch.clientY')
+  Point get client => new Point($dom_clientX, $dom_clientY);
+
+  @DomName('Touch.pageX')
+  @DomName('Touch.pageY')
+  Point get page => new Point($dom_pageX, $dom_pageY);
+
+  @DomName('Touch.screenX')
+  @DomName('Touch.screenY')
+  Point get screen => new Point($dom_screenX, $dom_screenY);
 }
 // 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
@@ -22144,7 +22885,7 @@
    */
   static bool get supported {
     if (JS('bool', '"ontouchstart" in window')) {
-      return Event._isTypeSupported('TouchEvent');
+      return Device.isEventTypeSupported('TouchEvent');
     }
     return false;
   }
@@ -22230,16 +22971,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Touch firstMatching(bool test(Touch value), { Touch orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Touch firstWhere(bool test(Touch value), { Touch orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Touch lastMatching(bool test(Touch value), {Touch orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Touch lastWhere(bool test(Touch value), {Touch orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Touch singleMatching(bool test(Touch value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Touch singleWhere(bool test(Touch value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Touch elementAt(int index) {
@@ -22307,6 +23048,10 @@
   Touch max([int compare(Touch a, Touch b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, Touch element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   Touch removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -22327,11 +23072,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(Touch element)) {
+  void removeWhere(bool test(Touch element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(Touch element)) {
+  void retainWhere(bool test(Touch element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -22347,8 +23092,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<Touch> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <Touch>[]);
+  }
+
   List<Touch> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Touch>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, Touch> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<Touch> mixins.
 
@@ -22544,21 +23297,25 @@
   @DocsEditable
   final int $dom_keyCode;
 
+  @JSName('layerX')
   @DomName('UIEvent.layerX')
   @DocsEditable
-  final int layerX;
+  final int $dom_layerX;
 
+  @JSName('layerY')
   @DomName('UIEvent.layerY')
   @DocsEditable
-  final int layerY;
+  final int $dom_layerY;
 
+  @JSName('pageX')
   @DomName('UIEvent.pageX')
   @DocsEditable
-  final int pageX;
+  final int $dom_pageX;
 
+  @JSName('pageY')
   @DomName('UIEvent.pageY')
   @DocsEditable
-  final int pageY;
+  final int $dom_pageY;
 
   WindowBase get view => _convertNativeToDart_Window(this._get_view);
   @JSName('view')
@@ -22577,6 +23334,24 @@
   @DocsEditable
   void $dom_initUIEvent(String type, bool canBubble, bool cancelable, Window view, int detail) native;
 
+
+  @deprecated
+  int get layerX => layer.x;
+  @deprecated
+  int get layerY => layer.y;
+
+  @deprecated
+  int get pageX => page.x;
+  @deprecated
+  int get pageY => page.y;
+
+  @DomName('UIEvent.layerX')
+  @DomName('UIEvent.layerY')
+  Point get layer => new Point($dom_layerX, $dom_layerY);
+
+  @DomName('UIEvent.pageX')
+  @DomName('UIEvent.pageY')
+  Point get page => new Point($dom_pageX, $dom_pageY);
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -22678,16 +23453,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  int firstMatching(bool test(int value), { int orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  int firstWhere(bool test(int value), { int orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  int lastMatching(bool test(int value), {int orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  int lastWhere(bool test(int value), {int orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  int singleMatching(bool test(int value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  int singleWhere(bool test(int value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   int elementAt(int index) {
@@ -22755,6 +23530,10 @@
   int max([int compare(int a, int b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, int element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -22775,11 +23554,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(int element)) {
+  void removeWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(int element)) {
+  void retainWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -22795,8 +23574,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <int>[]);
+  }
+
   List<int> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <int>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, int> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<int> mixins.
 
@@ -22807,7 +23594,9 @@
 
   @DomName('Uint16Array.subarray')
   @DocsEditable
-  Uint16Array subarray(int start, [int end]) native;
+  @Returns('Uint16Array')
+  @Creates('Uint16Array')
+  List<int> subarray(int start, [int end]) native;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -22896,16 +23685,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  int firstMatching(bool test(int value), { int orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  int firstWhere(bool test(int value), { int orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  int lastMatching(bool test(int value), {int orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  int lastWhere(bool test(int value), {int orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  int singleMatching(bool test(int value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  int singleWhere(bool test(int value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   int elementAt(int index) {
@@ -22973,6 +23762,10 @@
   int max([int compare(int a, int b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, int element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -22993,11 +23786,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(int element)) {
+  void removeWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(int element)) {
+  void retainWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -23013,8 +23806,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <int>[]);
+  }
+
   List<int> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <int>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, int> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<int> mixins.
 
@@ -23025,7 +23826,9 @@
 
   @DomName('Uint32Array.subarray')
   @DocsEditable
-  Uint32Array subarray(int start, [int end]) native;
+  @Returns('Uint32Array')
+  @Creates('Uint32Array')
+  List<int> subarray(int start, [int end]) native;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -23114,16 +23917,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  int firstMatching(bool test(int value), { int orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  int firstWhere(bool test(int value), { int orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  int lastMatching(bool test(int value), {int orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  int lastWhere(bool test(int value), {int orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  int singleMatching(bool test(int value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  int singleWhere(bool test(int value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   int elementAt(int index) {
@@ -23191,6 +23994,10 @@
   int max([int compare(int a, int b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, int element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -23211,11 +24018,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(int element)) {
+  void removeWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(int element)) {
+  void retainWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -23231,8 +24038,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <int>[]);
+  }
+
   List<int> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <int>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, int> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<int> mixins.
 
@@ -23243,7 +24058,9 @@
 
   @DomName('Uint8Array.subarray')
   @DocsEditable
-  Uint8Array subarray(int start, [int end]) native;
+  @Returns('Uint8Array')
+  @Creates('Uint8Array')
+  List<int> subarray(int start, [int end]) native;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -23329,16 +24146,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  int firstMatching(bool test(int value), { int orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  int firstWhere(bool test(int value), { int orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  int lastMatching(bool test(int value), {int orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  int lastWhere(bool test(int value), {int orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  int singleMatching(bool test(int value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  int singleWhere(bool test(int value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   int elementAt(int index) {
@@ -23406,6 +24223,10 @@
   int max([int compare(int a, int b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, int element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -23426,11 +24247,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(int element)) {
+  void removeWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(int element)) {
+  void retainWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -23446,8 +24267,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <int>[]);
+  }
+
   List<int> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <int>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, int> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<int> mixins.
 
@@ -23458,7 +24287,9 @@
 
   @DomName('Uint8ClampedArray.subarray')
   @DocsEditable
-  Uint8ClampedArray subarray(int start, [int end]) native;
+  @Returns('Uint8ClampedArray')
+  @Creates('Uint8ClampedArray')
+  List<int> subarray(int start, [int end]) native;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -23541,9 +24372,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-@DocsEditable
 @DomName('HTMLVideoElement')
-class VideoElement extends MediaElement native "*HTMLVideoElement" {
+class VideoElement extends MediaElement implements CanvasImageSource native "*HTMLVideoElement" {
 
   @DomName('HTMLVideoElement.HTMLVideoElement')
   @DocsEditable
@@ -23632,6 +24462,7 @@
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental
   void exitFullscreen() native;
+
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -24028,6 +24859,8 @@
 
   static const int GREEN_BITS = 0x0D53;
 
+  static const int HALF_FLOAT_OES = 0x8D61;
+
   static const int HIGH_FLOAT = 0x8DF2;
 
   static const int HIGH_INT = 0x8DF5;
@@ -24482,7 +25315,7 @@
 
   @DomName('WebGLRenderingContext.bufferSubData')
   @DocsEditable
-  void bufferSubData(int target, int offset, data) native;
+  void bufferSubData(int target, int offset, /*ArrayBuffer*/ data) native;
 
   @DomName('WebGLRenderingContext.checkFramebufferStatus')
   @DocsEditable
@@ -24514,11 +25347,11 @@
 
   @DomName('WebGLRenderingContext.compressedTexImage2D')
   @DocsEditable
-  void compressedTexImage2D(int target, int level, int internalformat, int width, int height, int border, ArrayBufferView data) native;
+  void compressedTexImage2D(int target, int level, int internalformat, int width, int height, int border, /*ArrayBufferView*/ data) native;
 
   @DomName('WebGLRenderingContext.compressedTexSubImage2D')
   @DocsEditable
-  void compressedTexSubImage2D(int target, int level, int xoffset, int yoffset, int width, int height, int format, ArrayBufferView data) native;
+  void compressedTexSubImage2D(int target, int level, int xoffset, int yoffset, int width, int height, int format, /*ArrayBufferView*/ data) native;
 
   @DomName('WebGLRenderingContext.copyTexImage2D')
   @DocsEditable
@@ -24792,7 +25625,7 @@
 
   @DomName('WebGLRenderingContext.readPixels')
   @DocsEditable
-  void readPixels(int x, int y, int width, int height, int format, int type, ArrayBufferView pixels) native;
+  void readPixels(int x, int y, int width, int height, int format, int type, /*ArrayBufferView*/ pixels) native;
 
   @DomName('WebGLRenderingContext.releaseShaderCompiler')
   @DocsEditable
@@ -24840,8 +25673,8 @@
 
   @DomName('WebGLRenderingContext.texImage2D')
   @DocsEditable
-  void texImage2D(int target, int level, int internalformat, int format_OR_width, int height_OR_type, border_OR_canvas_OR_image_OR_pixels_OR_video, [int format, int type, ArrayBufferView pixels]) {
-    if ((border_OR_canvas_OR_image_OR_pixels_OR_video is int || border_OR_canvas_OR_image_OR_pixels_OR_video == null)) {
+  void texImage2D(int target, int level, int internalformat, int format_OR_width, int height_OR_type, border_OR_canvas_OR_image_OR_pixels_OR_video, [int format, int type, /*ArrayBufferView*/ pixels]) {
+    if ((border_OR_canvas_OR_image_OR_pixels_OR_video is int || border_OR_canvas_OR_image_OR_pixels_OR_video == null) && ?pixels) {
       _texImage2D_1(target, level, internalformat, format_OR_width, height_OR_type, border_OR_canvas_OR_image_OR_pixels_OR_video, format, type, pixels);
       return;
     }
@@ -24867,7 +25700,7 @@
   @JSName('texImage2D')
   @DomName('WebGLRenderingContext.texImage2D')
   @DocsEditable
-  void _texImage2D_1(target, level, internalformat, width, height, int border, format, type, ArrayBufferView pixels) native;
+  void _texImage2D_1(target, level, internalformat, width, height, int border, format, type, pixels) native;
   @JSName('texImage2D')
   @DomName('WebGLRenderingContext.texImage2D')
   @DocsEditable
@@ -24895,8 +25728,8 @@
 
   @DomName('WebGLRenderingContext.texSubImage2D')
   @DocsEditable
-  void texSubImage2D(int target, int level, int xoffset, int yoffset, int format_OR_width, int height_OR_type, canvas_OR_format_OR_image_OR_pixels_OR_video, [int type, ArrayBufferView pixels]) {
-    if ((canvas_OR_format_OR_image_OR_pixels_OR_video is int || canvas_OR_format_OR_image_OR_pixels_OR_video == null)) {
+  void texSubImage2D(int target, int level, int xoffset, int yoffset, int format_OR_width, int height_OR_type, canvas_OR_format_OR_image_OR_pixels_OR_video, [int type, /*ArrayBufferView*/ pixels]) {
+    if ((canvas_OR_format_OR_image_OR_pixels_OR_video is int || canvas_OR_format_OR_image_OR_pixels_OR_video == null) && ?pixels) {
       _texSubImage2D_1(target, level, xoffset, yoffset, format_OR_width, height_OR_type, canvas_OR_format_OR_image_OR_pixels_OR_video, type, pixels);
       return;
     }
@@ -24922,7 +25755,7 @@
   @JSName('texSubImage2D')
   @DomName('WebGLRenderingContext.texSubImage2D')
   @DocsEditable
-  void _texSubImage2D_1(target, level, xoffset, yoffset, width, height, int format, type, ArrayBufferView pixels) native;
+  void _texSubImage2D_1(target, level, xoffset, yoffset, width, height, int format, type, pixels) native;
   @JSName('texSubImage2D')
   @DomName('WebGLRenderingContext.texSubImage2D')
   @DocsEditable
@@ -25411,7 +26244,7 @@
       view = window;
     }
     var eventType = 'WheelEvent';
-    if (_Device.isFirefox) {
+    if (Device.isFirefox) {
       eventType = 'MouseScrollEvents';
     }
     final event = document.$dom_createEvent(eventType);
@@ -25657,8 +26490,10 @@
    * [animationFrame] again for the animation to continue.
    */
   Future<num> get animationFrame {
-    var completer = new Completer<int>();
-    requestAnimationFrame(completer.complete);
+    var completer = new Completer<num>();
+    requestAnimationFrame((time) {
+      completer.complete(time);
+    });
     return completer.future;
   }
 
@@ -26238,12 +27073,12 @@
   @JSName('setInterval')
   @DomName('DOMWindow.setInterval')
   @DocsEditable
-  int _setInterval(TimeoutHandler handler, int timeout) native;
+  int _setInterval(Object handler, int timeout) native;
 
   @JSName('setTimeout')
   @DomName('DOMWindow.setTimeout')
   @DocsEditable
-  int _setTimeout(TimeoutHandler handler, int timeout) native;
+  int _setTimeout(Object handler, int timeout) native;
 
   @DomName('DOMWindow.showModalDialog')
   @DocsEditable
@@ -26274,14 +27109,40 @@
   @DocsEditable
   @SupportedBrowser(SupportedBrowser.CHROME)
   @Experimental
-  void requestFileSystem(int type, int size, FileSystemCallback successCallback, [ErrorCallback errorCallback]) native;
+  void _requestFileSystem(int type, int size, _FileSystemCallback successCallback, [_ErrorCallback errorCallback]) native;
+
+  @JSName('webkitRequestFileSystem')
+  @DomName('DOMWindow.webkitRequestFileSystem')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @Experimental
+  Future<FileSystem> requestFileSystem(int type, int size) {
+    var completer = new Completer<FileSystem>();
+    _requestFileSystem(type, size,
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
   @JSName('webkitResolveLocalFileSystemURL')
   @DomName('DOMWindow.webkitResolveLocalFileSystemURL')
   @DocsEditable
   @SupportedBrowser(SupportedBrowser.CHROME)
   @Experimental
-  void resolveLocalFileSystemUrl(String url, EntryCallback successCallback, [ErrorCallback errorCallback]) native;
+  void _resolveLocalFileSystemUrl(String url, _EntryCallback successCallback, [_ErrorCallback errorCallback]) native;
+
+  @JSName('webkitResolveLocalFileSystemURL')
+  @DomName('DOMWindow.webkitResolveLocalFileSystemURL')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @Experimental
+  Future<Entry> resolveLocalFileSystemUrl(String url) {
+    var completer = new Completer<Entry>();
+    _resolveLocalFileSystemUrl(url,
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
   @DomName('DOMWindow.onDOMContentLoaded')
   @DocsEditable
@@ -26631,18 +27492,31 @@
 
   @DomName('WorkerContext.setInterval')
   @DocsEditable
-  int setInterval(TimeoutHandler handler, int timeout) native;
+  int setInterval(Object handler, int timeout) native;
 
   @DomName('WorkerContext.setTimeout')
   @DocsEditable
-  int setTimeout(TimeoutHandler handler, int timeout) native;
+  int setTimeout(Object handler, int timeout) native;
 
   @JSName('webkitRequestFileSystem')
   @DomName('WorkerContext.webkitRequestFileSystem')
   @DocsEditable
   @SupportedBrowser(SupportedBrowser.CHROME)
   @Experimental
-  void requestFileSystem(int type, int size, [FileSystemCallback successCallback, ErrorCallback errorCallback]) native;
+  void _requestFileSystem(int type, int size, [_FileSystemCallback successCallback, _ErrorCallback errorCallback]) native;
+
+  @JSName('webkitRequestFileSystem')
+  @DomName('WorkerContext.webkitRequestFileSystem')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @Experimental
+  Future<FileSystem> requestFileSystem(int type, int size) {
+    var completer = new Completer<FileSystem>();
+    _requestFileSystem(type, size,
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
   @JSName('webkitRequestFileSystemSync')
   @DomName('WorkerContext.webkitRequestFileSystemSync')
@@ -26663,7 +27537,20 @@
   @DocsEditable
   @SupportedBrowser(SupportedBrowser.CHROME)
   @Experimental
-  void resolveLocalFileSystemUrl(String url, EntryCallback successCallback, [ErrorCallback errorCallback]) native;
+  void _resolveLocalFileSystemUrl(String url, _EntryCallback successCallback, [_ErrorCallback errorCallback]) native;
+
+  @JSName('webkitResolveLocalFileSystemURL')
+  @DomName('WorkerContext.webkitResolveLocalFileSystemURL')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @Experimental
+  Future<Entry> resolveLocalFileSystemUrl(String url) {
+    var completer = new Completer<Entry>();
+    _resolveLocalFileSystemUrl(url,
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
   @DomName('WorkerContext.onerror')
   @DocsEditable
@@ -26982,6 +27869,131 @@
   @DocsEditable
   DocumentFragment transformToFragment(Node source, Document docVal) native;
 }
+// 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.
+
+
+@DocsEditable
+@DomName('ClientRect')
+class _ClientRect implements Rect native "*ClientRect" {
+
+  // NOTE! All code below should be common with Rect.
+  // TODO(blois): implement with mixins when available.
+
+  String toString() {
+    return '($left, $top, $width, $height)';
+  }
+
+  bool operator ==(other) {
+    if (other is !Rect) return false;
+    return left == other.left && top == other.top && width == other.width &&
+        height == other.height;
+  }
+
+  /**
+   * Computes the intersection of this rectangle and the rectangle parameter.
+   * Returns null if there is no intersection.
+   */
+  Rect intersection(Rect rect) {
+    var x0 = max(left, rect.left);
+    var x1 = min(left + width, rect.left + rect.width);
+
+    if (x0 <= x1) {
+      var y0 = max(top, rect.top);
+      var y1 = min(top + height, rect.top + rect.height);
+
+      if (y0 <= y1) {
+        return new Rect(x0, y0, x1 - x0, y1 - y0);
+      }
+    }
+    return null;
+  }
+
+
+  /**
+   * Returns whether a rectangle intersects this rectangle.
+   */
+  bool intersects(Rect other) {
+    return (left <= other.left + other.width && other.left <= left + width &&
+        top <= other.top + other.height && other.top <= top + height);
+  }
+
+  /**
+   * Returns a new rectangle which completely contains this rectangle and the
+   * input rectangle.
+   */
+  Rect union(Rect rect) {
+    var right = max(this.left + this.width, rect.left + rect.width);
+    var bottom = max(this.top + this.height, rect.top + rect.height);
+
+    var left = min(this.left, rect.left);
+    var top = min(this.top, rect.top);
+
+    return new Rect(left, top, right - left, bottom - top);
+  }
+
+  /**
+   * Tests whether this rectangle entirely contains another rectangle.
+   */
+  bool containsRect(Rect another) {
+    return left <= another.left &&
+           left + width >= another.left + another.width &&
+           top <= another.top &&
+           top + height >= another.top + another.height;
+  }
+
+  /**
+   * Tests whether this rectangle entirely contains a point.
+   */
+  bool containsPoint(Point another) {
+    return another.x >= left &&
+           another.x <= left + width &&
+           another.y >= top &&
+           another.y <= top + height;
+  }
+
+  Rect ceil() => new Rect(left.ceil(), top.ceil(), width.ceil(), height.ceil());
+  Rect floor() => new Rect(left.floor(), top.floor(), width.floor(),
+      height.floor());
+  Rect round() => new Rect(left.round(), top.round(), width.round(),
+      height.round());
+
+  /**
+   * Truncates coordinates to integers and returns the result as a new
+   * rectangle.
+   */
+  Rect toInt() => new Rect(left.toInt(), top.toInt(), width.toInt(),
+      height.toInt());
+
+  Point get topLeft => new Point(this.left, this.top);
+  Point get bottomRight => new Point(this.left + this.width,
+      this.top + this.height);
+
+  @DomName('ClientRect.bottom')
+  @DocsEditable
+  final num bottom;
+
+  @DomName('ClientRect.height')
+  @DocsEditable
+  final num height;
+
+  @DomName('ClientRect.left')
+  @DocsEditable
+  final num left;
+
+  @DomName('ClientRect.right')
+  @DocsEditable
+  final num right;
+
+  @DomName('ClientRect.top')
+  @DocsEditable
+  final num top;
+
+  @DomName('ClientRect.width')
+  @DocsEditable
+  final num width;
+}
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -26989,103 +28001,103 @@
 
 @DocsEditable
 @DomName('ClientRectList')
-class _ClientRectList implements JavaScriptIndexingBehavior, List<ClientRect> native "*ClientRectList" {
+class _ClientRectList implements JavaScriptIndexingBehavior, List<Rect> native "*ClientRectList" {
 
   @DomName('ClientRectList.length')
   @DocsEditable
   int get length => JS("int", "#.length", this);
 
-  ClientRect operator[](int index) => JS("ClientRect", "#[#]", this, index);
+  Rect operator[](int index) => JS("Rect", "#[#]", this, index);
 
-  void operator[]=(int index, ClientRect value) {
+  void operator[]=(int index, Rect value) {
     throw new UnsupportedError("Cannot assign element of immutable List.");
   }
-  // -- start List<ClientRect> mixins.
-  // ClientRect is the element type.
+  // -- start List<Rect> mixins.
+  // Rect is the element type.
 
-  // From Iterable<ClientRect>:
+  // From Iterable<Rect>:
 
-  Iterator<ClientRect> get iterator {
+  Iterator<Rect> get iterator {
     // Note: NodeLists are not fixed size. And most probably length shouldn't
     // be cached in both iterator _and_ forEach method. For now caching it
     // for consistency.
-    return new FixedSizeListIterator<ClientRect>(this);
+    return new FixedSizeListIterator<Rect>(this);
   }
 
-  dynamic reduce(dynamic initialValue, dynamic combine(dynamic, ClientRect)) {
+  dynamic reduce(dynamic initialValue, dynamic combine(dynamic, Rect)) {
     return IterableMixinWorkaround.reduce(this, initialValue, combine);
   }
 
-  bool contains(ClientRect element) => IterableMixinWorkaround.contains(this, element);
+  bool contains(Rect element) => IterableMixinWorkaround.contains(this, element);
 
-  void forEach(void f(ClientRect element)) => IterableMixinWorkaround.forEach(this, f);
+  void forEach(void f(Rect element)) => IterableMixinWorkaround.forEach(this, f);
 
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  Iterable map(f(ClientRect element)) =>
+  Iterable map(f(Rect element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  Iterable<ClientRect> where(bool f(ClientRect element)) =>
+  Iterable<Rect> where(bool f(Rect element)) =>
       IterableMixinWorkaround.where(this, f);
 
-  Iterable expand(Iterable f(ClientRect element)) =>
+  Iterable expand(Iterable f(Rect element)) =>
       IterableMixinWorkaround.expand(this, f);
 
-  bool every(bool f(ClientRect element)) => IterableMixinWorkaround.every(this, f);
+  bool every(bool f(Rect element)) => IterableMixinWorkaround.every(this, f);
 
-  bool any(bool f(ClientRect element)) => IterableMixinWorkaround.any(this, f);
+  bool any(bool f(Rect element)) => IterableMixinWorkaround.any(this, f);
 
-  List<ClientRect> toList({ bool growable: true }) =>
-      new List<ClientRect>.from(this, growable: growable);
+  List<Rect> toList({ bool growable: true }) =>
+      new List<Rect>.from(this, growable: growable);
 
-  Set<ClientRect> toSet() => new Set<ClientRect>.from(this);
+  Set<Rect> toSet() => new Set<Rect>.from(this);
 
   bool get isEmpty => this.length == 0;
 
-  Iterable<ClientRect> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<Rect> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
-  Iterable<ClientRect> takeWhile(bool test(ClientRect value)) {
+  Iterable<Rect> takeWhile(bool test(Rect value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  Iterable<ClientRect> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<Rect> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
-  Iterable<ClientRect> skipWhile(bool test(ClientRect value)) {
+  Iterable<Rect> skipWhile(bool test(Rect value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  ClientRect firstMatching(bool test(ClientRect value), { ClientRect orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Rect firstWhere(bool test(Rect value), { Rect orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  ClientRect lastMatching(bool test(ClientRect value), {ClientRect orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Rect lastWhere(bool test(Rect value), {Rect orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  ClientRect singleMatching(bool test(ClientRect value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Rect singleWhere(bool test(Rect value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
-  ClientRect elementAt(int index) {
+  Rect elementAt(int index) {
     return this[index];
   }
 
-  // From Collection<ClientRect>:
+  // From Collection<Rect>:
 
-  void add(ClientRect value) {
+  void add(Rect value) {
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
-  void addLast(ClientRect value) {
+  void addLast(Rect value) {
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
-  void addAll(Iterable<ClientRect> iterable) {
+  void addAll(Iterable<Rect> iterable) {
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
-  // From List<ClientRect>:
+  // From List<Rect>:
   void set length(int value) {
     throw new UnsupportedError("Cannot resize immutable List.");
   }
@@ -27094,49 +28106,53 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  Iterable<ClientRect> get reversed {
+  Iterable<Rect> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
-  void sort([int compare(ClientRect a, ClientRect b)]) {
+  void sort([int compare(Rect a, Rect b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
   }
 
-  int indexOf(ClientRect element, [int start = 0]) =>
+  int indexOf(Rect element, [int start = 0]) =>
       Lists.indexOf(this, element, start, this.length);
 
-  int lastIndexOf(ClientRect element, [int start]) {
+  int lastIndexOf(Rect element, [int start]) {
     if (start == null) start = length - 1;
     return Lists.lastIndexOf(this, element, start);
   }
 
-  ClientRect get first {
+  Rect get first {
     if (this.length > 0) return this[0];
     throw new StateError("No elements");
   }
 
-  ClientRect get last {
+  Rect get last {
     if (this.length > 0) return this[this.length - 1];
     throw new StateError("No elements");
   }
 
-  ClientRect get single {
+  Rect get single {
     if (length == 1) return this[0];
     if (length == 0) throw new StateError("No elements");
     throw new StateError("More than one element");
   }
 
-  ClientRect min([int compare(ClientRect a, ClientRect b)]) =>
+  Rect min([int compare(Rect a, Rect b)]) =>
       IterableMixinWorkaround.min(this, compare);
 
-  ClientRect max([int compare(ClientRect a, ClientRect b)]) =>
+  Rect max([int compare(Rect a, Rect b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
-  ClientRect removeAt(int pos) {
+  void insert(int index, Rect element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  Rect removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  ClientRect removeLast() {
+  Rect removeLast() {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -27152,15 +28168,15 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(ClientRect element)) {
+  void removeWhere(bool test(Rect element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(ClientRect element)) {
+  void retainWhere(bool test(Rect element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<ClientRect> from, [int startFrom]) {
+  void setRange(int start, int rangeLength, List<Rect> from, [int startFrom]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
@@ -27168,18 +28184,26 @@
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [ClientRect initialValue]) {
+  void insertRange(int start, int rangeLength, [Rect initialValue]) {
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
-  List<ClientRect> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <ClientRect>[]);
+  List<Rect> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <Rect>[]);
+  }
 
-  // -- end List<ClientRect> mixins.
+  List<Rect> getRange(int start, int rangeLength) =>
+      sublist(start, start + rangeLength);
+
+  Map<int, Rect> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
+
+  // -- end List<Rect> mixins.
 
   @DomName('ClientRectList.item')
   @DocsEditable
-  ClientRect item(int index) native;
+  Rect item(int index) native;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -27254,16 +28278,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  CssRule firstMatching(bool test(CssRule value), { CssRule orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  CssRule firstWhere(bool test(CssRule value), { CssRule orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  CssRule lastMatching(bool test(CssRule value), {CssRule orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  CssRule lastWhere(bool test(CssRule value), {CssRule orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  CssRule singleMatching(bool test(CssRule value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  CssRule singleWhere(bool test(CssRule value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   CssRule elementAt(int index) {
@@ -27331,6 +28355,10 @@
   CssRule max([int compare(CssRule a, CssRule b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, CssRule element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   CssRule removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -27351,11 +28379,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(CssRule element)) {
+  void removeWhere(bool test(CssRule element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(CssRule element)) {
+  void retainWhere(bool test(CssRule element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -27371,8 +28399,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<CssRule> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <CssRule>[]);
+  }
+
   List<CssRule> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <CssRule>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, CssRule> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<CssRule> mixins.
 
@@ -27453,16 +28489,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  CssValue firstMatching(bool test(CssValue value), { CssValue orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  CssValue firstWhere(bool test(CssValue value), { CssValue orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  CssValue lastMatching(bool test(CssValue value), {CssValue orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  CssValue lastWhere(bool test(CssValue value), {CssValue orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  CssValue singleMatching(bool test(CssValue value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  CssValue singleWhere(bool test(CssValue value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   CssValue elementAt(int index) {
@@ -27530,6 +28566,10 @@
   CssValue max([int compare(CssValue a, CssValue b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, CssValue element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   CssValue removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -27550,11 +28590,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(CssValue element)) {
+  void removeWhere(bool test(CssValue element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(CssValue element)) {
+  void retainWhere(bool test(CssValue element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -27570,8 +28610,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<CssValue> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <CssValue>[]);
+  }
+
   List<CssValue> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <CssValue>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, CssValue> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<CssValue> mixins.
 
@@ -27652,16 +28700,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Entry firstMatching(bool test(Entry value), { Entry orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Entry firstWhere(bool test(Entry value), { Entry orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Entry lastMatching(bool test(Entry value), {Entry orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Entry lastWhere(bool test(Entry value), {Entry orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Entry singleMatching(bool test(Entry value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Entry singleWhere(bool test(Entry value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Entry elementAt(int index) {
@@ -27729,6 +28777,10 @@
   Entry max([int compare(Entry a, Entry b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, Entry element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   Entry removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -27749,11 +28801,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(Entry element)) {
+  void removeWhere(bool test(Entry element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(Entry element)) {
+  void retainWhere(bool test(Entry element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -27769,8 +28821,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<Entry> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <Entry>[]);
+  }
+
   List<Entry> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Entry>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, Entry> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<Entry> mixins.
 
@@ -27851,16 +28911,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  EntrySync firstMatching(bool test(EntrySync value), { EntrySync orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  EntrySync firstWhere(bool test(EntrySync value), { EntrySync orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  EntrySync lastMatching(bool test(EntrySync value), {EntrySync orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  EntrySync lastWhere(bool test(EntrySync value), {EntrySync orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  EntrySync singleMatching(bool test(EntrySync value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  EntrySync singleWhere(bool test(EntrySync value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   EntrySync elementAt(int index) {
@@ -27928,6 +28988,10 @@
   EntrySync max([int compare(EntrySync a, EntrySync b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, EntrySync element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   EntrySync removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -27948,11 +29012,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(EntrySync element)) {
+  void removeWhere(bool test(EntrySync element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(EntrySync element)) {
+  void retainWhere(bool test(EntrySync element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -27968,8 +29032,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<EntrySync> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <EntrySync>[]);
+  }
+
   List<EntrySync> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <EntrySync>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, EntrySync> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<EntrySync> mixins.
 
@@ -28050,16 +29122,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Gamepad firstMatching(bool test(Gamepad value), { Gamepad orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Gamepad firstWhere(bool test(Gamepad value), { Gamepad orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Gamepad lastMatching(bool test(Gamepad value), {Gamepad orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Gamepad lastWhere(bool test(Gamepad value), {Gamepad orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Gamepad singleMatching(bool test(Gamepad value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Gamepad singleWhere(bool test(Gamepad value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Gamepad elementAt(int index) {
@@ -28127,6 +29199,10 @@
   Gamepad max([int compare(Gamepad a, Gamepad b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, Gamepad element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   Gamepad removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -28147,11 +29223,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(Gamepad element)) {
+  void removeWhere(bool test(Gamepad element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(Gamepad element)) {
+  void retainWhere(bool test(Gamepad element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -28167,8 +29243,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<Gamepad> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <Gamepad>[]);
+  }
+
   List<Gamepad> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Gamepad>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, Gamepad> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<Gamepad> mixins.
 
@@ -28312,16 +29396,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Node firstMatching(bool test(Node value), { Node orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Node firstWhere(bool test(Node value), { Node orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Node lastMatching(bool test(Node value), {Node orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Node lastWhere(bool test(Node value), {Node orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Node singleMatching(bool test(Node value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Node singleWhere(bool test(Node value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Node elementAt(int index) {
@@ -28389,6 +29473,10 @@
   Node max([int compare(Node a, Node b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, Node element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   Node removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -28409,11 +29497,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(Node element)) {
+  void removeWhere(bool test(Node element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(Node element)) {
+  void retainWhere(bool test(Node element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -28429,8 +29517,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<Node> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <Node>[]);
+  }
+
   List<Node> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Node>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, Node> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<Node> mixins.
 
@@ -28535,16 +29631,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  SpeechInputResult firstMatching(bool test(SpeechInputResult value), { SpeechInputResult orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  SpeechInputResult firstWhere(bool test(SpeechInputResult value), { SpeechInputResult orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  SpeechInputResult lastMatching(bool test(SpeechInputResult value), {SpeechInputResult orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  SpeechInputResult lastWhere(bool test(SpeechInputResult value), {SpeechInputResult orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  SpeechInputResult singleMatching(bool test(SpeechInputResult value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  SpeechInputResult singleWhere(bool test(SpeechInputResult value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   SpeechInputResult elementAt(int index) {
@@ -28612,6 +29708,10 @@
   SpeechInputResult max([int compare(SpeechInputResult a, SpeechInputResult b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, SpeechInputResult element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   SpeechInputResult removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -28632,11 +29732,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(SpeechInputResult element)) {
+  void removeWhere(bool test(SpeechInputResult element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(SpeechInputResult element)) {
+  void retainWhere(bool test(SpeechInputResult element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -28652,8 +29752,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<SpeechInputResult> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <SpeechInputResult>[]);
+  }
+
   List<SpeechInputResult> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <SpeechInputResult>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, SpeechInputResult> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<SpeechInputResult> mixins.
 
@@ -28734,16 +29842,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  SpeechRecognitionResult firstMatching(bool test(SpeechRecognitionResult value), { SpeechRecognitionResult orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  SpeechRecognitionResult firstWhere(bool test(SpeechRecognitionResult value), { SpeechRecognitionResult orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  SpeechRecognitionResult lastMatching(bool test(SpeechRecognitionResult value), {SpeechRecognitionResult orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  SpeechRecognitionResult lastWhere(bool test(SpeechRecognitionResult value), {SpeechRecognitionResult orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  SpeechRecognitionResult singleMatching(bool test(SpeechRecognitionResult value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  SpeechRecognitionResult singleWhere(bool test(SpeechRecognitionResult value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   SpeechRecognitionResult elementAt(int index) {
@@ -28811,6 +29919,10 @@
   SpeechRecognitionResult max([int compare(SpeechRecognitionResult a, SpeechRecognitionResult b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, SpeechRecognitionResult element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   SpeechRecognitionResult removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -28831,11 +29943,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(SpeechRecognitionResult element)) {
+  void removeWhere(bool test(SpeechRecognitionResult element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(SpeechRecognitionResult element)) {
+  void retainWhere(bool test(SpeechRecognitionResult element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -28851,8 +29963,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<SpeechRecognitionResult> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <SpeechRecognitionResult>[]);
+  }
+
   List<SpeechRecognitionResult> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <SpeechRecognitionResult>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, SpeechRecognitionResult> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<SpeechRecognitionResult> mixins.
 
@@ -28933,16 +30053,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  StyleSheet firstMatching(bool test(StyleSheet value), { StyleSheet orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  StyleSheet firstWhere(bool test(StyleSheet value), { StyleSheet orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  StyleSheet lastMatching(bool test(StyleSheet value), {StyleSheet orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  StyleSheet lastWhere(bool test(StyleSheet value), {StyleSheet orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  StyleSheet singleMatching(bool test(StyleSheet value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  StyleSheet singleWhere(bool test(StyleSheet value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   StyleSheet elementAt(int index) {
@@ -29010,6 +30130,10 @@
   StyleSheet max([int compare(StyleSheet a, StyleSheet b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, StyleSheet element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   StyleSheet removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -29030,11 +30154,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(StyleSheet element)) {
+  void removeWhere(bool test(StyleSheet element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(StyleSheet element)) {
+  void retainWhere(bool test(StyleSheet element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -29050,8 +30174,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<StyleSheet> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <StyleSheet>[]);
+  }
+
   List<StyleSheet> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <StyleSheet>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, StyleSheet> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<StyleSheet> mixins.
 
@@ -29309,6 +30441,32 @@
 
 
 /**
+ * An object that can be drawn to a [CanvasRenderingContext2D] object with
+ * [CanvasRenderingContext2D.drawImage] or
+ * [CanvasRenderingContext2D.drawImageAtScale].
+ *
+ * If the CanvasImageSource is an [ImageElement] then the element's image is
+ * used. If the [ImageElement] is an animated image, then the poster frame is
+ * used. If there is no poster frame, then the first frame of animation is used.
+ *
+ * If the CanvasImageSource is a [VideoElement] then the frame at the current
+ * playback position is used as the image.
+ *
+ * If the CanvasImageSource is a [CanvasElement] then the element's bitmap is
+ * used.
+ *
+ * See also:
+ *
+ *  * [CanvasImageSource](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-sources-for-2d-rendering-contexts)
+ * from the WHATWG.
+ */
+abstract class CanvasImageSource {}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+/**
  * An object representing the top-level context object for web scripting.
  *
  * In a web browser, a [Window] object represents the actual browser window.
@@ -29480,7 +30638,7 @@
 
   Iterable<String> where(bool f(String element)) => readClasses().where(f);
 
-  Iterable expand(Iterable f(String element)) => readClasses.expand(f);
+  Iterable expand(Iterable f(String element)) => readClasses().expand(f);
 
   bool every(bool f(String element)) => readClasses().every(f);
 
@@ -29526,23 +30684,29 @@
     _modify((s) => s.retainAll(iterable));
   }
 
-  void removeMatching(bool test(String name)) {
-    _modify((s) => s.removeMatching(test));
+  void removeWhere(bool test(String name)) {
+    _modify((s) => s.removeWhere(test));
   }
 
-  void retainMatching(bool test(String name)) {
-    _modify((s) => s.retainMatching(test));
+  void retainWhere(bool test(String name)) {
+    _modify((s) => s.retainWhere(test));
   }
 
   bool isSubsetOf(Collection<String> collection) =>
     readClasses().isSubsetOf(collection);
 
-  bool containsAll(Collection<String> collection) =>
+  bool containsAll(Iterable<String> collection) =>
     readClasses().containsAll(collection);
 
-  Set<String> intersection(Collection<String> other) =>
+  Set<String> intersection(Set<String> other) =>
     readClasses().intersection(other);
 
+  Set<String> union(Set<String> other) =>
+    readClasses().union(other);
+
+  Set<String> difference(Set<String> other) =>
+    readClasses().difference(other);
+
   String get first => readClasses().first;
   String get last => readClasses().last;
   String get single => readClasses().single;
@@ -29559,12 +30723,12 @@
   Iterable<String> skip(int n) => readClasses().skip(n);
   Iterable<String> skipWhile(bool test(String value)) =>
       readClasses().skipWhile(test);
-  String firstMatching(bool test(String value), { String orElse() }) =>
-      readClasses().firstMatching(test, orElse: orElse);
-  String lastMatching(bool test(String value), {String orElse()}) =>
-      readClasses().lastMatching(test, orElse: orElse);
-  String singleMatching(bool test(String value)) =>
-      readClasses().singleMatching(test);
+  String firstWhere(bool test(String value), { String orElse() }) =>
+      readClasses().firstWhere(test, orElse: orElse);
+  String lastWhere(bool test(String value), {String orElse()}) =>
+      readClasses().lastWhere(test, orElse: orElse);
+  String singleWhere(bool test(String value)) =>
+      readClasses().singleWhere(test);
   String elementAt(int index) => readClasses().elementAt(index);
 
   void clear() {
@@ -29606,42 +30770,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-/**
- * Utils for device detection.
- */
-class _Device {
-  /**
-   * Gets the browser's user agent. Using this function allows tests to inject
-   * the user agent.
-   * Returns the user agent.
-   */
-  static String get userAgent => window.navigator.userAgent;
-
-  /**
-   * Determines if the current device is running Opera.
-   */
-  static bool get isOpera => userAgent.contains("Opera", 0);
-
-  /**
-   * Determines if the current device is running Internet Explorer.
-   */
-  static bool get isIE => !isOpera && userAgent.contains("MSIE", 0);
-
-  /**
-   * Determines if the current device is running Firefox.
-   */
-  static bool get isFirefox => userAgent.contains("Firefox", 0);
-
-  /**
-   * Determines if the current device is running WebKit.
-   */
-  static bool get isWebKit => !isOpera && userAgent.contains("WebKit", 0);
-}
-// 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.
-
-
 typedef void EventListener(Event event);
 // 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
@@ -30070,11 +31198,11 @@
    * Returns true if the key fires a keypress event in the current browser.
    */
   bool _firesKeyPressEvent(KeyEvent event) {
-    if (!_Device.isIE && !_Device.isWebKit) {
+    if (!Device.isIE && !Device.isWebKit) {
       return true;
     }
 
-    if (_Device.userAgent.contains('Mac') && event.altKey) {
+    if (Device.userAgent.contains('Mac') && event.altKey) {
       return KeyCode.isCharacterKey(event.keyCode);
     }
 
@@ -30087,13 +31215,13 @@
     if (!event.shiftKey &&
         (_keyDownList.last.keyCode == KeyCode.CTRL ||
          _keyDownList.last.keyCode == KeyCode.ALT ||
-         _Device.userAgent.contains('Mac') &&
+         Device.userAgent.contains('Mac') &&
          _keyDownList.last.keyCode == KeyCode.META)) {
       return false;
     }
 
     // Some keys with Ctrl/Shift do not issue keypress in WebKit.
-    if (_Device.isWebKit && event.ctrlKey && event.shiftKey && (
+    if (Device.isWebKit && event.ctrlKey && event.shiftKey && (
         event.keyCode == KeyCode.BACKSLASH ||
         event.keyCode == KeyCode.OPEN_SQUARE_BRACKET ||
         event.keyCode == KeyCode.CLOSE_SQUARE_BRACKET ||
@@ -30109,9 +31237,9 @@
     switch (event.keyCode) {
       case KeyCode.ENTER:
         // IE9 does not fire keypress on ENTER.
-        return !_Device.isIE;
+        return !Device.isIE;
       case KeyCode.ESC:
-        return !_Device.isWebKit;
+        return !Device.isWebKit;
     }
 
     return KeyCode.isCharacterKey(event.keyCode);
@@ -30123,7 +31251,7 @@
    */
   int _normalizeKeyCodes(KeyboardEvent event) {
     // Note: This may change once we get input about non-US keyboards.
-    if (_Device.isFirefox) {
+    if (Device.isFirefox) {
       switch(event.keyCode) {
         case KeyCode.FF_EQUALS:
           return KeyCode.EQUALS;
@@ -30146,7 +31274,7 @@
     if (_keyDownList.length > 0 &&
         (_keyDownList.last.keyCode == KeyCode.CTRL && !e.ctrlKey ||
          _keyDownList.last.keyCode == KeyCode.ALT && !e.altKey ||
-         _Device.userAgent.contains('Mac') &&
+         Device.userAgent.contains('Mac') &&
          _keyDownList.last.keyCode == KeyCode.META && !e.metaKey)) {
       _keyDownList = [];
     }
@@ -30173,13 +31301,13 @@
     var e = new KeyEvent(event);
     // IE reports the character code in the keyCode field for keypress events.
     // There are two exceptions however, Enter and Escape.
-    if (_Device.isIE) {
+    if (Device.isIE) {
       if (e.keyCode == KeyCode.ENTER || e.keyCode == KeyCode.ESC) {
         e._shadowCharCode = 0;
       } else {
         e._shadowCharCode = e.keyCode;
       }
-    } else if (_Device.isOpera) {
+    } else if (Device.isOpera) {
       // Opera reports the character code in the keyCode field.
       e._shadowCharCode = KeyCode.isCharacterKey(e.keyCode) ? e.keyCode : 0;
     }
@@ -30225,9 +31353,9 @@
 
 
 /**
- * Defines the keycode values for keys that are returned by 
+ * Defines the keycode values for keys that are returned by
  * KeyboardEvent.keyCode.
- * 
+ *
  * Important note: There is substantial divergence in how different browsers
  * handle keycodes and their variants in different locales/keyboard layouts. We
  * provide these constants to help make code processing keys more readable.
@@ -30235,7 +31363,7 @@
 abstract class KeyCode {
   // These constant names were borrowed from Closure's Keycode enumeration
   // class.
-  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keycodes.js.source.html  
+  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keycodes.js.source.html
   static const int WIN_KEY_FF_LINUX = 0;
   static const int MAC_ENTER = 3;
   static const int BACKSPACE = 8;
@@ -30430,12 +31558,12 @@
         (keyCode >= A && keyCode <= Z)) {
       return true;
     }
- 
+
     // Safari sends zero key code for non-latin characters.
-    if (_Device.isWebKit && keyCode == 0) {
+    if (Device.isWebKit && keyCode == 0) {
       return true;
     }
- 
+
     return (keyCode == SPACE || keyCode == QUESTION_MARK || keyCode == NUM_PLUS
         || keyCode == NUM_MINUS || keyCode == NUM_PERIOD ||
         keyCode == NUM_DIVISION || keyCode == SEMICOLON ||
@@ -30986,6 +32114,168 @@
    */
   static const String UNIDENTIFIED = "Unidentified";
 }
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+class _ModelTreeObserver {
+  static bool _initialized = false;
+
+  /**
+   * Start an observer watching the document for tree changes to automatically
+   * propagate model changes.
+   *
+   * Currently this does not support propagation through Shadow DOMs.
+   */
+  static void initialize() {
+    if (!_initialized) {
+      _initialized = true;
+
+      if (MutationObserver.supported) {
+        var observer = new MutationObserver(_processTreeChange);
+        observer.observe(document, childList: true, subtree: true);
+      } else {
+        document.on['DOMNodeInserted'].listen(_handleNodeInserted);
+        document.on['DOMNodeRemoved'].listen(_handleNodeRemoved);
+      }
+    }
+  }
+
+  static void _processTreeChange(List<MutationRecord> mutations,
+      MutationObserver observer) {
+    for (var record in mutations) {
+      for (var node in record.addedNodes) {
+        // When nodes enter the document we need to make sure that all of the
+        // models are properly propagated through the entire sub-tree.
+        propagateModel(node, _calculatedModel(node), true);
+      }
+      for (var node in record.removedNodes) {
+        propagateModel(node, _calculatedModel(node), false);
+      }
+    }
+  }
+
+  static void _handleNodeInserted(MutationEvent e) {
+    var node = e.target;
+    window.setImmediate(() {
+      propagateModel(node, _calculatedModel(node), true);
+    });
+  }
+
+  static void _handleNodeRemoved(MutationEvent e) {
+    var node = e.target;
+    window.setImmediate(() {
+      propagateModel(node, _calculatedModel(node), false);
+    });
+  }
+
+  /**
+   * Figures out what the model should be for a node, avoiding any cached
+   * model values.
+   */
+  static _calculatedModel(node) {
+    if (node._hasLocalModel == true) {
+      return node._model;
+    } else if (node.parentNode != null) {
+      return node.parentNode._model;
+    }
+    return null;
+  }
+
+  /**
+   * Pushes model changes down through the tree.
+   *
+   * Set fullTree to true if the state of the tree is unknown and model changes
+   * should be propagated through the entire tree.
+   */
+  static void propagateModel(Node node, model, bool fullTree) {
+    // Calling into user code with the != call could generate exceptions.
+    // Catch and report them a global exceptions.
+    try {
+      if (node._hasLocalModel != true && node._model != model &&
+          node._modelChangedStream != null) {
+        node._model = model;
+        node._modelChangedStream.add(node);
+      }
+    } on AsyncError catch (e) {
+      e.throwDelayed();
+    } catch (e, s) {
+      new AsyncError(e, s).throwDelayed();
+    }
+    for (var child = node.$dom_firstChild; child != null;
+        child = child.nextNode) {
+      if (child._hasLocalModel != true) {
+        propagateModel(child, model, fullTree);
+      } else if (fullTree) {
+        propagateModel(child, child._model, true);
+      }
+    }
+  }
+}
+// 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.
+
+
+/**
+ * A utility class for representing two-dimensional positions.
+ */
+class Point {
+  final num x;
+  final num y;
+
+  const Point([num x = 0, num y = 0]): x = x, y = y;
+
+  String toString() => '($x, $y)';
+
+  bool operator ==(other) {
+    if (other is !Point) return false;
+    return x == other.x && y == other.y;
+  }
+
+  Point operator +(Point other) {
+    return new Point(x + other.x, y + other.y);
+  }
+
+  Point operator -(Point other) {
+    return new Point(x - other.x, y - other.y);
+  }
+
+  Point operator *(num factor) {
+    return new Point(x * factor, y * factor);
+  }
+
+  /**
+   * Returns the distance between two points.
+   */
+  double distanceTo(Point other) {
+    var dx = x - other.x;
+    var dy = y - other.y;
+    return sqrt(dx * dx + dy * dy);
+  }
+
+  /**
+   * Returns the squared distance between two points.
+   *
+   * Squared distances can be used for comparisons when the actual value is not
+   * required.
+   */
+  num squaredDistanceTo(Point other) {
+    var dx = x - other.x;
+    var dy = y - other.y;
+    return dx * dx + dy * dy;
+  }
+
+  Point ceil() => new Point(x.ceil(), y.ceil());
+  Point floor() => new Point(x.floor(), y.floor());
+  Point round() => new Point(x.round(), y.round());
+
+  /**
+   * Truncates x and y to integers and returns the result as a new point.
+   */
+  Point toInt() => new Point(x.toInt(), y.toInt());
+}
 // 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.
@@ -31011,6 +32301,140 @@
    */
   static const String COMPLETE = "complete";
 }
+// 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.
+
+
+/**
+ * A class for representing two-dimensional rectangles.
+ */
+class Rect {
+  final num left;
+  final num top;
+  final num width;
+  final num height;
+
+  const Rect(this.left, this.top, this.width, this.height);
+
+  factory Rect.fromPoints(Point a, Point b) {
+    var left;
+    var width;
+    if (a.x < b.x) {
+      left = a.x;
+      width = b.x - left;
+    } else {
+      left = b.x;
+      width = a.x - left;
+    }
+    var top;
+    var height;
+    if (a.y < b.y) {
+      top = a.y;
+      height = b.y - top;
+    } else {
+      top = b.y;
+      height = a.y - top;
+    }
+
+    return new Rect(left, top, width, height);
+  }
+
+  num get right => left + width;
+  num get bottom => top + height;
+
+  // NOTE! All code below should be common with Rect.
+  // TODO: implement with mixins when available.
+
+  String toString() {
+    return '($left, $top, $width, $height)';
+  }
+
+  bool operator ==(other) {
+    if (other is !Rect) return false;
+    return left == other.left && top == other.top && width == other.width &&
+        height == other.height;
+  }
+
+  /**
+   * Computes the intersection of this rectangle and the rectangle parameter.
+   * Returns null if there is no intersection.
+   */
+  Rect intersection(Rect rect) {
+    var x0 = max(left, rect.left);
+    var x1 = min(left + width, rect.left + rect.width);
+
+    if (x0 <= x1) {
+      var y0 = max(top, rect.top);
+      var y1 = min(top + height, rect.top + rect.height);
+
+      if (y0 <= y1) {
+        return new Rect(x0, y0, x1 - x0, y1 - y0);
+      }
+    }
+    return null;
+  }
+
+
+  /**
+   * Returns whether a rectangle intersects this rectangle.
+   */
+  bool intersects(Rect other) {
+    return (left <= other.left + other.width && other.left <= left + width &&
+        top <= other.top + other.height && other.top <= top + height);
+  }
+
+  /**
+   * Returns a new rectangle which completely contains this rectangle and the
+   * input rectangle.
+   */
+  Rect union(Rect rect) {
+    var right = max(this.left + this.width, rect.left + rect.width);
+    var bottom = max(this.top + this.height, rect.top + rect.height);
+
+    var left = min(this.left, rect.left);
+    var top = min(this.top, rect.top);
+
+    return new Rect(left, top, right - left, bottom - top);
+  }
+
+  /**
+   * Tests whether this rectangle entirely contains another rectangle.
+   */
+  bool containsRect(Rect another) {
+    return left <= another.left &&
+           left + width >= another.left + another.width &&
+           top <= another.top &&
+           top + height >= another.top + another.height;
+  }
+
+  /**
+   * Tests whether this rectangle entirely contains a point.
+   */
+  bool containsPoint(Point another) {
+    return another.x >= left &&
+           another.x <= left + width &&
+           another.y >= top &&
+           another.y <= top + height;
+  }
+
+  Rect ceil() => new Rect(left.ceil(), top.ceil(), width.ceil(), height.ceil());
+  Rect floor() => new Rect(left.floor(), top.floor(), width.floor(),
+      height.floor());
+  Rect round() => new Rect(left.round(), top.round(), width.round(),
+      height.round());
+
+  /**
+   * Truncates coordinates to integers and returns the result as a new
+   * rectangle.
+   */
+  Rect toInt() => new Rect(left.toInt(), top.toInt(), width.toInt(),
+      height.toInt());
+
+  Point get topLeft => new Point(this.left, this.top);
+  Point get bottomRight => new Point(this.left + this.width,
+      this.top + this.height);
+}
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -31686,13 +33110,13 @@
 
   E get single => _list.single;
 
-  E firstMatching(bool test(E value), { E orElse() }) =>
-      _list.firstMatching(test, orElse: orElse);
+  E firstWhere(bool test(E value), { E orElse() }) =>
+      _list.firstWhere(test, orElse: orElse);
 
-  E lastMatching(bool test(E value), {E orElse()}) =>
-      _list.lastMatching(test, orElse: orElse);
+  E lastWhere(bool test(E value), {E orElse()}) =>
+      _list.lastWhere(test, orElse: orElse);
 
-  E singleMatching(bool test(E value)) => _list.singleMatching(test);
+  E singleWhere(bool test(E value)) => _list.singleWhere(test);
 
   E elementAt(int index) => _list.elementAt(index);
 
@@ -31708,9 +33132,9 @@
 
   void retainAll(Iterable elements) { _list.retainAll(elements); }
 
-  void removeMatching(bool test(E element)) { _list.removeMatching(test); }
+  void removeWhere(bool test(E element)) { _list.removeWhere(test); }
 
-  void retainMatching(bool test(E element)) { _list.retainMatching(test); }
+  void retainWhere(bool test(E element)) { _list.retainWhere(test); }
 
   void clear() { _list.clear(); }
 
@@ -31722,7 +33146,7 @@
 
   void set length(int newLength) { _list.length = newLength; }
 
-  void addLast(E value) { _list.addLast(value); }
+  void addLast(E value) { _list.add(value); }
 
   Iterable<E> get reversed => _list.reversed;
 
@@ -31732,11 +33156,15 @@
 
   int lastIndexOf(E element, [int start]) => _list.lastIndexOf(element, start);
 
+  void insert(int index, E element) => _list.insert(index, element);
+
   E removeAt(int index) => _list.removeAt(index);
 
   E removeLast() => _list.removeLast();
 
-  List<E> getRange(int start, int length) => _list.getRange(start, length);
+  List<E> sublist(int start, [int end]) => _list.sublist(start, end);
+
+  List<E> getRange(int start, int length) => sublist(start, start + length);
 
   void setRange(int start, int length, List<E> from, [int startFrom]) {
     _list.setRange(start, length, from, startFrom);
@@ -31747,6 +33175,8 @@
   void insertRange(int start, int length, [E fill]) {
     _list.insertRange(start, length, fill);
   }
+
+  Map<int, E> asMap() => IterableMixinWorkaround.asMapList(_list);
 }
 
 /**
@@ -32074,12 +33504,10 @@
    * KeyLocation.NUMPAD, KeyLocation.MOBILE, KeyLocation.JOYSTICK).
    */
   int get keyLocation => _parent.keyLocation;
-  int get layerX => _parent.layerX;
-  int get layerY => _parent.layerY;
+  Point get layer => _parent.layer;
   /** True if the Meta (or Mac command) key is pressed during this event. */
   bool get metaKey => _parent.metaKey;
-  int get pageX => _parent.pageX;
-  int get pageY => _parent.pageY;
+  Point get page => _parent.page;
   bool get returnValue => _parent.returnValue;
   void set returnValue(bool value) {
     _parent.returnValue = value;
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 870eaf7..a35d5d8 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -7,7 +7,9 @@
 import 'dart:indexed_db';
 import 'dart:isolate';
 import 'dart:json' as json;
+import 'dart:math';
 import 'dart:nativewrappers';
+import 'dart:typeddata' as _typeddata;
 import 'dart:web_sql';
 import 'dart:svg' as svg;
 import 'dart:web_audio' as web_audio;
@@ -525,7 +527,7 @@
   @DocsEditable
   int get byteLength native "ArrayBuffer_byteLength_Getter";
 
-  ArrayBuffer slice(int begin, [int end]) {
+  dynamic slice(int begin, [int end]) {
     if (?end) {
       return _slice_1(begin, end);
     }
@@ -534,11 +536,11 @@
 
   @DomName('ArrayBuffer._slice_1')
   @DocsEditable
-  ArrayBuffer _slice_1(begin, end) native "ArrayBuffer__slice_1_Callback";
+  dynamic _slice_1(begin, end) native "ArrayBuffer__slice_1_Callback";
 
   @DomName('ArrayBuffer._slice_2')
   @DocsEditable
-  ArrayBuffer _slice_2(begin) native "ArrayBuffer__slice_2_Callback";
+  dynamic _slice_2(begin) native "ArrayBuffer__slice_2_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -559,7 +561,7 @@
 
   @DomName('ArrayBufferView.buffer')
   @DocsEditable
-  ArrayBuffer get buffer native "ArrayBufferView_buffer_Getter";
+  dynamic get buffer native "ArrayBufferView_buffer_Getter";
 
   @DomName('ArrayBufferView.byteLength')
   @DocsEditable
@@ -1079,7 +1081,7 @@
 
 
 @DomName('HTMLCanvasElement')
-class CanvasElement extends _Element_Merged {
+class CanvasElement extends _Element_Merged implements CanvasImageSource {
   CanvasElement.internal() : super.internal();
 
   @DomName('HTMLCanvasElement.HTMLCanvasElement')
@@ -1475,7 +1477,7 @@
 
   @DomName('CanvasRenderingContext2D.arc')
   @DocsEditable
-  void arc(num x, num y, num radius, num startAngle, num endAngle, bool anticlockwise) native "CanvasRenderingContext2D_arc_Callback";
+  void $dom_arc(num x, num y, num radius, num startAngle, num endAngle, bool anticlockwise) native "CanvasRenderingContext2D_arc_Callback";
 
   @DomName('CanvasRenderingContext2D.arcTo')
   @DocsEditable
@@ -1558,7 +1560,7 @@
   @DocsEditable
   CanvasGradient createRadialGradient(num x0, num y0, num r0, num x1, num y1, num r1) native "CanvasRenderingContext2D_createRadialGradient_Callback";
 
-  void drawImage(canvas_OR_image_OR_video, num sx_OR_x, num sy_OR_y, [num sw_OR_width, num height_OR_sh, num dx, num dy, num dw, num dh]) {
+  void $dom_drawImage(canvas_OR_image_OR_video, num sx_OR_x, num sy_OR_y, [num sw_OR_width, num height_OR_sh, num dx, num dy, num dw, num dh]) {
     if ((canvas_OR_image_OR_video is ImageElement || canvas_OR_image_OR_video == null) && (sx_OR_x is num || sx_OR_x == null) && (sy_OR_y is num || sy_OR_y == null) && !?sw_OR_width && !?height_OR_sh && !?dx && !?dy && !?dw && !?dh) {
       _drawImage_1(canvas_OR_image_OR_video, sx_OR_x, sy_OR_y);
       return;
@@ -1873,6 +1875,107 @@
     this.strokeStyle = 'hsla($h, $s%, $l%, $a)';
   }
 
+  @DomName('CanvasRenderingContext2D.arc')
+  void arc(num x,  num y,  num radius,  num startAngle, num endAngle,
+      [bool anticlockwise = false]) {
+    $dom_arc(x, y, radius, startAngle, endAngle, anticlockwise);
+  }
+
+  /**
+   * Draws an image from a CanvasImageSource to this canvas.
+   *
+   * The entire image from [source] will be drawn to this context with its top
+   * left corner at the point ([destinationX], [destinationY]). If the image is
+   * larger than canvas will allow, the image will be cropped to fit the
+   * available space.
+   *
+   *     CanvasElement canvas = new CanvasElement(width: 600, height: 600);
+   *     CanvasRenderingContext2D ctx = canvas.context2d;
+   *     ImageElement img = document.query('img');
+   *
+   *     ctx.drawImage(img, 100, 100);
+   *
+   *     VideoElement video = document.query('video');
+   *     ctx.drawImage(video, 0, 0);
+   *
+   *     CanvasElement otherCanvas = document.query('canvas');
+   *     otherCanvas.width = 100;
+   *     otherCanvas.height = 100;
+   *     ctx.drawImage(otherCanvas, 590, 590); // will get cropped
+   *
+   * See also:
+   *
+   *   * [CanvasImageSource] for more information on what data is retrieved
+   * from [source].
+   *   * [drawImage](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
+   * from the WHATWG.
+   */
+  @DomName('CanvasRenderingContext2D.drawImage')
+  void drawImage(CanvasImageSource source, num destinationX, num destinationY) {
+    $dom_drawImage(source, destinationX, destinationY);
+  }
+
+  /**
+   * Draws an image from a CanvasImageSource to an area of this canvas.
+   *
+   * The image will be drawn to an area of this canvas defined by
+   * [destinationRect]. If [sourceRect] is not provided, then
+   * the entire rectangular image from [source] will be drawn to this context.
+   * If the dimensions of [source] or [sourceRect]
+   * differ from [destinationRect], then the image will be scaled to fit.
+   * If the image is larger than canvas
+   * will allow, the image will be cropped to fit the available space.
+   *
+   *     CanvasElement canvas = new CanvasElement(width: 600, height: 600);
+   *     CanvasRenderingContext2D ctx = canvas.context2d;
+   *     ImageElement img = document.query('img');
+   *     img.width = 100;
+   *     img.height = 100;
+   *
+   *     // Scale the image to 20x20.
+   *     ctx.drawImageAtScale(img, new Rect(50, 50, 20, 20));
+   *
+   *     VideoElement video = document.query('video');
+   *     video.width = 100;
+   *     video.height = 100;
+   *     // Take the middle 20x20 pixels from the video and stretch them.
+   *     ctx.drawImageAtScale(video, new Rect(50, 50, 100, 100),
+   *         sourceRect: new Rect(40, 40, 20, 20));
+   *
+   *     // Draw the top 100x20 pixels from the otherCanvas.
+   *     CanvasElement otherCanvas = document.query('canvas');
+   *     ctx.drawImageAtScale(otherCanvas, new Rect(0, 0, 100, 20),
+   *         sourceRect: new Rect(0, 0, 100, 20));
+   *
+   * See also:
+   *
+   *   * [CanvasImageSource] for more information on what data is retrieved
+   * from [source].
+   *   * [drawImage](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
+   * from the WHATWG.
+   */
+  @DomName('CanvasRenderingContext2D.drawImage')
+  void drawImageAtScale(CanvasImageSource source, Rect destinationRect,
+      {Rect sourceRect}) {
+    if (sourceRect == null) {
+      $dom_drawImage(source,
+          destinationRect.left,
+          destinationRect.top,
+          destinationRect.width,
+          destinationRect.height);
+    } else {
+      $dom_drawImage(source,
+          sourceRect.left,
+          sourceRect.top,
+          sourceRect.width,
+          sourceRect.height,
+          destinationRect.left,
+          destinationRect.top,
+          destinationRect.width,
+          destinationRect.height);
+    }
+  }
+
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -1927,43 +2030,6 @@
 
 
 @DocsEditable
-@DomName('ClientRect')
-class ClientRect extends NativeFieldWrapperClass1 {
-  ClientRect.internal();
-
-  @DomName('ClientRect.bottom')
-  @DocsEditable
-  num get bottom native "ClientRect_bottom_Getter";
-
-  @DomName('ClientRect.height')
-  @DocsEditable
-  num get height native "ClientRect_height_Getter";
-
-  @DomName('ClientRect.left')
-  @DocsEditable
-  num get left native "ClientRect_left_Getter";
-
-  @DomName('ClientRect.right')
-  @DocsEditable
-  num get right native "ClientRect_right_Getter";
-
-  @DomName('ClientRect.top')
-  @DocsEditable
-  num get top native "ClientRect_top_Getter";
-
-  @DomName('ClientRect.width')
-  @DocsEditable
-  num get width native "ClientRect_width_Getter";
-
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
 @DomName('CloseEvent')
 class CloseEvent extends Event {
   CloseEvent.internal() : super.internal();
@@ -2138,7 +2204,7 @@
 
 @DocsEditable
 @DomName('HTMLContentElement')
-@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@SupportedBrowser(SupportedBrowser.CHROME, '26')
 @Experimental
 class ContentElement extends _Element_Merged {
   ContentElement.internal() : super.internal();
@@ -2257,7 +2323,7 @@
 
   @DomName('Crypto.getRandomValues')
   @DocsEditable
-  ArrayBufferView getRandomValues(ArrayBufferView array) native "Crypto_getRandomValues_Callback";
+  dynamic getRandomValues(/*ArrayBufferView*/ array) native "Crypto_getRandomValues_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -2307,6 +2373,8 @@
 
 @DocsEditable
 @DomName('CSSHostRule')
+@SupportedBrowser(SupportedBrowser.CHROME, '26')
+@Experimental
 class CssHostRule extends CssRule {
   CssHostRule.internal() : super.internal();
 
@@ -2794,11 +2862,11 @@
 
   @DomName('CSSPrimitiveValue.getRGBColorValue')
   @DocsEditable
-  RgbColor getRgbColorValue() native "CSSPrimitiveValue_getRGBColorValue_Callback";
+  CssRgbColor getRgbColorValue() native "CSSPrimitiveValue_getRGBColorValue_Callback";
 
   @DomName('CSSPrimitiveValue.getRectValue')
   @DocsEditable
-  Rect getRectValue() native "CSSPrimitiveValue_getRectValue_Callback";
+  CssRect getRectValue() native "CSSPrimitiveValue_getRectValue_Callback";
 
   @DomName('CSSPrimitiveValue.getStringValue')
   @DocsEditable
@@ -2821,6 +2889,60 @@
 
 
 @DocsEditable
+@DomName('Rect')
+class CssRect extends NativeFieldWrapperClass1 {
+  CssRect.internal();
+
+  @DomName('Rect.bottom')
+  @DocsEditable
+  CssPrimitiveValue get bottom native "Rect_bottom_Getter";
+
+  @DomName('Rect.left')
+  @DocsEditable
+  CssPrimitiveValue get left native "Rect_left_Getter";
+
+  @DomName('Rect.right')
+  @DocsEditable
+  CssPrimitiveValue get right native "Rect_right_Getter";
+
+  @DomName('Rect.top')
+  @DocsEditable
+  CssPrimitiveValue get top native "Rect_top_Getter";
+
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('RGBColor')
+class CssRgbColor extends NativeFieldWrapperClass1 {
+  CssRgbColor.internal();
+
+  @DomName('RGBColor.blue')
+  @DocsEditable
+  CssPrimitiveValue get blue native "RGBColor_blue_Getter";
+
+  @DomName('RGBColor.green')
+  @DocsEditable
+  CssPrimitiveValue get green native "RGBColor_green_Getter";
+
+  @DomName('RGBColor.red')
+  @DocsEditable
+  CssPrimitiveValue get red native "RGBColor_red_Getter";
+
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
 @DomName('CSSRule')
 class CssRule extends NativeFieldWrapperClass1 {
   CssRule.internal();
@@ -2873,41 +2995,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-String _cachedBrowserPrefix;
-
-String get _browserPrefix {
-  if (_cachedBrowserPrefix == null) {
-    if (_Device.isFirefox) {
-      _cachedBrowserPrefix = '-moz-';
-    } else if (_Device.isIE) {
-      _cachedBrowserPrefix = '-ms-';
-    } else if (_Device.isOpera) {
-      _cachedBrowserPrefix = '-o-';
-    } else {
-      _cachedBrowserPrefix = '-webkit-';
-    }
-  }
-  return _cachedBrowserPrefix;
-}
-
-String _cachedBrowserPropertyPrefix;
-
-/// Prefix as used for JS property names.
-String get _browserPropertyPrefix {
-  if (_cachedBrowserPropertyPrefix == null) {
-    if (_Device.isFirefox) {
-      _cachedBrowserPropertyPrefix = 'moz';
-    } else if (_Device.isIE) {
-      _cachedBrowserPropertyPrefix = 'ms';
-    } else if (_Device.isOpera) {
-      _cachedBrowserPropertyPrefix = 'o';
-    } else {
-      _cachedBrowserPropertyPrefix = 'webkit';
-    }
-  }
-  return _cachedBrowserPropertyPrefix;
-}
-
 @DomName('CSSStyleDeclaration')
 class CssStyleDeclaration extends NativeFieldWrapperClass1 {
   factory CssStyleDeclaration() => _CssStyleDeclarationFactoryProvider.createCssStyleDeclaration();
@@ -2978,146 +3065,146 @@
   // TODO(jacobr): generate this list of properties using the existing script.
   /** Gets the value of "align-content" */
   String get alignContent =>
-    getPropertyValue('${_browserPrefix}align-content');
+    getPropertyValue('${Device.cssPrefix}align-content');
 
   /** Sets the value of "align-content" */
   void set alignContent(String value) {
-    setProperty('${_browserPrefix}align-content', value, '');
+    setProperty('${Device.cssPrefix}align-content', value, '');
   }
 
   /** Gets the value of "align-items" */
   String get alignItems =>
-    getPropertyValue('${_browserPrefix}align-items');
+    getPropertyValue('${Device.cssPrefix}align-items');
 
   /** Sets the value of "align-items" */
   void set alignItems(String value) {
-    setProperty('${_browserPrefix}align-items', value, '');
+    setProperty('${Device.cssPrefix}align-items', value, '');
   }
 
   /** Gets the value of "align-self" */
   String get alignSelf =>
-    getPropertyValue('${_browserPrefix}align-self');
+    getPropertyValue('${Device.cssPrefix}align-self');
 
   /** Sets the value of "align-self" */
   void set alignSelf(String value) {
-    setProperty('${_browserPrefix}align-self', value, '');
+    setProperty('${Device.cssPrefix}align-self', value, '');
   }
 
   /** Gets the value of "animation" */
   String get animation =>
-    getPropertyValue('${_browserPrefix}animation');
+    getPropertyValue('${Device.cssPrefix}animation');
 
   /** Sets the value of "animation" */
   void set animation(String value) {
-    setProperty('${_browserPrefix}animation', value, '');
+    setProperty('${Device.cssPrefix}animation', value, '');
   }
 
   /** Gets the value of "animation-delay" */
   String get animationDelay =>
-    getPropertyValue('${_browserPrefix}animation-delay');
+    getPropertyValue('${Device.cssPrefix}animation-delay');
 
   /** Sets the value of "animation-delay" */
   void set animationDelay(String value) {
-    setProperty('${_browserPrefix}animation-delay', value, '');
+    setProperty('${Device.cssPrefix}animation-delay', value, '');
   }
 
   /** Gets the value of "animation-direction" */
   String get animationDirection =>
-    getPropertyValue('${_browserPrefix}animation-direction');
+    getPropertyValue('${Device.cssPrefix}animation-direction');
 
   /** Sets the value of "animation-direction" */
   void set animationDirection(String value) {
-    setProperty('${_browserPrefix}animation-direction', value, '');
+    setProperty('${Device.cssPrefix}animation-direction', value, '');
   }
 
   /** Gets the value of "animation-duration" */
   String get animationDuration =>
-    getPropertyValue('${_browserPrefix}animation-duration');
+    getPropertyValue('${Device.cssPrefix}animation-duration');
 
   /** Sets the value of "animation-duration" */
   void set animationDuration(String value) {
-    setProperty('${_browserPrefix}animation-duration', value, '');
+    setProperty('${Device.cssPrefix}animation-duration', value, '');
   }
 
   /** Gets the value of "animation-fill-mode" */
   String get animationFillMode =>
-    getPropertyValue('${_browserPrefix}animation-fill-mode');
+    getPropertyValue('${Device.cssPrefix}animation-fill-mode');
 
   /** Sets the value of "animation-fill-mode" */
   void set animationFillMode(String value) {
-    setProperty('${_browserPrefix}animation-fill-mode', value, '');
+    setProperty('${Device.cssPrefix}animation-fill-mode', value, '');
   }
 
   /** Gets the value of "animation-iteration-count" */
   String get animationIterationCount =>
-    getPropertyValue('${_browserPrefix}animation-iteration-count');
+    getPropertyValue('${Device.cssPrefix}animation-iteration-count');
 
   /** Sets the value of "animation-iteration-count" */
   void set animationIterationCount(String value) {
-    setProperty('${_browserPrefix}animation-iteration-count', value, '');
+    setProperty('${Device.cssPrefix}animation-iteration-count', value, '');
   }
 
   /** Gets the value of "animation-name" */
   String get animationName =>
-    getPropertyValue('${_browserPrefix}animation-name');
+    getPropertyValue('${Device.cssPrefix}animation-name');
 
   /** Sets the value of "animation-name" */
   void set animationName(String value) {
-    setProperty('${_browserPrefix}animation-name', value, '');
+    setProperty('${Device.cssPrefix}animation-name', value, '');
   }
 
   /** Gets the value of "animation-play-state" */
   String get animationPlayState =>
-    getPropertyValue('${_browserPrefix}animation-play-state');
+    getPropertyValue('${Device.cssPrefix}animation-play-state');
 
   /** Sets the value of "animation-play-state" */
   void set animationPlayState(String value) {
-    setProperty('${_browserPrefix}animation-play-state', value, '');
+    setProperty('${Device.cssPrefix}animation-play-state', value, '');
   }
 
   /** Gets the value of "animation-timing-function" */
   String get animationTimingFunction =>
-    getPropertyValue('${_browserPrefix}animation-timing-function');
+    getPropertyValue('${Device.cssPrefix}animation-timing-function');
 
   /** Sets the value of "animation-timing-function" */
   void set animationTimingFunction(String value) {
-    setProperty('${_browserPrefix}animation-timing-function', value, '');
+    setProperty('${Device.cssPrefix}animation-timing-function', value, '');
   }
 
   /** Gets the value of "app-region" */
   String get appRegion =>
-    getPropertyValue('${_browserPrefix}app-region');
+    getPropertyValue('${Device.cssPrefix}app-region');
 
   /** Sets the value of "app-region" */
   void set appRegion(String value) {
-    setProperty('${_browserPrefix}app-region', value, '');
+    setProperty('${Device.cssPrefix}app-region', value, '');
   }
 
   /** Gets the value of "appearance" */
   String get appearance =>
-    getPropertyValue('${_browserPrefix}appearance');
+    getPropertyValue('${Device.cssPrefix}appearance');
 
   /** Sets the value of "appearance" */
   void set appearance(String value) {
-    setProperty('${_browserPrefix}appearance', value, '');
+    setProperty('${Device.cssPrefix}appearance', value, '');
   }
 
   /** Gets the value of "aspect-ratio" */
   String get aspectRatio =>
-    getPropertyValue('${_browserPrefix}aspect-ratio');
+    getPropertyValue('${Device.cssPrefix}aspect-ratio');
 
   /** Sets the value of "aspect-ratio" */
   void set aspectRatio(String value) {
-    setProperty('${_browserPrefix}aspect-ratio', value, '');
+    setProperty('${Device.cssPrefix}aspect-ratio', value, '');
   }
 
   /** Gets the value of "backface-visibility" */
   String get backfaceVisibility =>
-    getPropertyValue('${_browserPrefix}backface-visibility');
+    getPropertyValue('${Device.cssPrefix}backface-visibility');
 
   /** Sets the value of "backface-visibility" */
   void set backfaceVisibility(String value) {
-    setProperty('${_browserPrefix}backface-visibility', value, '');
+    setProperty('${Device.cssPrefix}backface-visibility', value, '');
   }
 
   /** Gets the value of "background" */
@@ -3158,11 +3245,11 @@
 
   /** Gets the value of "background-composite" */
   String get backgroundComposite =>
-    getPropertyValue('${_browserPrefix}background-composite');
+    getPropertyValue('${Device.cssPrefix}background-composite');
 
   /** Sets the value of "background-composite" */
   void set backgroundComposite(String value) {
-    setProperty('${_browserPrefix}background-composite', value, '');
+    setProperty('${Device.cssPrefix}background-composite', value, '');
   }
 
   /** Gets the value of "background-image" */
@@ -3248,11 +3335,11 @@
 
   /** Gets the value of "blend-mode" */
   String get blendMode =>
-    getPropertyValue('${_browserPrefix}blend-mode');
+    getPropertyValue('${Device.cssPrefix}blend-mode');
 
   /** Sets the value of "blend-mode" */
   void set blendMode(String value) {
-    setProperty('${_browserPrefix}blend-mode', value, '');
+    setProperty('${Device.cssPrefix}blend-mode', value, '');
   }
 
   /** Gets the value of "border" */
@@ -3266,74 +3353,74 @@
 
   /** Gets the value of "border-after" */
   String get borderAfter =>
-    getPropertyValue('${_browserPrefix}border-after');
+    getPropertyValue('${Device.cssPrefix}border-after');
 
   /** Sets the value of "border-after" */
   void set borderAfter(String value) {
-    setProperty('${_browserPrefix}border-after', value, '');
+    setProperty('${Device.cssPrefix}border-after', value, '');
   }
 
   /** Gets the value of "border-after-color" */
   String get borderAfterColor =>
-    getPropertyValue('${_browserPrefix}border-after-color');
+    getPropertyValue('${Device.cssPrefix}border-after-color');
 
   /** Sets the value of "border-after-color" */
   void set borderAfterColor(String value) {
-    setProperty('${_browserPrefix}border-after-color', value, '');
+    setProperty('${Device.cssPrefix}border-after-color', value, '');
   }
 
   /** Gets the value of "border-after-style" */
   String get borderAfterStyle =>
-    getPropertyValue('${_browserPrefix}border-after-style');
+    getPropertyValue('${Device.cssPrefix}border-after-style');
 
   /** Sets the value of "border-after-style" */
   void set borderAfterStyle(String value) {
-    setProperty('${_browserPrefix}border-after-style', value, '');
+    setProperty('${Device.cssPrefix}border-after-style', value, '');
   }
 
   /** Gets the value of "border-after-width" */
   String get borderAfterWidth =>
-    getPropertyValue('${_browserPrefix}border-after-width');
+    getPropertyValue('${Device.cssPrefix}border-after-width');
 
   /** Sets the value of "border-after-width" */
   void set borderAfterWidth(String value) {
-    setProperty('${_browserPrefix}border-after-width', value, '');
+    setProperty('${Device.cssPrefix}border-after-width', value, '');
   }
 
   /** Gets the value of "border-before" */
   String get borderBefore =>
-    getPropertyValue('${_browserPrefix}border-before');
+    getPropertyValue('${Device.cssPrefix}border-before');
 
   /** Sets the value of "border-before" */
   void set borderBefore(String value) {
-    setProperty('${_browserPrefix}border-before', value, '');
+    setProperty('${Device.cssPrefix}border-before', value, '');
   }
 
   /** Gets the value of "border-before-color" */
   String get borderBeforeColor =>
-    getPropertyValue('${_browserPrefix}border-before-color');
+    getPropertyValue('${Device.cssPrefix}border-before-color');
 
   /** Sets the value of "border-before-color" */
   void set borderBeforeColor(String value) {
-    setProperty('${_browserPrefix}border-before-color', value, '');
+    setProperty('${Device.cssPrefix}border-before-color', value, '');
   }
 
   /** Gets the value of "border-before-style" */
   String get borderBeforeStyle =>
-    getPropertyValue('${_browserPrefix}border-before-style');
+    getPropertyValue('${Device.cssPrefix}border-before-style');
 
   /** Sets the value of "border-before-style" */
   void set borderBeforeStyle(String value) {
-    setProperty('${_browserPrefix}border-before-style', value, '');
+    setProperty('${Device.cssPrefix}border-before-style', value, '');
   }
 
   /** Gets the value of "border-before-width" */
   String get borderBeforeWidth =>
-    getPropertyValue('${_browserPrefix}border-before-width');
+    getPropertyValue('${Device.cssPrefix}border-before-width');
 
   /** Sets the value of "border-before-width" */
   void set borderBeforeWidth(String value) {
-    setProperty('${_browserPrefix}border-before-width', value, '');
+    setProperty('${Device.cssPrefix}border-before-width', value, '');
   }
 
   /** Gets the value of "border-bottom" */
@@ -3410,56 +3497,56 @@
 
   /** Gets the value of "border-end" */
   String get borderEnd =>
-    getPropertyValue('${_browserPrefix}border-end');
+    getPropertyValue('${Device.cssPrefix}border-end');
 
   /** Sets the value of "border-end" */
   void set borderEnd(String value) {
-    setProperty('${_browserPrefix}border-end', value, '');
+    setProperty('${Device.cssPrefix}border-end', value, '');
   }
 
   /** Gets the value of "border-end-color" */
   String get borderEndColor =>
-    getPropertyValue('${_browserPrefix}border-end-color');
+    getPropertyValue('${Device.cssPrefix}border-end-color');
 
   /** Sets the value of "border-end-color" */
   void set borderEndColor(String value) {
-    setProperty('${_browserPrefix}border-end-color', value, '');
+    setProperty('${Device.cssPrefix}border-end-color', value, '');
   }
 
   /** Gets the value of "border-end-style" */
   String get borderEndStyle =>
-    getPropertyValue('${_browserPrefix}border-end-style');
+    getPropertyValue('${Device.cssPrefix}border-end-style');
 
   /** Sets the value of "border-end-style" */
   void set borderEndStyle(String value) {
-    setProperty('${_browserPrefix}border-end-style', value, '');
+    setProperty('${Device.cssPrefix}border-end-style', value, '');
   }
 
   /** Gets the value of "border-end-width" */
   String get borderEndWidth =>
-    getPropertyValue('${_browserPrefix}border-end-width');
+    getPropertyValue('${Device.cssPrefix}border-end-width');
 
   /** Sets the value of "border-end-width" */
   void set borderEndWidth(String value) {
-    setProperty('${_browserPrefix}border-end-width', value, '');
+    setProperty('${Device.cssPrefix}border-end-width', value, '');
   }
 
   /** Gets the value of "border-fit" */
   String get borderFit =>
-    getPropertyValue('${_browserPrefix}border-fit');
+    getPropertyValue('${Device.cssPrefix}border-fit');
 
   /** Sets the value of "border-fit" */
   void set borderFit(String value) {
-    setProperty('${_browserPrefix}border-fit', value, '');
+    setProperty('${Device.cssPrefix}border-fit', value, '');
   }
 
   /** Gets the value of "border-horizontal-spacing" */
   String get borderHorizontalSpacing =>
-    getPropertyValue('${_browserPrefix}border-horizontal-spacing');
+    getPropertyValue('${Device.cssPrefix}border-horizontal-spacing');
 
   /** Sets the value of "border-horizontal-spacing" */
   void set borderHorizontalSpacing(String value) {
-    setProperty('${_browserPrefix}border-horizontal-spacing', value, '');
+    setProperty('${Device.cssPrefix}border-horizontal-spacing', value, '');
   }
 
   /** Gets the value of "border-image" */
@@ -3608,38 +3695,38 @@
 
   /** Gets the value of "border-start" */
   String get borderStart =>
-    getPropertyValue('${_browserPrefix}border-start');
+    getPropertyValue('${Device.cssPrefix}border-start');
 
   /** Sets the value of "border-start" */
   void set borderStart(String value) {
-    setProperty('${_browserPrefix}border-start', value, '');
+    setProperty('${Device.cssPrefix}border-start', value, '');
   }
 
   /** Gets the value of "border-start-color" */
   String get borderStartColor =>
-    getPropertyValue('${_browserPrefix}border-start-color');
+    getPropertyValue('${Device.cssPrefix}border-start-color');
 
   /** Sets the value of "border-start-color" */
   void set borderStartColor(String value) {
-    setProperty('${_browserPrefix}border-start-color', value, '');
+    setProperty('${Device.cssPrefix}border-start-color', value, '');
   }
 
   /** Gets the value of "border-start-style" */
   String get borderStartStyle =>
-    getPropertyValue('${_browserPrefix}border-start-style');
+    getPropertyValue('${Device.cssPrefix}border-start-style');
 
   /** Sets the value of "border-start-style" */
   void set borderStartStyle(String value) {
-    setProperty('${_browserPrefix}border-start-style', value, '');
+    setProperty('${Device.cssPrefix}border-start-style', value, '');
   }
 
   /** Gets the value of "border-start-width" */
   String get borderStartWidth =>
-    getPropertyValue('${_browserPrefix}border-start-width');
+    getPropertyValue('${Device.cssPrefix}border-start-width');
 
   /** Sets the value of "border-start-width" */
   void set borderStartWidth(String value) {
-    setProperty('${_browserPrefix}border-start-width', value, '');
+    setProperty('${Device.cssPrefix}border-start-width', value, '');
   }
 
   /** Gets the value of "border-style" */
@@ -3707,11 +3794,11 @@
 
   /** Gets the value of "border-vertical-spacing" */
   String get borderVerticalSpacing =>
-    getPropertyValue('${_browserPrefix}border-vertical-spacing');
+    getPropertyValue('${Device.cssPrefix}border-vertical-spacing');
 
   /** Sets the value of "border-vertical-spacing" */
   void set borderVerticalSpacing(String value) {
-    setProperty('${_browserPrefix}border-vertical-spacing', value, '');
+    setProperty('${Device.cssPrefix}border-vertical-spacing', value, '');
   }
 
   /** Gets the value of "border-width" */
@@ -3734,92 +3821,92 @@
 
   /** Gets the value of "box-align" */
   String get boxAlign =>
-    getPropertyValue('${_browserPrefix}box-align');
+    getPropertyValue('${Device.cssPrefix}box-align');
 
   /** Sets the value of "box-align" */
   void set boxAlign(String value) {
-    setProperty('${_browserPrefix}box-align', value, '');
+    setProperty('${Device.cssPrefix}box-align', value, '');
   }
 
   /** Gets the value of "box-decoration-break" */
   String get boxDecorationBreak =>
-    getPropertyValue('${_browserPrefix}box-decoration-break');
+    getPropertyValue('${Device.cssPrefix}box-decoration-break');
 
   /** Sets the value of "box-decoration-break" */
   void set boxDecorationBreak(String value) {
-    setProperty('${_browserPrefix}box-decoration-break', value, '');
+    setProperty('${Device.cssPrefix}box-decoration-break', value, '');
   }
 
   /** Gets the value of "box-direction" */
   String get boxDirection =>
-    getPropertyValue('${_browserPrefix}box-direction');
+    getPropertyValue('${Device.cssPrefix}box-direction');
 
   /** Sets the value of "box-direction" */
   void set boxDirection(String value) {
-    setProperty('${_browserPrefix}box-direction', value, '');
+    setProperty('${Device.cssPrefix}box-direction', value, '');
   }
 
   /** Gets the value of "box-flex" */
   String get boxFlex =>
-    getPropertyValue('${_browserPrefix}box-flex');
+    getPropertyValue('${Device.cssPrefix}box-flex');
 
   /** Sets the value of "box-flex" */
   void set boxFlex(String value) {
-    setProperty('${_browserPrefix}box-flex', value, '');
+    setProperty('${Device.cssPrefix}box-flex', value, '');
   }
 
   /** Gets the value of "box-flex-group" */
   String get boxFlexGroup =>
-    getPropertyValue('${_browserPrefix}box-flex-group');
+    getPropertyValue('${Device.cssPrefix}box-flex-group');
 
   /** Sets the value of "box-flex-group" */
   void set boxFlexGroup(String value) {
-    setProperty('${_browserPrefix}box-flex-group', value, '');
+    setProperty('${Device.cssPrefix}box-flex-group', value, '');
   }
 
   /** Gets the value of "box-lines" */
   String get boxLines =>
-    getPropertyValue('${_browserPrefix}box-lines');
+    getPropertyValue('${Device.cssPrefix}box-lines');
 
   /** Sets the value of "box-lines" */
   void set boxLines(String value) {
-    setProperty('${_browserPrefix}box-lines', value, '');
+    setProperty('${Device.cssPrefix}box-lines', value, '');
   }
 
   /** Gets the value of "box-ordinal-group" */
   String get boxOrdinalGroup =>
-    getPropertyValue('${_browserPrefix}box-ordinal-group');
+    getPropertyValue('${Device.cssPrefix}box-ordinal-group');
 
   /** Sets the value of "box-ordinal-group" */
   void set boxOrdinalGroup(String value) {
-    setProperty('${_browserPrefix}box-ordinal-group', value, '');
+    setProperty('${Device.cssPrefix}box-ordinal-group', value, '');
   }
 
   /** Gets the value of "box-orient" */
   String get boxOrient =>
-    getPropertyValue('${_browserPrefix}box-orient');
+    getPropertyValue('${Device.cssPrefix}box-orient');
 
   /** Sets the value of "box-orient" */
   void set boxOrient(String value) {
-    setProperty('${_browserPrefix}box-orient', value, '');
+    setProperty('${Device.cssPrefix}box-orient', value, '');
   }
 
   /** Gets the value of "box-pack" */
   String get boxPack =>
-    getPropertyValue('${_browserPrefix}box-pack');
+    getPropertyValue('${Device.cssPrefix}box-pack');
 
   /** Sets the value of "box-pack" */
   void set boxPack(String value) {
-    setProperty('${_browserPrefix}box-pack', value, '');
+    setProperty('${Device.cssPrefix}box-pack', value, '');
   }
 
   /** Gets the value of "box-reflect" */
   String get boxReflect =>
-    getPropertyValue('${_browserPrefix}box-reflect');
+    getPropertyValue('${Device.cssPrefix}box-reflect');
 
   /** Sets the value of "box-reflect" */
   void set boxReflect(String value) {
-    setProperty('${_browserPrefix}box-reflect', value, '');
+    setProperty('${Device.cssPrefix}box-reflect', value, '');
   }
 
   /** Gets the value of "box-shadow" */
@@ -3869,11 +3956,11 @@
 
   /** Gets the value of "clip-path" */
   String get clipPath =>
-    getPropertyValue('${_browserPrefix}clip-path');
+    getPropertyValue('${Device.cssPrefix}clip-path');
 
   /** Sets the value of "clip-path" */
   void set clipPath(String value) {
-    setProperty('${_browserPrefix}clip-path', value, '');
+    setProperty('${Device.cssPrefix}clip-path', value, '');
   }
 
   /** Gets the value of "color" */
@@ -3887,137 +3974,137 @@
 
   /** Gets the value of "color-correction" */
   String get colorCorrection =>
-    getPropertyValue('${_browserPrefix}color-correction');
+    getPropertyValue('${Device.cssPrefix}color-correction');
 
   /** Sets the value of "color-correction" */
   void set colorCorrection(String value) {
-    setProperty('${_browserPrefix}color-correction', value, '');
+    setProperty('${Device.cssPrefix}color-correction', value, '');
   }
 
   /** Gets the value of "column-axis" */
   String get columnAxis =>
-    getPropertyValue('${_browserPrefix}column-axis');
+    getPropertyValue('${Device.cssPrefix}column-axis');
 
   /** Sets the value of "column-axis" */
   void set columnAxis(String value) {
-    setProperty('${_browserPrefix}column-axis', value, '');
+    setProperty('${Device.cssPrefix}column-axis', value, '');
   }
 
   /** Gets the value of "column-break-after" */
   String get columnBreakAfter =>
-    getPropertyValue('${_browserPrefix}column-break-after');
+    getPropertyValue('${Device.cssPrefix}column-break-after');
 
   /** Sets the value of "column-break-after" */
   void set columnBreakAfter(String value) {
-    setProperty('${_browserPrefix}column-break-after', value, '');
+    setProperty('${Device.cssPrefix}column-break-after', value, '');
   }
 
   /** Gets the value of "column-break-before" */
   String get columnBreakBefore =>
-    getPropertyValue('${_browserPrefix}column-break-before');
+    getPropertyValue('${Device.cssPrefix}column-break-before');
 
   /** Sets the value of "column-break-before" */
   void set columnBreakBefore(String value) {
-    setProperty('${_browserPrefix}column-break-before', value, '');
+    setProperty('${Device.cssPrefix}column-break-before', value, '');
   }
 
   /** Gets the value of "column-break-inside" */
   String get columnBreakInside =>
-    getPropertyValue('${_browserPrefix}column-break-inside');
+    getPropertyValue('${Device.cssPrefix}column-break-inside');
 
   /** Sets the value of "column-break-inside" */
   void set columnBreakInside(String value) {
-    setProperty('${_browserPrefix}column-break-inside', value, '');
+    setProperty('${Device.cssPrefix}column-break-inside', value, '');
   }
 
   /** Gets the value of "column-count" */
   String get columnCount =>
-    getPropertyValue('${_browserPrefix}column-count');
+    getPropertyValue('${Device.cssPrefix}column-count');
 
   /** Sets the value of "column-count" */
   void set columnCount(String value) {
-    setProperty('${_browserPrefix}column-count', value, '');
+    setProperty('${Device.cssPrefix}column-count', value, '');
   }
 
   /** Gets the value of "column-gap" */
   String get columnGap =>
-    getPropertyValue('${_browserPrefix}column-gap');
+    getPropertyValue('${Device.cssPrefix}column-gap');
 
   /** Sets the value of "column-gap" */
   void set columnGap(String value) {
-    setProperty('${_browserPrefix}column-gap', value, '');
+    setProperty('${Device.cssPrefix}column-gap', value, '');
   }
 
   /** Gets the value of "column-progression" */
   String get columnProgression =>
-    getPropertyValue('${_browserPrefix}column-progression');
+    getPropertyValue('${Device.cssPrefix}column-progression');
 
   /** Sets the value of "column-progression" */
   void set columnProgression(String value) {
-    setProperty('${_browserPrefix}column-progression', value, '');
+    setProperty('${Device.cssPrefix}column-progression', value, '');
   }
 
   /** Gets the value of "column-rule" */
   String get columnRule =>
-    getPropertyValue('${_browserPrefix}column-rule');
+    getPropertyValue('${Device.cssPrefix}column-rule');
 
   /** Sets the value of "column-rule" */
   void set columnRule(String value) {
-    setProperty('${_browserPrefix}column-rule', value, '');
+    setProperty('${Device.cssPrefix}column-rule', value, '');
   }
 
   /** Gets the value of "column-rule-color" */
   String get columnRuleColor =>
-    getPropertyValue('${_browserPrefix}column-rule-color');
+    getPropertyValue('${Device.cssPrefix}column-rule-color');
 
   /** Sets the value of "column-rule-color" */
   void set columnRuleColor(String value) {
-    setProperty('${_browserPrefix}column-rule-color', value, '');
+    setProperty('${Device.cssPrefix}column-rule-color', value, '');
   }
 
   /** Gets the value of "column-rule-style" */
   String get columnRuleStyle =>
-    getPropertyValue('${_browserPrefix}column-rule-style');
+    getPropertyValue('${Device.cssPrefix}column-rule-style');
 
   /** Sets the value of "column-rule-style" */
   void set columnRuleStyle(String value) {
-    setProperty('${_browserPrefix}column-rule-style', value, '');
+    setProperty('${Device.cssPrefix}column-rule-style', value, '');
   }
 
   /** Gets the value of "column-rule-width" */
   String get columnRuleWidth =>
-    getPropertyValue('${_browserPrefix}column-rule-width');
+    getPropertyValue('${Device.cssPrefix}column-rule-width');
 
   /** Sets the value of "column-rule-width" */
   void set columnRuleWidth(String value) {
-    setProperty('${_browserPrefix}column-rule-width', value, '');
+    setProperty('${Device.cssPrefix}column-rule-width', value, '');
   }
 
   /** Gets the value of "column-span" */
   String get columnSpan =>
-    getPropertyValue('${_browserPrefix}column-span');
+    getPropertyValue('${Device.cssPrefix}column-span');
 
   /** Sets the value of "column-span" */
   void set columnSpan(String value) {
-    setProperty('${_browserPrefix}column-span', value, '');
+    setProperty('${Device.cssPrefix}column-span', value, '');
   }
 
   /** Gets the value of "column-width" */
   String get columnWidth =>
-    getPropertyValue('${_browserPrefix}column-width');
+    getPropertyValue('${Device.cssPrefix}column-width');
 
   /** Sets the value of "column-width" */
   void set columnWidth(String value) {
-    setProperty('${_browserPrefix}column-width', value, '');
+    setProperty('${Device.cssPrefix}column-width', value, '');
   }
 
   /** Gets the value of "columns" */
   String get columns =>
-    getPropertyValue('${_browserPrefix}columns');
+    getPropertyValue('${Device.cssPrefix}columns');
 
   /** Sets the value of "columns" */
   void set columns(String value) {
-    setProperty('${_browserPrefix}columns', value, '');
+    setProperty('${Device.cssPrefix}columns', value, '');
   }
 
   /** Gets the value of "content" */
@@ -4058,11 +4145,11 @@
 
   /** Gets the value of "dashboard-region" */
   String get dashboardRegion =>
-    getPropertyValue('${_browserPrefix}dashboard-region');
+    getPropertyValue('${Device.cssPrefix}dashboard-region');
 
   /** Sets the value of "dashboard-region" */
   void set dashboardRegion(String value) {
-    setProperty('${_browserPrefix}dashboard-region', value, '');
+    setProperty('${Device.cssPrefix}dashboard-region', value, '');
   }
 
   /** Gets the value of "direction" */
@@ -4094,74 +4181,74 @@
 
   /** Gets the value of "filter" */
   String get filter =>
-    getPropertyValue('${_browserPrefix}filter');
+    getPropertyValue('${Device.cssPrefix}filter');
 
   /** Sets the value of "filter" */
   void set filter(String value) {
-    setProperty('${_browserPrefix}filter', value, '');
+    setProperty('${Device.cssPrefix}filter', value, '');
   }
 
   /** Gets the value of "flex" */
   String get flex =>
-    getPropertyValue('${_browserPrefix}flex');
+    getPropertyValue('${Device.cssPrefix}flex');
 
   /** Sets the value of "flex" */
   void set flex(String value) {
-    setProperty('${_browserPrefix}flex', value, '');
+    setProperty('${Device.cssPrefix}flex', value, '');
   }
 
   /** Gets the value of "flex-basis" */
   String get flexBasis =>
-    getPropertyValue('${_browserPrefix}flex-basis');
+    getPropertyValue('${Device.cssPrefix}flex-basis');
 
   /** Sets the value of "flex-basis" */
   void set flexBasis(String value) {
-    setProperty('${_browserPrefix}flex-basis', value, '');
+    setProperty('${Device.cssPrefix}flex-basis', value, '');
   }
 
   /** Gets the value of "flex-direction" */
   String get flexDirection =>
-    getPropertyValue('${_browserPrefix}flex-direction');
+    getPropertyValue('${Device.cssPrefix}flex-direction');
 
   /** Sets the value of "flex-direction" */
   void set flexDirection(String value) {
-    setProperty('${_browserPrefix}flex-direction', value, '');
+    setProperty('${Device.cssPrefix}flex-direction', value, '');
   }
 
   /** Gets the value of "flex-flow" */
   String get flexFlow =>
-    getPropertyValue('${_browserPrefix}flex-flow');
+    getPropertyValue('${Device.cssPrefix}flex-flow');
 
   /** Sets the value of "flex-flow" */
   void set flexFlow(String value) {
-    setProperty('${_browserPrefix}flex-flow', value, '');
+    setProperty('${Device.cssPrefix}flex-flow', value, '');
   }
 
   /** Gets the value of "flex-grow" */
   String get flexGrow =>
-    getPropertyValue('${_browserPrefix}flex-grow');
+    getPropertyValue('${Device.cssPrefix}flex-grow');
 
   /** Sets the value of "flex-grow" */
   void set flexGrow(String value) {
-    setProperty('${_browserPrefix}flex-grow', value, '');
+    setProperty('${Device.cssPrefix}flex-grow', value, '');
   }
 
   /** Gets the value of "flex-shrink" */
   String get flexShrink =>
-    getPropertyValue('${_browserPrefix}flex-shrink');
+    getPropertyValue('${Device.cssPrefix}flex-shrink');
 
   /** Sets the value of "flex-shrink" */
   void set flexShrink(String value) {
-    setProperty('${_browserPrefix}flex-shrink', value, '');
+    setProperty('${Device.cssPrefix}flex-shrink', value, '');
   }
 
   /** Gets the value of "flex-wrap" */
   String get flexWrap =>
-    getPropertyValue('${_browserPrefix}flex-wrap');
+    getPropertyValue('${Device.cssPrefix}flex-wrap');
 
   /** Sets the value of "flex-wrap" */
   void set flexWrap(String value) {
-    setProperty('${_browserPrefix}flex-wrap', value, '');
+    setProperty('${Device.cssPrefix}flex-wrap', value, '');
   }
 
   /** Gets the value of "float" */
@@ -4175,20 +4262,20 @@
 
   /** Gets the value of "flow-from" */
   String get flowFrom =>
-    getPropertyValue('${_browserPrefix}flow-from');
+    getPropertyValue('${Device.cssPrefix}flow-from');
 
   /** Sets the value of "flow-from" */
   void set flowFrom(String value) {
-    setProperty('${_browserPrefix}flow-from', value, '');
+    setProperty('${Device.cssPrefix}flow-from', value, '');
   }
 
   /** Gets the value of "flow-into" */
   String get flowInto =>
-    getPropertyValue('${_browserPrefix}flow-into');
+    getPropertyValue('${Device.cssPrefix}flow-into');
 
   /** Sets the value of "flow-into" */
   void set flowInto(String value) {
-    setProperty('${_browserPrefix}flow-into', value, '');
+    setProperty('${Device.cssPrefix}flow-into', value, '');
   }
 
   /** Gets the value of "font" */
@@ -4211,20 +4298,20 @@
 
   /** Gets the value of "font-feature-settings" */
   String get fontFeatureSettings =>
-    getPropertyValue('${_browserPrefix}font-feature-settings');
+    getPropertyValue('${Device.cssPrefix}font-feature-settings');
 
   /** Sets the value of "font-feature-settings" */
   void set fontFeatureSettings(String value) {
-    setProperty('${_browserPrefix}font-feature-settings', value, '');
+    setProperty('${Device.cssPrefix}font-feature-settings', value, '');
   }
 
   /** Gets the value of "font-kerning" */
   String get fontKerning =>
-    getPropertyValue('${_browserPrefix}font-kerning');
+    getPropertyValue('${Device.cssPrefix}font-kerning');
 
   /** Sets the value of "font-kerning" */
   void set fontKerning(String value) {
-    setProperty('${_browserPrefix}font-kerning', value, '');
+    setProperty('${Device.cssPrefix}font-kerning', value, '');
   }
 
   /** Gets the value of "font-size" */
@@ -4238,20 +4325,20 @@
 
   /** Gets the value of "font-size-delta" */
   String get fontSizeDelta =>
-    getPropertyValue('${_browserPrefix}font-size-delta');
+    getPropertyValue('${Device.cssPrefix}font-size-delta');
 
   /** Sets the value of "font-size-delta" */
   void set fontSizeDelta(String value) {
-    setProperty('${_browserPrefix}font-size-delta', value, '');
+    setProperty('${Device.cssPrefix}font-size-delta', value, '');
   }
 
   /** Gets the value of "font-smoothing" */
   String get fontSmoothing =>
-    getPropertyValue('${_browserPrefix}font-smoothing');
+    getPropertyValue('${Device.cssPrefix}font-smoothing');
 
   /** Sets the value of "font-smoothing" */
   void set fontSmoothing(String value) {
-    setProperty('${_browserPrefix}font-smoothing', value, '');
+    setProperty('${Device.cssPrefix}font-smoothing', value, '');
   }
 
   /** Gets the value of "font-stretch" */
@@ -4283,11 +4370,11 @@
 
   /** Gets the value of "font-variant-ligatures" */
   String get fontVariantLigatures =>
-    getPropertyValue('${_browserPrefix}font-variant-ligatures');
+    getPropertyValue('${Device.cssPrefix}font-variant-ligatures');
 
   /** Sets the value of "font-variant-ligatures" */
   void set fontVariantLigatures(String value) {
-    setProperty('${_browserPrefix}font-variant-ligatures', value, '');
+    setProperty('${Device.cssPrefix}font-variant-ligatures', value, '');
   }
 
   /** Gets the value of "font-weight" */
@@ -4301,38 +4388,38 @@
 
   /** Gets the value of "grid-column" */
   String get gridColumn =>
-    getPropertyValue('${_browserPrefix}grid-column');
+    getPropertyValue('${Device.cssPrefix}grid-column');
 
   /** Sets the value of "grid-column" */
   void set gridColumn(String value) {
-    setProperty('${_browserPrefix}grid-column', value, '');
+    setProperty('${Device.cssPrefix}grid-column', value, '');
   }
 
   /** Gets the value of "grid-columns" */
   String get gridColumns =>
-    getPropertyValue('${_browserPrefix}grid-columns');
+    getPropertyValue('${Device.cssPrefix}grid-columns');
 
   /** Sets the value of "grid-columns" */
   void set gridColumns(String value) {
-    setProperty('${_browserPrefix}grid-columns', value, '');
+    setProperty('${Device.cssPrefix}grid-columns', value, '');
   }
 
   /** Gets the value of "grid-row" */
   String get gridRow =>
-    getPropertyValue('${_browserPrefix}grid-row');
+    getPropertyValue('${Device.cssPrefix}grid-row');
 
   /** Sets the value of "grid-row" */
   void set gridRow(String value) {
-    setProperty('${_browserPrefix}grid-row', value, '');
+    setProperty('${Device.cssPrefix}grid-row', value, '');
   }
 
   /** Gets the value of "grid-rows" */
   String get gridRows =>
-    getPropertyValue('${_browserPrefix}grid-rows');
+    getPropertyValue('${Device.cssPrefix}grid-rows');
 
   /** Sets the value of "grid-rows" */
   void set gridRows(String value) {
-    setProperty('${_browserPrefix}grid-rows', value, '');
+    setProperty('${Device.cssPrefix}grid-rows', value, '');
   }
 
   /** Gets the value of "height" */
@@ -4346,56 +4433,56 @@
 
   /** Gets the value of "highlight" */
   String get highlight =>
-    getPropertyValue('${_browserPrefix}highlight');
+    getPropertyValue('${Device.cssPrefix}highlight');
 
   /** Sets the value of "highlight" */
   void set highlight(String value) {
-    setProperty('${_browserPrefix}highlight', value, '');
+    setProperty('${Device.cssPrefix}highlight', value, '');
   }
 
   /** Gets the value of "hyphenate-character" */
   String get hyphenateCharacter =>
-    getPropertyValue('${_browserPrefix}hyphenate-character');
+    getPropertyValue('${Device.cssPrefix}hyphenate-character');
 
   /** Sets the value of "hyphenate-character" */
   void set hyphenateCharacter(String value) {
-    setProperty('${_browserPrefix}hyphenate-character', value, '');
+    setProperty('${Device.cssPrefix}hyphenate-character', value, '');
   }
 
   /** Gets the value of "hyphenate-limit-after" */
   String get hyphenateLimitAfter =>
-    getPropertyValue('${_browserPrefix}hyphenate-limit-after');
+    getPropertyValue('${Device.cssPrefix}hyphenate-limit-after');
 
   /** Sets the value of "hyphenate-limit-after" */
   void set hyphenateLimitAfter(String value) {
-    setProperty('${_browserPrefix}hyphenate-limit-after', value, '');
+    setProperty('${Device.cssPrefix}hyphenate-limit-after', value, '');
   }
 
   /** Gets the value of "hyphenate-limit-before" */
   String get hyphenateLimitBefore =>
-    getPropertyValue('${_browserPrefix}hyphenate-limit-before');
+    getPropertyValue('${Device.cssPrefix}hyphenate-limit-before');
 
   /** Sets the value of "hyphenate-limit-before" */
   void set hyphenateLimitBefore(String value) {
-    setProperty('${_browserPrefix}hyphenate-limit-before', value, '');
+    setProperty('${Device.cssPrefix}hyphenate-limit-before', value, '');
   }
 
   /** Gets the value of "hyphenate-limit-lines" */
   String get hyphenateLimitLines =>
-    getPropertyValue('${_browserPrefix}hyphenate-limit-lines');
+    getPropertyValue('${Device.cssPrefix}hyphenate-limit-lines');
 
   /** Sets the value of "hyphenate-limit-lines" */
   void set hyphenateLimitLines(String value) {
-    setProperty('${_browserPrefix}hyphenate-limit-lines', value, '');
+    setProperty('${Device.cssPrefix}hyphenate-limit-lines', value, '');
   }
 
   /** Gets the value of "hyphens" */
   String get hyphens =>
-    getPropertyValue('${_browserPrefix}hyphens');
+    getPropertyValue('${Device.cssPrefix}hyphens');
 
   /** Sets the value of "hyphens" */
   void set hyphens(String value) {
-    setProperty('${_browserPrefix}hyphens', value, '');
+    setProperty('${Device.cssPrefix}hyphens', value, '');
   }
 
   /** Gets the value of "image-orientation" */
@@ -4427,11 +4514,11 @@
 
   /** Gets the value of "justify-content" */
   String get justifyContent =>
-    getPropertyValue('${_browserPrefix}justify-content');
+    getPropertyValue('${Device.cssPrefix}justify-content');
 
   /** Sets the value of "justify-content" */
   void set justifyContent(String value) {
-    setProperty('${_browserPrefix}justify-content', value, '');
+    setProperty('${Device.cssPrefix}justify-content', value, '');
   }
 
   /** Gets the value of "left" */
@@ -4454,47 +4541,47 @@
 
   /** Gets the value of "line-align" */
   String get lineAlign =>
-    getPropertyValue('${_browserPrefix}line-align');
+    getPropertyValue('${Device.cssPrefix}line-align');
 
   /** Sets the value of "line-align" */
   void set lineAlign(String value) {
-    setProperty('${_browserPrefix}line-align', value, '');
+    setProperty('${Device.cssPrefix}line-align', value, '');
   }
 
   /** Gets the value of "line-box-contain" */
   String get lineBoxContain =>
-    getPropertyValue('${_browserPrefix}line-box-contain');
+    getPropertyValue('${Device.cssPrefix}line-box-contain');
 
   /** Sets the value of "line-box-contain" */
   void set lineBoxContain(String value) {
-    setProperty('${_browserPrefix}line-box-contain', value, '');
+    setProperty('${Device.cssPrefix}line-box-contain', value, '');
   }
 
   /** Gets the value of "line-break" */
   String get lineBreak =>
-    getPropertyValue('${_browserPrefix}line-break');
+    getPropertyValue('${Device.cssPrefix}line-break');
 
   /** Sets the value of "line-break" */
   void set lineBreak(String value) {
-    setProperty('${_browserPrefix}line-break', value, '');
+    setProperty('${Device.cssPrefix}line-break', value, '');
   }
 
   /** Gets the value of "line-clamp" */
   String get lineClamp =>
-    getPropertyValue('${_browserPrefix}line-clamp');
+    getPropertyValue('${Device.cssPrefix}line-clamp');
 
   /** Sets the value of "line-clamp" */
   void set lineClamp(String value) {
-    setProperty('${_browserPrefix}line-clamp', value, '');
+    setProperty('${Device.cssPrefix}line-clamp', value, '');
   }
 
   /** Gets the value of "line-grid" */
   String get lineGrid =>
-    getPropertyValue('${_browserPrefix}line-grid');
+    getPropertyValue('${Device.cssPrefix}line-grid');
 
   /** Sets the value of "line-grid" */
   void set lineGrid(String value) {
-    setProperty('${_browserPrefix}line-grid', value, '');
+    setProperty('${Device.cssPrefix}line-grid', value, '');
   }
 
   /** Gets the value of "line-height" */
@@ -4508,11 +4595,11 @@
 
   /** Gets the value of "line-snap" */
   String get lineSnap =>
-    getPropertyValue('${_browserPrefix}line-snap');
+    getPropertyValue('${Device.cssPrefix}line-snap');
 
   /** Sets the value of "line-snap" */
   void set lineSnap(String value) {
-    setProperty('${_browserPrefix}line-snap', value, '');
+    setProperty('${Device.cssPrefix}line-snap', value, '');
   }
 
   /** Gets the value of "list-style" */
@@ -4553,29 +4640,29 @@
 
   /** Gets the value of "locale" */
   String get locale =>
-    getPropertyValue('${_browserPrefix}locale');
+    getPropertyValue('${Device.cssPrefix}locale');
 
   /** Sets the value of "locale" */
   void set locale(String value) {
-    setProperty('${_browserPrefix}locale', value, '');
+    setProperty('${Device.cssPrefix}locale', value, '');
   }
 
   /** Gets the value of "logical-height" */
   String get logicalHeight =>
-    getPropertyValue('${_browserPrefix}logical-height');
+    getPropertyValue('${Device.cssPrefix}logical-height');
 
   /** Sets the value of "logical-height" */
   void set logicalHeight(String value) {
-    setProperty('${_browserPrefix}logical-height', value, '');
+    setProperty('${Device.cssPrefix}logical-height', value, '');
   }
 
   /** Gets the value of "logical-width" */
   String get logicalWidth =>
-    getPropertyValue('${_browserPrefix}logical-width');
+    getPropertyValue('${Device.cssPrefix}logical-width');
 
   /** Sets the value of "logical-width" */
   void set logicalWidth(String value) {
-    setProperty('${_browserPrefix}logical-width', value, '');
+    setProperty('${Device.cssPrefix}logical-width', value, '');
   }
 
   /** Gets the value of "margin" */
@@ -4589,38 +4676,38 @@
 
   /** Gets the value of "margin-after" */
   String get marginAfter =>
-    getPropertyValue('${_browserPrefix}margin-after');
+    getPropertyValue('${Device.cssPrefix}margin-after');
 
   /** Sets the value of "margin-after" */
   void set marginAfter(String value) {
-    setProperty('${_browserPrefix}margin-after', value, '');
+    setProperty('${Device.cssPrefix}margin-after', value, '');
   }
 
   /** Gets the value of "margin-after-collapse" */
   String get marginAfterCollapse =>
-    getPropertyValue('${_browserPrefix}margin-after-collapse');
+    getPropertyValue('${Device.cssPrefix}margin-after-collapse');
 
   /** Sets the value of "margin-after-collapse" */
   void set marginAfterCollapse(String value) {
-    setProperty('${_browserPrefix}margin-after-collapse', value, '');
+    setProperty('${Device.cssPrefix}margin-after-collapse', value, '');
   }
 
   /** Gets the value of "margin-before" */
   String get marginBefore =>
-    getPropertyValue('${_browserPrefix}margin-before');
+    getPropertyValue('${Device.cssPrefix}margin-before');
 
   /** Sets the value of "margin-before" */
   void set marginBefore(String value) {
-    setProperty('${_browserPrefix}margin-before', value, '');
+    setProperty('${Device.cssPrefix}margin-before', value, '');
   }
 
   /** Gets the value of "margin-before-collapse" */
   String get marginBeforeCollapse =>
-    getPropertyValue('${_browserPrefix}margin-before-collapse');
+    getPropertyValue('${Device.cssPrefix}margin-before-collapse');
 
   /** Sets the value of "margin-before-collapse" */
   void set marginBeforeCollapse(String value) {
-    setProperty('${_browserPrefix}margin-before-collapse', value, '');
+    setProperty('${Device.cssPrefix}margin-before-collapse', value, '');
   }
 
   /** Gets the value of "margin-bottom" */
@@ -4634,29 +4721,29 @@
 
   /** Gets the value of "margin-bottom-collapse" */
   String get marginBottomCollapse =>
-    getPropertyValue('${_browserPrefix}margin-bottom-collapse');
+    getPropertyValue('${Device.cssPrefix}margin-bottom-collapse');
 
   /** Sets the value of "margin-bottom-collapse" */
   void set marginBottomCollapse(String value) {
-    setProperty('${_browserPrefix}margin-bottom-collapse', value, '');
+    setProperty('${Device.cssPrefix}margin-bottom-collapse', value, '');
   }
 
   /** Gets the value of "margin-collapse" */
   String get marginCollapse =>
-    getPropertyValue('${_browserPrefix}margin-collapse');
+    getPropertyValue('${Device.cssPrefix}margin-collapse');
 
   /** Sets the value of "margin-collapse" */
   void set marginCollapse(String value) {
-    setProperty('${_browserPrefix}margin-collapse', value, '');
+    setProperty('${Device.cssPrefix}margin-collapse', value, '');
   }
 
   /** Gets the value of "margin-end" */
   String get marginEnd =>
-    getPropertyValue('${_browserPrefix}margin-end');
+    getPropertyValue('${Device.cssPrefix}margin-end');
 
   /** Sets the value of "margin-end" */
   void set marginEnd(String value) {
-    setProperty('${_browserPrefix}margin-end', value, '');
+    setProperty('${Device.cssPrefix}margin-end', value, '');
   }
 
   /** Gets the value of "margin-left" */
@@ -4679,11 +4766,11 @@
 
   /** Gets the value of "margin-start" */
   String get marginStart =>
-    getPropertyValue('${_browserPrefix}margin-start');
+    getPropertyValue('${Device.cssPrefix}margin-start');
 
   /** Sets the value of "margin-start" */
   void set marginStart(String value) {
-    setProperty('${_browserPrefix}margin-start', value, '');
+    setProperty('${Device.cssPrefix}margin-start', value, '');
   }
 
   /** Gets the value of "margin-top" */
@@ -4697,236 +4784,236 @@
 
   /** Gets the value of "margin-top-collapse" */
   String get marginTopCollapse =>
-    getPropertyValue('${_browserPrefix}margin-top-collapse');
+    getPropertyValue('${Device.cssPrefix}margin-top-collapse');
 
   /** Sets the value of "margin-top-collapse" */
   void set marginTopCollapse(String value) {
-    setProperty('${_browserPrefix}margin-top-collapse', value, '');
+    setProperty('${Device.cssPrefix}margin-top-collapse', value, '');
   }
 
   /** Gets the value of "marquee" */
   String get marquee =>
-    getPropertyValue('${_browserPrefix}marquee');
+    getPropertyValue('${Device.cssPrefix}marquee');
 
   /** Sets the value of "marquee" */
   void set marquee(String value) {
-    setProperty('${_browserPrefix}marquee', value, '');
+    setProperty('${Device.cssPrefix}marquee', value, '');
   }
 
   /** Gets the value of "marquee-direction" */
   String get marqueeDirection =>
-    getPropertyValue('${_browserPrefix}marquee-direction');
+    getPropertyValue('${Device.cssPrefix}marquee-direction');
 
   /** Sets the value of "marquee-direction" */
   void set marqueeDirection(String value) {
-    setProperty('${_browserPrefix}marquee-direction', value, '');
+    setProperty('${Device.cssPrefix}marquee-direction', value, '');
   }
 
   /** Gets the value of "marquee-increment" */
   String get marqueeIncrement =>
-    getPropertyValue('${_browserPrefix}marquee-increment');
+    getPropertyValue('${Device.cssPrefix}marquee-increment');
 
   /** Sets the value of "marquee-increment" */
   void set marqueeIncrement(String value) {
-    setProperty('${_browserPrefix}marquee-increment', value, '');
+    setProperty('${Device.cssPrefix}marquee-increment', value, '');
   }
 
   /** Gets the value of "marquee-repetition" */
   String get marqueeRepetition =>
-    getPropertyValue('${_browserPrefix}marquee-repetition');
+    getPropertyValue('${Device.cssPrefix}marquee-repetition');
 
   /** Sets the value of "marquee-repetition" */
   void set marqueeRepetition(String value) {
-    setProperty('${_browserPrefix}marquee-repetition', value, '');
+    setProperty('${Device.cssPrefix}marquee-repetition', value, '');
   }
 
   /** Gets the value of "marquee-speed" */
   String get marqueeSpeed =>
-    getPropertyValue('${_browserPrefix}marquee-speed');
+    getPropertyValue('${Device.cssPrefix}marquee-speed');
 
   /** Sets the value of "marquee-speed" */
   void set marqueeSpeed(String value) {
-    setProperty('${_browserPrefix}marquee-speed', value, '');
+    setProperty('${Device.cssPrefix}marquee-speed', value, '');
   }
 
   /** Gets the value of "marquee-style" */
   String get marqueeStyle =>
-    getPropertyValue('${_browserPrefix}marquee-style');
+    getPropertyValue('${Device.cssPrefix}marquee-style');
 
   /** Sets the value of "marquee-style" */
   void set marqueeStyle(String value) {
-    setProperty('${_browserPrefix}marquee-style', value, '');
+    setProperty('${Device.cssPrefix}marquee-style', value, '');
   }
 
   /** Gets the value of "mask" */
   String get mask =>
-    getPropertyValue('${_browserPrefix}mask');
+    getPropertyValue('${Device.cssPrefix}mask');
 
   /** Sets the value of "mask" */
   void set mask(String value) {
-    setProperty('${_browserPrefix}mask', value, '');
+    setProperty('${Device.cssPrefix}mask', value, '');
   }
 
   /** Gets the value of "mask-attachment" */
   String get maskAttachment =>
-    getPropertyValue('${_browserPrefix}mask-attachment');
+    getPropertyValue('${Device.cssPrefix}mask-attachment');
 
   /** Sets the value of "mask-attachment" */
   void set maskAttachment(String value) {
-    setProperty('${_browserPrefix}mask-attachment', value, '');
+    setProperty('${Device.cssPrefix}mask-attachment', value, '');
   }
 
   /** Gets the value of "mask-box-image" */
   String get maskBoxImage =>
-    getPropertyValue('${_browserPrefix}mask-box-image');
+    getPropertyValue('${Device.cssPrefix}mask-box-image');
 
   /** Sets the value of "mask-box-image" */
   void set maskBoxImage(String value) {
-    setProperty('${_browserPrefix}mask-box-image', value, '');
+    setProperty('${Device.cssPrefix}mask-box-image', value, '');
   }
 
   /** Gets the value of "mask-box-image-outset" */
   String get maskBoxImageOutset =>
-    getPropertyValue('${_browserPrefix}mask-box-image-outset');
+    getPropertyValue('${Device.cssPrefix}mask-box-image-outset');
 
   /** Sets the value of "mask-box-image-outset" */
   void set maskBoxImageOutset(String value) {
-    setProperty('${_browserPrefix}mask-box-image-outset', value, '');
+    setProperty('${Device.cssPrefix}mask-box-image-outset', value, '');
   }
 
   /** Gets the value of "mask-box-image-repeat" */
   String get maskBoxImageRepeat =>
-    getPropertyValue('${_browserPrefix}mask-box-image-repeat');
+    getPropertyValue('${Device.cssPrefix}mask-box-image-repeat');
 
   /** Sets the value of "mask-box-image-repeat" */
   void set maskBoxImageRepeat(String value) {
-    setProperty('${_browserPrefix}mask-box-image-repeat', value, '');
+    setProperty('${Device.cssPrefix}mask-box-image-repeat', value, '');
   }
 
   /** Gets the value of "mask-box-image-slice" */
   String get maskBoxImageSlice =>
-    getPropertyValue('${_browserPrefix}mask-box-image-slice');
+    getPropertyValue('${Device.cssPrefix}mask-box-image-slice');
 
   /** Sets the value of "mask-box-image-slice" */
   void set maskBoxImageSlice(String value) {
-    setProperty('${_browserPrefix}mask-box-image-slice', value, '');
+    setProperty('${Device.cssPrefix}mask-box-image-slice', value, '');
   }
 
   /** Gets the value of "mask-box-image-source" */
   String get maskBoxImageSource =>
-    getPropertyValue('${_browserPrefix}mask-box-image-source');
+    getPropertyValue('${Device.cssPrefix}mask-box-image-source');
 
   /** Sets the value of "mask-box-image-source" */
   void set maskBoxImageSource(String value) {
-    setProperty('${_browserPrefix}mask-box-image-source', value, '');
+    setProperty('${Device.cssPrefix}mask-box-image-source', value, '');
   }
 
   /** Gets the value of "mask-box-image-width" */
   String get maskBoxImageWidth =>
-    getPropertyValue('${_browserPrefix}mask-box-image-width');
+    getPropertyValue('${Device.cssPrefix}mask-box-image-width');
 
   /** Sets the value of "mask-box-image-width" */
   void set maskBoxImageWidth(String value) {
-    setProperty('${_browserPrefix}mask-box-image-width', value, '');
+    setProperty('${Device.cssPrefix}mask-box-image-width', value, '');
   }
 
   /** Gets the value of "mask-clip" */
   String get maskClip =>
-    getPropertyValue('${_browserPrefix}mask-clip');
+    getPropertyValue('${Device.cssPrefix}mask-clip');
 
   /** Sets the value of "mask-clip" */
   void set maskClip(String value) {
-    setProperty('${_browserPrefix}mask-clip', value, '');
+    setProperty('${Device.cssPrefix}mask-clip', value, '');
   }
 
   /** Gets the value of "mask-composite" */
   String get maskComposite =>
-    getPropertyValue('${_browserPrefix}mask-composite');
+    getPropertyValue('${Device.cssPrefix}mask-composite');
 
   /** Sets the value of "mask-composite" */
   void set maskComposite(String value) {
-    setProperty('${_browserPrefix}mask-composite', value, '');
+    setProperty('${Device.cssPrefix}mask-composite', value, '');
   }
 
   /** Gets the value of "mask-image" */
   String get maskImage =>
-    getPropertyValue('${_browserPrefix}mask-image');
+    getPropertyValue('${Device.cssPrefix}mask-image');
 
   /** Sets the value of "mask-image" */
   void set maskImage(String value) {
-    setProperty('${_browserPrefix}mask-image', value, '');
+    setProperty('${Device.cssPrefix}mask-image', value, '');
   }
 
   /** Gets the value of "mask-origin" */
   String get maskOrigin =>
-    getPropertyValue('${_browserPrefix}mask-origin');
+    getPropertyValue('${Device.cssPrefix}mask-origin');
 
   /** Sets the value of "mask-origin" */
   void set maskOrigin(String value) {
-    setProperty('${_browserPrefix}mask-origin', value, '');
+    setProperty('${Device.cssPrefix}mask-origin', value, '');
   }
 
   /** Gets the value of "mask-position" */
   String get maskPosition =>
-    getPropertyValue('${_browserPrefix}mask-position');
+    getPropertyValue('${Device.cssPrefix}mask-position');
 
   /** Sets the value of "mask-position" */
   void set maskPosition(String value) {
-    setProperty('${_browserPrefix}mask-position', value, '');
+    setProperty('${Device.cssPrefix}mask-position', value, '');
   }
 
   /** Gets the value of "mask-position-x" */
   String get maskPositionX =>
-    getPropertyValue('${_browserPrefix}mask-position-x');
+    getPropertyValue('${Device.cssPrefix}mask-position-x');
 
   /** Sets the value of "mask-position-x" */
   void set maskPositionX(String value) {
-    setProperty('${_browserPrefix}mask-position-x', value, '');
+    setProperty('${Device.cssPrefix}mask-position-x', value, '');
   }
 
   /** Gets the value of "mask-position-y" */
   String get maskPositionY =>
-    getPropertyValue('${_browserPrefix}mask-position-y');
+    getPropertyValue('${Device.cssPrefix}mask-position-y');
 
   /** Sets the value of "mask-position-y" */
   void set maskPositionY(String value) {
-    setProperty('${_browserPrefix}mask-position-y', value, '');
+    setProperty('${Device.cssPrefix}mask-position-y', value, '');
   }
 
   /** Gets the value of "mask-repeat" */
   String get maskRepeat =>
-    getPropertyValue('${_browserPrefix}mask-repeat');
+    getPropertyValue('${Device.cssPrefix}mask-repeat');
 
   /** Sets the value of "mask-repeat" */
   void set maskRepeat(String value) {
-    setProperty('${_browserPrefix}mask-repeat', value, '');
+    setProperty('${Device.cssPrefix}mask-repeat', value, '');
   }
 
   /** Gets the value of "mask-repeat-x" */
   String get maskRepeatX =>
-    getPropertyValue('${_browserPrefix}mask-repeat-x');
+    getPropertyValue('${Device.cssPrefix}mask-repeat-x');
 
   /** Sets the value of "mask-repeat-x" */
   void set maskRepeatX(String value) {
-    setProperty('${_browserPrefix}mask-repeat-x', value, '');
+    setProperty('${Device.cssPrefix}mask-repeat-x', value, '');
   }
 
   /** Gets the value of "mask-repeat-y" */
   String get maskRepeatY =>
-    getPropertyValue('${_browserPrefix}mask-repeat-y');
+    getPropertyValue('${Device.cssPrefix}mask-repeat-y');
 
   /** Sets the value of "mask-repeat-y" */
   void set maskRepeatY(String value) {
-    setProperty('${_browserPrefix}mask-repeat-y', value, '');
+    setProperty('${Device.cssPrefix}mask-repeat-y', value, '');
   }
 
   /** Gets the value of "mask-size" */
   String get maskSize =>
-    getPropertyValue('${_browserPrefix}mask-size');
+    getPropertyValue('${Device.cssPrefix}mask-size');
 
   /** Sets the value of "mask-size" */
   void set maskSize(String value) {
-    setProperty('${_browserPrefix}mask-size', value, '');
+    setProperty('${Device.cssPrefix}mask-size', value, '');
   }
 
   /** Gets the value of "max-height" */
@@ -4940,20 +5027,20 @@
 
   /** Gets the value of "max-logical-height" */
   String get maxLogicalHeight =>
-    getPropertyValue('${_browserPrefix}max-logical-height');
+    getPropertyValue('${Device.cssPrefix}max-logical-height');
 
   /** Sets the value of "max-logical-height" */
   void set maxLogicalHeight(String value) {
-    setProperty('${_browserPrefix}max-logical-height', value, '');
+    setProperty('${Device.cssPrefix}max-logical-height', value, '');
   }
 
   /** Gets the value of "max-logical-width" */
   String get maxLogicalWidth =>
-    getPropertyValue('${_browserPrefix}max-logical-width');
+    getPropertyValue('${Device.cssPrefix}max-logical-width');
 
   /** Sets the value of "max-logical-width" */
   void set maxLogicalWidth(String value) {
-    setProperty('${_browserPrefix}max-logical-width', value, '');
+    setProperty('${Device.cssPrefix}max-logical-width', value, '');
   }
 
   /** Gets the value of "max-width" */
@@ -4985,20 +5072,20 @@
 
   /** Gets the value of "min-logical-height" */
   String get minLogicalHeight =>
-    getPropertyValue('${_browserPrefix}min-logical-height');
+    getPropertyValue('${Device.cssPrefix}min-logical-height');
 
   /** Sets the value of "min-logical-height" */
   void set minLogicalHeight(String value) {
-    setProperty('${_browserPrefix}min-logical-height', value, '');
+    setProperty('${Device.cssPrefix}min-logical-height', value, '');
   }
 
   /** Gets the value of "min-logical-width" */
   String get minLogicalWidth =>
-    getPropertyValue('${_browserPrefix}min-logical-width');
+    getPropertyValue('${Device.cssPrefix}min-logical-width');
 
   /** Sets the value of "min-logical-width" */
   void set minLogicalWidth(String value) {
-    setProperty('${_browserPrefix}min-logical-width', value, '');
+    setProperty('${Device.cssPrefix}min-logical-width', value, '');
   }
 
   /** Gets the value of "min-width" */
@@ -5021,11 +5108,11 @@
 
   /** Gets the value of "nbsp-mode" */
   String get nbspMode =>
-    getPropertyValue('${_browserPrefix}nbsp-mode');
+    getPropertyValue('${Device.cssPrefix}nbsp-mode');
 
   /** Sets the value of "nbsp-mode" */
   void set nbspMode(String value) {
-    setProperty('${_browserPrefix}nbsp-mode', value, '');
+    setProperty('${Device.cssPrefix}nbsp-mode', value, '');
   }
 
   /** Gets the value of "opacity" */
@@ -5039,11 +5126,11 @@
 
   /** Gets the value of "order" */
   String get order =>
-    getPropertyValue('${_browserPrefix}order');
+    getPropertyValue('${Device.cssPrefix}order');
 
   /** Sets the value of "order" */
   void set order(String value) {
-    setProperty('${_browserPrefix}order', value, '');
+    setProperty('${Device.cssPrefix}order', value, '');
   }
 
   /** Gets the value of "orientation" */
@@ -5120,11 +5207,11 @@
 
   /** Gets the value of "overflow-scrolling" */
   String get overflowScrolling =>
-    getPropertyValue('${_browserPrefix}overflow-scrolling');
+    getPropertyValue('${Device.cssPrefix}overflow-scrolling');
 
   /** Sets the value of "overflow-scrolling" */
   void set overflowScrolling(String value) {
-    setProperty('${_browserPrefix}overflow-scrolling', value, '');
+    setProperty('${Device.cssPrefix}overflow-scrolling', value, '');
   }
 
   /** Gets the value of "overflow-wrap" */
@@ -5165,20 +5252,20 @@
 
   /** Gets the value of "padding-after" */
   String get paddingAfter =>
-    getPropertyValue('${_browserPrefix}padding-after');
+    getPropertyValue('${Device.cssPrefix}padding-after');
 
   /** Sets the value of "padding-after" */
   void set paddingAfter(String value) {
-    setProperty('${_browserPrefix}padding-after', value, '');
+    setProperty('${Device.cssPrefix}padding-after', value, '');
   }
 
   /** Gets the value of "padding-before" */
   String get paddingBefore =>
-    getPropertyValue('${_browserPrefix}padding-before');
+    getPropertyValue('${Device.cssPrefix}padding-before');
 
   /** Sets the value of "padding-before" */
   void set paddingBefore(String value) {
-    setProperty('${_browserPrefix}padding-before', value, '');
+    setProperty('${Device.cssPrefix}padding-before', value, '');
   }
 
   /** Gets the value of "padding-bottom" */
@@ -5192,11 +5279,11 @@
 
   /** Gets the value of "padding-end" */
   String get paddingEnd =>
-    getPropertyValue('${_browserPrefix}padding-end');
+    getPropertyValue('${Device.cssPrefix}padding-end');
 
   /** Sets the value of "padding-end" */
   void set paddingEnd(String value) {
-    setProperty('${_browserPrefix}padding-end', value, '');
+    setProperty('${Device.cssPrefix}padding-end', value, '');
   }
 
   /** Gets the value of "padding-left" */
@@ -5219,11 +5306,11 @@
 
   /** Gets the value of "padding-start" */
   String get paddingStart =>
-    getPropertyValue('${_browserPrefix}padding-start');
+    getPropertyValue('${Device.cssPrefix}padding-start');
 
   /** Sets the value of "padding-start" */
   void set paddingStart(String value) {
-    setProperty('${_browserPrefix}padding-start', value, '');
+    setProperty('${Device.cssPrefix}padding-start', value, '');
   }
 
   /** Gets the value of "padding-top" */
@@ -5273,38 +5360,38 @@
 
   /** Gets the value of "perspective" */
   String get perspective =>
-    getPropertyValue('${_browserPrefix}perspective');
+    getPropertyValue('${Device.cssPrefix}perspective');
 
   /** Sets the value of "perspective" */
   void set perspective(String value) {
-    setProperty('${_browserPrefix}perspective', value, '');
+    setProperty('${Device.cssPrefix}perspective', value, '');
   }
 
   /** Gets the value of "perspective-origin" */
   String get perspectiveOrigin =>
-    getPropertyValue('${_browserPrefix}perspective-origin');
+    getPropertyValue('${Device.cssPrefix}perspective-origin');
 
   /** Sets the value of "perspective-origin" */
   void set perspectiveOrigin(String value) {
-    setProperty('${_browserPrefix}perspective-origin', value, '');
+    setProperty('${Device.cssPrefix}perspective-origin', value, '');
   }
 
   /** Gets the value of "perspective-origin-x" */
   String get perspectiveOriginX =>
-    getPropertyValue('${_browserPrefix}perspective-origin-x');
+    getPropertyValue('${Device.cssPrefix}perspective-origin-x');
 
   /** Sets the value of "perspective-origin-x" */
   void set perspectiveOriginX(String value) {
-    setProperty('${_browserPrefix}perspective-origin-x', value, '');
+    setProperty('${Device.cssPrefix}perspective-origin-x', value, '');
   }
 
   /** Gets the value of "perspective-origin-y" */
   String get perspectiveOriginY =>
-    getPropertyValue('${_browserPrefix}perspective-origin-y');
+    getPropertyValue('${Device.cssPrefix}perspective-origin-y');
 
   /** Sets the value of "perspective-origin-y" */
   void set perspectiveOriginY(String value) {
-    setProperty('${_browserPrefix}perspective-origin-y', value, '');
+    setProperty('${Device.cssPrefix}perspective-origin-y', value, '');
   }
 
   /** Gets the value of "pointer-events" */
@@ -5327,11 +5414,11 @@
 
   /** Gets the value of "print-color-adjust" */
   String get printColorAdjust =>
-    getPropertyValue('${_browserPrefix}print-color-adjust');
+    getPropertyValue('${Device.cssPrefix}print-color-adjust');
 
   /** Sets the value of "print-color-adjust" */
   void set printColorAdjust(String value) {
-    setProperty('${_browserPrefix}print-color-adjust', value, '');
+    setProperty('${Device.cssPrefix}print-color-adjust', value, '');
   }
 
   /** Gets the value of "quotes" */
@@ -5345,38 +5432,38 @@
 
   /** Gets the value of "region-break-after" */
   String get regionBreakAfter =>
-    getPropertyValue('${_browserPrefix}region-break-after');
+    getPropertyValue('${Device.cssPrefix}region-break-after');
 
   /** Sets the value of "region-break-after" */
   void set regionBreakAfter(String value) {
-    setProperty('${_browserPrefix}region-break-after', value, '');
+    setProperty('${Device.cssPrefix}region-break-after', value, '');
   }
 
   /** Gets the value of "region-break-before" */
   String get regionBreakBefore =>
-    getPropertyValue('${_browserPrefix}region-break-before');
+    getPropertyValue('${Device.cssPrefix}region-break-before');
 
   /** Sets the value of "region-break-before" */
   void set regionBreakBefore(String value) {
-    setProperty('${_browserPrefix}region-break-before', value, '');
+    setProperty('${Device.cssPrefix}region-break-before', value, '');
   }
 
   /** Gets the value of "region-break-inside" */
   String get regionBreakInside =>
-    getPropertyValue('${_browserPrefix}region-break-inside');
+    getPropertyValue('${Device.cssPrefix}region-break-inside');
 
   /** Sets the value of "region-break-inside" */
   void set regionBreakInside(String value) {
-    setProperty('${_browserPrefix}region-break-inside', value, '');
+    setProperty('${Device.cssPrefix}region-break-inside', value, '');
   }
 
   /** Gets the value of "region-overflow" */
   String get regionOverflow =>
-    getPropertyValue('${_browserPrefix}region-overflow');
+    getPropertyValue('${Device.cssPrefix}region-overflow');
 
   /** Sets the value of "region-overflow" */
   void set regionOverflow(String value) {
-    setProperty('${_browserPrefix}region-overflow', value, '');
+    setProperty('${Device.cssPrefix}region-overflow', value, '');
   }
 
   /** Gets the value of "resize" */
@@ -5399,47 +5486,47 @@
 
   /** Gets the value of "rtl-ordering" */
   String get rtlOrdering =>
-    getPropertyValue('${_browserPrefix}rtl-ordering');
+    getPropertyValue('${Device.cssPrefix}rtl-ordering');
 
   /** Sets the value of "rtl-ordering" */
   void set rtlOrdering(String value) {
-    setProperty('${_browserPrefix}rtl-ordering', value, '');
+    setProperty('${Device.cssPrefix}rtl-ordering', value, '');
   }
 
   /** Gets the value of "shape-inside" */
   String get shapeInside =>
-    getPropertyValue('${_browserPrefix}shape-inside');
+    getPropertyValue('${Device.cssPrefix}shape-inside');
 
   /** Sets the value of "shape-inside" */
   void set shapeInside(String value) {
-    setProperty('${_browserPrefix}shape-inside', value, '');
+    setProperty('${Device.cssPrefix}shape-inside', value, '');
   }
 
   /** Gets the value of "shape-margin" */
   String get shapeMargin =>
-    getPropertyValue('${_browserPrefix}shape-margin');
+    getPropertyValue('${Device.cssPrefix}shape-margin');
 
   /** Sets the value of "shape-margin" */
   void set shapeMargin(String value) {
-    setProperty('${_browserPrefix}shape-margin', value, '');
+    setProperty('${Device.cssPrefix}shape-margin', value, '');
   }
 
   /** Gets the value of "shape-outside" */
   String get shapeOutside =>
-    getPropertyValue('${_browserPrefix}shape-outside');
+    getPropertyValue('${Device.cssPrefix}shape-outside');
 
   /** Sets the value of "shape-outside" */
   void set shapeOutside(String value) {
-    setProperty('${_browserPrefix}shape-outside', value, '');
+    setProperty('${Device.cssPrefix}shape-outside', value, '');
   }
 
   /** Gets the value of "shape-padding" */
   String get shapePadding =>
-    getPropertyValue('${_browserPrefix}shape-padding');
+    getPropertyValue('${Device.cssPrefix}shape-padding');
 
   /** Sets the value of "shape-padding" */
   void set shapePadding(String value) {
-    setProperty('${_browserPrefix}shape-padding', value, '');
+    setProperty('${Device.cssPrefix}shape-padding', value, '');
   }
 
   /** Gets the value of "size" */
@@ -5489,11 +5576,11 @@
 
   /** Gets the value of "tap-highlight-color" */
   String get tapHighlightColor =>
-    getPropertyValue('${_browserPrefix}tap-highlight-color');
+    getPropertyValue('${Device.cssPrefix}tap-highlight-color');
 
   /** Sets the value of "tap-highlight-color" */
   void set tapHighlightColor(String value) {
-    setProperty('${_browserPrefix}tap-highlight-color', value, '');
+    setProperty('${Device.cssPrefix}tap-highlight-color', value, '');
   }
 
   /** Gets the value of "text-align" */
@@ -5507,20 +5594,20 @@
 
   /** Gets the value of "text-align-last" */
   String get textAlignLast =>
-    getPropertyValue('${_browserPrefix}text-align-last');
+    getPropertyValue('${Device.cssPrefix}text-align-last');
 
   /** Sets the value of "text-align-last" */
   void set textAlignLast(String value) {
-    setProperty('${_browserPrefix}text-align-last', value, '');
+    setProperty('${Device.cssPrefix}text-align-last', value, '');
   }
 
   /** Gets the value of "text-combine" */
   String get textCombine =>
-    getPropertyValue('${_browserPrefix}text-combine');
+    getPropertyValue('${Device.cssPrefix}text-combine');
 
   /** Sets the value of "text-combine" */
   void set textCombine(String value) {
-    setProperty('${_browserPrefix}text-combine', value, '');
+    setProperty('${Device.cssPrefix}text-combine', value, '');
   }
 
   /** Gets the value of "text-decoration" */
@@ -5534,74 +5621,74 @@
 
   /** Gets the value of "text-decoration-line" */
   String get textDecorationLine =>
-    getPropertyValue('${_browserPrefix}text-decoration-line');
+    getPropertyValue('${Device.cssPrefix}text-decoration-line');
 
   /** Sets the value of "text-decoration-line" */
   void set textDecorationLine(String value) {
-    setProperty('${_browserPrefix}text-decoration-line', value, '');
+    setProperty('${Device.cssPrefix}text-decoration-line', value, '');
   }
 
   /** Gets the value of "text-decoration-style" */
   String get textDecorationStyle =>
-    getPropertyValue('${_browserPrefix}text-decoration-style');
+    getPropertyValue('${Device.cssPrefix}text-decoration-style');
 
   /** Sets the value of "text-decoration-style" */
   void set textDecorationStyle(String value) {
-    setProperty('${_browserPrefix}text-decoration-style', value, '');
+    setProperty('${Device.cssPrefix}text-decoration-style', value, '');
   }
 
   /** Gets the value of "text-decorations-in-effect" */
   String get textDecorationsInEffect =>
-    getPropertyValue('${_browserPrefix}text-decorations-in-effect');
+    getPropertyValue('${Device.cssPrefix}text-decorations-in-effect');
 
   /** Sets the value of "text-decorations-in-effect" */
   void set textDecorationsInEffect(String value) {
-    setProperty('${_browserPrefix}text-decorations-in-effect', value, '');
+    setProperty('${Device.cssPrefix}text-decorations-in-effect', value, '');
   }
 
   /** Gets the value of "text-emphasis" */
   String get textEmphasis =>
-    getPropertyValue('${_browserPrefix}text-emphasis');
+    getPropertyValue('${Device.cssPrefix}text-emphasis');
 
   /** Sets the value of "text-emphasis" */
   void set textEmphasis(String value) {
-    setProperty('${_browserPrefix}text-emphasis', value, '');
+    setProperty('${Device.cssPrefix}text-emphasis', value, '');
   }
 
   /** Gets the value of "text-emphasis-color" */
   String get textEmphasisColor =>
-    getPropertyValue('${_browserPrefix}text-emphasis-color');
+    getPropertyValue('${Device.cssPrefix}text-emphasis-color');
 
   /** Sets the value of "text-emphasis-color" */
   void set textEmphasisColor(String value) {
-    setProperty('${_browserPrefix}text-emphasis-color', value, '');
+    setProperty('${Device.cssPrefix}text-emphasis-color', value, '');
   }
 
   /** Gets the value of "text-emphasis-position" */
   String get textEmphasisPosition =>
-    getPropertyValue('${_browserPrefix}text-emphasis-position');
+    getPropertyValue('${Device.cssPrefix}text-emphasis-position');
 
   /** Sets the value of "text-emphasis-position" */
   void set textEmphasisPosition(String value) {
-    setProperty('${_browserPrefix}text-emphasis-position', value, '');
+    setProperty('${Device.cssPrefix}text-emphasis-position', value, '');
   }
 
   /** Gets the value of "text-emphasis-style" */
   String get textEmphasisStyle =>
-    getPropertyValue('${_browserPrefix}text-emphasis-style');
+    getPropertyValue('${Device.cssPrefix}text-emphasis-style');
 
   /** Sets the value of "text-emphasis-style" */
   void set textEmphasisStyle(String value) {
-    setProperty('${_browserPrefix}text-emphasis-style', value, '');
+    setProperty('${Device.cssPrefix}text-emphasis-style', value, '');
   }
 
   /** Gets the value of "text-fill-color" */
   String get textFillColor =>
-    getPropertyValue('${_browserPrefix}text-fill-color');
+    getPropertyValue('${Device.cssPrefix}text-fill-color');
 
   /** Sets the value of "text-fill-color" */
   void set textFillColor(String value) {
-    setProperty('${_browserPrefix}text-fill-color', value, '');
+    setProperty('${Device.cssPrefix}text-fill-color', value, '');
   }
 
   /** Gets the value of "text-indent" */
@@ -5660,11 +5747,11 @@
 
   /** Gets the value of "text-orientation" */
   String get textOrientation =>
-    getPropertyValue('${_browserPrefix}text-orientation');
+    getPropertyValue('${Device.cssPrefix}text-orientation');
 
   /** Sets the value of "text-orientation" */
   void set textOrientation(String value) {
-    setProperty('${_browserPrefix}text-orientation', value, '');
+    setProperty('${Device.cssPrefix}text-orientation', value, '');
   }
 
   /** Gets the value of "text-overflow" */
@@ -5732,11 +5819,11 @@
 
   /** Gets the value of "text-security" */
   String get textSecurity =>
-    getPropertyValue('${_browserPrefix}text-security');
+    getPropertyValue('${Device.cssPrefix}text-security');
 
   /** Sets the value of "text-security" */
   void set textSecurity(String value) {
-    setProperty('${_browserPrefix}text-security', value, '');
+    setProperty('${Device.cssPrefix}text-security', value, '');
   }
 
   /** Gets the value of "text-shadow" */
@@ -5750,38 +5837,38 @@
 
   /** Gets the value of "text-size-adjust" */
   String get textSizeAdjust =>
-    getPropertyValue('${_browserPrefix}text-size-adjust');
+    getPropertyValue('${Device.cssPrefix}text-size-adjust');
 
   /** Sets the value of "text-size-adjust" */
   void set textSizeAdjust(String value) {
-    setProperty('${_browserPrefix}text-size-adjust', value, '');
+    setProperty('${Device.cssPrefix}text-size-adjust', value, '');
   }
 
   /** Gets the value of "text-stroke" */
   String get textStroke =>
-    getPropertyValue('${_browserPrefix}text-stroke');
+    getPropertyValue('${Device.cssPrefix}text-stroke');
 
   /** Sets the value of "text-stroke" */
   void set textStroke(String value) {
-    setProperty('${_browserPrefix}text-stroke', value, '');
+    setProperty('${Device.cssPrefix}text-stroke', value, '');
   }
 
   /** Gets the value of "text-stroke-color" */
   String get textStrokeColor =>
-    getPropertyValue('${_browserPrefix}text-stroke-color');
+    getPropertyValue('${Device.cssPrefix}text-stroke-color');
 
   /** Sets the value of "text-stroke-color" */
   void set textStrokeColor(String value) {
-    setProperty('${_browserPrefix}text-stroke-color', value, '');
+    setProperty('${Device.cssPrefix}text-stroke-color', value, '');
   }
 
   /** Gets the value of "text-stroke-width" */
   String get textStrokeWidth =>
-    getPropertyValue('${_browserPrefix}text-stroke-width');
+    getPropertyValue('${Device.cssPrefix}text-stroke-width');
 
   /** Sets the value of "text-stroke-width" */
   void set textStrokeWidth(String value) {
-    setProperty('${_browserPrefix}text-stroke-width', value, '');
+    setProperty('${Device.cssPrefix}text-stroke-width', value, '');
   }
 
   /** Gets the value of "text-transform" */
@@ -5849,56 +5936,56 @@
 
   /** Gets the value of "transform" */
   String get transform =>
-    getPropertyValue('${_browserPrefix}transform');
+    getPropertyValue('${Device.cssPrefix}transform');
 
   /** Sets the value of "transform" */
   void set transform(String value) {
-    setProperty('${_browserPrefix}transform', value, '');
+    setProperty('${Device.cssPrefix}transform', value, '');
   }
 
   /** Gets the value of "transform-origin" */
   String get transformOrigin =>
-    getPropertyValue('${_browserPrefix}transform-origin');
+    getPropertyValue('${Device.cssPrefix}transform-origin');
 
   /** Sets the value of "transform-origin" */
   void set transformOrigin(String value) {
-    setProperty('${_browserPrefix}transform-origin', value, '');
+    setProperty('${Device.cssPrefix}transform-origin', value, '');
   }
 
   /** Gets the value of "transform-origin-x" */
   String get transformOriginX =>
-    getPropertyValue('${_browserPrefix}transform-origin-x');
+    getPropertyValue('${Device.cssPrefix}transform-origin-x');
 
   /** Sets the value of "transform-origin-x" */
   void set transformOriginX(String value) {
-    setProperty('${_browserPrefix}transform-origin-x', value, '');
+    setProperty('${Device.cssPrefix}transform-origin-x', value, '');
   }
 
   /** Gets the value of "transform-origin-y" */
   String get transformOriginY =>
-    getPropertyValue('${_browserPrefix}transform-origin-y');
+    getPropertyValue('${Device.cssPrefix}transform-origin-y');
 
   /** Sets the value of "transform-origin-y" */
   void set transformOriginY(String value) {
-    setProperty('${_browserPrefix}transform-origin-y', value, '');
+    setProperty('${Device.cssPrefix}transform-origin-y', value, '');
   }
 
   /** Gets the value of "transform-origin-z" */
   String get transformOriginZ =>
-    getPropertyValue('${_browserPrefix}transform-origin-z');
+    getPropertyValue('${Device.cssPrefix}transform-origin-z');
 
   /** Sets the value of "transform-origin-z" */
   void set transformOriginZ(String value) {
-    setProperty('${_browserPrefix}transform-origin-z', value, '');
+    setProperty('${Device.cssPrefix}transform-origin-z', value, '');
   }
 
   /** Gets the value of "transform-style" */
   String get transformStyle =>
-    getPropertyValue('${_browserPrefix}transform-style');
+    getPropertyValue('${Device.cssPrefix}transform-style');
 
   /** Sets the value of "transform-style" */
   void set transformStyle(String value) {
-    setProperty('${_browserPrefix}transform-style', value, '');
+    setProperty('${Device.cssPrefix}transform-style', value, '');
   }
 
   /** Gets the value of "transition" */
@@ -5907,7 +5994,7 @@
   @SupportedBrowser(SupportedBrowser.IE, '10')
   @SupportedBrowser(SupportedBrowser.SAFARI)
   String get transition =>
-    getPropertyValue('${_browserPrefix}transition');
+    getPropertyValue('${Device.cssPrefix}transition');
 
   /** Sets the value of "transition" */
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -5915,43 +6002,43 @@
   @SupportedBrowser(SupportedBrowser.IE, '10')
   @SupportedBrowser(SupportedBrowser.SAFARI)
   void set transition(String value) {
-    setProperty('${_browserPrefix}transition', value, '');
+    setProperty('${Device.cssPrefix}transition', value, '');
   }
 
   /** Gets the value of "transition-delay" */
   String get transitionDelay =>
-    getPropertyValue('${_browserPrefix}transition-delay');
+    getPropertyValue('${Device.cssPrefix}transition-delay');
 
   /** Sets the value of "transition-delay" */
   void set transitionDelay(String value) {
-    setProperty('${_browserPrefix}transition-delay', value, '');
+    setProperty('${Device.cssPrefix}transition-delay', value, '');
   }
 
   /** Gets the value of "transition-duration" */
   String get transitionDuration =>
-    getPropertyValue('${_browserPrefix}transition-duration');
+    getPropertyValue('${Device.cssPrefix}transition-duration');
 
   /** Sets the value of "transition-duration" */
   void set transitionDuration(String value) {
-    setProperty('${_browserPrefix}transition-duration', value, '');
+    setProperty('${Device.cssPrefix}transition-duration', value, '');
   }
 
   /** Gets the value of "transition-property" */
   String get transitionProperty =>
-    getPropertyValue('${_browserPrefix}transition-property');
+    getPropertyValue('${Device.cssPrefix}transition-property');
 
   /** Sets the value of "transition-property" */
   void set transitionProperty(String value) {
-    setProperty('${_browserPrefix}transition-property', value, '');
+    setProperty('${Device.cssPrefix}transition-property', value, '');
   }
 
   /** Gets the value of "transition-timing-function" */
   String get transitionTimingFunction =>
-    getPropertyValue('${_browserPrefix}transition-timing-function');
+    getPropertyValue('${Device.cssPrefix}transition-timing-function');
 
   /** Sets the value of "transition-timing-function" */
   void set transitionTimingFunction(String value) {
-    setProperty('${_browserPrefix}transition-timing-function', value, '');
+    setProperty('${Device.cssPrefix}transition-timing-function', value, '');
   }
 
   /** Gets the value of "unicode-bidi" */
@@ -5974,29 +6061,29 @@
 
   /** Gets the value of "user-drag" */
   String get userDrag =>
-    getPropertyValue('${_browserPrefix}user-drag');
+    getPropertyValue('${Device.cssPrefix}user-drag');
 
   /** Sets the value of "user-drag" */
   void set userDrag(String value) {
-    setProperty('${_browserPrefix}user-drag', value, '');
+    setProperty('${Device.cssPrefix}user-drag', value, '');
   }
 
   /** Gets the value of "user-modify" */
   String get userModify =>
-    getPropertyValue('${_browserPrefix}user-modify');
+    getPropertyValue('${Device.cssPrefix}user-modify');
 
   /** Sets the value of "user-modify" */
   void set userModify(String value) {
-    setProperty('${_browserPrefix}user-modify', value, '');
+    setProperty('${Device.cssPrefix}user-modify', value, '');
   }
 
   /** Gets the value of "user-select" */
   String get userSelect =>
-    getPropertyValue('${_browserPrefix}user-select');
+    getPropertyValue('${Device.cssPrefix}user-select');
 
   /** Sets the value of "user-select" */
   void set userSelect(String value) {
-    setProperty('${_browserPrefix}user-select', value, '');
+    setProperty('${Device.cssPrefix}user-select', value, '');
   }
 
   /** Gets the value of "user-zoom" */
@@ -6082,38 +6169,38 @@
 
   /** Gets the value of "wrap" */
   String get wrap =>
-    getPropertyValue('${_browserPrefix}wrap');
+    getPropertyValue('${Device.cssPrefix}wrap');
 
   /** Sets the value of "wrap" */
   void set wrap(String value) {
-    setProperty('${_browserPrefix}wrap', value, '');
+    setProperty('${Device.cssPrefix}wrap', value, '');
   }
 
   /** Gets the value of "wrap-flow" */
   String get wrapFlow =>
-    getPropertyValue('${_browserPrefix}wrap-flow');
+    getPropertyValue('${Device.cssPrefix}wrap-flow');
 
   /** Sets the value of "wrap-flow" */
   void set wrapFlow(String value) {
-    setProperty('${_browserPrefix}wrap-flow', value, '');
+    setProperty('${Device.cssPrefix}wrap-flow', value, '');
   }
 
   /** Gets the value of "wrap-through" */
   String get wrapThrough =>
-    getPropertyValue('${_browserPrefix}wrap-through');
+    getPropertyValue('${Device.cssPrefix}wrap-through');
 
   /** Sets the value of "wrap-through" */
   void set wrapThrough(String value) {
-    setProperty('${_browserPrefix}wrap-through', value, '');
+    setProperty('${Device.cssPrefix}wrap-through', value, '');
   }
 
   /** Gets the value of "writing-mode" */
   String get writingMode =>
-    getPropertyValue('${_browserPrefix}writing-mode');
+    getPropertyValue('${Device.cssPrefix}writing-mode');
 
   /** Sets the value of "writing-mode" */
   void set writingMode(String value) {
-    setProperty('${_browserPrefix}writing-mode', value, '');
+    setProperty('${Device.cssPrefix}writing-mode', value, '');
   }
 
   /** Gets the value of "z-index" */
@@ -6472,7 +6559,14 @@
 
   @DomName('DataTransferItem.getAsString')
   @DocsEditable
-  void getAsString([StringCallback callback]) native "DataTransferItem_getAsString_Callback";
+  void _getAsString([_StringCallback callback]) native "DataTransferItem_getAsString_Callback";
+
+  Future<String> getAsString() {
+    var completer = new Completer<String>();
+    _getAsString(
+        (value) { completer.complete(value); });
+    return completer.future;
+  }
 
   @DomName('DataTransferItem.webkitGetAsEntry')
   @DocsEditable
@@ -6538,7 +6632,7 @@
 @DomName('DataView')
 class DataView extends ArrayBufferView {
   DataView.internal() : super.internal();
-  factory DataView(ArrayBuffer buffer, [int byteOffset, int byteLength]) => _create(buffer, byteOffset, byteLength);
+  factory DataView(/*ArrayBuffer*/ buffer, [int byteOffset, int byteLength]) => _create(buffer, byteOffset, byteLength);
 
   @DocsEditable
   static DataView _create(buffer, byteOffset, byteLength) native "DataView_constructorCallback";
@@ -6883,15 +6977,39 @@
 
   @DomName('DirectoryEntry.getDirectory')
   @DocsEditable
-  void getDirectory(String path, {Map options, EntryCallback successCallback, ErrorCallback errorCallback}) native "DirectoryEntry_getDirectory_Callback";
+  void _getDirectory(String path, {Map options, _EntryCallback successCallback, _ErrorCallback errorCallback}) native "DirectoryEntry_getDirectory_Callback";
+
+  Future<Entry> getDirectory(String path, {Map options}) {
+    var completer = new Completer<Entry>();
+    _getDirectory(path, options : options,
+        successCallback : (value) { completer.complete(value); },
+        errorCallback : (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
   @DomName('DirectoryEntry.getFile')
   @DocsEditable
-  void getFile(String path, {Map options, EntryCallback successCallback, ErrorCallback errorCallback}) native "DirectoryEntry_getFile_Callback";
+  void _getFile(String path, {Map options, _EntryCallback successCallback, _ErrorCallback errorCallback}) native "DirectoryEntry_getFile_Callback";
+
+  Future<Entry> getFile(String path, {Map options}) {
+    var completer = new Completer<Entry>();
+    _getFile(path, options : options,
+        successCallback : (value) { completer.complete(value); },
+        errorCallback : (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
   @DomName('DirectoryEntry.removeRecursively')
   @DocsEditable
-  void removeRecursively(VoidCallback successCallback, [ErrorCallback errorCallback]) native "DirectoryEntry_removeRecursively_Callback";
+  void _removeRecursively(VoidCallback successCallback, [_ErrorCallback errorCallback]) native "DirectoryEntry_removeRecursively_Callback";
+
+  Future removeRecursively() {
+    var completer = new Completer();
+    _removeRecursively(
+        () { completer.complete(); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6937,7 +7055,15 @@
 
   @DomName('DirectoryReader.readEntries')
   @DocsEditable
-  void readEntries(EntriesCallback successCallback, [ErrorCallback errorCallback]) native "DirectoryReader_readEntries_Callback";
+  void _readEntries(_EntriesCallback successCallback, [_ErrorCallback errorCallback]) native "DirectoryReader_readEntries_Callback";
+
+  Future<List<Entry>> readEntries() {
+    var completer = new Completer<List<Entry>>();
+    _readEntries(
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -7228,22 +7354,21 @@
   @DocsEditable
   CanvasRenderingContext $dom_getCssCanvasContext(String contextId, String name, int width, int height) native "Document_getCSSCanvasContext_Callback";
 
-  /// Deprecated: use query("#$elementId") instead.
   @DomName('Document.getElementById')
   @DocsEditable
-  Element $dom_getElementById(String elementId) native "Document_getElementById_Callback";
+  Element getElementById(String elementId) native "Document_getElementById_Callback";
 
   @DomName('Document.getElementsByClassName')
   @DocsEditable
-  List<Node> $dom_getElementsByClassName(String tagname) native "Document_getElementsByClassName_Callback";
+  List<Node> getElementsByClassName(String tagname) native "Document_getElementsByClassName_Callback";
 
   @DomName('Document.getElementsByName')
   @DocsEditable
-  List<Node> $dom_getElementsByName(String elementName) native "Document_getElementsByName_Callback";
+  List<Node> getElementsByName(String elementName) native "Document_getElementsByName_Callback";
 
   @DomName('Document.getElementsByTagName')
   @DocsEditable
-  List<Node> $dom_getElementsByTagName(String tagname) native "Document_getElementsByTagName_Callback";
+  List<Node> getElementsByTagName(String tagname) native "Document_getElementsByTagName_Callback";
 
   @DomName('Document.queryCommandEnabled')
   @DocsEditable
@@ -7265,10 +7390,24 @@
   @DocsEditable
   String queryCommandValue(String command) native "Document_queryCommandValue_Callback";
 
-  /// Deprecated: renamed to the shorter name [query].
+  /**
+ * Finds the first descendant element of this document that matches the
+ * specified group of selectors.
+ *
+ * Unless your webpage contains multiple documents, the top-level query
+ * method behaves the same as this method, so you should use it instead to
+ * save typing a few characters.
+ *
+ * [selectors] should be a string using CSS selector syntax.
+ *     var element1 = document.query('.className');
+ *     var element2 = document.query('#id');
+ *
+ * For details about CSS selector syntax, see the
+ * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
+ */
   @DomName('Document.querySelector')
   @DocsEditable
-  Element $dom_querySelector(String selectors) native "Document_querySelector_Callback";
+  Element query(String selectors) native "Document_querySelector_Callback";
 
   /// Deprecated: use query("#$elementId") instead.
   @DomName('Document.querySelectorAll')
@@ -7497,30 +7636,6 @@
 
 
   /**
-   * Finds the first descendant element of this document that matches the
-   * specified group of selectors.
-   *
-   * Unless your webpage contains multiple documents, the top-level query
-   * method behaves the same as this method, so you should use it instead to
-   * save typing a few characters.
-   *
-   * [selectors] should be a string using CSS selector syntax.
-   *     var element1 = document.query('.className');
-   *     var element2 = document.query('#id');
-   *
-   * For details about CSS selector syntax, see the
-   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
-   */
-  Element query(String selectors) {
-    // It is fine for our RegExp to detect element id query selectors to have
-    // false negatives but not false positives.
-    if (new RegExp("^#[_a-zA-Z]\\w*\$").hasMatch(selectors)) {
-      return $dom_getElementById(selectors.substring(1));
-    }
-    return $dom_querySelector(selectors);
-  }
-
-  /**
    * Finds all descendant elements of this document that match the specified
    * group of selectors.
    *
@@ -7535,26 +7650,7 @@
    * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
    */
   List<Element> queryAll(String selectors) {
-    if (new RegExp("""^\\[name=["'][^'"]+['"]\\]\$""").hasMatch(selectors)) {
-      final mutableMatches = $dom_getElementsByName(
-          selectors.substring(7,selectors.length - 2));
-      int len = mutableMatches.length;
-      final copyOfMatches = new List<Element>(len);
-      for (int i = 0; i < len; ++i) {
-        copyOfMatches[i] = mutableMatches[i];
-      }
-      return new _FrozenElementList._wrap(copyOfMatches);
-    } else if (new RegExp("^[*a-zA-Z0-9]+\$").hasMatch(selectors)) {
-      final mutableMatches = $dom_getElementsByTagName(selectors);
-      int len = mutableMatches.length;
-      final copyOfMatches = new List<Element>(len);
-      for (int i = 0; i < len; ++i) {
-        copyOfMatches[i] = mutableMatches[i];
-      }
-      return new _FrozenElementList._wrap(copyOfMatches);
-    } else {
-      return new _FrozenElementList._wrap($dom_querySelectorAll(selectors));
-    }
+    return new _FrozenElementList._wrap($dom_querySelectorAll(selectors));
   }
 }
 // Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
@@ -7596,7 +7692,7 @@
 
   String get innerHtml {
     final e = new Element.tag("div");
-    e.nodes.add(this.clone(true));
+    e.append(this.clone(true));
     return e.innerHtml;
   }
 
@@ -7614,19 +7710,11 @@
   }
 
   /**
-   * Adds the specified element after the last child of this
-   * document fragment.
-   */
-  void append(Element element) {
-    this.children.add(element);
-  }
-
-  /**
    * Adds the specified text as a text node after the last child of this
    * document fragment.
    */
   void appendText(String text) {
-    this.nodes.add(new Text(text));
+    this.append(new Text(text));
   }
 
 
@@ -7635,7 +7723,7 @@
    * last child of this document fragment.
    */
   void appendHtml(String text) {
-    this.nodes.add(new DocumentFragment.html(text));
+    this.append(new DocumentFragment.html(text));
   }
 
   DocumentFragment.internal() : super.internal();
@@ -7862,16 +7950,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  DomMimeType firstMatching(bool test(DomMimeType value), { DomMimeType orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  DomMimeType firstWhere(bool test(DomMimeType value), { DomMimeType orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  DomMimeType lastMatching(bool test(DomMimeType value), {DomMimeType orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  DomMimeType lastWhere(bool test(DomMimeType value), {DomMimeType orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  DomMimeType singleMatching(bool test(DomMimeType value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  DomMimeType singleWhere(bool test(DomMimeType value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   DomMimeType elementAt(int index) {
@@ -7939,6 +8027,10 @@
   DomMimeType max([int compare(DomMimeType a, DomMimeType b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, DomMimeType element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   DomMimeType removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -7959,11 +8051,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(DomMimeType element)) {
+  void removeWhere(bool test(DomMimeType element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(DomMimeType element)) {
+  void retainWhere(bool test(DomMimeType element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -7979,8 +8071,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<DomMimeType> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <DomMimeType>[]);
+  }
+
   List<DomMimeType> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <DomMimeType>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, DomMimeType> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<DomMimeType> mixins.
 
@@ -8132,16 +8232,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  DomPlugin firstMatching(bool test(DomPlugin value), { DomPlugin orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  DomPlugin firstWhere(bool test(DomPlugin value), { DomPlugin orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  DomPlugin lastMatching(bool test(DomPlugin value), {DomPlugin orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  DomPlugin lastWhere(bool test(DomPlugin value), {DomPlugin orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  DomPlugin singleMatching(bool test(DomPlugin value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  DomPlugin singleWhere(bool test(DomPlugin value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   DomPlugin elementAt(int index) {
@@ -8209,6 +8309,10 @@
   DomPlugin max([int compare(DomPlugin a, DomPlugin b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, DomPlugin element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   DomPlugin removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -8229,11 +8333,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(DomPlugin element)) {
+  void removeWhere(bool test(DomPlugin element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(DomPlugin element)) {
+  void retainWhere(bool test(DomPlugin element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -8249,8 +8353,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<DomPlugin> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <DomPlugin>[]);
+  }
+
   List<DomPlugin> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <DomPlugin>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, DomPlugin> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<DomPlugin> mixins.
 
@@ -8520,16 +8632,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  String firstMatching(bool test(String value), { String orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  String firstWhere(bool test(String value), { String orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  String lastMatching(bool test(String value), {String orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  String lastWhere(bool test(String value), {String orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  String singleMatching(bool test(String value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  String singleWhere(bool test(String value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   String elementAt(int index) {
@@ -8597,6 +8709,10 @@
   String max([int compare(String a, String b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, String element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   String removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -8617,11 +8733,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(String element)) {
+  void removeWhere(bool test(String element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(String element)) {
+  void retainWhere(bool test(String element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -8637,8 +8753,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<String> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <String>[]);
+  }
+
   List<String> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <String>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, String> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<String> mixins.
 
@@ -8808,16 +8932,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Element firstMatching(bool test(Element value), {Element orElse()}) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Element firstWhere(bool test(Element value), {Element orElse()}) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Element lastMatching(bool test(Element value), {Element orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Element lastWhere(bool test(Element value), {Element orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Element singleMatching(bool test(Element value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Element singleWhere(bool test(Element value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Element elementAt(int index) {
@@ -8842,7 +8966,7 @@
   }
 
   Element add(Element value) {
-    _element.$dom_appendChild(value);
+    _element.append(value);
     return value;
   }
 
@@ -8856,7 +8980,7 @@
     }
 
     for (Element element in iterable) {
-      _element.$dom_appendChild(element);
+      _element.append(element);
     }
   }
 
@@ -8894,12 +9018,12 @@
     IterableMixinWorkaround.retainAll(this, elements);
   }
 
-  void removeMatching(bool test(Element element)) {
-    IterableMixinWorkaround.removeMatching(this, test);
+  void removeWhere(bool test(Element element)) {
+    IterableMixinWorkaround.removeWhere(this, test);
   }
 
-  void retainMatching(bool test(Element element)) {
-    IterableMixinWorkaround.retainMatching(this, test);
+  void retainWhere(bool test(Element element)) {
+    IterableMixinWorkaround.retainWhere(this, test);
   }
 
   void removeRange(int start, int rangeLength) {
@@ -8910,9 +9034,13 @@
     throw new UnimplementedError();
   }
 
+  List sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return new _FrozenElementList._wrap(Lists.getRange(this, start, end, []));
+  }
+
   List getRange(int start, int rangeLength) =>
-    new _FrozenElementList._wrap(Lists.getRange(this, start, rangeLength,
-        []));
+      sublist(start, start + rangeLength);
 
   int indexOf(Element element, [int start = 0]) {
     return Lists.indexOf(this, element, start, this.length);
@@ -8923,6 +9051,17 @@
     return Lists.lastIndexOf(this, element, start);
   }
 
+  void insert(int index, Element element) {
+    if (index < 0 || index > length) {
+      throw new RangeError.range(index, 0, length);
+    }
+    if (index == length) {
+      _element.append(element);
+    } else {
+      throw new UnimplementedError("insert on ElementLists");
+    }
+  }
+
   void clear() {
     // It is unclear if we want to keep non element nodes?
     _element.text = '';
@@ -8969,6 +9108,10 @@
   Element max([int compare(Element a, Element b)]) {
     return IterableMixinWorkaround.max(this, compare);
   }
+
+  Map<int, Element> asMap() {
+    return IterableMixinWorkaround.asMapList(this);
+  }
 }
 
 // TODO(jacobr): this is an inefficient implementation but it is hard to see
@@ -9047,16 +9190,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Element firstMatching(bool test(Element value), {Element orElse()}) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Element firstWhere(bool test(Element value), {Element orElse()}) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Element lastMatching(bool test(Element value), {Element orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Element lastWhere(bool test(Element value), {Element orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Element singleMatching(bool test(Element value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Element singleWhere(bool test(Element value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Element elementAt(int index) {
@@ -9116,8 +9259,12 @@
     throw new UnsupportedError('');
   }
 
+  List<Element> sublist(int start, [int end]) {
+    return new _FrozenElementList._wrap(_nodeList.sublist(start, end));
+  }
+
   List<Element> getRange(int start, int rangeLength) =>
-    new _FrozenElementList._wrap(_nodeList.getRange(start, rangeLength));
+      sublist(start, start + rangeLength);
 
   int indexOf(Element element, [int start = 0]) =>
     _nodeList.indexOf(element, start);
@@ -9149,11 +9296,11 @@
     throw new UnsupportedError('');
   }
 
-  void removeMatching(bool test(Element element)) {
+  void removeWhere(bool test(Element element)) {
     throw new UnsupportedError('');
   }
 
-  void retainMatching(bool test(Element element)) {
+  void retainWhere(bool test(Element element)) {
     throw new UnsupportedError('');
   }
 
@@ -9170,6 +9317,10 @@
   Element max([int compare(Element a, Element b)]) {
     return IterableMixinWorkaround.max(this, compare);
   }
+
+  Map<int, Element> asMap() {
+    return IterableMixinWorkaround.asMapList(this);
+  }
 }
 
 class _FrozenElementListIterator implements Iterator<Element> {
@@ -9318,25 +9469,6 @@
   }
 
   /**
-   * Finds the first descendant element of this element that matches the
-   * specified group of selectors.
-   *
-   * [selectors] should be a string using CSS selector syntax.
-   *
-   *     // Gets the first descendant with the class 'classname'
-   *     var element = element.query('.className');
-   *     // Gets the element with id 'id'
-   *     var element = element.query('#id');
-   *     // Gets the first descendant [ImageElement]
-   *     var img = element.query('img');
-   *
-   * See also:
-   *
-   * * [CSS Selectors](http://docs.webplatform.org/wiki/css/selectors)
-   */
-  Element query(String selectors) => $dom_querySelector(selectors);
-
-  /**
    * Finds all descendent elements of this element that match the specified
    * group of selectors.
    *
@@ -9433,12 +9565,37 @@
     return window.$dom_getComputedStyle(this, pseudoElement);
   }
 
-  /**
-   * Adds the specified element to after the last child of this element.
-   */
-  void append(Element e) {
-    this.children.add(e);
-  }
+  @deprecated
+  int get clientHeight => client.height;
+  @deprecated
+  int get clientLeft => client.left;
+  @deprecated
+  int get clientTop => client.top;
+  @deprecated
+  int get clientWidth => client.width;
+
+  @DomName('Element.clientHeight')
+  @DomName('Element.clientLeft')
+  @DomName('Element.clientTop')
+  @DomName('Element.clientWidth')
+  Rect get client => new Rect($dom_clientLeft, $dom_clientTop, $dom_clientWidth,
+      $dom_clientHeight);
+
+  @deprecated
+  int get offsetHeight => offset.height;
+  @deprecated
+  int get offsetLeft => offset.left;
+  @deprecated
+  int get offsetTop => offset.top;
+  @deprecated
+  int get offsetWidth => offset.width;
+
+  @DomName('Element.offsetHeight')
+  @DomName('Element.offsetLeft')
+  @DomName('Element.offsetTop')
+  @DomName('Element.offsetWidth')
+  Rect get offset => new Rect($dom_offsetLeft, $dom_offsetTop, $dom_offsetWidth,
+      $dom_offsetHeight);
 
   /**
    * Adds the specified text as a text node after the last child of this
@@ -9781,19 +9938,19 @@
 
   @DomName('Element.clientHeight')
   @DocsEditable
-  int get clientHeight native "Element_clientHeight_Getter";
+  int get $dom_clientHeight native "Element_clientHeight_Getter";
 
   @DomName('Element.clientLeft')
   @DocsEditable
-  int get clientLeft native "Element_clientLeft_Getter";
+  int get $dom_clientLeft native "Element_clientLeft_Getter";
 
   @DomName('Element.clientTop')
   @DocsEditable
-  int get clientTop native "Element_clientTop_Getter";
+  int get $dom_clientTop native "Element_clientTop_Getter";
 
   @DomName('Element.clientWidth')
   @DocsEditable
-  int get clientWidth native "Element_clientWidth_Getter";
+  int get $dom_clientWidth native "Element_clientWidth_Getter";
 
   @DomName('Element.firstElementChild')
   @DocsEditable
@@ -9809,11 +9966,11 @@
 
   @DomName('Element.offsetHeight')
   @DocsEditable
-  int get offsetHeight native "Element_offsetHeight_Getter";
+  int get $dom_offsetHeight native "Element_offsetHeight_Getter";
 
   @DomName('Element.offsetLeft')
   @DocsEditable
-  int get offsetLeft native "Element_offsetLeft_Getter";
+  int get $dom_offsetLeft native "Element_offsetLeft_Getter";
 
   @DomName('Element.offsetParent')
   @DocsEditable
@@ -9821,11 +9978,11 @@
 
   @DomName('Element.offsetTop')
   @DocsEditable
-  int get offsetTop native "Element_offsetTop_Getter";
+  int get $dom_offsetTop native "Element_offsetTop_Getter";
 
   @DomName('Element.offsetWidth')
   @DocsEditable
-  int get offsetWidth native "Element_offsetWidth_Getter";
+  int get $dom_offsetWidth native "Element_offsetWidth_Getter";
 
   @DomName('Element.previousElementSibling')
   @DocsEditable
@@ -9902,15 +10059,15 @@
 
   @DomName('Element.getBoundingClientRect')
   @DocsEditable
-  ClientRect getBoundingClientRect() native "Element_getBoundingClientRect_Callback";
+  Rect getBoundingClientRect() native "Element_getBoundingClientRect_Callback";
 
   @DomName('Element.getClientRects')
   @DocsEditable
-  List<ClientRect> getClientRects() native "Element_getClientRects_Callback";
+  List<Rect> getClientRects() native "Element_getClientRects_Callback";
 
   @DomName('Element.getElementsByClassName')
   @DocsEditable
-  List<Node> $dom_getElementsByClassName(String name) native "Element_getElementsByClassName_Callback";
+  List<Node> getElementsByClassName(String name) native "Element_getElementsByClassName_Callback";
 
   @DomName('Element.getElementsByTagName')
   @DocsEditable
@@ -9924,9 +10081,26 @@
   @DocsEditable
   bool $dom_hasAttributeNS(String namespaceURI, String localName) native "Element_hasAttributeNS_Callback";
 
+  /**
+ * Finds the first descendant element of this element that matches the
+ * specified group of selectors.
+ *
+ * [selectors] should be a string using CSS selector syntax.
+ *
+ *     // Gets the first descendant with the class 'classname'
+ *     var element = element.query('.className');
+ *     // Gets the element with id 'id'
+ *     var element = element.query('#id');
+ *     // Gets the first descendant [ImageElement]
+ *     var img = element.query('img');
+ *
+ * See also:
+ *
+ * * [CSS Selectors](http://docs.webplatform.org/wiki/css/selectors)
+ */
   @DomName('Element.querySelector')
   @DocsEditable
-  Element $dom_querySelector(String selectors) native "Element_querySelector_Callback";
+  Element query(String selectors) native "Element_querySelector_Callback";
 
   @DomName('Element.querySelectorAll')
   @DocsEditable
@@ -10267,7 +10441,7 @@
     final match = _START_TAG_REGEXP.firstMatch(html);
     if (match != null) {
       tag = match.group(1).toLowerCase();
-      if (_Device.isIE && _TABLE_TAGS.containsKey(tag)) {
+      if (Device.isIE && _TABLE_TAGS.containsKey(tag)) {
         return _createTableForIE(html, tag);
       }
       parentTag = _CUSTOM_PARENT_TAG_MAP[tag];
@@ -10310,7 +10484,8 @@
     switch (tag) {
       case 'td':
       case 'th':
-        element = _singleNode(_singleNode(table.rows).cells);
+        TableRowElement row = _singleNode(table.rows);
+        element = _singleNode(row.cells);
         break;
       case 'tr':
         element = _singleNode(table.rows);
@@ -10495,7 +10670,7 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void EntriesCallback(List<Entry> entries);
+typedef void _EntriesCallback(List<Entry> entries);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -10528,7 +10703,7 @@
   @DocsEditable
   String get name native "Entry_name_Getter";
 
-  void copyTo(DirectoryEntry parent, [String name, EntryCallback successCallback, ErrorCallback errorCallback]) {
+  void _copyTo(DirectoryEntry parent, {String name, _EntryCallback successCallback, _ErrorCallback errorCallback}) {
     if (?name) {
       _copyTo_1(parent, name, successCallback, errorCallback);
       return;
@@ -10545,15 +10720,39 @@
   @DocsEditable
   void _copyTo_2(parent) native "Entry__copyTo_2_Callback";
 
+  Future<Entry> copyTo(DirectoryEntry parent, {String name}) {
+    var completer = new Completer<Entry>();
+    _copyTo(parent, name : name,
+        successCallback : (value) { completer.complete(value); },
+        errorCallback : (error) { completer.completeError(error); });
+    return completer.future;
+  }
+
   @DomName('Entry.getMetadata')
   @DocsEditable
-  void getMetadata(MetadataCallback successCallback, [ErrorCallback errorCallback]) native "Entry_getMetadata_Callback";
+  void _getMetadata(MetadataCallback successCallback, [_ErrorCallback errorCallback]) native "Entry_getMetadata_Callback";
+
+  Future<Metadata> getMetadata() {
+    var completer = new Completer<Metadata>();
+    _getMetadata(
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
   @DomName('Entry.getParent')
   @DocsEditable
-  void getParent([EntryCallback successCallback, ErrorCallback errorCallback]) native "Entry_getParent_Callback";
+  void _getParent([_EntryCallback successCallback, _ErrorCallback errorCallback]) native "Entry_getParent_Callback";
 
-  void moveTo(DirectoryEntry parent, [String name, EntryCallback successCallback, ErrorCallback errorCallback]) {
+  Future<Entry> getParent() {
+    var completer = new Completer<Entry>();
+    _getParent(
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
+
+  void _moveTo(DirectoryEntry parent, {String name, _EntryCallback successCallback, _ErrorCallback errorCallback}) {
     if (?name) {
       _moveTo_1(parent, name, successCallback, errorCallback);
       return;
@@ -10570,9 +10769,25 @@
   @DocsEditable
   void _moveTo_2(parent) native "Entry__moveTo_2_Callback";
 
+  Future<Entry> moveTo(DirectoryEntry parent, {String name}) {
+    var completer = new Completer<Entry>();
+    _moveTo(parent, name : name,
+        successCallback : (value) { completer.complete(value); },
+        errorCallback : (error) { completer.completeError(error); });
+    return completer.future;
+  }
+
   @DomName('Entry.remove')
   @DocsEditable
-  void remove(VoidCallback successCallback, [ErrorCallback errorCallback]) native "Entry_remove_Callback";
+  void _remove(VoidCallback successCallback, [_ErrorCallback errorCallback]) native "Entry_remove_Callback";
+
+  Future remove() {
+    var completer = new Completer();
+    _remove(
+        () { completer.complete(); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
   @DomName('Entry.toURL')
   @DocsEditable
@@ -10586,7 +10801,7 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void EntryCallback(Entry entry);
+typedef void _EntryCallback(Entry entry);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -10651,7 +10866,7 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void ErrorCallback(FileError error);
+typedef void _ErrorCallback(FileError error);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -10822,18 +11037,6 @@
   @DocsEditable
   void stopPropagation() native "Event_stopPropagation_Callback";
 
-
-  /**
-   * Checks to see if the event class is supported by the current platform.
-   */
-  static bool _isTypeSupported(String eventType) {
-    // Browsers throw for unsupported event names.
-    try {
-      var e = document.$dom_createEvent(eventType);
-      return e is Event;
-    } catch (_) { }
-    return false;
-  }
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -11038,6 +11241,87 @@
 
 
 @DocsEditable
+@DomName('EXTDrawBuffers')
+class ExtDrawBuffers extends NativeFieldWrapperClass1 {
+  ExtDrawBuffers.internal();
+
+  static const int COLOR_ATTACHMENT0_EXT = 0x8CE0;
+
+  static const int COLOR_ATTACHMENT10_EXT = 0x8CEA;
+
+  static const int COLOR_ATTACHMENT11_EXT = 0x8CEB;
+
+  static const int COLOR_ATTACHMENT12_EXT = 0x8CEC;
+
+  static const int COLOR_ATTACHMENT13_EXT = 0x8CED;
+
+  static const int COLOR_ATTACHMENT14_EXT = 0x8CEE;
+
+  static const int COLOR_ATTACHMENT15_EXT = 0x8CEF;
+
+  static const int COLOR_ATTACHMENT1_EXT = 0x8CE1;
+
+  static const int COLOR_ATTACHMENT2_EXT = 0x8CE2;
+
+  static const int COLOR_ATTACHMENT3_EXT = 0x8CE3;
+
+  static const int COLOR_ATTACHMENT4_EXT = 0x8CE4;
+
+  static const int COLOR_ATTACHMENT5_EXT = 0x8CE5;
+
+  static const int COLOR_ATTACHMENT6_EXT = 0x8CE6;
+
+  static const int COLOR_ATTACHMENT7_EXT = 0x8CE7;
+
+  static const int COLOR_ATTACHMENT8_EXT = 0x8CE8;
+
+  static const int COLOR_ATTACHMENT9_EXT = 0x8CE9;
+
+  static const int DRAW_BUFFER0_EXT = 0x8825;
+
+  static const int DRAW_BUFFER10_EXT = 0x882F;
+
+  static const int DRAW_BUFFER11_EXT = 0x8830;
+
+  static const int DRAW_BUFFER12_EXT = 0x8831;
+
+  static const int DRAW_BUFFER13_EXT = 0x8832;
+
+  static const int DRAW_BUFFER14_EXT = 0x8833;
+
+  static const int DRAW_BUFFER15_EXT = 0x8834;
+
+  static const int DRAW_BUFFER1_EXT = 0x8826;
+
+  static const int DRAW_BUFFER2_EXT = 0x8827;
+
+  static const int DRAW_BUFFER3_EXT = 0x8828;
+
+  static const int DRAW_BUFFER4_EXT = 0x8829;
+
+  static const int DRAW_BUFFER5_EXT = 0x882A;
+
+  static const int DRAW_BUFFER6_EXT = 0x882B;
+
+  static const int DRAW_BUFFER7_EXT = 0x882C;
+
+  static const int DRAW_BUFFER8_EXT = 0x882D;
+
+  static const int DRAW_BUFFER9_EXT = 0x882E;
+
+  static const int MAX_COLOR_ATTACHMENTS_EXT = 0x8CDF;
+
+  static const int MAX_DRAW_BUFFERS_EXT = 0x8824;
+
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
 @DomName('EXTTextureFilterAnisotropic')
 class ExtTextureFilterAnisotropic extends NativeFieldWrapperClass1 {
   ExtTextureFilterAnisotropic.internal();
@@ -11147,7 +11431,7 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void FileCallback(File file);
+typedef void _FileCallback(File file);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -11162,11 +11446,27 @@
 
   @DomName('FileEntry.createWriter')
   @DocsEditable
-  void createWriter(FileWriterCallback successCallback, [ErrorCallback errorCallback]) native "FileEntry_createWriter_Callback";
+  void _createWriter(_FileWriterCallback successCallback, [_ErrorCallback errorCallback]) native "FileEntry_createWriter_Callback";
+
+  Future<FileWriter> createWriter() {
+    var completer = new Completer<FileWriter>();
+    _createWriter(
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
   @DomName('FileEntry.file')
   @DocsEditable
-  void file(FileCallback successCallback, [ErrorCallback errorCallback]) native "FileEntry_file_Callback";
+  void _file(_FileCallback successCallback, [_ErrorCallback errorCallback]) native "FileEntry_file_Callback";
+
+  Future<File> file() {
+    var completer = new Completer<File>();
+    _file(
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -11360,16 +11660,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  File firstMatching(bool test(File value), { File orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  File firstWhere(bool test(File value), { File orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  File lastMatching(bool test(File value), {File orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  File lastWhere(bool test(File value), {File orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  File singleMatching(bool test(File value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  File singleWhere(bool test(File value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   File elementAt(int index) {
@@ -11437,6 +11737,10 @@
   File max([int compare(File a, File b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, File element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   File removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -11457,11 +11761,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(File element)) {
+  void removeWhere(bool test(File element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(File element)) {
+  void retainWhere(bool test(File element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -11477,8 +11781,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<File> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <File>[]);
+  }
+
   List<File> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <File>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, File> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<File> mixins.
 
@@ -11643,7 +11955,7 @@
 
   @DomName('FileReaderSync.readAsArrayBuffer')
   @DocsEditable
-  ArrayBuffer readAsArrayBuffer(Blob blob) native "FileReaderSync_readAsArrayBuffer_Callback";
+  dynamic readAsArrayBuffer(Blob blob) native "FileReaderSync_readAsArrayBuffer_Callback";
 
   @DomName('FileReaderSync.readAsBinaryString')
   @DocsEditable
@@ -11702,7 +12014,7 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void FileSystemCallback(FileSystem fileSystem);
+typedef void _FileSystemCallback(FileSystem fileSystem);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -11844,7 +12156,7 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void FileWriterCallback(FileWriter fileWriter);
+typedef void _FileWriterCallback(FileWriter fileWriter);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -11973,16 +12285,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  num firstMatching(bool test(num value), { num orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  num firstWhere(bool test(num value), { num orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  num lastMatching(bool test(num value), {num orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  num lastWhere(bool test(num value), {num orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  num singleMatching(bool test(num value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  num singleWhere(bool test(num value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   num elementAt(int index) {
@@ -12050,6 +12362,10 @@
   num max([int compare(num a, num b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, num element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   num removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -12070,11 +12386,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(num element)) {
+  void removeWhere(bool test(num element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(num element)) {
+  void retainWhere(bool test(num element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -12090,8 +12406,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<num> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <num>[]);
+  }
+
   List<num> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <num>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, num> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<num> mixins.
 
@@ -12099,7 +12423,7 @@
   @DocsEditable
   void setElements(Object array, [int offset]) native "Float32Array_setElements_Callback";
 
-  Float32Array subarray(int start, [int end]) {
+  List<double> subarray(int start, [int end]) {
     if (?end) {
       return _subarray_1(start, end);
     }
@@ -12108,11 +12432,11 @@
 
   @DomName('Float32Array._subarray_1')
   @DocsEditable
-  Float32Array _subarray_1(start, end) native "Float32Array__subarray_1_Callback";
+  List<double> _subarray_1(start, end) native "Float32Array__subarray_1_Callback";
 
   @DomName('Float32Array._subarray_2')
   @DocsEditable
-  Float32Array _subarray_2(start) native "Float32Array__subarray_2_Callback";
+  List<double> _subarray_2(start) native "Float32Array__subarray_2_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -12210,16 +12534,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  num firstMatching(bool test(num value), { num orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  num firstWhere(bool test(num value), { num orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  num lastMatching(bool test(num value), {num orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  num lastWhere(bool test(num value), {num orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  num singleMatching(bool test(num value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  num singleWhere(bool test(num value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   num elementAt(int index) {
@@ -12287,6 +12611,10 @@
   num max([int compare(num a, num b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, num element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   num removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -12307,11 +12635,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(num element)) {
+  void removeWhere(bool test(num element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(num element)) {
+  void retainWhere(bool test(num element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -12327,8 +12655,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<num> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <num>[]);
+  }
+
   List<num> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <num>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, num> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<num> mixins.
 
@@ -12336,7 +12672,7 @@
   @DocsEditable
   void setElements(Object array, [int offset]) native "Float64Array_setElements_Callback";
 
-  Float64Array subarray(int start, [int end]) {
+  List<double> subarray(int start, [int end]) {
     if (?end) {
       return _subarray_1(start, end);
     }
@@ -12345,11 +12681,11 @@
 
   @DomName('Float64Array._subarray_1')
   @DocsEditable
-  Float64Array _subarray_1(start, end) native "Float64Array__subarray_1_Callback";
+  List<double> _subarray_1(start, end) native "Float64Array__subarray_1_Callback";
 
   @DomName('Float64Array._subarray_2')
   @DocsEditable
-  Float64Array _subarray_2(start) native "Float64Array__subarray_2_Callback";
+  List<double> _subarray_2(start) native "Float64Array__subarray_2_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -12599,7 +12935,7 @@
                 controller.add(_ensurePosition(position));
               },
               (error) {
-                controller.signalError(error);
+                controller.addError(error);
               },
               options);
         } else {
@@ -12612,14 +12948,9 @@
   }
 
   Geoposition _ensurePosition(domPosition) {
-    try {
-      // Firefox may throw on this.
-      if (domPosition is Geoposition) {
-        return domPosition;
-      }
-    } catch(e) {}
-    return new _GeopositionWrapper(domPosition);
+    return domPosition;
   }
+
   Geolocation.internal();
 
   @DomName('Geolocation.clearWatch')
@@ -12901,16 +13232,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Node firstMatching(bool test(Node value), { Node orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Node firstWhere(bool test(Node value), { Node orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Node lastMatching(bool test(Node value), {Node orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Node lastWhere(bool test(Node value), {Node orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Node singleMatching(bool test(Node value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Node singleWhere(bool test(Node value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Node elementAt(int index) {
@@ -12978,6 +13309,10 @@
   Node max([int compare(Node a, Node b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, Node element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   Node removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -12998,11 +13333,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(Node element)) {
+  void removeWhere(bool test(Node element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(Node element)) {
+  void retainWhere(bool test(Node element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -13018,8 +13353,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<Node> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <Node>[]);
+  }
+
   List<Node> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Node>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, Node> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<Node> mixins.
 
@@ -13112,16 +13455,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Node firstMatching(bool test(Node value), { Node orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Node firstWhere(bool test(Node value), { Node orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Node lastMatching(bool test(Node value), {Node orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Node lastWhere(bool test(Node value), {Node orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Node singleMatching(bool test(Node value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Node singleWhere(bool test(Node value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Node elementAt(int index) {
@@ -13189,6 +13532,10 @@
   Node max([int compare(Node a, Node b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, Node element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   Node removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -13209,11 +13556,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(Node element)) {
+  void removeWhere(bool test(Node element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(Node element)) {
+  void retainWhere(bool test(Node element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -13229,8 +13576,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<Node> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <Node>[]);
+  }
+
   List<Node> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Node>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, Node> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<Node> mixins.
 
@@ -13516,7 +13871,7 @@
     if (method == null) {
       method = 'GET';
     }
-    xhr.open(method, url, true);
+    xhr.open(method, url, async: true);
 
     if (withCredentials != null) {
       xhr.withCredentials = withCredentials;
@@ -13826,7 +14181,7 @@
    */
   @DomName('XMLHttpRequest.open')
   @DocsEditable
-  void open(String method, String url, [bool async, String user, String password]) native "XMLHttpRequest_open_Callback";
+  void open(String method, String url, {bool async, String user, String password}) native "XMLHttpRequest_open_Callback";
 
   /**
    * Specify a particular MIME type (such as `text/xml`) desired for the
@@ -14163,12 +14518,9 @@
 // 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.
 
-// WARNING: Do not edit - generated code.
 
-
-@DocsEditable
 @DomName('HTMLImageElement')
-class ImageElement extends _Element_Merged {
+class ImageElement extends _Element_Merged implements CanvasImageSource {
   ImageElement.internal() : super.internal();
 
   @DomName('HTMLImageElement.HTMLImageElement')
@@ -14720,7 +15072,7 @@
   @DocsEditable
   void setCustomValidity(String error) native "HTMLInputElement_setCustomValidity_Callback";
 
-  void setRangeText(String replacement, [int start, int end, String selectionMode]) {
+  void setRangeText(String replacement, {int start, int end, String selectionMode}) {
     if ((replacement is String || replacement == null) && !?start && !?end && !?selectionMode) {
       _setRangeText_1(replacement);
       return;
@@ -15434,16 +15786,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  int firstMatching(bool test(int value), { int orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  int firstWhere(bool test(int value), { int orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  int lastMatching(bool test(int value), {int orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  int lastWhere(bool test(int value), {int orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  int singleMatching(bool test(int value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  int singleWhere(bool test(int value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   int elementAt(int index) {
@@ -15511,6 +15863,10 @@
   int max([int compare(int a, int b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, int element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -15531,11 +15887,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(int element)) {
+  void removeWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(int element)) {
+  void retainWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -15551,8 +15907,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <int>[]);
+  }
+
   List<int> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <int>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, int> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<int> mixins.
 
@@ -15560,7 +15924,7 @@
   @DocsEditable
   void setElements(Object array, [int offset]) native "Int16Array_setElements_Callback";
 
-  Int16Array subarray(int start, [int end]) {
+  List<int> subarray(int start, [int end]) {
     if (?end) {
       return _subarray_1(start, end);
     }
@@ -15569,11 +15933,11 @@
 
   @DomName('Int16Array._subarray_1')
   @DocsEditable
-  Int16Array _subarray_1(start, end) native "Int16Array__subarray_1_Callback";
+  List<int> _subarray_1(start, end) native "Int16Array__subarray_1_Callback";
 
   @DomName('Int16Array._subarray_2')
   @DocsEditable
-  Int16Array _subarray_2(start) native "Int16Array__subarray_2_Callback";
+  List<int> _subarray_2(start) native "Int16Array__subarray_2_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -15671,16 +16035,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  int firstMatching(bool test(int value), { int orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  int firstWhere(bool test(int value), { int orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  int lastMatching(bool test(int value), {int orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  int lastWhere(bool test(int value), {int orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  int singleMatching(bool test(int value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  int singleWhere(bool test(int value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   int elementAt(int index) {
@@ -15748,6 +16112,10 @@
   int max([int compare(int a, int b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, int element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -15768,11 +16136,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(int element)) {
+  void removeWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(int element)) {
+  void retainWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -15788,8 +16156,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <int>[]);
+  }
+
   List<int> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <int>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, int> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<int> mixins.
 
@@ -15797,7 +16173,7 @@
   @DocsEditable
   void setElements(Object array, [int offset]) native "Int32Array_setElements_Callback";
 
-  Int32Array subarray(int start, [int end]) {
+  List<int> subarray(int start, [int end]) {
     if (?end) {
       return _subarray_1(start, end);
     }
@@ -15806,11 +16182,11 @@
 
   @DomName('Int32Array._subarray_1')
   @DocsEditable
-  Int32Array _subarray_1(start, end) native "Int32Array__subarray_1_Callback";
+  List<int> _subarray_1(start, end) native "Int32Array__subarray_1_Callback";
 
   @DomName('Int32Array._subarray_2')
   @DocsEditable
-  Int32Array _subarray_2(start) native "Int32Array__subarray_2_Callback";
+  List<int> _subarray_2(start) native "Int32Array__subarray_2_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -15908,16 +16284,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  int firstMatching(bool test(int value), { int orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  int firstWhere(bool test(int value), { int orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  int lastMatching(bool test(int value), {int orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  int lastWhere(bool test(int value), {int orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  int singleMatching(bool test(int value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  int singleWhere(bool test(int value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   int elementAt(int index) {
@@ -15985,6 +16361,10 @@
   int max([int compare(int a, int b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, int element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -16005,11 +16385,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(int element)) {
+  void removeWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(int element)) {
+  void retainWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -16025,8 +16405,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <int>[]);
+  }
+
   List<int> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <int>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, int> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<int> mixins.
 
@@ -16034,7 +16422,7 @@
   @DocsEditable
   void setElements(Object array, [int offset]) native "Int8Array_setElements_Callback";
 
-  Int8Array subarray(int start, [int end]) {
+  List<int> subarray(int start, [int end]) {
     if (?end) {
       return _subarray_1(start, end);
     }
@@ -16043,11 +16431,11 @@
 
   @DomName('Int8Array._subarray_1')
   @DocsEditable
-  Int8Array _subarray_1(start, end) native "Int8Array__subarray_1_Callback";
+  List<int> _subarray_1(start, end) native "Int8Array__subarray_1_Callback";
 
   @DomName('Int8Array._subarray_2')
   @DocsEditable
-  Int8Array _subarray_2(start) native "Int8Array__subarray_2_Callback";
+  List<int> _subarray_2(start) native "Int8Array__subarray_2_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -17090,7 +17478,7 @@
   @DocsEditable
   void play() native "HTMLMediaElement_play_Callback";
 
-  void addKey(String keySystem, Uint8Array key, [Uint8Array initData, String sessionId]) {
+  void addKey(String keySystem, List<int> key, [List<int> initData, String sessionId]) {
     if (?initData) {
       _webkitAddKey_1(keySystem, key, initData, sessionId);
       return;
@@ -17114,7 +17502,7 @@
   @Experimental
   void cancelKeyRequest(String keySystem, String sessionId) native "HTMLMediaElement_webkitCancelKeyRequest_Callback";
 
-  void generateKeyRequest(String keySystem, [Uint8Array initData]) {
+  void generateKeyRequest(String keySystem, [List<int> initData]) {
     if (?initData) {
       _webkitGenerateKeyRequest_1(keySystem, initData);
       return;
@@ -17310,7 +17698,7 @@
 
   @DomName('MediaKeyEvent.initData')
   @DocsEditable
-  Uint8Array get initData native "MediaKeyEvent_initData_Getter";
+  List<int> get initData native "MediaKeyEvent_initData_Getter";
 
   @DomName('MediaKeyEvent.keySystem')
   @DocsEditable
@@ -17318,7 +17706,7 @@
 
   @DomName('MediaKeyEvent.message')
   @DocsEditable
-  Uint8Array get message native "MediaKeyEvent_message_Getter";
+  List<int> get message native "MediaKeyEvent_message_Getter";
 
   @DomName('MediaKeyEvent.sessionId')
   @DocsEditable
@@ -18091,11 +18479,11 @@
 
   @DomName('MouseEvent.clientX')
   @DocsEditable
-  int get clientX native "MouseEvent_clientX_Getter";
+  int get $dom_clientX native "MouseEvent_clientX_Getter";
 
   @DomName('MouseEvent.clientY')
   @DocsEditable
-  int get clientY native "MouseEvent_clientY_Getter";
+  int get $dom_clientY native "MouseEvent_clientY_Getter";
 
   @DomName('MouseEvent.ctrlKey')
   @DocsEditable
@@ -18115,11 +18503,11 @@
 
   @DomName('MouseEvent.offsetX')
   @DocsEditable
-  int get offsetX native "MouseEvent_offsetX_Getter";
+  int get $dom_offsetX native "MouseEvent_offsetX_Getter";
 
   @DomName('MouseEvent.offsetY')
   @DocsEditable
-  int get offsetY native "MouseEvent_offsetY_Getter";
+  int get $dom_offsetY native "MouseEvent_offsetY_Getter";
 
   @DomName('MouseEvent.relatedTarget')
   @DocsEditable
@@ -18127,11 +18515,11 @@
 
   @DomName('MouseEvent.screenX')
   @DocsEditable
-  int get screenX native "MouseEvent_screenX_Getter";
+  int get $dom_screenX native "MouseEvent_screenX_Getter";
 
   @DomName('MouseEvent.screenY')
   @DocsEditable
-  int get screenY native "MouseEvent_screenY_Getter";
+  int get $dom_screenY native "MouseEvent_screenY_Getter";
 
   @DomName('MouseEvent.shiftKey')
   @DocsEditable
@@ -18146,19 +18534,60 @@
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental
-  int get movementX native "MouseEvent_webkitMovementX_Getter";
+  int get $dom_webkitMovementX native "MouseEvent_webkitMovementX_Getter";
 
   @DomName('MouseEvent.webkitMovementY')
   @DocsEditable
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental
-  int get movementY native "MouseEvent_webkitMovementY_Getter";
+  int get $dom_webkitMovementY native "MouseEvent_webkitMovementY_Getter";
 
   @DomName('MouseEvent.initMouseEvent')
   @DocsEditable
   void $dom_initMouseEvent(String type, bool canBubble, bool cancelable, Window view, int detail, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, int button, EventTarget relatedTarget) native "MouseEvent_initMouseEvent_Callback";
 
+
+  @deprecated
+  int get clientX => client.x;
+  @deprecated
+  int get clientY => client.y;
+  @deprecated
+  int get offsetX => offset.x;
+  @deprecated
+  int get offsetY => offset.y;
+  @deprecated
+  int get movementX => movement.x;
+  @deprecated
+  int get movementY => movement.y;
+  @deprecated
+  int get screenX => screen.x;
+  @deprecated
+  int get screenY => screen.y;
+
+  @DomName('MouseEvent.clientX')
+  @DomName('MouseEvent.clientY')
+  Point get client => new Point($dom_clientX, $dom_clientY);
+
+  @DomName('MouseEvent.movementX')
+  @DomName('MouseEvent.movementY')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  Point get movement => new Point($dom_webkitMovementX, $dom_webkitMovementY);
+
+  /**
+   * The coordinates of the mouse pointer in target node coordinates.
+   *
+   * This value may vary between platforms if the target node moves
+   * after the event has fired or if the element has CSS transforms affecting
+   * it.
+   */
+  Point get offset => new Point($dom_offsetX, $dom_offsetY);
+
+  @DomName('MouseEvent.screenX')
+  @DomName('MouseEvent.screenY')
+  Point get screen => new Point($dom_screenX, $dom_screenY);
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -18582,26 +19011,38 @@
   }
 
   void add(Node value) {
-    _this.$dom_appendChild(value);
+    _this.append(value);
   }
 
   void addLast(Node value) {
-    _this.$dom_appendChild(value);
+    _this.append(value);
   }
 
 
   void addAll(Iterable<Node> iterable) {
     if (iterable is _ChildNodeListLazy) {
-      if (iterable._this != _this) {
+      if (!identical(iterable._this, _this)) {
         // Optimized route for copying between nodes.
         for (var i = 0, len = iterable.length; i < len; ++i) {
-          _this.$dom_appendChild(iterable[0]);
+          // Should use $dom_firstChild, Bug 8886.
+          _this.append(iterable[0]);
         }
       }
       return;
     }
     for (Node node in iterable) {
-      _this.$dom_appendChild(node);
+      _this.append(node);
+    }
+  }
+
+  void insert(int index, Node node) {
+    if (index < 0 || index > length) {
+      throw new RangeError.range(index, 0, length);
+    }
+    if (index == length) {
+      _this.append(node);
+    } else {
+      this_.insertBefore(node, this[index]);
     }
   }
 
@@ -18636,12 +19077,12 @@
     IterableMixinWorkaround.retainAll(this, elements);
   }
 
-  void removeMatching(bool test(Node node)) {
-    IterableMixinWorkaround.removeMatching(this, test);
+  void removeWhere(bool test(Node node)) {
+    IterableMixinWorkaround.removeWhere(this, test);
   }
 
-  void retainMatching(bool test(Node node)) {
-    IterableMixinWorkaround.retainMatching(this, test);
+  void retainWhere(bool test(Node node)) {
+    IterableMixinWorkaround.retainWhere(this, test);
   }
 
   void clear() {
@@ -18709,16 +19150,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Node firstMatching(bool test(Node value), {Node orElse()}) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Node firstWhere(bool test(Node value), {Node orElse()}) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Node lastMatching(bool test(Node value), {Node orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Node lastWhere(bool test(Node value), {Node orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Node singleMatching(bool test(Node value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Node singleWhere(bool test(Node value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Node elementAt(int index) {
@@ -18754,8 +19195,13 @@
     throw new UnsupportedError(
         "Cannot insertRange on immutable List.");
   }
+  List<Node> sublist(int start, [int end]) {
+    if (end == null) end == length;
+    return Lists.getRange(this, start, end, <Node>[]);
+  }
+
   List<Node> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Node>[]);
+      sublist(start, start + rangeLength);
 
   // -- end List<Node> mixins.
 
@@ -18769,6 +19215,8 @@
   }
 
   Node operator[](int index) => _this.$dom_childNodes[index];
+
+  Map<int, Node> asMap() => IterableMixinWorkaround.asMapList(this);
 }
 
 @DomName('Node')
@@ -18783,7 +19231,7 @@
     List copy = new List.from(value);
     text = '';
     for (Node node in copy) {
-      $dom_appendChild(node);
+      append(node);
     }
   }
 
@@ -18814,6 +19262,111 @@
     return this;
   }
 
+  /**
+   * Inserts all of the nodes into this node directly before refChild.
+   *
+   * See also:
+   *
+   * * [insertBefore]
+   */
+  Node insertAllBefore(Iterable<Node> newNodes, Node refChild) {
+    if (newNodes is _ChildNodeListLazy) {
+      if (identical(newNodes._this, this)) {
+        throw new ArgumentError(newNodes);
+      }
+
+      // Optimized route for copying between nodes.
+      for (var i = 0, len = newNodes.length; i < len; ++i) {
+        // Should use $dom_firstChild, Bug 8886.
+        this.insertBefore(newNodes[0], refChild);
+      }
+    } else {
+      for (var node in newNodes) {
+        this.insertBefore(node, refChild);
+      }
+    }
+  }
+
+  // Note that this may either be the locally set model or a cached value
+  // of the inherited model. This is cached to minimize model change
+  // notifications.
+  var _model;
+  bool _hasLocalModel;
+  StreamController<Node> _modelChangedStream;
+
+  /**
+   * The data model which is inherited through the tree.
+   *
+   * Setting this will propagate the value to all descendant nodes. If the
+   * model is not set on this node then it will be inherited from ancestor
+   * nodes.
+   *
+   * Currently this does not support propagation through Shadow DOMs.
+   *
+   * [clearModel] must be used to remove the model property from this node
+   * and have the model inherit from ancestor nodes.
+   */
+  @Experimental
+  get model {
+    // If we have a change handler then we've cached the model locally.
+    if (_modelChangedStream != null) {
+      return _model;
+    }
+    // Otherwise start looking up the tree.
+    for (var node = this; node != null; node = node.parentNode) {
+      if (node._hasLocalModel == true) {
+        return node._model;
+      }
+    }
+    return null;
+  }
+
+  @Experimental
+  void set model(value) {
+    var changed = model != value;
+    _model = value;
+    _hasLocalModel = true;
+    _ModelTreeObserver.initialize();
+
+    if (changed) {
+      if (_modelChangedStream != null) {
+        _modelChangedStream.add(this);
+      }
+      // Propagate new model to all descendants.
+      _ModelTreeObserver.propagateModel(this, value, false);
+    }
+  }
+
+  /**
+   * Clears the locally set model and makes this model be inherited from parent
+   * nodes.
+   */
+  @Experimental
+  void clearModel() {
+    if (_hasLocalModel == true) {
+      _hasLocalModel = false;
+
+      // Propagate new model to all descendants.
+      if (parentNode != null) {
+        _ModelTreeObserver.propagateModel(this, parentNode.model, false);
+      } else {
+        _ModelTreeObserver.propagateModel(this, null, false);
+      }
+    }
+  }
+
+  /**
+   * Get a stream of models, whenever the model changes.
+   */
+  Stream<Node> get onModelChanged {
+    if (_modelChangedStream == null) {
+      // Ensure the model is cached locally to minimize change notifications.
+      _model = model;
+      _modelChangedStream = new StreamController.broadcast();
+    }
+    return _modelChangedStream.stream;
+  }
+
   Node.internal() : super.internal();
 
   @DomName('Node.childNodes')
@@ -18878,7 +19431,7 @@
 
   @DomName('Node.appendChild')
   @DocsEditable
-  Node $dom_appendChild(Node newChild) native "Node_appendChild_Callback";
+  Node append(Node newChild) native "Node_appendChild_Callback";
 
   @DomName('Node.cloneNode')
   @DocsEditable
@@ -19087,16 +19640,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Node firstMatching(bool test(Node value), { Node orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Node firstWhere(bool test(Node value), { Node orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Node lastMatching(bool test(Node value), {Node orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Node lastWhere(bool test(Node value), {Node orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Node singleMatching(bool test(Node value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Node singleWhere(bool test(Node value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Node elementAt(int index) {
@@ -19164,6 +19717,10 @@
   Node max([int compare(Node a, Node b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, Node element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   Node removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -19184,11 +19741,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(Node element)) {
+  void removeWhere(bool test(Node element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(Node element)) {
+  void retainWhere(bool test(Node element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -19204,8 +19761,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<Node> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <Node>[]);
+  }
+
   List<Node> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Node>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, Node> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<Node> mixins.
 
@@ -19326,7 +19891,14 @@
 
   @DomName('Notification.requestPermission')
   @DocsEditable
-  static void requestPermission(NotificationPermissionCallback callback) native "Notification_requestPermission_Callback";
+  static void _requestPermission([_NotificationPermissionCallback callback]) native "Notification_requestPermission_Callback";
+
+  static Future<String> requestPermission() {
+    var completer = new Completer<String>();
+    _requestPermission(
+        (value) { completer.complete(value); });
+    return completer.future;
+  }
 
   @DomName('Notification.show')
   @DocsEditable
@@ -19385,7 +19957,14 @@
 
   @DomName('NotificationCenter.requestPermission')
   @DocsEditable
-  void requestPermission(VoidCallback callback) native "NotificationCenter_requestPermission_Callback";
+  void _requestPermission([VoidCallback callback]) native "NotificationCenter_requestPermission_Callback";
+
+  Future requestPermission() {
+    var completer = new Completer();
+    _requestPermission(
+        () { completer.complete(); });
+    return completer.future;
+  }
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -19395,7 +19974,7 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void NotificationPermissionCallback(String permission);
+typedef void _NotificationPermissionCallback(String permission);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -19589,6 +20168,19 @@
 
 
 @DocsEditable
+@DomName('OESTextureHalfFloat')
+class OesTextureHalfFloat extends NativeFieldWrapperClass1 {
+  OesTextureHalfFloat.internal();
+
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
 @DomName('OESVertexArrayObject')
 class OesVertexArrayObject extends NativeFieldWrapperClass1 {
   OesVertexArrayObject.internal();
@@ -20317,7 +20909,7 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void RtcErrorCallback(String errorInformation);
+typedef void _RtcErrorCallback(String errorInformation);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -20325,7 +20917,7 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void RtcSessionDescriptionCallback(RtcSessionDescription sdp);
+typedef void _RtcSessionDescriptionCallback(RtcSessionDescription sdp);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -20450,11 +21042,11 @@
 
   @DomName('Range.getBoundingClientRect')
   @DocsEditable
-  ClientRect getBoundingClientRect() native "Range_getBoundingClientRect_Callback";
+  Rect getBoundingClientRect() native "Range_getBoundingClientRect_Callback";
 
   @DomName('Range.getClientRects')
   @DocsEditable
-  List<ClientRect> getClientRects() native "Range_getClientRects_Callback";
+  List<Rect> getClientRects() native "Range_getClientRects_Callback";
 
   @DomName('Range.insertNode')
   @DocsEditable
@@ -20549,35 +21141,6 @@
 // WARNING: Do not edit - generated code.
 
 
-@DocsEditable
-@DomName('Rect')
-class Rect extends NativeFieldWrapperClass1 {
-  Rect.internal();
-
-  @DomName('Rect.bottom')
-  @DocsEditable
-  CssPrimitiveValue get bottom native "Rect_bottom_Getter";
-
-  @DomName('Rect.left')
-  @DocsEditable
-  CssPrimitiveValue get left native "Rect_left_Getter";
-
-  @DomName('Rect.right')
-  @DocsEditable
-  CssPrimitiveValue get right native "Rect_right_Getter";
-
-  @DomName('Rect.top')
-  @DocsEditable
-  CssPrimitiveValue get top native "Rect_top_Getter";
-
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
 typedef void RequestAnimationFrameCallback(num highResTime);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -20587,31 +21150,6 @@
 
 
 @DocsEditable
-@DomName('RGBColor')
-class RgbColor extends NativeFieldWrapperClass1 {
-  RgbColor.internal();
-
-  @DomName('RGBColor.blue')
-  @DocsEditable
-  CssPrimitiveValue get blue native "RGBColor_blue_Getter";
-
-  @DomName('RGBColor.green')
-  @DocsEditable
-  CssPrimitiveValue get green native "RGBColor_green_Getter";
-
-  @DomName('RGBColor.red')
-  @DocsEditable
-  CssPrimitiveValue get red native "RGBColor_red_Getter";
-
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
 @DomName('RTCDataChannel')
 class RtcDataChannel extends EventTarget {
   RtcDataChannel.internal() : super.internal();
@@ -20673,11 +21211,11 @@
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "RTCDataChannel_removeEventListener_Callback";
 
   void send(data) {
-    if ((data is ArrayBuffer || data == null)) {
+    if ((data is ArrayBufferView || data is _typeddata.TypedData || data == null)) {
       _send_1(data);
       return;
     }
-    if ((data is ArrayBufferView || data == null)) {
+    if ((data is ArrayBuffer || data is _typeddata.ByteBuffer || data == null)) {
       _send_2(data);
       return;
     }
@@ -20806,7 +21344,7 @@
 class RtcPeerConnection extends EventTarget {
 
   /**
-   * Checks if Real Time Communication (RTC) APIs are supported and enabled on 
+   * Checks if Real Time Communication (RTC) APIs are supported and enabled on
    * the current platform.
    */
   static bool get supported => true;
@@ -20895,7 +21433,15 @@
 
   @DomName('RTCPeerConnection.createAnswer')
   @DocsEditable
-  void createAnswer(RtcSessionDescriptionCallback successCallback, [RtcErrorCallback failureCallback, Map mediaConstraints]) native "RTCPeerConnection_createAnswer_Callback";
+  void _createAnswer(_RtcSessionDescriptionCallback successCallback, [_RtcErrorCallback failureCallback, Map mediaConstraints]) native "RTCPeerConnection_createAnswer_Callback";
+
+  Future<RtcSessionDescription> createAnswer([Map mediaConstraints]) {
+    var completer = new Completer<RtcSessionDescription>();
+    _createAnswer(mediaConstraints,
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
   @DomName('RTCPeerConnection.createDTMFSender')
   @DocsEditable
@@ -20907,7 +21453,15 @@
 
   @DomName('RTCPeerConnection.createOffer')
   @DocsEditable
-  void createOffer(RtcSessionDescriptionCallback successCallback, [RtcErrorCallback failureCallback, Map mediaConstraints]) native "RTCPeerConnection_createOffer_Callback";
+  void _createOffer(_RtcSessionDescriptionCallback successCallback, [_RtcErrorCallback failureCallback, Map mediaConstraints]) native "RTCPeerConnection_createOffer_Callback";
+
+  Future<RtcSessionDescription> createOffer([Map mediaConstraints]) {
+    var completer = new Completer<RtcSessionDescription>();
+    _createOffer(mediaConstraints,
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
   @DomName('RTCPeerConnection.dispatchEvent')
   @DocsEditable
@@ -20935,11 +21489,27 @@
 
   @DomName('RTCPeerConnection.setLocalDescription')
   @DocsEditable
-  void setLocalDescription(RtcSessionDescription description, [VoidCallback successCallback, RtcErrorCallback failureCallback]) native "RTCPeerConnection_setLocalDescription_Callback";
+  void _setLocalDescription(RtcSessionDescription description, [VoidCallback successCallback, _RtcErrorCallback failureCallback]) native "RTCPeerConnection_setLocalDescription_Callback";
+
+  Future setLocalDescription(RtcSessionDescription description) {
+    var completer = new Completer();
+    _setLocalDescription(description,
+        () { completer.complete(); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
   @DomName('RTCPeerConnection.setRemoteDescription')
   @DocsEditable
-  void setRemoteDescription(RtcSessionDescription description, [VoidCallback successCallback, RtcErrorCallback failureCallback]) native "RTCPeerConnection_setRemoteDescription_Callback";
+  void _setRemoteDescription(RtcSessionDescription description, [VoidCallback successCallback, _RtcErrorCallback failureCallback]) native "RTCPeerConnection_setRemoteDescription_Callback";
+
+  Future setRemoteDescription(RtcSessionDescription description) {
+    var completer = new Completer();
+    _setRemoteDescription(description,
+        () { completer.complete(); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
   @DomName('RTCPeerConnection.updateIce')
   @DocsEditable
@@ -21170,33 +21740,38 @@
   String get tone native "RTCDTMFToneChangeEvent_tone_Getter";
 
 }
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
-// WARNING: Do not edit - generated code.
-
 
 @DocsEditable
 @DomName('Screen')
 class Screen extends NativeFieldWrapperClass1 {
+
+  @DomName('Screen.availHeight')
+  @DomName('Screen.availLeft')
+  @DomName('Screen.availTop')
+  @DomName('Screen.availWidth')
+  Rect get available => new Rect($dom_availLeft, $dom_availTop, $dom_availWidth,
+      $dom_availHeight);
   Screen.internal();
 
   @DomName('Screen.availHeight')
   @DocsEditable
-  int get availHeight native "Screen_availHeight_Getter";
+  int get $dom_availHeight native "Screen_availHeight_Getter";
 
   @DomName('Screen.availLeft')
   @DocsEditable
-  int get availLeft native "Screen_availLeft_Getter";
+  int get $dom_availLeft native "Screen_availLeft_Getter";
 
   @DomName('Screen.availTop')
   @DocsEditable
-  int get availTop native "Screen_availTop_Getter";
+  int get $dom_availTop native "Screen_availTop_Getter";
 
   @DomName('Screen.availWidth')
   @DocsEditable
-  int get availWidth native "Screen_availWidth_Getter";
+  int get $dom_availWidth native "Screen_availWidth_Getter";
 
   @DomName('Screen.colorDepth')
   @DocsEditable
@@ -21213,7 +21788,6 @@
   @DomName('Screen.width')
   @DocsEditable
   int get width native "Screen_width_Getter";
-
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -21526,7 +22100,7 @@
 
 @DocsEditable
 @DomName('HTMLShadowElement')
-@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@SupportedBrowser(SupportedBrowser.CHROME, '26')
 @Experimental
 class ShadowElement extends _Element_Merged {
   ShadowElement.internal() : super.internal();
@@ -21555,7 +22129,7 @@
 
 
 @DomName('ShadowRoot')
-@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@SupportedBrowser(SupportedBrowser.CHROME, '26')
 @Experimental
 class ShadowRoot extends DocumentFragment {
   ShadowRoot.internal() : super.internal();
@@ -21598,15 +22172,15 @@
 
   @DomName('ShadowRoot.getElementById')
   @DocsEditable
-  Element $dom_getElementById(String elementId) native "ShadowRoot_getElementById_Callback";
+  Element getElementById(String elementId) native "ShadowRoot_getElementById_Callback";
 
   @DomName('ShadowRoot.getElementsByClassName')
   @DocsEditable
-  List<Node> $dom_getElementsByClassName(String className) native "ShadowRoot_getElementsByClassName_Callback";
+  List<Node> getElementsByClassName(String className) native "ShadowRoot_getElementsByClassName_Callback";
 
   @DomName('ShadowRoot.getElementsByTagName')
   @DocsEditable
-  List<Node> $dom_getElementsByTagName(String tagName) native "ShadowRoot_getElementsByTagName_Callback";
+  List<Node> getElementsByTagName(String tagName) native "ShadowRoot_getElementsByTagName_Callback";
 
   @DomName('ShadowRoot.getSelection')
   @DocsEditable
@@ -21695,7 +22269,7 @@
 
   @DomName('SourceBuffer.append')
   @DocsEditable
-  void append(Uint8Array data) native "SourceBuffer_append_Callback";
+  void append(List<int> data) native "SourceBuffer_append_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -21774,16 +22348,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  SourceBuffer firstMatching(bool test(SourceBuffer value), { SourceBuffer orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  SourceBuffer firstWhere(bool test(SourceBuffer value), { SourceBuffer orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  SourceBuffer lastMatching(bool test(SourceBuffer value), {SourceBuffer orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  SourceBuffer lastWhere(bool test(SourceBuffer value), {SourceBuffer orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  SourceBuffer singleMatching(bool test(SourceBuffer value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  SourceBuffer singleWhere(bool test(SourceBuffer value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   SourceBuffer elementAt(int index) {
@@ -21851,6 +22425,10 @@
   SourceBuffer max([int compare(SourceBuffer a, SourceBuffer b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, SourceBuffer element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   SourceBuffer removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -21871,11 +22449,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(SourceBuffer element)) {
+  void removeWhere(bool test(SourceBuffer element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(SourceBuffer element)) {
+  void retainWhere(bool test(SourceBuffer element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -21891,8 +22469,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<SourceBuffer> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <SourceBuffer>[]);
+  }
+
   List<SourceBuffer> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <SourceBuffer>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, SourceBuffer> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<SourceBuffer> mixins.
 
@@ -22094,16 +22680,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  SpeechGrammar firstMatching(bool test(SpeechGrammar value), { SpeechGrammar orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  SpeechGrammar firstWhere(bool test(SpeechGrammar value), { SpeechGrammar orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  SpeechGrammar lastMatching(bool test(SpeechGrammar value), {SpeechGrammar orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  SpeechGrammar lastWhere(bool test(SpeechGrammar value), {SpeechGrammar orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  SpeechGrammar singleMatching(bool test(SpeechGrammar value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  SpeechGrammar singleWhere(bool test(SpeechGrammar value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   SpeechGrammar elementAt(int index) {
@@ -22171,6 +22757,10 @@
   SpeechGrammar max([int compare(SpeechGrammar a, SpeechGrammar b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, SpeechGrammar element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   SpeechGrammar removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -22191,11 +22781,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(SpeechGrammar element)) {
+  void removeWhere(bool test(SpeechGrammar element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(SpeechGrammar element)) {
+  void retainWhere(bool test(SpeechGrammar element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -22211,8 +22801,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<SpeechGrammar> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <SpeechGrammar>[]);
+  }
+
   List<SpeechGrammar> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <SpeechGrammar>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, SpeechGrammar> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<SpeechGrammar> mixins.
 
@@ -22746,11 +23344,27 @@
 
   @DomName('StorageInfo.queryUsageAndQuota')
   @DocsEditable
-  void queryUsageAndQuota(int storageType, [StorageInfoUsageCallback usageCallback, StorageInfoErrorCallback errorCallback]) native "StorageInfo_queryUsageAndQuota_Callback";
+  void _queryUsageAndQuota(int storageType, [_StorageInfoUsageCallback usageCallback, _StorageInfoErrorCallback errorCallback]) native "StorageInfo_queryUsageAndQuota_Callback";
+
+  Future<int> queryUsageAndQuota(int storageType) {
+    var completer = new Completer<int>();
+    _queryUsageAndQuota(storageType,
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
   @DomName('StorageInfo.requestQuota')
   @DocsEditable
-  void requestQuota(int storageType, int newQuotaInBytes, [StorageInfoQuotaCallback quotaCallback, StorageInfoErrorCallback errorCallback]) native "StorageInfo_requestQuota_Callback";
+  void _requestQuota(int storageType, int newQuotaInBytes, [StorageInfoQuotaCallback quotaCallback, _StorageInfoErrorCallback errorCallback]) native "StorageInfo_requestQuota_Callback";
+
+  Future<int> requestQuota(int storageType, int newQuotaInBytes) {
+    var completer = new Completer<int>();
+    _requestQuota(storageType, newQuotaInBytes,
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -22760,7 +23374,7 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void StorageInfoErrorCallback(DomException error);
+typedef void _StorageInfoErrorCallback(DomException error);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -22776,7 +23390,7 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void StorageInfoUsageCallback(int currentUsageInBytes, int currentQuotaInBytes);
+typedef void _StorageInfoUsageCallback(int currentUsageInBytes, int currentQuotaInBytes);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -22784,7 +23398,7 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void StringCallback(String data);
+typedef void _StringCallback(String data);
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -23763,16 +24377,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  TextTrackCue firstMatching(bool test(TextTrackCue value), { TextTrackCue orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  TextTrackCue firstWhere(bool test(TextTrackCue value), { TextTrackCue orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  TextTrackCue lastMatching(bool test(TextTrackCue value), {TextTrackCue orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  TextTrackCue lastWhere(bool test(TextTrackCue value), {TextTrackCue orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  TextTrackCue singleMatching(bool test(TextTrackCue value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  TextTrackCue singleWhere(bool test(TextTrackCue value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   TextTrackCue elementAt(int index) {
@@ -23840,6 +24454,10 @@
   TextTrackCue max([int compare(TextTrackCue a, TextTrackCue b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, TextTrackCue element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   TextTrackCue removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -23860,11 +24478,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(TextTrackCue element)) {
+  void removeWhere(bool test(TextTrackCue element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(TextTrackCue element)) {
+  void retainWhere(bool test(TextTrackCue element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -23880,8 +24498,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<TextTrackCue> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <TextTrackCue>[]);
+  }
+
   List<TextTrackCue> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <TextTrackCue>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, TextTrackCue> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<TextTrackCue> mixins.
 
@@ -23974,16 +24600,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  TextTrack firstMatching(bool test(TextTrack value), { TextTrack orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  TextTrack firstWhere(bool test(TextTrack value), { TextTrack orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  TextTrack lastMatching(bool test(TextTrack value), {TextTrack orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  TextTrack lastWhere(bool test(TextTrack value), {TextTrack orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  TextTrack singleMatching(bool test(TextTrack value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  TextTrack singleWhere(bool test(TextTrack value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   TextTrack elementAt(int index) {
@@ -24051,6 +24677,10 @@
   TextTrack max([int compare(TextTrack a, TextTrack b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, TextTrack element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   TextTrack removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -24071,11 +24701,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(TextTrack element)) {
+  void removeWhere(bool test(TextTrack element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(TextTrack element)) {
+  void retainWhere(bool test(TextTrack element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -24091,8 +24721,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<TextTrack> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <TextTrack>[]);
+  }
+
   List<TextTrack> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <TextTrack>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, TextTrack> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<TextTrack> mixins.
 
@@ -24171,8 +24809,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.
 
-// WARNING: Do not edit - generated code.
-
 
 @DocsEditable
 @DomName('Touch')
@@ -24181,11 +24817,11 @@
 
   @DomName('Touch.clientX')
   @DocsEditable
-  int get clientX native "Touch_clientX_Getter";
+  int get $dom_clientX native "Touch_clientX_Getter";
 
   @DomName('Touch.clientY')
   @DocsEditable
-  int get clientY native "Touch_clientY_Getter";
+  int get $dom_clientY native "Touch_clientY_Getter";
 
   @DomName('Touch.identifier')
   @DocsEditable
@@ -24193,19 +24829,19 @@
 
   @DomName('Touch.pageX')
   @DocsEditable
-  int get pageX native "Touch_pageX_Getter";
+  int get $dom_pageX native "Touch_pageX_Getter";
 
   @DomName('Touch.pageY')
   @DocsEditable
-  int get pageY native "Touch_pageY_Getter";
+  int get $dom_pageY native "Touch_pageY_Getter";
 
   @DomName('Touch.screenX')
   @DocsEditable
-  int get screenX native "Touch_screenX_Getter";
+  int get $dom_screenX native "Touch_screenX_Getter";
 
   @DomName('Touch.screenY')
   @DocsEditable
-  int get screenY native "Touch_screenY_Getter";
+  int get $dom_screenY native "Touch_screenY_Getter";
 
   @DomName('Touch.target')
   @DocsEditable
@@ -24239,6 +24875,18 @@
   @Experimental
   num get rotationAngle native "Touch_webkitRotationAngle_Getter";
 
+
+  @DomName('Touch.clientX')
+  @DomName('Touch.clientY')
+  Point get client => new Point($dom_clientX, $dom_clientY);
+
+  @DomName('Touch.pageX')
+  @DomName('Touch.pageY')
+  Point get page => new Point($dom_pageX, $dom_pageY);
+
+  @DomName('Touch.screenX')
+  @DomName('Touch.screenY')
+  Point get screen => new Point($dom_screenX, $dom_screenY);
 }
 // 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
@@ -24307,7 +24955,7 @@
     // Bug #8186 add equivalent 'ontouchstart' check for Dartium.
     // Basically, this is a fairly common check and it'd be great if it did not
     // throw exceptions.
-    return Event._isTypeSupported('TouchEvent');
+    return Device.isEventTypeSupported('TouchEvent');
   }
 }
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
@@ -24392,16 +25040,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Touch firstMatching(bool test(Touch value), { Touch orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Touch firstWhere(bool test(Touch value), { Touch orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Touch lastMatching(bool test(Touch value), {Touch orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Touch lastWhere(bool test(Touch value), {Touch orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Touch singleMatching(bool test(Touch value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Touch singleWhere(bool test(Touch value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Touch elementAt(int index) {
@@ -24469,6 +25117,10 @@
   Touch max([int compare(Touch a, Touch b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, Touch element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   Touch removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -24489,11 +25141,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(Touch element)) {
+  void removeWhere(bool test(Touch element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(Touch element)) {
+  void retainWhere(bool test(Touch element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -24509,8 +25161,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<Touch> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <Touch>[]);
+  }
+
   List<Touch> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Touch>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, Touch> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<Touch> mixins.
 
@@ -24746,19 +25406,19 @@
 
   @DomName('UIEvent.layerX')
   @DocsEditable
-  int get layerX native "UIEvent_layerX_Getter";
+  int get $dom_layerX native "UIEvent_layerX_Getter";
 
   @DomName('UIEvent.layerY')
   @DocsEditable
-  int get layerY native "UIEvent_layerY_Getter";
+  int get $dom_layerY native "UIEvent_layerY_Getter";
 
   @DomName('UIEvent.pageX')
   @DocsEditable
-  int get pageX native "UIEvent_pageX_Getter";
+  int get $dom_pageX native "UIEvent_pageX_Getter";
 
   @DomName('UIEvent.pageY')
   @DocsEditable
-  int get pageY native "UIEvent_pageY_Getter";
+  int get $dom_pageY native "UIEvent_pageY_Getter";
 
   @DomName('UIEvent.view')
   @DocsEditable
@@ -24772,6 +25432,24 @@
   @DocsEditable
   void $dom_initUIEvent(String type, bool canBubble, bool cancelable, Window view, int detail) native "UIEvent_initUIEvent_Callback";
 
+
+  @deprecated
+  int get layerX => layer.x;
+  @deprecated
+  int get layerY => layer.y;
+
+  @deprecated
+  int get pageX => page.x;
+  @deprecated
+  int get pageY => page.y;
+
+  @DomName('UIEvent.layerX')
+  @DomName('UIEvent.layerY')
+  Point get layer => new Point($dom_layerX, $dom_layerY);
+
+  @DomName('UIEvent.pageX')
+  @DomName('UIEvent.pageY')
+  Point get page => new Point($dom_pageX, $dom_pageY);
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -24885,16 +25563,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  int firstMatching(bool test(int value), { int orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  int firstWhere(bool test(int value), { int orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  int lastMatching(bool test(int value), {int orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  int lastWhere(bool test(int value), {int orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  int singleMatching(bool test(int value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  int singleWhere(bool test(int value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   int elementAt(int index) {
@@ -24962,6 +25640,10 @@
   int max([int compare(int a, int b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, int element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -24982,11 +25664,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(int element)) {
+  void removeWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(int element)) {
+  void retainWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -25002,8 +25684,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <int>[]);
+  }
+
   List<int> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <int>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, int> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<int> mixins.
 
@@ -25011,7 +25701,7 @@
   @DocsEditable
   void setElements(Object array, [int offset]) native "Uint16Array_setElements_Callback";
 
-  Uint16Array subarray(int start, [int end]) {
+  List<int> subarray(int start, [int end]) {
     if (?end) {
       return _subarray_1(start, end);
     }
@@ -25020,11 +25710,11 @@
 
   @DomName('Uint16Array._subarray_1')
   @DocsEditable
-  Uint16Array _subarray_1(start, end) native "Uint16Array__subarray_1_Callback";
+  List<int> _subarray_1(start, end) native "Uint16Array__subarray_1_Callback";
 
   @DomName('Uint16Array._subarray_2')
   @DocsEditable
-  Uint16Array _subarray_2(start) native "Uint16Array__subarray_2_Callback";
+  List<int> _subarray_2(start) native "Uint16Array__subarray_2_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -25122,16 +25812,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  int firstMatching(bool test(int value), { int orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  int firstWhere(bool test(int value), { int orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  int lastMatching(bool test(int value), {int orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  int lastWhere(bool test(int value), {int orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  int singleMatching(bool test(int value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  int singleWhere(bool test(int value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   int elementAt(int index) {
@@ -25199,6 +25889,10 @@
   int max([int compare(int a, int b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, int element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -25219,11 +25913,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(int element)) {
+  void removeWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(int element)) {
+  void retainWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -25239,8 +25933,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <int>[]);
+  }
+
   List<int> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <int>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, int> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<int> mixins.
 
@@ -25248,7 +25950,7 @@
   @DocsEditable
   void setElements(Object array, [int offset]) native "Uint32Array_setElements_Callback";
 
-  Uint32Array subarray(int start, [int end]) {
+  List<int> subarray(int start, [int end]) {
     if (?end) {
       return _subarray_1(start, end);
     }
@@ -25257,11 +25959,11 @@
 
   @DomName('Uint32Array._subarray_1')
   @DocsEditable
-  Uint32Array _subarray_1(start, end) native "Uint32Array__subarray_1_Callback";
+  List<int> _subarray_1(start, end) native "Uint32Array__subarray_1_Callback";
 
   @DomName('Uint32Array._subarray_2')
   @DocsEditable
-  Uint32Array _subarray_2(start) native "Uint32Array__subarray_2_Callback";
+  List<int> _subarray_2(start) native "Uint32Array__subarray_2_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -25359,16 +26061,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  int firstMatching(bool test(int value), { int orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  int firstWhere(bool test(int value), { int orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  int lastMatching(bool test(int value), {int orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  int lastWhere(bool test(int value), {int orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  int singleMatching(bool test(int value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  int singleWhere(bool test(int value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   int elementAt(int index) {
@@ -25436,6 +26138,10 @@
   int max([int compare(int a, int b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, int element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -25456,11 +26162,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(int element)) {
+  void removeWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(int element)) {
+  void retainWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -25476,8 +26182,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <int>[]);
+  }
+
   List<int> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <int>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, int> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<int> mixins.
 
@@ -25485,7 +26199,7 @@
   @DocsEditable
   void setElements(Object array, [int offset]) native "Uint8Array_setElements_Callback";
 
-  Uint8Array subarray(int start, [int end]) {
+  List<int> subarray(int start, [int end]) {
     if (?end) {
       return _subarray_1(start, end);
     }
@@ -25494,11 +26208,11 @@
 
   @DomName('Uint8Array._subarray_1')
   @DocsEditable
-  Uint8Array _subarray_1(start, end) native "Uint8Array__subarray_1_Callback";
+  List<int> _subarray_1(start, end) native "Uint8Array__subarray_1_Callback";
 
   @DomName('Uint8Array._subarray_2')
   @DocsEditable
-  Uint8Array _subarray_2(start) native "Uint8Array__subarray_2_Callback";
+  List<int> _subarray_2(start) native "Uint8Array__subarray_2_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -25594,16 +26308,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  int firstMatching(bool test(int value), { int orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  int firstWhere(bool test(int value), { int orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  int lastMatching(bool test(int value), {int orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  int lastWhere(bool test(int value), {int orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  int singleMatching(bool test(int value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  int singleWhere(bool test(int value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   int elementAt(int index) {
@@ -25671,6 +26385,10 @@
   int max([int compare(int a, int b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, int element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -25691,11 +26409,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(int element)) {
+  void removeWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(int element)) {
+  void retainWhere(bool test(int element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -25711,8 +26429,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<int> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <int>[]);
+  }
+
   List<int> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <int>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, int> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<int> mixins.
 
@@ -25720,7 +26446,7 @@
   @DocsEditable
   void setElements(Object array, [int offset]) native "Uint8ClampedArray_setElements_Callback";
 
-  Uint8ClampedArray subarray(int start, [int end]) {
+  List<int> subarray(int start, [int end]) {
     if (?end) {
       return _subarray_1(start, end);
     }
@@ -25729,11 +26455,11 @@
 
   @DomName('Uint8ClampedArray._subarray_1')
   @DocsEditable
-  Uint8ClampedArray _subarray_1(start, end) native "Uint8ClampedArray__subarray_1_Callback";
+  List<int> _subarray_1(start, end) native "Uint8ClampedArray__subarray_1_Callback";
 
   @DomName('Uint8ClampedArray._subarray_2')
   @DocsEditable
-  Uint8ClampedArray _subarray_2(start) native "Uint8ClampedArray__subarray_2_Callback";
+  List<int> _subarray_2(start) native "Uint8ClampedArray__subarray_2_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -25848,12 +26574,9 @@
 // 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.
 
-// WARNING: Do not edit - generated code.
 
-
-@DocsEditable
 @DomName('HTMLVideoElement')
-class VideoElement extends MediaElement {
+class VideoElement extends MediaElement implements CanvasImageSource {
   VideoElement.internal() : super.internal();
 
   @DomName('HTMLVideoElement.HTMLVideoElement')
@@ -26419,6 +27142,8 @@
 
   static const int GREEN_BITS = 0x0D53;
 
+  static const int HALF_FLOAT_OES = 0x8D61;
+
   static const int HIGH_FLOAT = 0x8DF2;
 
   static const int HIGH_INT = 0x8DF5;
@@ -26868,11 +27593,11 @@
   void blendFuncSeparate(int srcRGB, int dstRGB, int srcAlpha, int dstAlpha) native "WebGLRenderingContext_blendFuncSeparate_Callback";
 
   void bufferData(int target, data_OR_size, int usage) {
-    if ((target is int || target == null) && (data_OR_size is ArrayBuffer || data_OR_size == null) && (usage is int || usage == null)) {
+    if ((target is int || target == null) && (data_OR_size is ArrayBufferView || data_OR_size is _typeddata.TypedData || data_OR_size == null) && (usage is int || usage == null)) {
       _bufferData_1(target, data_OR_size, usage);
       return;
     }
-    if ((target is int || target == null) && (data_OR_size is ArrayBufferView || data_OR_size == null) && (usage is int || usage == null)) {
+    if ((target is int || target == null) && (data_OR_size is ArrayBuffer || data_OR_size is _typeddata.ByteBuffer || data_OR_size == null) && (usage is int || usage == null)) {
       _bufferData_2(target, data_OR_size, usage);
       return;
     }
@@ -26895,12 +27620,12 @@
   @DocsEditable
   void _bufferData_3(target, data_OR_size, usage) native "WebGLRenderingContext__bufferData_3_Callback";
 
-  void bufferSubData(int target, int offset, data) {
-    if ((target is int || target == null) && (offset is int || offset == null) && (data is ArrayBuffer || data == null)) {
+  void bufferSubData(int target, int offset, /*ArrayBuffer*/ data) {
+    if ((target is int || target == null) && (offset is int || offset == null) && (data is ArrayBufferView || data is _typeddata.TypedData || data == null)) {
       _bufferSubData_1(target, offset, data);
       return;
     }
-    if ((target is int || target == null) && (offset is int || offset == null) && (data is ArrayBufferView || data == null)) {
+    if ((target is int || target == null) && (offset is int || offset == null) && (data is ArrayBuffer || data is _typeddata.ByteBuffer || data == null)) {
       _bufferSubData_2(target, offset, data);
       return;
     }
@@ -26945,11 +27670,11 @@
 
   @DomName('WebGLRenderingContext.compressedTexImage2D')
   @DocsEditable
-  void compressedTexImage2D(int target, int level, int internalformat, int width, int height, int border, ArrayBufferView data) native "WebGLRenderingContext_compressedTexImage2D_Callback";
+  void compressedTexImage2D(int target, int level, int internalformat, int width, int height, int border, /*ArrayBufferView*/ data) native "WebGLRenderingContext_compressedTexImage2D_Callback";
 
   @DomName('WebGLRenderingContext.compressedTexSubImage2D')
   @DocsEditable
-  void compressedTexSubImage2D(int target, int level, int xoffset, int yoffset, int width, int height, int format, ArrayBufferView data) native "WebGLRenderingContext_compressedTexSubImage2D_Callback";
+  void compressedTexSubImage2D(int target, int level, int xoffset, int yoffset, int width, int height, int format, /*ArrayBufferView*/ data) native "WebGLRenderingContext_compressedTexSubImage2D_Callback";
 
   @DomName('WebGLRenderingContext.copyTexImage2D')
   @DocsEditable
@@ -27221,7 +27946,7 @@
 
   @DomName('WebGLRenderingContext.readPixels')
   @DocsEditable
-  void readPixels(int x, int y, int width, int height, int format, int type, ArrayBufferView pixels) native "WebGLRenderingContext_readPixels_Callback";
+  void readPixels(int x, int y, int width, int height, int format, int type, /*ArrayBufferView*/ pixels) native "WebGLRenderingContext_readPixels_Callback";
 
   @DomName('WebGLRenderingContext.releaseShaderCompiler')
   @DocsEditable
@@ -27267,8 +27992,8 @@
   @DocsEditable
   void stencilOpSeparate(int face, int fail, int zfail, int zpass) native "WebGLRenderingContext_stencilOpSeparate_Callback";
 
-  void texImage2D(int target, int level, int internalformat, int format_OR_width, int height_OR_type, border_OR_canvas_OR_image_OR_pixels_OR_video, [int format, int type, ArrayBufferView pixels]) {
-    if ((target is int || target == null) && (level is int || level == null) && (internalformat is int || internalformat == null) && (format_OR_width is int || format_OR_width == null) && (height_OR_type is int || height_OR_type == null) && (border_OR_canvas_OR_image_OR_pixels_OR_video is int || border_OR_canvas_OR_image_OR_pixels_OR_video == null) && (format is int || format == null) && (type is int || type == null) && (pixels is ArrayBufferView || pixels == null)) {
+  void texImage2D(int target, int level, int internalformat, int format_OR_width, int height_OR_type, border_OR_canvas_OR_image_OR_pixels_OR_video, [int format, int type, /*ArrayBufferView*/ pixels]) {
+    if ((target is int || target == null) && (level is int || level == null) && (internalformat is int || internalformat == null) && (format_OR_width is int || format_OR_width == null) && (height_OR_type is int || height_OR_type == null) && (border_OR_canvas_OR_image_OR_pixels_OR_video is int || border_OR_canvas_OR_image_OR_pixels_OR_video == null) && (format is int || format == null) && (type is int || type == null) && (pixels is ArrayBufferView || pixels is _typeddata.TypedData || pixels == null)) {
       _texImage2D_1(target, level, internalformat, format_OR_width, height_OR_type, border_OR_canvas_OR_image_OR_pixels_OR_video, format, type, pixels);
       return;
     }
@@ -27319,8 +28044,8 @@
   @DocsEditable
   void texParameteri(int target, int pname, int param) native "WebGLRenderingContext_texParameteri_Callback";
 
-  void texSubImage2D(int target, int level, int xoffset, int yoffset, int format_OR_width, int height_OR_type, canvas_OR_format_OR_image_OR_pixels_OR_video, [int type, ArrayBufferView pixels]) {
-    if ((target is int || target == null) && (level is int || level == null) && (xoffset is int || xoffset == null) && (yoffset is int || yoffset == null) && (format_OR_width is int || format_OR_width == null) && (height_OR_type is int || height_OR_type == null) && (canvas_OR_format_OR_image_OR_pixels_OR_video is int || canvas_OR_format_OR_image_OR_pixels_OR_video == null) && (type is int || type == null) && (pixels is ArrayBufferView || pixels == null)) {
+  void texSubImage2D(int target, int level, int xoffset, int yoffset, int format_OR_width, int height_OR_type, canvas_OR_format_OR_image_OR_pixels_OR_video, [int type, /*ArrayBufferView*/ pixels]) {
+    if ((target is int || target == null) && (level is int || level == null) && (xoffset is int || xoffset == null) && (yoffset is int || yoffset == null) && (format_OR_width is int || format_OR_width == null) && (height_OR_type is int || height_OR_type == null) && (canvas_OR_format_OR_image_OR_pixels_OR_video is int || canvas_OR_format_OR_image_OR_pixels_OR_video == null) && (type is int || type == null) && (pixels is ArrayBufferView || pixels is _typeddata.TypedData || pixels == null)) {
       _texSubImage2D_1(target, level, xoffset, yoffset, format_OR_width, height_OR_type, canvas_OR_format_OR_image_OR_pixels_OR_video, type, pixels);
       return;
     }
@@ -27369,7 +28094,7 @@
 
   @DomName('WebGLRenderingContext.uniform1fv')
   @DocsEditable
-  void uniform1fv(WebGLUniformLocation location, Float32Array v) native "WebGLRenderingContext_uniform1fv_Callback";
+  void uniform1fv(WebGLUniformLocation location, List<double> v) native "WebGLRenderingContext_uniform1fv_Callback";
 
   @DomName('WebGLRenderingContext.uniform1i')
   @DocsEditable
@@ -27377,7 +28102,7 @@
 
   @DomName('WebGLRenderingContext.uniform1iv')
   @DocsEditable
-  void uniform1iv(WebGLUniformLocation location, Int32Array v) native "WebGLRenderingContext_uniform1iv_Callback";
+  void uniform1iv(WebGLUniformLocation location, List<int> v) native "WebGLRenderingContext_uniform1iv_Callback";
 
   @DomName('WebGLRenderingContext.uniform2f')
   @DocsEditable
@@ -27385,7 +28110,7 @@
 
   @DomName('WebGLRenderingContext.uniform2fv')
   @DocsEditable
-  void uniform2fv(WebGLUniformLocation location, Float32Array v) native "WebGLRenderingContext_uniform2fv_Callback";
+  void uniform2fv(WebGLUniformLocation location, List<double> v) native "WebGLRenderingContext_uniform2fv_Callback";
 
   @DomName('WebGLRenderingContext.uniform2i')
   @DocsEditable
@@ -27393,7 +28118,7 @@
 
   @DomName('WebGLRenderingContext.uniform2iv')
   @DocsEditable
-  void uniform2iv(WebGLUniformLocation location, Int32Array v) native "WebGLRenderingContext_uniform2iv_Callback";
+  void uniform2iv(WebGLUniformLocation location, List<int> v) native "WebGLRenderingContext_uniform2iv_Callback";
 
   @DomName('WebGLRenderingContext.uniform3f')
   @DocsEditable
@@ -27401,7 +28126,7 @@
 
   @DomName('WebGLRenderingContext.uniform3fv')
   @DocsEditable
-  void uniform3fv(WebGLUniformLocation location, Float32Array v) native "WebGLRenderingContext_uniform3fv_Callback";
+  void uniform3fv(WebGLUniformLocation location, List<double> v) native "WebGLRenderingContext_uniform3fv_Callback";
 
   @DomName('WebGLRenderingContext.uniform3i')
   @DocsEditable
@@ -27409,7 +28134,7 @@
 
   @DomName('WebGLRenderingContext.uniform3iv')
   @DocsEditable
-  void uniform3iv(WebGLUniformLocation location, Int32Array v) native "WebGLRenderingContext_uniform3iv_Callback";
+  void uniform3iv(WebGLUniformLocation location, List<int> v) native "WebGLRenderingContext_uniform3iv_Callback";
 
   @DomName('WebGLRenderingContext.uniform4f')
   @DocsEditable
@@ -27417,7 +28142,7 @@
 
   @DomName('WebGLRenderingContext.uniform4fv')
   @DocsEditable
-  void uniform4fv(WebGLUniformLocation location, Float32Array v) native "WebGLRenderingContext_uniform4fv_Callback";
+  void uniform4fv(WebGLUniformLocation location, List<double> v) native "WebGLRenderingContext_uniform4fv_Callback";
 
   @DomName('WebGLRenderingContext.uniform4i')
   @DocsEditable
@@ -27425,19 +28150,19 @@
 
   @DomName('WebGLRenderingContext.uniform4iv')
   @DocsEditable
-  void uniform4iv(WebGLUniformLocation location, Int32Array v) native "WebGLRenderingContext_uniform4iv_Callback";
+  void uniform4iv(WebGLUniformLocation location, List<int> v) native "WebGLRenderingContext_uniform4iv_Callback";
 
   @DomName('WebGLRenderingContext.uniformMatrix2fv')
   @DocsEditable
-  void uniformMatrix2fv(WebGLUniformLocation location, bool transpose, Float32Array array) native "WebGLRenderingContext_uniformMatrix2fv_Callback";
+  void uniformMatrix2fv(WebGLUniformLocation location, bool transpose, List<double> array) native "WebGLRenderingContext_uniformMatrix2fv_Callback";
 
   @DomName('WebGLRenderingContext.uniformMatrix3fv')
   @DocsEditable
-  void uniformMatrix3fv(WebGLUniformLocation location, bool transpose, Float32Array array) native "WebGLRenderingContext_uniformMatrix3fv_Callback";
+  void uniformMatrix3fv(WebGLUniformLocation location, bool transpose, List<double> array) native "WebGLRenderingContext_uniformMatrix3fv_Callback";
 
   @DomName('WebGLRenderingContext.uniformMatrix4fv')
   @DocsEditable
-  void uniformMatrix4fv(WebGLUniformLocation location, bool transpose, Float32Array array) native "WebGLRenderingContext_uniformMatrix4fv_Callback";
+  void uniformMatrix4fv(WebGLUniformLocation location, bool transpose, List<double> array) native "WebGLRenderingContext_uniformMatrix4fv_Callback";
 
   @DomName('WebGLRenderingContext.useProgram')
   @DocsEditable
@@ -27453,7 +28178,7 @@
 
   @DomName('WebGLRenderingContext.vertexAttrib1fv')
   @DocsEditable
-  void vertexAttrib1fv(int indx, Float32Array values) native "WebGLRenderingContext_vertexAttrib1fv_Callback";
+  void vertexAttrib1fv(int indx, List<double> values) native "WebGLRenderingContext_vertexAttrib1fv_Callback";
 
   @DomName('WebGLRenderingContext.vertexAttrib2f')
   @DocsEditable
@@ -27461,7 +28186,7 @@
 
   @DomName('WebGLRenderingContext.vertexAttrib2fv')
   @DocsEditable
-  void vertexAttrib2fv(int indx, Float32Array values) native "WebGLRenderingContext_vertexAttrib2fv_Callback";
+  void vertexAttrib2fv(int indx, List<double> values) native "WebGLRenderingContext_vertexAttrib2fv_Callback";
 
   @DomName('WebGLRenderingContext.vertexAttrib3f')
   @DocsEditable
@@ -27469,7 +28194,7 @@
 
   @DomName('WebGLRenderingContext.vertexAttrib3fv')
   @DocsEditable
-  void vertexAttrib3fv(int indx, Float32Array values) native "WebGLRenderingContext_vertexAttrib3fv_Callback";
+  void vertexAttrib3fv(int indx, List<double> values) native "WebGLRenderingContext_vertexAttrib3fv_Callback";
 
   @DomName('WebGLRenderingContext.vertexAttrib4f')
   @DocsEditable
@@ -27477,7 +28202,7 @@
 
   @DomName('WebGLRenderingContext.vertexAttrib4fv')
   @DocsEditable
-  void vertexAttrib4fv(int indx, Float32Array values) native "WebGLRenderingContext_vertexAttrib4fv_Callback";
+  void vertexAttrib4fv(int indx, List<double> values) native "WebGLRenderingContext_vertexAttrib4fv_Callback";
 
   @DomName('WebGLRenderingContext.vertexAttribPointer')
   @DocsEditable
@@ -27895,7 +28620,7 @@
       view = window;
     }
     var eventType = 'WheelEvent';
-    if (_Device.isFirefox) {
+    if (Device.isFirefox) {
       eventType = 'MouseScrollEvents';
     }
     final event = document.$dom_createEvent(eventType);
@@ -28004,8 +28729,10 @@
    * [animationFrame] again for the animation to continue.
    */
   Future<num> get animationFrame {
-    var completer = new Completer<int>();
-    requestAnimationFrame(completer.complete);
+    var completer = new Completer<num>();
+    requestAnimationFrame((time) {
+      completer.complete(time);
+    });
     return completer.future;
   }
 
@@ -28446,11 +29173,11 @@
 
   @DomName('DOMWindow.setInterval')
   @DocsEditable
-  int _setInterval(TimeoutHandler handler, int timeout) native "DOMWindow_setInterval_Callback";
+  int _setInterval(Object handler, int timeout) native "DOMWindow_setInterval_Callback";
 
   @DomName('DOMWindow.setTimeout')
   @DocsEditable
-  int _setTimeout(TimeoutHandler handler, int timeout) native "DOMWindow_setTimeout_Callback";
+  int _setTimeout(Object handler, int timeout) native "DOMWindow_setTimeout_Callback";
 
   @DomName('DOMWindow.showModalDialog')
   @DocsEditable
@@ -28478,13 +29205,29 @@
   @DocsEditable
   @SupportedBrowser(SupportedBrowser.CHROME)
   @Experimental
-  void requestFileSystem(int type, int size, FileSystemCallback successCallback, [ErrorCallback errorCallback]) native "DOMWindow_webkitRequestFileSystem_Callback";
+  void _requestFileSystem(int type, int size, _FileSystemCallback successCallback, [_ErrorCallback errorCallback]) native "DOMWindow_webkitRequestFileSystem_Callback";
+
+  Future<FileSystem> requestFileSystem(int type, int size) {
+    var completer = new Completer<FileSystem>();
+    _requestFileSystem(type, size,
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
   @DomName('DOMWindow.webkitResolveLocalFileSystemURL')
   @DocsEditable
   @SupportedBrowser(SupportedBrowser.CHROME)
   @Experimental
-  void resolveLocalFileSystemUrl(String url, EntryCallback successCallback, [ErrorCallback errorCallback]) native "DOMWindow_webkitResolveLocalFileSystemURL_Callback";
+  void _resolveLocalFileSystemUrl(String url, _EntryCallback successCallback, [_ErrorCallback errorCallback]) native "DOMWindow_webkitResolveLocalFileSystemURL_Callback";
+
+  Future<Entry> resolveLocalFileSystemUrl(String url) {
+    var completer = new Completer<Entry>();
+    _resolveLocalFileSystemUrl(url,
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
   @DomName('DOMWindow.onDOMContentLoaded')
   @DocsEditable
@@ -28832,17 +29575,25 @@
 
   @DomName('WorkerContext.setInterval')
   @DocsEditable
-  int setInterval(TimeoutHandler handler, int timeout) native "WorkerContext_setInterval_Callback";
+  int setInterval(Object handler, int timeout) native "WorkerContext_setInterval_Callback";
 
   @DomName('WorkerContext.setTimeout')
   @DocsEditable
-  int setTimeout(TimeoutHandler handler, int timeout) native "WorkerContext_setTimeout_Callback";
+  int setTimeout(Object handler, int timeout) native "WorkerContext_setTimeout_Callback";
 
   @DomName('WorkerContext.webkitRequestFileSystem')
   @DocsEditable
   @SupportedBrowser(SupportedBrowser.CHROME)
   @Experimental
-  void requestFileSystem(int type, int size, [FileSystemCallback successCallback, ErrorCallback errorCallback]) native "WorkerContext_webkitRequestFileSystem_Callback";
+  void _requestFileSystem(int type, int size, [_FileSystemCallback successCallback, _ErrorCallback errorCallback]) native "WorkerContext_webkitRequestFileSystem_Callback";
+
+  Future<FileSystem> requestFileSystem(int type, int size) {
+    var completer = new Completer<FileSystem>();
+    _requestFileSystem(type, size,
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
   @DomName('WorkerContext.webkitRequestFileSystemSync')
   @DocsEditable
@@ -28860,7 +29611,15 @@
   @DocsEditable
   @SupportedBrowser(SupportedBrowser.CHROME)
   @Experimental
-  void resolveLocalFileSystemUrl(String url, EntryCallback successCallback, [ErrorCallback errorCallback]) native "WorkerContext_webkitResolveLocalFileSystemURL_Callback";
+  void _resolveLocalFileSystemUrl(String url, _EntryCallback successCallback, [_ErrorCallback errorCallback]) native "WorkerContext_webkitResolveLocalFileSystemURL_Callback";
+
+  Future<Entry> resolveLocalFileSystemUrl(String url) {
+    var completer = new Completer<Entry>();
+    _resolveLocalFileSystemUrl(url,
+        (value) { completer.complete(value); },
+        (error) { completer.completeError(error); });
+    return completer.future;
+  }
 
   @DomName('WorkerContext.onerror')
   @DocsEditable
@@ -29205,6 +29964,132 @@
   DocumentFragment transformToFragment(Node source, Document docVal) native "XSLTProcessor_transformToFragment_Callback";
 
 }
+// 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.
+
+
+@DocsEditable
+@DomName('ClientRect')
+class _ClientRect extends NativeFieldWrapperClass1 implements Rect {
+
+  // NOTE! All code below should be common with Rect.
+  // TODO(blois): implement with mixins when available.
+
+  String toString() {
+    return '($left, $top, $width, $height)';
+  }
+
+  bool operator ==(other) {
+    if (other is !Rect) return false;
+    return left == other.left && top == other.top && width == other.width &&
+        height == other.height;
+  }
+
+  /**
+   * Computes the intersection of this rectangle and the rectangle parameter.
+   * Returns null if there is no intersection.
+   */
+  Rect intersection(Rect rect) {
+    var x0 = max(left, rect.left);
+    var x1 = min(left + width, rect.left + rect.width);
+
+    if (x0 <= x1) {
+      var y0 = max(top, rect.top);
+      var y1 = min(top + height, rect.top + rect.height);
+
+      if (y0 <= y1) {
+        return new Rect(x0, y0, x1 - x0, y1 - y0);
+      }
+    }
+    return null;
+  }
+
+
+  /**
+   * Returns whether a rectangle intersects this rectangle.
+   */
+  bool intersects(Rect other) {
+    return (left <= other.left + other.width && other.left <= left + width &&
+        top <= other.top + other.height && other.top <= top + height);
+  }
+
+  /**
+   * Returns a new rectangle which completely contains this rectangle and the
+   * input rectangle.
+   */
+  Rect union(Rect rect) {
+    var right = max(this.left + this.width, rect.left + rect.width);
+    var bottom = max(this.top + this.height, rect.top + rect.height);
+
+    var left = min(this.left, rect.left);
+    var top = min(this.top, rect.top);
+
+    return new Rect(left, top, right - left, bottom - top);
+  }
+
+  /**
+   * Tests whether this rectangle entirely contains another rectangle.
+   */
+  bool containsRect(Rect another) {
+    return left <= another.left &&
+           left + width >= another.left + another.width &&
+           top <= another.top &&
+           top + height >= another.top + another.height;
+  }
+
+  /**
+   * Tests whether this rectangle entirely contains a point.
+   */
+  bool containsPoint(Point another) {
+    return another.x >= left &&
+           another.x <= left + width &&
+           another.y >= top &&
+           another.y <= top + height;
+  }
+
+  Rect ceil() => new Rect(left.ceil(), top.ceil(), width.ceil(), height.ceil());
+  Rect floor() => new Rect(left.floor(), top.floor(), width.floor(),
+      height.floor());
+  Rect round() => new Rect(left.round(), top.round(), width.round(),
+      height.round());
+
+  /**
+   * Truncates coordinates to integers and returns the result as a new
+   * rectangle.
+   */
+  Rect toInt() => new Rect(left.toInt(), top.toInt(), width.toInt(),
+      height.toInt());
+
+  Point get topLeft => new Point(this.left, this.top);
+  Point get bottomRight => new Point(this.left + this.width,
+      this.top + this.height);
+  _ClientRect.internal();
+
+  @DomName('ClientRect.bottom')
+  @DocsEditable
+  num get bottom native "ClientRect_bottom_Getter";
+
+  @DomName('ClientRect.height')
+  @DocsEditable
+  num get height native "ClientRect_height_Getter";
+
+  @DomName('ClientRect.left')
+  @DocsEditable
+  num get left native "ClientRect_left_Getter";
+
+  @DomName('ClientRect.right')
+  @DocsEditable
+  num get right native "ClientRect_right_Getter";
+
+  @DomName('ClientRect.top')
+  @DocsEditable
+  num get top native "ClientRect_top_Getter";
+
+  @DomName('ClientRect.width')
+  @DocsEditable
+  num get width native "ClientRect_width_Getter";
+}
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -29214,104 +30099,104 @@
 
 @DocsEditable
 @DomName('ClientRectList')
-class _ClientRectList extends NativeFieldWrapperClass1 implements List<ClientRect> {
+class _ClientRectList extends NativeFieldWrapperClass1 implements List<Rect> {
   _ClientRectList.internal();
 
   @DomName('ClientRectList.length')
   @DocsEditable
   int get length native "ClientRectList_length_Getter";
 
-  ClientRect operator[](int index) native "ClientRectList_item_Callback";
+  Rect operator[](int index) native "ClientRectList_item_Callback";
 
-  void operator[]=(int index, ClientRect value) {
+  void operator[]=(int index, Rect value) {
     throw new UnsupportedError("Cannot assign element of immutable List.");
   }
-  // -- start List<ClientRect> mixins.
-  // ClientRect is the element type.
+  // -- start List<Rect> mixins.
+  // Rect is the element type.
 
-  // From Iterable<ClientRect>:
+  // From Iterable<Rect>:
 
-  Iterator<ClientRect> get iterator {
+  Iterator<Rect> get iterator {
     // Note: NodeLists are not fixed size. And most probably length shouldn't
     // be cached in both iterator _and_ forEach method. For now caching it
     // for consistency.
-    return new FixedSizeListIterator<ClientRect>(this);
+    return new FixedSizeListIterator<Rect>(this);
   }
 
-  dynamic reduce(dynamic initialValue, dynamic combine(dynamic, ClientRect)) {
+  dynamic reduce(dynamic initialValue, dynamic combine(dynamic, Rect)) {
     return IterableMixinWorkaround.reduce(this, initialValue, combine);
   }
 
-  bool contains(ClientRect element) => IterableMixinWorkaround.contains(this, element);
+  bool contains(Rect element) => IterableMixinWorkaround.contains(this, element);
 
-  void forEach(void f(ClientRect element)) => IterableMixinWorkaround.forEach(this, f);
+  void forEach(void f(Rect element)) => IterableMixinWorkaround.forEach(this, f);
 
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  Iterable map(f(ClientRect element)) =>
+  Iterable map(f(Rect element)) =>
       IterableMixinWorkaround.mapList(this, f);
 
-  Iterable<ClientRect> where(bool f(ClientRect element)) =>
+  Iterable<Rect> where(bool f(Rect element)) =>
       IterableMixinWorkaround.where(this, f);
 
-  Iterable expand(Iterable f(ClientRect element)) =>
+  Iterable expand(Iterable f(Rect element)) =>
       IterableMixinWorkaround.expand(this, f);
 
-  bool every(bool f(ClientRect element)) => IterableMixinWorkaround.every(this, f);
+  bool every(bool f(Rect element)) => IterableMixinWorkaround.every(this, f);
 
-  bool any(bool f(ClientRect element)) => IterableMixinWorkaround.any(this, f);
+  bool any(bool f(Rect element)) => IterableMixinWorkaround.any(this, f);
 
-  List<ClientRect> toList({ bool growable: true }) =>
-      new List<ClientRect>.from(this, growable: growable);
+  List<Rect> toList({ bool growable: true }) =>
+      new List<Rect>.from(this, growable: growable);
 
-  Set<ClientRect> toSet() => new Set<ClientRect>.from(this);
+  Set<Rect> toSet() => new Set<Rect>.from(this);
 
   bool get isEmpty => this.length == 0;
 
-  Iterable<ClientRect> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<Rect> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
-  Iterable<ClientRect> takeWhile(bool test(ClientRect value)) {
+  Iterable<Rect> takeWhile(bool test(Rect value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  Iterable<ClientRect> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<Rect> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
-  Iterable<ClientRect> skipWhile(bool test(ClientRect value)) {
+  Iterable<Rect> skipWhile(bool test(Rect value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  ClientRect firstMatching(bool test(ClientRect value), { ClientRect orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Rect firstWhere(bool test(Rect value), { Rect orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  ClientRect lastMatching(bool test(ClientRect value), {ClientRect orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Rect lastWhere(bool test(Rect value), {Rect orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  ClientRect singleMatching(bool test(ClientRect value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Rect singleWhere(bool test(Rect value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
-  ClientRect elementAt(int index) {
+  Rect elementAt(int index) {
     return this[index];
   }
 
-  // From Collection<ClientRect>:
+  // From Collection<Rect>:
 
-  void add(ClientRect value) {
+  void add(Rect value) {
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
-  void addLast(ClientRect value) {
+  void addLast(Rect value) {
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
-  void addAll(Iterable<ClientRect> iterable) {
+  void addAll(Iterable<Rect> iterable) {
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
-  // From List<ClientRect>:
+  // From List<Rect>:
   void set length(int value) {
     throw new UnsupportedError("Cannot resize immutable List.");
   }
@@ -29320,49 +30205,53 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  Iterable<ClientRect> get reversed {
+  Iterable<Rect> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
-  void sort([int compare(ClientRect a, ClientRect b)]) {
+  void sort([int compare(Rect a, Rect b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
   }
 
-  int indexOf(ClientRect element, [int start = 0]) =>
+  int indexOf(Rect element, [int start = 0]) =>
       Lists.indexOf(this, element, start, this.length);
 
-  int lastIndexOf(ClientRect element, [int start]) {
+  int lastIndexOf(Rect element, [int start]) {
     if (start == null) start = length - 1;
     return Lists.lastIndexOf(this, element, start);
   }
 
-  ClientRect get first {
+  Rect get first {
     if (this.length > 0) return this[0];
     throw new StateError("No elements");
   }
 
-  ClientRect get last {
+  Rect get last {
     if (this.length > 0) return this[this.length - 1];
     throw new StateError("No elements");
   }
 
-  ClientRect get single {
+  Rect get single {
     if (length == 1) return this[0];
     if (length == 0) throw new StateError("No elements");
     throw new StateError("More than one element");
   }
 
-  ClientRect min([int compare(ClientRect a, ClientRect b)]) =>
+  Rect min([int compare(Rect a, Rect b)]) =>
       IterableMixinWorkaround.min(this, compare);
 
-  ClientRect max([int compare(ClientRect a, ClientRect b)]) =>
+  Rect max([int compare(Rect a, Rect b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
-  ClientRect removeAt(int pos) {
+  void insert(int index, Rect element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  Rect removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  ClientRect removeLast() {
+  Rect removeLast() {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -29378,15 +30267,15 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(ClientRect element)) {
+  void removeWhere(bool test(Rect element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(ClientRect element)) {
+  void retainWhere(bool test(Rect element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<ClientRect> from, [int startFrom]) {
+  void setRange(int start, int rangeLength, List<Rect> from, [int startFrom]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
@@ -29394,18 +30283,26 @@
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [ClientRect initialValue]) {
+  void insertRange(int start, int rangeLength, [Rect initialValue]) {
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
-  List<ClientRect> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <ClientRect>[]);
+  List<Rect> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <Rect>[]);
+  }
 
-  // -- end List<ClientRect> mixins.
+  List<Rect> getRange(int start, int rangeLength) =>
+      sublist(start, start + rangeLength);
+
+  Map<int, Rect> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
+
+  // -- end List<Rect> mixins.
 
   @DomName('ClientRectList.item')
   @DocsEditable
-  ClientRect item(int index) native "ClientRectList_item_Callback";
+  Rect item(int index) native "ClientRectList_item_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -29484,16 +30381,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  CssRule firstMatching(bool test(CssRule value), { CssRule orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  CssRule firstWhere(bool test(CssRule value), { CssRule orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  CssRule lastMatching(bool test(CssRule value), {CssRule orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  CssRule lastWhere(bool test(CssRule value), {CssRule orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  CssRule singleMatching(bool test(CssRule value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  CssRule singleWhere(bool test(CssRule value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   CssRule elementAt(int index) {
@@ -29561,6 +30458,10 @@
   CssRule max([int compare(CssRule a, CssRule b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, CssRule element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   CssRule removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -29581,11 +30482,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(CssRule element)) {
+  void removeWhere(bool test(CssRule element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(CssRule element)) {
+  void retainWhere(bool test(CssRule element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -29601,8 +30502,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<CssRule> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <CssRule>[]);
+  }
+
   List<CssRule> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <CssRule>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, CssRule> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<CssRule> mixins.
 
@@ -29687,16 +30596,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  CssValue firstMatching(bool test(CssValue value), { CssValue orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  CssValue firstWhere(bool test(CssValue value), { CssValue orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  CssValue lastMatching(bool test(CssValue value), {CssValue orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  CssValue lastWhere(bool test(CssValue value), {CssValue orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  CssValue singleMatching(bool test(CssValue value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  CssValue singleWhere(bool test(CssValue value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   CssValue elementAt(int index) {
@@ -29764,6 +30673,10 @@
   CssValue max([int compare(CssValue a, CssValue b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, CssValue element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   CssValue removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -29784,11 +30697,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(CssValue element)) {
+  void removeWhere(bool test(CssValue element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(CssValue element)) {
+  void retainWhere(bool test(CssValue element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -29804,8 +30717,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<CssValue> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <CssValue>[]);
+  }
+
   List<CssValue> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <CssValue>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, CssValue> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<CssValue> mixins.
 
@@ -30033,16 +30954,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Entry firstMatching(bool test(Entry value), { Entry orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Entry firstWhere(bool test(Entry value), { Entry orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Entry lastMatching(bool test(Entry value), {Entry orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Entry lastWhere(bool test(Entry value), {Entry orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Entry singleMatching(bool test(Entry value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Entry singleWhere(bool test(Entry value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Entry elementAt(int index) {
@@ -30110,6 +31031,10 @@
   Entry max([int compare(Entry a, Entry b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, Entry element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   Entry removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -30130,11 +31055,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(Entry element)) {
+  void removeWhere(bool test(Entry element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(Entry element)) {
+  void retainWhere(bool test(Entry element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -30150,8 +31075,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<Entry> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <Entry>[]);
+  }
+
   List<Entry> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Entry>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, Entry> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<Entry> mixins.
 
@@ -30236,16 +31169,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  EntrySync firstMatching(bool test(EntrySync value), { EntrySync orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  EntrySync firstWhere(bool test(EntrySync value), { EntrySync orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  EntrySync lastMatching(bool test(EntrySync value), {EntrySync orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  EntrySync lastWhere(bool test(EntrySync value), {EntrySync orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  EntrySync singleMatching(bool test(EntrySync value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  EntrySync singleWhere(bool test(EntrySync value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   EntrySync elementAt(int index) {
@@ -30313,6 +31246,10 @@
   EntrySync max([int compare(EntrySync a, EntrySync b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, EntrySync element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   EntrySync removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -30333,11 +31270,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(EntrySync element)) {
+  void removeWhere(bool test(EntrySync element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(EntrySync element)) {
+  void retainWhere(bool test(EntrySync element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -30353,8 +31290,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<EntrySync> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <EntrySync>[]);
+  }
+
   List<EntrySync> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <EntrySync>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, EntrySync> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<EntrySync> mixins.
 
@@ -30439,16 +31384,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Gamepad firstMatching(bool test(Gamepad value), { Gamepad orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Gamepad firstWhere(bool test(Gamepad value), { Gamepad orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Gamepad lastMatching(bool test(Gamepad value), {Gamepad orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Gamepad lastWhere(bool test(Gamepad value), {Gamepad orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Gamepad singleMatching(bool test(Gamepad value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Gamepad singleWhere(bool test(Gamepad value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Gamepad elementAt(int index) {
@@ -30516,6 +31461,10 @@
   Gamepad max([int compare(Gamepad a, Gamepad b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, Gamepad element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   Gamepad removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -30536,11 +31485,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(Gamepad element)) {
+  void removeWhere(bool test(Gamepad element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(Gamepad element)) {
+  void retainWhere(bool test(Gamepad element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -30556,8 +31505,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<Gamepad> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <Gamepad>[]);
+  }
+
   List<Gamepad> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Gamepad>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, Gamepad> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<Gamepad> mixins.
 
@@ -30733,16 +31690,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Node firstMatching(bool test(Node value), { Node orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Node firstWhere(bool test(Node value), { Node orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Node lastMatching(bool test(Node value), {Node orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Node lastWhere(bool test(Node value), {Node orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Node singleMatching(bool test(Node value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Node singleWhere(bool test(Node value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Node elementAt(int index) {
@@ -30810,6 +31767,10 @@
   Node max([int compare(Node a, Node b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, Node element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   Node removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -30830,11 +31791,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(Node element)) {
+  void removeWhere(bool test(Node element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(Node element)) {
+  void retainWhere(bool test(Node element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -30850,8 +31811,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<Node> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <Node>[]);
+  }
+
   List<Node> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Node>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, Node> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<Node> mixins.
 
@@ -30960,16 +31929,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  SpeechInputResult firstMatching(bool test(SpeechInputResult value), { SpeechInputResult orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  SpeechInputResult firstWhere(bool test(SpeechInputResult value), { SpeechInputResult orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  SpeechInputResult lastMatching(bool test(SpeechInputResult value), {SpeechInputResult orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  SpeechInputResult lastWhere(bool test(SpeechInputResult value), {SpeechInputResult orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  SpeechInputResult singleMatching(bool test(SpeechInputResult value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  SpeechInputResult singleWhere(bool test(SpeechInputResult value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   SpeechInputResult elementAt(int index) {
@@ -31037,6 +32006,10 @@
   SpeechInputResult max([int compare(SpeechInputResult a, SpeechInputResult b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, SpeechInputResult element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   SpeechInputResult removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -31057,11 +32030,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(SpeechInputResult element)) {
+  void removeWhere(bool test(SpeechInputResult element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(SpeechInputResult element)) {
+  void retainWhere(bool test(SpeechInputResult element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -31077,8 +32050,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<SpeechInputResult> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <SpeechInputResult>[]);
+  }
+
   List<SpeechInputResult> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <SpeechInputResult>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, SpeechInputResult> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<SpeechInputResult> mixins.
 
@@ -31163,16 +32144,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  SpeechRecognitionResult firstMatching(bool test(SpeechRecognitionResult value), { SpeechRecognitionResult orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  SpeechRecognitionResult firstWhere(bool test(SpeechRecognitionResult value), { SpeechRecognitionResult orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  SpeechRecognitionResult lastMatching(bool test(SpeechRecognitionResult value), {SpeechRecognitionResult orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  SpeechRecognitionResult lastWhere(bool test(SpeechRecognitionResult value), {SpeechRecognitionResult orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  SpeechRecognitionResult singleMatching(bool test(SpeechRecognitionResult value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  SpeechRecognitionResult singleWhere(bool test(SpeechRecognitionResult value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   SpeechRecognitionResult elementAt(int index) {
@@ -31240,6 +32221,10 @@
   SpeechRecognitionResult max([int compare(SpeechRecognitionResult a, SpeechRecognitionResult b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, SpeechRecognitionResult element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   SpeechRecognitionResult removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -31260,11 +32245,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(SpeechRecognitionResult element)) {
+  void removeWhere(bool test(SpeechRecognitionResult element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(SpeechRecognitionResult element)) {
+  void retainWhere(bool test(SpeechRecognitionResult element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -31280,8 +32265,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<SpeechRecognitionResult> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <SpeechRecognitionResult>[]);
+  }
+
   List<SpeechRecognitionResult> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <SpeechRecognitionResult>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, SpeechRecognitionResult> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<SpeechRecognitionResult> mixins.
 
@@ -31366,16 +32359,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  StyleSheet firstMatching(bool test(StyleSheet value), { StyleSheet orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  StyleSheet firstWhere(bool test(StyleSheet value), { StyleSheet orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  StyleSheet lastMatching(bool test(StyleSheet value), {StyleSheet orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  StyleSheet lastWhere(bool test(StyleSheet value), {StyleSheet orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  StyleSheet singleMatching(bool test(StyleSheet value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  StyleSheet singleWhere(bool test(StyleSheet value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   StyleSheet elementAt(int index) {
@@ -31443,6 +32436,10 @@
   StyleSheet max([int compare(StyleSheet a, StyleSheet b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, StyleSheet element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   StyleSheet removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -31463,11 +32460,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(StyleSheet element)) {
+  void removeWhere(bool test(StyleSheet element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(StyleSheet element)) {
+  void retainWhere(bool test(StyleSheet element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -31483,8 +32480,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<StyleSheet> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <StyleSheet>[]);
+  }
+
   List<StyleSheet> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <StyleSheet>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, StyleSheet> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<StyleSheet> mixins.
 
@@ -31744,6 +32749,32 @@
 
 
 /**
+ * An object that can be drawn to a [CanvasRenderingContext2D] object with
+ * [CanvasRenderingContext2D.drawImage] or
+ * [CanvasRenderingContext2D.drawImageAtScale].
+ *
+ * If the CanvasImageSource is an [ImageElement] then the element's image is
+ * used. If the [ImageElement] is an animated image, then the poster frame is
+ * used. If there is no poster frame, then the first frame of animation is used.
+ *
+ * If the CanvasImageSource is a [VideoElement] then the frame at the current
+ * playback position is used as the image.
+ *
+ * If the CanvasImageSource is a [CanvasElement] then the element's bitmap is
+ * used.
+ *
+ * See also:
+ *
+ *  * [CanvasImageSource](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-sources-for-2d-rendering-contexts)
+ * from the WHATWG.
+ */
+abstract class CanvasImageSource {}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+/**
  * An object representing the top-level context object for web scripting.
  *
  * In a web browser, a [Window] object represents the actual browser window.
@@ -31915,7 +32946,7 @@
 
   Iterable<String> where(bool f(String element)) => readClasses().where(f);
 
-  Iterable expand(Iterable f(String element)) => readClasses.expand(f);
+  Iterable expand(Iterable f(String element)) => readClasses().expand(f);
 
   bool every(bool f(String element)) => readClasses().every(f);
 
@@ -31961,23 +32992,29 @@
     _modify((s) => s.retainAll(iterable));
   }
 
-  void removeMatching(bool test(String name)) {
-    _modify((s) => s.removeMatching(test));
+  void removeWhere(bool test(String name)) {
+    _modify((s) => s.removeWhere(test));
   }
 
-  void retainMatching(bool test(String name)) {
-    _modify((s) => s.retainMatching(test));
+  void retainWhere(bool test(String name)) {
+    _modify((s) => s.retainWhere(test));
   }
 
   bool isSubsetOf(Collection<String> collection) =>
     readClasses().isSubsetOf(collection);
 
-  bool containsAll(Collection<String> collection) =>
+  bool containsAll(Iterable<String> collection) =>
     readClasses().containsAll(collection);
 
-  Set<String> intersection(Collection<String> other) =>
+  Set<String> intersection(Set<String> other) =>
     readClasses().intersection(other);
 
+  Set<String> union(Set<String> other) =>
+    readClasses().union(other);
+
+  Set<String> difference(Set<String> other) =>
+    readClasses().difference(other);
+
   String get first => readClasses().first;
   String get last => readClasses().last;
   String get single => readClasses().single;
@@ -31994,12 +33031,12 @@
   Iterable<String> skip(int n) => readClasses().skip(n);
   Iterable<String> skipWhile(bool test(String value)) =>
       readClasses().skipWhile(test);
-  String firstMatching(bool test(String value), { String orElse() }) =>
-      readClasses().firstMatching(test, orElse: orElse);
-  String lastMatching(bool test(String value), {String orElse()}) =>
-      readClasses().lastMatching(test, orElse: orElse);
-  String singleMatching(bool test(String value)) =>
-      readClasses().singleMatching(test);
+  String firstWhere(bool test(String value), { String orElse() }) =>
+      readClasses().firstWhere(test, orElse: orElse);
+  String lastWhere(bool test(String value), {String orElse()}) =>
+      readClasses().lastWhere(test, orElse: orElse);
+  String singleWhere(bool test(String value)) =>
+      readClasses().singleWhere(test);
   String elementAt(int index) => readClasses().elementAt(index);
 
   void clear() {
@@ -32469,11 +33506,11 @@
    * Returns true if the key fires a keypress event in the current browser.
    */
   bool _firesKeyPressEvent(KeyEvent event) {
-    if (!_Device.isIE && !_Device.isWebKit) {
+    if (!Device.isIE && !Device.isWebKit) {
       return true;
     }
 
-    if (_Device.userAgent.contains('Mac') && event.altKey) {
+    if (Device.userAgent.contains('Mac') && event.altKey) {
       return KeyCode.isCharacterKey(event.keyCode);
     }
 
@@ -32486,13 +33523,13 @@
     if (!event.shiftKey &&
         (_keyDownList.last.keyCode == KeyCode.CTRL ||
          _keyDownList.last.keyCode == KeyCode.ALT ||
-         _Device.userAgent.contains('Mac') &&
+         Device.userAgent.contains('Mac') &&
          _keyDownList.last.keyCode == KeyCode.META)) {
       return false;
     }
 
     // Some keys with Ctrl/Shift do not issue keypress in WebKit.
-    if (_Device.isWebKit && event.ctrlKey && event.shiftKey && (
+    if (Device.isWebKit && event.ctrlKey && event.shiftKey && (
         event.keyCode == KeyCode.BACKSLASH ||
         event.keyCode == KeyCode.OPEN_SQUARE_BRACKET ||
         event.keyCode == KeyCode.CLOSE_SQUARE_BRACKET ||
@@ -32508,9 +33545,9 @@
     switch (event.keyCode) {
       case KeyCode.ENTER:
         // IE9 does not fire keypress on ENTER.
-        return !_Device.isIE;
+        return !Device.isIE;
       case KeyCode.ESC:
-        return !_Device.isWebKit;
+        return !Device.isWebKit;
     }
 
     return KeyCode.isCharacterKey(event.keyCode);
@@ -32522,7 +33559,7 @@
    */
   int _normalizeKeyCodes(KeyboardEvent event) {
     // Note: This may change once we get input about non-US keyboards.
-    if (_Device.isFirefox) {
+    if (Device.isFirefox) {
       switch(event.keyCode) {
         case KeyCode.FF_EQUALS:
           return KeyCode.EQUALS;
@@ -32545,7 +33582,7 @@
     if (_keyDownList.length > 0 &&
         (_keyDownList.last.keyCode == KeyCode.CTRL && !e.ctrlKey ||
          _keyDownList.last.keyCode == KeyCode.ALT && !e.altKey ||
-         _Device.userAgent.contains('Mac') &&
+         Device.userAgent.contains('Mac') &&
          _keyDownList.last.keyCode == KeyCode.META && !e.metaKey)) {
       _keyDownList = [];
     }
@@ -32572,13 +33609,13 @@
     var e = new KeyEvent(event);
     // IE reports the character code in the keyCode field for keypress events.
     // There are two exceptions however, Enter and Escape.
-    if (_Device.isIE) {
+    if (Device.isIE) {
       if (e.keyCode == KeyCode.ENTER || e.keyCode == KeyCode.ESC) {
         e._shadowCharCode = 0;
       } else {
         e._shadowCharCode = e.keyCode;
       }
-    } else if (_Device.isOpera) {
+    } else if (Device.isOpera) {
       // Opera reports the character code in the keyCode field.
       e._shadowCharCode = KeyCode.isCharacterKey(e.keyCode) ? e.keyCode : 0;
     }
@@ -32624,9 +33661,9 @@
 
 
 /**
- * Defines the keycode values for keys that are returned by 
+ * Defines the keycode values for keys that are returned by
  * KeyboardEvent.keyCode.
- * 
+ *
  * Important note: There is substantial divergence in how different browsers
  * handle keycodes and their variants in different locales/keyboard layouts. We
  * provide these constants to help make code processing keys more readable.
@@ -32634,7 +33671,7 @@
 abstract class KeyCode {
   // These constant names were borrowed from Closure's Keycode enumeration
   // class.
-  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keycodes.js.source.html  
+  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keycodes.js.source.html
   static const int WIN_KEY_FF_LINUX = 0;
   static const int MAC_ENTER = 3;
   static const int BACKSPACE = 8;
@@ -32829,12 +33866,12 @@
         (keyCode >= A && keyCode <= Z)) {
       return true;
     }
- 
+
     // Safari sends zero key code for non-latin characters.
-    if (_Device.isWebKit && keyCode == 0) {
+    if (Device.isWebKit && keyCode == 0) {
       return true;
     }
- 
+
     return (keyCode == SPACE || keyCode == QUESTION_MARK || keyCode == NUM_PLUS
         || keyCode == NUM_MINUS || keyCode == NUM_PERIOD ||
         keyCode == NUM_DIVISION || keyCode == SEMICOLON ||
@@ -33385,6 +34422,168 @@
    */
   static const String UNIDENTIFIED = "Unidentified";
 }
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+class _ModelTreeObserver {
+  static bool _initialized = false;
+
+  /**
+   * Start an observer watching the document for tree changes to automatically
+   * propagate model changes.
+   *
+   * Currently this does not support propagation through Shadow DOMs.
+   */
+  static void initialize() {
+    if (!_initialized) {
+      _initialized = true;
+
+      if (MutationObserver.supported) {
+        var observer = new MutationObserver(_processTreeChange);
+        observer.observe(document, childList: true, subtree: true);
+      } else {
+        document.on['DOMNodeInserted'].listen(_handleNodeInserted);
+        document.on['DOMNodeRemoved'].listen(_handleNodeRemoved);
+      }
+    }
+  }
+
+  static void _processTreeChange(List<MutationRecord> mutations,
+      MutationObserver observer) {
+    for (var record in mutations) {
+      for (var node in record.addedNodes) {
+        // When nodes enter the document we need to make sure that all of the
+        // models are properly propagated through the entire sub-tree.
+        propagateModel(node, _calculatedModel(node), true);
+      }
+      for (var node in record.removedNodes) {
+        propagateModel(node, _calculatedModel(node), false);
+      }
+    }
+  }
+
+  static void _handleNodeInserted(MutationEvent e) {
+    var node = e.target;
+    window.setImmediate(() {
+      propagateModel(node, _calculatedModel(node), true);
+    });
+  }
+
+  static void _handleNodeRemoved(MutationEvent e) {
+    var node = e.target;
+    window.setImmediate(() {
+      propagateModel(node, _calculatedModel(node), false);
+    });
+  }
+
+  /**
+   * Figures out what the model should be for a node, avoiding any cached
+   * model values.
+   */
+  static _calculatedModel(node) {
+    if (node._hasLocalModel == true) {
+      return node._model;
+    } else if (node.parentNode != null) {
+      return node.parentNode._model;
+    }
+    return null;
+  }
+
+  /**
+   * Pushes model changes down through the tree.
+   *
+   * Set fullTree to true if the state of the tree is unknown and model changes
+   * should be propagated through the entire tree.
+   */
+  static void propagateModel(Node node, model, bool fullTree) {
+    // Calling into user code with the != call could generate exceptions.
+    // Catch and report them a global exceptions.
+    try {
+      if (node._hasLocalModel != true && node._model != model &&
+          node._modelChangedStream != null) {
+        node._model = model;
+        node._modelChangedStream.add(node);
+      }
+    } on AsyncError catch (e) {
+      e.throwDelayed();
+    } catch (e, s) {
+      new AsyncError(e, s).throwDelayed();
+    }
+    for (var child = node.$dom_firstChild; child != null;
+        child = child.nextNode) {
+      if (child._hasLocalModel != true) {
+        propagateModel(child, model, fullTree);
+      } else if (fullTree) {
+        propagateModel(child, child._model, true);
+      }
+    }
+  }
+}
+// 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.
+
+
+/**
+ * A utility class for representing two-dimensional positions.
+ */
+class Point {
+  final num x;
+  final num y;
+
+  const Point([num x = 0, num y = 0]): x = x, y = y;
+
+  String toString() => '($x, $y)';
+
+  bool operator ==(other) {
+    if (other is !Point) return false;
+    return x == other.x && y == other.y;
+  }
+
+  Point operator +(Point other) {
+    return new Point(x + other.x, y + other.y);
+  }
+
+  Point operator -(Point other) {
+    return new Point(x - other.x, y - other.y);
+  }
+
+  Point operator *(num factor) {
+    return new Point(x * factor, y * factor);
+  }
+
+  /**
+   * Returns the distance between two points.
+   */
+  double distanceTo(Point other) {
+    var dx = x - other.x;
+    var dy = y - other.y;
+    return sqrt(dx * dx + dy * dy);
+  }
+
+  /**
+   * Returns the squared distance between two points.
+   *
+   * Squared distances can be used for comparisons when the actual value is not
+   * required.
+   */
+  num squaredDistanceTo(Point other) {
+    var dx = x - other.x;
+    var dy = y - other.y;
+    return dx * dx + dy * dy;
+  }
+
+  Point ceil() => new Point(x.ceil(), y.ceil());
+  Point floor() => new Point(x.floor(), y.floor());
+  Point round() => new Point(x.round(), y.round());
+
+  /**
+   * Truncates x and y to integers and returns the result as a new point.
+   */
+  Point toInt() => new Point(x.toInt(), y.toInt());
+}
 // 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.
@@ -33410,6 +34609,140 @@
    */
   static const String COMPLETE = "complete";
 }
+// 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.
+
+
+/**
+ * A class for representing two-dimensional rectangles.
+ */
+class Rect {
+  final num left;
+  final num top;
+  final num width;
+  final num height;
+
+  const Rect(this.left, this.top, this.width, this.height);
+
+  factory Rect.fromPoints(Point a, Point b) {
+    var left;
+    var width;
+    if (a.x < b.x) {
+      left = a.x;
+      width = b.x - left;
+    } else {
+      left = b.x;
+      width = a.x - left;
+    }
+    var top;
+    var height;
+    if (a.y < b.y) {
+      top = a.y;
+      height = b.y - top;
+    } else {
+      top = b.y;
+      height = a.y - top;
+    }
+
+    return new Rect(left, top, width, height);
+  }
+
+  num get right => left + width;
+  num get bottom => top + height;
+
+  // NOTE! All code below should be common with Rect.
+  // TODO: implement with mixins when available.
+
+  String toString() {
+    return '($left, $top, $width, $height)';
+  }
+
+  bool operator ==(other) {
+    if (other is !Rect) return false;
+    return left == other.left && top == other.top && width == other.width &&
+        height == other.height;
+  }
+
+  /**
+   * Computes the intersection of this rectangle and the rectangle parameter.
+   * Returns null if there is no intersection.
+   */
+  Rect intersection(Rect rect) {
+    var x0 = max(left, rect.left);
+    var x1 = min(left + width, rect.left + rect.width);
+
+    if (x0 <= x1) {
+      var y0 = max(top, rect.top);
+      var y1 = min(top + height, rect.top + rect.height);
+
+      if (y0 <= y1) {
+        return new Rect(x0, y0, x1 - x0, y1 - y0);
+      }
+    }
+    return null;
+  }
+
+
+  /**
+   * Returns whether a rectangle intersects this rectangle.
+   */
+  bool intersects(Rect other) {
+    return (left <= other.left + other.width && other.left <= left + width &&
+        top <= other.top + other.height && other.top <= top + height);
+  }
+
+  /**
+   * Returns a new rectangle which completely contains this rectangle and the
+   * input rectangle.
+   */
+  Rect union(Rect rect) {
+    var right = max(this.left + this.width, rect.left + rect.width);
+    var bottom = max(this.top + this.height, rect.top + rect.height);
+
+    var left = min(this.left, rect.left);
+    var top = min(this.top, rect.top);
+
+    return new Rect(left, top, right - left, bottom - top);
+  }
+
+  /**
+   * Tests whether this rectangle entirely contains another rectangle.
+   */
+  bool containsRect(Rect another) {
+    return left <= another.left &&
+           left + width >= another.left + another.width &&
+           top <= another.top &&
+           top + height >= another.top + another.height;
+  }
+
+  /**
+   * Tests whether this rectangle entirely contains a point.
+   */
+  bool containsPoint(Point another) {
+    return another.x >= left &&
+           another.x <= left + width &&
+           another.y >= top &&
+           another.y <= top + height;
+  }
+
+  Rect ceil() => new Rect(left.ceil(), top.ceil(), width.ceil(), height.ceil());
+  Rect floor() => new Rect(left.floor(), top.floor(), width.floor(),
+      height.floor());
+  Rect round() => new Rect(left.round(), top.round(), width.round(),
+      height.round());
+
+  /**
+   * Truncates coordinates to integers and returns the result as a new
+   * rectangle.
+   */
+  Rect toInt() => new Rect(left.toInt(), top.toInt(), width.toInt(),
+      height.toInt());
+
+  Point get topLeft => new Point(this.left, this.top);
+  Point get bottomRight => new Point(this.left + this.width,
+      this.top + this.height);
+}
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -33503,13 +34836,13 @@
 
   E get single => _list.single;
 
-  E firstMatching(bool test(E value), { E orElse() }) =>
-      _list.firstMatching(test, orElse: orElse);
+  E firstWhere(bool test(E value), { E orElse() }) =>
+      _list.firstWhere(test, orElse: orElse);
 
-  E lastMatching(bool test(E value), {E orElse()}) =>
-      _list.lastMatching(test, orElse: orElse);
+  E lastWhere(bool test(E value), {E orElse()}) =>
+      _list.lastWhere(test, orElse: orElse);
 
-  E singleMatching(bool test(E value)) => _list.singleMatching(test);
+  E singleWhere(bool test(E value)) => _list.singleWhere(test);
 
   E elementAt(int index) => _list.elementAt(index);
 
@@ -33525,9 +34858,9 @@
 
   void retainAll(Iterable elements) { _list.retainAll(elements); }
 
-  void removeMatching(bool test(E element)) { _list.removeMatching(test); }
+  void removeWhere(bool test(E element)) { _list.removeWhere(test); }
 
-  void retainMatching(bool test(E element)) { _list.retainMatching(test); }
+  void retainWhere(bool test(E element)) { _list.retainWhere(test); }
 
   void clear() { _list.clear(); }
 
@@ -33539,7 +34872,7 @@
 
   void set length(int newLength) { _list.length = newLength; }
 
-  void addLast(E value) { _list.addLast(value); }
+  void addLast(E value) { _list.add(value); }
 
   Iterable<E> get reversed => _list.reversed;
 
@@ -33549,11 +34882,15 @@
 
   int lastIndexOf(E element, [int start]) => _list.lastIndexOf(element, start);
 
+  void insert(int index, E element) => _list.insert(index, element);
+
   E removeAt(int index) => _list.removeAt(index);
 
   E removeLast() => _list.removeLast();
 
-  List<E> getRange(int start, int length) => _list.getRange(start, length);
+  List<E> sublist(int start, [int end]) => _list.sublist(start, end);
+
+  List<E> getRange(int start, int length) => sublist(start, start + length);
 
   void setRange(int start, int length, List<E> from, [int startFrom]) {
     _list.setRange(start, length, from, startFrom);
@@ -33564,6 +34901,8 @@
   void insertRange(int start, int length, [E fill]) {
     _list.insertRange(start, length, fill);
   }
+
+  Map<int, E> asMap() => IterableMixinWorkaround.asMapList(_list);
 }
 
 /**
@@ -33733,12 +35072,10 @@
    * KeyLocation.NUMPAD, KeyLocation.MOBILE, KeyLocation.JOYSTICK).
    */
   int get keyLocation => _parent.keyLocation;
-  int get layerX => _parent.layerX;
-  int get layerY => _parent.layerY;
+  Point get layer => _parent.layer;
   /** True if the Meta (or Mac command) key is pressed during this event. */
   bool get metaKey => _parent.metaKey;
-  int get pageX => _parent.pageX;
-  int get pageY => _parent.pageY;
+  Point get page => _parent.page;
   bool get returnValue => _parent.returnValue;
   void set returnValue(bool value) {
     _parent.returnValue = value;
@@ -33855,42 +35192,6 @@
 class _TextFactoryProvider {
   static Text createText(String data) => document.$dom_createTextNode(data);
 }
-// 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.
-
-
-/**
- * Utils for device detection.
- */
-class _Device {
-  /**
-   * Gets the browser's user agent. Using this function allows tests to inject
-   * the user agent.
-   * Returns the user agent.
-   */
-  static String get userAgent => window.navigator.userAgent;
-
-  /**
-   * Determines if the current device is running Opera.
-   */
-  static bool get isOpera => userAgent.contains("Opera", 0);
-
-  /**
-   * Determines if the current device is running Internet Explorer.
-   */
-  static bool get isIE => !isOpera && userAgent.contains("MSIE", 0);
-
-  /**
-   * Determines if the current device is running Firefox.
-   */
-  static bool get isFirefox => userAgent.contains("Firefox", 0);
-
-  /**
-   * Determines if the current device is running WebKit.
-   */
-  static bool get isWebKit => !isOpera && userAgent.contains("WebKit", 0);
-}
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -34540,8 +35841,15 @@
 class _Utils {
   static double dateTimeToDouble(DateTime dateTime) =>
       dateTime.millisecondsSinceEpoch.toDouble();
-  static DateTime doubleToDateTime(double dateTime) =>
-      new DateTime.fromMillisecondsSinceEpoch(dateTime.toInt());
+  static DateTime doubleToDateTime(double dateTime) {
+    try {
+      return new DateTime.fromMillisecondsSinceEpoch(dateTime.toInt());
+    } catch(_) {
+      // TODO(antonnm): treat exceptions properly in bindings and
+      // find out how to treat NaNs.
+      return null;
+    }
+  }
 
   static List convertToList(List list) {
     // FIXME: [possible optimization]: do not copy the array if Dart_IsArray is fine w/ it.
@@ -34573,6 +35881,7 @@
 
   static window() native "Utils_window";
   static print(String message) native "Utils_print";
+  static forwardingPrint(String message) native "Utils_forwardingPrint";
   static SendPort spawnDomFunctionImpl(Function topLevelFunction) native "Utils_spawnDomFunction";
   static int _getNewIsolateId() native "Utils_getNewIsolateId";
   static bool shadowRootSupported(Document document) native "Utils_shadowRootSupported";
@@ -34652,3 +35961,5 @@
     _Utils.print(s);
   }
 };
+
+final _forwardingPrintClosure = _Utils.forwardingPrint;
diff --git a/sdk/lib/html/html_common/device.dart b/sdk/lib/html/html_common/device.dart
new file mode 100644
index 0000000..fe9ad35
--- /dev/null
+++ b/sdk/lib/html/html_common/device.dart
@@ -0,0 +1,112 @@
+// 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.
+
+part of html_common;
+
+/**
+ * Utils for device detection.
+ */
+class Device {
+  static bool _isOpera;
+  static bool _isIE;
+  static bool _isFirefox;
+  static bool _isWebKit;
+  static String _cachedCssPrefix;
+  static String _cachedPropertyPrefix;
+
+  /**
+   * Gets the browser's user agent. Using this function allows tests to inject
+   * the user agent.
+ * Returns the user agent.
+   */
+  static String get userAgent => window.navigator.userAgent;
+
+  /**
+   * Determines if the current device is running Opera.
+   */
+  static bool get isOpera {
+    if (_isOpera == null) {
+      _isOpera = userAgent.contains("Opera", 0);
+    }
+    return _isOpera;
+  }
+
+  /**
+   * Determines if the current device is running Internet Explorer.
+   */
+  static bool get isIE {
+    if (_isIE == null) {
+      _isIE = !isOpera && userAgent.contains("MSIE", 0);
+    }
+    return _isIE;
+  }
+
+  /**
+   * Determines if the current device is running Firefox.
+   */
+  static bool get isFirefox {
+    if (_isFirefox == null) {
+      _isFirefox = userAgent.contains("Firefox", 0);
+    }
+    return _isFirefox;
+  }
+
+  /**
+   * Determines if the current device is running WebKit.
+   */
+  static bool get isWebKit {
+    if (_isWebKit == null) {
+      _isWebKit = !isOpera && userAgent.contains("WebKit", 0);
+    }
+    return _isWebKit;
+  }
+
+  /**
+   * Gets the CSS property prefix for the current platform.
+   */
+  static String get cssPrefix {
+    if (_cachedCssPrefix == null) {
+      if (isFirefox) {
+        _cachedCssPrefix = '-moz-';
+      } else if (isIE) {
+        _cachedCssPrefix = '-ms-';
+      } else if (isOpera) {
+        _cachedCssPrefix = '-o-';
+      } else {
+        _cachedCssPrefix = '-webkit-';
+      }
+    }
+    return _cachedCssPrefix;
+  }
+
+  /**
+   * Prefix as used for JS property names.
+   */
+  static String get propertyPrefix {
+    if (_cachedPropertyPrefix == null) {
+      if (isFirefox) {
+        _cachedPropertyPrefix = 'moz';
+      } else if (isIE) {
+        _cachedPropertyPrefix = 'ms';
+      } else if (isOpera) {
+        _cachedPropertyPrefix = 'o';
+      } else {
+        _cachedPropertyPrefix = 'webkit';
+      }
+    }
+    return _cachedPropertyPrefix;
+  }
+
+  /**
+   * Checks to see if the event class is supported by the current platform.
+   */
+  static bool isEventTypeSupported(String eventType) {
+    // Browsers throw for unsupported event names.
+    try {
+      var e = document.$dom_createEvent(eventType);
+      return e is Event;
+    } catch (_) { }
+    return false;
+  }
+}
diff --git a/sdk/lib/html/html_common/filtered_element_list.dart b/sdk/lib/html/html_common/filtered_element_list.dart
index 2644720..5c07fe1 100644
--- a/sdk/lib/html/html_common/filtered_element_list.dart
+++ b/sdk/lib/html/html_common/filtered_element_list.dart
@@ -80,7 +80,7 @@
   }
 
   void removeRange(int start, int rangeLength) {
-    _filtered.getRange(start, rangeLength).forEach((el) => el.remove());
+    _filtered.sublist(start, start + rangeLength).forEach((el) => el.remove());
   }
 
   void insertRange(int start, int rangeLength, [initialValue = null]) {
@@ -105,6 +105,10 @@
   Iterable<Element> where(bool f(Element element)) => _filtered.where(f);
   Iterable expand(Iterable f(Element element)) => _filtered.expand(f);
 
+  void insert(int index, Element value) {
+    _childNodes.insert(index, value);
+  }
+
   Element removeAt(int index) {
     final result = this[index];
     result.remove();
@@ -133,12 +137,12 @@
     IterableMixinWorkaround.retainAll(this, elements);
   }
 
-  void removeMatching(bool test(Element element)) {
-    IterableMixinWorkaround.removeMatching(this, test);
+  void removeWhere(bool test(Element element)) {
+    IterableMixinWorkaround.removeWhere(this, test);
   }
 
-  void retainMatching(bool test(Element element)) {
-    IterableMixinWorkaround.retainMatching(this, test);
+  void retainWhere(bool test(Element element)) {
+    IterableMixinWorkaround.retainWhere(this, test);
   }
 
   dynamic reduce(dynamic initialValue,
@@ -150,16 +154,16 @@
   List<Element> toList({ bool growable: true }) =>
       new List<Element>.from(this, growable: growable);
   Set<Element> toSet() => new Set<Element>.from(this);
-  Element firstMatching(bool test(Element value), {Element orElse()}) {
-    return _filtered.firstMatching(test, orElse: orElse);
+  Element firstWhere(bool test(Element value), {Element orElse()}) {
+    return _filtered.firstWhere(test, orElse: orElse);
   }
 
-  Element lastMatching(bool test(Element value), {Element orElse()}) {
-    return _filtered.lastMatching(test, orElse: orElse);
+  Element lastWhere(bool test(Element value), {Element orElse()}) {
+    return _filtered.lastWhere(test, orElse: orElse);
   }
 
-  Element singleMatching(bool test(Element value)) {
-    return _filtered.singleMatching(test);
+  Element singleWhere(bool test(Element value)) {
+    return _filtered.singleWhere(test);
   }
 
   Element elementAt(int index) {
@@ -170,8 +174,10 @@
   int get length => _filtered.length;
   Element operator [](int index) => _filtered[index];
   Iterator<Element> get iterator => _filtered.iterator;
+  List<Element> sublist(int start, [int end]) =>
+    _filtered.sublist(start, end);
   List<Element> getRange(int start, int rangeLength) =>
-    _filtered.getRange(start, rangeLength);
+    sublist(start, start + rangeLength);
   int indexOf(Element element, [int start = 0]) =>
     _filtered.indexOf(element, start);
 
diff --git a/sdk/lib/html/html_common/html_common.dart b/sdk/lib/html/html_common/html_common.dart
index 94ddf18..f023b30 100644
--- a/sdk/lib/html/html_common/html_common.dart
+++ b/sdk/lib/html/html_common/html_common.dart
@@ -10,6 +10,7 @@
 import 'metadata.dart';
 export 'metadata.dart';
 
+part 'device.dart';
 part 'filtered_element_list.dart';
 part 'lists.dart';
 
diff --git a/sdk/lib/html/html_common/html_common_dart2js.dart b/sdk/lib/html/html_common/html_common_dart2js.dart
index 7392945..a27b3a0 100644
--- a/sdk/lib/html/html_common/html_common_dart2js.dart
+++ b/sdk/lib/html/html_common/html_common_dart2js.dart
@@ -13,6 +13,7 @@
 export 'metadata.dart';
 
 part 'conversions.dart';
+part 'device.dart';
 part 'filtered_element_list.dart';
 part 'lists.dart';
 
diff --git a/sdk/lib/html/html_common/lists.dart b/sdk/lib/html/html_common/lists.dart
index 03cc29e..b565aba 100644
--- a/sdk/lib/html/html_common/lists.dart
+++ b/sdk/lib/html/html_common/lists.dart
@@ -51,37 +51,18 @@
 
   /**
    * Returns a sub list copy of this list, from [start] to
-   * [:start + length:].
+   * [end] ([end] not inclusive).
    * Returns an empty list if [length] is 0.
-   * Throws an [ArgumentError] if [length] is negative.
-   * Throws a [RangeError] if [start] or [:start + length:] are out of range.
+   * It is an error if indices are not valid for the list, or
+   * if [end] is before [start].
    */
-  static List getRange(List a, int start, int length, List accumulator) {
-    if (length < 0) throw new ArgumentError('length');
+  static List getRange(List a, int start, int end, List accumulator) {
     if (start < 0) throw new RangeError.value(start);
-    int end = start + length;
+    if (end < start) throw new RangeError.value(end);
     if (end > a.length) throw new RangeError.value(end);
     for (int i = start; i < end; i++) {
       accumulator.add(a[i]);
     }
     return accumulator;
   }
-
-  static String join(List<Object> list, [String separator]) {
-    if (list.isEmpty) return "";
-    if (list.length == 1) return "${list[0]}";
-    StringBuffer buffer = new StringBuffer();
-    if (separator == null || separator == "") {
-      for (int i = 0; i < list.length; i++) {
-        buffer.add("${list[i]}");
-      }
-    } else {
-      buffer.add("${list[0]}");
-      for (int i = 1; i < list.length; i++) {
-        buffer.add(separator);
-        buffer.add("${list[i]}");
-      }
-    }
-    return buffer.toString();
-  }
 }
diff --git a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
index 9c3b377..9ecf7cb 100644
--- a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
+++ b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
@@ -1005,7 +1005,7 @@
 
     request.onError.listen((e) {
       //TODO: Report stacktrace once issue 4061 is resolved.
-      controller.signalError(e);
+      controller.addError(e);
     });
 
     request.onSuccess.listen((e) {
@@ -1014,7 +1014,7 @@
         controller.close();
       } else {
         controller.add(cursor);
-        if (autoAdvance == true) {
+        if (autoAdvance == true && controller.hasSubscribers) {
           cursor.next();
         }
       }
diff --git a/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart b/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
index c0d888c..3e843ac 100644
--- a/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
+++ b/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
@@ -1064,7 +1064,7 @@
 
     request.onError.listen((e) {
       //TODO: Report stacktrace once issue 4061 is resolved.
-      controller.signalError(e);
+      controller.addError(e);
     });
 
     request.onSuccess.listen((e) {
@@ -1073,7 +1073,7 @@
         controller.close();
       } else {
         controller.add(cursor);
-        if (autoAdvance == true) {
+        if (autoAdvance == true && controller.hasSubscribers) {
           cursor.next();
         }
       }
diff --git a/sdk/lib/io/base64.dart b/sdk/lib/io/base64.dart
index 12c1e5f8..1469c8d 100644
--- a/sdk/lib/io/base64.dart
+++ b/sdk/lib/io/base64.dart
@@ -51,9 +51,9 @@
     StringBuffer output = new StringBuffer();
     for (i = 0; i < characters.length; i++) {
       if (i > 0 && i % 76 == 0) {
-        output.add("\r\n");
+        output.write("\r\n");
       }
-      output.add(characters[i]);
+      output.write(characters[i]);
     }
     return output.toString();
   }
diff --git a/sdk/lib/io/buffer_list.dart b/sdk/lib/io/buffer_list.dart
index 4f0a3f7..0b3716c 100644
--- a/sdk/lib/io/buffer_list.dart
+++ b/sdk/lib/io/buffer_list.dart
@@ -25,6 +25,11 @@
     if (offset != 0) _index = offset;
   }
 
+  /** Alias for [add]. */
+  void write(List<int> buffer, [int offset = 0]) {
+    add(buffer, offset);
+  }
+
   /**
    * Returns the first buffer from the list. This returns the whole
    * buffer and does not remove the buffer from the list. Use
@@ -61,7 +66,8 @@
    * Read [count] bytes from the buffer list. If the number of bytes
    * requested is not available null will be returned.
    */
-  List<int> readBytes(int count) {
+  List<int> readBytes([int count]) {
+    if (count == null) count = length;
     List<int> result;
     if (_length == 0 || _length < count) return null;
     if (_index == 0 && _buffers.first.length == count) {
@@ -73,7 +79,7 @@
     } else {
       int firstRemaining = _buffers.first.length - _index;
       if (firstRemaining >= count) {
-        result = _buffers.first.getRange(_index, count);
+        result = _buffers.first.sublist(_index, _index + count);
         _index += count;
         _length -= count;
         if (_index == _buffers.first.length) {
diff --git a/sdk/lib/io/common.dart b/sdk/lib/io/common.dart
index 3f8c550..d74105b 100644
--- a/sdk/lib/io/common.dart
+++ b/sdk/lib/io/common.dart
@@ -18,7 +18,7 @@
   * An [OSError] object holds information about an error from the
   * operating system.
   */
-class OSError {
+class OSError implements Error {
   /** Constant used to indicate that no OS error code is available. */
   static const int noErrorCode = -1;
 
@@ -28,17 +28,17 @@
   /** Converts an OSError object to a string representation. */
   String toString() {
     StringBuffer sb = new StringBuffer();
-    sb.add("OS Error");
+    sb.write("OS Error");
     if (!message.isEmpty) {
-      sb.add(": ");
-      sb.add(message);
+      sb.write(": ");
+      sb.write(message);
       if (errorCode != noErrorCode) {
-        sb.add(", errno = ");
-        sb.add(errorCode.toString());
+        sb.write(", errno = ");
+        sb.write(errorCode.toString());
       }
     } else if (errorCode != noErrorCode) {
-      sb.add(": errno = ");
-      sb.add(errorCode.toString());
+      sb.write(": errno = ");
+      sb.write(errorCode.toString());
     }
     return sb.toString();
   }
diff --git a/sdk/lib/io/data_transformer.dart b/sdk/lib/io/data_transformer.dart
new file mode 100644
index 0000000..cb7d705
--- /dev/null
+++ b/sdk/lib/io/data_transformer.dart
@@ -0,0 +1,93 @@
+// 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.
+
+part of dart.io;
+
+/**
+ * Private helper-class to handle native filters.
+ */
+abstract class _Filter {
+  /**
+   * Call to process a chunk of data. A call to [process] should only be made
+   * when [processed] returns [null].
+   */
+  void process(List<int> data);
+
+  /**
+   * Get a chunk of processed data. When there are no more data available,
+   * [processed] will return [null]. Set [flush] to [false] for non-final
+   * calls to improve performance of some filters.
+   */
+  List<int> processed({bool flush: true});
+
+  /**
+   * Mark the filter as closed. Always call this method for any filter created
+   * to avoid leaking resources. [end] can be called at any time, but any
+   * successive calls to [process] or [processed] will fail.
+   */
+  void end();
+
+  external static _Filter newZLibDeflateFilter(bool gzip, int level);
+  external static _Filter newZLibInflateFilter();
+}
+
+
+class _FilterTransformer extends StreamEventTransformer<List<int>, List<int>> {
+  final _Filter _filter;
+  bool _closed = false;
+  bool _empty = true;
+
+  _FilterTransformer(_Filter this._filter);
+
+  void handleData(List<int> data, EventSink<List<int>> sink) {
+    if (_closed) return;
+    try {
+      _empty = false;
+      _filter.process(data);
+      var out;
+      while ((out = _filter.processed(flush: false)) != null) {
+        sink.add(out);
+      }
+    } catch (e, s) {
+      _closed = true;
+      sink.addError(new AsyncError(e, s));
+      sink.close();
+    }
+  }
+
+  void handleDone(EventSink<List<int>> sink) {
+    if (_closed) return;
+    if (_empty) _filter.process(const []);
+    try {
+      var out;
+      while ((out = _filter.processed()) != null) {
+        sink.add(out);
+      }
+    } catch (e, s) {
+      sink.addError(new AsyncError(e, s));
+      _closed = true;
+    }
+    if (!_closed) _filter.end();
+    _closed = true;
+    sink.close();
+  }
+}
+
+
+/**
+ * ZLibDeflater class used to deflate a stream of bytes, using zlib.
+ */
+class ZLibDeflater extends _FilterTransformer {
+  ZLibDeflater({bool gzip: true, int level: 6})
+      : super(_Filter.newZLibDeflateFilter(gzip, level));
+}
+
+
+/**
+ * ZLibInflater class used to inflate a stream of bytes, using zlib.
+ */
+class ZLibInflater extends _FilterTransformer {
+  ZLibInflater() : super(_Filter.newZLibInflateFilter());
+}
+
diff --git a/sdk/lib/io/directory.dart b/sdk/lib/io/directory.dart
index fd70674..cf9ae48 100644
--- a/sdk/lib/io/directory.dart
+++ b/sdk/lib/io/directory.dart
@@ -166,19 +166,19 @@
                               OSError this.osError = null]);
   String toString() {
     StringBuffer sb = new StringBuffer();
-    sb.add("DirectoryIOException");
+    sb.write("DirectoryIOException");
     if (!message.isEmpty) {
-      sb.add(": $message");
+      sb.write(": $message");
       if (path != null) {
-        sb.add(", path = $path");
+        sb.write(", path = $path");
       }
       if (osError != null) {
-        sb.add(" ($osError)");
+        sb.write(" ($osError)");
       }
     } else if (osError != null) {
-      sb.add(": $osError");
+      sb.write(": $osError");
       if (path != null) {
-        sb.add(", path = $path");
+        sb.write(", path = $path");
       }
     }
     return sb.toString();
diff --git a/sdk/lib/io/directory_impl.dart b/sdk/lib/io/directory_impl.dart
index 2b519e7..a129cc7 100644
--- a/sdk/lib/io/directory_impl.dart
+++ b/sdk/lib/io/directory_impl.dart
@@ -247,7 +247,7 @@
     responsePort.receive((message, replyTo) {
       if (message is !List || message[RESPONSE_TYPE] is !int) {
         responsePort.close();
-        controller.signalError(new DirectoryIOException("Internal error"));
+        controller.addError(new DirectoryIOException("Internal error"));
         return;
       }
       switch (message[RESPONSE_TYPE]) {
@@ -261,7 +261,7 @@
           var errorType =
               message[RESPONSE_ERROR][_ERROR_RESPONSE_ERROR_TYPE];
           if (errorType == _ILLEGAL_ARGUMENT_RESPONSE) {
-            controller.signalError(new ArgumentError());
+            controller.addError(new ArgumentError());
           } else if (errorType == _OSERROR_RESPONSE) {
             var responseError = message[RESPONSE_ERROR];
             var err = new OSError(
@@ -269,12 +269,12 @@
                 responseError[_OSERROR_RESPONSE_ERROR_CODE]);
             var errorPath = message[RESPONSE_PATH];
             if (errorPath == null) errorPath = path;
-            controller.signalError(
+            controller.addError(
                 new DirectoryIOException("Directory listing failed",
                                          errorPath,
                                          err));
           } else {
-            controller.signalError(new DirectoryIOException("Internal error"));
+            controller.addError(new DirectoryIOException("Internal error"));
           }
           break;
         case LIST_DONE:
diff --git a/sdk/lib/io/file.dart b/sdk/lib/io/file.dart
index f42555e..d484cf3 100644
--- a/sdk/lib/io/file.dart
+++ b/sdk/lib/io/file.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -19,6 +19,11 @@
 /**
  * [File] objects are references to files.
  *
+ * If [path] is a symbolic link, rather than a file, then
+ * the methods of [File] operate on the ultimate target of the
+ * link, except for File.delete and File.deleteSync, which operate on
+ * the link.
+ *
  * To operate on the underlying file data there are two options:
  *
  *  * Use streaming: read the contents of the file from the [Stream]
@@ -174,8 +179,14 @@
    * * [FileMode.WRITE]: truncates the file to length zero.
    * * [FileMode.APPEND]: sets the initial write position to the end
    *   of the file.
+   *
+   *  When writing strings through the returned [IOSink] the encoding
+   *  specified using [encoding] will be used. The returned [IOSink]
+   *  has an [:encoding:] property which can be changed after the
+   *  [IOSink] has been created.
    */
-  IOSink<File> openWrite([FileMode mode = FileMode.WRITE]);
+  IOSink<File> openWrite({FileMode mode: FileMode.WRITE,
+                          Encoding encoding: Encoding.UTF_8});
 
   /**
    * Read the entire file contents as a list of bytes. Returns a
@@ -455,14 +466,14 @@
                          OSError this.osError = null]);
   String toString() {
     StringBuffer sb = new StringBuffer();
-    sb.add("FileIOException");
+    sb.write("FileIOException");
     if (!message.isEmpty) {
-      sb.add(": $message");
+      sb.write(": $message");
       if (osError != null) {
-        sb.add(" ($osError)");
+        sb.write(" ($osError)");
       }
     } else if (osError != null) {
-      sb.add(": osError");
+      sb.write(": osError");
     }
     return sb.toString();
   }
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index 0ba765c..1d9aa40 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -94,7 +94,7 @@
       })
       .catchError((e) {
         if (!_unsubscribed) {
-          _controller.signalError(e);
+          _controller.addError(e);
           _closeFile().then((_) { _controller.close(); });
           _unsubscribed = true;
         }
@@ -114,7 +114,7 @@
         _readBlock();
       })
       .catchError((e) {
-        _controller.signalError(e);
+        _controller.addError(e);
         _controller.close();
       });
   }
@@ -299,6 +299,8 @@
 
   external static _create(String path);
 
+  external static _createLink(String path, String target);
+
   void createSync() {
     var result = _create(_path);
     throwIfError(result, "Cannot create file '$_path'");
@@ -468,14 +470,15 @@
     return new _FileStream(_path);
   }
 
-  IOSink<File> openWrite([FileMode mode = FileMode.WRITE]) {
+  IOSink<File> openWrite({FileMode mode: FileMode.WRITE,
+                          Encoding encoding: Encoding.UTF_8}) {
     if (mode != FileMode.WRITE &&
         mode != FileMode.APPEND) {
       throw new FileIOException(
           "Wrong FileMode. Use FileMode.WRITE or FileMode.APPEND");
     }
     var consumer = new _FileStreamConsumer(this, mode);
-    return new IOSink<File>(consumer);
+    return new IOSink<File>(consumer, encoding: encoding);
   }
 
   Future<List<int>> readAsBytes() {
@@ -547,23 +550,14 @@
 
   Future<File> writeAsBytes(List<int> bytes,
                             [FileMode mode = FileMode.WRITE]) {
-    Completer<File> completer = new Completer<File>();
     try {
-      var stream = openWrite(mode);
-      stream.add(bytes);
-      stream.close();
-      stream.done
-        .then((_) {
-          completer.complete(this);
-        })
-        .catchError((e) {
-          completer.completeError(e);
-        });
+      IOSink<File> sink = openWrite(mode: mode);
+      sink.writeBytes(bytes);
+      sink.close();
+      return sink.done.then((_) => this);;
     } catch (e) {
-      Timer.run(() => completer.completeError(e));
-      return completer.future;
+      return new Future.immediateError(e);
     }
-    return completer.future;
   }
 
   void writeAsBytesSync(List<int> bytes, [FileMode mode = FileMode.WRITE]) {
diff --git a/sdk/lib/io/file_system_entity.dart b/sdk/lib/io/file_system_entity.dart
index bbe8cd5..e13477b 100644
--- a/sdk/lib/io/file_system_entity.dart
+++ b/sdk/lib/io/file_system_entity.dart
@@ -4,6 +4,23 @@
 
 part of dart.io;
 
+class FileSystemEntityType {
+  static const FILE = const FileSystemEntityType._internal(0);
+  static const DIRECTORY = const FileSystemEntityType._internal(1);
+  static const LINK = const FileSystemEntityType._internal(2);
+  static const NOT_FOUND = const FileSystemEntityType._internal(3);
+  static const _typeList = const [FileSystemEntityType.FILE,
+                                  FileSystemEntityType.DIRECTORY,
+                                  FileSystemEntityType.LINK,
+                                  FileSystemEntityType.NOT_FOUND];
+  const FileSystemEntityType._internal(int this._type);
+
+  static FileSystemEntityType _lookup(int type) => _typeList[type];
+  String toString() => const ['FILE', 'DIRECTORY', 'LINK', 'NOT_FOUND'][_type];
+
+  final int _type;
+}
+
 /**
  * A [FileSystemEntity] is a common super class for [File] and
  * [Directory] objects.
@@ -16,4 +33,30 @@
  */
 abstract class FileSystemEntity {
   String get path;
+
+  external static int _getType(String path, bool followLinks);
+
+  static int _getTypeSync(String path, bool followLinks) {
+    var result = _getType(path, followLinks);
+    _throwIfError(result, 'Error getting type of FileSystemEntity');
+    return result;
+  }
+
+  static FileSystemEntityType typeSync(String path, {bool followLinks: true})
+      => FileSystemEntityType._lookup(_getTypeSync(path, followLinks));
+
+  static bool isLinkSync(String path) =>
+      (_getTypeSync(path, false) == FileSystemEntityType.LINK._type);
+
+  static bool isFileSync(String path) =>
+      (_getTypeSync(path, true) == FileSystemEntityType.FILE._type);
+
+  static bool isDirectorySync(String path) =>
+      (_getTypeSync(path, true) == FileSystemEntityType.DIRECTORY._type);
+
+  static _throwIfError(Object result, String msg) {
+    if (result is OSError) {
+      throw new FileIOException(msg, result);
+    }
+  }
 }
diff --git a/sdk/lib/io/http.dart b/sdk/lib/io/http.dart
index feaeb0e..912a366 100644
--- a/sdk/lib/io/http.dart
+++ b/sdk/lib/io/http.dart
@@ -399,9 +399,7 @@
  * use code like this:
  *
  *     HttpClientRequest request = ...;
- *     var v = new HeaderValue();
- *     v.value = "text/plain";
- *     v.parameters["q"] = "0.3"
+ *     var v = new HeaderValue("text/plain", {"q": "0.3"});
  *     request.headers.add(HttpHeaders.ACCEPT, v);
  *     request.headers.add(HttpHeaders.ACCEPT, "text/html");
  *
@@ -413,12 +411,16 @@
  *       HeaderValue v = new HeaderValue.fromString(value);
  *       // Use v.value and v.parameters
  *     });
+ *
+ * An instance of [HeaderValue] is immutable.
  */
 abstract class HeaderValue {
   /**
    * Creates a new header value object setting the value part.
    */
-  factory HeaderValue([String value = ""]) => new _HeaderValue(value);
+  factory HeaderValue([String value = "", Map<String, String> parameters]) {
+    return new _HeaderValue(value, parameters);
+  }
 
   /**
    * Creates a new header value object from parsing a header value
@@ -431,9 +433,9 @@
   }
 
   /**
-   * Gets and sets the header value.
+   * Gets the header value.
    */
-  String value;
+  String get value;
 
   /**
    * Gets the map of parameters.
@@ -473,15 +475,22 @@
 
 
 /**
- * Representation of a content type.
+ * Representation of a content type. An instance of [ContentType] is
+ * immutable.
  */
 abstract class ContentType implements HeaderValue {
   /**
    * Creates a new content type object setting the primary type and
-   * sub type.
+   * sub type. The charset and additional parameters can also be set
+   * using [charset] and [parameters]. If charset is passed and
+   * [parameters] contains charset as well the passed [charset] will
+   * override the value in parameters. Keys and values passed in
+   * parameters will be converted to lower case.
    */
-  factory ContentType([String primaryType = "", String subType = ""]) {
-    return new _ContentType(primaryType, subType);
+  factory ContentType(String primaryType,
+                      String subType,
+                      {String charset, Map<String, String> parameters}) {
+    return new _ContentType(primaryType, subType, charset, parameters);
   }
 
   /**
@@ -500,24 +509,19 @@
   }
 
   /**
-   * Gets and sets the content type in the form "primaryType/subType".
+   * Gets the primary type.
    */
-  String value;
+  String get primaryType;
 
   /**
-   * Gets and sets the primary type.
+   * Gets the sub type.
    */
-  String primaryType;
+  String get subType;
 
   /**
-   * Gets and sets the sub type.
+   * Gets the character set.
    */
-  String subType;
-
-  /**
-   * Gets and sets the character set.
-   */
-  String charset;
+  String get charset;
 }
 
 
@@ -672,6 +676,32 @@
 
 /**
  * HTTP response to be send back to the client.
+ *
+ * This object has a number of properties for setting up the HTTP
+ * header of the response. When the header has been set up the methods
+ * from the [IOSink] can be used to write the actual body of the HTTP
+ * response. When one of the [IOSink] methods is used for the
+ * first time the request header is send. Calling any methods that
+ * will change the header after it is sent will throw an exception.
+ *
+ * When writing string data through the [IOSink] the encoding used
+ * will be determined from the "charset" parameter of the
+ * "Content-Type" header.
+ *
+ *   HttpResponse response = ...
+ *   response.headers.contentType
+ *       = new ContentType("application", "json", charset: "utf-8");
+ *   response.write(...);  // Strings written will be UTF-8 encoded.
+ *
+ * If no charset is provided the default of ISO-8859-1 (Latin 1) will
+ * be used.
+ *
+ *   HttpResponse response = ...
+ *   response.headers.add(HttpHeaders.CONTENT_TYPE, "text/plain");
+ *   response.write(...);  // Strings written will be ISO-8859-1 encoded.
+ *
+ * If an unsupported encoding is used an exception will be thrown if
+ * using one of the write methods taking a string.
  */
 abstract class HttpResponse implements IOSink<HttpResponse> {
   // TODO(ajohnsen): Add documentation of how to pipe a file to the response.
@@ -856,13 +886,31 @@
 /**
  * HTTP request for a client connection.
  *
- * The request is an [IOSink], used to write the request data. When
- * all request data has been written, close the stream to indicate the end of
- * the request.
+ * This object has a number of properties for setting up the HTTP
+ * header of the request. When the header has been set up the methods
+ * from the [IOSink] can be used to write the actual body of the HTTP
+ * request. When one of the [IOSink] methods is used for the first
+ * time the request header is send. Calling any methods that will
+ * change the header after it is sent will throw an exception.
  *
- * When this is accessed for the first time the request header is
- * send. Calling any methods that will change the header after
- * having retrieved the output stream will throw an exception.
+ * When writing string data through the [IOSink] the
+ * encoding used will be determined from the "charset" parameter of
+ * the "Content-Type" header.
+ *
+ *   HttpClientRequest request = ...
+ *   request.headers.contentType
+ *       = new ContentType("application", "json", charset: "utf-8");
+ *   request.write(...);  // Strings written will be UTF-8 encoded.
+ *
+ * If no charset is provided the default of ISO-8859-1 (Latin 1) will
+ * be used.
+ *
+ *   HttpClientRequest request = ...
+ *   request.headers.add(HttpHeaders.CONTENT_TYPE, "text/plain");
+ *   request.write(...);  // Strings written will be ISO-8859-1 encoded.
+ *
+ * If an unsupported encoding is used an exception will be thrown if
+ * using one of the write methods taking a string.
  */
 abstract class HttpClientRequest
     implements IOSink<HttpClientRequest> {
diff --git a/sdk/lib/io/http_headers.dart b/sdk/lib/io/http_headers.dart
index 9d586d4..261f1cd 100644
--- a/sdk/lib/io/http_headers.dart
+++ b/sdk/lib/io/http_headers.dart
@@ -198,7 +198,7 @@
     if (values != null) {
       return new ContentType.fromString(values[0]);
     } else {
-      return new ContentType();
+      return null;
     }
   }
 
@@ -277,7 +277,7 @@
     } else if (lowerCaseName == HttpHeaders.CONTENT_TYPE) {
       _set(HttpHeaders.CONTENT_TYPE, value);
     } else {
-        _addValue(lowerCaseName, value);
+      _addValue(lowerCaseName, value);
     }
   }
 
@@ -320,7 +320,7 @@
     return true;
   }
 
-  void _finalize() {
+  void _synchronize() {
     // If the content length is not known make sure chunked transfer
     // encoding is used for HTTP 1.1.
     if (contentLength < 0) {
@@ -337,80 +337,59 @@
         protocolVersion == "1.1") {
       contentLength = -1;
     }
+  }
+
+  void _finalize() {
+    _synchronize();
     _mutable = false;
   }
 
-  _write(IOSink sink) {
+  _write(_BufferList buffer) {
     final COLONSP = const [_CharCode.COLON, _CharCode.SP];
     final COMMASP = const [_CharCode.COMMA, _CharCode.SP];
     final CRLF = const [_CharCode.CR, _CharCode.LF];
 
-    var bufferSize = 16 * 1024;
-    var buffer = new Uint8List(bufferSize);
-    var bufferPos = 0;
-
-    void writeBuffer() {
-      sink.add(buffer.getRange(0, bufferPos));
-      bufferPos = 0;
-    }
-
     // Format headers.
     _headers.forEach((String name, List<String> values) {
       bool fold = _foldHeader(name);
-      List<int> nameData;
-      nameData = name.codeUnits;
-      int nameDataLen = nameData.length;
-      if (nameDataLen + 2 > bufferSize - bufferPos) writeBuffer();
-      buffer.setRange(bufferPos, nameDataLen, nameData);
-      bufferPos += nameDataLen;
-      buffer[bufferPos++] = _CharCode.COLON;
-      buffer[bufferPos++] = _CharCode.SP;
+      var nameData = name.codeUnits;
+      buffer.add(nameData);
+      buffer.add(const [_CharCode.COLON, _CharCode.SP]);
       for (int i = 0; i < values.length; i++) {
-        List<int> data = values[i].codeUnits;
-        int dataLen = data.length;
-        // Worst case here is writing the name, value and 6 additional bytes.
-        if (nameDataLen + dataLen + 6 > bufferSize - bufferPos) writeBuffer();
         if (i > 0) {
           if (fold) {
-            buffer[bufferPos++] = _CharCode.COMMA;
-            buffer[bufferPos++] = _CharCode.SP;
+            buffer.add(const [_CharCode.COMMA, _CharCode.SP]);
           } else {
-            buffer[bufferPos++] = _CharCode.CR;
-            buffer[bufferPos++] = _CharCode.LF;
-            buffer.setRange(bufferPos, nameDataLen, nameData);
-            bufferPos += nameDataLen;
-            buffer[bufferPos++] = _CharCode.COLON;
-            buffer[bufferPos++] = _CharCode.SP;
+            buffer.add(const [_CharCode.CR, _CharCode.LF]);
+            buffer.add(nameData);
+            buffer.add(const [_CharCode.COLON, _CharCode.SP]);
           }
         }
-        buffer.setRange(bufferPos, dataLen, data);
-        bufferPos += dataLen;
+        buffer.add(values[i].codeUnits);
       }
-      buffer[bufferPos++] = _CharCode.CR;
-      buffer[bufferPos++] = _CharCode.LF;
+      buffer.add(const [_CharCode.CR, _CharCode.LF]);
     });
-    writeBuffer();
   }
 
   String toString() {
     StringBuffer sb = new StringBuffer();
     _headers.forEach((String name, List<String> values) {
-      sb.add(name);
-      sb.add(": ");
+      sb.write(name);
+      sb.write(": ");
       bool fold = _foldHeader(name);
       for (int i = 0; i < values.length; i++) {
         if (i > 0) {
           if (fold) {
-            sb.add(", ");
+            sb.write(", ");
           } else {
-            sb.add("\n");
-            sb.add(name);
-            sb.add(": ");
+            sb.write("\n");
+            sb.write(name);
+            sb.write(": ");
           }
         }
-        sb.add(values[i]);
+        sb.write(values[i]);
       }
-      sb.add("\n");
+      sb.write("\n");
     });
     return sb.toString();
   }
@@ -493,13 +472,18 @@
 
 
 class _HeaderValue implements HeaderValue {
-  _HeaderValue([String this.value = ""]);
+  String _value;
+  Map<String, String> _parameters;
 
-  _HeaderValue.fromString(String value, {this.parameterSeparator: ";"}) {
+  _HeaderValue([String this._value = "", this._parameters]);
+
+  _HeaderValue.fromString(String value, {parameterSeparator: ";"}) {
     // Parse the string.
-    _parse(value);
+    _parse(value, parameterSeparator);
   }
 
+  String get value => _value;
+
   Map<String, String> get parameters {
     if (_parameters == null) _parameters = new Map<String, String>();
     return _parameters;
@@ -507,19 +491,19 @@
 
   String toString() {
     StringBuffer sb = new StringBuffer();
-    sb.add(value);
+    sb.write(_value);
     if (parameters != null && parameters.length > 0) {
       _parameters.forEach((String name, String value) {
-        sb.add("; ");
-        sb.add(name);
-        sb.add("=");
-        sb.add(value);
+        sb.write("; ");
+        sb.write(name);
+        sb.write("=");
+        sb.write(value);
       });
     }
     return sb.toString();
   }
 
-  void _parse(String s) {
+  void _parse(String s, String parameterSeparator) {
     int index = 0;
 
     bool done() => index == s.length;
@@ -580,7 +564,7 @@
               index++;
               break;
             }
-            sb.add(s[index]);
+            sb.write(s[index]);
             index++;
           }
           return sb.toString();
@@ -606,58 +590,53 @@
     }
 
     skipWS();
-    value = parseValue();
+    _value = parseValue();
     skipWS();
     if (done()) return;
     maybeExpect(parameterSeparator);
     parseParameters();
   }
-
-  String value;
-  String parameterSeparator;
-  Map<String, String> _parameters;
 }
 
 
 class _ContentType extends _HeaderValue implements ContentType {
-  _ContentType(String primaryType, String subType)
-      : _primaryType = primaryType, _subType = subType, super("");
+  String _primaryType = "";
+  String _subType = "";
 
-  _ContentType.fromString(String value) : super.fromString(value);
+  _ContentType(String primaryType,
+               String subType,
+               String charset,
+               Map<String, String> parameters)
+      : _primaryType = primaryType, _subType = subType, super("") {
+    if (_primaryType == null) _primaryType = "";
+    if (_subType == null) _subType = "";
+    _value = "$_primaryType/$_subType";;
+    if (parameters != null) {
+      parameters.forEach((String key, String value) {
+        this.parameters[key.toLowerCase()] = value.toLowerCase();
+      });
+    }
+    if (charset != null) {
+      this.parameters["charset"] = charset.toLowerCase();
+    }
+  }
 
-  String get value => "$_primaryType/$_subType";
-
-  void set value(String s) {
-    int index = s.indexOf("/");
-    if (index == -1 || index == (s.length - 1)) {
-      primaryType = s.trim().toLowerCase();
-      subType = "";
+  _ContentType.fromString(String value) : super.fromString(value) {
+    int index = _value.indexOf("/");
+    if (index == -1 || index == (_value.length - 1)) {
+      _primaryType = _value.trim().toLowerCase();
+      _subType = "";
     } else {
-      primaryType = s.substring(0, index).trim().toLowerCase();
-      subType = s.substring(index + 1).trim().toLowerCase();
+      _primaryType = _value.substring(0, index).trim().toLowerCase();
+      _subType = _value.substring(index + 1).trim().toLowerCase();
     }
   }
 
   String get primaryType => _primaryType;
 
-  void set primaryType(String s) {
-    _primaryType = s;
-  }
-
   String get subType => _subType;
 
-  void set subType(String s) {
-    _subType = s;
-  }
-
   String get charset => parameters["charset"];
-
-  void set charset(String s) {
-    parameters["charset"] = s;
-  }
-
-  String _primaryType = "";
-  String _subType = "";
 }
 
 
@@ -757,27 +736,27 @@
 
   String toString() {
     StringBuffer sb = new StringBuffer();
-    sb.add(name);
-    sb.add("=");
-    sb.add(value);
+    sb.write(name);
+    sb.write("=");
+    sb.write(value);
     if (expires != null) {
-      sb.add("; Expires=");
-      sb.add(_HttpUtils.formatDate(expires));
+      sb.write("; Expires=");
+      sb.write(_HttpUtils.formatDate(expires));
     }
     if (maxAge != null) {
-      sb.add("; Max-Age=");
-      sb.add(maxAge);
+      sb.write("; Max-Age=");
+      sb.write(maxAge);
     }
     if (domain != null) {
-      sb.add("; Domain=");
-      sb.add(domain);
+      sb.write("; Domain=");
+      sb.write(domain);
     }
     if (path != null) {
-      sb.add("; Path=");
-      sb.add(path);
+      sb.write("; Path=");
+      sb.write(path);
     }
-    if (secure) sb.add("; Secure");
-    if (httpOnly) sb.add("; HttpOnly");
+    if (secure) sb.write("; Secure");
+    if (httpOnly) sb.write("; HttpOnly");
     return sb.toString();
   }
 
diff --git a/sdk/lib/io/http_impl.dart b/sdk/lib/io/http_impl.dart
index 31099cc..1f79457 100644
--- a/sdk/lib/io/http_impl.dart
+++ b/sdk/lib/io/http_impl.dart
@@ -92,15 +92,14 @@
 
     if (_httpServer._sessionManagerInstance != null) {
       // Map to session if exists.
-      var sessionId = cookies.reduce(null, (last, cookie) {
-        if (last != null) return last;
-        return cookie.name.toUpperCase() == _DART_SESSION_ID ?
-            cookie.value : null;
-      });
-      if (sessionId != null) {
+      var sessionIds = cookies
+          .where((cookie) => cookie.name.toUpperCase() == _DART_SESSION_ID)
+          .map((cookie) => cookie.value);
+      for (var sessionId in sessionIds) {
         _session = _httpServer._sessionManager.getSession(sessionId);
         if (_session != null) {
           _session._markSeen();
+          break;
         }
       }
     }
@@ -323,16 +322,15 @@
   // requests and in error handling.
   bool _ignoreBody = false;
   bool _headersWritten = false;
-  bool _chunked = false;
 
-  final IOSink _ioSink;
+  IOSink _ioSink;
   final _HttpOutgoing _outgoing;
 
   final _HttpHeaders headers;
 
   _HttpOutboundMessage(String protocolVersion, _HttpOutgoing outgoing)
       : _outgoing = outgoing,
-        _ioSink = new IOSink(outgoing),
+        _ioSink = new IOSink(outgoing, encoding: Encoding.ASCII),
         headers = new _HttpHeaders(protocolVersion);
 
   int get contentLength => headers.contentLength;
@@ -345,78 +343,179 @@
     headers.persistentConnection = p;
   }
 
+  Encoding get encoding {
+    var charset;
+    if (headers.contentType != null && headers.contentType.charset != null) {
+      charset = headers.contentType.charset;
+    } else {
+      charset = "iso-8859-1";
+    }
+    return Encoding.fromName(charset);
+  }
+
+  void set encoding(Encoding value) {
+    throw new StateError("IOSink encoding is not mutable");
+  }
+
+  void write(Object obj) {
+    _writeHeaders();
+    // This comment is copied from runtime/lib/string_buffer_patch.dart.
+    // TODO(srdjan): The following four lines could be replaced by
+    // '$obj', but apparently this is too slow on the Dart VM.
+    String string;
+    if (obj is String) {
+      string = obj;
+    } else {
+      string = obj.toString();
+      if (string is! String) {
+        throw new ArgumentError('toString() did not return a string');
+      }
+    }
+    if (string.isEmpty) return;
+    _ioSink.write(string);
+  }
+
+  void writeAll(Iterable objects) {
+    for (Object obj in objects) write(obj);
+  }
+
+  void writeln([Object obj = ""]) {
+    write(obj);
+    write("\n");
+  }
+
+  void writeCharCode(int charCode) {
+    write(new String.fromCharCode(charCode));
+  }
+
+  void writeBytes(List<int> data) {
+    _writeHeaders();
+    if (data.length == 0) return;
+    _ioSink.writeBytes(data);
+  }
+
   Future<T> consume(Stream<List<int>> stream) {
     _writeHeaders();
-    if (_ignoreBody) return new Future.immediate(this);
-    if (_chunked) {
-      // Transform when chunked.
-      stream = stream.transform(new _ChunkedTransformer());
-    }
-    return _ioSink.consume(stream).then((_) => this);
+    return _ioSink.consume(stream);
   }
 
-  void add(List<int> data) {
+  Future<T> writeStream(Stream<List<int>> stream) {
     _writeHeaders();
-    if (_ignoreBody || data.length == 0) return;
-    if (_chunked) {
-      _ChunkedTransformer._addChunk(data, _ioSink.add);
-    } else {
-      _ioSink.add(data);
-    }
-  }
-
-  void addString(String string, [Encoding encoding = Encoding.UTF_8]) {
-    add(_encodeString(string, encoding));
-  }
-
-  Future<T> addStream(Stream<List<int>> stream) {
-    _writeHeaders();
-    if (_ignoreBody) return new Future.immediate(this);
-    if (_chunked) {
-      // Transform when chunked.
-      stream = stream.transform(new _ChunkedTransformer(writeEnd: false));
-    }
-    return _ioSink.addStream(stream).then((_) => this);
+    return _ioSink.writeStream(stream).then((_) => this);
   }
 
   void close() {
-    if (!_headersWritten && !_ignoreBody && headers.chunkedTransferEncoding) {
+    // TODO(ajohnsen): Currently, contentLength, chunkedTransferEncoding and
+    // persistentConnection is not guaranteed to be in sync.
+    if (!_headersWritten && !_ignoreBody && headers.contentLength == -1) {
       // If no body was written, _ignoreBody is false (it's not a HEAD
       // request) and the content-length is unspecified, set contentLength to 0.
+      headers.chunkedTransferEncoding = false;
       headers.contentLength = 0;
     }
     _writeHeaders();
-    if (!_ignoreBody) {
-      if (_chunked) {
-        _ChunkedTransformer._addChunk([], _ioSink.add);
-      }
-    }
     _ioSink.close();
   }
 
-  Future<T> get done => _ioSink.done.then((_) => this);
+  Future<T> get done {
+    _writeHeaders();
+    return _ioSink.done;
+  }
 
   void _writeHeaders() {
     if (_headersWritten) return;
-    bool _tmpIgnoreBody = _ignoreBody;
-    _ignoreBody = false;
     _headersWritten = true;
+    _ioSink.encoding = Encoding.ASCII;
+    headers._synchronize();  // Be sure the 'chunked' option is updated.
+    bool asGZip = false;
+    bool isServerSide = this is _HttpResponse;
+    if (isServerSide && headers.chunkedTransferEncoding) {
+      var response = this;
+      List acceptEncodings =
+          response._httpRequest.headers[HttpHeaders.ACCEPT_ENCODING];
+      List contentEncoding = headers[HttpHeaders.CONTENT_ENCODING];
+      if (acceptEncodings != null &&
+          acceptEncodings
+              .expand((list) => list.split(","))
+              .any((encoding) => encoding.trim().toLowerCase() == "gzip") &&
+          contentEncoding == null) {
+        headers.set(HttpHeaders.CONTENT_ENCODING, "gzip");
+        asGZip = true;
+      }
+    }
     _writeHeader();
-    _ignoreBody = _tmpIgnoreBody;
+    _ioSink = new IOSink(new _HttpOutboundConsumer(_ioSink, _consume, asGZip));
+    _ioSink.encoding = encoding;
+  }
+
+  Future _consume(IOSink ioSink, Stream<List<int>> stream, bool asGZip) {
+    int contentLength = headers.contentLength;
     if (_ignoreBody) {
-      _ioSink.close();
-      return;
+      ioSink.close();
+      return stream.reduce(null, (x, y) {}).then((_) => this);
     }
-    _chunked = headers.chunkedTransferEncoding;
-    if (headers.contentLength >= 0) {
-      _outgoing.setTransferLength(headers.contentLength);
+    stream = stream.transform(new _BufferTransformer());
+    if (headers.chunkedTransferEncoding) {
+      if (asGZip) {
+        stream = stream.transform(new ZLibDeflater(gzip: true, level: 6));
+      }
+      stream = stream.transform(new _ChunkedTransformer());
+    } else if (contentLength >= 0) {
+      stream = stream.transform(new _ContentLengthValidator(contentLength));
     }
+    return stream.pipe(ioSink).then((_) => this);
   }
 
   void _writeHeader();  // TODO(ajohnsen): Better name.
 }
 
 
+class _HttpOutboundConsumer implements StreamConsumer {
+  Function _consume;
+  IOSink _ioSink;
+  bool _asGZip;
+  _HttpOutboundConsumer(IOSink this._ioSink,
+                        Function this._consume,
+                        bool this._asGZip);
+
+  Future consume(var stream) => _consume(_ioSink, stream, _asGZip);
+}
+
+
+class _BufferTransformer extends StreamEventTransformer<List<int>, List<int>> {
+  const int MIN_CHUNK_SIZE = 4 * 1024;
+  const int MAX_BUFFER_SIZE = 16 * 1024;
+
+  final _BufferList _buffer = new _BufferList();
+
+  void handleData(List<int> data, EventSink<List<int>> sink) {
+    // TODO(ajohnsen): Use timeout?
+    if (data.length == 0) return;
+    if (data.length >= MIN_CHUNK_SIZE) {
+      flush(sink);
+      sink.add(data);
+    } else {
+      _buffer.add(data);
+      if (_buffer.length >= MAX_BUFFER_SIZE) {
+        flush(sink);
+      }
+    }
+  }
+
+  void handleDone(EventSink<List<int>> sink) {
+    flush(sink);
+    sink.close();
+  }
+
+  void flush(EventSink<List<int>> sink) {
+    if (_buffer.length > 0) {
+      sink.add(_buffer.readBytes());
+      _buffer.clear();
+    }
+  }
+}
+
+
 class _HttpResponse extends _HttpOutboundMessage<HttpResponse>
     implements HttpResponse {
   int statusCode = 200;
@@ -445,25 +544,30 @@
     var future = _httpRequest._httpConnection.detachSocket();
     // Close connection so the socket is 'free'.
     close();
+    done.catchError((_) {
+      // Catch any error on done, as they automatically will be propegated to
+      // the websocket.
+    });
     return future;
   }
 
   HttpConnectionInfo get connectionInfo => _httpRequest.connectionInfo;
 
   void _writeHeader() {
-    writeSP() => add([_CharCode.SP]);
-    writeCRLF() => add([_CharCode.CR, _CharCode.LF]);
+    var buffer = new _BufferList();
+    writeSP() => buffer.add(const [_CharCode.SP]);
+    writeCRLF() => buffer.add(const [_CharCode.CR, _CharCode.LF]);
 
     // Write status line.
     if (headers.protocolVersion == "1.1") {
-      add(_Const.HTTP11);
+      buffer.add(_Const.HTTP11);
     } else {
-      add(_Const.HTTP10);
+      buffer.add(_Const.HTTP10);
     }
     writeSP();
-    addString(statusCode.toString());
+    buffer.add(statusCode.toString().codeUnits);
     writeSP();
-    addString(reasonPhrase);
+    buffer.add(reasonPhrase.codeUnits);
     writeCRLF();
 
     var session = _httpRequest._session;
@@ -476,12 +580,15 @@
         if (cookies[i].name.toUpperCase() == _DART_SESSION_ID) {
           cookies[i].value = session.id;
           cookies[i].httpOnly = true;
+          cookies[i].path = "/";
           found = true;
-          break;
         }
       }
       if (!found) {
-        cookies.add(new Cookie(_DART_SESSION_ID, session.id)..httpOnly = true);
+        var cookie = new Cookie(_DART_SESSION_ID, session.id);
+        cookie.httpOnly = true;
+        cookie.path = "/";
+        cookies.add(cookie);
       }
     }
     // Add all the cookies set to the headers.
@@ -494,8 +601,9 @@
     headers._finalize();
 
     // Write headers.
-    headers._write(this);
+    headers._write(buffer);
     writeCRLF();
+    _ioSink.writeBytes(buffer.readBytes());
   }
 
   String _findReasonPhrase(int statusCode) {
@@ -644,10 +752,11 @@
   }
 
   void _writeHeader() {
-    writeSP() => add([_CharCode.SP]);
-    writeCRLF() => add([_CharCode.CR, _CharCode.LF]);
+    var buffer = new _BufferList();
+    writeSP() => buffer.add(const [_CharCode.SP]);
+    writeCRLF() => buffer.add(const [_CharCode.CR, _CharCode.LF]);
 
-    addString(method);
+    buffer.add(method.codeUnits);
     writeSP();
     // Send the path for direct connections and the whole URL for
     // proxy connections.
@@ -661,22 +770,22 @@
           path = "${path}?${uri.query}";
         }
       }
-      addString(path);
+      buffer.add(path.codeUnits);
     } else {
-      addString(uri.toString());
+      buffer.add(uri.toString().codeUnits);
     }
     writeSP();
-    add(_Const.HTTP11);
+    buffer.add(_Const.HTTP11);
     writeCRLF();
 
     // Add the cookies to the headers.
     if (!cookies.isEmpty) {
       StringBuffer sb = new StringBuffer();
       for (int i = 0; i < cookies.length; i++) {
-        if (i > 0) sb.add("; ");
-        sb.add(cookies[i].name);
-        sb.add("=");
-        sb.add(cookies[i].value);
+        if (i > 0) sb.write("; ");
+        sb.write(cookies[i].name);
+        sb.write("=");
+        sb.write(cookies[i].value);
       }
       headers.add(HttpHeaders.COOKIE, sb.toString());
     }
@@ -684,34 +793,26 @@
     headers._finalize();
 
     // Write headers.
-    headers._write(this);
+    headers._write(buffer);
     writeCRLF();
+    _ioSink.writeBytes(buffer.readBytes());
   }
 }
 
 
 // Transformer that transforms data to HTTP Chunked Encoding.
 class _ChunkedTransformer extends StreamEventTransformer<List<int>, List<int>> {
-  final bool writeEnd;
-  _ChunkedTransformer({this.writeEnd: true});
-
-  void handleData(List<int> data, StreamSink<List<int>> sink) {
-    _addChunk(data, sink.add);
+  void handleData(List<int> data, EventSink<List<int>> sink) {
+    sink.add(_chunkHeader(data.length));
+    if (data.length > 0) sink.add(data);
+    sink.add(_chunkFooter);
   }
 
-  void handleDone(StreamSink<List<int>> sink) {
-    if (writeEnd) {
-      _addChunk([], sink.add);
-    }
+  void handleDone(EventSink<List<int>> sink) {
+    handleData(const [], sink);
     sink.close();
   }
 
-  static void _addChunk(List<int> data, void add(List<int> data)) {
-    add(_chunkHeader(data.length));
-    if (data.length > 0) add(data);
-    add(_chunkFooter);
-  }
-
   static List<int> _chunkHeader(int length) {
     const hexDigits = const [0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
                              0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46];
@@ -734,76 +835,42 @@
 }
 
 
-// Transformer that invokes [_onDone] when completed.
-class _DoneTransformer implements StreamTransformer<List<int>, List<int>> {
-  final StreamController<List<int>> _controller
-      = new StreamController<List<int>>();
-  final Function _onDone;
-
-  _DoneTransformer(this._onDone);
-
-  Stream<List<int>> bind(Stream<List<int>> stream) {
-    var subscription = stream.listen(
-        _controller.add,
-        onError: _controller.signalError,
-        onDone: () {
-          _onDone();
-          _controller.close();
-        });
-    return _controller.stream;
-  }
-}
-
-// Transformer that validates the data written.
-class _DataValidatorTransformer
-    implements StreamTransformer<List<int>, List<int>> {
-  final StreamController<List<int>> _controller =
-      new StreamController<List<int>>();
+// Transformer that validates the content length.
+class _ContentLengthValidator
+    extends StreamEventTransformer<List<int>, List<int>> {
+  final int expectedContentLength;
   int _bytesWritten = 0;
 
-  int expectedTransferLength;
+  _ContentLengthValidator(int this.expectedContentLength);
 
-  Stream<List<int>> bind(Stream<List<int>> stream) {
-    var subscription;
-    subscription = stream.listen(
-        (data) {
-          if (expectedTransferLength != null) {
-            _bytesWritten += data.length;
-            if (_bytesWritten > expectedTransferLength) {
-              subscription.cancel();
-              _controller.signalError(new HttpException(
-                  "Content size exceeds specified contentLength. "
-                  "$_bytesWritten bytes written while expected "
-                  "$expectedTransferLength."));
-              _controller.close();
-              return;
-            }
-          }
-          _controller.add(data);
-        },
-        onError: (error) {
-          _controller.signalError(error);
-          _controller.close();
-        },
-        onDone: () {
-          if (expectedTransferLength != null) {
-            if (_bytesWritten < expectedTransferLength) {
-              _controller.signalError(new HttpException(
-                  "Content size below specified contentLength. "
-                  " $_bytesWritten bytes written while expected "
-                  "$expectedTransferLength."));
-            }
-          }
-          _controller.close();
-        },
-        unsubscribeOnError: true);
-    return _controller.stream;
+  void handleData(List<int> data, EventSink<List<int>> sink) {
+    _bytesWritten += data.length;
+    if (_bytesWritten > expectedContentLength) {
+      sink.addError(new AsyncError(new HttpException(
+          "Content size exceeds specified contentLength. "
+          "$_bytesWritten bytes written while expected "
+          "$expectedContentLength. "
+          "[${new String.fromCharCodes(data)}]")));
+      sink.close();
+    } else {
+      sink.add(data);
+    }
+  }
+
+  void handleDone(EventSink<List<int>> sink) {
+    if (_bytesWritten < expectedContentLength) {
+      sink.addError(new AsyncError(new HttpException(
+          "Content size below specified contentLength. "
+          " $_bytesWritten bytes written while expected "
+          "$expectedContentLength.")));
+    }
+    sink.close();
   }
 }
 
+
 // Extends StreamConsumer as this is an internal type, only used to pipe to.
 class _HttpOutgoing implements StreamConsumer<List<int>, dynamic> {
-  final _DataValidatorTransformer _validator = new _DataValidatorTransformer();
   Function _onStream;
   final Completer _consumeCompleter = new Completer();
 
@@ -812,12 +879,8 @@
     return _consumeCompleter.future;
   }
 
-  void setTransferLength(int transferLength) {
-    _validator.expectedTransferLength = transferLength;
-  }
-
   Future consume(Stream<List<int>> stream) {
-    _onStream(stream.transform(_validator))
+    _onStream(stream)
         .then((_) => _consumeCompleter.complete(),
               onError: _consumeCompleter.completeError);
     // Use .then to ensure a Future branch.
@@ -900,7 +963,7 @@
         // Sending request, set up response completer.
         _nextResponseCompleter = new Completer();
 
-        var requestFuture = _socket.addStream(stream)
+        var requestFuture = _socket.writeStream(stream)
             .catchError((e) {
               destroy();
               throw e;
@@ -1163,6 +1226,7 @@
                                          sendClientCertificate: true)
                   : Socket.connect(host, port))
         .then((socket) {
+          socket.setOption(SocketOption.TCP_NODELAY, true);
           var connection = new _HttpClientConnection(key, socket, this);
           _activeConnections.add(connection);
           return new _ConnnectionInfo(connection, proxy);
@@ -1227,7 +1291,7 @@
                                            outgoing);
           var request = new _HttpRequest(response, incoming, _httpServer, this);
           outgoing.onStream((stream) {
-            return _streamFuture = _socket.addStream(stream)
+            return _streamFuture = _socket.writeStream(stream)
                 .then((_) {
                   if (_state == _DETACHED) return;
                   if (response.persistentConnection &&
@@ -1325,11 +1389,12 @@
                                          bool unsubscribeOnError}) {
     _serverSocket.listen(
         (Socket socket) {
+          socket.setOption(SocketOption.TCP_NODELAY, true);
           // Accept the client connection.
           _HttpConnection connection = new _HttpConnection(socket, this);
           _connections.add(connection);
         },
-        onError: _controller.signalError,
+        onError: _controller.addError,
         onDone: _controller.close);
     return _controller.stream.listen(onData,
                                      onError: onError,
@@ -1366,7 +1431,7 @@
   }
 
   void _handleError(AsyncError error) {
-    if (!closed) _controller.signalError(error);
+    if (!closed) _controller.addError(error);
   }
 
   void _connectionClosed(_HttpConnection connection) {
@@ -1508,25 +1573,45 @@
                             unsubscribeOnError: unsubscribeOnError);
   }
 
+  Encoding get encoding => _socket.encoding;
+
+  void set encoding(Encoding value) {
+    _socket.encoding = value;
+  }
+
+  void write(Object obj) => _socket.write(obj);
+
+  void writeln([Object obj = ""]) => _socket.writeln(obj);
+
+  void writeCharCode(int charCode) => _socket.writeCharCode(charCode);
+
+  void writeAll(Iterable objects) => _socket.writeAll(objects);
+
+  void writeBytes(List<int> bytes) => _socket.writeBytes(bytes);
+
   Future<Socket> consume(Stream<List<int>> stream) {
     return _socket.consume(stream);
   }
 
-  Future<Socket> addStream(Stream<List<int>> stream) {
-    return _socket.addStream(stream);
-  }
-
-  void addString(String string, [Encoding encoding = Encoding.UTF_8]) {
-    return _socket.addString(string, encoding);
+  Future<Socket> writeStream(Stream<List<int>> stream) {
+    return _socket.writeStream(stream);
   }
 
   void destroy() => _socket.destroy();
-  void add(List<int> data) => _socket.add(data);
+
   void close() => _socket.close();
+
   Future<Socket> get done => _socket.done;
+
   int get port => _socket.port;
+
   String get remoteHost => _socket.remoteHost;
+
   int get remotePort => _socket.remotePort;
+
+  bool setOption(SocketOption option, bool enabled) {
+    return _socket.setOption(option, enabled);
+  }
 }
 
 
diff --git a/sdk/lib/io/http_parser.dart b/sdk/lib/io/http_parser.dart
index 68fbc32..c008f34 100644
--- a/sdk/lib/io/http_parser.dart
+++ b/sdk/lib/io/http_parser.dart
@@ -118,7 +118,7 @@
       subscription.resume();
       subscription.onData(controller.add);
       subscription.onDone(controller.close);
-      subscription.onError(controller.signalError);
+      subscription.onError(controller.addError);
     }
   }
 
@@ -566,17 +566,17 @@
               _controller.add(_incoming);
               break;
             }
-            if (_chunked) {
-              _state = _State.CHUNK_SIZE;
-              _remainingContent = 0;
-            } else if (_transferLength == 0 ||
-                         (_messageType == _MessageType.RESPONSE &&
-                          (_noMessageBody || _responseToMethod == "HEAD"))) {
+            if (_transferLength == 0 ||
+                (_messageType == _MessageType.RESPONSE &&
+                 (_noMessageBody || _responseToMethod == "HEAD"))) {
               _reset();
               var tmp = _incoming;
               _closeIncoming();
               _controller.add(tmp);
               break;
+            } else if (_chunked) {
+              _state = _State.CHUNK_SIZE;
+              _remainingContent = 0;
             } else if (_transferLength > 0) {
               _remainingContent = _transferLength;
               _state = _State.BODY;
@@ -642,13 +642,16 @@
             List<int> data;
             if (_remainingContent == null ||
                 dataAvailable <= _remainingContent) {
-              data = new Uint8List(dataAvailable);
-              data.setRange(0, dataAvailable, _buffer, _index);
+              if (_index == 0) {
+                data = _buffer;
+              } else {
+                data = new Uint8List(dataAvailable);
+                data.setRange(0, dataAvailable, _buffer, _index);
+              }
             } else {
               data = new Uint8List(_remainingContent);
               data.setRange(0, _remainingContent, _buffer, _index);
             }
-
             _bodyController.add(data);
             if (_remainingContent != null) {
               _remainingContent -= data.length;
@@ -708,7 +711,7 @@
       if (_state != _State.UPGRADED &&
           !(_state == _State.START && !_requestParser) &&
           !(_state == _State.BODY && !_chunked && _transferLength == -1)) {
-        _bodyController.signalError(
+        _bodyController.addError(
             new AsyncError(
                 new HttpParserException(
                     "Connection closed while receiving data")));
@@ -761,7 +764,7 @@
   }
 
   void _onError(e) {
-    _controller.signalError(e);
+    _controller.addError(e);
   }
 
   String get version {
@@ -792,7 +795,7 @@
   List<int> readUnparsedData() {
     if (_buffer == null) return null;
     if (_index == _buffer.length) return null;
-    var result = _buffer.getRange(_index, _buffer.length - _index);
+    var result = _buffer.sublist(_index);
     _releaseBuffer();
     return result;
   }
@@ -882,7 +885,8 @@
   }
 
   void _closeIncoming() {
-    assert(_incoming != null);
+    // Ignore multiple close (can happend in re-entrance).
+    if (_incoming == null) return;
     var tmp = _incoming;
     _incoming = null;
     tmp.close();
@@ -929,7 +933,7 @@
   void error(error) {
     if (_socketSubscription != null) _socketSubscription.cancel();
     _state = _State.FAILURE;
-    _controller.signalError(error);
+    _controller.addError(error);
     _controller.close();
   }
 
diff --git a/sdk/lib/io/http_utils.dart b/sdk/lib/io/http_utils.dart
index 8fe62ed..8c23491 100644
--- a/sdk/lib/io/http_utils.dart
+++ b/sdk/lib/io/http_utils.dart
@@ -104,20 +104,20 @@
 
     DateTime d = date.toUtc();
     StringBuffer sb = new StringBuffer();
-    sb.add(wkday[d.weekday - 1]);
-    sb.add(", ");
-    sb.add(d.day.toString());
-    sb.add(" ");
-    sb.add(month[d.month - 1]);
-    sb.add(" ");
-    sb.add(d.year.toString());
-    sb.add(d.hour < 9 ? " 0" : " ");
-    sb.add(d.hour.toString());
-    sb.add(d.minute < 9 ? ":0" : ":");
-    sb.add(d.minute.toString());
-    sb.add(d.second < 9 ? ":0" : ":");
-    sb.add(d.second.toString());
-    sb.add(" GMT");
+    sb.write(wkday[d.weekday - 1]);
+    sb.write(", ");
+    sb.write(d.day.toString());
+    sb.write(" ");
+    sb.write(month[d.month - 1]);
+    sb.write(" ");
+    sb.write(d.year.toString());
+    sb.write(d.hour < 9 ? " 0" : " ");
+    sb.write(d.hour.toString());
+    sb.write(d.minute < 9 ? ":0" : ":");
+    sb.write(d.minute.toString());
+    sb.write(d.second < 9 ? ":0" : ":");
+    sb.write(d.second.toString());
+    sb.write(" GMT");
     return sb.toString();
   }
 
diff --git a/sdk/lib/io/io.dart b/sdk/lib/io/io.dart
index 0ff9b24..9b1c418 100644
--- a/sdk/lib/io/io.dart
+++ b/sdk/lib/io/io.dart
@@ -21,11 +21,12 @@
 import 'dart:math';
 import 'dart:uri';
 import 'dart:utf';
-import 'dart:scalarlist';
+import 'dart:typeddata';
 
 part 'base64.dart';
 part 'buffer_list.dart';
 part 'common.dart';
+part 'data_transformer.dart';
 part 'directory.dart';
 part 'directory_impl.dart';
 part 'eventhandler.dart';
@@ -39,7 +40,9 @@
 part 'http_session.dart';
 part 'http_utils.dart';
 part 'io_sink.dart';
+part 'link.dart';
 part 'mime_multipart_parser.dart';
+part 'options.dart';
 part 'path.dart';
 part 'path_impl.dart';
 part 'platform.dart';
diff --git a/sdk/lib/io/io_sink.dart b/sdk/lib/io/io_sink.dart
index ace6f92..7c564fa 100644
--- a/sdk/lib/io/io_sink.dart
+++ b/sdk/lib/io/io_sink.dart
@@ -5,18 +5,31 @@
 part of dart.io;
 
 /**
- * Helper class to wrap a [StreamConsumer<List<int>, T>] and provide utility
- * functions for writing to the StreamConsumer directly. The [IOSink]
- * buffers the input given by [add] and [addString] and will delay a [consume]
- * or [addStream] until the buffer is flushed.
+ * Helper class to wrap a [StreamConsumer<List<int>, T>] and provide
+ * utility functions for writing to the StreamConsumer directly. The
+ * [IOSink] buffers the input given by [write], [writeAll], [writeln],
+ * [writeCharCode] and [writeBytes] and will delay a [consume] or
+ * [writeStream] until the buffer is flushed.
  *
  * When the [IOSink] is bound to a stream (through either [consume]
- * or [addStream]) any call to the [IOSink] will throw a
+ * or [writeStream]) any call to the [IOSink] will throw a
  * [StateError].
  */
-abstract class IOSink<T> implements StreamConsumer<List<int>, T> {
-  factory IOSink(StreamConsumer<List<int>, T> target)
-      => new _IOSinkImpl(target);
+abstract class IOSink<T> implements StreamConsumer<List<int>, T>, StringSink {
+  factory IOSink(StreamConsumer<List<int>, T> target,
+                 {Encoding encoding: Encoding.UTF_8})
+      => new _IOSinkImpl(target, encoding);
+
+  /**
+   * The [Encoding] used when writing strings. Depending on the
+   * underlying consumer this property might be mutable.
+   */
+  Encoding encoding;
+
+  /**
+   * Writes the bytes uninterpreted to the consumer.
+   */
+  void writeBytes(List<int> data);
 
   /**
    * Provide functionality for piping to the [IOSink].
@@ -26,17 +39,7 @@
   /**
    * Like [consume], but will not close the target when done.
    */
-  Future<T> addStream(Stream<List<int>> stream);
-
-  /**
-   * Write a list of bytes to the target.
-   */
-  void add(List<int> data);
-
-  /**
-   * Write a String to the target.
-   */
-  void addString(String string, [Encoding encoding = Encoding.UTF_8]);
+  Future<T> writeStream(Stream<List<int>> stream);
 
   /**
    * Close the target.
@@ -54,12 +57,62 @@
 class _IOSinkImpl<T> implements IOSink<T> {
   final StreamConsumer<List<int>, T> _target;
 
+  Completer _writeStreamCompleter;
   StreamController<List<int>> _controllerInstance;
   Future<T> _pipeFuture;
   StreamSubscription<List<int>> _bindSubscription;
   bool _paused = true;
+  bool _encodingMutable = true;
 
-  _IOSinkImpl(StreamConsumer<List<int>, T> target) : _target = target;
+  _IOSinkImpl(StreamConsumer<List<int>, T> this._target, this._encoding);
+
+  Encoding _encoding;
+
+  Encoding get encoding => _encoding;
+
+  void set encoding(Encoding value) {
+    if (!_encodingMutable) {
+      throw new StateError("IOSink encoding is not mutable");
+    }
+    _encoding = value;
+  }
+
+  void write(Object obj) {
+    // This comment is copied from runtime/lib/string_buffer_patch.dart.
+    // TODO(srdjan): The following four lines could be replaced by
+    // '$obj', but apparently this is too slow on the Dart VM.
+    String string;
+    if (obj is String) {
+      string = obj;
+    } else {
+      string = obj.toString();
+      if (string is! String) {
+        throw new ArgumentError('toString() did not return a string');
+      }
+    }
+    if (string.isEmpty) return;
+    writeBytes(_encodeString(string, _encoding));
+  }
+
+  void writeAll(Iterable objects) {
+    for (Object obj in objects) write(obj);
+  }
+
+  void writeln([Object obj = ""]) {
+    write(obj);
+    write("\n");
+  }
+
+  void writeCharCode(int charCode) {
+    write(new String.fromCharCode(charCode));
+  }
+
+  void writeBytes(List<int> data) {
+    if (_isBound) {
+      throw new StateError("IOSink is already bound to a stream");
+    }
+    _controller.add(data);
+  }
 
   Future<T> consume(Stream<List<int>> stream) {
     if (_isBound) {
@@ -68,24 +121,13 @@
     return _fillFromStream(stream);
   }
 
-  Future<T> addStream(Stream<List<int>> stream) {
+  Future<T> writeStream(Stream<List<int>> stream) {
     if (_isBound) {
       throw new StateError("IOSink is already bound to a stream");
     }
     return _fillFromStream(stream, unbind: true);
   }
 
-  void add(List<int> data) {
-    if (_isBound) {
-      throw new StateError("IOSink is already bound to a stream");
-    }
-    _controller.add(data);
-  }
-
-  void addString(String string, [Encoding encoding = Encoding.UTF_8]) {
-    add(_encodeString(string, encoding));
-  }
-
   void close() {
     if (_isBound) {
       throw new StateError("IOSink is already bound to a stream");
@@ -95,7 +137,19 @@
 
   Future<T> get done {
     _controller;
-    return _pipeFuture.then((_) => this);
+    return _pipeFuture;
+  }
+
+  void _completeWriteStreamCompleter([error]) {
+    if (_writeStreamCompleter == null) return;
+    var tmp = _writeStreamCompleter;
+    _writeStreamCompleter = null;
+    if (error == null) {
+      _bindSubscription = null;
+      tmp.complete();
+    } else {
+      tmp.completeError(error);
+    }
   }
 
   StreamController<List<int>> get _controller {
@@ -103,7 +157,10 @@
       _controllerInstance = new StreamController<List<int>>(
           onPauseStateChange: _onPauseStateChange,
           onSubscriptionStateChange: _onSubscriptionStateChange);
-      _pipeFuture = _controller.stream.pipe(_target).then((_) => this);
+      var future = _controller.stream.pipe(_target);
+      future.then((_) => _completeWriteStreamCompleter(),
+                  onError: (error) => _completeWriteStreamCompleter(error));
+      _pipeFuture = future.then((value) => value);
     }
     return _controllerInstance;
   }
@@ -153,39 +210,25 @@
 
   Future<T> _fillFromStream(Stream<List<int>> stream, {unbind: false}) {
     _controller;
-    Completer<T> unbindCompleter;
+    assert(_writeStreamCompleter == null);
     if (unbind) {
-      unbindCompleter = new Completer<T>();
-    }
-    completeUnbind([error]) {
-      if (unbindCompleter == null) return;
-      var tmp = unbindCompleter;
-      unbindCompleter = null;
-      if (error == null) {
-        _bindSubscription = null;
-        tmp.complete();
-      } else {
-        tmp.completeError(error);
-      }
+      _writeStreamCompleter = new Completer<T>();
     }
     _bindSubscription = stream.listen(
         _controller.add,
         onDone: () {
           if (unbind) {
-            completeUnbind();
+            _completeWriteStreamCompleter();
           } else {
             _controller.close();
           }
         },
-        onError: _controller.signalError);
+        onError: _controller.addError);
     if (_paused) _pause();
     if (unbind) {
-      _pipeFuture
-          .then((_) => completeUnbind(),
-                onError: (error) => completeUnbind(error));
-      return unbindCompleter.future;
+      return _writeStreamCompleter.future;
     } else {
-      return _pipeFuture.then((_) => this);
+      return _pipeFuture;
     }
   }
 }
diff --git a/sdk/lib/io/iolib_sources.gypi b/sdk/lib/io/iolib_sources.gypi
index 92113b4..5f5692a 100644
--- a/sdk/lib/io/iolib_sources.gypi
+++ b/sdk/lib/io/iolib_sources.gypi
@@ -7,6 +7,7 @@
     'base64.dart',
     'buffer_list.dart',
     'common.dart',
+    'data_transformer.dart',
     'directory.dart',
     'directory_impl.dart',
     'eventhandler.dart',
@@ -20,7 +21,9 @@
     'http_session.dart',
     'http_utils.dart',
     'io_sink.dart',
+    'link.dart',
     'mime_multipart_parser.dart',
+    'options.dart',
     'path.dart',
     'path_impl.dart',
     'platform.dart',
diff --git a/sdk/lib/io/link.dart b/sdk/lib/io/link.dart
new file mode 100644
index 0000000..00aeb2d
--- /dev/null
+++ b/sdk/lib/io/link.dart
@@ -0,0 +1,178 @@
+// 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.
+
+part of dart.io;
+
+/**
+ * [Link] objects are references to filesystem links.
+ *
+ */
+abstract class Link extends FileSystemEntity {
+  /**
+   * Create a Link object.
+   */
+  factory Link(String path) => new _Link(path);
+
+  /**
+   * Create a Link object from a Path object.
+   */
+  factory Link.fromPath(Path path) => new _Link.fromPath(path);
+
+  /**
+   * Check if the link exists. The link may exist, even if its target
+   * is missing or deleted.
+   * Returns a [:Future<bool>:] that completes when the answer is known.
+   */
+  Future<bool> exists();
+
+  /**
+   * Synchronously check if the link exists. The link may exist, even if
+   * its target is missing or deleted.
+   */
+  bool existsSync();
+
+  /**
+   * Create a symbolic link. Returns a [:Future<Link>:] that completes with
+   * the link when it has been created. If the link exists, the function
+   * the future will complete with an error.
+   *
+   * On the Windows platform, this will only work with directories, and the
+   * target directory must exist. The link will be created as a Junction.
+   * Only absolute links will be created, and relative paths to the target
+   * will be converted to absolute paths.
+   */
+  Future<Link> create(String target);
+
+  /**
+   * Synchronously create the link. Calling [createSync] on an existing link
+   * will throw an exception.
+   *
+   * On the Windows platform, this will only work with directories, and the
+   * target directory must exist. The link will be created as a Junction.
+   * Only absolute links will be created, and relative paths to the target
+   * will be converted to absolute paths.
+   */
+  void createSync(String target);
+
+  /**
+   * Synchronously update the link. Calling [updateSync] on a non-existing link
+   * will throw an exception.
+   *
+   * If [linkRelative] is true, the target argument should be a relative path,
+   * and the link will interpret the target as a path relative to the link's
+   * directory.
+   *
+   * On the Windows platform, this will only work with directories, and the
+   * target directory must exist.
+   */
+  void updateSync(String target, {bool linkRelative: false });
+
+  /**
+   * Delete the link. Returns a [:Future<Link>:] that completes with
+   * the link when it has been deleted.  This does not delete, or otherwise
+   * affect, the target of the link.
+   */
+  Future<Link> delete();
+
+  /**
+   * Synchronously delete the link. This does not delete, or otherwise
+   * affect, the target of the link.
+   */
+  void deleteSync();
+}
+
+
+class _Link extends FileSystemEntity implements Link {
+  final String path;
+
+  _Link(String this.path);
+
+  _Link.fromPath(Path inputPath) : path = inputPath.toNativePath();
+
+  Future<bool> exists() {
+    // TODO(whesse): Replace with asynchronous version.
+    return new Future.immediate(existsSync());
+  }
+
+  bool existsSync() => FileSystemEntity.isLinkSync(path);
+
+  Future<Link> create(String target) {
+    // TODO(whesse): Replace with asynchronous version.
+    return new Future.of(() {
+      createSync(target);
+      return this;
+    });
+  }
+
+  void createSync(String target) {
+    if (Platform.operatingSystem == 'windows') {
+      target = _makeWindowsLinkTarget(target);
+    }
+    var result = _File._createLink(path, target);
+    if (result is Error) {
+      throw new LinkIOException("Error in Link.createSync", result);
+    }
+  }
+
+  // Put target into the form "\??\C:\my\target\dir".
+  String _makeWindowsLinkTarget(String target) {
+    if (target.startsWith('\\??\\')) {
+      return target;
+    }
+    if (!(target.length > 3 && target[1] == ':' && target[2] == '\\')) {
+      target = new File(target).fullPathSync();
+    }
+    if (target.length > 3 && target[1] == ':' && target[2] == '\\') {
+      target = '\\??\\$target';
+    } else {
+      throw new ArgumentError(
+          'Target $target of Link.create on Windows cannot be converted' +
+          ' to start with a drive letter.  Unexpected error.');
+    }
+    return target;
+  }
+
+  void updateSync(String target, {bool linkRelative: false }) {
+    // TODO(whesse): Replace with atomic update, where supported by platform.
+    deleteSync();
+    createSync(target);
+  }
+
+  Future<Link> delete() {
+    return new File(path).delete().then((_) => this);
+  }
+
+  void deleteSync() {
+    new File(path).deleteSync();
+  }
+}
+
+
+class LinkIOException implements Exception {
+  const LinkIOException([String this.message = "",
+                         String this.path = "",
+                         OSError this.osError = null]);
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write("LinkIOException");
+    if (!message.isEmpty) {
+      sb.write(": $message");
+      if (path != null) {
+        sb.write(", path = $path");
+      }
+      if (osError != null) {
+        sb.write(" ($osError)");
+      }
+    } else if (osError != null) {
+      sb.write(": $osError");
+      if (path != null) {
+        sb.write(", path = $path");
+      }
+    }
+    return sb.toString();
+  }
+  final String message;
+  final String path;
+  final OSError osError;
+}
diff --git a/sdk/lib/io/mime_multipart_parser.dart b/sdk/lib/io/mime_multipart_parser.dart
index 51f6b7f..cd12c20 100644
--- a/sdk/lib/io/mime_multipart_parser.dart
+++ b/sdk/lib/io/mime_multipart_parser.dart
@@ -79,17 +79,17 @@
         var contentLength = boundaryPrefix + index - _boundaryIndex;
         if (contentLength <= boundaryPrefix) {
           partDataReceived(
-              _boundary.getRange(0, contentLength));
+              _boundary.sublist(0, contentLength));
         } else {
           partDataReceived(
-              _boundary.getRange(0, boundaryPrefix));
+              _boundary.sublist(0, boundaryPrefix));
           partDataReceived(
-              buffer.getRange(0, contentLength - boundaryPrefix));
+              buffer.sublist(0, contentLength - boundaryPrefix));
         }
       } else {
-        var contentLength = index - contentStartIndex - _boundaryIndex;
+        var contentEndIndex = index - _boundaryIndex;
         partDataReceived(
-            buffer.getRange(contentStartIndex, contentLength));
+            buffer.sublist(contentStartIndex, contentEndIndex));
       }
     }
 
@@ -163,7 +163,7 @@
             _state = _HEADER_ENDING;
             } else {
               // Start of new header field.
-              _headerField.addCharCode(_toLowerCase(byte));
+              _headerField.writeCharCode(_toLowerCase(byte));
               _state = _HEADER_FIELD;
             }
             break;
@@ -175,7 +175,7 @@
               if (!_isTokenChar(byte)) {
                 throw new MimeParserException("Invalid header field name");
               }
-              _headerField.addCharCode(_toLowerCase(byte));
+              _headerField.writeCharCode(_toLowerCase(byte));
             }
             break;
 
@@ -184,7 +184,7 @@
               _state = _HEADER_VALUE_FOLDING_OR_ENDING;
             } else if (byte != _CharCode.SP && byte != _CharCode.HT) {
               // Start of new header value.
-              _headerValue.addCharCode(byte);
+              _headerValue.writeCharCode(byte);
               _state = _HEADER_VALUE;
             }
             break;
@@ -193,7 +193,7 @@
             if (byte == _CharCode.CR) {
               _state = _HEADER_VALUE_FOLDING_OR_ENDING;
             } else {
-              _headerValue.addCharCode(byte);
+              _headerValue.writeCharCode(byte);
             }
             break;
 
@@ -211,13 +211,13 @@
               if (headerReceived != null) {
                 headerReceived(headerField, headerValue);
               }
-              _headerField.clear();
-              _headerValue.clear();
+              _headerField = new StringBuffer();
+              _headerValue = new StringBuffer();
               if (byte == _CharCode.CR) {
                 _state = _HEADER_ENDING;
               } else {
                 // Start of new header field.
-                _headerField.addCharCode(_toLowerCase(byte));
+                _headerField.writeCharCode(_toLowerCase(byte));
                 _state = _HEADER_FIELD;
               }
             }
diff --git a/sdk/lib/core/options.dart b/sdk/lib/io/options.dart
similarity index 95%
rename from sdk/lib/core/options.dart
rename to sdk/lib/io/options.dart
index 696ad8d..91a8e58 100644
--- a/sdk/lib/core/options.dart
+++ b/sdk/lib/io/options.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-part of dart.core;
+part of dart.io;
 
 /**
  * The Options object allows accessing the arguments which have been passed to
@@ -47,7 +47,7 @@
   List<String> get arguments {
     if (_arguments == null) {
       // On first access make a copy of the native arguments.
-      _arguments = _nativeArguments.getRange(0, _nativeArguments.length);
+      _arguments = _nativeArguments.sublist(0, _nativeArguments.length);
     }
     return _arguments;
   }
diff --git a/sdk/lib/io/path.dart b/sdk/lib/io/path.dart
index c59017a..aa42caec 100644
--- a/sdk/lib/io/path.dart
+++ b/sdk/lib/io/path.dart
@@ -128,6 +128,7 @@
   /**
    * Converts a path to a string using the native filesystem's conventions.
    *
+   * Always returns '.' if the path is empty.
    * On Windows, converts '/'s to backwards slashes, and removes
    * the leading '/' if the path starts with a drive specification.
    * For most valid Windows paths, this should be the inverse of the
diff --git a/sdk/lib/io/path_impl.dart b/sdk/lib/io/path_impl.dart
index a42a290..50e4d38 100644
--- a/sdk/lib/io/path_impl.dart
+++ b/sdk/lib/io/path_impl.dart
@@ -46,7 +46,7 @@
 
   Path relativeTo(Path base) {
     // Returns a path "relative" such that
-    //    base.join(relative) == this.canonicalize.
+    // base.join(relative) == this.canonicalize.
     // Throws exception if an impossible case is reached.
     if (base.isAbsolute != isAbsolute ||
         base.isWindowsShare != isWindowsShare) {
@@ -57,6 +57,37 @@
     }
 
     var basePath = base.toString();
+    // Handle drive letters specially on Windows.
+    if (base.isAbsolute && Platform.operatingSystem == 'windows') {
+      bool baseHasDrive =
+          basePath.length >= 4 && basePath[2] == ':' && basePath[3] == '/';
+      bool pathHasDrive =
+          _path.length >= 4 && _path[2] == ':' && _path[3] == '/';
+      if (baseHasDrive && pathHasDrive) {
+        int baseDrive = basePath.codeUnitAt(1) | 32;  // Convert to uppercase.
+        if (baseDrive >= 'a'.codeUnitAt(0) &&
+            baseDrive <= 'z'.codeUnitAt(0) &&
+            baseDrive == (_path.codeUnitAt(1) | 32)) {
+          if(basePath[1] != _path[1]) {
+            // Replace the drive letter in basePath with that from _path.
+            basePath = '/${_path[1]}:/${basePath.substring(4)}';
+            base = new Path(basePath);
+          }
+        } else {
+          throw new ArgumentError(
+              "Invalid case of Path.relativeTo(base):\n"
+              "  Base path and target path are on different Windows drives.\n"
+              "  Arguments: $_path.relativeTo($base)");
+        }
+      } else if (baseHasDrive != pathHasDrive) {
+        throw new ArgumentError(
+            "Invalid case of Path.relativeTo(base):\n"
+            "  Base path must start with a drive letter if and "
+            "only if target path does.\n"
+            "  Arguments: $_path.relativeTo($base)");
+      }
+
+    }
     if (_path.startsWith(basePath)) {
       if (_path == basePath) return new Path('.');
       // There must be a '/' at the end of the match, or immediately after.
@@ -88,7 +119,7 @@
     if (common < baseSegments.length && baseSegments[common] == '..') {
       throw new ArgumentError(
           "Invalid case of Path.relativeTo(base):\n"
-          "  Base path has more '..'s than path does."
+          "  Base path has more '..'s than path does.\n"
           "  Arguments: $_path.relativeTo($base)");
     }
     for (int i = common; i < baseSegments.length; i++) {
@@ -123,8 +154,9 @@
     return joined.canonicalize();
   }
 
-  // Note: The URI RFC names for these operations are normalize, resolve, and
-  // relativize.
+  // Note: The URI RFC names for canonicalize, join, and relativeTo
+  // are normalize, resolve, and relativize.  But resolve and relativize
+  // drop the last segment of the base path (the filename), on URIs.
   Path canonicalize() {
     if (isCanonical) return this;
     return makeCanonical();
@@ -214,6 +246,7 @@
   }
 
   String toNativePath() {
+    if (isEmpty) return '.';
     if (Platform.operatingSystem == 'windows') {
       String nativePath = _path;
       // Drop '/' before a drive letter.
diff --git a/sdk/lib/io/secure_server_socket.dart b/sdk/lib/io/secure_server_socket.dart
index 7a9b34d..bcbc731 100644
--- a/sdk/lib/io/secure_server_socket.dart
+++ b/sdk/lib/io/secure_server_socket.dart
@@ -198,14 +198,14 @@
       if (_closed) {
         throw e;
       } else {
-        _controller.signalError(e);
+        _controller.addError(e);
         close();
       }
     });
   }
 
   void _onError(e) {
-    _controller.signalError(e);
+    _controller.addError(e);
     close();
   }
 
diff --git a/sdk/lib/io/secure_socket.dart b/sdk/lib/io/secure_socket.dart
index 62ecb4d..41fdf59 100644
--- a/sdk/lib/io/secure_socket.dart
+++ b/sdk/lib/io/secure_socket.dart
@@ -433,7 +433,7 @@
       }
     }
     List<int> result = (toRead == 0) ? null :
-        buffer.data.getRange(buffer.start, toRead);
+        buffer.data.sublist(buffer.start, buffer.start + toRead);
     buffer.advanceStart(toRead);
 
     // Set up a read event if the filter still has data.
@@ -464,7 +464,7 @@
   // up handlers to flush the pipeline when possible.
   int write(List<int> data, [int offset, int bytes]) {
     if (_closedWrite) {
-      _controller.signalError(new AsyncError(new SocketIOException(
+      _controller.addError(new AsyncError(new SocketIOException(
           "Writing to a closed socket")));
       return 0;
     }
@@ -483,6 +483,11 @@
 
   X509Certificate get peerCertificate => _secureFilter.peerCertificate;
 
+  bool setOption(SocketOption option, bool enabled) {
+    if (_socket == null) return false;
+    return _socket.setOption(option, enabled);
+  }
+
   void _writeHandler() {
     if (_status == CLOSED) return;
     _writeEncryptedData();
@@ -572,7 +577,7 @@
     if (_connectPending) {
       _handshakeComplete.completeError(e);
     } else {
-      _controller.signalError(e);
+      _controller.addError(e);
     }
     _close();
   }
diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart
index aa05fdc..1680f6b 100644
--- a/sdk/lib/io/socket.dart
+++ b/sdk/lib/io/socket.dart
@@ -86,6 +86,24 @@
 }
 
 /**
+ * The [SocketOption] is used as a parameter to [Socket.setOption] and
+ * [RawSocket.setOption] to set customize the behaviour of the underlying
+ * socket.
+ */
+class SocketOption {
+  /**
+   * Enable or disable no-delay on the socket. If TCP_NODELAY is enabled, the
+   * socket will not buffer data internally, but instead write each data chunk
+   * as an invidual TCP packet.
+   *
+   * TCP_NODELAY is disabled by default.
+   */
+  static const SocketOption TCP_NODELAY = const SocketOption._(0);
+  const SocketOption._(this._value);
+  final _value;
+}
+
+/**
  * Events for the [RawSocket].
  */
 class RawSocketEvent {
@@ -179,6 +197,14 @@
    * to true again to receive another write event.
    */
   bool writeEventsEnabled;
+
+  /**
+   * Use [setOption] to customize the [RawSocket]. See [SocketOption] for
+   * available options.
+   *
+   * Returns [true] if the option was set successfully, false otherwise.
+   */
+  bool setOption(SocketOption option, bool enabled);
 }
 
 /**
@@ -205,6 +231,14 @@
    */
   void destroy();
 
+  /**
+   * Use [setOption] to customize the [RawSocket]. See [SocketOption] for
+   * available options.
+   *
+   * Returns [true] if the option was set successfully, false otherwise.
+   */
+  bool setOption(SocketOption option, bool enabled);
+
   int get port;
   String get remoteHost;
   int get remotePort;
@@ -216,14 +250,14 @@
                            OSError this.osError = null]);
   String toString() {
     StringBuffer sb = new StringBuffer();
-    sb.add("SocketIOException");
+    sb.write("SocketIOException");
     if (!message.isEmpty) {
-      sb.add(": $message");
+      sb.write(": $message");
       if (osError != null) {
-        sb.add(" ($osError)");
+        sb.write(" ($osError)");
       }
     } else if (osError != null) {
-      sb.add(": $osError");
+      sb.write(": $osError");
     }
     return sb.toString();
   }
diff --git a/sdk/lib/io/string_transformer.dart b/sdk/lib/io/string_transformer.dart
index cea080a..7cc9bc0 100644
--- a/sdk/lib/io/string_transformer.dart
+++ b/sdk/lib/io/string_transformer.dart
@@ -8,16 +8,71 @@
  * String encodings.
  */
 class Encoding {
-  static const Encoding UTF_8 = const Encoding._internal("UTF-8");
-  static const Encoding ISO_8859_1 = const Encoding._internal("ISO-8859-1");
-  static const Encoding ASCII = const Encoding._internal("ASCII");
+  static const Encoding UTF_8 = const Encoding._internal("utf-8");
+  static const Encoding ISO_8859_1 = const Encoding._internal("iso-8859-1");
+  static const Encoding ASCII = const Encoding._internal("us-ascii");
+
+  // All aliasses (in lowercase) of supported encoding from
+  // http://www.iana.org/assignments/character-sets/character-sets.xml.
+  static Map<String, Encoding> _nameToEncoding = <String, Encoding> {
+    // ISO_8859-1:1987.
+    "iso_8859-1:1987": ISO_8859_1,
+    "iso-ir-100": ISO_8859_1,
+    "iso_8859-1": ISO_8859_1,
+    "iso-8859-1": ISO_8859_1,
+    "latin1": ISO_8859_1,
+    "l1": ISO_8859_1,
+    "ibm819": ISO_8859_1,
+    "cp819": ISO_8859_1,
+    "csisolatin1": ISO_8859_1,
+
+    // US-ASCII.
+    "iso-ir-6": ASCII,
+    "ansi_x3.4-1968": ASCII,
+    "ansi_x3.4-1986": ASCII,
+    "iso_646.irv:1991": ASCII,
+    "iso646-us": ASCII,
+    "us-ascii": ASCII,
+    "us": ASCII,
+    "ibm367": ASCII,
+    "cp367": ASCII,
+    "csascii": ASCII,
+    "ascii": ASCII,  // This is not in the IANA official names.
+
+    // UTF-8.
+    "csutf8": UTF_8,
+    "utf-8": UTF_8
+  };
+
+  /**
+   * Gets an [Encoding] object from the name of the character set
+   * name. The names used are the IANA official names for the
+   * character set (see
+   * http://www.iana.org/assignments/character-sets/character-sets.xml).
+   *
+   * The [name] passed is case insensitive.
+   *
+   * If character set is not supported [:null:] is returned.
+   */
+  static Encoding fromName(String name) {
+    if (name == null) return null;
+    name = name.toLowerCase();
+    return _nameToEncoding[name];
+  }
+
+  /**
+   * Name of the encoding. This will be the lower-case version of one of the
+   * IANA official names for the character set (see
+   * http://www.iana.org/assignments/character-sets/character-sets.xml)
+   */
+  final String name;
+
   /**
    * SYSTEM encoding is the current code page on Windows and UTF-8 on
    * Linux and Mac.
    */
-  static const Encoding SYSTEM = const Encoding._internal("SYSTEM");
+  static const Encoding SYSTEM = const Encoding._internal("system");
   const Encoding._internal(String this.name);
-  final String name;
 }
 
 
@@ -157,12 +212,12 @@
   const int _LF = 10;
   const int _CR = 13;
 
-  final StringBuffer _buffer = new StringBuffer();
+  StringBuffer _buffer = new StringBuffer();
   String _carry;
 
-  void _handle(String data, StreamSink<String> sink, bool isClosing) {
+  void _handle(String data, EventSink<String> sink, bool isClosing) {
     if (_carry != null) {
-      data = _carry.concat(data);
+      data = _carry + data;
       _carry = null;
     }
     int startPos = 0;
@@ -184,9 +239,9 @@
         }
       }
       if (skip > 0) {
-        _buffer.add(data.substring(startPos, pos));
+        _buffer.write(data.substring(startPos, pos));
         sink.add(_buffer.toString());
-        _buffer.clear();
+        _buffer = new StringBuffer();
         startPos = pos = pos + skip;
       } else {
         pos++;
@@ -194,19 +249,19 @@
     }
     if (pos != startPos) {
       // Add remaining
-      _buffer.add(data.substring(startPos, pos));
+      _buffer.write(data.substring(startPos, pos));
     }
     if (isClosing && !_buffer.isEmpty) {
       sink.add(_buffer.toString());
-      _buffer.clear();
+      _buffer = new StringBuffer();
     }
   }
 
-  void handleData(String data, StreamSink<String> sink) {
+  void handleData(String data, EventSink<String> sink) {
     _handle(data, sink, false);
   }
 
-  void handleDone(StreamSink<String> sink) {
+  void handleDone(EventSink<String> sink) {
     _handle("", sink, true);
     sink.close();
   }
@@ -219,7 +274,7 @@
 
   _SingleByteDecoder(this._replacementChar);
 
-  void handleData(List<int> data, StreamSink<String> sink) {
+  void handleData(List<int> data, EventSink<String> sink) {
     var buffer = new List<int>(data.length);
     for (int i = 0; i < data.length; i++) {
       int char = _decodeByte(data[i]);
@@ -253,10 +308,10 @@
 
 abstract class _SingleByteEncoder
     extends StreamEventTransformer<String, List<int>> {
-  void handleData(String data, StreamSink<List<int>> sink) {
+  void handleData(String data, EventSink<List<int>> sink) {
     var bytes = _encode(data);
     if (bytes == null) {
-      sink.signalError(
+      sink.addError(
           new AsyncError(
               new FormatException("Invalid character for encoding")));
       sink.close();
@@ -307,7 +362,7 @@
 // Utility class for decoding Windows current code page data delivered
 // as a stream of bytes.
 class _WindowsCodePageDecoder extends StreamEventTransformer<List<int>, String> {
-  void handleData(List<int> data, StreamSink<String> sink) {
+  void handleData(List<int> data, EventSink<String> sink) {
     sink.add(_decodeBytes(data));
   }
 
diff --git a/sdk/lib/io/timer_impl.dart b/sdk/lib/io/timer_impl.dart
index c08f3bb..107daba 100644
--- a/sdk/lib/io/timer_impl.dart
+++ b/sdk/lib/io/timer_impl.dart
@@ -32,7 +32,7 @@
     return _createTimer(callback, milliSeconds, false);
   }
 
-  factory _Timer.repeating(int milliSeconds, void callback(Timer timer)) {
+  factory _Timer.periodic(int milliSeconds, void callback(Timer timer)) {
     return _createTimer(callback, milliSeconds, true);
   }
 
@@ -84,7 +84,7 @@
         }
         entry = entry.nextEntry();
       }
-      _timers.addLast(this);
+      _timers.add(this);
     }
   }
 
@@ -132,7 +132,7 @@
         _Timer timer = entry.element;
         if (timer._wakeupTime <= currentTime) {
           entry.remove();
-          pending_timers.addLast(timer);
+          pending_timers.add(timer);
           entry = _timers.firstEntry();
         } else {
           break;
@@ -193,7 +193,7 @@
 _getTimerFactoryClosure() {
   return (int milliSeconds, void callback(Timer timer), bool repeating) {
     if (repeating) {
-      return new _Timer.repeating(milliSeconds, callback);
+      return new _Timer.periodic(milliSeconds, callback);
     }
     return new _Timer(milliSeconds, callback);
   };
diff --git a/sdk/lib/io/websocket_impl.dart b/sdk/lib/io/websocket_impl.dart
index a849ae1..fcbe1ca 100644
--- a/sdk/lib/io/websocket_impl.dart
+++ b/sdk/lib/io/websocket_impl.dart
@@ -33,18 +33,15 @@
 }
 
 /**
- * The web socket protocol processor handles the protocol byte stream
- * which is supplied through the [:update:] and [:closed:]
- * methods. As the protocol is processed the following callbacks are
- * called:
+ * The web socket protocol transformer handles the protocol byte stream
+ * which is supplied through the [:handleData:]. As the protocol is processed,
+ * it'll output frame data as either a List<int> or String.
  *
- *   [:onMessageStart:]
- *   [:onMessageData:]
- *   [:onMessageEnd:]
- *   [:onClosed:]
- *
+ * Important infomation about usage: Be sure you use unsubscribeOnError, so the
+ * socket will be closed when the processer encounter an error. Not using it
+ * will lead to undefined behaviour.
  */
-class _WebSocketProtocolProcessor {
+class _WebSocketProtocolTransformer extends StreamEventTransformer {
   static const int START = 0;
   static const int LEN_FIRST = 1;
   static const int LEN_REST = 2;
@@ -53,7 +50,7 @@
   static const int CLOSED = 5;
   static const int FAILURE = 6;
 
-  _WebSocketProtocolProcessor() {
+  _WebSocketProtocolTransformer() {
     _prepareForNextFrame();
     _currentMessageType = _WebSocketMessageType.NONE;
   }
@@ -61,9 +58,10 @@
   /**
    * Process data received from the underlying communication channel.
    */
-  void update(List<int> buffer, int offset, int count) {
-    int index = offset;
-    int lastIndex = offset + count;
+  void handleData(List<int> buffer, EventSink sink) {
+    int count = buffer.length;
+    int index = 0;
+    int lastIndex = count;
     try {
       if (_state == CLOSED) {
         throw new WebSocketException("Data on closed connection");
@@ -89,9 +87,7 @@
                 throw new WebSocketException("Protocol error");
               }
               _currentMessageType = _WebSocketMessageType.TEXT;
-              if (onMessageStart != null) {
-                onMessageStart(_WebSocketMessageType.TEXT);
-              }
+              _buffer = new StringBuffer();
               break;
 
             case _WebSocketOpcode.BINARY:
@@ -99,9 +95,7 @@
                 throw new WebSocketException("Protocol error");
               }
               _currentMessageType = _WebSocketMessageType.BINARY;
-              if (onMessageStart != null) {
-                onMessageStart(_WebSocketMessageType.BINARY);
-              }
+              _buffer = new _BufferList();
               break;
 
             case _WebSocketOpcode.CLOSE:
@@ -124,7 +118,7 @@
               throw new WebSocketException("Protocol error");
             }
             if (_len < 126) {
-              _lengthDone();
+              _lengthDone(sink);
             } else if (_len == 126) {
               _len = 0;
               _remainingLenBytes = 2;
@@ -140,7 +134,7 @@
             _len = _len << 8 | byte;
             _remainingLenBytes--;
             if (_remainingLenBytes == 0) {
-              _lengthDone();
+              _lengthDone(sink);
             }
             break;
 
@@ -148,7 +142,7 @@
             _maskingKey = _maskingKey << 8 | byte;
             _remainingMaskingKeyBytes--;
             if (_remainingMaskingKeyBytes == 0) {
-              _maskDone();
+              _maskDone(sink);
             }
             break;
 
@@ -179,12 +173,12 @@
                 if (_controlPayload == null) {
                   _controlPayload = new List<int>();
                 }
-                _controlPayload.addAll(buffer.getRange(index, payload));
+                _controlPayload.addAll(buffer.sublist(index, index + payload));
                 index += payload;
               }
 
               if (_remainingPayloadBytes == 0) {
-                _controlFrameEnd();
+                _controlFrameEnd(sink);
               }
             } else {
               switch (_currentMessageType) {
@@ -192,13 +186,19 @@
                   throw new WebSocketException("Protocol error");
 
                 case _WebSocketMessageType.TEXT:
-                case _WebSocketMessageType.BINARY:
-                  if (onMessageData != null) {
-                    onMessageData(buffer, index, payload);
-                  }
+                  _buffer.write(_decodeString(
+                      buffer.sublist(index, index + payload)));
                   index += payload;
                   if (_remainingPayloadBytes == 0) {
-                    _messageFrameEnd();
+                    _messageFrameEnd(sink);
+                  }
+                  break;
+
+                case _WebSocketMessageType.BINARY:
+                  _buffer.write(buffer.sublist(index, index + payload));
+                  index += payload;
+                  if (_remainingPayloadBytes == 0) {
+                    _messageFrameEnd(sink);
                   }
                   break;
 
@@ -216,99 +216,99 @@
         index++;
       }
     } catch (e) {
-      if (onClosed != null) onClosed(WebSocketStatus.PROTOCOL_ERROR,
-                                      "Protocol error");
       _state = FAILURE;
+      sink.addError(e);
     }
   }
 
-  /**
-   * Indicate that the underlying communication channel has been closed.
-   */
-  void closed() {
-    if (_state == START || _state == CLOSED || _state == FAILURE) return;
-    if (onClosed != null) onClosed(WebSocketStatus.ABNORMAL_CLOSURE,
-                                    "Connection closed unexpectedly");
-    _state = CLOSED;
-  }
-
-  void _lengthDone() {
+  void _lengthDone(EventSink sink) {
     if (_masked) {
       _state = MASK;
       _remainingMaskingKeyBytes = 4;
     } else {
       _remainingPayloadBytes = _len;
-      _startPayload();
+      _startPayload(sink);
     }
   }
 
-  void _maskDone() {
+  void _maskDone(EventSink sink) {
     _remainingPayloadBytes = _len;
-    _startPayload();
+    _startPayload(sink);
   }
 
-  void _startPayload() {
+  void _startPayload(EventSink sink) {
     // If there is no actual payload perform perform callbacks without
     // going through the PAYLOAD state.
     if (_remainingPayloadBytes == 0) {
       if (_isControlFrame()) {
         switch (_opcode) {
           case _WebSocketOpcode.CLOSE:
-            if (onClosed != null) onClosed(1005, "");
             _state = CLOSED;
+            sink.close();
             break;
           case _WebSocketOpcode.PING:
-            if (onPing != null) onPing(null);
+            // TODO(ajohnsen): Handle ping.
             break;
           case _WebSocketOpcode.PONG:
-            if (onPong != null) onPong(null);
+            // TODO(ajohnsen): Handle pong.
             break;
         }
         _prepareForNextFrame();
       } else {
-        _messageFrameEnd();
+        _messageFrameEnd(sink);
       }
     } else {
       _state = PAYLOAD;
     }
   }
 
-  void _messageFrameEnd() {
+  void _messageFrameEnd(EventSink sink) {
     if (_fin) {
-      if (onMessageEnd != null) onMessageEnd();
+      switch (_currentMessageType) {
+        case _WebSocketMessageType.TEXT:
+          sink.add(_buffer.toString());
+          break;
+        case _WebSocketMessageType.BINARY:
+          if (_buffer.length == 0) {
+            sink.add(const []);
+          } else {
+            sink.add(_buffer.readBytes(_buffer.length));
+          }
+          break;
+      }
+      _buffer = null;
       _currentMessageType = _WebSocketMessageType.NONE;
     }
     _prepareForNextFrame();
   }
 
-  void _controlFrameEnd() {
+  void _controlFrameEnd(EventSink sink) {
     switch (_opcode) {
       case _WebSocketOpcode.CLOSE:
-        int status = WebSocketStatus.NO_STATUS_RECEIVED;
-        String reason = "";
+        closeCode = WebSocketStatus.NO_STATUS_RECEIVED;
         if (_controlPayload.length > 0) {
           if (_controlPayload.length == 1) {
             throw new WebSocketException("Protocol error");
           }
-          status = _controlPayload[0] << 8 | _controlPayload[1];
-          if (status == WebSocketStatus.NO_STATUS_RECEIVED) {
+          closeCode = _controlPayload[0] << 8 | _controlPayload[1];
+          if (closeCode == WebSocketStatus.NO_STATUS_RECEIVED) {
             throw new WebSocketException("Protocol error");
           }
           if (_controlPayload.length > 2) {
-            reason = _decodeString(
-                _controlPayload.getRange(2, _controlPayload.length - 2));
+            closeReason = _decodeString(
+                _controlPayload.sublist(2));
           }
         }
-        if (onClosed != null) onClosed(status, reason);
         _state = CLOSED;
+        sink.close();
         break;
 
       case _WebSocketOpcode.PING:
-        if (onPing != null) onPing(_controlPayload);
+        // TODO(ajohnsen): Handle ping.
         break;
 
       case _WebSocketOpcode.PONG:
-        if (onPong != null) onPong(_controlPayload);
+        // TODO(ajohnsen): Handle pong.
         break;
     }
     _prepareForNextFrame();
@@ -347,13 +347,10 @@
 
   int _currentMessageType;
   List<int> _controlPayload;
+  var _buffer;  // Either StringBuffer or _BufferList.
 
-  Function onMessageStart;
-  Function onMessageData;
-  Function onMessageEnd;
-  Function onPing;
-  Function onPong;
-  Function onClosed;
+  int closeCode = WebSocketStatus.NO_STATUS_RECEIVED;
+  String closeReason = "";
 }
 
 
@@ -365,7 +362,7 @@
     stream.listen((request) {
         _upgrade(request)
             .then((WebSocket webSocket) => _controller.add(webSocket))
-            .catchError((error) => _controller.signalError(error));
+            .catchError((error) => _controller.addError(error));
     });
 
     return _controller.stream;
@@ -430,9 +427,6 @@
 class _WebSocketImpl extends Stream implements WebSocket {
   final StreamController _controller = new StreamController();
 
-  final _WebSocketProtocolProcessor _processor =
-      new _WebSocketProtocolProcessor();
-
   final Socket _socket;
   int _readyState = WebSocket.CONNECTING;
   bool _writeClosed = false;
@@ -514,61 +508,45 @@
   _WebSocketImpl._fromSocket(Socket this._socket) {
     _readyState = WebSocket.OPEN;
 
-    int type;
-    var data;
-    _processor.onMessageStart = (int t) {
-      type = t;
-      if (type == _WebSocketMessageType.TEXT) {
-        data = new StringBuffer();
-      } else {
-        data = [];
-      }
-    };
-    _processor.onMessageData = (buffer, offset, count) {
-      if (type == _WebSocketMessageType.TEXT) {
-        data.add(_decodeString(buffer.getRange(offset, count)));
-      } else {
-        data.addAll(buffer.getRange(offset, count));
-      }
-    };
-    _processor.onMessageEnd = () {
-      if (type == _WebSocketMessageType.TEXT) {
-        _controller.add(data.toString());
-      } else {
-        _controller.add(data);
-      }
-    };
-    _processor.onClosed = (code, reason) {
-      bool clean = true;
-      if (_readyState == WebSocket.OPEN) {
-        _readyState = WebSocket.CLOSING;
-        if (code != WebSocketStatus.NO_STATUS_RECEIVED) {
-          _close(code);
-        } else {
-          _close();
-          clean = false;
-        }
-        _readyState = WebSocket.CLOSED;
-      }
-      if (_readyState == WebSocket.CLOSED) return;
-      _closeCode = code;
-      _closeReason = reason;
-      _controller.close();
-    };
-
-    _socket.listen(
-        (data) => _processor.update(data, 0, data.length),
-        onDone: () => _processor.closed(),
-        onError: (error) => _controller.signalError(error));
+    bool closed = false;
+    var transformer = new _WebSocketProtocolTransformer();
+    _socket.transform(transformer).listen(
+        (data) {
+          _controller.add(data);
+        },
+        onError: (error) {
+          if (closed) return;
+          closed = true;
+          _controller.addError(error);
+          _controller.close();
+        },
+        onDone: () {
+          if (closed) return;
+          closed = true;
+          if (_readyState == WebSocket.OPEN) {
+            _readyState = WebSocket.CLOSING;
+            if (transformer.closeCode != WebSocketStatus.NO_STATUS_RECEIVED) {
+              _close(transformer.closeCode);
+            } else {
+              _close();
+            }
+            _readyState = WebSocket.CLOSED;
+          }
+          _closeCode = transformer.closeCode;
+          _closeReason = transformer.closeReason;
+          _controller.close();
+          if (_writeClosed) _socket.destroy();
+        },
+        unsubscribeOnError: true);
 
     _socket.done
         .catchError((error) {
-          if (_readyState == WebSocket.CLOSED) return;
+          if (closed) return;
+          closed = true;
           _readyState = WebSocket.CLOSED;
-          _closeCode = ABNORMAL_CLOSURE;
-          _controller.signalError(error);
+          _closeCode = WebSocketStatus.ABNORMAL_CLOSURE;
+          _controller.addError(error);
           _controller.close();
-          _socket.destroy();
         })
         .whenComplete(() {
           _writeClosed = true;
@@ -648,12 +626,7 @@
     } else {
       opcode = _WebSocketOpcode.TEXT;
     }
-    try {
-      _sendFrame(opcode, data);
-    } catch (_) {
-      // The socket can be closed before _socket.done have a chance
-      // to complete.
-    }
+    _sendFrame(opcode, data);
   }
 
   void _sendFrame(int opcode, [List<int> data]) {
@@ -686,9 +659,15 @@
       header[index++] = dataLength >> (((lengthBytes - 1) - i) * 8) & 0xFF;
     }
     assert(index == headerSize);
-    _socket.add(header);
-    if (data != null) {
-      _socket.add(data);
+    try {
+      _socket.writeBytes(header);
+      if (data != null) {
+        _socket.writeBytes(data);
+      }
+    } catch (_) {
+      // The socket can be closed before _socket.done have a chance
+      // to complete.
+      _writeClosed = true;
     }
   }
 }
diff --git a/sdk/lib/isolate/isolate_stream.dart b/sdk/lib/isolate/isolate_stream.dart
index d72389f..4cb39f1 100644
--- a/sdk/lib/isolate/isolate_stream.dart
+++ b/sdk/lib/isolate/isolate_stream.dart
@@ -126,6 +126,7 @@
  * [IsolateSink]s can be transmitted to other isolates.
  */
 class IsolateSink extends StreamSink<dynamic> {
+  // TODO(8997): Implement EventSink instead.
   bool _isClosed = false;
   final SendPort _port;
   IsolateSink._fromPort(this._port);
@@ -149,7 +150,7 @@
     _port.send(mangled);
   }
 
-  void signalError(AsyncError errorEvent) {
+  void addError(AsyncError errorEvent) {
     throw new UnimplementedError("signalError on isolate streams");
   }
 
diff --git a/sdk/lib/json/json_base.dart b/sdk/lib/json/json_base.dart
index 5432e5aa..8faa30e 100644
--- a/sdk/lib/json/json_base.dart
+++ b/sdk/lib/json/json_base.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+part of dart.json;
+
 // JSON parsing and serialization.
 
 /**
@@ -708,7 +710,7 @@
         charCodes.add(charCode);
       }
     }
-    sb.add(needsEscape ? new String.fromCharCodes(charCodes) : s);
+    sb.write(needsEscape ? new String.fromCharCodes(charCodes) : s);
   }
 
   void checkCycle(final object) {
@@ -748,54 +750,54 @@
   bool stringifyJsonValue(final object) {
     if (object is num) {
       // TODO: use writeOn.
-      sb.add(numberToString(object));
+      sb.write(numberToString(object));
       return true;
     } else if (identical(object, true)) {
-      sb.add('true');
+      sb.write('true');
       return true;
     } else if (identical(object, false)) {
-      sb.add('false');
+      sb.write('false');
        return true;
     } else if (object == null) {
-      sb.add('null');
+      sb.write('null');
       return true;
     } else if (object is String) {
-      sb.add('"');
+      sb.write('"');
       escape(sb, object);
-      sb.add('"');
+      sb.write('"');
       return true;
     } else if (object is List) {
       checkCycle(object);
       List a = object;
-      sb.add('[');
+      sb.write('[');
       if (a.length > 0) {
         stringifyValue(a[0]);
         // TODO: switch to Iterables.
         for (int i = 1; i < a.length; i++) {
-          sb.add(',');
+          sb.write(',');
           stringifyValue(a[i]);
         }
       }
-      sb.add(']');
+      sb.write(']');
       seen.removeLast();
       return true;
     } else if (object is Map) {
       checkCycle(object);
       Map<String, Object> m = object;
-      sb.add('{');
+      sb.write('{');
       bool first = true;
       m.forEach((String key, Object value) {
         if (!first) {
-          sb.add(',"');
+          sb.write(',"');
         } else {
-          sb.add('"');
+          sb.write('"');
         }
         escape(sb, key);
-        sb.add('":');
+        sb.write('":');
         stringifyValue(value);
         first = false;
       });
-      sb.add('}');
+      sb.write('}');
       seen.removeLast();
       return true;
     } else {
diff --git a/sdk/lib/mirrors/mirrors_impl.dart b/sdk/lib/mirrors/mirrors_impl.dart
index 73f79c2..b49c40e 100644
--- a/sdk/lib/mirrors/mirrors_impl.dart
+++ b/sdk/lib/mirrors/mirrors_impl.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+part of dart.mirrors;
+
 /**
  * A [MirrorSystem] is the main interface used to reflect on a set of
  * associated libraries.
diff --git a/sdk/lib/svg/dart2js/svg_dart2js.dart b/sdk/lib/svg/dart2js/svg_dart2js.dart
index 0784b5a..dea8a56 100644
--- a/sdk/lib/svg/dart2js/svg_dart2js.dart
+++ b/sdk/lib/svg/dart2js/svg_dart2js.dart
@@ -755,7 +755,7 @@
 
   @DomName('SVGColor.rgbColor')
   @DocsEditable
-  final RgbColor rgbColor;
+  final CssRgbColor rgbColor;
 
   @DomName('SVGColor.setColor')
   @DocsEditable
@@ -3112,16 +3112,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Length firstMatching(bool test(Length value), { Length orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Length firstWhere(bool test(Length value), { Length orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Length lastMatching(bool test(Length value), {Length orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Length lastWhere(bool test(Length value), {Length orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Length singleMatching(bool test(Length value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Length singleWhere(bool test(Length value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Length elementAt(int index) {
@@ -3187,6 +3187,10 @@
   Length max([int compare(Length a, Length b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, Length element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   Length removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -3207,11 +3211,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(Length element)) {
+  void removeWhere(bool test(Length element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(Length element)) {
+  void retainWhere(bool test(Length element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -3227,8 +3231,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<Length> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <Length>[]);
+  }
+
   List<Length> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Length>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, Length> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<Length> mixins.
 
@@ -3738,16 +3750,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Number firstMatching(bool test(Number value), { Number orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Number firstWhere(bool test(Number value), { Number orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Number lastMatching(bool test(Number value), {Number orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Number lastWhere(bool test(Number value), {Number orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Number singleMatching(bool test(Number value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Number singleWhere(bool test(Number value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Number elementAt(int index) {
@@ -3813,6 +3825,10 @@
   Number max([int compare(Number a, Number b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, Number element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   Number removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -3833,11 +3849,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(Number element)) {
+  void removeWhere(bool test(Number element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(Number element)) {
+  void retainWhere(bool test(Number element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -3853,8 +3869,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<Number> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <Number>[]);
+  }
+
   List<Number> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Number>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, Number> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<Number> mixins.
 
@@ -4640,16 +4664,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  PathSeg firstMatching(bool test(PathSeg value), { PathSeg orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  PathSeg firstWhere(bool test(PathSeg value), { PathSeg orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  PathSeg lastMatching(bool test(PathSeg value), {PathSeg orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  PathSeg lastWhere(bool test(PathSeg value), {PathSeg orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  PathSeg singleMatching(bool test(PathSeg value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  PathSeg singleWhere(bool test(PathSeg value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   PathSeg elementAt(int index) {
@@ -4715,6 +4739,10 @@
   PathSeg max([int compare(PathSeg a, PathSeg b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, PathSeg element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   PathSeg removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -4735,11 +4763,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(PathSeg element)) {
+  void removeWhere(bool test(PathSeg element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(PathSeg element)) {
+  void retainWhere(bool test(PathSeg element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -4755,8 +4783,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<PathSeg> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <PathSeg>[]);
+  }
+
   List<PathSeg> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <PathSeg>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, PathSeg> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<PathSeg> mixins.
 
@@ -5447,9 +5483,10 @@
   @DocsEditable
   factory StopElement() => _SvgElementFactoryProvider.createSvgElement_tag("stop");
 
+  @JSName('offset')
   @DomName('SVGStopElement.offset')
   @DocsEditable
-  final AnimatedNumber offset;
+  final AnimatedNumber gradientOffset;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -5526,16 +5563,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  String firstMatching(bool test(String value), { String orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  String firstWhere(bool test(String value), { String orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  String lastMatching(bool test(String value), {String orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  String lastWhere(bool test(String value), {String orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  String singleMatching(bool test(String value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  String singleWhere(bool test(String value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   String elementAt(int index) {
@@ -5601,6 +5638,10 @@
   String max([int compare(String a, String b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, String element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   String removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -5621,11 +5662,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(String element)) {
+  void removeWhere(bool test(String element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(String element)) {
+  void retainWhere(bool test(String element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -5641,8 +5682,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<String> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <String>[]);
+  }
+
   List<String> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <String>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, String> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<String> mixins.
 
@@ -6690,16 +6739,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Transform firstMatching(bool test(Transform value), { Transform orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Transform firstWhere(bool test(Transform value), { Transform orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Transform lastMatching(bool test(Transform value), {Transform orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Transform lastWhere(bool test(Transform value), {Transform orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Transform singleMatching(bool test(Transform value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Transform singleWhere(bool test(Transform value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Transform elementAt(int index) {
@@ -6765,6 +6814,10 @@
   Transform max([int compare(Transform a, Transform b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, Transform element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   Transform removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -6785,11 +6838,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(Transform element)) {
+  void removeWhere(bool test(Transform element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(Transform element)) {
+  void retainWhere(bool test(Transform element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -6805,8 +6858,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<Transform> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <Transform>[]);
+  }
+
   List<Transform> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Transform>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, Transform> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<Transform> mixins.
 
@@ -7209,16 +7270,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  ElementInstance firstMatching(bool test(ElementInstance value), { ElementInstance orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  ElementInstance firstWhere(bool test(ElementInstance value), { ElementInstance orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  ElementInstance lastMatching(bool test(ElementInstance value), {ElementInstance orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  ElementInstance lastWhere(bool test(ElementInstance value), {ElementInstance orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  ElementInstance singleMatching(bool test(ElementInstance value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  ElementInstance singleWhere(bool test(ElementInstance value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   ElementInstance elementAt(int index) {
@@ -7286,6 +7347,10 @@
   ElementInstance max([int compare(ElementInstance a, ElementInstance b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, ElementInstance element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   ElementInstance removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -7306,11 +7371,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(ElementInstance element)) {
+  void removeWhere(bool test(ElementInstance element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(ElementInstance element)) {
+  void retainWhere(bool test(ElementInstance element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -7326,8 +7391,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<ElementInstance> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <ElementInstance>[]);
+  }
+
   List<ElementInstance> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <ElementInstance>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, ElementInstance> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<ElementInstance> mixins.
 
@@ -7395,9 +7468,10 @@
   @DocsEditable
   final AnimatedNumber intercept;
 
+  @JSName('offset')
   @DomName('SVGComponentTransferFunctionElement.offset')
   @DocsEditable
-  final AnimatedNumber offset;
+  final AnimatedNumber gradientOffset;
 
   @DomName('SVGComponentTransferFunctionElement.slope')
   @DocsEditable
diff --git a/sdk/lib/svg/dartium/svg_dartium.dart b/sdk/lib/svg/dartium/svg_dartium.dart
index d049d13..b6fc12e 100644
--- a/sdk/lib/svg/dartium/svg_dartium.dart
+++ b/sdk/lib/svg/dartium/svg_dartium.dart
@@ -857,7 +857,7 @@
 
   @DomName('SVGColor.rgbColor')
   @DocsEditable
-  RgbColor get rgbColor native "SVGColor_rgbColor_Getter";
+  CssRgbColor get rgbColor native "SVGColor_rgbColor_Getter";
 
   @DomName('SVGColor.setColor')
   @DocsEditable
@@ -3375,16 +3375,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Length firstMatching(bool test(Length value), { Length orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Length firstWhere(bool test(Length value), { Length orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Length lastMatching(bool test(Length value), {Length orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Length lastWhere(bool test(Length value), {Length orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Length singleMatching(bool test(Length value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Length singleWhere(bool test(Length value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Length elementAt(int index) {
@@ -3450,6 +3450,10 @@
   Length max([int compare(Length a, Length b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, Length element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   Length removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -3470,11 +3474,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(Length element)) {
+  void removeWhere(bool test(Length element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(Length element)) {
+  void retainWhere(bool test(Length element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -3490,8 +3494,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<Length> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <Length>[]);
+  }
+
   List<Length> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Length>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, Length> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<Length> mixins.
 
@@ -4078,16 +4090,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Number firstMatching(bool test(Number value), { Number orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Number firstWhere(bool test(Number value), { Number orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Number lastMatching(bool test(Number value), {Number orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Number lastWhere(bool test(Number value), {Number orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Number singleMatching(bool test(Number value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Number singleWhere(bool test(Number value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Number elementAt(int index) {
@@ -4153,6 +4165,10 @@
   Number max([int compare(Number a, Number b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, Number element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   Number removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -4173,11 +4189,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(Number element)) {
+  void removeWhere(bool test(Number element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(Number element)) {
+  void retainWhere(bool test(Number element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -4193,8 +4209,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<Number> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <Number>[]);
+  }
+
   List<Number> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Number>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, Number> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<Number> mixins.
 
@@ -5257,16 +5281,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  PathSeg firstMatching(bool test(PathSeg value), { PathSeg orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  PathSeg firstWhere(bool test(PathSeg value), { PathSeg orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  PathSeg lastMatching(bool test(PathSeg value), {PathSeg orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  PathSeg lastWhere(bool test(PathSeg value), {PathSeg orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  PathSeg singleMatching(bool test(PathSeg value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  PathSeg singleWhere(bool test(PathSeg value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   PathSeg elementAt(int index) {
@@ -5332,6 +5356,10 @@
   PathSeg max([int compare(PathSeg a, PathSeg b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, PathSeg element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   PathSeg removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -5352,11 +5380,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(PathSeg element)) {
+  void removeWhere(bool test(PathSeg element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(PathSeg element)) {
+  void retainWhere(bool test(PathSeg element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -5372,8 +5400,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<PathSeg> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <PathSeg>[]);
+  }
+
   List<PathSeg> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <PathSeg>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, PathSeg> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<PathSeg> mixins.
 
@@ -6160,7 +6196,7 @@
 
   @DomName('SVGStopElement.offset')
   @DocsEditable
-  AnimatedNumber get offset native "SVGStopElement_offset_Getter";
+  AnimatedNumber get gradientOffset native "SVGStopElement_offset_Getter";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6241,16 +6277,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  String firstMatching(bool test(String value), { String orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  String firstWhere(bool test(String value), { String orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  String lastMatching(bool test(String value), {String orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  String lastWhere(bool test(String value), {String orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  String singleMatching(bool test(String value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  String singleWhere(bool test(String value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   String elementAt(int index) {
@@ -6316,6 +6352,10 @@
   String max([int compare(String a, String b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, String element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   String removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -6336,11 +6376,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(String element)) {
+  void removeWhere(bool test(String element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(String element)) {
+  void retainWhere(bool test(String element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -6356,8 +6396,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<String> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <String>[]);
+  }
+
   List<String> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <String>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, String> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<String> mixins.
 
@@ -7494,16 +7542,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Transform firstMatching(bool test(Transform value), { Transform orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Transform firstWhere(bool test(Transform value), { Transform orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Transform lastMatching(bool test(Transform value), {Transform orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Transform lastWhere(bool test(Transform value), {Transform orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Transform singleMatching(bool test(Transform value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Transform singleWhere(bool test(Transform value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Transform elementAt(int index) {
@@ -7569,6 +7617,10 @@
   Transform max([int compare(Transform a, Transform b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, Transform element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   Transform removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -7589,11 +7641,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(Transform element)) {
+  void removeWhere(bool test(Transform element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(Transform element)) {
+  void retainWhere(bool test(Transform element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -7609,8 +7661,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<Transform> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <Transform>[]);
+  }
+
   List<Transform> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Transform>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, Transform> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<Transform> mixins.
 
@@ -8067,16 +8127,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  ElementInstance firstMatching(bool test(ElementInstance value), { ElementInstance orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  ElementInstance firstWhere(bool test(ElementInstance value), { ElementInstance orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  ElementInstance lastMatching(bool test(ElementInstance value), {ElementInstance orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  ElementInstance lastWhere(bool test(ElementInstance value), {ElementInstance orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  ElementInstance singleMatching(bool test(ElementInstance value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  ElementInstance singleWhere(bool test(ElementInstance value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   ElementInstance elementAt(int index) {
@@ -8144,6 +8204,10 @@
   ElementInstance max([int compare(ElementInstance a, ElementInstance b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, ElementInstance element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   ElementInstance removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -8164,11 +8228,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(ElementInstance element)) {
+  void removeWhere(bool test(ElementInstance element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(ElementInstance element)) {
+  void retainWhere(bool test(ElementInstance element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -8184,8 +8248,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<ElementInstance> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <ElementInstance>[]);
+  }
+
   List<ElementInstance> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <ElementInstance>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, ElementInstance> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<ElementInstance> mixins.
 
@@ -8271,7 +8343,7 @@
 
   @DomName('SVGComponentTransferFunctionElement.offset')
   @DocsEditable
-  AnimatedNumber get offset native "SVGComponentTransferFunctionElement_offset_Getter";
+  AnimatedNumber get gradientOffset native "SVGComponentTransferFunctionElement_offset_Getter";
 
   @DomName('SVGComponentTransferFunctionElement.slope')
   @DocsEditable
diff --git a/sdk/lib/typeddata/typeddata.dart b/sdk/lib/typeddata/typeddata.dart
new file mode 100644
index 0000000..efaf880
--- /dev/null
+++ b/sdk/lib/typeddata/typeddata.dart
@@ -0,0 +1,9 @@
+// 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 dart.typeddata;
+
+import 'dart:collection';
+
+part 'typeddata_base.dart';
diff --git a/sdk/lib/typeddata/typeddata_base.dart b/sdk/lib/typeddata/typeddata_base.dart
new file mode 100644
index 0000000..f40c403
--- /dev/null
+++ b/sdk/lib/typeddata/typeddata_base.dart
@@ -0,0 +1,681 @@
+// 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.
+
+part of dart.typeddata;
+
+/**
+ * A sequence of bytes underlying a typed data object.
+ * Used to process large quantities of binary or numerical data
+ * more efficiently using a typed view.
+ */
+abstract class ByteBuffer {
+  /**
+   * Returns the length of this byte buffer, in bytes.
+   */
+  int get lengthInBytes;
+
+}
+
+
+/**
+ * A typed view of a sequence of bytes.
+ */
+abstract class TypedData {
+  /**
+   * Returns the number of bytes in the representation of each element in this
+   * list.
+   */
+  int get elementSizeInBytes;
+
+  /**
+   * Returns the offset in bytes into the underlying byte buffer of this view.
+   */
+  int get offsetInBytes;
+
+  /**
+   * Returns the length of this view, in bytes.
+   */
+  int get lengthInBytes;
+
+  /**
+   * Returns the byte buffer associated with this object.
+   */
+  ByteBuffer get buffer;
+}
+
+
+/**
+ * A fixed-length, random-access sequence of bytes that also provides random
+ * and unaligned access to the fixed-width integers and floating point
+ * numbers represented by those bytes.
+ * ByteData may be used to pack and unpack data from external sources
+ * (such as networks or files systems), and to process large quantities
+ * of numerical data more efficiently than would be possible
+ * with ordinary [List] implementations. ByteData can save space, by
+ * eliminating the need for object headers, and time, by eliminating the
+ * need for data copies. Finally, ByteData may be used to intentionally
+ * reinterpret the bytes representing one arithmetic type as another.
+ * For example this code fragment determine what 32-bit signed integer
+ * is represented by the bytes of a 32-bit floating point number:
+ *
+ *     var buffer = new Uint8List(8).buffer;
+ *     var bdata = new ByteData.view(buffer);
+ *     bdata.setFloat32(0, 3.04);
+ *     int huh = bdata.getInt32(0);
+ */
+abstract class ByteData implements TypedData {
+  /**
+   * Creates a [ByteData] of the specified length (in elements), all of
+   * whose elements are initially zero.
+   */
+  external factory ByteData(int length);
+
+  /**
+   * Creates an [ByteData] _view_ of the specified region in the specified
+   * byte buffer. Changes in the [ByteData] will be visible in the byte
+   * buffer and vice versa. If the [offsetInBytes] index of the region is not
+   * specified, it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to null, which indicates
+   * that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   */
+  external factory ByteData.view(ByteBuffer buffer,
+                                 [int offsetInBytes = 0, int length]);
+
+  /**
+   * Returns the (possibly negative) integer represented by the byte at the
+   * specified [byteOffset] in this object, in two's complement binary
+   * representation. The return value will be between -128 and 127, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * greater than or equal to the length of this object.
+   */
+  int getInt8(int byteOffset);
+
+  /**
+   * Sets the byte at the specified [byteOffset] in this object to the
+   * two's complement binary representation of the specified [value], which
+   * must fit in a single byte. In other words, [value] must be between
+   * -128 and 127, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * greater than or equal to the length of this object.
+   */
+  void setInt8(int byteOffset, int value);
+
+  /**
+   * Returns the positive integer represented by the byte at the specified
+   * [byteOffset] in this object, in unsigned binary form. The
+   * return value will be between 0 and 255, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * greater than or equal to the length of this object.
+   */
+  int getUint8(int byteOffset);
+
+  /**
+   * Sets the byte at the specified [byteOffset] in this object to the
+   * unsigned binary representation of the specified [value], which must fit
+   * in a single byte. in other words, [value] must be between 0 and 255,
+   * inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative,
+   * or greater than or equal to the length of this object.
+   */
+  void setUint8(int byteOffset, int value);
+
+  /**
+   * Returns the (possibly negative) integer represented by the two bytes at
+   * the specified [byteOffset] in this object, in two's complement binary
+   * form.
+   * The return value will be between 2<sup>15</sup> and 2<sup>15</sup> - 1,
+   * inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 2` is greater than the length of this object.
+   */
+  int getInt16(int byteOffset);
+
+  /**
+   * Sets the two bytes starting at the specified [byteOffset] in this
+   * object to the two's complement binary representation of the specified
+   * [value], which must fit in two bytes. In other words, [value] must lie
+   * between 2<sup>15</sup> and 2<sup>15</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 2` is greater than the length of this object.
+   */
+  void setInt16(int byteOffset, int value);
+
+  /**
+   * Returns the positive integer represented by the two bytes starting
+   * at the specified [byteOffset] in this object, in unsigned binary
+   * form.
+   * The return value will be between 0 and  2<sup>16</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 2` is greater than the length of this object.
+   */
+  int getUint16(int byteOffset);
+
+  /**
+   * Sets the two bytes starting at the specified [byteOffset] in this object
+   * to the unsigned binary representation of the specified [value],
+   * which must fit in two bytes. in other words, [value] must be between
+   * 0 and 2<sup>16</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 2` is greater than the length of this object.
+   */
+  void setUint16(int byteOffset, int value);
+
+  /**
+   * Returns the (possibly negative) integer represented by the four bytes at
+   * the specified [byteOffset] in this object, in two's complement binary
+   * form.
+   * The return value will be between 2<sup>31</sup> and 2<sup>31</sup> - 1,
+   * inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 4` is greater than the length of this object.
+   */
+  int getInt32(int byteOffset);
+
+  /**
+   * Sets the four bytes starting at the specified [byteOffset] in this
+   * object to the two's complement binary representation of the specified
+   * [value], which must fit in four bytes. In other words, [value] must lie
+   * between 2<sup>31</sup> and 2<sup>31</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 4` is greater than the length of this object.
+   */
+  void setInt32(int byteOffset, int value);
+
+  /**
+   * Returns the positive integer represented by the four bytes starting
+   * at the specified [byteOffset] in this object, in unsigned binary
+   * form.
+   * The return value will be between 0 and  2<sup>32</sup> - 1, inclusive.
+   *
+   */
+  int getUint32(int byteOffset);
+
+  /**
+   * Sets the four bytes starting at the specified [byteOffset] in this object
+   * to the unsigned binary representation of the specified [value],
+   * which must fit in four bytes. in other words, [value] must be between
+   * 0 and 2<sup>32</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 4` is greater than the length of this object.
+   */
+  void setUint32(int byteOffset, int value);
+
+  /**
+   * Returns the (possibly negative) integer represented by the eight bytes at
+   * the specified [byteOffset] in this object, in two's complement binary
+   * form.
+   * The return value will be between 2<sup>63</sup> and 2<sup>63</sup> - 1,
+   * inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 8` is greater than the length of this object.
+   */
+  int getInt64(int byteOffset);
+
+  /**
+   * Sets the eight bytes starting at the specified [byteOffset] in this
+   * object to the two's complement binary representation of the specified
+   * [value], which must fit in eight bytes. In other words, [value] must lie
+   * between 2<sup>63</sup> and 2<sup>63</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 8` is greater than the length of this object.
+   */
+  void setInt64(int byteOffset, int value);
+
+  /**
+   * Returns the positive integer represented by the eight bytes starting
+   * at the specified [byteOffset] in this object, in unsigned binary
+   * form.
+   * The return value will be between 0 and  2<sup>64</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 8` is greater than the length of this object.
+   */
+  int getUint64(int byteOffset);
+
+  /**
+   * Sets the eight bytes starting at the specified [byteOffset] in this object
+   * to the unsigned binary representation of the specified [value],
+   * which must fit in eight bytes. in other words, [value] must be between
+   * 0 and 2<sup>64</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 8` is greater than the length of this object.
+   */
+  void setUint64(int byteOffset, int value);
+
+  /**
+   * Returns the floating point number represented by the four bytes at
+   * the specified [byteOffset] in this object, in IEEE 754
+   * single-precision binary floating-point format (binary32).
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 4` is greater than the length of this object.
+   */
+  double getFloat32(int byteOffset);
+
+  /**
+   * Sets the four bytes starting at the specified [byteOffset] in this
+   * object to the IEEE 754 single-precision binary floating-point
+   * (binary32) representation of the specified [value].
+   *
+   * **Note that this method can lose precision.** The input [value] is
+   * a 64-bit floating point value, which will be converted to 32-bit
+   * floating point value by IEEE 754 rounding rules before it is stored.
+   * If [value] cannot be represented exactly as a binary32, it will be
+   * converted to the nearest binary32 value.  If two binary32 values are
+   * equally close, the one whose least significant bit is zero will be used.
+   * Note that finite (but large) values can be converted to infinity, and
+   * small non-zero values can be converted to zero.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 4` is greater than the length of this object.
+   */
+  void setFloat32(int byteOffset, double value);
+
+  /**
+   * Returns the floating point number represented by the eight bytes at
+   * the specified [byteOffset] in this object, in IEEE 754
+   * double-precision binary floating-point format (binary64).
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 8` is greater than the length of this object.
+   */
+  double getFloat64(int byteOffset);
+
+  /**
+   * Sets the eight bytes starting at the specified [byteOffset] in this
+   * object to the IEEE 754 double-precision binary floating-point
+   * (binary64) representation of the specified [value].
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 8` is greater than the length of this object.
+   */
+  void setFloat64(int byteOffset, double value);
+}
+
+
+/**
+ * A fixed-length list of 8-bit signed integers.
+ * For long lists, this implementation can be considerably
+ * more space- and time-efficient than the default [List] implementation.
+ */
+abstract class Int8List implements List<int>, TypedData {
+  /**
+   * Creates an [Int8List] of the specified length (in elements), all of
+   * whose elements are initially zero.
+   */
+  external factory Int8List(int length);
+
+  /**
+   * Creates an [Int8List] _view_ of the specified region in the specified
+   * byte buffer. Changes in the [Int8List] will be visible in the byte
+   * buffer and vice versa. If the [offsetInBytes] index of the region is not
+   * specified, it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to null, which indicates
+   * that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   */
+  external factory Int8List.view(ByteBuffer buffer,
+                                 [int offsetInBytes = 0, int length]);
+
+  static const int BYTES_PER_ELEMENT = 1;
+}
+
+
+/**
+ * A fixed-length list of 8-bit unsigned integers.
+ * For long lists, this implementation can be considerably
+ * more space- and time-efficient than the default [List] implementation.
+ */
+abstract class Uint8List implements List<int>, TypedData {
+  /**
+   * Creates a [Uint8List] of the specified length (in elements), all of
+   * whose elements are initially zero.
+   */
+  external factory Uint8List(int length);
+
+  /**
+   * Creates a [Uint8List] _view_ of the specified region in the specified
+   * byte buffer. Changes in the [Uint8List] will be visible in the byte
+   * buffer and vice versa. If the [offsetInBytes] index of the region is not
+   * specified, it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to null, which indicates
+   * that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   */
+  external factory Uint8List.view(ByteBuffer buffer,
+                                  [int offsetInBytes = 0, int length]);
+
+  static const int BYTES_PER_ELEMENT = 1;
+}
+
+
+/**
+ * A fixed-length list of 8-bit unsigned integers.
+ * For long lists, this implementation can be considerably
+ * more space- and time-efficient than the default [List] implementation.
+ * Indexed store clamps the value to range 0..0xFF.
+ */
+abstract class Uint8ClampedList implements List<int>, TypedData {
+  /**
+   * Creates a [Uint8ClampedList] of the specified length (in elements), all of
+   * whose elements are initially zero.
+   */
+  external factory Uint8ClampedList(int length);
+
+  /**
+   * Creates a [Uint8ClampedList] _view_ of the specified region in the
+   * specified byte [buffer]. Changes in the [Uint8List] will be visible in the
+   * byte buffer and vice versa. If the [offsetInBytes] index of the region is
+   * not specified, it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to null, which indicates that
+   * the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   */
+  external factory Uint8ClampedList.view(ByteBuffer buffer,
+                                         [int offsetInBytes = 0, int length]);
+
+  static const int BYTES_PER_ELEMENT = 1;
+}
+
+
+/**
+ * A fixed-length list of 16-bit signed integers that is viewable as a
+ * [TypedData]. For long lists, this implementation can be considerably
+ * more space- and time-efficient than the default [List] implementation.
+ */
+abstract class Int16List implements List<int>, TypedData {
+  /**
+   * Creates an [Int16List] of the specified length (in elements), all of
+   * whose elements are initially zero.
+   */
+  external factory Int16List(int length);
+
+  /**
+   * Creates an [Int16List] _view_ of the specified region in the specified
+   * byte buffer. Changes in the [Int16List] will be visible in the byte
+   * buffer and vice versa. If the [offsetInBytes] index of the region is not
+   * specified, it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to null, which indicates
+   * that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   *
+   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
+   * BYTES_PER_ELEMENT.
+   */
+  external factory Int16List.view(ByteBuffer buffer,
+                                  [int offsetInBytes = 0, int length]);
+
+  static const int BYTES_PER_ELEMENT = 2;
+}
+
+
+/**
+ * A fixed-length list of 16-bit unsigned integers that is viewable as a
+ * [TypedData]. For long lists, this implementation can be considerably
+ * more space- and time-efficient than the default [List] implementation.
+ */
+abstract class Uint16List implements List<int>, TypedData {
+  /**
+   * Creates a [Uint16List] of the specified length (in elements), all
+   * of whose elements are initially zero.
+   */
+  external factory Uint16List(int length);
+
+  /**
+   * Creates a [Uint16List] _view_ of the specified region in
+   * the specified byte buffer. Changes in the [Uint16List] will be
+   * visible in the byte buffer and vice versa. If the [offsetInBytes] index
+   * of the region is not specified, it defaults to zero (the first byte in
+   * the byte buffer). If the length is not specified, it defaults to null,
+   * which indicates that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   *
+   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
+   * BYTES_PER_ELEMENT.
+   */
+  external factory Uint16List.view(ByteBuffer buffer,
+                                   [int offsetInBytes = 0, int length]);
+
+  static const int BYTES_PER_ELEMENT = 2;
+}
+
+
+/**
+ * A fixed-length list of 32-bit signed integers that is viewable as a
+ * [TypedData]. For long lists, this implementation can be considerably
+ * more space- and time-efficient than the default [List] implementation.
+ */
+abstract class Int32List implements List<int>, TypedData {
+  /**
+   * Creates an [Int32List] of the specified length (in elements), all of
+   * whose elements are initially zero.
+   */
+  external factory Int32List(int length);
+
+  /**
+   * Creates an [Int32List] _view_ of the specified region in the specified
+   * byte buffer. Changes in the [Int32List] will be visible in the byte
+   * buffer and vice versa. If the [offsetInBytes] index of the region is not
+   * specified, it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to null, which indicates
+   * that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   *
+   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
+   * BYTES_PER_ELEMENT.
+   */
+  external factory Int32List.view(ByteBuffer buffer,
+                                  [int offsetInBytes = 0, int length]);
+
+  static const int BYTES_PER_ELEMENT = 4;
+}
+
+
+/**
+ * A fixed-length list of 32-bit unsigned integers that is viewable as a
+ * [TypedData]. For long lists, this implementation can be considerably
+ * more space- and time-efficient than the default [List] implementation.
+ */
+abstract class Uint32List implements List<int>, TypedData {
+  /**
+   * Creates a [Uint32List] of the specified length (in elements), all
+   * of whose elements are initially zero.
+   */
+  external factory Uint32List(int length);
+
+  /**
+   * Creates a [Uint32List] _view_ of the specified region in
+   * the specified byte buffer. Changes in the [Uint32] will be
+   * visible in the byte buffer and vice versa. If the [offsetInBytes] index
+   * of the region is not specified, it defaults to zero (the first byte in
+   * the byte buffer). If the length is not specified, it defaults to null,
+   * which indicates that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   *
+   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
+   * BYTES_PER_ELEMENT.
+   */
+  external factory Uint32List.view(ByteBuffer buffer,
+                                   [int offsetInBytes = 0, int length]);
+
+  static const int BYTES_PER_ELEMENT = 4;
+}
+
+
+/**
+ * A fixed-length list of 64-bit signed integers that is viewable as a
+ * [TypedData]. For long lists, this implementation can be considerably
+ * more space- and time-efficient than the default [List] implementation.
+ */
+abstract class Int64List implements List<int>, TypedData {
+  /**
+   * Creates an [Int64List] of the specified length (in elements), all of
+   * whose elements are initially zero.
+   */
+  external factory Int64List(int length);
+
+  /**
+   * Creates an [Int64List] _view_ of the specified region in the specified
+   * byte buffer. Changes in the [Int64List] will be visible in the byte buffer
+   * and vice versa. If the [offsetInBytes] index of the region is not
+   * specified, it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to null, which indicates that
+   * the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   *
+   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
+   * BYTES_PER_ELEMENT.
+   */
+  external factory Int64List.view(ByteBuffer buffer,
+                                  [int offsetInBytes = 0, int length]);
+
+  static const int BYTES_PER_ELEMENT = 8;
+}
+
+
+/**
+ * A fixed-length list of 64-bit unsigned integers that is viewable as a
+ * [TypedData]. For long lists, this implementation can be considerably
+ * more space- and time-efficient than the default [List] implementation.
+ */
+abstract class Uint64List implements List<int>, TypedData {
+  /**
+   * Creates a [Uint64List] of the specified length (in elements), all
+   * of whose elements are initially zero.
+   */
+  external factory Uint64List(int length);
+
+  /**
+   * Creates an [Uint64List] _view_ of the specified region in
+   * the specified byte buffer. Changes in the [Uint64List] will be
+   * visible in the byte buffer and vice versa. If the [offsetInBytes]
+   * index of the region is not specified, it defaults to zero (the first
+   * byte in the byte buffer). If the length is not specified, it defaults
+   * to null, which indicates that the view extends to the end of the byte
+   * buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   *
+   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
+   * BYTES_PER_ELEMENT.
+   */
+  external factory Uint64List.view(ByteBuffer buffer,
+                                   [int offsetInBytes = 0, int length]);
+
+  static const int BYTES_PER_ELEMENT = 8;
+}
+
+
+/**
+ * A fixed-length list of IEEE 754 single-precision binary floating-point
+ * numbers  that is viewable as a [TypedData]. For long lists, this
+ * implementation can be considerably more space- and time-efficient than
+ * the default [List] implementation.
+ */
+abstract class Float32List implements List<double>, TypedData {
+  /**
+   * Creates a [Float32List] of the specified length (in elements), all of
+   * whose elements are initially zero.
+   */
+  external factory Float32List(int length);
+
+  /**
+   * Creates a [Float32List] _view_ of the specified region in the specified
+   * byte buffer. Changes in the [Float32List] will be visible in the byte
+   * buffer and vice versa. If the [offsetInBytes] index of the region is not
+   * specified, it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to null, which indicates
+   * that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   *
+   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
+   * BYTES_PER_ELEMENT.
+   */
+  external factory Float32List.view(ByteBuffer buffer,
+                                    [int offsetInBytes = 0, int length]);
+
+  static const int BYTES_PER_ELEMENT = 4;
+}
+
+
+/**
+ * A fixed-length list of IEEE 754 double-precision binary floating-point
+ * numbers  that is viewable as a [TypedData]. For long lists, this
+ * implementation can be considerably more space- and time-efficient than
+ * the default [List] implementation.
+ */
+abstract class Float64List implements List<double>, TypedData {
+  /**
+   * Creates a [Float64List] of the specified length (in elements), all of
+   * whose elements are initially zero.
+   */
+  external factory Float64List(int length);
+
+  /**
+   * Creates a [Float64List] _view_ of the specified region in the specified
+   * byte buffer. Changes in the [Float64List] will be visible in the byte
+   * buffer and vice versa. If the [offsetInBytes] index of the region is not
+   * specified, it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to null, which indicates
+   * that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   *
+   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
+   * BYTES_PER_ELEMENT.
+   */
+  external factory Float64List.view(ByteBuffer buffer,
+                                    [int offsetInBytes = 0, int length]);
+
+  static const int BYTES_PER_ELEMENT = 8;
+}
diff --git a/sdk/lib/typeddata/typeddata_sources.gypi b/sdk/lib/typeddata/typeddata_sources.gypi
new file mode 100644
index 0000000..7961185
--- /dev/null
+++ b/sdk/lib/typeddata/typeddata_sources.gypi
@@ -0,0 +1,11 @@
+# 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.
+
+{
+  'sources': [
+    'typeddata.dart',
+    # The above file needs to be first as it lists the parts below.
+    'typeddata_base.dart',
+  ],
+}
diff --git a/sdk/lib/uri/encode_decode.dart b/sdk/lib/uri/encode_decode.dart
index 124c803..6cddcc0 100644
--- a/sdk/lib/uri/encode_decode.dart
+++ b/sdk/lib/uri/encode_decode.dart
@@ -116,9 +116,9 @@
   for (int i = 0; i < text.length; i++) {
     int ch = text.codeUnitAt(i);
     if (ch < 128 && ((canonicalTable[ch >> 4] & (1 << (ch & 0x0f))) != 0)) {
-      result.add(text[i]);
+      result.write(text[i]);
     } else if (text[i] == " ") {
-      result.add("+");
+      result.write("+");
     } else {
       if (ch >= 0xD800 && ch < 0xDC00) {
         // Low surrogate. We expect a next char high surrogate.
@@ -132,7 +132,7 @@
         }
       }
       for (int codepoint in codepointsToUtf8([ch])) {
-        result.add(byteToHex(codepoint));
+        result.write(byteToHex(codepoint));
       }
     }
   }
@@ -173,9 +173,9 @@
     String ch = text[i];
     if (ch != '%') {
       if (ch == '+') {
-        result.add(" ");
+        result.write(" ");
       } else {
-        result.add(ch);
+        result.write(ch);
       }
       i++;
     } else {
@@ -190,7 +190,7 @@
           break;
         ch = text[i];
       }
-      result.add(decodeUtf8(codepoints));
+      result.write(decodeUtf8(codepoints));
     }
   }
   return result.toString();
diff --git a/sdk/lib/uri/uri_base.dart b/sdk/lib/uri/uri_base.dart
index c775080..9f228d4 100644
--- a/sdk/lib/uri/uri_base.dart
+++ b/sdk/lib/uri/uri_base.dart
@@ -194,18 +194,18 @@
         "origin is applicable to http/https schemes only. Not \'$scheme\'");
     }
     StringBuffer sb = new StringBuffer();
-    sb.add(scheme);
-    sb.add(":");
+    sb.write(scheme);
+    sb.write(":");
     if (domain == null || domain == "") {
       // TODO(aprelev@gmail.com): Use StateException instead
       throw new ArgumentError("Cannot use origin without a domain");
     }
 
-    sb.add("//");
-    sb.add(domain);
+    sb.write("//");
+    sb.write(domain);
     if (port != 0) {
-      sb.add(":");
-      sb.add(port);
+      sb.write(":");
+      sb.write(port);
     }
     return sb.toString();
   }
@@ -214,15 +214,15 @@
     StringBuffer sb = new StringBuffer();
     _addIfNonEmpty(sb, scheme, scheme, ':');
     if (hasAuthority || (scheme == "file")) {
-      sb.add("//");
+      sb.write("//");
       _addIfNonEmpty(sb, userInfo, userInfo, "@");
-      sb.add(domain == null ? "null" : domain);
+      sb.write(domain == null ? "null" : domain);
       if (port != 0) {
-        sb.add(":");
-        sb.add(port.toString());
+        sb.write(":");
+        sb.write(port.toString());
       }
     }
-    sb.add(path == null ? "null" : path);
+    sb.write(path == null ? "null" : path);
     _addIfNonEmpty(sb, query, "?", query);
     _addIfNonEmpty(sb, fragment, "#", fragment);
     return sb.toString();
@@ -252,8 +252,8 @@
   static void _addIfNonEmpty(StringBuffer sb, String test,
                              String first, String second) {
     if ("" != test) {
-      sb.add(first == null ? "null" : first);
-      sb.add(second == null ? "null" : second);
+      sb.write(first == null ? "null" : first);
+      sb.write(second == null ? "null" : second);
     }
   }
 }
diff --git a/sdk/lib/utf/utf_stream.dart b/sdk/lib/utf/utf_stream.dart
index 71dc76d..1480aa1 100644
--- a/sdk/lib/utf/utf_stream.dart
+++ b/sdk/lib/utf/utf_stream.dart
@@ -22,7 +22,7 @@
 
   _StringDecoder(int this._replacementChar);
 
-  void handleData(List<int> bytes, StreamSink<String> sink) {
+  void handleData(List<int> bytes, EventSink<String> sink) {
     _buffer = <int>[];
     List<int> carry = _carry;
     _carry = null;
@@ -52,7 +52,7 @@
           _carry.addAll(carry);
           _carry.addAll(bytes);
         } else {
-          _carry = bytes.getRange(currentPos, bytes.length - currentPos);
+          _carry = bytes.sublist(currentPos);
         }
         break;
       } else {
@@ -69,7 +69,7 @@
     _buffer = null;
   }
 
-  void handleDone(StreamSink<String> sink) {
+  void handleDone(EventSink<String> sink) {
     if (_carry != null) {
       sink.add(new String.fromCharCodes(
           new List.filled(_carry.length, _replacementChar)));
@@ -142,7 +142,7 @@
 abstract class _StringEncoder
     extends StreamEventTransformer<String, List<int>> {
 
-  void handleData(String data, StreamSink<List<int>> sink) {
+  void handleData(String data, EventSink<List<int>> sink) {
     sink.add(_processString(data));
   }
 
diff --git a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
index 7bc07f1..13d8b36 100644
--- a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
+++ b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
@@ -4,6 +4,7 @@
 import 'dart:collection';
 import 'dart:html';
 import 'dart:html_common';
+import 'dart:_js_helper' show Creates, Returns;
 import 'dart:_foreign_helper' show JS;
 // DO NOT EDIT - unless you are editing documentation as per:
 // https://code.google.com/p/dart/wiki/ContributingHTMLDocumentation
@@ -84,7 +85,9 @@
 
   @DomName('AudioBuffer.getChannelData')
   @DocsEditable
-  Float32Array getChannelData(int channelIndex) native;
+  @Returns('Float32Array')
+  @Creates('Float32Array')
+  List<double> getChannelData(int channelIndex) native;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -267,7 +270,7 @@
 
   @DomName('AudioContext.decodeAudioData')
   @DocsEditable
-  void decodeAudioData(ArrayBuffer audioData, AudioBufferCallback successCallback, [AudioBufferCallback errorCallback]) native;
+  void decodeAudioData(/*ArrayBuffer*/ audioData, AudioBufferCallback successCallback, [AudioBufferCallback errorCallback]) native;
 
   @DomName('AudioContext.startRendering')
   @DocsEditable
@@ -364,6 +367,18 @@
 @DomName('AudioNode')
 class AudioNode native "*AudioNode" {
 
+  @DomName('AudioNode.channelCount')
+  @DocsEditable
+  int channelCount;
+
+  @DomName('AudioNode.channelCountMode')
+  @DocsEditable
+  String channelCountMode;
+
+  @DomName('AudioNode.channelInterpretation')
+  @DocsEditable
+  String channelInterpretation;
+
   @DomName('AudioNode.context')
   @DocsEditable
   final AudioContext context;
@@ -822,7 +837,9 @@
 
   @DomName('WaveShaperNode.curve')
   @DocsEditable
-  Float32Array curve;
+  @Returns('Float32Array')
+  @Creates('Float32Array')
+  List<double> curve;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
diff --git a/sdk/lib/web_audio/dartium/web_audio_dartium.dart b/sdk/lib/web_audio/dartium/web_audio_dartium.dart
index 23ad0a3..59a43ad 100644
--- a/sdk/lib/web_audio/dartium/web_audio_dartium.dart
+++ b/sdk/lib/web_audio/dartium/web_audio_dartium.dart
@@ -5,6 +5,7 @@
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:nativewrappers';
+import 'dart:typeddata' as _typeddata;
 // DO NOT EDIT
 // Auto-generated dart:audio library.
 
@@ -61,15 +62,15 @@
 
   @DomName('AnalyserNode.getByteFrequencyData')
   @DocsEditable
-  void getByteFrequencyData(Uint8Array array) native "AnalyserNode_getByteFrequencyData_Callback";
+  void getByteFrequencyData(List<int> array) native "AnalyserNode_getByteFrequencyData_Callback";
 
   @DomName('AnalyserNode.getByteTimeDomainData')
   @DocsEditable
-  void getByteTimeDomainData(Uint8Array array) native "AnalyserNode_getByteTimeDomainData_Callback";
+  void getByteTimeDomainData(List<int> array) native "AnalyserNode_getByteTimeDomainData_Callback";
 
   @DomName('AnalyserNode.getFloatFrequencyData')
   @DocsEditable
-  void getFloatFrequencyData(Float32Array array) native "AnalyserNode_getFloatFrequencyData_Callback";
+  void getFloatFrequencyData(List<double> array) native "AnalyserNode_getFloatFrequencyData_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -110,7 +111,7 @@
 
   @DomName('AudioBuffer.getChannelData')
   @DocsEditable
-  Float32Array getChannelData(int channelIndex) native "AudioBuffer_getChannelData_Callback";
+  List<double> getChannelData(int channelIndex) native "AudioBuffer_getChannelData_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -267,7 +268,7 @@
     if ((buffer_OR_numberOfChannels is int || buffer_OR_numberOfChannels == null) && (mixToMono_OR_numberOfFrames is int || mixToMono_OR_numberOfFrames == null) && (sampleRate is num || sampleRate == null)) {
       return _createBuffer_1(buffer_OR_numberOfChannels, mixToMono_OR_numberOfFrames, sampleRate);
     }
-    if ((buffer_OR_numberOfChannels is ArrayBuffer || buffer_OR_numberOfChannels == null) && (mixToMono_OR_numberOfFrames is bool || mixToMono_OR_numberOfFrames == null) && !?sampleRate) {
+    if ((buffer_OR_numberOfChannels is ArrayBuffer || buffer_OR_numberOfChannels is _typeddata.ByteBuffer || buffer_OR_numberOfChannels == null) && (mixToMono_OR_numberOfFrames is bool || mixToMono_OR_numberOfFrames == null) && !?sampleRate) {
       return _createBuffer_2(buffer_OR_numberOfChannels, mixToMono_OR_numberOfFrames);
     }
     throw new ArgumentError("Incorrect number or type of arguments");
@@ -390,11 +391,11 @@
 
   @DomName('AudioContext.createWaveTable')
   @DocsEditable
-  WaveTable createWaveTable(Float32Array real, Float32Array imag) native "AudioContext_createWaveTable_Callback";
+  WaveTable createWaveTable(List<double> real, List<double> imag) native "AudioContext_createWaveTable_Callback";
 
   @DomName('AudioContext.decodeAudioData')
   @DocsEditable
-  void decodeAudioData(ArrayBuffer audioData, AudioBufferCallback successCallback, [AudioBufferCallback errorCallback]) native "AudioContext_decodeAudioData_Callback";
+  void decodeAudioData(/*ArrayBuffer*/ audioData, AudioBufferCallback successCallback, [AudioBufferCallback errorCallback]) native "AudioContext_decodeAudioData_Callback";
 
   @DomName('AudioContext.startRendering')
   @DocsEditable
@@ -488,6 +489,30 @@
 class AudioNode extends NativeFieldWrapperClass1 {
   AudioNode.internal();
 
+  @DomName('AudioNode.channelCount')
+  @DocsEditable
+  int get channelCount native "AudioNode_channelCount_Getter";
+
+  @DomName('AudioNode.channelCount')
+  @DocsEditable
+  void set channelCount(int value) native "AudioNode_channelCount_Setter";
+
+  @DomName('AudioNode.channelCountMode')
+  @DocsEditable
+  String get channelCountMode native "AudioNode_channelCountMode_Getter";
+
+  @DomName('AudioNode.channelCountMode')
+  @DocsEditable
+  void set channelCountMode(String value) native "AudioNode_channelCountMode_Setter";
+
+  @DomName('AudioNode.channelInterpretation')
+  @DocsEditable
+  String get channelInterpretation native "AudioNode_channelInterpretation_Getter";
+
+  @DomName('AudioNode.channelInterpretation')
+  @DocsEditable
+  void set channelInterpretation(String value) native "AudioNode_channelInterpretation_Setter";
+
   @DomName('AudioNode.context')
   @DocsEditable
   AudioContext get context native "AudioNode_context_Getter";
@@ -587,7 +612,7 @@
 
   @DomName('AudioParam.setValueCurveAtTime')
   @DocsEditable
-  void setValueCurveAtTime(Float32Array values, num time, num duration) native "AudioParam_setValueCurveAtTime_Callback";
+  void setValueCurveAtTime(List<double> values, num time, num duration) native "AudioParam_setValueCurveAtTime_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -678,7 +703,7 @@
 
   @DomName('BiquadFilterNode.getFrequencyResponse')
   @DocsEditable
-  void getFrequencyResponse(Float32Array frequencyHz, Float32Array magResponse, Float32Array phaseResponse) native "BiquadFilterNode_getFrequencyResponse_Callback";
+  void getFrequencyResponse(List<double> frequencyHz, List<double> magResponse, List<double> phaseResponse) native "BiquadFilterNode_getFrequencyResponse_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -1092,11 +1117,11 @@
 
   @DomName('WaveShaperNode.curve')
   @DocsEditable
-  Float32Array get curve native "WaveShaperNode_curve_Getter";
+  List<double> get curve native "WaveShaperNode_curve_Getter";
 
   @DomName('WaveShaperNode.curve')
   @DocsEditable
-  void set curve(Float32Array value) native "WaveShaperNode_curve_Setter";
+  void set curve(List<double> value) native "WaveShaperNode_curve_Setter";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
diff --git a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
index 7b68ee5..c0df4c9 100644
--- a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
+++ b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
@@ -306,16 +306,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Map firstMatching(bool test(Map value), { Map orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Map firstWhere(bool test(Map value), { Map orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Map lastMatching(bool test(Map value), {Map orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Map lastWhere(bool test(Map value), {Map orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Map singleMatching(bool test(Map value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Map singleWhere(bool test(Map value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Map elementAt(int index) {
@@ -383,6 +383,10 @@
   Map max([int compare(Map a, Map b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, Map element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   Map removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -403,11 +407,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(Map element)) {
+  void removeWhere(bool test(Map element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(Map element)) {
+  void retainWhere(bool test(Map element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -423,8 +427,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<Map> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <Map>[]);
+  }
+
   List<Map> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Map>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, Map> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<Map> mixins.
 
diff --git a/sdk/lib/web_sql/dartium/web_sql_dartium.dart b/sdk/lib/web_sql/dartium/web_sql_dartium.dart
index c6b7de5..e984c16 100644
--- a/sdk/lib/web_sql/dartium/web_sql_dartium.dart
+++ b/sdk/lib/web_sql/dartium/web_sql_dartium.dart
@@ -328,16 +328,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Map firstMatching(bool test(Map value), { Map orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Map firstWhere(bool test(Map value), { Map orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Map lastMatching(bool test(Map value), {Map orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Map lastWhere(bool test(Map value), {Map orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Map singleMatching(bool test(Map value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Map singleWhere(bool test(Map value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Map elementAt(int index) {
@@ -405,6 +405,10 @@
   Map max([int compare(Map a, Map b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, Map element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   Map removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -425,11 +429,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test(Map element)) {
+  void removeWhere(bool test(Map element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test(Map element)) {
+  void retainWhere(bool test(Map element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -445,8 +449,16 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<Map> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <Map>[]);
+  }
+
   List<Map> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Map>[]);
+      sublist(start, start + rangeLength);
+
+  Map<int, Map> asMap() =>
+    IterableMixinWorkaround.asMapList(this);
 
   // -- end List<Map> mixins.
 
diff --git a/tests/co19/co19-compiler.status b/tests/co19/co19-compiler.status
index 5038551..b850e58 100644
--- a/tests/co19/co19-compiler.status
+++ b/tests/co19/co19-compiler.status
@@ -105,8 +105,8 @@
 LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A02_t01: Fail # co19 issue 372 (@static-clean where type warnings are expected)
 LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A06_t01: Fail # co19 issue 372 (@static-clean where type warnings are expected)
 
-
-
+LibTest/core/Set/intersection_A01_t01: Fail # issue 390
+LibTest/core/Set/intersection_A01_t02: Pass # issue 390
 
 Language/11_Expressions/30_Identifier_Reference_A01_t08: Skip # testing framework or VM issue 7388 (dies on Turkish character)
 
@@ -238,7 +238,6 @@
 Language/11_Expressions/29_Assignable_Expressions_A01_t09: Fail, OK # TODO(ahe): This test is failing after correctly implementing static warning checks in co19 test suite. The co19 authors have informed me that some of these failures are due to bugs in the test suite.
 Language/11_Expressions/29_Assignable_Expressions_A01_t26: Fail, OK # TODO(ahe): This test is failing after correctly implementing static warning checks in co19 test suite. The co19 authors have informed me that some of these failures are due to bugs in the test suite.
 Language/11_Expressions/30_Identifier_Reference_A02_t01: Fail, OK # TODO(ahe): This test is failing after correctly implementing static warning checks in co19 test suite. The co19 authors have informed me that some of these failures are due to bugs in the test suite.
-Language/11_Expressions/30_Identifier_Reference_A07_t01: Fail, OK # TODO(ahe): This test is failing after correctly implementing static warning checks in co19 test suite. The co19 authors have informed me that some of these failures are due to bugs in the test suite.
 Language/11_Expressions/30_Identifier_Reference_A08_t02: Fail, OK # TODO(ahe): This test is failing after correctly implementing static warning checks in co19 test suite. The co19 authors have informed me that some of these failures are due to bugs in the test suite.
 Language/12_Statements/04_Local_Function_Declaration_A01_t01: Fail, OK # TODO(ahe): This test is failing after correctly implementing static warning checks in co19 test suite. The co19 authors have informed me that some of these failures are due to bugs in the test suite.
 Language/12_Statements/06_For/1_For_Loop_A01_t07: Fail, OK # TODO(ahe): This test is failing after correctly implementing static warning checks in co19 test suite. The co19 authors have informed me that some of these failures are due to bugs in the test suite.
@@ -493,5 +492,79 @@
 LibTest/core/String/charCodes_A01_t01: Fail # Deprecated string members removed (issue 382).
 LibTest/core/String/splitChars_A01_t01: Fail # Deprecated string members removed (issue 382).
 
-[ $runtime == drt && ($compiler == none || $compiler == frog) ]
+LibTest/core/StringBuffer/addAll_A01_t02: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/StringBuffer/addAll_A03_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/StringBuffer/add_A01_t02: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/StringBuffer/add_A01_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/StringBuffer/addAll_A01_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/StringBuffer/toString_A01_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A03_t02: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A04_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A08_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A06_t02: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A07_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A08_t02: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A09_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/14_Function_Invocation/1_Actual_Argument_List_Evaluation_A02_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A04_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/15_Method_Invocation/3_Static_Invocation_A04_t05: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A02_t04: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/05_Strings/1_String_Interpolation_A03_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/05_Strings/1_String_Interpolation_A04_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+
+Language/14_Types/6_Type_dynamic_A03_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.fromMillisecondsSinceEpoch_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.fromMillisecondsSinceEpoch_A01_t02: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.fromMillisecondsSinceEpoch_A02_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.fromString_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.fromString_A01_t02: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.fromString_A02_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.fromString_A03_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.now_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.now_A01_t02: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.now_A01_t03: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.utc_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date_A01_t02: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date_A01_t03: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date_A01_t04: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/add_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/add_A02_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/add_A03_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/add_A05_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/compareTo_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/compareTo_A01_t02: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/compareTo_A02_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/day_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/difference_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/difference_A01_t02: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/difference_A02_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/hour_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/isUtc_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/millisecond_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/millisecondsSinceEpoch_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/minute_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/month_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/operator_GE_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/operator_GT_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/operator_LE_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/operator_LT_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/operator_equality_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/second_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/subtract_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/subtract_A02_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/subtract_A03_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/subtract_A05_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/timeZoneName_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/timeZoneOffset_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/toLocal_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/toString_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/toString_A02_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/toUtc_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/weekday_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/year_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+
+LibTest/core/int/operator_division_A01_t01: Fail # truncate/ceil/floor/round returns ints, issue 389
+
+[ $runtime == drt && $compiler == none ]
 *: Skip
diff --git a/tests/co19/co19-dart2dart.status b/tests/co19/co19-dart2dart.status
index 0445889..fdd3ad2 100644
--- a/tests/co19/co19-dart2dart.status
+++ b/tests/co19/co19-dart2dart.status
@@ -81,14 +81,11 @@
 Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t02: Fail # Inherited from VM (circular initialization?).
 Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t05: Fail # Inherited from dart2js
 Language/06_Functions/06_Functions_A01_t22: Fail # inherited from VM
-Language/06_Functions/06_Functions_A01_t31: Fail # http://dartbug.com/5519
-Language/06_Functions/1_Function_Declaration_A01_t01: Fail # http://dartbug.com/5519
 Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t03: Fail # http://dartbug.com/5519
 Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t04: Fail # http://dartbug.com/5519
 Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t05: Fail # http://dartbug.com/5519
 Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t06: Fail # http://dartbug.com/5519
 Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t07: Fail # http://dartbug.com/5519
-Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A01_t01: Fail # inherited from dart2js
 Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A01_t06: Fail # http://dartbug.com/5519
 Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A01_t07: Fail # http://dartbug.com/5519
 Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A01_t10: Fail # http://dartbug.com/5519
@@ -355,7 +352,7 @@
 Language/15_Reference/1_Lexical_Rules/1_Reserved_Words_A40_t04: Fail # inherited from dart2js
 Language/15_Reference/1_Lexical_Rules_A02_t06: Fail # inherited from dart2js
 LibTest/core/Date/Date.fromMillisecondsSinceEpoch_A03_t01: Fail # Inherited from dart2js
-LibTest/core/Date/Date.fromString_A03_t01: Fail, OK # Issue co19 - 121
+LibTest/core/Date/Date.fromString_A03_t01: Pass, OK # Issue co19 - 121 (currently passing due to co19 issues 373 and 374)
 LibTest/core/Date/toString_A02_t01: Fail, OK # inherited from VM
 LibTest/core/Date/year_A01_t01: Fail, OK # inherited from VM
 LibTest/core/LinkedHashMap/LinkedHashMap_class_A01_t01: Fail, OK # co19 issue 293
@@ -639,6 +636,49 @@
 LibTest/core/Set/Set.from_A01_t01: Fail # Moved collection classes from core to collection. co19 issue 371.
 Language/14_Types/4_Interface_Types_A08_t06: Fail # Moved collection classes from core to collection. co19 issue 371.
 
+Language/14_Types/6_Type_dynamic_A03_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.fromMillisecondsSinceEpoch_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.fromMillisecondsSinceEpoch_A01_t02: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.fromMillisecondsSinceEpoch_A03_t01: pass
+LibTest/core/Date/Date.fromString_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.fromString_A01_t02: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.fromString_A03_t01: pass
+LibTest/core/Date/Date.now_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.now_A01_t02: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.now_A01_t03: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.utc_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date_A01_t03: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date_A01_t04: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/add_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/add_A02_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/add_A03_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/compareTo_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/compareTo_A01_t02: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/day_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/difference_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/difference_A01_t02: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/hour_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/isUtc_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/millisecond_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/millisecondsSinceEpoch_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/minute_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/month_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/operator_GE_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/operator_GT_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/operator_LE_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/operator_LT_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/second_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/subtract_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/subtract_A02_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/subtract_A03_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/timeZoneName_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/timeZoneOffset_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/toLocal_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/toString_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/toUtc_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/weekday_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+
 LibTest/core/Strings/join_A01_t01: Fail # Strings class has been removed. co19 issue 380
 LibTest/core/Strings/join_A04_t01: Fail # Strings class has been removed. co19 issue 380
 LibTest/core/Strings/concatAll_A01_t01: Fail # Strings class has been removed. co19 issue 380
@@ -669,3 +709,33 @@
 LibTest/core/String/charCodeAt_A03_t01: Fail # Deprecated string members removed (issue 382).
 LibTest/core/String/charCodeAt_A01_t01: Fail # Deprecated string members removed (issue 382).
 LibTest/core/String/splitChars_A01_t01: Fail # Deprecated string members removed (issue 382).
+
+LibTest/core/StringBuffer/addAll_A01_t02: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/StringBuffer/add_A01_t02: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/StringBuffer/add_A01_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/StringBuffer/addAll_A01_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/StringBuffer/toString_A01_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A03_t02: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A04_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/12_Statements/01_Blocks_A01_t03: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/14_Function_Invocation/1_Actual_Argument_List_Evaluation_A02_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/11_Instance_Creation/1_New_A09_t12: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/11_Instance_Creation/1_New_A09_t05: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/11_Instance_Creation/1_New_A13_t03: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/11_Instance_Creation/1_New_A09_t06: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A04_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/15_Method_Invocation/3_Static_Invocation_A04_t05: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A02_t04: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/05_Strings/1_String_Interpolation_A03_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/05_Strings/1_String_Interpolation_A04_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+
+LibTest/core/double/ceil_A01_t03: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/double/ceil_A01_t04: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/double/floor_A01_t03: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/double/floor_A01_t04: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/double/round_A01_t02: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/double/round_A01_t04: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/double/truncate_A01_t03: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/double/truncate_A01_t04: Fail # truncate/ceil/floor/round returns ints, issue 389
+
+LibTest/core/List/getRange_A02_t01: Fail # issue 391
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index ccc970e..5210805 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -43,11 +43,8 @@
 Language/07_Classes/6_Constructors_A01_t04: Fail # TODO(ahe): Please triage this failure.
 Language/07_Classes/6_Constructors_A01_t05: Fail # TODO(ahe): Please triage this failure.
 Language/07_Classes/6_Constructors_A01_t06: Fail # TODO(ahe): Please triage this failure.
-Language/07_Classes/9_Superclasses/1_Inheritance_and_Overriding_A02_t03: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/01_Constants_A05_t01: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/01_Constants_A13_t06: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/01_Constants_A20_t03: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/05_Strings/1_String_Interpolation_A01_t06: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/08_Throw_A01_t01: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/08_Throw_A05_t01: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/08_Throw_A05_t02: Fail # TODO(ahe): Please triage this failure.
@@ -62,25 +59,6 @@
 Language/11_Expressions/18_Assignment_A05_t02: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/18_Assignment_A05_t04: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/18_Assignment_A05_t05: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/19_Conditional_A01_t14: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/19_Conditional_A01_t15: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/20_Logical_Boolean_Expressions_A01_t14: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/20_Logical_Boolean_Expressions_A01_t15: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/21_Bitwise_Expressions_A01_t16: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/21_Bitwise_Expressions_A01_t17: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/22_Equality_A01_t23: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/22_Equality_A01_t24: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/23_Relational_Expressions_A01_t22: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/23_Relational_Expressions_A01_t23: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/24_Shift_A01_t13: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/24_Shift_A01_t14: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/25_Additive_Expressions_A01_t13: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/25_Additive_Expressions_A01_t14: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/26_Multiplicative_Expressions_A01_t16: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/26_Multiplicative_Expressions_A01_t17: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/27_Unary_Expressions_A01_t20: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/27_Unary_Expressions_A01_t21: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/27_Unary_Expressions_A01_t22: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/30_Identifier_Reference_A04_t09: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/30_Identifier_Reference_A05_t01: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/30_Identifier_Reference_A05_t12: Fail # TODO(ahe): Please triage this failure.
@@ -146,8 +124,6 @@
 LibTest/math/pow_A01_t01: Fail # TODO(ahe): Please triage this failure.
 LibTest/math/pow_A11_t01: Fail # TODO(ahe): Please triage this failure.
 LibTest/math/pow_A13_t01: Fail # TODO(ahe): Please triage this failure.
-LibTest/math/sin_A01_t01: Fail # TODO(ahe): Please triage this failure.
-LibTest/math/tan_A01_t01: Fail # TODO(ahe): Please triage this failure.
 
 LibTest/isolate/ReceivePort/receive_A01_t02: Fail # Issue 6750
 
@@ -160,17 +136,49 @@
 
 Language/09_Generics/09_Generics_A04_t03: Fail # dart2js does not treat 2.0 as a double; dartbug.com/1533
 
-[ $compiler == dart2js && ($system == linux || $system == macos)]
-LibTest/math/exp_A01_t01: Fail # TODO(ahe): Please triage this failure.
+[ $compiler == dart2js && $runtime == ie9 ]
+Language/11_Expressions/03_Numbers_A01_t06: Fail # Issue: 8920
+Language/11_Expressions/03_Numbers_A01_t09: Fail # Issue: 8920
+Language/11_Expressions/06_Lists_A07_t02: Fail # Issue: 8920
+Language/11_Expressions/07_Maps_A06_t02: Fail # Issue: 8920
+Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A02_t04: Fail # Issue: 8920
+LibTest/core/Date/Date_A01_t03: Fail # Issue: 8920
+LibTest/core/Date/Date.fromString_A03_t01: Fail # Issue: 8920
+LibTest/core/Date/timeZoneName_A01_t01: Fail # Issue: 8920
+LibTest/core/Date/year_A01_t01: Fail # Issue: 8920
+LibTest/core/double/round_A01_t01: Fail # Issue: 8920
+LibTest/core/double/toRadixString_A01_t01: Fail # Issue: 8920
+LibTest/core/double/toStringAsExponential_A01_t04: Fail # Issue: 8920
+LibTest/core/double/toStringAsPrecision_A01_t04: Fail # Issue: 8920
+LibTest/core/Expect/identical_A01_t01: Fail # Issue: 8920
+LibTest/core/int/compareTo_A01_t01: Fail # Issue: 8920
+LibTest/core/int/operator_left_shift_A01_t01: Fail # Issue: 8920
+LibTest/core/int/operator_remainder_A01_t03: Fail # Issue: 8920
+LibTest/core/int/operator_truncating_division_A01_t02: Fail # Issue: 8920
+LibTest/core/int/remainder_A01_t01: Fail # Issue: 8920
+LibTest/core/int/remainder_A01_t03: Fail # Issue: 8920
+LibTest/core/int/toRadixString_A01_t01: Fail # Issue: 8920
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A06_t02: Fail # Issue: 8920
+LibTest/core/RegExp/Pattern_semantics/firstMatch_DecimalEscape_A01_t02: Fail # Issue: 8920
+LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: Fail # Issue: 8920
+LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: Fail # Issue: 8920
+LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: Fail # Issue: 8920
+LibTest/core/String/contains_A01_t02: Fail # Issue: 8920
+LibTest/isolate/ReceivePort/toSendPort_A01_t02: Pass, Fail # Issue: 8920
 
+
+# These tests are passing with 'runtime == ie9' but are either skipped or fail
+# on other configurations
+[ $compiler == dart2js && ($runtime == ie10 || $runtime == ff || $runtime == chrome || $runtime == drt || $runtime == safari || $runtime == opera || $runtime == d8 || $runtime == jsshell) ]
+LibTest/math/exp_A01_t01: Fail, OK # co19 issue 44
+LibTest/math/sin_A01_t01: Fail # TODO(ahe): Please triage this failure.
+LibTest/math/tan_A01_t01: Fail # TODO(ahe): Please triage this failure.
+
+[ $compiler == dart2js ]
 LibTest/math/parseDouble_A02_t01: Fail, OK # co19 issue 317
 LibTest/math/parseInt_A01_t01: Fail, OK # co19 issue 317
 LibTest/math/parseInt_A02_t01: Fail, OK # co19 issue 317
 
-[ $compiler == dart2js && $unchecked ]
-LibTest/core/Date/Date.fromMillisecondsSinceEpoch_A03_t01: Fail # TODO(ahe): Please triage this failure.
-
-
 [ $compiler == dart2js && $runtime == jsshell ]
 LibTest/core/Map/Map_class_A01_t04: Pass, Slow # Issue 8096
 Language/11_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A03_t01: Fail # TODO(ngeoaffray): Please triage these failure.
@@ -182,6 +190,17 @@
 LibTest/math/acos_A01_t01: Fail # TODO(ngeoaffray): Please triage these failure.
 LibTest/math/asin_A01_t01: Fail # TODO(ngeoaffray): Please triage these failure.
 
+[ $compiler == dart2js && $minified ]
+
+# These tests assume that the invocation mirror gets the original name of the
+# method, but that information is not present when minifying.  They could be
+# fixed by using the invocation mirror to invoke a method on a different object
+# and checking that the correct method is invoked.
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t02: Fail, OK
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t03: Fail, OK
+Language/11_Expressions/18_Assignment_A08_t04: Fail, OK
+
+
 [ $compiler == dart2js && $checked ]
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A17_t03: Fail # TODO(ahe): Please triage this failure.
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A17_t04: Fail # TODO(ahe): Please triage this failure.
@@ -216,7 +235,6 @@
 Language/13_Libraries_and_Scripts/1_Imports_A03_t26: Fail # TODO(ahe): Please triage this failure.
 Language/13_Libraries_and_Scripts/1_Imports_A03_t46: Fail # TODO(ahe): Please triage this failure.
 Language/13_Libraries_and_Scripts/1_Imports_A03_t66: Fail # TODO(ahe): Please triage this failure.
-Language/14_Types/8_Parameterized_Types_A02_t01: Fail # TODO(ahe): Please triage this failure.
 LibTest/core/AssertionError/column_A01_t02: Fail # TODO(ahe): Please triage this failure.
 LibTest/core/AssertionError/failedAssertion_A01_t01: Fail # TODO(ahe): Please triage this failure.
 LibTest/core/AssertionError/line_A01_t02: Fail # TODO(ahe): Please triage this failure.
@@ -273,7 +291,6 @@
 
 [ $compiler == dart2js ]
 Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t03: Fail # TODO(ahe): Enforce optional parameter semantics.
-Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A01_t01: Fail # http://dartbug.com/5026
 Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t04: Fail # TODO(ahe): Enforce optional parameter semantics.
 Language/06_Functions/2_Formal_Parameters_A03_t03: Fail # TODO(ahe): Enforce optional parameter semantics.
 Language/06_Functions/2_Formal_Parameters_A03_t04: Fail # TODO(ahe): Enforce optional parameter semantics.
@@ -332,7 +349,6 @@
 Language/11_Expressions/32_Type_Cast_A01_t04: Fail, OK # co19 issue 241
 
 Language/11_Expressions/22_Equality_A01_t01: Fail, OK # Function declaration takes precedence over function expression.
-Language/11_Expressions/28_Postfix_Expressions_A01_t01: Fail, OK # A map literal cannot start an expression statement.
 
 Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A01_t14: Fail, OK # co19 issue 210
 Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A01_t15: Fail, OK # co19 issue 210
@@ -549,6 +565,48 @@
 
 LibTest/core/Date/operator_equality_A01_t01: Fail # DateTime.== now looks at timezone, co19 issue 379.
 
+LibTest/core/Date/Date.fromMillisecondsSinceEpoch_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.fromMillisecondsSinceEpoch_A01_t02: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.fromMillisecondsSinceEpoch_A03_t01: pass
+LibTest/core/Date/Date.fromString_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.fromString_A01_t02: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.fromString_A03_t01: pass
+LibTest/core/Date/Date.now_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.now_A01_t02: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.now_A01_t03: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.utc_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date_A01_t03: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date_A01_t04: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/add_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/add_A02_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/add_A03_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/compareTo_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/compareTo_A01_t02: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/day_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/difference_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/difference_A01_t02: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/hour_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/isUtc_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/millisecond_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/millisecondsSinceEpoch_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/minute_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/month_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/operator_GE_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/operator_GT_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/operator_LE_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/operator_LT_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/second_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/subtract_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/subtract_A02_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/subtract_A03_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/timeZoneName_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/timeZoneOffset_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/toLocal_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/toString_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/toUtc_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/weekday_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+
 Language/12_Statements/10_Try_A03_t01: Fail # co19 issue 381
 Language/12_Statements/10_Try_A03_t02: Fail # co19 issue 381
 Language/12_Statements/10_Try_A03_t03: Fail # co19 issue 381
@@ -563,12 +621,55 @@
 LibTest/core/IllegalJSRegExpException/toString_A01_t01: Fail # IllegalJSRegExpException has been removed. co19 issue 375.
 LibTest/core/IllegalJSRegExpException/IllegalJSRegExpException_A01_t01: Fail # IllegalJSRegExpException has been removed. co19 issue 375.
 
+LibTest/core/StringBuffer/addAll_A01_t02: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/StringBuffer/add_A01_t02: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/StringBuffer/add_A01_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/StringBuffer/addAll_A01_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/StringBuffer/toString_A01_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A03_t02: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A04_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/12_Statements/01_Blocks_A01_t03: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/14_Function_Invocation/1_Actual_Argument_List_Evaluation_A02_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/11_Instance_Creation/1_New_A09_t12: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/11_Instance_Creation/1_New_A09_t05: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/11_Instance_Creation/1_New_A13_t03: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/11_Instance_Creation/1_New_A09_t06: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A04_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/15_Method_Invocation/3_Static_Invocation_A04_t05: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A02_t04: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/05_Strings/1_String_Interpolation_A03_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/05_Strings/1_String_Interpolation_A04_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+
+LibTest/core/double/operator_truncating_division_A01_t01: Fail # truncate/ceil/floor/round returns ints, issue 361
+LibTest/core/double/operator_truncating_division_A01_t03: Fail # truncate/ceil/floor/round returns ints, issue 361
+LibTest/core/double/operator_truncating_division_A01_t04: Fail # truncate/ceil/floor/round returns ints, issue 361
+LibTest/core/double/operator_truncating_division_A01_t05: Fail # truncate/ceil/floor/round returns ints, issue 361
+LibTest/core/double/operator_truncating_division_A01_t06: Fail # truncate/ceil/floor/round returns ints, issue 361
+
+LibTest/core/double/ceil_A01_t03: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/double/ceil_A01_t04: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/double/floor_A01_t03: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/double/floor_A01_t04: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/double/isNaN_A01_t03: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/double/round_A01_t02: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/double/round_A01_t04: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/double/truncate_A01_t03: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/double/truncate_A01_t04: Fail # truncate/ceil/floor/round returns ints, issue 389
+
+LibTest/core/List/getRange_A02_t01: Fail # issue 391
+
 # Issues with co19 test suite in checked mode.
 [ $compiler == dart2js && $checked ]
 LibTest/isolate/SendPort/call_A01_t01: Fail # Future is in async library. co19 issue 367
 
+LibTest/core/Set/intersection_A01_t01: Fail # issue 390
+LibTest/core/Set/intersection_A01_t02: Fail # issue 390
+LibTest/core/Set/intersection_A01_t03: Fail # issue 390
+
 # Issues with co19 test suite in unchecked mode.
 [ $compiler == dart2js && $unchecked ]
+LibTest/core/Set/intersection_A03_t01: Fail # Doesn't expect null to be allowed in Set or Map keys (issue 377). Passes in checked mode due to Issue 390.
+
 LibTest/core/Future/chain_A02_t05: Fail # Future is in async library. co19 issue 367
 LibTest/core/Future/transform_A02_t04: Fail # Future is in async library. co19 issue 367
 
@@ -601,7 +702,6 @@
 LibTest/core/int/toRadixString_A01_t01: Fail, OK # Bad test: uses Expect.fail, Expect.throws, assumes case of result, and uses unsupported radixes.
 LibTest/core/String/contains_A01_t02: Fail, OK # co19 issue 105.
 
-
 [ $compiler == dart2js && $system == macos ]
 LibTest/math/acos_A01_t01: Fail, OK # co19 issue 44
 LibTest/math/asin_A01_t01: Fail, OK # co19 issue 44
@@ -627,11 +727,10 @@
 
 Language/11_Expressions/01_Constants_A12_t01: Fail # internal error: CompileTimeConstantEvaluator not implemented
 Language/11_Expressions/22_Equality_A05_t01: Fail # != cannot be called on super
-Language/11_Expressions/27_Unary_Expressions_A01_t10: Fail # cannot deal with super in complex assignments
 Language/11_Expressions/30_Identifier_Reference_A02_t01: Fail # Pseudo keyword "abstract".
 
 [ $compiler == dart2js && $jscl ]
-LibTest/core/Date/Date.fromString_A03_t01: Fail # Issue co19 - 121
+LibTest/core/Date/Date.fromString_A03_t01: Pass # Issue co19 - 121 (currently passing due to co19 issues 373 and 374)
 LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A06_t02: Fail # IllegalJSRegExpException: '\c(' 'SyntaxError: Invalid regular expression: /\c(/: Unterminated group'
 LibTest/core/RegExp/Pattern_semantics/firstMatch_DecimalEscape_A01_t02: Fail # Expect.fail('Some exception expected')
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: Fail # Expect.fail('Some exception expected')
@@ -646,8 +745,11 @@
 [ $compiler == dart2js && $jscl ]
 LibTest/core/Expect/identical_A01_t01: Fail # TODO(floitsch): Is NaN identical to NaN?
 
+[ $compiler == dart2js && $runtime == d8 ]
+Language/14_Types/6_Type_dynamic_A03_t01: Fail # Renamed Date to DateTime (issue 373, 374)
 
-[ $compiler == dart2js && $browser ]
+
+[ $compiler == dart2js && ($runtime == ie10 || $runtime == ff || $runtime == chrome || $runtime == drt || $runtime == safari || $runtime == opera) ]
 *: Skip
 
 
@@ -663,8 +765,6 @@
 Language/05_Variables/05_Variables_A01_t14: Fail # Checks that variable declaration cannot contain 'const', 'final' and 'var' simultaneously.
 Language/05_Variables/05_Variables_A01_t15: Fail # Checks that a variable declaration cannot contain the 'abstract' keyword.
 Language/05_Variables/05_Variables_A04_t01: Fail # Checks that a compile-time error occurs if a local constant variable is redefined.
-Language/06_Functions/06_Functions_A01_t31: Fail # Checks that functions can't be declared as static inside of a function body.
-Language/06_Functions/1_Function_Declaration_A01_t01: Fail # Checks that it is a compile-time error to preface library function with 'static'.
 Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t03: Fail # Checks that a required parameter can be constant. Reassigning it should produce a compile-time error.
 Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t04: Fail # Checks that static variable declaration can't be a required formal parameter
 Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t05: Fail # Checks that reassigning a final required parameter produces a compile-time error.
@@ -714,7 +814,6 @@
 Language/11_Expressions/23_Relational_Expressions_A01_t11: Fail # Checks that a relational expression cannot be the operand of another relational expression.
 Language/11_Expressions/23_Relational_Expressions_A01_t12: Fail # Checks that a relational expression cannot be the operand of another relational expression.
 Language/11_Expressions/23_Relational_Expressions_A01_t13: Fail # Checks that a relational expression cannot be the operand of another relational expression.
-Language/11_Expressions/30_Identifier_Reference_A07_t01: Fail # Checks that it is a compile-time error when a built-in identifier "abstract" is used as a type annotation of a local variable.
 Language/12_Statements/03_Variable_Declaration_A04_t01: Fail # Checks that if the variable declaration is prefixed with the const modifier, then variable must be initialized to a constant expression.
 Language/15_Reference/1_Lexical_Rules_A02_t06: Fail # Checks that Unicode whitespaces other than WHITESPACE are not permitted in the source code. Checks symbol U+00a0.
 
@@ -732,7 +831,13 @@
 Language/07_Classes/3_Setters_A04_t06: Fail # http://dartbug.com/5023
 Language/07_Classes/3_Setters_A04_t07: Fail # http://dartbug.com/5023
 
-Language/14_Types/5_Function_Types_A01_t01: Fail # http://dartbug.com/5022
+Language/14_Types/4_Interface_Types_A05_t04: Fail # http://dartbug.com/5022
+Language/14_Types/4_Interface_Types_A10_t04: Fail # http://dartbug.com/5022
+Language/14_Types/4_Interface_Types_A10_t06: Fail # http://dartbug.com/5022
+Language/14_Types/4_Interface_Types_A10_t07: Fail # http://dartbug.com/5022
+Language/14_Types/4_Interface_Types_A10_t08: Fail # http://dartbug.com/5022
+Language/14_Types/4_Interface_Types_A10_t09: Fail # http://dartbug.com/5022
+Language/14_Types/5_Function_Types_A06_t01: Fail # http://dartbug.com/5022
 
 Language/13_Libraries_and_Scripts/4_Scripts_A03_t01: Fail # http://dartbug.com/5683
 Language/13_Libraries_and_Scripts/4_Scripts_A03_t03: Fail # http://dartbug.com/5683
@@ -767,11 +872,11 @@
 LibTest/core/Set/add_A01_t02: Fail # Doesn't expect null to be allowed in Set or Map keys (issue 377).
 LibTest/core/Set/addAll_A01_t02: Fail # Doesn't expect null to be allowed in Set or Map keys (issue 377).
 LibTest/core/Set/contains_A01_t02: Fail # Doesn't expect null to be allowed in Set or Map keys (issue 377).
-LibTest/core/Set/containsAll_A01_t02: Fail # Doesn't expect null to be allowed in Set or Map keys (issue 377).
-LibTest/core/Set/intersection_A03_t01: Fail # Doesn't expect null to be allowed in Set or Map keys (issue 377).
-LibTest/core/Set/isSubsetOf_A01_t02: Fail # Doesn't expect null to be allowed in Set or Map keys (issue 377).
 LibTest/core/Set/remove_A01_t02: Fail # Doesn't expect null to be allowed in Set or Map keys (issue 377).
 LibTest/core/Set/removeAll_A01_t02: Fail # Doesn't expect null to be allowed in Set or Map keys (issue 377).
+LibTest/core/Set/isSubsetOf_A01_t02: Fail # Doesn't expect null to be allowed in Set or Map keys (issue 377).
+LibTest/core/Set/containsAll_A01_t02: Fail # Doesn't expect null to be allowed in Set or Map keys (issue 377).
+
 
 LibTest/core/Map/forEach_A01_t07: Fail # Doesn't expect concurrent modification error (issue 376).
 
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index b8ff98e..510bd96 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -6,6 +6,8 @@
 LibTest/core/Strings/concatAll_A04_t01: Fail, OK # checks for ArgumentError. TypeError is ok too. co19 issue 366
 LibTest/core/Strings/join_A04_t01: Fail, OK # checks for ArgumentError. TypeError is ok too. co19 issue 366
 
+LibTest/core/int/operator_division_A01_t01: Fail # ~/ returns ints, issue 361
+
 [ $compiler == none && $runtime == vm ]
 Language/13_Libraries_and_Scripts/1_Imports_A02_t21: Crash # Dart issue 6060
 Language/13_Libraries_and_Scripts/1_Imports_A02_t22: Crash # Dart issue 6060
@@ -146,6 +148,17 @@
 
 LibTest/core/List/last_A02_t01: Fail # List.last throws a StateError, co19 issue 359
 
+LibTest/core/double/truncate_A01_t03: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/double/truncate_A01_t04: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/double/ceil_A01_t03: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/double/ceil_A01_t04: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/double/double_class_A01_t01: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/double/floor_A01_t03: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/double/floor_A01_t04: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/double/round_A01_t02: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/double/round_A01_t04: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/double/isNaN_A01_t03: Fail # truncate/ceil/floor/round returns ints, issue 389
+
 LibTest/core/double/toInt_A01_t03: Fail # conversion to integer throws UnsupportedError for NaN/Infinity now, co19 issue 360
 LibTest/core/double/toInt_A01_t04: Fail # conversion to integer throws UnsupportedError for NaN/Infinity now, co19 issue 360
 
@@ -253,9 +266,6 @@
 
 Language/11_Expressions/11_Instance_Creation_A05_t02: Fail # co19 issue 234
 
-[ $compiler == none && $runtime == vm && $unchecked ]
-LibTest/core/Date/Date.fromMillisecondsSinceEpoch_A03_t01: Fail # TODO(vm-team): Please triage this failure.
-
 [ $compiler == none && $runtime == vm ]
 Language/11_Expressions/01_Constants_A16_t01: Fail # Not properly reporting exception in initializer expressions
 Language/11_Expressions/01_Constants_A16_t02: Fail # Not properly reporting exception in initializer expressions
@@ -303,7 +313,7 @@
 LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A06_t02: Fail
 
 [ $compiler == none && $runtime == vm ]
-LibTest/core/Date/Date.fromString_A03_t01: Fail # Issue co19 - 121
+LibTest/core/Date/Date.fromString_A03_t01: Pass # Issue co19 - 121  (currently passing due to co19 issues 373 and 374)
 LibTest/core/Match/operator_subscript_A01_t01: Fail
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: Fail
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: Fail
@@ -515,11 +525,9 @@
 LibTest/core/Set/add_A01_t02: Fail # Doesn't expect null to be allowed in Set or Map keys (issue 377).
 LibTest/core/Set/addAll_A01_t02: Fail # Doesn't expect null to be allowed in Set or Map keys (issue 377).
 LibTest/core/Set/contains_A01_t02: Fail # Doesn't expect null to be allowed in Set or Map keys (issue 377).
-LibTest/core/Set/containsAll_A01_t02: Fail # Doesn't expect null to be allowed in Set or Map keys (issue 377).
-LibTest/core/Set/intersection_A03_t01: Fail # Doesn't expect null to be allowed in Set or Map keys (issue 377).
-LibTest/core/Set/isSubsetOf_A01_t02: Fail # Doesn't expect null to be allowed in Set or Map keys (issue 377).
 LibTest/core/Set/remove_A01_t02: Fail # Doesn't expect null to be allowed in Set or Map keys (issue 377).
 LibTest/core/Set/removeAll_A01_t02: Fail # Doesn't expect null to be allowed in Set or Map keys (issue 377).
+LibTest/core/Set/isSubsetOf_A01_t02: Fail # Doesn't expect null to be allowed in Set or Map keys (issue 377).
 
 LibTest/core/Map/forEach_A01_t07: Fail # Doesn't expect concurrent modification error (issue 376).
 
@@ -529,6 +537,69 @@
 LibTest/core/String/charCodeAt_A01_t01: Fail # Deprecated string members removed (issue 382).
 LibTest/core/String/splitChars_A01_t01: Fail # Deprecated string members removed (issue 382).
 
+Language/14_Types/6_Type_dynamic_A03_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.fromMillisecondsSinceEpoch_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.fromMillisecondsSinceEpoch_A01_t02: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.fromString_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.fromString_A01_t02: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.now_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.now_A01_t02: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.now_A01_t03: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date.utc_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date_A01_t03: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/Date_A01_t04: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/add_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/add_A02_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/add_A03_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/compareTo_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/compareTo_A01_t02: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/day_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/difference_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/difference_A01_t02: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/hour_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/isUtc_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/millisecond_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/millisecondsSinceEpoch_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/minute_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/month_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/operator_GE_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/operator_GT_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/operator_LE_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/operator_LT_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/second_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/subtract_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/subtract_A02_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/subtract_A03_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/timeZoneName_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/timeZoneOffset_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/toLocal_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/toString_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/toUtc_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+LibTest/core/Date/weekday_A01_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+
+
+LibTest/core/StringBuffer/addAll_A01_t02: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/StringBuffer/add_A01_t02: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/StringBuffer/add_A01_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/StringBuffer/addAll_A01_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/StringBuffer/toString_A01_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A03_t02: Fail # StringBuffer renamed add to write. co19 issue 388.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A04_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/12_Statements/01_Blocks_A01_t03: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/14_Function_Invocation/1_Actual_Argument_List_Evaluation_A02_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/11_Instance_Creation/1_New_A09_t12: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/11_Instance_Creation/1_New_A09_t05: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/11_Instance_Creation/1_New_A13_t03: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/11_Instance_Creation/1_New_A09_t06: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A04_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/15_Method_Invocation/3_Static_Invocation_A04_t05: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A02_t04: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/05_Strings/1_String_Interpolation_A03_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+Language/11_Expressions/05_Strings/1_String_Interpolation_A04_t01: Fail # StringBuffer renamed add to write. co19 issue 388.
+
+LibTest/core/List/getRange_A02_t01: Fail # issue 391
+
 [ $compiler == none && $runtime == vm && $unchecked ]
 LibTest/core/Future/chain_A02_t05: Fail # Future is in async library. co19 issue 367
 LibTest/core/Future/transform_A02_t04: Fail # Future is in async library. co19 issue 367
@@ -537,6 +608,17 @@
 LibTest/isolate/SendPort/call_A01_t01: Fail # Future is in async library. co19 issue 367
 Language/14_Types/4_Interface_Types_A08_t06: Fail # Moved collection classes from core to collection. co19 issue 371.
 
+LibTest/core/Set/containsAll_A01_t02: Fail # issue 390
+LibTest/core/Set/intersection_A01_t01: Fail # issue 390
+LibTest/core/Set/intersection_A01_t02: Fail # issue 390
+LibTest/core/Set/intersection_A01_t03: Fail # issue 390
+
+[ $compiler == none && $runtime == vm && $unchecked ]
+LibTest/core/Set/containsAll_A01_t02: Fail # Doesn't expect null to be allowed in Set or Map keys (issue 377). Succeedes in checked mode due to Issue 390.
+LibTest/core/Set/intersection_A03_t01: Fail # Doesn't expect null to be allowed in Set or Map keys (issue 377). Succeedes in checked mode due to Issue 390.
+
+
+
 [ $compiler == none && $arch == simarm ]
 *: Skip
 
diff --git a/tests/compiler/dart2js/analyze_api_test.dart b/tests/compiler/dart2js/analyze_api_test.dart
index 1432d40..7c086a5 100644
--- a/tests/compiler/dart2js/analyze_api_test.dart
+++ b/tests/compiler/dart2js/analyze_api_test.dart
@@ -68,6 +68,9 @@
   }
 
   bool checkWhiteList(Uri uri, String message) {
+    if (uri == null) {
+      return false;
+    }
     String path = uri.path;
     for (String file in whiteListMap.keys) {
       if (path.endsWith(file)) {
diff --git a/tests/compiler/dart2js/analyze_only_test.dart b/tests/compiler/dart2js/analyze_only_test.dart
index f17aed4..ffbc7a5 100644
--- a/tests/compiler/dart2js/analyze_only_test.dart
+++ b/tests/compiler/dart2js/analyze_only_test.dart
@@ -108,6 +108,17 @@
     });
 
   runCompiler(
+    """main() {
+         Foo foo; // Unresolved and analyzed.
+       }""",
+    ['--analyze-only', '--analyze-signatures-only'],
+    (String code, List errors, List warnings) {
+      Expect.isNull(code);
+      Expect.isTrue(errors.isEmpty);
+      Expect.isTrue(warnings.isEmpty);
+    });
+
+  runCompiler(
     "Foo foo; // Unresolved and analyzed.",
     ['--analyze-only', '--analyze-all'],
     (String code, List errors, List warnings) {
@@ -126,4 +137,23 @@
       Expect.equals(1, warnings.length);
       Expect.equals('Warning: cannot resolve type Foo', warnings[0].toString());
     });
+
+  runCompiler(
+    "",
+    ['--analyze-only', '--analyze-all'],
+    (String code, List errors, List warnings) {
+      Expect.isNull(code);
+      Expect.isTrue(errors.isEmpty);
+      Expect.isTrue(warnings.isEmpty);
+    });
+
+  // --analyze-signatures-only implies --analyze-only
+  runCompiler(
+    "",
+    ['--analyze-signatures-only', '--analyze-all'],
+    (String code, List errors, List warnings) {
+      Expect.isNull(code);
+      Expect.isTrue(errors.isEmpty);
+      Expect.isTrue(warnings.isEmpty);
+    });
 }
diff --git a/tests/compiler/dart2js/call_site_type_inferer_static_test.dart b/tests/compiler/dart2js/call_site_type_inferer_static_test.dart
index bc4e2c5..4dabd93 100644
--- a/tests/compiler/dart2js/call_site_type_inferer_static_test.dart
+++ b/tests/compiler/dart2js/call_site_type_inferer_static_test.dart
@@ -102,9 +102,9 @@
   runTest(TEST_FOUR, [HType.DOUBLE]);
   runTest(TEST_FIVE, [HType.NUMBER]);
   runTest(TEST_SIX, [HType.NUMBER]);
-  runTest(TEST_SEVEN);
-  runTest(TEST_EIGHT, [HType.INTEGER, HType.UNKNOWN]);
-  runTest(TEST_NINE);
+  runTest(TEST_SEVEN, [HType.NON_NULL]);
+  runTest(TEST_EIGHT, [HType.INTEGER, HType.NON_NULL]);
+  runTest(TEST_NINE, [HType.NON_NULL, HType.NON_NULL]);
   runTest(TEST_TEN);
 }
 
diff --git a/tests/compiler/dart2js/call_site_type_inferer_test.dart b/tests/compiler/dart2js/call_site_type_inferer_test.dart
index f3c9e76..2c2b529 100644
--- a/tests/compiler/dart2js/call_site_type_inferer_test.dart
+++ b/tests/compiler/dart2js/call_site_type_inferer_test.dart
@@ -236,11 +236,11 @@
   runTest(TEST_4, [HType.DOUBLE]);
   runTest(TEST_5, [HType.NUMBER]);
   runTest(TEST_6, [HType.NUMBER]);
-  runTest(TEST_7);
-  runTest(TEST_8, [HType.INTEGER, HType.UNKNOWN]);
+  runTest(TEST_7, [HType.NON_NULL]);
+  runTest(TEST_8, [HType.INTEGER, HType.NON_NULL]);
   runTest(TEST_9, [HType.INTEGER, HType.INTEGER]);
   runTest(TEST_10, [HType.INTEGER, HType.INTEGER]);
-  runTest(TEST_11);
+  runTest(TEST_11, [HType.NON_NULL, HType.NON_NULL]);
 
   defaultTypes = new OptionalParameterTypes(1);
   defaultTypes.update(0, const SourceString("p2"), HType.INTEGER);
@@ -266,7 +266,7 @@
   defaultTypes.update(1, const SourceString("p3"), HType.STRING);
   runTest(TEST_17, [HType.INTEGER, HType.BOOLEAN, HType.DOUBLE], defaultTypes);
 
-  runTest(TEST_18);
+  runTest(TEST_18, [HType.NON_NULL, HType.NON_NULL]);
 }
 
 void main() {
diff --git a/tests/compiler/dart2js/compiler_helper.dart b/tests/compiler/dart2js/compiler_helper.dart
index 405fb63..d388aa9 100644
--- a/tests/compiler/dart2js/compiler_helper.dart
+++ b/tests/compiler/dart2js/compiler_helper.dart
@@ -56,7 +56,8 @@
   lego.Element element = compiler.mainApp.find(buildSourceString(entry));
   if (element == null) return null;
   compiler.phase = Compiler.PHASE_RESOLVING;
-  compiler.backend.enqueueHelpers(compiler.enqueuer.resolution);
+  compiler.backend.enqueueHelpers(compiler.enqueuer.resolution,
+                                  compiler.globalDependencies);
   compiler.processQueue(compiler.enqueuer.resolution, element);
   compiler.world.populate();
   var context = new js.JavaScriptItemCompilationContext();
diff --git a/tests/compiler/dart2js/concrete_type_inference_test.dart b/tests/compiler/dart2js/concrete_type_inference_test.dart
index 324b79d..b86d2e6 100644
--- a/tests/compiler/dart2js/concrete_type_inference_test.dart
+++ b/tests/compiler/dart2js/concrete_type_inference_test.dart
@@ -48,22 +48,28 @@
 
 void testBasicTypes() {
   checkPrintType('true', (compiler, type) {
-    Expect.identical(compiler.boolClass, type.getUniqueType());
+    var backend = compiler.backend;
+    Expect.identical(backend.boolImplementation, type.exactType.element);
   });
   checkPrintType('1.0', (compiler, type) {
-    Expect.identical(compiler.doubleClass, type.getUniqueType());
+    var backend = compiler.backend;
+    Expect.identical(backend.doubleImplementation, type.exactType.element);
   });
   checkPrintType('1', (compiler, type) {
-    Expect.identical(compiler.intClass, type.getUniqueType());
+    var backend = compiler.backend;
+    Expect.identical(backend.intImplementation, type.exactType.element);
   });
   checkPrintType('[]', (compiler, type) {
-    Expect.identical(compiler.listClass, type.getUniqueType());
+    var backend = compiler.backend;
+    Expect.identical(backend.listImplementation, type.exactType.element);
   });
   checkPrintType('null', (compiler, type) {
-    Expect.identical(compiler.nullClass, type.getUniqueType());
+    var backend = compiler.backend;
+    Expect.identical(backend.nullImplementation, type.exactType.element);
   });
   checkPrintType('"foo"', (compiler, type) {
-    Expect.identical(compiler.stringClass, type.getUniqueType());
+    var backend = compiler.backend;
+    Expect.identical(backend.stringImplementation, type.exactType.element);
   });
 }
 
@@ -79,9 +85,9 @@
         var thirdParameter =
           fiskElement.computeSignature(compiler).optionalParameters.tail.head;
         Expect.identical(
-            compiler.intClass,
+            compiler.backend.intImplementation,
             compiler.typesTask.getGuaranteedTypeOfElement(firstParameter)
-                .getUniqueType());
+                .exactType.element);
         Expect.isNull(
             compiler.typesTask.getGuaranteedTypeOfElement(secondParameter));
         Expect.isNull(
diff --git a/tests/compiler/dart2js/cpa_inference_test.dart b/tests/compiler/dart2js/cpa_inference_test.dart
index a204b4d..922bc50 100644
--- a/tests/compiler/dart2js/cpa_inference_test.dart
+++ b/tests/compiler/dart2js/cpa_inference_test.dart
@@ -56,7 +56,7 @@
     string = inferrer.baseTypes.stringBaseType;
     list = inferrer.baseTypes.listBaseType;
     map = inferrer.baseTypes.mapBaseType;
-    nullType = new NullBaseType();
+    nullType = const NullBaseType();
     Element mainElement = compiler.mainApp.find(buildSourceString('main'));
     ast = mainElement.parseNode(compiler);
   }
@@ -89,12 +89,11 @@
   ConcreteType concreteFrom(List<BaseType> baseTypes) {
     ConcreteType result = inferrer.emptyConcreteType;
     for (final baseType in baseTypes) {
-      result = result.union(compiler.maxConcreteTypeSize,
-          inferrer.singletonConcreteType(baseType));
+      result = result.union(inferrer.singletonConcreteType(baseType));
     }
     // We make sure the concrete types expected by the tests don't default to
     // dynamic because of widening.
-    assert(!result.isUnkown());
+    assert(!result.isUnknown());
     return result;
   }
 
@@ -114,7 +113,7 @@
    * occurence of [: variable; :] in the program is the unknown concrete type.
    */
   void checkNodeHasUnknownType(String variable) {
-    return Expect.isTrue(inferrer.inferredTypes[findNode(variable)].isUnkown());
+    return Expect.isTrue(inferrer.inferredTypes[findNode(variable)].isUnknown());
   }
 
   /**
@@ -135,20 +134,25 @@
   void checkFieldHasUknownType(String className, String fieldName) {
     return Expect.isTrue(
         inferrer.inferredFieldTypes[findField(className, fieldName)]
-                .isUnkown());
+                .isUnknown());
   }
 }
 
 const String CORELIB = r'''
   print(var obj) {}
   abstract class num { 
-    operator +(x);
-    operator *(x);
-    operator -(x);
+    num operator +(num x);
+    num operator *(num x);
+    num operator -(num x);
     operator ==(x);
+    num floor();
   }
-  abstract class int extends num { }
-  abstract class double extends num { }
+  abstract class int extends num {
+    bool get isEven;
+  }
+  abstract class double extends num {
+    bool get isNaN;
+  }
   class bool {}
   class String {}
   class Object {}
@@ -163,9 +167,7 @@
   class Null {}
   class Type {}
   class Dynamic_ {}
-  bool identical(Object a, Object b) {}
-  dynamic JS(String typeDescription, String codeTemplate,
-             [var arg0, var arg1, var arg2]) {}''';
+  bool identical(Object a, Object b) {}''';
 
 AnalysisResult analyze(String code, {int maxConcreteTypeSize: 1000}) {
   Uri uri = new Uri.fromComponents(scheme: 'source');
@@ -206,7 +208,7 @@
   result.checkNodeHasType('v2', [result.double]);
   result.checkNodeHasType('v3', [result.string]);
   result.checkNodeHasType('v4', [result.bool]);
-  result.checkNodeHasType('v5', [new NullBaseType()]);
+  result.checkNodeHasType('v5', [result.nullType]);
 }
 
 testRedefinition() {
@@ -312,10 +314,18 @@
 testToplevelVariable() {
   final String source = r"""
       final top = 'abc';
-      main() { var foo = top; foo; }
+      class A {
+         f() => top;
+      }
+      main() { 
+        var foo = top;
+        var bar = new A().f();
+        foo; bar;
+      }
       """;
   AnalysisResult result = analyze(source);
   result.checkNodeHasType('foo', [result.string]);
+  result.checkNodeHasType('bar', [result.string]);
 }
 
 testNonRecusiveFunction() {
@@ -438,8 +448,9 @@
       """;
   AnalysisResult result = analyze(source);
   result.checkFieldHasType('A', 'x', [result.int, result.bool]);
-  result.checkFieldHasType('A', 'y', [result.string, new NullBaseType()]);
-  result.checkFieldHasType('A', 'z', [result.string]);
+  result.checkFieldHasType('A', 'y', [result.string, result.nullType]);
+  // TODO(polux): we can be smarter and infer {string} for z
+  result.checkFieldHasType('A', 'z', [result.string, result.nullType]);
 }
 
 testGetters() {
@@ -577,7 +588,7 @@
   AnalysisResult result = analyze(source);
 
   final foo = result.base('Foo');
-  final nil = new NullBaseType();
+  final nil = result.nullType;
 
   result.checkFieldHasType('A', 'x', [result.int, result.string]);
   result.checkFieldHasType('A', 'y', [nil]);
@@ -649,7 +660,7 @@
   AnalysisResult result = analyze(source);
 
   final foo = result.base('Foo');
-  final nil = new NullBaseType();
+  final nil = result.nullType;
 
   result.checkFieldHasType('A', 'x', [result.int, result.string]);
   result.checkFieldHasType('A', 'y', [nil, result.bool]);
@@ -799,10 +810,8 @@
       """;
   AnalysisResult result = analyze(source);
   result.checkNodeHasType('x', [result.string]);
-  // TODO(polux): the two following results should be [:[null, string:], see
-  // testFieldInitialization().
-  result.checkFieldHasType('A', 'witness1', [result.int]);
-  result.checkFieldHasType('A', 'witness2', [result.string]);
+  result.checkFieldHasType('A', 'witness1', [result.int, result.nullType]);
+  result.checkFieldHasType('A', 'witness2', [result.string, result.nullType]);
 }
 
 testCompoundOperators1() {
@@ -862,12 +871,10 @@
   AnalysisResult result = analyze(source);
   result.checkFieldHasType('A', 'xx', [result.int]);
   result.checkFieldHasType('A', 'yy', [result.int]);
-  // TODO(polux): the four following results should be [:[null, string]:], see
-  // testFieldInitialization().
-  result.checkFieldHasType('A', 'witness1', [result.string]);
-  result.checkFieldHasType('A', 'witness2', [result.string]);
-  result.checkFieldHasType('A', 'witness3', [result.string]);
-  result.checkFieldHasType('A', 'witness4', [result.string]);
+  result.checkFieldHasType('A', 'witness1', [result.string, result.nullType]);
+  result.checkFieldHasType('A', 'witness2', [result.string, result.nullType]);
+  result.checkFieldHasType('A', 'witness3', [result.string, result.nullType]);
+  result.checkFieldHasType('A', 'witness4', [result.string, result.nullType]);
 }
 
 testInequality() {
@@ -890,24 +897,68 @@
   result.checkNodeHasType('foo', [result.bool]);
   result.checkNodeHasType('bar', [result.bool]);
   result.checkNodeHasType('baz', []);
-  // TODO(polux): the following result should be [:[null, string]:], see
-  // testFieldInitialization().
-  result.checkFieldHasType('A', 'witness', [result.string]);
+  result.checkFieldHasType('A', 'witness', [result.string, result.nullType]);
 }
 
-testFieldInitialization() {
+testFieldInitialization1() {
   final String source = r"""
     class A {
       var x;
       var y = 1;
     }
+    class B extends A {
+      var z = "foo";
+    }
+    main () {
+      new B();
+    }
+    """;
+  AnalysisResult result = analyze(source);
+  result.checkFieldHasType('A', 'x', [result.nullType]);
+  result.checkFieldHasType('A', 'y', [result.int]);
+  result.checkFieldHasType('B', 'z', [result.string]);
+}
+
+testFieldInitialization2() {
+  final String source = r"""
+    var top = 42;
+    class A {
+      var x = top;
+    }
     main () {
       new A();
     }
     """;
   AnalysisResult result = analyze(source);
-  result.checkFieldHasType('A', 'x', [result.nullType]);
-  result.checkFieldHasType('A', 'y', [result.int]);
+  result.checkFieldHasType('A', 'x', [result.int]);
+}
+
+testFieldInitialization3() {
+  final String source = r"""
+    class A {
+      var x;
+    }
+    f() => new A().x;
+    class B {
+      var x = new A().x;
+      var y = f();
+    }
+    main () {
+      var foo = new B().x;
+      var bar = new B().y;
+      new A().x = "a";
+      foo; bar;
+    }
+    """;
+  AnalysisResult result = analyze(source);
+  // checks that B.B is set as a reader of A.x
+  result.checkFieldHasType('B', 'x', [result.nullType, result.string]);
+  // checks that B.B is set as a caller of f
+  result.checkFieldHasType('B', 'y', [result.nullType, result.string]);
+  // checks that readers of x are notified by changes in x's type
+  result.checkNodeHasType('foo', [result.nullType, result.string]);
+  // checks that readers of y are notified by changes in y's type
+  result.checkNodeHasType('bar', [result.nullType, result.string]);
 }
 
 testLists() {
@@ -1022,13 +1073,45 @@
 
 testJsCall() {
   final String source = r"""
+    import 'dart:foreign';
+
+    class A {}
+    class B extends A {}
+    class BB extends B {}
+    class C extends A {}
+    class D extends A {}
+
+    class X {}
+
     main () {
-      var x = JS('', '', null);
-      x;
+      // we don't create any D on purpose
+      new B(); new BB(); new C();
+
+      var a = JS('', '');
+      var b = JS('Object', '');
+      var c = JS('=List', '');
+      var d = JS('String', '');
+      var e = JS('int', '');
+      var f = JS('double', '');
+      var g = JS('num', '');
+      var h = JS('bool', '');
+      var i = JS('A', '');
+      var j = JS('X', '');
+      a; b; c; d; e; f; g; h; i; j;
     }
     """;
   AnalysisResult result = analyze(source);
-  result.checkNodeHasUnknownType('x');
+  result.checkNodeHasUnknownType('a');
+  result.checkNodeHasUnknownType('b');
+  result.checkNodeHasType('c', [result.nullType, result.list]);
+  result.checkNodeHasType('d', [result.nullType, result.string]);
+  result.checkNodeHasType('e', [result.nullType, result.int]);
+  result.checkNodeHasType('f', [result.nullType, result.double]);
+  result.checkNodeHasType('g', [result.nullType, result.num]);
+  result.checkNodeHasType('h', [result.nullType, result.bool]);
+  result.checkNodeHasType('i', [result.nullType, result.base('B'),
+                                result.base('BB'), result.base('C')]);
+  result.checkNodeHasType('j', [result.nullType]);
 }
 
 testIsCheck() {
@@ -1069,6 +1152,38 @@
   result.checkNodeHasType('foo', [result.int]);
 }
 
+testGoodGuys() {
+  final String source = r"""
+      main() {
+        var a = 1.isEven;
+        var b = 3.14.isNaN;
+        var c = 1.floor();
+        var d = 3.14.floor();
+        a; b; c; d;
+      }
+      """;
+  AnalysisResult result = analyze(source);
+  result.checkNodeHasType('a', [result.bool]);
+  result.checkNodeHasType('b', [result.bool]);
+  result.checkNodeHasType('c', [result.num]);
+  result.checkNodeHasType('d', [result.num]);
+}
+
+testIntDoubleNum() {
+  final String source = r"""
+      main() {
+        var a = 1;
+        var b = 1.0;
+        var c = true ? 1 : 1.0;
+        a; b; c;
+      }
+      """;
+  AnalysisResult result = analyze(source);
+  result.checkNodeHasType('a', [result.int]);
+  result.checkNodeHasType('b', [result.double]);
+  result.checkNodeHasType('c', [result.num]);
+}
+
 void main() {
   testDynamicBackDoor();
   testLiterals();
@@ -1078,7 +1193,7 @@
   testWhile();
   testFor1();
   testFor2();
-  // testToplevelVariable();  // toplevel variables are not yet supported
+  testToplevelVariable();
   testNonRecusiveFunction();
   testRecusiveFunction();
   testMutuallyRecusiveFunction();
@@ -1101,7 +1216,9 @@
   testCompoundOperators2();
   testSetIndexOperator();
   testInequality();
-  // testFieldInitialization(); // TODO(polux)
+  testFieldInitialization1();
+  testFieldInitialization2();
+  testFieldInitialization3();
   testSendWithWrongArity();
   testBigTypesWidening1();
   testBigTypesWidening2();
@@ -1112,4 +1229,6 @@
   testJsCall();
   testIsCheck();
   testSeenClasses();
+  testGoodGuys();
+  testIntDoubleNum();
 }
diff --git a/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart b/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
new file mode 100644
index 0000000..b5dc726
--- /dev/null
+++ b/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
@@ -0,0 +1,106 @@
+// 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 of the graph segmentation algorithm used by deferred loading
+// to determine which elements can be deferred and which libraries
+// much be included in the initial download (loaded eagerly).
+
+import 'dart:async' show Future;
+import 'dart:uri' show Uri;
+import 'dart:io';
+
+import '../../../sdk/lib/_internal/compiler/implementation/apiimpl.dart'
+       show Compiler;
+
+import '../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart'
+       as dart2js;
+
+import '../../../sdk/lib/_internal/compiler/implementation/filenames.dart'
+       show getCurrentDirectory;
+
+import '../../../sdk/lib/_internal/compiler/implementation/source_file.dart'
+       show SourceFile;
+
+import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider.dart'
+       show FormattingDiagnosticHandler,
+            SourceFileProvider;
+
+class MemorySourceFileProvider extends SourceFileProvider {
+  Future<String> readStringFromUri(Uri resourceUri) {
+    if (resourceUri.scheme != 'memory') {
+      return super.readStringFromUri(resourceUri);
+    }
+    String source = MEMORY_SOURCE_FILES[resourceUri.path];
+    // TODO(ahe): Return new Future.immediateError(...) ?
+    if (source == null) throw 'No such file $resourceUri';
+    String resourceName = '$resourceUri';
+    this.sourceFiles[resourceName] = new SourceFile(resourceName, source);
+    return new Future.immediate(source);
+  }
+}
+
+void main() {
+  Uri cwd = getCurrentDirectory();
+  Uri script = cwd.resolve(new Options().script);
+  Uri libraryRoot = script.resolve('../../../sdk/');
+  Uri packageRoot = script.resolve('./packages/');
+
+  var provider = new MemorySourceFileProvider();
+  var handler = new FormattingDiagnosticHandler(provider);
+
+  Compiler compiler = new Compiler(provider.readStringFromUri,
+                                   (name, extension) => null,
+                                   handler.diagnosticHandler,
+                                   libraryRoot,
+                                   packageRoot,
+                                   ['--analyze-only']);
+  compiler.run(new Uri('memory:main.dart'));
+  var main = compiler.mainApp.find(dart2js.Compiler.MAIN);
+  Expect.isNotNull(main, 'Could not find "main"');
+  compiler.deferredLoadTask.onResolutionComplete(main);
+
+  var deferredClasses =
+      compiler.deferredLoadTask.allDeferredElements.where((e) => e.isClass())
+      .toSet();
+
+  var expando =
+      deferredClasses.where((e) => e.name.slowToString() == 'Expando').single;
+
+  var myClass =
+      deferredClasses.where((e) => e.name.slowToString() == 'MyClass').single;
+
+  var deferredLibrary = compiler.libraries['memory:deferred.dart'];
+
+  Expect.equals(deferredLibrary, myClass.getLibrary());
+  Expect.equals(compiler.coreLibrary, expando.declaration.getLibrary());
+}
+
+const Map MEMORY_SOURCE_FILES = const {
+  'main.dart': """
+import 'dart:async';
+
+@lazy import 'deferred.dart';
+
+const lazy = const DeferredLibrary('deferred');
+
+main() {
+  lazy.load().then((_) {
+    Expect.equals(42, new MyClass().foo(87));
+  });
+}
+
+""",
+  'deferred.dart': """
+library deferred;
+
+class MyClass {
+  const MyClass();
+
+  foo(x) {
+    new Expando();
+    return (x - 3) ~/ 2;
+  }
+}
+""",
+};
diff --git a/tests/compiler/dart2js/deprecated_features_test.dart b/tests/compiler/dart2js/deprecated_features_test.dart
index 7c8bc58..b2aafa2 100644
--- a/tests/compiler/dart2js/deprecated_features_test.dart
+++ b/tests/compiler/dart2js/deprecated_features_test.dart
@@ -16,12 +16,12 @@
     if (kind == Diagnostic.VERBOSE_INFO) return;
     if (identical(kind.name, 'source map')) return;
     if (uri == null) {
-      messages.add('$kind: $message\n');
+      messages.write('$kind: $message\n');
     } else {
       Expect.equals('main:${uri.path}', '$uri');
       String source = TEST_SOURCE[uri.path];
       Expect.isNotNull(source);
-      messages.add('$begin<${source.substring(begin, end)}>:${uri.path}:'
+      messages.write('$begin<${source.substring(begin, end)}>:${uri.path}:'
                    '$kind: $message\n');
     }
   }
diff --git a/tests/compiler/dart2js/field_type_inferer_test.dart b/tests/compiler/dart2js/field_type_inferer_test.dart
index 04773aa..d791841 100644
--- a/tests/compiler/dart2js/field_type_inferer_test.dart
+++ b/tests/compiler/dart2js/field_type_inferer_test.dart
@@ -358,7 +358,7 @@
   runTest(TEST_1, {'f': HType.NULL});
   runTest(TEST_2, {'f1': HType.NULL, 'f2': HType.INTEGER});
   runTest(TEST_3, {'f1': HType.INTEGER, 'f2': HType.INTEGER_OR_NULL});
-  runTest(TEST_4, {'f1': HType.UNKNOWN, 'f2': HType.STRING_OR_NULL});
+  runTest(TEST_4, {'f1': HType.NON_NULL, 'f2': HType.STRING_OR_NULL});
   runTest(TEST_5, {'f1': HType.STRING, 'f2': HType.STRING});
   runTest(TEST_6, {'f1': HType.STRING, 'f2': HType.EXTENDABLE_ARRAY});
   runTest(TEST_7, {'f1': HType.INDEXABLE_PRIMITIVE,
@@ -377,7 +377,7 @@
   runTest(TEST_17, {'f': HType.UNKNOWN});
   runTest(TEST_18, {'f1': HType.INTEGER,
                     'f2': HType.STRING,
-                    'f3': HType.UNKNOWN});
+                    'f3': HType.NON_NULL});
   runTest(TEST_19, {'f1': HType.UNKNOWN,
                     'f2': HType.UNKNOWN,
                     'f3': HType.UNKNOWN});
diff --git a/tests/compiler/dart2js/field_type_simple_inferer_test.dart b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
new file mode 100644
index 0000000..1c393d7
--- /dev/null
+++ b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
@@ -0,0 +1,478 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '../../../sdk/lib/_internal/compiler/implementation/types/types.dart'
+    show TypeMask;
+
+import 'compiler_helper.dart';
+import 'parser_helper.dart';
+
+void compileAndFind(String code,
+                    String className,
+                    String memberName,
+                    bool disableInlining,
+                    check(compiler, element)) {
+  Uri uri = new Uri.fromComponents(scheme: 'source');
+  var compiler = compilerFor(code, uri);
+  compiler.runCompiler(uri);
+  compiler.disableInlining = disableInlining;
+  var cls = findElement(compiler, className);
+  var member = cls.lookupMember(buildSourceString(memberName));
+  return check(compiler.typesTask.typesInferrer, member);
+}
+
+const String TEST_1 = r"""
+  class A {
+    int f;
+  }
+  main() { new A(); }
+""";
+
+const String TEST_2 = r"""
+  class A {
+    int f1;
+    int f2 = 1;
+  }
+  main() { new A(); }
+""";
+
+const String TEST_3 = r"""
+  class A {
+    int f1;
+    int f2;
+    A() : f1 = 1;
+  }
+  main() { new A().f2 = 2; }
+""";
+
+const String TEST_4 = r"""
+  class A {
+    int f1;
+    int f2;
+    A() : f1 = 1;
+  }
+  main() {
+    A a = new A();
+    a.f1 = "a";
+    a.f2 = "a";
+  }
+""";
+
+const String TEST_5 = r"""
+  class A {
+    int f1 = 1;
+    int f2 = 1;
+    A(x) {
+      f1 = "1";
+      if (x) {
+        f2 = "1";
+      } else {
+        f2 = "2";
+      }
+    }
+  }
+  main() {
+    new A(true);
+    new A(false);
+  }
+""";
+
+const String TEST_6 = r"""
+  class A {
+    int f1 = 1;
+    int f2 = 1;
+    A(x) {
+      f1 = "1";
+      if (x) {
+        f2 = "1";
+      } else {
+        f2 = "2";
+      }
+      if (x) {
+        f2 = new List();
+      } else {
+        f2 = new List();
+      }
+    }
+  }
+  main() {
+    new A(true);
+    new A(false);
+  }
+""";
+
+const String TEST_7 = r"""
+  class A {
+    int f1 = 1;
+    int f2 = 1;
+    A(x) {
+      f1 = "1";
+      if (x) {
+        f2 = "1";
+      } else {
+        f2 = "2";
+      }
+      if (x) {
+        f1 = new List();
+        f2 = new List();
+      } else {
+        f2 = new List();
+      }
+    }
+  }
+  main() {
+    new A(true);
+    new A(false);
+  }
+""";
+
+const String TEST_8 = r"""
+  class A {
+    int f;
+    A(x) {
+      if (x) {
+        f = "1";
+      } else {
+      }
+    }
+  }
+  main() {
+    new A(true);
+    new A(false);
+  }
+""";
+
+const String TEST_9 = r"""
+  class A {
+    int f;
+    A(x) {
+      if (x) {
+      } else {
+        f = "1";
+      }
+    }
+  }
+  main() {
+    new A(true);
+    new A(false);
+  }
+""";
+
+const String TEST_10 = r"""
+  class A {
+    int f;
+    A() {
+      f = 1;
+    }
+    m() => f + 1;
+  }
+  void f(x) { x.f = "2"; }
+  main() {
+    A a;
+    f(a);
+    a = new A();
+    a.m();
+  }
+""";
+
+
+const String TEST_11 = r"""
+  class S {
+    int fs = 1;
+    ms() { fs = 1; }
+  }
+
+  class A extends S {
+    m() { ms(); }
+  }
+
+  main() {
+    A a = new A();
+    a.m();
+  }
+""";
+
+const String TEST_12 = r"""
+  class S {
+    int fs = 1;
+    S() { fs = "2"; }
+  }
+
+  class A extends S {
+  }
+
+  main() {
+    A a = new A();
+  }
+""";
+
+const String TEST_13 = r"""
+  class S {
+    int fs;
+    S() { fs = 1; }
+  }
+
+  class A extends S {
+    A() { fs = 1; }
+  }
+
+  main() {
+    A a = new A();
+  }
+""";
+
+const String TEST_14 = r"""
+  class A {
+    var f;
+    A() { f = 1; }
+    A.other() { f = 2; }
+  }
+
+  main() {
+    A a = new A();
+    a = new A.other();
+  }
+""";
+
+const String TEST_15 = r"""
+  class A {
+    var f;
+    A() { f = "1"; }
+    A.other() { f = new List(); }
+  }
+
+  main() {
+    A a = new A();
+    a = new A.other();
+  }
+""";
+
+const String TEST_16 = r"""
+  class A {
+    var f;
+    A() { f = "1"; }
+    A.other() : f = 1 { }
+  }
+
+  main() {
+    A a = new A();
+    a = new A.other();
+  }
+""";
+
+const String TEST_17 = r"""
+  g([p]) => p.f = 1;
+  class A {
+    var f;
+    A(x) {
+      var a;
+      if (x) {
+        a = this;
+      } else {
+        a = g;
+      }
+      a();
+    }
+  }
+  main() {
+    new A(true);
+    new A(false);
+  }
+""";
+
+const String TEST_18 = r"""
+  class A {
+    var f1;
+    var f2;
+    var f3;
+    A(x) {
+      f1 = 1;
+      var a;
+      if (x) {
+        f2 = "1";
+        a = this;
+      } else {
+        a = 1;
+        f2 = "1";
+      }
+      f3 = a;
+    }
+  }
+  main() {
+    new A(true);
+    new A(false);
+  }
+""";
+
+const String TEST_19 = r"""
+  class A {
+    var f1;
+    var f2;
+    var f3;
+    A(x) {
+      f1 = 1;
+      var a;
+      if (x) {
+        f2 = "1";
+        a = this;
+      } else {
+        a = 1;
+        f2 = "1";
+      }
+      f3 = a;
+      a();
+    }
+  }
+  main() {
+    new A(true);
+    new A(false);
+  }
+""";
+
+const String TEST_20 = r"""
+  class A {
+    var f;
+    A(x) {
+      for (var i in this) {
+      }
+      f = 42;
+    }
+  }
+  main() {
+    new A();
+  }
+""";
+
+const String TEST_21 = r"""
+  class A {
+    var f;
+    A() {
+      for (var i in this) {
+      }
+      f = 42;
+    }
+    get iterator => null;
+  }
+  main() {
+    new A();
+  }
+""";
+
+const String TEST_22 = r"""
+  class A {
+    var f1;
+    var f2;
+    var f3;
+    A() {
+      f1 = 42;
+      f2 = f1 == null ? 42 : f3 == null ? 41: 43;
+      f3 = 'foo';
+    }
+  }
+  main() {
+    new A();
+  }
+""";
+
+const String TEST_23 = r"""
+  class A {
+    var f1 = 42;
+    var f2 = 42;
+    var f3 = 42;
+    var f4 = 42;
+    A() {
+      // Test string interpolation.
+      '${f1 = null}';
+      // Test string juxtaposition.
+      ''
+      '${f2 = null}';
+      // Test list literal.
+      [f3 = null];
+      // Test map literal.
+      var c = {'foo': f4 = null };
+    }
+  }
+  main() {
+    new A();
+  }
+""";
+
+void doTest(String test, bool disableInlining, Map<String, Function> fields) {
+  fields.forEach((String name, Function f) {
+    compileAndFind(
+      test,
+      'A',
+      name,
+      disableInlining,
+      (inferrer, field) {
+        TypeMask type = f(inferrer);
+        TypeMask inferredType = inferrer.typeOf[field];
+        Expect.equals(type, inferredType);
+    });
+  });
+}
+
+void runTest(String test, Map<String, Function> fields) {
+  doTest(test, false, fields);
+  doTest(test, true, fields);
+}
+
+void test() {
+  runTest(TEST_1, {'f': (inferrer) => inferrer.nullType});
+  runTest(TEST_2, {'f1': (inferrer) => inferrer.nullType,
+                   'f2': (inferrer) => inferrer.intType});
+  runTest(TEST_3, {'f1': (inferrer) => inferrer.intType,
+                   'f2': (inferrer) => inferrer.intType.nullable()});
+  runTest(TEST_4, {'f1': (inferrer) => inferrer.giveUpType,
+                   'f2': (inferrer) => inferrer.stringType.nullable()});
+
+  // TODO(ngeoffray): We should try to infer that the initialization
+  // code at the declaration site of the fields does not matter.
+  runTest(TEST_5, {'f1': (inferrer) => inferrer.giveUpType,
+                   'f2': (inferrer) => inferrer.giveUpType});
+  runTest(TEST_6, {'f1': (inferrer) => inferrer.giveUpType,
+                   'f2': (inferrer) => inferrer.giveUpType});
+  runTest(TEST_7, {'f1': (inferrer) => inferrer.giveUpType,
+                   'f2': (inferrer) => inferrer.giveUpType});
+
+  runTest(TEST_8, {'f': (inferrer) => inferrer.stringType.nullable()});
+  runTest(TEST_9, {'f': (inferrer) => inferrer.stringType.nullable()});
+  runTest(TEST_10, {'f': (inferrer) => inferrer.giveUpType});
+  runTest(TEST_11, {'fs': (inferrer) => inferrer.intType});
+
+  // TODO(ngeoffray): We should try to infer that the initialization
+  // code at the declaration site of the fields does not matter.
+  runTest(TEST_12, {'fs': (inferrer) => inferrer.giveUpType});
+
+  runTest(TEST_13, {'fs': (inferrer) => inferrer.intType});
+  runTest(TEST_14, {'f': (inferrer) => inferrer.intType});
+  runTest(TEST_15, {'f': (inferrer) {
+                            ClassElement cls =
+                                inferrer.compiler.backend.jsIndexableClass;
+                            return new TypeMask.nonNullSubtype(cls.rawType);
+                         }});
+  runTest(TEST_16, {'f': (inferrer) => inferrer.giveUpType});
+  runTest(TEST_17, {'f': (inferrer) => inferrer.intType.nullable()});
+  runTest(TEST_18, {'f1': (inferrer) => inferrer.intType,
+                    'f2': (inferrer) => inferrer.stringType,
+                    'f3': (inferrer) => inferrer.dynamicType});
+  runTest(TEST_19, {'f1': (inferrer) => inferrer.intType,
+                    'f2': (inferrer) => inferrer.stringType,
+                    'f3': (inferrer) => inferrer.dynamicType});
+  runTest(TEST_20, {'f': (inferrer) => inferrer.intType});
+  runTest(TEST_21, {'f': (inferrer) => inferrer.intType.nullable()});
+
+  runTest(TEST_22, {'f1': (inferrer) => inferrer.intType,
+                    'f2': (inferrer) => inferrer.intType,
+                    'f3': (inferrer) => inferrer.stringType.nullable()});
+
+  runTest(TEST_23, {'f1': (inferrer) => inferrer.intType.nullable(),
+                    'f2': (inferrer) => inferrer.intType.nullable(),
+                    'f3': (inferrer) => inferrer.intType.nullable(),
+                    'f4': (inferrer) => inferrer.intType.nullable()});
+}
+
+void main() {
+  test();
+}
diff --git a/tests/compiler/dart2js/interceptor_test.dart b/tests/compiler/dart2js/interceptor_test.dart
index ff0076a..cc965b1 100644
--- a/tests/compiler/dart2js/interceptor_test.dart
+++ b/tests/compiler/dart2js/interceptor_test.dart
@@ -36,12 +36,12 @@
   var generated = compile(TEST_ONE, entry: 'foo');
   // Check that the one shot interceptor got converted to a direct
   // call to the interceptor object.
-  Expect.isTrue(generated.contains('CONSTANT.get\$toString(a + 42);'));
+  Expect.isTrue(generated.contains('JSNumber_methods.get\$toString(a + 42);'));
 
   // Check that one-shot interceptors preserve variable names, see
   // https://code.google.com/p/dart/issues/detail?id=8106.
   generated = compile(TEST_TWO, entry: 'foo');
-  Expect.isTrue(generated.contains(r'$.$$add$n(a, 42)'));
+  Expect.isTrue(generated.contains(r'$.$add$n(a, 42)'));
   Expect.isTrue(generated.contains('myVariableName'));
 
   // Check that an intercepted getter that does not need to be
diff --git a/tests/compiler/dart2js/metadata_test.dart b/tests/compiler/dart2js/metadata_test.dart
index b90ca18..c0a521c 100644
--- a/tests/compiler/dart2js/metadata_test.dart
+++ b/tests/compiler/dart2js/metadata_test.dart
@@ -150,9 +150,12 @@
 
     Uri uri = new Uri.fromComponents(scheme: 'source', path: 'main.dart');
 
+    Uri async = new Uri.fromComponents(scheme: 'dart', path: 'async');
+
     var compiler = compilerFor(source, uri)
         ..registerSource(partUri, partSource)
         ..registerSource(libUri, libSource)
+        ..registerSource(async, 'class DeferredLibrary {}')
         ..runCompiler(uri);
     compiler.enqueuer.resolution.queueIsClosed = false;
     LibraryElement element = compiler.libraries['$uri'];
diff --git a/tests/compiler/dart2js/mini_parser_test.dart b/tests/compiler/dart2js/mini_parser_test.dart
index 369c3b0..7227f28 100644
--- a/tests/compiler/dart2js/mini_parser_test.dart
+++ b/tests/compiler/dart2js/mini_parser_test.dart
@@ -4,6 +4,7 @@
 
 // Simple test to ensure that mini_parser keeps working.
 
+import 'dart:io';
 import '../../../sdk/lib/_internal/compiler/implementation/tools/mini_parser.dart'
     as tool;
 
diff --git a/tests/compiler/dart2js/minify_many_locals_test.dart b/tests/compiler/dart2js/minify_many_locals_test.dart
index 98260b9..dadd15c 100644
--- a/tests/compiler/dart2js/minify_many_locals_test.dart
+++ b/tests/compiler/dart2js/minify_many_locals_test.dart
@@ -7,15 +7,15 @@
 
 main() {
   var buffer = new StringBuffer();
-  buffer.add("var foo(");
+  buffer.write("var foo(");
   for (int i = 0; i < 2000; i++) {
-    buffer.add("x$i, ");
+    buffer.write("x$i, ");
   }
-  buffer.add("x) { int i = ");
+  buffer.write("x) { int i = ");
   for (int i = 0; i < 2000; i++) {
-    buffer.add("x$i+");
+    buffer.write("x$i+");
   }
-  buffer.add("2000; return i; }");
+  buffer.write("2000; return i; }");
   var generated = compile(buffer.toString(), entry: 'foo', minify: true);
   RegExp re = new RegExp(r"\(a,b,c");
   Expect.isTrue(re.hasMatch(generated));
diff --git a/tests/compiler/dart2js/mirrors_test.dart b/tests/compiler/dart2js/mirrors_test.dart
index 9f10a8c..f32e36e 100644
--- a/tests/compiler/dart2js/mirrors_test.dart
+++ b/tests/compiler/dart2js/mirrors_test.dart
@@ -4,6 +4,7 @@
 
 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart';
 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart';
+import '../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart';
 
 import 'dart:io';
 
@@ -38,11 +39,14 @@
   var dirPath = scriptPath.directoryPath;
   var libPath = dirPath.join(new Path('../../../sdk/'));
   var inputPath = dirPath.join(new Path('mirrors_helper.dart'));
-  var compilation = new Compilation.library([inputPath], libPath, null,
-      <String>['--preserve-comments']);
-  Expect.isNotNull(compilation, "No compilation created");
+  var result = analyze([inputPath], libPath,
+                       options: <String>['--preserve-comments']);
+  result.then((MirrorSystem mirrors) {
+    test(mirrors);
+  });
+}
 
-  var mirrors = compilation.mirrors;
+void test(MirrorSystem mirrors) {
   Expect.isNotNull(mirrors, "No mirror system returned from compilation");
 
   var libraries = mirrors.libraries;
@@ -106,7 +110,7 @@
                 "Unexpected library returned from type");
 
   Expect.isFalse(fooClass.isObject, "Class is Object");
-  Expect.isFalse(fooClass.isDynamic, "Class is Dynamic");
+  Expect.isFalse(fooClass.isDynamic, "Class is dynamic");
   Expect.isFalse(fooClass.isVoid, "Class is void");
   Expect.isFalse(fooClass.isTypeVariable, "Class is a type variable");
   Expect.isFalse(fooClass.isTypedef, "Class is a typedef");
@@ -433,7 +437,7 @@
                 "Unexpected library returned from type");
 
   Expect.isFalse(barClass.isObject, "Interface is Object");
-  Expect.isFalse(barClass.isDynamic, "Interface is Dynamic");
+  Expect.isFalse(barClass.isDynamic, "Interface is dynamic");
   Expect.isFalse(barClass.isVoid, "Interface is void");
   Expect.isFalse(barClass.isTypeVariable, "Interface is a type variable");
   Expect.isFalse(barClass.isTypedef, "Interface is a typedef");
@@ -527,7 +531,7 @@
                 "Unexpected library returned from type");
 
   Expect.isFalse(bazClass.isObject, "Class is Object");
-  Expect.isFalse(bazClass.isDynamic, "Class is Dynamic");
+  Expect.isFalse(bazClass.isDynamic, "Class is dynamic");
   Expect.isFalse(bazClass.isVoid, "Class is void");
   Expect.isFalse(bazClass.isTypeVariable, "Class is a type variable");
   Expect.isFalse(bazClass.isTypedef, "Class is a typedef");
@@ -638,12 +642,12 @@
 
   var dynamicType = method1.returnType;
   Expect.isNotNull(dynamicType, "Return type was null");
-  Expect.isFalse(dynamicType.isObject, "Dynamic is Object");
-  Expect.isTrue(dynamicType.isDynamic, "Dynamic is not Dynamic");
-  Expect.isFalse(dynamicType.isVoid, "Dynamic is void");
-  Expect.isFalse(dynamicType.isTypeVariable, "Dynamic is a type variable");
-  Expect.isFalse(dynamicType.isTypedef, "Dynamic is a typedef");
-  Expect.isFalse(dynamicType.isFunction, "Dynamic is a function");
+  Expect.isFalse(dynamicType.isObject, "dynamic is Object");
+  Expect.isTrue(dynamicType.isDynamic, "dynamic is not dynamic");
+  Expect.isFalse(dynamicType.isVoid, "dynamic is void");
+  Expect.isFalse(dynamicType.isTypeVariable, "dynamic is a type variable");
+  Expect.isFalse(dynamicType.isTypedef, "dynamic is a typedef");
+  Expect.isFalse(dynamicType.isFunction, "dynamic is a function");
 
   var method1Parameters = method1.parameters;
   Expect.isNotNull(method1Parameters, "Method parameters is null");
@@ -693,7 +697,7 @@
   var voidType = method2.returnType;
   Expect.isNotNull(voidType, "Return type was null");
   Expect.isFalse(voidType.isObject, "void is Object");
-  Expect.isFalse(voidType.isDynamic, "void is Dynamic");
+  Expect.isFalse(voidType.isDynamic, "void is dynamic");
   Expect.isTrue(voidType.isVoid, "void is not void");
   Expect.isFalse(voidType.isTypeVariable, "void is a type variable");
   Expect.isFalse(voidType.isTypedef, "void is a typedef");
@@ -807,7 +811,7 @@
   Expect.stringEquals("mirrors_helper.Func", funcTypedef.qualifiedName,
                       "Unexpected simpleName");
   Expect.isFalse(funcTypedef.isObject, "Typedef is Object");
-  Expect.isFalse(funcTypedef.isDynamic, "Typedef is Dynamic");
+  Expect.isFalse(funcTypedef.isDynamic, "Typedef is dynamic");
   Expect.isFalse(funcTypedef.isVoid, "Typedef is void");
   Expect.isFalse(funcTypedef.isTypeVariable, "Typedef is a type variable");
   Expect.isTrue(funcTypedef.isTypedef, "Typedef is not a typedef");
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index 149ccf3..6e52aae 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -55,6 +55,8 @@
   class Null {}
   class Dynamic_ {}
   class LinkedHashMap {}
+  class ConstantMap {}
+  class TypeImpl {}
   S() {}
   unwrapException(e) {}
   assertHelper(a){}
@@ -62,14 +64,23 @@
   throwNoSuchMethod(obj, name, arguments, expectedArgumentNames) {}
   throwAbstractClassInstantiationError(className) {}''';
 
+const String FOREIGN_LIBRARY = r'''
+  dynamic JS(String typeDescription, String codeTemplate,
+    [var arg0, var arg1, var arg2, var arg3, var arg4, var arg5, var arg6,
+     var arg7, var arg8, var arg9, var arg10, var arg11]) {}''';
+
 const String DEFAULT_INTERCEPTORSLIB = r'''
-  class JSArray implements List {
+  class JSIndexable {}
+  class JSArray implements List, JSIndexable {
     var length;
     operator[](index) {}
     operator[]=(index, value) {}
     var add;
   }
-  class JSString implements String {
+  class JSMutableArray extends JSArray {}
+  class JSFixedArray extends JSMutableArray {}
+  class JSExtendableArray extends JSMutableArray {}
+  class JSString implements String, JSIndexable {
     var length;
     operator[](index) {}
     toString() {}
@@ -121,7 +132,7 @@
   class String implements Pattern {}
   class Object {
     operator ==(other) {}
-    String toString() {}
+    String toString() { return null; }
   }
   class Type {}
   class Function {}
@@ -132,7 +143,7 @@
     DateTime.utc(year);
   }
   abstract class Pattern {}
-  bool identical(Object a, Object b) {}''';
+  bool identical(Object a, Object b) { return null; }''';
 
 const String DEFAULT_ISOLATE_HELPERLIB = r'''
   class _WorkerBase {}''';
@@ -163,6 +174,7 @@
     // We need to set the assert method to avoid calls with a 'null'
     // target being interpreted as a call to assert.
     jsHelperLibrary = createLibrary("helper", helperSource);
+    foreignLibrary = createLibrary("foreign", FOREIGN_LIBRARY);
     interceptorsLibrary = createLibrary("interceptors", interceptorsSource);
     isolateHelperLibrary = createLibrary("isolate_helper", isolateHelperSource);
 
@@ -208,6 +220,7 @@
     parseScript(source, library);
     library.setExports(library.localScope.values.toList());
     registerSource(uri, source);
+    libraries.putIfAbsent(uri.toString(), () => library);
     return library;
   }
 
diff --git a/tests/compiler/dart2js/patch_test.dart b/tests/compiler/dart2js/patch_test.dart
index 272bf9d..529c716 100644
--- a/tests/compiler/dart2js/patch_test.dart
+++ b/tests/compiler/dart2js/patch_test.dart
@@ -5,6 +5,9 @@
 import "../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart";
 import "../../../sdk/lib/_internal/compiler/implementation/elements/elements.dart";
 import "../../../sdk/lib/_internal/compiler/implementation/tree/tree.dart";
+import
+    "../../../sdk/lib/_internal/compiler/implementation/universe/universe.dart"
+        show TypedSelector;
 import "../../../sdk/lib/_internal/compiler/implementation/util/util.dart";
 import "mock_compiler.dart";
 import "parser_helper.dart";
@@ -696,6 +699,61 @@
       compiler.warnings[0].message.kind == MessageKind.PATCH_POINT_TO_FUNCTION);
 }
 
+testPatchAndSelector() {
+  var compiler = applyPatch(
+      """
+      class A {
+        external void clear();
+      }
+      class B extends A {
+      }
+      """,
+      """
+      patch class A {
+        int method() => 0;
+        patch void clear() {}
+      }
+      """);
+  ClassElement cls = ensure(compiler, "A", compiler.coreLibrary.find,
+                            expectIsPatched: true);
+  cls.ensureResolved(compiler);
+
+  ensure(compiler, "method", cls.patch.lookupLocalMember,
+         checkHasBody: true, expectIsRegular: true);
+
+  ensure(compiler, "clear", cls.lookupLocalMember,
+         checkHasBody: true, expectIsPatched: true);
+
+  compiler.phase = Compiler.PHASE_DONE_RESOLVING;
+
+  // Check that a method just in the patch class is a target for a
+  // typed selector.
+  var selector = new Selector.call(
+      buildSourceString('method'), compiler.coreLibrary, 0);
+  var typedSelector = new TypedSelector.exact(cls.rawType, selector);
+  Element method =
+      cls.implementation.lookupLocalMember(buildSourceString('method'));
+  Expect.isTrue(selector.applies(method, compiler));
+  Expect.isTrue(typedSelector.applies(method, compiler));
+
+  // Check that the declaration method in the declaration class is a target
+  // for a typed selector.
+  selector = new Selector.call(
+      buildSourceString('clear'), compiler.coreLibrary, 0);
+  typedSelector = new TypedSelector.exact(cls.rawType, selector);
+  method = cls.lookupLocalMember(buildSourceString('clear'));
+  Expect.isTrue(selector.applies(method, compiler));
+  Expect.isTrue(typedSelector.applies(method, compiler));
+
+  // Check that the declaration method in the declaration class is a target
+  // for a typed selector on a subclass.
+  cls = ensure(compiler, "B", compiler.coreLibrary.find);
+  cls.ensureResolved(compiler);
+  typedSelector = new TypedSelector.exact(cls.rawType, selector);
+  Expect.isTrue(selector.applies(method, compiler));
+  Expect.isTrue(typedSelector.applies(method, compiler));
+}
+
 main() {
   testPatchConstructor();
   testPatchFunction();
@@ -723,4 +781,6 @@
   testPatchNonSetter();
   testPatchNoSetter();
   testPatchNonFunction();
+
+  testPatchAndSelector();
 }
diff --git a/tests/compiler/dart2js/return_type_inferer_test.dart b/tests/compiler/dart2js/return_type_inferer_test.dart
index 1dd60ff..6878a80 100644
--- a/tests/compiler/dart2js/return_type_inferer_test.dart
+++ b/tests/compiler/dart2js/return_type_inferer_test.dart
@@ -82,9 +82,9 @@
   runTest(TEST_FOUR, HType.DOUBLE);
   runTest(TEST_FIVE, HType.NUMBER);
   runTest(TEST_SIX, HType.NUMBER);
-  runTest(TEST_SEVEN);
+  runTest(TEST_SEVEN, HType.NON_NULL);
   runTest(TEST_EIGHT, HType.INTEGER);
-  runTest(TEST_NINE);
+  runTest(TEST_NINE, HType.NON_NULL);
   runTest(TEST_TEN);
 }
 
diff --git a/tests/compiler/dart2js/simple_inferrer_and_or_test.dart b/tests/compiler/dart2js/simple_inferrer_and_or_test.dart
index 21c0f8d..c98657f 100644
--- a/tests/compiler/dart2js/simple_inferrer_and_or_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_and_or_test.dart
@@ -42,7 +42,7 @@
     Expect.equals(type, typesInferrer.returnTypeOf[element]);
   }
 
-  checkReturn('returnDyn1', compiler.dynamicClass);
-  checkReturn('returnDyn2', compiler.dynamicClass);
-  checkReturn('returnDyn3', compiler.dynamicClass);
+  checkReturn('returnDyn1', typesInferrer.dynamicType);
+  checkReturn('returnDyn2', typesInferrer.dynamicType);
+  checkReturn('returnDyn3', typesInferrer.dynamicType);
 }
diff --git a/tests/compiler/dart2js/simple_inferrer_closure_test.dart b/tests/compiler/dart2js/simple_inferrer_closure_test.dart
index d9351e3..c3f9a9a 100644
--- a/tests/compiler/dart2js/simple_inferrer_closure_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_closure_test.dart
@@ -44,7 +44,7 @@
   var a = 42;
   if (a == 53) {
     var f = () {
-      a = 32;
+      return a;
     };
   }
   return a;
@@ -60,6 +60,12 @@
   return a;
 }
 
+returnInt4() {
+  var a = 42;
+  g() { return a; }
+  return g();
+}
+
 main() {
   returnInt1();
   returnDyn1();
@@ -67,6 +73,7 @@
   returnDyn2();
   returnInt3();
   returnDyn3();
+  returnInt4();
 }
 """;
 
@@ -82,13 +89,15 @@
     Expect.equals(type, typesInferrer.returnTypeOf[element]);
   }
 
-  checkReturn('returnInt1', compiler.intClass);
-  checkReturn('returnInt2', compiler.intClass);
-  checkReturn('returnInt3', compiler.intClass);
+  checkReturn('returnInt1', typesInferrer.intType);
+  // TODO(ngeoffray): We don't use types of mutated captured
+  // variables anymore, because they could lead to optimistic results
+  // needing to be re-analyzed.
+  checkReturn('returnInt2', typesInferrer.dynamicType);
+  checkReturn('returnInt3', typesInferrer.intType);
+  checkReturn('returnInt4', typesInferrer.intType);
 
-  checkReturn('returnDyn1', compiler.dynamicClass);
-  checkReturn('returnDyn2', compiler.dynamicClass);
-  checkReturn('returnDyn3', compiler.dynamicClass);
-
-  print(typesInferrer.returnTypeOf);
+  checkReturn('returnDyn1', typesInferrer.dynamicType);
+  checkReturn('returnDyn2', typesInferrer.dynamicType);
+  checkReturn('returnDyn3', typesInferrer.dynamicType);
 }
diff --git a/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart b/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart
new file mode 100644
index 0000000..92e80e49
--- /dev/null
+++ b/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart
@@ -0,0 +1,39 @@
+// 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 a non-used generative constructor does not prevent
+// infering types for fields.
+
+import 'compiler_helper.dart';
+import 'parser_helper.dart';
+
+const String TEST = """
+
+class A {
+  final intField;
+  final stringField;
+  A() : intField = 42, stringField = 'foo';
+  A.bar() : intField = 54, stringField = 42;
+}
+
+main() {
+  new A();
+}
+""";
+
+void main() {
+  Uri uri = new Uri.fromComponents(scheme: 'source');
+  var compiler = compilerFor(TEST, uri);
+  compiler.runCompiler(uri);
+  var typesInferrer = compiler.typesTask.typesInferrer;
+
+  checkFieldTypeInClass(String className, String fieldName, type) {
+    var cls = findElement(compiler, className);
+    var element = cls.lookupLocalMember(buildSourceString(fieldName));
+    Expect.equals(type, typesInferrer.typeOf[element]);
+  }
+
+  checkFieldTypeInClass('A', 'intField', typesInferrer.intType);
+  checkFieldTypeInClass('A', 'stringField', typesInferrer.stringType);
+}
diff --git a/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart b/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart
new file mode 100644
index 0000000..653f543
--- /dev/null
+++ b/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart
@@ -0,0 +1,37 @@
+// 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 we are analyzing field parameters correctly.
+
+import 'compiler_helper.dart';
+import 'parser_helper.dart';
+
+const String TEST = """
+
+class A {
+  final dynamicField;
+  A() : dynamicField = 42;
+  A.bar(this.dynamicField);
+}
+
+main() {
+  new A();
+  new A.bar('foo');
+}
+""";
+
+void main() {
+  Uri uri = new Uri.fromComponents(scheme: 'source');
+  var compiler = compilerFor(TEST, uri);
+  compiler.runCompiler(uri);
+  var typesInferrer = compiler.typesTask.typesInferrer;
+
+  checkFieldTypeInClass(String className, String fieldName, type) {
+    var cls = findElement(compiler, className);
+    var element = cls.lookupLocalMember(buildSourceString(fieldName));
+    Expect.equals(type, typesInferrer.typeOf[element]);
+  }
+
+  checkFieldTypeInClass('A', 'dynamicField', typesInferrer.dynamicType);
+}
diff --git a/tests/compiler/dart2js/simple_inferrer_final_field_test.dart b/tests/compiler/dart2js/simple_inferrer_final_field_test.dart
new file mode 100644
index 0000000..5f82f9e
--- /dev/null
+++ b/tests/compiler/dart2js/simple_inferrer_final_field_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'compiler_helper.dart';
+import 'parser_helper.dart';
+
+const String TEST = """
+
+class A {
+  final intField;
+  final giveUpField;
+  A() : intField = 42, giveUpField = 'foo';
+  A.bar() : intField = 54, giveUpField = 42;
+}
+
+main() {
+  new A();
+  new A.bar();
+}
+""";
+
+void main() {
+  Uri uri = new Uri.fromComponents(scheme: 'source');
+  var compiler = compilerFor(TEST, uri);
+  compiler.runCompiler(uri);
+  var typesInferrer = compiler.typesTask.typesInferrer;
+
+  checkFieldTypeInClass(String className, String fieldName, type) {
+    var cls = findElement(compiler, className);
+    var element = cls.lookupLocalMember(buildSourceString(fieldName));
+    Expect.equals(type, typesInferrer.typeOf[element]);
+  }
+
+  checkFieldTypeInClass('A', 'intField', typesInferrer.intType);
+  checkFieldTypeInClass('A', 'giveUpField', typesInferrer.giveUpType);
+}
diff --git a/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart b/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart
new file mode 100644
index 0000000..144b2d0
--- /dev/null
+++ b/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart
@@ -0,0 +1,90 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'compiler_helper.dart';
+import 'parser_helper.dart';
+
+const String TEST = """
+
+class A {
+  get foo => 'string';
+  set foo(value) {}
+  operator[](index) => 'string';
+  operator[]=(index, value) {}
+  
+  returnDynamic1() => foo--;
+  returnNum1() => --foo;
+  returnNum2() => foo -= 42;
+
+  returnDynamic2() => this[index]--;
+  returnNum3() => --this[index];
+  returnNum4() => this[index] -= 42;
+
+  returnDynamic3() => this.bar--;
+  returnNum5() => --this.bar;
+  returnNum6() => this.bar -= 42;
+}
+
+class B extends A {
+  get foo() => 42;
+  operator[](index) => 42;
+
+  returnString1() => super.foo--;
+  returnDynamic1() => --super.foo;
+  returnDynamic2() => super.foo -= 42;
+
+  returnString2() => super[index]--;
+  returnDynamic3() => --super[index];
+  returnDynamic4() => super[index] -= 42;
+}
+
+main() {
+  new A()..returnNum1()
+         ..returnNum2()
+         ..returnNum3()
+         ..returnNum4()
+         ..returnNum5()
+         ..returnNum6()
+         ..returnDynamic1()
+         ..returnDynamic2()
+         ..returnDynamic3();
+
+  new B()..returnString1()
+         ..returnString2()
+         ..returnDynamic1()
+         ..returnDynamic2()
+         ..returnDynamic3()
+         ..returnDynamic4();
+}
+""";
+
+void main() {
+  Uri uri = new Uri.fromComponents(scheme: 'source');
+  var compiler = compilerFor(TEST, uri);
+  compiler.runCompiler(uri);
+  var typesInferrer = compiler.typesTask.typesInferrer;
+
+  checkReturnInClass(String className, String methodName, type) {
+    var cls = findElement(compiler, className);
+    var element = cls.lookupLocalMember(buildSourceString(methodName));
+    Expect.equals(type, typesInferrer.returnTypeOf[element]);
+  }
+
+  checkReturnInClass('A', 'returnNum1', typesInferrer.numType);
+  checkReturnInClass('A', 'returnNum2', typesInferrer.numType);
+  checkReturnInClass('A', 'returnNum3', typesInferrer.numType);
+  checkReturnInClass('A', 'returnNum4', typesInferrer.numType);
+  checkReturnInClass('A', 'returnNum5', typesInferrer.numType);
+  checkReturnInClass('A', 'returnNum6', typesInferrer.numType);
+  checkReturnInClass('A', 'returnDynamic1', typesInferrer.dynamicType);
+  checkReturnInClass('A', 'returnDynamic2', typesInferrer.dynamicType);
+  checkReturnInClass('A', 'returnDynamic3', typesInferrer.dynamicType);
+
+  checkReturnInClass('B', 'returnString1', typesInferrer.stringType);
+  checkReturnInClass('B', 'returnString2', typesInferrer.stringType);
+  checkReturnInClass('B', 'returnDynamic1', typesInferrer.dynamicType);
+  checkReturnInClass('B', 'returnDynamic2', typesInferrer.dynamicType);
+  checkReturnInClass('B', 'returnDynamic3', typesInferrer.dynamicType);
+  checkReturnInClass('B', 'returnDynamic4', typesInferrer.dynamicType);
+}
diff --git a/tests/compiler/dart2js/simple_inferrer_test.dart b/tests/compiler/dart2js/simple_inferrer_test.dart
index 58afca9..ff250e0 100644
--- a/tests/compiler/dart2js/simple_inferrer_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_test.dart
@@ -2,7 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import
+    '../../../sdk/lib/_internal/compiler/implementation/types/types.dart'
+    show TypeMask;
+
 import 'compiler_helper.dart';
+import 'parser_helper.dart';
 
 const String TEST = """
 returnNum1(a) {
@@ -15,7 +20,7 @@
   else return 2;
 }
 
-returnInt(a) {
+returnInt1(a) {
   if (a) return 1;
   else return 2;
 }
@@ -30,12 +35,89 @@
   else return 'foo';
 }
 
+returnInt2() {
+  var a = 42;
+  return a++;
+}
+
+returnNum3() {
+  var a = 42;
+  return ++a;
+}
+
+returnNum4() {
+  var a = 42;
+  a++;
+  return a;
+}
+
+returnIntOrNull(a) {
+  if (a) return 42;
+}
+
+returnInt3(a) {
+  if (a) return 42;
+  throw 42;
+}
+
+get topLevelGetter => 42;
+returnDynamic() => topLevelGetter(42);
+
+class A {
+  factory A() = A.generative;
+  A.generative();
+
+  get myField => 42;
+  set myField(a) {}
+  returnNum1() => ++myField;
+  returnNum2() => ++this.myField;
+  returnNum3() => this.myField += 42;
+  returnNum4() => myField += 42;
+  operator[](index) => 42;
+  operator[]= (index, value) {}
+  returnNum5() => ++this[0];
+  returnNum6() => this[0] += 1;
+}
+
+class B extends A {
+  B() : super.generative();
+  returnNum1() => ++new A().myField;
+  returnNum2() => new A().myField += 4;
+  returnNum3() => ++new A()[0];
+  returnNum4() => new A()[0] += 42;
+  returnNum5() => ++super.myField;
+  returnNum6() => super.myField += 4;
+  returnNum7() => ++super[0];
+  returnNum8() => super[0] += 54;
+}
+
 main() {
   returnNum1(true);
   returnNum2(true);
-  returnInt(true);
+  returnInt1(true);
+  returnInt2(true);
+  returnInt3(true);
   returnDouble(true);
   returnGiveUp(true);
+  returnNum3();
+  returnNum4();
+  returnIntOrNull(true);
+  returnDynamic();
+  new A()..returnNum1()
+         ..returnNum2()
+         ..returnNum3()
+         ..returnNum4()
+         ..returnNum5()
+         ..returnNum6();
+
+  new B()..returnNum1()
+         ..returnNum2()
+         ..returnNum3()
+         ..returnNum4()
+         ..returnNum5()
+         ..returnNum6()
+         ..returnNum7()
+         ..returnNum8();
 }
 """;
 
@@ -45,18 +127,49 @@
   compiler.runCompiler(uri);
   var typesInferrer = compiler.typesTask.typesInferrer;
 
-  var element = findElement(compiler, 'returnNum1');
-  Expect.equals(compiler.numClass, typesInferrer.returnTypeOf[element]);
+  checkReturn(String name, type) {
+    var element = findElement(compiler, name);
+    Expect.equals(type, typesInferrer.returnTypeOf[element]);
+  }
+  checkReturn('returnNum1', typesInferrer.numType);
+  checkReturn('returnNum2', typesInferrer.numType);
+  checkReturn('returnInt1', typesInferrer.intType);
+  checkReturn('returnInt2', typesInferrer.intType);
+  checkReturn('returnDouble', typesInferrer.doubleType);
+  checkReturn('returnGiveUp', typesInferrer.giveUpType);
+  checkReturn('returnNum3', typesInferrer.numType);
+  checkReturn('returnNum4', typesInferrer.numType);
+  checkReturn('returnIntOrNull', typesInferrer.intType.nullable());
+  checkReturn('returnInt3', typesInferrer.intType);
+  checkReturn('returnDynamic', typesInferrer.dynamicType);
 
-  element = findElement(compiler, 'returnNum2');
-  Expect.equals(compiler.numClass, typesInferrer.returnTypeOf[element]);
+  checkReturnInClass(String className, String methodName, type) {
+    var cls = findElement(compiler, className);
+    var element = cls.lookupLocalMember(buildSourceString(methodName));
+    Expect.equals(type, typesInferrer.returnTypeOf[element]);
+  }
 
-  element = findElement(compiler, 'returnInt');
-  Expect.equals(compiler.intClass, typesInferrer.returnTypeOf[element]);
+  checkReturnInClass('A', 'returnNum1', typesInferrer.numType);
+  checkReturnInClass('A', 'returnNum2', typesInferrer.numType);
+  checkReturnInClass('A', 'returnNum3', typesInferrer.numType);
+  checkReturnInClass('A', 'returnNum4', typesInferrer.numType);
+  checkReturnInClass('A', 'returnNum5', typesInferrer.numType);
+  checkReturnInClass('A', 'returnNum6', typesInferrer.numType);
 
-  element = findElement(compiler, 'returnDouble');
-  Expect.equals(compiler.doubleClass, typesInferrer.returnTypeOf[element]);
+  checkReturnInClass('B', 'returnNum1', typesInferrer.numType);
+  checkReturnInClass('B', 'returnNum2', typesInferrer.numType);
+  checkReturnInClass('B', 'returnNum3', typesInferrer.numType);
+  checkReturnInClass('B', 'returnNum4', typesInferrer.numType);
+  checkReturnInClass('B', 'returnNum5', typesInferrer.numType);
+  checkReturnInClass('B', 'returnNum6', typesInferrer.numType);
+  checkReturnInClass('B', 'returnNum7', typesInferrer.numType);
+  checkReturnInClass('B', 'returnNum8', typesInferrer.numType);
 
-  element = findElement(compiler, 'returnGiveUp');
-  Expect.equals(typesInferrer.giveUpType, typesInferrer.returnTypeOf[element]);
+  checkFactoryConstructor(String className) {
+    var cls = findElement(compiler, className);
+    var element = cls.localLookup(buildSourceString(className));
+    Expect.equals(new TypeMask.nonNullExact(cls.rawType),
+                  typesInferrer.returnTypeOf[element]);
+  }
+  checkFactoryConstructor('A');
 }
diff --git a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart b/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
index 700b5f8..150d2c7 100644
--- a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
@@ -140,14 +140,14 @@
     Expect.equals(type, typesInferrer.returnTypeOf[element]);
   }
 
-  checkReturn('returnInt1', compiler.intClass);
-  checkReturn('returnInt2', compiler.intClass);
-  checkReturn('returnInt3', compiler.intClass);
-  checkReturn('returnInt4', compiler.intClass);
-  checkReturn('returnInt5', compiler.intClass);
+  checkReturn('returnInt1', typesInferrer.intType);
+  checkReturn('returnInt2', typesInferrer.intType);
+  checkReturn('returnInt3', typesInferrer.intType);
+  checkReturn('returnInt4', typesInferrer.intType);
+  checkReturn('returnInt5', typesInferrer.intType);
 
-  checkReturn('returnDyn1', compiler.dynamicClass);
-  checkReturn('returnDyn2', compiler.dynamicClass);
-  checkReturn('returnDyn3', compiler.dynamicClass);
-  checkReturn('returnDyn4', compiler.dynamicClass);
+  checkReturn('returnDyn1', typesInferrer.dynamicType);
+  checkReturn('returnDyn2', typesInferrer.dynamicType);
+  checkReturn('returnDyn3', typesInferrer.dynamicType);
+  checkReturn('returnDyn4', typesInferrer.dynamicType);
 }
diff --git a/tests/compiler/dart2js/subtype_test.dart b/tests/compiler/dart2js/subtype_test.dart
index daded9a..11534ce 100644
--- a/tests/compiler/dart2js/subtype_test.dart
+++ b/tests/compiler/dart2js/subtype_test.dart
@@ -11,15 +11,22 @@
 
 void main() {
   testInterfaceSubtype();
+  testCallableSubtype();
+  testFunctionSubtyping();
+  testTypedefSubtyping();
+  testFunctionSubtypingOptional();
+  testTypedefSubtypingOptional();
+  testFunctionSubtypingNamed();
+  testTypedefSubtypingNamed();
 }
 
 void testInterfaceSubtype() {
   var env = new TypeEnvironment(r"""
       class A<T> {}
-      class B<T1,T2> extends A<T1> {}
+      class B<T1, T2> extends A<T1> {}
       // TODO(johnniwinther): Inheritance with different type arguments is
       // currently not supported by the implementation.
-      class C<T1,T2> extends B<T2,T1> /*implements A<A<T1>>*/ {}
+      class C<T1, T2> extends B<T2, T1> /*implements A<A<T1>>*/ {}
       """);
 
   void expect(bool value, DartType T, DartType S) {
@@ -215,4 +222,273 @@
   expect(false, C_int_String, instantiate(A, [A_String]));
 }
 
+void testCallableSubtype() {
 
+  var env = new TypeEnvironment(r"""
+      class U {}
+      class V extends U {}
+      class W extends V {}
+      class A {
+        int call(V v, int i);
+
+        int m1(U u, int i);
+        int m2(W w, num n);
+        U m3(V v, int i);
+        int m4(V v, U u);
+        void m5(V v, int i);
+      }
+      """);
+
+  void expect(bool value, DartType T, DartType S) {
+    Expect.equals(value, env.isSubtype(T, S), '$T <: $S');
+  }
+
+  ClassElement classA = env.getElement('A');
+  DartType A = classA.rawType;
+  DartType function = env['Function'];
+  DartType m1 = env.getMemberType(classA, 'm1');
+  DartType m2 = env.getMemberType(classA, 'm2');
+  DartType m3 = env.getMemberType(classA, 'm3');
+  DartType m4 = env.getMemberType(classA, 'm4');
+  DartType m5 = env.getMemberType(classA, 'm5');
+
+  expect(true, A, function);
+  expect(true, A, m1);
+  expect(true, A, m2);
+  expect(false, A, m3);
+  expect(false, A, m4);
+  expect(true, A, m5);
+}
+
+testFunctionSubtyping() {
+  var env = new TypeEnvironment(r"""
+      void void_() {}
+      void void_2() {}
+      int int_() => 0;
+      int int_2() => 0;
+      Object Object_() => null;
+      double double_() => 0.0;
+      void void__int(int i) {}
+      int int__int(int i) => 0;
+      int int__int2(int i) => 0;
+      int int__Object(Object o) => 0;
+      Object Object__int(int i) => null;
+      int int__double(double d) => 0;
+      int int__int_int(int i1, int i2) => 0;
+      void inline_void_(void f()) {}
+      void inline_void__int(void f(int i)) {}
+      """);
+  functionSubtypingHelper(env);
+}
+
+testTypedefSubtyping() {
+  var env = new TypeEnvironment(r"""
+      typedef void void_();
+      typedef void void_2();
+      typedef int int_();
+      typedef int int_2();
+      typedef Object Object_();
+      typedef double double_();
+      typedef void void__int(int i);
+      typedef int int__int(int i);
+      typedef int int__int2(int i);
+      typedef int int__Object(Object o);
+      typedef Object Object__int(int i);
+      typedef int int__double(double d);
+      typedef int int__int_int(int i1, int i2);
+      typedef void inline_void_(void f());
+      typedef void inline_void__int(void f(int i));
+      """);
+  functionSubtypingHelper(env);
+}
+
+functionSubtypingHelper(TypeEnvironment env) {
+  void expect(bool expectedResult, String sub, String sup) {
+    DartType subtype = env.getElementType(sub);
+    DartType supertype = env.getElementType(sup);
+    Expect.equals(expectedResult, env.isSubtype(subtype, supertype),
+        '$subtype <: $supertype');
+  }
+
+  // () -> int <: Function
+  expect(true, 'int_', 'Function');
+  // Function <: () -> int
+  expect(false, 'Function', 'int_');
+
+  // () -> int <: () -> void
+  expect(true, 'int_', 'void_');
+  // () -> void <: () -> int
+  expect(false, 'void_', 'int_');
+  // () -> void <: () -> void
+  expect(true, 'void_', 'void_2');
+  // () -> int <: () -> int
+  expect(true, 'int_', 'int_2');
+  // () -> int <: () -> Object
+  expect(true, 'int_', 'Object_');
+  // () -> int <: () -> double
+  expect(false, 'int_', 'double_');
+  // () -> int <: (int) -> void
+  expect(false, 'int_', 'void__int');
+  // () -> void <: (int) -> int
+  expect(false, 'void_', 'int__int');
+  // () -> void <: (int) -> void
+  expect(false, 'void_', 'void__int');
+  // (int) -> int <: (int) -> int
+  expect(true, 'int__int', 'int__int2');
+  // (Object) -> int <: (int) -> Object
+  expect(true, 'int__Object', 'Object__int');
+  // (int) -> int <: (double) -> int
+  expect(false, 'int__int', 'int__double');
+  // () -> int <: (int) -> int
+  expect(false, 'int_', 'int__int');
+  // (int) -> int <: (int,int) -> int
+  expect(false, 'int__int', 'int__int_int');
+  // (int,int) -> int <: (int) -> int
+  expect(false, 'int__int_int', 'int__int');
+  // (()->void) -> void <: ((int)->void) -> void
+  expect(false, 'inline_void_', 'inline_void__int');
+  // ((int)->void) -> void <: (()->void) -> void
+  expect(false, 'inline_void__int', 'inline_void_');
+}
+
+testFunctionSubtypingOptional() {
+  var env = new TypeEnvironment(r"""
+      void void_() {}
+      void void__int(int i) {}
+      void void___int([int i]) {}
+      void void___int2([int i]) {}
+      void void___Object([Object o]) {}
+      void void__int__int(int i1, [int i2]) {}
+      void void__int__int2(int i1, [int i2]) {}
+      void void___double(double d) {}
+      void void___int_int([int i1, int i2]) {}
+      void void___Object_int([Object o, int i]) {}
+      """);
+  functionSubtypingOptionalHelper(env);
+}
+
+testTypedefSubtypingOptional() {
+  var env = new TypeEnvironment(r"""
+      typedef void void_();
+      typedef void void__int(int i);
+      typedef void void___int([int i]);
+      typedef void void___int2([int i]);
+      typedef void void___Object([Object o]);
+      typedef void void__int__int(int i1, [int i2]);
+      typedef void void__int__int2(int i1, [int i2]);
+      typedef void void___double(double d);
+      typedef void void___int_int([int i1, int i2]);
+      typedef void void___Object_int([Object o, int i]);
+      """);
+  functionSubtypingOptionalHelper(env);
+}
+
+functionSubtypingOptionalHelper(TypeEnvironment env) {
+  expect(bool expectedResult, String sub, String sup) {
+    DartType subtype = env.getElementType(sub);
+    DartType supertype = env.getElementType(sup);
+    Expect.equals(expectedResult, env.isSubtype(subtype, supertype),
+        '$subtype <: $supertype');
+  }
+
+  // Test ([int])->void <: ()->void.
+  expect(true, 'void___int', 'void_');
+  // Test ([int])->void <: (int)->void.
+  expect(false, 'void___int', 'void__int');
+  // Test (int)->void <: ([int])->void.
+  expect(false, 'void__int', 'void___int');
+  // Test ([int])->void <: ([int])->void.
+  expect(true, 'void___int', 'void___int2');
+  // Test ([Object])->void <: ([int])->void.
+  expect(true, 'void___Object', 'void___int');
+  // Test ([int])->void <: ([Object])->void.
+  expect(true, 'void___int', 'void___Object');
+  // Test (int,[int])->void <: (int,[int])->void.
+  expect(true, 'void__int__int', 'void__int__int2');
+  // Test ([int])->void <: ([double])->void.
+  expect(false, 'void___int', 'void___double');
+  // Test ([int])->void <: ([int,int])->void.
+  expect(false, 'void___int', 'void___int_int');
+  // Test ([int,int])->void <: ([int])->void.
+  expect(true, 'void___int_int', 'void___int');
+  // Test ([Object,int])->void <: ([int])->void.
+  expect(true, 'void___Object_int', 'void___int');
+}
+
+testFunctionSubtypingNamed() {
+  var env = new TypeEnvironment(r"""
+      void void_() {}
+      void void__int(int i) {}
+      void void___a_int({int a}) {}
+      void void___a_int2({int a}) {}
+      void void___b_int({int b}) {}
+      void void___a_Object({Object a}) {}
+      void void__int__a_int(int i1, {int a}) {}
+      void void__int__a_int2(int i1, {int a}) {}
+      void void___a_double({double a}) {}
+      void void___a_int_b_int({int a, int b}) {}
+      void void___a_int_b_int_c_int({int a, int b, int c}) {}
+      void void___a_int_c_int({int a, int c}) {}
+      void void___b_int_c_int({int b, int c}) {}
+      void void___c_int({int c}) {}
+      """);
+  functionSubtypingNamedHelper(env);
+}
+
+testTypedefSubtypingNamed() {
+  var env = new TypeEnvironment(r"""
+      typedef void void_();
+      typedef void void__int(int i);
+      typedef void void___a_int({int a});
+      typedef void void___a_int2({int a});
+      typedef void void___b_int({int b});
+      typedef void void___a_Object({Object a});
+      typedef void void__int__a_int(int i1, {int a});
+      typedef void void__int__a_int2(int i1, {int a});
+      typedef void void___a_double({double a});
+      typedef void void___a_int_b_int({int a, int b});
+      typedef void void___a_int_b_int_c_int({int a, int b, int c});
+      typedef void void___a_int_c_int({int a, int c});
+      typedef void void___b_int_c_int({int b, int c});
+      typedef void void___c_int({int c});
+      """);
+  functionSubtypingNamedHelper(env);
+}
+
+functionSubtypingNamedHelper(TypeEnvironment env) {
+  expect(bool expectedResult, String sub, String sup) {
+    DartType subtype = env.getElementType(sub);
+    DartType supertype = env.getElementType(sup);
+    Expect.equals(expectedResult, env.isSubtype(subtype, supertype),
+        '$subtype <: $supertype');
+  }
+
+  // Test ({int a})->void <: ()->void.
+  expect(true, 'void___a_int', 'void_');
+  // Test ({int a})->void <: (int)->void.
+  expect(false, 'void___a_int', 'void__int');
+  // Test (int)->void <: ({int a})->void.
+  expect(false, 'void__int', 'void___a_int');
+  // Test ({int a})->void <: ({int a})->void.
+  expect(true, 'void___a_int', 'void___a_int2');
+  // Test ({int a})->void <: ({int b})->void.
+  expect(false, 'void___a_int', 'void___b_int');
+  // Test ({Object a})->void <: ({int a})->void.
+  expect(true, 'void___a_Object', 'void___a_int');
+  // Test ({int a})->void <: ({Object a})->void.
+  expect(true, 'void___a_int', 'void___a_Object');
+  // Test (int,{int a})->void <: (int,{int a})->void.
+  expect(true, 'void__int__a_int', 'void__int__a_int2');
+  // Test ({int a})->void <: ({double a})->void.
+  expect(false, 'void___a_int', 'void___a_double');
+  // Test ({int a})->void <: ({int a,int b})->void.
+  expect(false, 'void___a_int', 'void___a_int_b_int');
+  // Test ({int a,int b})->void <: ({int a})->void.
+  expect(true, 'void___a_int_b_int', 'void___a_int');
+  // Test ({int a,int b,int c})->void <: ({int a,int c})->void.
+  expect(true, 'void___a_int_b_int_c_int', 'void___a_int_c_int');
+  // Test ({int a,int b,int c})->void <: ({int b,int c})->void.
+  expect(true, 'void___a_int_b_int_c_int', 'void___b_int_c_int');
+  // Test ({int a,int b,int c})->void <: ({int c})->void.
+  expect(true, 'void___a_int_b_int_c_int', 'void___c_int');
+}
diff --git a/tests/compiler/dart2js/type_checker_test.dart b/tests/compiler/dart2js/type_checker_test.dart
index 39e688a..b6200eb 100644
--- a/tests/compiler/dart2js/type_checker_test.dart
+++ b/tests/compiler/dart2js/type_checker_test.dart
@@ -16,6 +16,7 @@
 
 import '../../../sdk/lib/_internal/compiler/implementation/dart_types.dart';
 
+DartType voidType;
 DartType intType;
 DartType boolType;
 DartType stringType;
@@ -36,10 +37,7 @@
                 // testNewExpression,
                 testConditionalExpression,
                 testIfStatement,
-                testThis,
-                testFunctionSubtyping,
-                testFunctionSubtypingOptional,
-                testFunctionSubtypingNamed];
+                testThis];
   for (Function test in tests) {
     setup();
     test();
@@ -496,151 +494,6 @@
   analyzeIn(foo, "{ Foo f = this; }");
 }
 
-testFunctionSubtyping() {
-  // Checks that the type (in1 -> out1) is a subtype of (in2 -> out2).
-  bool isSubtype(List<DartType> in1, DartType out1, List<DartType> in2,
-                 DartType out2) {
-    return compiler.types.isSubtype(
-        new FunctionType(null, out1, new Link<DartType>.fromList(in1),
-                         const Link<DartType>(),
-                         const Link<SourceString>(), const Link<DartType>()),
-        new FunctionType(null, out2, new Link<DartType>.fromList(in2),
-                         const Link<DartType>(),
-                         const Link<SourceString>(), const Link<DartType>()));
-  }
-  Expect.isTrue(isSubtype([], intType, [], intType));
-  Expect.isTrue(isSubtype([], intType, [], objectType));
-  Expect.isFalse(isSubtype([], intType, [], doubleType));
-  Expect.isTrue(isSubtype([intType], intType, [intType], intType));
-  Expect.isTrue(isSubtype([objectType], intType, [intType], objectType));
-  Expect.isFalse(isSubtype([intType], intType, [doubleType], intType));
-  Expect.isFalse(isSubtype([intType], intType, [intType, intType], intType));
-  Expect.isFalse(isSubtype([intType, intType], intType, [intType], intType));
-}
-
-testFunctionSubtypingOptional() {
-  // Checks whether the type (in1,[opt1] -> void) is a subtype of
-  // (in2,[opt2] -> void).
-  expect(bool value, List<DartType> in1, List<DartType> opt1,
-                     List<DartType> in2, List<DartType> opt2) {
-    var fn1 = new FunctionType(null,
-        compiler.types.dynamicType,
-        new Link<DartType>.fromList(in1),
-        new Link<DartType>.fromList(opt1),
-        const Link<SourceString>(), const Link<DartType>());
-    var fn2 = new FunctionType(null,
-        compiler.types.dynamicType,
-        new Link<DartType>.fromList(in2),
-        new Link<DartType>.fromList(opt2),
-        const Link<SourceString>(), const Link<DartType>());
-    Expect.equals(value, compiler.types.isSubtype(fn1, fn2), "$fn1 <: $fn2");
-  }
-
-  // Test ()->void <: ()->void.
-  expect(true, [], [], [], []);
-  // Test ([int])->void <: ()->void.
-  expect(true, [], [intType], [], []);
-  // Test ([int])->void <: (int)->void.
-  expect(false, [], [intType], [intType], []);
-  // Test (int)->void <: ([int])->void.
-  expect(false, [intType], [], [], [intType]);
-  // Test ([int])->void <: ([int])->void.
-  expect(true, [], [intType], [], [intType]);
-  // Test ([Object])->void <: ([int])->void.
-  expect(true, [], [objectType], [], [intType]);
-  // Test ([int])->void <: ([Object])->void.
-  expect(true, [], [intType], [], [objectType]);
-  // Test (int,[int])->void <: (int,[int])->void.
-  expect(true, [intType], [intType], [intType], [intType]);
-  // Test ([int])->void <: ([double])->void.
-  expect(false, [], [intType], [], [doubleType]);
-  // Test ([int])->void <: ([int,int])->void.
-  expect(false, [], [intType], [], [intType, intType]);
-  // Test ([int,int])->void <: ([int])->void.
-  expect(true, [], [intType, intType], [], [intType]);
-  // Test ([Object,int])->void <: ([int])->void.
-  expect(true, [], [objectType, intType], [], [intType]);
-}
-
-
-testFunctionSubtypingNamed() {
-  // Checks whether the type (in1,{nm1} -> out1) is a subtype of
-  // (in2,{nm2} -> out2).
-  expect(bool value, List<DartType> in1, Map<String,DartType> nm1,
-                     List<DartType> in2, Map<String,DartType> nm2) {
-
-    SourceString convertString(String string) => new SourceString(string);
-    int compareString(a, b) => a.compareTo(b);
-
-    Link<SourceString> createNames(Map<String,DartType> nm) {
-      List<String> nmSorted = new List<String>.from(nm.keys)..sort();
-      List<SourceString> nmSourceStrings =
-          nmSorted.map((string) => new SourceString(string)).toList();
-      return new Link<SourceString>.fromList(nmSourceStrings);
-    }
-
-    Link<DartType> createTypes(Map<String,DartType> nm,
-                               Link<SourceString> names) {
-      var types = new LinkBuilder<DartType>();
-      for (SourceString name in names) {
-        types.addLast(nm[name.slowToString()]);
-      }
-      return types.toLink();
-    }
-
-    Link<SourceString> names1 = createNames(nm1);
-    Link<DartType> types1 = createTypes(nm1, names1);
-    Link<SourceString> names2 = createNames(nm2);
-    Link<DartType> types2 = createTypes(nm2, names2);
-    var fn1 = new FunctionType(null,
-        compiler.types.dynamicType,
-        new Link<DartType>.fromList(in1),
-        const Link<DartType>(),
-        names1, types1);
-    var fn2 = new FunctionType(null,
-        compiler.types.dynamicType,
-        new Link<DartType>.fromList(in2),
-        const Link<DartType>(),
-        names2, types2);
-    Expect.equals(value, compiler.types.isSubtype(fn1, fn2), "$fn1 <: $fn2");
-  }
-
-  // Test ()->void <: ()->void.
-  expect(true, [], {}, [], {});
-  // Test ({int a})->void <: ()->void.
-  expect(true, [], {'a': intType}, [], {});
-  // Test ({int a})->void <: (int)->void.
-  expect(false, [], {'a': intType}, [intType], {});
-  // Test (int)->void <: ({int a})->void.
-  expect(false, [intType], {}, [], {'a': intType});
-  // Test ({int a})->void <: ({int a})->void.
-  expect(true, [], {'a': intType}, [], {'a': intType});
-  // Test ({int a})->void <: ({int b})->void.
-  expect(false, [], {'a': intType}, [], {'b': intType});
-  // Test ({Object a})->void <: ({int a})->void.
-  expect(true, [], {'a': objectType}, [], {'a': intType});
-  // Test ({int a})->void <: ([Object])->void.
-  expect(true, [], {'a': intType}, [], {'a': objectType});
-  // Test (int,{int a})->void <: (int,{int a})->void.
-  expect(true, [intType], {'a': intType}, [intType], {'a': intType});
-  // Test ({int a})->void <: ({double a})->void.
-  expect(false, [], {'a': intType}, [], {'a': doubleType});
-  // Test ({int a})->void <: ({int a,int b})->void.
-  expect(false, [], {'a': intType}, [], {'a': intType, 'b': intType});
-  // Test ({int a,int b})->void <: ({int a})->void.
-  expect(true, [], {'a': intType, 'b': intType}, [], {'a': intType});
-  // Test ({int a,int b,int c})->void <: ({int a,int c})->void.
-  expect(true, [], {'a': intType, 'b': intType, 'c': intType},
-               [], {'a': intType, 'c': intType});
-  // Test ({int a,int b,int c})->void <: ({int b,int c})->void.
-  expect(true, [], {'a': intType, 'b': intType, 'c': intType},
-               [], {'b': intType, 'c': intType});
-  // Test ({int a,int b,int c})->void <: ({int c})->void.
-  expect(true, [], {'a': intType, 'b': intType, 'c': intType},
-               [], {'c': intType});
-}
-
-
 const CLASS_WITH_METHODS = '''
 class ClassWithMethods {
   untypedNoArgumentMethod() {}
@@ -680,6 +533,7 @@
 void setup() {
   compiler = new MockCompiler();
   types = compiler.types;
+  voidType = compiler.types.voidType;
   intType = compiler.intClass.computeType(compiler);
   doubleType = compiler.doubleClass.computeType(compiler);
   boolType = compiler.boolClass.computeType(compiler);
diff --git a/tests/compiler/dart2js/type_combination_test.dart b/tests/compiler/dart2js/type_combination_test.dart
index ada905c..f978334 100644
--- a/tests/compiler/dart2js/type_combination_test.dart
+++ b/tests/compiler/dart2js/type_combination_test.dart
@@ -25,13 +25,19 @@
 const DOUBLE_OR_NULL = HType.DOUBLE_OR_NULL;
 const STRING_OR_NULL = HType.STRING_OR_NULL;
 const NULL = HType.NULL;
+const NON_NULL = HType.NON_NULL;
 
 var patternClass;
 HType nonPrimitive1;
 HType nonPrimitive2;
 HType potentialArray;
 HType potentialString;
+
 HType jsArrayOrNull;
+HType jsMutableArrayOrNull;
+HType jsFixedArrayOrNull;
+HType jsExtendableArrayOrNull;
+HType jsIndexableOrNull;
 
 void testUnion(MockCompiler compiler) {
   Expect.equals(CONFLICTING,
@@ -130,25 +136,25 @@
                 BOOLEAN.union(UNKNOWN, compiler));
   Expect.equals(BOOLEAN,
                 BOOLEAN.union(BOOLEAN, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 BOOLEAN.union(NUMBER, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 BOOLEAN.union(INTEGER, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 BOOLEAN.union(DOUBLE, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 BOOLEAN.union(INDEXABLE_PRIMITIVE, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 BOOLEAN.union(STRING, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 BOOLEAN.union(READABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 BOOLEAN.union(MUTABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 BOOLEAN.union(EXTENDABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 BOOLEAN.union(nonPrimitive1, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 BOOLEAN.union(nonPrimitive2, compiler));
   Expect.equals(UNKNOWN,
                 BOOLEAN.union(potentialArray, compiler));
@@ -166,14 +172,14 @@
                 BOOLEAN.union(STRING_OR_NULL, compiler));
   Expect.equals(BOOLEAN_OR_NULL,
                 BOOLEAN.union(NULL, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 BOOLEAN.union(FIXED_ARRAY, compiler));
 
   Expect.equals(NUMBER,
                 NUMBER.union(CONFLICTING, compiler));
   Expect.equals(UNKNOWN,
                 NUMBER.union(UNKNOWN, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 NUMBER.union(BOOLEAN, compiler));
   Expect.equals(NUMBER,
                 NUMBER.union(NUMBER, compiler));
@@ -181,19 +187,19 @@
                 NUMBER.union(INTEGER, compiler));
   Expect.equals(NUMBER,
                 NUMBER.union(DOUBLE, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 NUMBER.union(INDEXABLE_PRIMITIVE, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 NUMBER.union(STRING, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 NUMBER.union(READABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 NUMBER.union(MUTABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 NUMBER.union(EXTENDABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 NUMBER.union(nonPrimitive1, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 NUMBER.union(nonPrimitive2, compiler));
   Expect.equals(UNKNOWN,
                 NUMBER.union(potentialArray, compiler));
@@ -211,14 +217,14 @@
                 NUMBER.union(STRING_OR_NULL, compiler));
   Expect.equals(NUMBER_OR_NULL,
                 NUMBER.union(NULL, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 NUMBER.union(FIXED_ARRAY, compiler));
 
   Expect.equals(INTEGER,
                 INTEGER.union(CONFLICTING, compiler));
   Expect.equals(UNKNOWN,
                 INTEGER.union(UNKNOWN, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 INTEGER.union(BOOLEAN, compiler));
   Expect.equals(NUMBER,
                 INTEGER.union(NUMBER, compiler));
@@ -226,19 +232,19 @@
                 INTEGER.union(INTEGER, compiler));
   Expect.equals(NUMBER,
                 INTEGER.union(DOUBLE, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 INTEGER.union(INDEXABLE_PRIMITIVE, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 INTEGER.union(STRING, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 INTEGER.union(READABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 INTEGER.union(MUTABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 INTEGER.union(EXTENDABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 INTEGER.union(nonPrimitive1, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 INTEGER.union(nonPrimitive2, compiler));
   Expect.equals(UNKNOWN,
                 INTEGER.union(potentialArray, compiler));
@@ -256,14 +262,14 @@
                 INTEGER.union(STRING_OR_NULL, compiler));
   Expect.equals(INTEGER_OR_NULL,
                 INTEGER.union(NULL, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 INTEGER.union(FIXED_ARRAY, compiler));
 
   Expect.equals(DOUBLE,
                 DOUBLE.union(CONFLICTING, compiler));
   Expect.equals(UNKNOWN,
                 DOUBLE.union(UNKNOWN, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 DOUBLE.union(BOOLEAN, compiler));
   Expect.equals(NUMBER,
                 DOUBLE.union(NUMBER, compiler));
@@ -271,19 +277,19 @@
                 DOUBLE.union(INTEGER, compiler));
   Expect.equals(DOUBLE,
                 DOUBLE.union(DOUBLE, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 DOUBLE.union(INDEXABLE_PRIMITIVE, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 DOUBLE.union(STRING, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 DOUBLE.union(READABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 DOUBLE.union(MUTABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 DOUBLE.union(EXTENDABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 DOUBLE.union(nonPrimitive1, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 DOUBLE.union(nonPrimitive2, compiler));
   Expect.equals(UNKNOWN,
                 DOUBLE.union(potentialArray, compiler));
@@ -301,20 +307,20 @@
                 DOUBLE.union(STRING_OR_NULL, compiler));
   Expect.equals(DOUBLE_OR_NULL,
                 DOUBLE.union(NULL, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 DOUBLE.union(FIXED_ARRAY, compiler));
 
   Expect.equals(INDEXABLE_PRIMITIVE,
                 INDEXABLE_PRIMITIVE.union(CONFLICTING, compiler));
   Expect.equals(UNKNOWN,
                 INDEXABLE_PRIMITIVE.union(UNKNOWN, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 INDEXABLE_PRIMITIVE.union(BOOLEAN, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 INDEXABLE_PRIMITIVE.union(NUMBER, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 INDEXABLE_PRIMITIVE.union(INTEGER, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 INDEXABLE_PRIMITIVE.union(DOUBLE, compiler));
   Expect.equals(INDEXABLE_PRIMITIVE,
                 INDEXABLE_PRIMITIVE.union(INDEXABLE_PRIMITIVE,
@@ -328,9 +334,9 @@
   Expect.equals(INDEXABLE_PRIMITIVE,
                 INDEXABLE_PRIMITIVE.union(EXTENDABLE_ARRAY,
                 compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 INDEXABLE_PRIMITIVE.union(nonPrimitive1, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 INDEXABLE_PRIMITIVE.union(nonPrimitive2, compiler));
   Expect.equals(UNKNOWN,
                 INDEXABLE_PRIMITIVE.union(potentialArray, compiler));
@@ -344,9 +350,9 @@
                 INDEXABLE_PRIMITIVE.union(INTEGER_OR_NULL, compiler));
   Expect.equals(UNKNOWN,
                 INDEXABLE_PRIMITIVE.union(DOUBLE_OR_NULL, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(jsIndexableOrNull,
                 INDEXABLE_PRIMITIVE.union(STRING_OR_NULL, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(jsIndexableOrNull,
                 INDEXABLE_PRIMITIVE.union(NULL, compiler));
   Expect.equals(INDEXABLE_PRIMITIVE,
                 INDEXABLE_PRIMITIVE.union(FIXED_ARRAY, compiler));
@@ -355,13 +361,13 @@
                 STRING.union(CONFLICTING, compiler));
   Expect.equals(UNKNOWN,
                 STRING.union(UNKNOWN, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 STRING.union(BOOLEAN, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 STRING.union(NUMBER, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 STRING.union(INTEGER, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 STRING.union(DOUBLE, compiler));
   Expect.equals(INDEXABLE_PRIMITIVE,
                 STRING.union(INDEXABLE_PRIMITIVE, compiler));
@@ -373,9 +379,9 @@
                 STRING.union(MUTABLE_ARRAY, compiler));
   Expect.equals(INDEXABLE_PRIMITIVE,
                 STRING.union(EXTENDABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 STRING.union(nonPrimitive1, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 STRING.union(nonPrimitive2, compiler));
   Expect.equals(UNKNOWN,
                 STRING.union(potentialArray, compiler));
@@ -400,13 +406,13 @@
                 READABLE_ARRAY.union(CONFLICTING, compiler));
   Expect.equals(UNKNOWN,
                 READABLE_ARRAY.union(UNKNOWN, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 READABLE_ARRAY.union(BOOLEAN, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 READABLE_ARRAY.union(NUMBER, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 READABLE_ARRAY.union(INTEGER, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 READABLE_ARRAY.union(DOUBLE, compiler));
   Expect.equals(INDEXABLE_PRIMITIVE,
                 READABLE_ARRAY.union(INDEXABLE_PRIMITIVE, compiler));
@@ -418,9 +424,9 @@
                 READABLE_ARRAY.union(MUTABLE_ARRAY, compiler));
   Expect.equals(READABLE_ARRAY,
                 READABLE_ARRAY.union(EXTENDABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 READABLE_ARRAY.union(nonPrimitive1, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 READABLE_ARRAY.union(nonPrimitive2, compiler));
   Expect.equals(potentialArray,
                 READABLE_ARRAY.union(potentialArray, compiler));
@@ -434,7 +440,7 @@
                 READABLE_ARRAY.union(INTEGER_OR_NULL, compiler));
   Expect.equals(UNKNOWN,
                 READABLE_ARRAY.union(DOUBLE_OR_NULL, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(jsIndexableOrNull,
                 READABLE_ARRAY.union(STRING_OR_NULL, compiler));
   Expect.equals(jsArrayOrNull,
                 READABLE_ARRAY.union(NULL, compiler));
@@ -445,13 +451,13 @@
                 MUTABLE_ARRAY.union(CONFLICTING, compiler));
   Expect.equals(UNKNOWN,
                 MUTABLE_ARRAY.union(UNKNOWN, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 MUTABLE_ARRAY.union(BOOLEAN, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 MUTABLE_ARRAY.union(NUMBER, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 MUTABLE_ARRAY.union(INTEGER, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 MUTABLE_ARRAY.union(DOUBLE, compiler));
   Expect.equals(INDEXABLE_PRIMITIVE,
                 MUTABLE_ARRAY.union(INDEXABLE_PRIMITIVE, compiler));
@@ -463,9 +469,9 @@
                 MUTABLE_ARRAY.union(MUTABLE_ARRAY, compiler));
   Expect.equals(MUTABLE_ARRAY,
                 MUTABLE_ARRAY.union(EXTENDABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 MUTABLE_ARRAY.union(nonPrimitive1, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 MUTABLE_ARRAY.union(nonPrimitive2, compiler));
   Expect.equals(potentialArray,MUTABLE_ARRAY.union(potentialArray,
                 compiler));
@@ -479,9 +485,9 @@
                 MUTABLE_ARRAY.union(INTEGER_OR_NULL, compiler));
   Expect.equals(UNKNOWN,
                 MUTABLE_ARRAY.union(DOUBLE_OR_NULL, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(jsIndexableOrNull,
                 MUTABLE_ARRAY.union(STRING_OR_NULL, compiler));
-  Expect.equals(jsArrayOrNull,
+  Expect.equals(jsMutableArrayOrNull,
                 MUTABLE_ARRAY.union(NULL, compiler));
   Expect.equals(MUTABLE_ARRAY,
                 MUTABLE_ARRAY.union(FIXED_ARRAY, compiler));
@@ -490,13 +496,13 @@
                 EXTENDABLE_ARRAY.union(CONFLICTING, compiler));
   Expect.equals(UNKNOWN,
                 EXTENDABLE_ARRAY.union(UNKNOWN, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 EXTENDABLE_ARRAY.union(BOOLEAN, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 EXTENDABLE_ARRAY.union(NUMBER, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 EXTENDABLE_ARRAY.union(INTEGER, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 EXTENDABLE_ARRAY.union(DOUBLE, compiler));
   Expect.equals(INDEXABLE_PRIMITIVE,
                 EXTENDABLE_ARRAY.union(INDEXABLE_PRIMITIVE, compiler));
@@ -508,9 +514,9 @@
                 EXTENDABLE_ARRAY.union(MUTABLE_ARRAY, compiler));
   Expect.equals(EXTENDABLE_ARRAY,
                 EXTENDABLE_ARRAY.union(EXTENDABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 EXTENDABLE_ARRAY.union(nonPrimitive1, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 EXTENDABLE_ARRAY.union(nonPrimitive2, compiler));
   Expect.equals(potentialArray,
                 EXTENDABLE_ARRAY.union(potentialArray, compiler));
@@ -524,9 +530,9 @@
                 EXTENDABLE_ARRAY.union(INTEGER_OR_NULL, compiler));
   Expect.equals(UNKNOWN,
                 EXTENDABLE_ARRAY.union(DOUBLE_OR_NULL, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(jsIndexableOrNull,
                 EXTENDABLE_ARRAY.union(STRING_OR_NULL, compiler));
-  Expect.equals(jsArrayOrNull,
+  Expect.equals(jsExtendableArrayOrNull,
                 EXTENDABLE_ARRAY.union(NULL, compiler));
   Expect.equals(MUTABLE_ARRAY,
                 EXTENDABLE_ARRAY.union(FIXED_ARRAY, compiler));
@@ -535,27 +541,27 @@
                 nonPrimitive1.union(CONFLICTING, compiler));
   Expect.equals(UNKNOWN,
                 nonPrimitive1.union(UNKNOWN, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 nonPrimitive1.union(BOOLEAN, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 nonPrimitive1.union(NUMBER, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 nonPrimitive1.union(INTEGER, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 nonPrimitive1.union(DOUBLE, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 nonPrimitive1.union(INDEXABLE_PRIMITIVE, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 nonPrimitive1.union(STRING, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 nonPrimitive1.union(READABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 nonPrimitive1.union(MUTABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 nonPrimitive1.union(EXTENDABLE_ARRAY, compiler));
   Expect.equals(nonPrimitive1,
                 nonPrimitive1.union(nonPrimitive1, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 nonPrimitive1.union(nonPrimitive2, compiler));
   Expect.equals(UNKNOWN,
                 nonPrimitive1.union(potentialArray, compiler));
@@ -572,32 +578,32 @@
   Expect.equals(UNKNOWN,
                 nonPrimitive1.union(STRING_OR_NULL, compiler));
   Expect.isTrue(nonPrimitive1.union(NULL, compiler) is HBoundedType);
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 nonPrimitive1.union(FIXED_ARRAY, compiler));
 
   Expect.equals(nonPrimitive2,
                 nonPrimitive2.union(CONFLICTING, compiler));
   Expect.equals(UNKNOWN,
                 nonPrimitive2.union(UNKNOWN, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 nonPrimitive2.union(BOOLEAN, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 nonPrimitive2.union(NUMBER, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 nonPrimitive2.union(INTEGER, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 nonPrimitive2.union(DOUBLE, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 nonPrimitive2.union(INDEXABLE_PRIMITIVE, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 nonPrimitive2.union(STRING, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 nonPrimitive2.union(READABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 nonPrimitive2.union(MUTABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 nonPrimitive2.union(EXTENDABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 nonPrimitive2.union(nonPrimitive1, compiler));
   Expect.equals(nonPrimitive2,
                 nonPrimitive2.union(nonPrimitive2, compiler));
@@ -616,7 +622,7 @@
   Expect.equals(UNKNOWN,
                 nonPrimitive2.union(STRING_OR_NULL, compiler));
   Expect.isTrue(nonPrimitive2.union(NULL, compiler) is HBoundedType);
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 nonPrimitive2.union(FIXED_ARRAY, compiler));
 
   Expect.equals(potentialArray,
@@ -901,15 +907,15 @@
                 STRING_OR_NULL.union(INTEGER, compiler));
   Expect.equals(UNKNOWN,
                 STRING_OR_NULL.union(DOUBLE, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(jsIndexableOrNull,
                 STRING_OR_NULL.union(INDEXABLE_PRIMITIVE, compiler));
   Expect.equals(STRING_OR_NULL,
                 STRING_OR_NULL.union(STRING, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(jsIndexableOrNull,
                 STRING_OR_NULL.union(READABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(jsIndexableOrNull,
                 STRING_OR_NULL.union(MUTABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(jsIndexableOrNull,
                 STRING_OR_NULL.union(EXTENDABLE_ARRAY, compiler));
   Expect.equals(UNKNOWN,
                 STRING_OR_NULL.union(nonPrimitive1, compiler));
@@ -931,7 +937,7 @@
                 STRING_OR_NULL.union(STRING_OR_NULL, compiler));
   Expect.equals(STRING_OR_NULL,
                 STRING_OR_NULL.union(NULL, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(jsIndexableOrNull,
                 STRING_OR_NULL.union(FIXED_ARRAY, compiler));
 
   Expect.equals(NULL,
@@ -946,20 +952,18 @@
                 NULL.union(INTEGER, compiler));
   Expect.equals(DOUBLE_OR_NULL,
                 NULL.union(DOUBLE, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(jsIndexableOrNull,
                 NULL.union(INDEXABLE_PRIMITIVE, compiler));
   Expect.equals(STRING_OR_NULL,
                 NULL.union(STRING, compiler));
   Expect.equals(jsArrayOrNull,
                 NULL.union(READABLE_ARRAY, compiler));
-  Expect.equals(jsArrayOrNull,
+  Expect.equals(jsMutableArrayOrNull,
                 NULL.union(MUTABLE_ARRAY, compiler));
-  Expect.equals(jsArrayOrNull,
+  Expect.equals(jsExtendableArrayOrNull,
                 NULL.union(EXTENDABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
-                NULL.union(nonPrimitive1, compiler));
-  Expect.equals(UNKNOWN,
-                NULL.union(nonPrimitive2, compiler));
+  Expect.isTrue(NULL.union(nonPrimitive1, compiler).canBeNull());
+  Expect.isTrue(NULL.union(nonPrimitive2, compiler).canBeNull());
   Expect.equals(potentialArray,
                 NULL.union(potentialArray, compiler));
   Expect.equals(potentialString,
@@ -976,20 +980,20 @@
                 NULL.union(STRING_OR_NULL, compiler));
   Expect.equals(NULL,
                 NULL.union(NULL, compiler));
-  Expect.equals(jsArrayOrNull,
+  Expect.equals(jsFixedArrayOrNull,
                 NULL.union(FIXED_ARRAY, compiler));
 
   Expect.equals(FIXED_ARRAY,
                 FIXED_ARRAY.union(CONFLICTING, compiler));
   Expect.equals(UNKNOWN,
                 FIXED_ARRAY.union(UNKNOWN, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 FIXED_ARRAY.union(BOOLEAN, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 FIXED_ARRAY.union(NUMBER, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 FIXED_ARRAY.union(INTEGER, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 FIXED_ARRAY.union(DOUBLE, compiler));
   Expect.equals(INDEXABLE_PRIMITIVE,
                 FIXED_ARRAY.union(INDEXABLE_PRIMITIVE, compiler));
@@ -1001,9 +1005,9 @@
                 FIXED_ARRAY.union(MUTABLE_ARRAY, compiler));
   Expect.equals(MUTABLE_ARRAY,
                 FIXED_ARRAY.union(EXTENDABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 FIXED_ARRAY.union(nonPrimitive1, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(NON_NULL,
                 FIXED_ARRAY.union(nonPrimitive2, compiler));
   Expect.equals(potentialArray,
                 FIXED_ARRAY.union(potentialArray, compiler));
@@ -1017,9 +1021,9 @@
                 FIXED_ARRAY.union(INTEGER_OR_NULL, compiler));
   Expect.equals(UNKNOWN,
                 FIXED_ARRAY.union(DOUBLE_OR_NULL, compiler));
-  Expect.equals(UNKNOWN,
+  Expect.equals(jsIndexableOrNull,
                 FIXED_ARRAY.union(STRING_OR_NULL, compiler));
-  Expect.equals(jsArrayOrNull,
+  Expect.equals(jsFixedArrayOrNull,
                 FIXED_ARRAY.union(NULL, compiler));
   Expect.equals(FIXED_ARRAY,
                 FIXED_ARRAY.union(FIXED_ARRAY, compiler));
@@ -1340,7 +1344,7 @@
                 INDEXABLE_PRIMITIVE.intersection(INTEGER_OR_NULL, compiler));
   Expect.equals(CONFLICTING,
                 INDEXABLE_PRIMITIVE.intersection(DOUBLE_OR_NULL, compiler));
-  Expect.equals(CONFLICTING,
+  Expect.equals(STRING,
                 INDEXABLE_PRIMITIVE.intersection(STRING_OR_NULL, compiler));
   Expect.equals(CONFLICTING,
                 INDEXABLE_PRIMITIVE.intersection(NULL, compiler));
@@ -2038,9 +2042,12 @@
   MockCompiler compiler = new MockCompiler();
   compiler.interceptorsLibrary.forEachLocalMember((element) {
     if (element.isClass()) {
-      compiler.enqueuer.resolution.registerInstantiatedClass(element);
+      compiler.enqueuer.resolution.registerInstantiatedClass(
+          element, compiler.globalDependencies);
     }
   });
+  compiler.enqueuer.resolution.registerInstantiatedClass(
+      compiler.mapClass, compiler.globalDependencies);
   compiler.world.populate();
 
   // Grab hold of a supertype for String so we can produce potential
@@ -2055,8 +2062,16 @@
       compiler.listClass.computeType(compiler), compiler);
   potentialString = new HType.subtype(
       patternClass.computeType(compiler), compiler);
-  jsArrayOrNull = new HType.exact(
+  jsArrayOrNull = new HType.subclass(
       compiler.backend.jsArrayClass.computeType(compiler), compiler);
+  jsMutableArrayOrNull = new HType.subclass(
+      compiler.backend.jsMutableArrayClass.computeType(compiler), compiler);
+  jsFixedArrayOrNull = new HType.exact(
+      compiler.backend.jsFixedArrayClass.computeType(compiler), compiler);
+  jsExtendableArrayOrNull = new HType.exact(
+      compiler.backend.jsExtendableArrayClass.computeType(compiler), compiler);
+  jsIndexableOrNull = new HType.subtype(
+      compiler.backend.jsIndexableClass.computeType(compiler), compiler);
 
   testUnion(compiler);
   testIntersection(compiler);
diff --git a/tests/compiler/dart2js/type_representation_test.dart b/tests/compiler/dart2js/type_representation_test.dart
new file mode 100644
index 0000000..2edf644
--- /dev/null
+++ b/tests/compiler/dart2js/type_representation_test.dart
@@ -0,0 +1,136 @@
+// 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 subtype_test;
+
+import 'type_test_helper.dart';
+import '../../../sdk/lib/_internal/compiler/implementation/dart_types.dart';
+import '../../../sdk/lib/_internal/compiler/implementation/elements/elements.dart'
+       show Element, ClassElement;
+import '../../../sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart'
+       show TypeRepresentationGenerator;
+
+void main() {
+  testTypeRepresentations();
+}
+
+void testTypeRepresentations() {
+  var env = new TypeEnvironment(r"""
+      typedef void Typedef();
+
+      void m1() {}
+      int m2() => 0;
+      List<int> m3() => null;
+      m4() {}
+      m5(int a, String b) {}
+      m6(int a, [String b]) {}
+      m7(int a, String b, [List<int> c, d]) {}
+      m8(int a, {String b}) {}
+      m9(int a, String b, {List<int> c, d}) {}
+      m10(void f(int a, [b])) {}
+      """);
+
+  TypeRepresentationGenerator typeRepresentation =
+      new TypeRepresentationGenerator(env.compiler);
+  String onVariable(TypeVariableType type) => type.name.slowToString();
+
+  void expect(String expectedRepresentation, DartType type) {
+    String foundRepresentation =
+        typeRepresentation.getTypeRepresentation(type, onVariable);
+    Expect.stringEquals(expectedRepresentation, foundRepresentation);
+  }
+
+  ClassElement List_ = env.getElement('List');
+  TypeVariableType List_E = List_.typeVariables.head;
+  ClassElement Map_ = env.getElement('Map');
+  TypeVariableType Map_K = Map_.typeVariables.head;
+  TypeVariableType Map_V = Map_.typeVariables.tail.head;
+
+  DartType Object_ = env['Object'];
+  DartType int_ = env['int'];
+  DartType String_ = env['String'];
+  DartType dynamic_ = env['dynamic'];
+  DartType Typedef_ = env['Typedef'];
+
+  String List_rep = typeRepresentation.getJsName(List_);
+  String List_E_rep = onVariable(List_E);
+  String Map_rep = typeRepresentation.getJsName(Map_);
+  String Map_K_rep = onVariable(Map_K);
+  String Map_V_rep = onVariable(Map_V);
+
+  String Object_rep = typeRepresentation.getJsName(Object_.element);
+  String int_rep = typeRepresentation.getJsName(int_.element);
+  String String_rep = typeRepresentation.getJsName(String_.element);
+
+  expect('$int_rep', int_);
+  expect('$String_rep', String_);
+  expect('null', dynamic_);
+
+  // List<E>
+  expect('[$List_rep, $List_E_rep]', List_.computeType(env.compiler));
+  // List
+  expect('$List_rep', List_.rawType);
+  // List<dynamic>
+  expect('[$List_rep, null]', instantiate(List_, [dynamic_]));
+  // List<int>
+  expect('[$List_rep, $int_rep]', instantiate(List_, [int_]));
+  // List<Typedef>
+  expect('[$List_rep, {func: true, retvoid: true}]',
+      instantiate(List_, [Typedef_]));
+
+  // Map<K,V>
+  expect('[$Map_rep, $Map_K_rep, $Map_V_rep]', Map_.computeType(env.compiler));
+  // Map
+  expect('$Map_rep', Map_.rawType);
+  // Map<dynamic,dynamic>
+  expect('[$Map_rep, null, null]', instantiate(Map_, [dynamic_, dynamic_]));
+  // Map<int,String>
+  expect('[$Map_rep, $int_rep, $String_rep]',
+      instantiate(Map_, [int_, String_]));
+
+  // void m1() {}
+  expect("{func: true, retvoid: true}",
+      env.getElement('m1').computeType(env.compiler));
+
+  // int m2() => 0;
+  expect("{func: true, ret: $int_rep}",
+      env.getElement('m2').computeType(env.compiler));
+
+  // List<int> m3() => null;
+  expect("{func: true, ret: [$List_rep, $int_rep]}",
+      env.getElement('m3').computeType(env.compiler));
+
+  // m4() {}
+  expect("{func: true}",
+      env.getElement('m4').computeType(env.compiler));
+
+  // m5(int a, String b) {}
+  expect("{func: true, args: [$int_rep, $String_rep]}",
+      env.getElement('m5').computeType(env.compiler));
+
+  // m6(int a, [String b]) {}
+  expect("{func: true, args: [$int_rep], opt: [$String_rep]}",
+      env.getElement('m6').computeType(env.compiler));
+
+  // m7(int a, String b, [List<int> c, d]) {}
+  expect("{func: true, args: [$int_rep, $String_rep],"
+         " opt: [[$List_rep, $int_rep], null]}",
+      env.getElement('m7').computeType(env.compiler));
+
+  // m8(int a, {String b}) {}
+  expect("{func: true, args: [$int_rep], named: {b: $String_rep}}",
+      env.getElement('m8').computeType(env.compiler));
+
+  // m9(int a, String b, {List<int> c, d}) {}
+  expect("{func: true, args: [$int_rep, $String_rep],"
+         " named: {c: [$List_rep, $int_rep], d: null}}",
+      env.getElement('m9').computeType(env.compiler));
+
+  // m10(void f(int a, [b])) {}
+  expect("{func: true, args:"
+         " [{func: true, retvoid: true, args: [$int_rep], opt: [null]}]}",
+      env.getElement('m10').computeType(env.compiler));
+}
+
+
diff --git a/tests/compiler/dart2js/type_test_helper.dart b/tests/compiler/dart2js/type_test_helper.dart
index 94faace..586af02 100644
--- a/tests/compiler/dart2js/type_test_helper.dart
+++ b/tests/compiler/dart2js/type_test_helper.dart
@@ -5,10 +5,17 @@
 library type_test_helper;
 
 import '../../../sdk/lib/_internal/compiler/implementation/dart_types.dart';
+import "parser_helper.dart" show SourceString;
 import "compiler_helper.dart";
 
-InterfaceType instantiate(ClassElement element, List<DartType> arguments) {
-  return new InterfaceType(element, new Link<DartType>.fromList(arguments));
+GenericType instantiate(TypeDeclarationElement element,
+                        List<DartType> arguments) {
+  if (element.isClass()) {
+    return new InterfaceType(element, new Link<DartType>.fromList(arguments));
+  } else {
+    assert(element.isTypedef());
+    return new TypedefType(element, new Link<DartType>.fromList(arguments));
+  }
 }
 
 class TypeEnvironment {
@@ -29,8 +36,10 @@
   Element getElement(String name) {
     var element = findElement(compiler, name);
     Expect.isNotNull(element);
-    if (identical(element.kind, ElementKind.CLASS)) {
+    if (element.isClass()) {
       element.ensureResolved(compiler);
+    } else if (element.isTypedef()) {
+      element.computeType(compiler);
     }
     return element;
   }
@@ -44,7 +53,35 @@
     return getElementType(name);
   }
 
+  DartType getMemberType(ClassElement element, String name) {
+    Element member = element.localLookup(new SourceString(name));
+    return member.computeType(compiler);
+  }
+
   bool isSubtype(DartType T, DartType S) {
     return compiler.types.isSubtype(T, S);
   }
+
+  FunctionType functionType(DartType returnType,
+                            List<DartType> parameters,
+                            {List<DartType> optionalParameter,
+                             Map<String,DartType> namedParameters}) {
+    Link<DartType> parameterTypes =
+        new Link<DartType>.fromList(parameters);
+    Link<DartType> optionalParameterTypes = optionalParameter != null
+        ? new Link<DartType>.fromList(optionalParameter)
+        : const Link<DartType>();
+    var namedParameterNames = new LinkBuilder<SourceString>();
+    var namedParameterTypes = new LinkBuilder<DartType>();
+    if (namedParameters != null) {
+      namedParameters.forEach((String name, DartType type) {
+        namedParameterNames.addLast(new SourceString(name));
+        namedParameterTypes.addLast(type);
+      });
+    }
+    FunctionType type = new FunctionType(
+        compiler.functionClass,
+        returnType, parameterTypes, optionalParameterTypes,
+        namedParameterNames.toLink(), namedParameterTypes.toLink());
+  }
 }
diff --git a/tests/compiler/dart2js/type_variable_occurrence_test.dart b/tests/compiler/dart2js/type_variable_occurrence_test.dart
new file mode 100644
index 0000000..51f6282
--- /dev/null
+++ b/tests/compiler/dart2js/type_variable_occurrence_test.dart
@@ -0,0 +1,127 @@
+// 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 subtype_test;
+
+import 'type_test_helper.dart';
+import '../../../sdk/lib/_internal/compiler/implementation/dart_types.dart';
+import "../../../sdk/lib/_internal/compiler/implementation/elements/elements.dart"
+       show Element, ClassElement;
+
+void main() {
+  testTypeVariableOccurrence();
+}
+
+testTypeVariableOccurrence() {
+  var env = new TypeEnvironment(r"""
+      typedef S Typedef1<S>();
+      typedef void Typedef2<S>(S s);
+      typedef void Typedef3<S>(A<S> a);
+
+      class A<T> {
+        int field1;
+        T field2;
+        A<int> field3;
+        A<T> field4;
+        A<A<int>> field5;
+        A<A<T>> field6;
+    
+        Typedef1 field7;
+        Typedef1<int> field8;
+        Typedef1<T> field9;
+        Typedef1<Typedef1<T>> field10;
+
+        Typedef2 field11;
+        Typedef2<int> field12;
+        Typedef2<T> field13;
+        Typedef2<Typedef1<T>> field14;
+
+        Typedef3 field15;
+        Typedef3<int> field16;
+        Typedef3<T> field17;
+        Typedef3<Typedef1<T>> field18;
+
+        void method1() {}
+        T method2() => null;
+        A<T> method3() => null;
+        void method4(T t) {}
+        void method5(A<T> t) {}
+        void method6(void foo(T t)) {}
+        void method7([T t]) {}
+        void method8({T t}) {}
+      }
+      """);
+
+  ClassElement A = env.getElement('A');
+
+  expect(bool expect, String memberName) {
+    DartType memberType = env.getMemberType(A, memberName);
+    TypeVariableType typeVariable = memberType.typeVariableOccurrence;
+    if (expect) {
+      Expect.isNotNull(typeVariable);
+      Expect.equals(A, Types.getClassContext(memberType));
+    } else {
+      Expect.isNull(typeVariable);
+      Expect.isNull(Types.getClassContext(memberType));
+    }
+  }
+
+  // int field1;
+  expect(false, 'field1');
+  // T field2;
+  expect(true, 'field2');
+  // A<int> field3;
+  expect(false, 'field3');
+  // A<T> field4;
+  expect(true, 'field4');
+  // A<A<int>> field5;
+  expect(false, 'field5');
+  // A<A<T>> field6;
+  expect(true, 'field6');
+
+  // Typedef1 field7;
+  expect(false, 'field7');
+  // Typedef1<int> field8;
+  expect(false, 'field8');
+  // Typedef1<T> field9;
+  expect(true, 'field9');
+  // Typedef1<Typedef1<T>> field10;
+  expect(true, 'field10');
+
+  // Typedef2 field11;
+  expect(false, 'field11');
+  // Typedef2<int> field12;
+  expect(false, 'field12');
+  // Typedef2<T> field13;
+  expect(true, 'field13');
+  // Typedef2<Typedef1<T>> field14;
+  expect(true, 'field14');
+
+  // Typedef3 field15;
+  expect(false, 'field15');
+  // Typedef3<int> field16;
+  expect(false, 'field16');
+  // Typedef3<T> field17;
+  expect(true, 'field17');
+  // Typedef3<Typedef1<T>> field18;
+  expect(true, 'field18');
+
+  // void method1() {}
+  expect(false, 'method1');
+  // T method2() => null;
+  expect(true, 'method2');
+  // A<T> method3() => null;
+  expect(true, 'method3');
+  // void method4(T t) {}
+  expect(true, 'method4');
+  // void method5(A<T> t) {}
+  expect(true, 'method5');
+  // void method6(void foo(T t)) {}
+  expect(true, 'method6');
+  // void method7([T t]);
+  expect(true, 'method7');
+  // void method8({T t});
+  expect(true, 'method8');
+
+}
diff --git a/tests/compiler/dart2js/types_of_captured_variables_test.dart b/tests/compiler/dart2js/types_of_captured_variables_test.dart
new file mode 100644
index 0000000..77c9e25
--- /dev/null
+++ b/tests/compiler/dart2js/types_of_captured_variables_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'compiler_helper.dart';
+
+const String TEST1 = r"""
+main() {
+  var a = 52;
+  var f = () => a + 3;
+  f();
+}
+""";
+
+const String TEST2 = r"""
+main() {
+  var a = 52;
+  var g = () { a = 48; };
+  var f = () => a + 3;
+  f();
+  g();
+}
+""";
+
+const String TEST3 = r"""
+main() {
+  var a = 52;
+  var g = () { a = 'foo'; };
+  var f = () => a + 3;
+  f();
+  g();
+}
+""";
+
+main() {
+  // Test that we know the type of captured, non-mutated variables.
+  String generated = compileAll(TEST1);
+  Expect.isTrue(generated.contains('+ 3'));
+
+  // Test that we know the type of captured, mutated variables.
+  generated = compileAll(TEST2);
+  Expect.isTrue(generated.contains('+ 3'));
+
+  // Test that we know when types of a captured, mutated variable
+  // conflict.
+  generated = compileAll(TEST3);
+  Expect.isFalse(generated.contains('+ 3'));
+}
diff --git a/tests/compiler/dart2js/unparser_test.dart b/tests/compiler/dart2js/unparser_test.dart
index ee7b710..a6bb634 100644
--- a/tests/compiler/dart2js/unparser_test.dart
+++ b/tests/compiler/dart2js/unparser_test.dart
@@ -306,16 +306,16 @@
 
 testUnparseParameters(List<String> variableDeclarations) {
   var sb = new StringBuffer();
-  sb.add('Constructor(');
+  sb.write('Constructor(');
   int index = 0;
   for (String variableDeclaration in variableDeclarations) {
     if (index != 0) {
-      sb.add(', ');
+      sb.write(', ');
     }
-    sb.add(variableDeclaration);
+    sb.write(variableDeclaration);
     index++;
   }
-  sb.add(');');
+  sb.write(');');
 
   FunctionExpression node = parseMember(sb.toString());
   index = 0;
diff --git a/tests/compiler/dart2js/value_range2_test.dart b/tests/compiler/dart2js/value_range2_test.dart
index bd84602..1c24f97 100644
--- a/tests/compiler/dart2js/value_range2_test.dart
+++ b/tests/compiler/dart2js/value_range2_test.dart
@@ -11,7 +11,7 @@
 Value instructionValue = info.newInstructionValue(new HReturn(null));
 Value lengthValue = info.newLengthValue(new HReturn(null));
 
-Range createSingleRange(Value value) => info.newRange(value, value);
+Range createSingleRange(Value value) => info.newNormalizedRange(value, value);
 
 Range createSingleIntRange(int value) {
   return createSingleRange(info.newIntValue(value));
@@ -22,15 +22,16 @@
 Range createSingleLengthRange() => createSingleRange(lengthValue);
 
 Range createIntRange(int lower, int upper) {
-  return info.newRange(info.newIntValue(lower), info.newIntValue(upper));
+  return info.newNormalizedRange(
+      info.newIntValue(lower), info.newIntValue(upper));
 }
 
 Range createLengthRange(int lower) {
-  return info.newRange(info.newIntValue(lower), lengthValue);
+  return info.newNormalizedRange(info.newIntValue(lower), lengthValue);
 }
 
 Range createInstructionRange(int lower) {
-  return info.newRange(info.newIntValue(lower), instructionValue);
+  return info.newNormalizedRange(info.newIntValue(lower), instructionValue);
 }
 
 Range instruction = createSingleInstructionRange();
@@ -48,7 +49,7 @@
 checkAndRange(Range one, Range two, lower, upper) {
   if (lower is num) lower = info.newIntValue(lower);
   if (upper is num) upper = info.newIntValue(upper);
-  Range range = info.newRange(lower, upper);
+  Range range = info.newNormalizedRange(lower, upper);
   Expect.equals(range, one & two);
 }
 
@@ -84,7 +85,7 @@
     upper = info.newIntValue(upper);
   }
 
-  Expect.equals(info.newRange(lower, upper), one - two);
+  Expect.equals(info.newNormalizedRange(lower, upper), one - two);
 }
 
 checkNegateRange(Range range, [arg1, arg2]) {
@@ -106,7 +107,7 @@
     } else {
       up = arg2;
     }
-    Expect.equals(info.newRange(low, up), -range);
+    Expect.equals(info.newNormalizedRange(low, up), -range);
   }
 }
 
diff --git a/tests/compiler/dart2js/value_range_test.dart b/tests/compiler/dart2js/value_range_test.dart
index e1bfe73..1f03e88 100644
--- a/tests/compiler/dart2js/value_range_test.dart
+++ b/tests/compiler/dart2js/value_range_test.dart
@@ -213,7 +213,6 @@
   class Function {}
   class List {
     List([int length]);
-    List.filled(int length, fill);
   }
   abstract class Map {}
   class Closure {}
@@ -222,12 +221,16 @@
   bool identical(Object a, Object b) {}''';
 
 const String INTERCEPTORSLIB_WITH_MEMBERS = r'''
-  class JSArray {
+  class JSIndexable {}
+  class JSArray implements JSIndexable {
     var length;
     var removeLast;
     operator[] (_) {}
   }
-  class JSString {
+  class JSMutableArray extends JSArray {}
+  class JSFixedArray extends JSMutableArray {}
+  class JSExtendableArray extends JSMutableArray {}
+  class JSString implements JSIndexable {
     var length;
   }
   class JSNumber {
diff --git a/tests/compiler/dart2js_extra/bailout_test.dart b/tests/compiler/dart2js_extra/bailout_test.dart
index dd31071f..cbc42ae 100644
--- a/tests/compiler/dart2js_extra/bailout_test.dart
+++ b/tests/compiler/dart2js_extra/bailout_test.dart
@@ -37,7 +37,7 @@
   for (int i = 0; i < n; i++) {
     var o = myString;
     if (false) o[1] = 2;
-    res = res.concat(o[i]);
+    res += o[i];
   }
   return res;
 }
@@ -48,7 +48,7 @@
   for (int i in myString.codeUnits) {
     var o = myString;
     if (false) o[1] = 2;
-    res = res.concat(new String.fromCharCodes([i]));
+    res += new String.fromCharCodes([i]);
   }
   return res;
 }
@@ -60,7 +60,7 @@
     for (int j = 0; j < n; j++) {
       var o = myString;
       if (false) o[1] = 2;
-      res = res.concat(o[j]);
+      res += o[j];
     }
   }
   return res;
@@ -73,7 +73,7 @@
   while (i < n) {
     var o = myString;
     if (false) o[1] = 2;
-    res = res.concat(o[i]);
+    res += o[i];
     i++;
   }
   return res;
@@ -86,7 +86,7 @@
   do {
     var o = myString;
     if (false) o[1] = 2;
-    res = res.concat(o[i]);
+    res += o[i];
     i++;
   } while (i < n);
   return res;
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index 1660de8d..f0490f9 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -10,6 +10,9 @@
 
 deferred_semantics_test/none: Fail # TODO(ahe): Multitest cannot use import.
 
+[ $runtime == ff ]
+deferred/deferred_constant_test: Pass, Crash # Issue 9158
+deferred/deferred_class_test: Pass, Crash # Issue 9158
 
 [ $compiler == dart2js && $checked ]
 parameter_bailout_test: Fail, OK
diff --git a/tests/compiler/dart2js_extra/regress/4515_1_test.dart b/tests/compiler/dart2js_extra/regress/4515_1_test.dart
index 41faa95..6d8b136 100644
--- a/tests/compiler/dart2js_extra/regress/4515_1_test.dart
+++ b/tests/compiler/dart2js_extra/regress/4515_1_test.dart
@@ -11,5 +11,5 @@
 main() {
   A a = new A();
   a.a(1);
-  Expect.throws(() => print(f(a.a)), (e) => e is NoSuchMethodError);
+  Expect.throws(() => print(f(a.a)));
 }
diff --git a/tests/compiler/dart2js_extra/regress/4515_2_test.dart b/tests/compiler/dart2js_extra/regress/4515_2_test.dart
index fb271a1..8ddc8de 100644
--- a/tests/compiler/dart2js_extra/regress/4515_2_test.dart
+++ b/tests/compiler/dart2js_extra/regress/4515_2_test.dart
@@ -11,6 +11,5 @@
 main() {
   A a = new A();
   a.a(1);
-  Expect.throws(
-      () => print(f((x) => (a.a(x)))), (e) => e is NoSuchMethodError);
+  Expect.throws(() => print(f((x) => (a.a(x)))));
 }
diff --git a/tests/compiler/dart2js_extra/super_call_test.dart b/tests/compiler/dart2js_extra/super_call_test.dart
index 6fde7c2..7c28f44 100644
--- a/tests/compiler/dart2js_extra/super_call_test.dart
+++ b/tests/compiler/dart2js_extra/super_call_test.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
 class A {
   foo() => "A.foo${baz()}";
   baz() => "A.baz";
diff --git a/tests/compiler/dart2js_extra/this_phi_elimination_test.dart b/tests/compiler/dart2js_extra/this_phi_elimination_test.dart
index eaac2ba..f678b8f 100644
--- a/tests/compiler/dart2js_extra/this_phi_elimination_test.dart
+++ b/tests/compiler/dart2js_extra/this_phi_elimination_test.dart
@@ -15,5 +15,5 @@
 
 main() {
   Expect.equals(42, new A().foo(0));
-  Expect.throws(() => new A().foo(""), (e) => e is NoSuchMethodError);
+  Expect.throws(() => new A().foo(""));
 }
diff --git a/tests/compiler/dart2js_extra/to_string_test.dart b/tests/compiler/dart2js_extra/to_string_test.dart
index ee28afe..0227534 100644
--- a/tests/compiler/dart2js_extra/to_string_test.dart
+++ b/tests/compiler/dart2js_extra/to_string_test.dart
@@ -9,7 +9,7 @@
   final x;
   final y;
   Concater(x, y) : this.x = x, this.y = y;
-  add() => x.concat(y.toString());
+  add() => x + y.toString();
 }
 
 test(expected, x) {
diff --git a/tests/compiler/dart2js_native/field_type_test.dart b/tests/compiler/dart2js_native/field_type_test.dart
new file mode 100644
index 0000000..9de1cfb
--- /dev/null
+++ b/tests/compiler/dart2js_native/field_type_test.dart
@@ -0,0 +1,68 @@
+// 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.
+
+// A native class has no defined constructor.
+// This regression test verifies that compiler accounts for hidden constructor
+// when analysing field values.
+
+class Node native "*Node" {
+
+  final Node parentNode;
+
+  ModelSource _modelSource;  // If null, inherited from parent.
+
+  ModelSource get modelSource {
+    for (Node node = this; node != null; node = node.parentNode) {
+      ModelSource source = node._modelSource;
+      if (source != null) return source;
+    }
+    return null;
+  }
+
+  // Copy of above code renamed with suffix '2'.
+
+  ModelSource _modelSource2;  // If null, inherited from parent.
+
+  ModelSource get modelSource2 {
+    for (Node node = this; node != null; node = node.parentNode) {
+      ModelSource source = node._modelSource2;
+      if (source != null) return source;
+    }
+    return null;
+  }
+}
+
+makeNode(parent) native;
+
+class ModelSource {
+  var name;
+  ModelSource(this.name);
+  toString() => 'ModelSource($name)';
+}
+
+void setup() native """
+// This code is all inside 'setup' and so not accesible from the global scope.
+function Node(parent){ this.parentNode = parent; }
+makeNode = function(p){return new Node(p);};
+""";
+
+
+main() {
+  setup();
+
+  var n1 = makeNode(null);
+  var n2 = makeNode(n1);
+  var n3 = makeNode(n2);
+
+  var m1 = new ModelSource('1');
+  n2._modelSource = null;        // null write.
+  n2._modelSource = m1;          // Non-null write.
+  var x1 = n3.modelSource;
+  Expect.identical(m1, x1);
+
+  var m2 = new ModelSource('2');
+  n2._modelSource2 = m2;         // The only write is non-null.
+  var x2 = n3.modelSource2;
+  Expect.identical(m2, x2);
+}
diff --git a/tests/compiler/dart2js_native/is_check_test.dart b/tests/compiler/dart2js_native/is_check_test.dart
new file mode 100644
index 0000000..f0ae311
--- /dev/null
+++ b/tests/compiler/dart2js_native/is_check_test.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A native "*A" {}
+
+main() {
+  var a = [new Object()];
+  Expect.isFalse(a[0] is A);
+}
diff --git a/tests/compiler/dart2js_native/native_call_arity2_frog_test.dart b/tests/compiler/dart2js_native/native_call_arity2_frog_test.dart
index b24893a..f292ad1 100644
--- a/tests/compiler/dart2js_native/native_call_arity2_frog_test.dart
+++ b/tests/compiler/dart2js_native/native_call_arity2_frog_test.dart
@@ -13,8 +13,8 @@
   int foo([x, y]) native;
 }
 
-A makeA() native { return new A(); }
-B makeB() native { return new B(); }
+makeA() native;
+makeB() native;
 
 void setup() native """
 function inherits(child, parent) {
@@ -38,7 +38,6 @@
 makeB = function(){return new B;};
 """;
 
-
 testDynamicContext() {
   var things = [makeA(), makeB()];
   var a = things[0];
diff --git a/tests/compiler/dart2js_native/native_no_such_method_exception3_frog_test.dart b/tests/compiler/dart2js_native/native_no_such_method_exception3_frog_test.dart
index 22f4369..bdae2c8 100644
--- a/tests/compiler/dart2js_native/native_no_such_method_exception3_frog_test.dart
+++ b/tests/compiler/dart2js_native/native_no_such_method_exception3_frog_test.dart
@@ -2,6 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+class GetName {
+  foo(x, y, [z]) => "foo";
+}
+
+String getName(im) => im.invokeOn(new GetName());
+
 class A native "*A" {
   bar() => 42;
 }
@@ -12,7 +18,7 @@
 
 class C {
   static create() => new C();
-  noSuchMethod(x) => "${x.memberName}:${x.positionalArguments}";
+  noSuchMethod(x) => "${getName(x)}:${x.positionalArguments}";
 }
 
 makeA() native;
diff --git a/tests/compiler/dart2js_native/native_no_such_method_exception4_frog_test.dart b/tests/compiler/dart2js_native/native_no_such_method_exception4_frog_test.dart
index 3827cac..e9621bb 100644
--- a/tests/compiler/dart2js_native/native_no_such_method_exception4_frog_test.dart
+++ b/tests/compiler/dart2js_native/native_no_such_method_exception4_frog_test.dart
@@ -2,9 +2,16 @@
 // 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 GetName {
+  foo(x, y) => "foo";
+  baz(x, y, z) => "baz";
+}
+
+String getName(im) => im.invokeOn(new GetName());
+
 class A native "*A" {
   bar() => 42;
-  noSuchMethod(x) => "native(${x.memberName}:${x.positionalArguments})";
+  noSuchMethod(x) => "native(${getName(x)}:${x.positionalArguments})";
 }
 
 class B native "*B" {
diff --git a/tests/compiler/dart2js_native/native_no_such_method_exception5_frog_test.dart b/tests/compiler/dart2js_native/native_no_such_method_exception5_frog_test.dart
index c0f03ac..2a44809 100644
--- a/tests/compiler/dart2js_native/native_no_such_method_exception5_frog_test.dart
+++ b/tests/compiler/dart2js_native/native_no_such_method_exception5_frog_test.dart
@@ -2,9 +2,16 @@
 // 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 GetName {
+  foo(x, [y]) => "foo";
+  baz(x, y, z) => "baz";
+}
+
+String getName(im) => im.invokeOn(new GetName());
+
 class A native "*A" {
   bar() => 42;
-  noSuchMethod(x) => "native(${x.memberName}:${x.positionalArguments})";
+  noSuchMethod(x) => "native(${getName(x)}:${x.positionalArguments})";
 }
 
 class B native "*B" {
@@ -13,7 +20,7 @@
 
 class C {
   static create() => new C();
-  noSuchMethod(x) => "${x.memberName}:${x.positionalArguments}";
+  noSuchMethod(x) => "${getName(x)}:${x.positionalArguments}";
 }
 
 makeA() native;
diff --git a/tests/corelib/collection_length_test.dart b/tests/corelib/collection_length_test.dart
index e98cb1b..487884a 100644
--- a/tests/corelib/collection_length_test.dart
+++ b/tests/corelib/collection_length_test.dart
@@ -14,11 +14,11 @@
   int length = n;
   while (true) {
     if ((length & 1) == 1) {
-      string = string.concat(s);
+      string += s;
     }
     length >>= 1;
     if (length == 0) break;
-    s = s.concat(s);
+    s += s;
   }
   testLength(string, n);
   testLength(string.codeUnits, n);
@@ -41,6 +41,7 @@
 }
 
 void testList(List list, n) {
+  // Works even if list is fixed-length.
   for (int i = 0; i < n; i++) {
     list[i] = i;
   }
@@ -68,8 +69,8 @@
   testCollection(new HashSet(), N);
   testCollection(new LinkedHashSet(), N);
   testCollection(new ListQueue(), N);
+  testCollection(new DoubleLinkedQueue(), N);
   testList(new List()..length = N, N);
   testList(new List(N), N);
   testString(N);
-  // DoubleLinkedQueue has linear length, but fast isEmpty.
 }
diff --git a/tests/corelib/collection_removes_test.dart b/tests/corelib/collection_removes_test.dart
index d057ed8..7d04483 100644
--- a/tests/corelib/collection_removes_test.dart
+++ b/tests/corelib/collection_removes_test.dart
@@ -45,15 +45,15 @@
   }
 }
 
-testRemoveMatching(Collection base, bool test(value)) {
+testRemoveWhere(Collection base, bool test(value)) {
   Set retained = new Set();
   for (var element in base) {
     if (!test(element)) {
       retained.add(element);
     }
   }
-  String name = "$base.removeMatching(...) -> $retained";
-  base.removeMatching(test);
+  String name = "$base.removeWhere(...) -> $retained";
+  base.removeWhere(test);
   for (var value in base) {
     Expect.isFalse(test(value), "$name: Found $value");
   }
@@ -62,15 +62,15 @@
   }
 }
 
-testRetainMatching(Collection base, bool test(value)) {
+testRetainWhere(Collection base, bool test(value)) {
   Set retained = new Set();
   for (var element in base) {
     if (test(element)) {
       retained.add(element);
     }
   }
-  String name = "$base.retainMatching(...) -> $retained";
-  base.retainMatching(test);
+  String name = "$base.retainWhere(...) -> $retained";
+  base.retainWhere(test);
   for (var value in base) {
     Expect.isTrue(test(value), "$name: Found $value");
   }
@@ -94,16 +94,16 @@
       testRemoveAll(base.toList(), deltaSet);
       testRetainAll(base.toList(), delta);
       testRetainAll(base.toList(), deltaSet);
-      testRemoveMatching(base.toList(), deltaSet.contains);
-      testRetainMatching(base.toList(),
+      testRemoveWhere(base.toList(), deltaSet.contains);
+      testRetainWhere(base.toList(),
                          (e) => !deltaSet.contains(e));
 
       testRemoveAll(base.toSet(), delta);
       testRemoveAll(base.toSet(), deltaSet);
       testRetainAll(base.toSet(), delta);
       testRetainAll(base.toSet(), deltaSet);
-      testRemoveMatching(base.toSet(), deltaSet.contains);
-      testRetainMatching(base.toSet(), (e) => !deltaSet.contains(e));
+      testRemoveWhere(base.toSet(), deltaSet.contains);
+      testRetainWhere(base.toSet(), (e) => !deltaSet.contains(e));
     }
   }
 }
diff --git a/tests/corelib/collection_test.dart b/tests/corelib/collection_test.dart
index 64dfe2b..8ef81f7 100644
--- a/tests/corelib/collection_test.dart
+++ b/tests/corelib/collection_test.dart
@@ -31,10 +31,10 @@
   }
   new CollectionTest(fixedList);
 
-  // Dynamic size list.
+  // Growable list.
   new CollectionTest(new List.from(TEST_ELEMENTS));
 
-  // Dynamic size set.
+  // Set.
   new CollectionTest(new Set.from(TEST_ELEMENTS));
 
   // Queue.
diff --git a/tests/corelib/collection_to_string_test.dart b/tests/corelib/collection_to_string_test.dart
index 3f07236..cbac852 100644
--- a/tests/corelib/collection_to_string_test.dart
+++ b/tests/corelib/collection_to_string_test.dart
@@ -209,14 +209,14 @@
 Collection populateRandomCollection(int size, bool exact,
     StringBuffer stringRep, List beingMade, Collection coll) {
   beingMade.add(coll);
-  stringRep.add(coll is List ? '[' : '{');
+  stringRep.write(coll is List ? '[' : '{');
 
   for (int i = 0; i < size; i++) {
-    if (i != 0) stringRep.add(', ');
+    if (i != 0) stringRep.write(', ');
     coll.add(randomElement(random(size), exact, stringRep, beingMade));
   }
 
-  stringRep.add(coll is List ? ']' : '}');
+  stringRep.write(coll is List ? ']' : '}');
   beingMade.removeLast();
   return coll;
 }
@@ -224,15 +224,15 @@
 /** Like populateRandomCollection, but for sets (elements must be hashable) */
 Set populateRandomSet(int size, bool exact, StringBuffer stringRep,
     List beingMade, Set set) {
-  stringRep.add('{');
+  stringRep.write('{');
 
   for (int i = 0; i < size; i++) {
-    if (i != 0) stringRep.add(', ');
+    if (i != 0) stringRep.write(', ');
     set.add(i);
-    stringRep.add(i);
+    stringRep.write(i);
   }
 
-  stringRep.add('}');
+  stringRep.write('}');
   return set;
 }
 
@@ -241,19 +241,19 @@
 Map populateRandomMap(int size, bool exact, StringBuffer stringRep,
     List beingMade, Map map) {
   beingMade.add(map);
-  stringRep.add('{');
+  stringRep.write('{');
 
   for (int i = 0; i < size; i++) {
-    if (i != 0) stringRep.add(', ');
+    if (i != 0) stringRep.write(', ');
 
     int key = i; // Ensures no duplicates
-    stringRep.add(key);
-    stringRep.add(': ');
+    stringRep.write(key);
+    stringRep.write(': ');
     Object val = randomElement(random(size), exact, stringRep, beingMade);
     map[key] = val;
   }
 
-  stringRep.add('}');
+  stringRep.write('}');
   beingMade.removeLast();
   return map;
 }
@@ -272,7 +272,7 @@
   double elementTypeFrac = rand.nextDouble();
   if (elementTypeFrac < 1/3) {
     result = random(1000);
-    stringRep.add(result);
+    stringRep.write(result);
   } else if (elementTypeFrac < 2/3) {
     // Element Is a random (new) collection
     result = randomCollectionHelper(size, exact, stringRep, beingMade);
@@ -280,9 +280,9 @@
     // Element Is a random recursive ref
     result = beingMade[random(beingMade.length)];
     if (result is List)
-      stringRep.add('[...]');
+      stringRep.write('[...]');
     else
-      stringRep.add('{...}');
+      stringRep.write('{...}');
   }
   return result;
 }
diff --git a/tests/corelib/compare_to2_test.dart b/tests/corelib/compare_to2_test.dart
index 8100fc4..3d1353c 100644
--- a/tests/corelib/compare_to2_test.dart
+++ b/tests/corelib/compare_to2_test.dart
@@ -13,14 +13,14 @@
   var maxFraction = 0.9999999999999999;
   var minAbove1 = 1.0000000000000002;
   var maxNonInt = 4503599627370495.5;
-  var maxNonIntFloorAsDouble = maxNonInt.floor();
-  var maxNonIntFloorAsInt = maxNonIntFloorAsDouble.toInt();
+  var maxNonIntFloorAsInt = maxNonInt.floor();
+  var maxNonIntFloorAsDouble = maxNonIntFloorAsInt.toDouble();
   var maxExactIntAsDouble = 9007199254740992.0;
   var maxExactIntAsInt = 9007199254740992;
   var two53 = 1 << 53;  // Same as maxExactIntAsInt.
   var two53p1 = two53 + 1;
   var maxFiniteAsDouble = 1.7976931348623157e+308;
-  var maxFiniteAsInt = maxFiniteAsDouble.toInt();
+  var maxFiniteAsInt = maxFiniteAsDouble.truncate();
   int huge = 1 << 2000;
   int hugeP1 = huge + 1;
   var inf = double.INFINITY;
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 089101b..9bc31d7 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -12,6 +12,14 @@
 [ $runtime == ff || $runtime == ie9 || $runtime == jsshell ]
 unicode_test: Fail
 
+[ $runtime == ff || $runtime == ie9 || $runtime == jsshell || $runtime == safari ]
+double_round3_test: Fail, OK # Runtime rounds 0.49999999999999994 to 1.
+double_round_to_double2_test: Fail, OK # Runtime rounds 0.49999999999999994 to 1.
+
+[ $runtime == ie9 ]
+double_round4_test: Fail, OK # IE bug: Math.round(4503599627370497) != 4503599627370497.
+double_round_to_double3_test: Fail, OK # IE bug: Math.round(4503599627370497) != 4503599627370497.
+
 [ $compiler == dart2js && ($runtime == chrome || $runtime == drt || $runtime == d8 || $runtime == safari) ]
 string_trim_unicode_test: Fail  # V8 bug 2408
 
@@ -41,9 +49,6 @@
 
 string_replace_func_test: Skip # Bug 6554 - doesn't terminate.
 
-[ $compiler == dart2js && $checked ]
-string_codeunits_test: Fail # Issue 8904
-
 [ $compiler == dart2js && $runtime == none ]
 *: Fail, Pass # TODO(ahe): Triage these tests.
 
diff --git a/tests/corelib/date_time_parse_test.dart b/tests/corelib/date_time_parse_test.dart
index f885392..0df517a 100644
--- a/tests/corelib/date_time_parse_test.dart
+++ b/tests/corelib/date_time_parse_test.dart
@@ -8,13 +8,13 @@
   Expect.equals(expected.isUtc, actual.isUtc);
 }
 main() {
-  check(new Date(2012, 02, 27, 13, 27), "2012-02-27 13:27:00");
-  check(new Date.utc(2012, 02, 27, 13, 27, 0, 123),
+  check(new DateTime(2012, 02, 27, 13, 27), "2012-02-27 13:27:00");
+  check(new DateTime.utc(2012, 02, 27, 13, 27, 0, 123),
         "2012-02-27 13:27:00.123456z");
-  check(new Date(2012, 02, 27, 13, 27), "20120227 13:27:00");
-  check(new Date(2012, 02, 27, 13, 27), "20120227T132700");
-  check(new Date(2012, 02, 27), "20120227");
-  check(new Date(2012, 02, 27), "+20120227");
-  check(new Date.utc(2012, 02, 27, 14), "2012-02-27T14Z");
-  check(new Date.utc(-12345, 1, 1), "-123450101 00:00:00 Z");
+  check(new DateTime(2012, 02, 27, 13, 27), "20120227 13:27:00");
+  check(new DateTime(2012, 02, 27, 13, 27), "20120227T132700");
+  check(new DateTime(2012, 02, 27), "20120227");
+  check(new DateTime(2012, 02, 27), "+20120227");
+  check(new DateTime.utc(2012, 02, 27, 14), "2012-02-27T14Z");
+  check(new DateTime.utc(-12345, 1, 1), "-123450101 00:00:00 Z");
 }
diff --git a/tests/corelib/double_ceil2_test.dart b/tests/corelib/double_ceil2_test.dart
new file mode 100644
index 0000000..12d4412
--- /dev/null
+++ b/tests/corelib/double_ceil2_test.dart
@@ -0,0 +1,10 @@
+// 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.
+
+main() {
+  Expect.throws(() => double.INFINITY.ceil(), (e) => e is UnsupportedError);
+  Expect.throws(() => double.NEGATIVE_INFINITY.ceil(),
+                (e) => e is UnsupportedError);
+  Expect.throws(() => double.NAN.ceil(), (e) => e is UnsupportedError);
+}
diff --git a/tests/corelib/double_ceil_test.dart b/tests/corelib/double_ceil_test.dart
new file mode 100644
index 0000000..cb52287
--- /dev/null
+++ b/tests/corelib/double_ceil_test.dart
@@ -0,0 +1,80 @@
+// 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.
+
+main() {
+  Expect.equals(0, 0.0.ceil());
+  Expect.equals(1, double.MIN_POSITIVE.ceil());
+  Expect.equals(1, (2.0 * double.MIN_POSITIVE).ceil());
+  Expect.equals(1, (1.18e-38).ceil());
+  Expect.equals(1, (1.18e-38 * 2).ceil());
+  Expect.equals(1, 0.49999999999999994.ceil());
+  Expect.equals(1, 0.5.ceil());
+  Expect.equals(1, 0.9999999999999999.ceil());
+  Expect.equals(1, 1.0.ceil());
+  Expect.equals(2, 1.000000000000001.ceil());
+  // The following numbers are on the border of 52 bits.
+  // For example: 4503599627370499 + 0.5 => 4503599627370500.
+  Expect.equals(4503599627370496, 4503599627370496.0.ceil());
+  Expect.equals(4503599627370497, 4503599627370497.0.ceil());
+  Expect.equals(4503599627370498, 4503599627370498.0.ceil());
+  Expect.equals(4503599627370499, 4503599627370499.0.ceil());
+
+  Expect.equals(9007199254740991, 9007199254740991.0.ceil());
+  Expect.equals(9007199254740992, 9007199254740992.0.ceil());
+  Expect.equals(179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368,
+                double.MAX_FINITE.ceil());
+
+  Expect.equals(0, (-double.MIN_POSITIVE).ceil());
+  Expect.equals(0, (2.0 * -double.MIN_POSITIVE).ceil());
+  Expect.equals(0, (-1.18e-38).ceil());
+  Expect.equals(0, (-1.18e-38 * 2).ceil());
+  Expect.equals(0, (-0.49999999999999994).ceil());
+  Expect.equals(0, (-0.5).ceil());
+  Expect.equals(0, (-0.9999999999999999).ceil());
+  Expect.equals(-1, (-1.0).ceil());
+  Expect.equals(-1, (-1.000000000000001).ceil());
+  Expect.equals(-4503599627370496, (-4503599627370496.0).ceil());
+  Expect.equals(-4503599627370497, (-4503599627370497.0).ceil());
+  Expect.equals(-4503599627370498, (-4503599627370498.0).ceil());
+  Expect.equals(-4503599627370499, (-4503599627370499.0).ceil());
+  Expect.equals(-9007199254740991, (-9007199254740991.0).ceil());
+  Expect.equals(-9007199254740992, (-9007199254740992.0).ceil());
+  Expect.equals(-179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368,
+                (-double.MAX_FINITE).ceil());
+
+  Expect.isTrue(0.0.ceil() is int);
+  Expect.isTrue(double.MIN_POSITIVE.ceil() is int);
+  Expect.isTrue((2.0 * double.MIN_POSITIVE).ceil() is int);
+  Expect.isTrue((1.18e-38).ceil() is int);
+  Expect.isTrue((1.18e-38 * 2).ceil() is int);
+  Expect.isTrue(0.49999999999999994.ceil() is int);
+  Expect.isTrue(0.5.ceil() is int);
+  Expect.isTrue(0.9999999999999999.ceil() is int);
+  Expect.isTrue(1.0.ceil() is int);
+  Expect.isTrue(1.000000000000001.ceil() is int);
+  Expect.isTrue(4503599627370496.0.ceil() is int);
+  Expect.isTrue(4503599627370497.0.ceil() is int);
+  Expect.isTrue(4503599627370498.0.ceil() is int);
+  Expect.isTrue(4503599627370499.0.ceil() is int);
+  Expect.isTrue(9007199254740991.0.ceil() is int);
+  Expect.isTrue(9007199254740992.0.ceil() is int);
+  Expect.isTrue(double.MAX_FINITE.ceil() is int);
+
+  Expect.isTrue((-double.MIN_POSITIVE).ceil() is int);
+  Expect.isTrue((2.0 * -double.MIN_POSITIVE).ceil() is int);
+  Expect.isTrue((-1.18e-38).ceil() is int);
+  Expect.isTrue((-1.18e-38 * 2).ceil() is int);
+  Expect.isTrue((-0.49999999999999994).ceil() is int);
+  Expect.isTrue((-0.5).ceil() is int);
+  Expect.isTrue((-0.9999999999999999).ceil() is int);
+  Expect.isTrue((-1.0).ceil() is int);
+  Expect.isTrue((-1.000000000000001).ceil() is int);
+  Expect.isTrue((-4503599627370496.0).ceil() is int);
+  Expect.isTrue((-4503599627370497.0).ceil() is int);
+  Expect.isTrue((-4503599627370498.0).ceil() is int);
+  Expect.isTrue((-4503599627370499.0).ceil() is int);
+  Expect.isTrue((-9007199254740991.0).ceil() is int);
+  Expect.isTrue((-9007199254740992.0).ceil() is int);
+  Expect.isTrue((-double.MAX_FINITE).ceil() is int);
+}
\ No newline at end of file
diff --git a/tests/corelib/double_ceil_to_double_test.dart b/tests/corelib/double_ceil_to_double_test.dart
new file mode 100644
index 0000000..40b2c7d
--- /dev/null
+++ b/tests/corelib/double_ceil_to_double_test.dart
@@ -0,0 +1,91 @@
+// 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.
+
+main() {
+  Expect.equals(0.0, 0.0.ceilToDouble());
+  Expect.equals(1.0, double.MIN_POSITIVE.ceilToDouble());
+  Expect.equals(1.0, (2.0 * double.MIN_POSITIVE).ceilToDouble());
+  Expect.equals(1.0, (1.18e-38).ceilToDouble());
+  Expect.equals(1.0, (1.18e-38 * 2).ceilToDouble());
+  Expect.equals(1.0, 0.49999999999999994.ceilToDouble());
+  Expect.equals(1.0, 0.5.ceilToDouble());
+  Expect.equals(1.0, 0.9999999999999999.ceilToDouble());
+  Expect.equals(1.0, 1.0.ceilToDouble());
+  Expect.equals(2.0, 1.000000000000001.ceilToDouble());
+  // The following numbers are on the border of 52 bits.
+  // For example: 4503599627370499 + 0.5 => 4503599627370500.
+  Expect.equals(4503599627370496.0, 4503599627370496.0.ceilToDouble());
+  Expect.equals(4503599627370497.0, 4503599627370497.0.ceilToDouble());
+  Expect.equals(4503599627370498.0, 4503599627370498.0.ceilToDouble());
+  Expect.equals(4503599627370499.0, 4503599627370499.0.ceilToDouble());
+
+  Expect.equals(9007199254740991.0, 9007199254740991.0.ceilToDouble());
+  Expect.equals(9007199254740992.0, 9007199254740992.0.ceilToDouble());
+  Expect.equals(double.MAX_FINITE, double.MAX_FINITE.ceilToDouble());
+
+  Expect.equals(0.0, (-double.MIN_POSITIVE).ceilToDouble());
+  Expect.equals(0.0, (2.0 * -double.MIN_POSITIVE).ceilToDouble());
+  Expect.equals(0.0, (-1.18e-38).ceilToDouble());
+  Expect.equals(0.0, (-1.18e-38 * 2).ceilToDouble());
+  Expect.equals(0.0, (-0.49999999999999994).ceilToDouble());
+  Expect.equals(0.0, (-0.5).ceilToDouble());
+  Expect.equals(0.0, (-0.9999999999999999).ceilToDouble());
+  Expect.equals(-1.0, (-1.0).ceilToDouble());
+  Expect.equals(-1.0, (-1.000000000000001).ceilToDouble());
+  Expect.equals(-4503599627370496.0, (-4503599627370496.0).ceilToDouble());
+  Expect.equals(-4503599627370497.0, (-4503599627370497.0).ceilToDouble());
+  Expect.equals(-4503599627370498.0, (-4503599627370498.0).ceilToDouble());
+  Expect.equals(-4503599627370499.0, (-4503599627370499.0).ceilToDouble());
+  Expect.equals(-9007199254740991.0, (-9007199254740991.0).ceilToDouble());
+  Expect.equals(-9007199254740992.0, (-9007199254740992.0).ceilToDouble());
+  Expect.equals(-double.MAX_FINITE, (-double.MAX_FINITE).ceilToDouble());
+
+  Expect.equals(double.INFINITY, double.INFINITY.ceilToDouble());
+  Expect.equals(double.NEGATIVE_INFINITY,
+                double.NEGATIVE_INFINITY.ceilToDouble());
+  Expect.isTrue(double.NAN.ceilToDouble().isNaN);
+
+  Expect.isTrue(0.0.ceilToDouble() is double);
+  Expect.isTrue(double.MIN_POSITIVE.ceilToDouble() is double);
+  Expect.isTrue((2.0 * double.MIN_POSITIVE).ceilToDouble() is double);
+  Expect.isTrue((1.18e-38).ceilToDouble() is double);
+  Expect.isTrue((1.18e-38 * 2).ceilToDouble() is double);
+  Expect.isTrue(0.49999999999999994.ceilToDouble() is double);
+  Expect.isTrue(0.5.ceilToDouble() is double);
+  Expect.isTrue(0.9999999999999999.ceilToDouble() is double);
+  Expect.isTrue(1.0.ceilToDouble() is double);
+  Expect.isTrue(1.000000000000001.ceilToDouble() is double);
+  Expect.isTrue(4503599627370496.0.ceilToDouble() is double);
+  Expect.isTrue(4503599627370497.0.ceilToDouble() is double);
+  Expect.isTrue(4503599627370498.0.ceilToDouble() is double);
+  Expect.isTrue(4503599627370499.0.ceilToDouble() is double);
+  Expect.isTrue(9007199254740991.0.ceilToDouble() is double);
+  Expect.isTrue(9007199254740992.0.ceilToDouble() is double);
+  Expect.isTrue(double.MAX_FINITE.ceilToDouble() is double);
+
+  Expect.isTrue((-double.MIN_POSITIVE).ceilToDouble().isNegative);
+  Expect.isTrue((2.0 * -double.MIN_POSITIVE).ceilToDouble().isNegative);
+  Expect.isTrue((-1.18e-38).ceilToDouble().isNegative);
+  Expect.isTrue((-1.18e-38 * 2).ceilToDouble().isNegative);
+  Expect.isTrue((-0.49999999999999994).ceilToDouble().isNegative);
+  Expect.isTrue((-0.5).ceilToDouble().isNegative);
+  Expect.isTrue((-0.9999999999999999).ceilToDouble().isNegative);
+
+  Expect.isTrue((-double.MIN_POSITIVE).ceilToDouble() is double);
+  Expect.isTrue((2.0 * -double.MIN_POSITIVE).ceilToDouble() is double);
+  Expect.isTrue((-1.18e-38).ceilToDouble() is double);
+  Expect.isTrue((-1.18e-38 * 2).ceilToDouble() is double);
+  Expect.isTrue((-0.49999999999999994).ceilToDouble() is double);
+  Expect.isTrue((-0.5).ceilToDouble() is double);
+  Expect.isTrue((-0.9999999999999999).ceilToDouble() is double);
+  Expect.isTrue((-1.0).ceilToDouble() is double);
+  Expect.isTrue((-1.000000000000001).ceilToDouble() is double);
+  Expect.isTrue((-4503599627370496.0).ceilToDouble() is double);
+  Expect.isTrue((-4503599627370497.0).ceilToDouble() is double);
+  Expect.isTrue((-4503599627370498.0).ceilToDouble() is double);
+  Expect.isTrue((-4503599627370499.0).ceilToDouble() is double);
+  Expect.isTrue((-9007199254740991.0).ceilToDouble() is double);
+  Expect.isTrue((-9007199254740992.0).ceilToDouble() is double);
+  Expect.isTrue((-double.MAX_FINITE).ceilToDouble() is double);
+}
\ No newline at end of file
diff --git a/tests/corelib/double_floor2_test.dart b/tests/corelib/double_floor2_test.dart
new file mode 100644
index 0000000..b17a375
--- /dev/null
+++ b/tests/corelib/double_floor2_test.dart
@@ -0,0 +1,10 @@
+// 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.
+
+main() {
+  Expect.throws(() => double.INFINITY.floor(), (e) => e is UnsupportedError);
+  Expect.throws(() => double.NEGATIVE_INFINITY.floor(),
+                (e) => e is UnsupportedError);
+  Expect.throws(() => double.NAN.floor(), (e) => e is UnsupportedError);
+}
diff --git a/tests/corelib/double_floor_test.dart b/tests/corelib/double_floor_test.dart
new file mode 100644
index 0000000..cafc159
--- /dev/null
+++ b/tests/corelib/double_floor_test.dart
@@ -0,0 +1,80 @@
+// 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.
+
+main() {
+  Expect.equals(0, 0.0.floor());
+  Expect.equals(0, double.MIN_POSITIVE.floor());
+  Expect.equals(0, (2.0 * double.MIN_POSITIVE).floor());
+  Expect.equals(0, (1.18e-38).floor());
+  Expect.equals(0, (1.18e-38 * 2).floor());
+  Expect.equals(0, 0.49999999999999994.floor());
+  Expect.equals(0, 0.5.floor());
+  Expect.equals(0, 0.9999999999999999.floor());
+  Expect.equals(1, 1.0.floor());
+  Expect.equals(1, 1.000000000000001.floor());
+  // The following numbers are on the border of 52 bits.
+  // For example: 4503599627370499 + 0.5 => 4503599627370500.
+  Expect.equals(4503599627370496, 4503599627370496.0.floor());
+  Expect.equals(4503599627370497, 4503599627370497.0.floor());
+  Expect.equals(4503599627370498, 4503599627370498.0.floor());
+  Expect.equals(4503599627370499, 4503599627370499.0.floor());
+
+  Expect.equals(9007199254740991, 9007199254740991.0.floor());
+  Expect.equals(9007199254740992, 9007199254740992.0.floor());
+  Expect.equals(179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368,
+                double.MAX_FINITE.floor());
+
+  Expect.equals(-1, (-double.MIN_POSITIVE).floor());
+  Expect.equals(-1, (2.0 * -double.MIN_POSITIVE).floor());
+  Expect.equals(-1, (-1.18e-38).floor());
+  Expect.equals(-1, (-1.18e-38 * 2).floor());
+  Expect.equals(-1, (-0.49999999999999994).floor());
+  Expect.equals(-1, (-0.5).floor());
+  Expect.equals(-1, (-0.9999999999999999).floor());
+  Expect.equals(-1, (-1.0).floor());
+  Expect.equals(-2, (-1.000000000000001).floor());
+  Expect.equals(-4503599627370496, (-4503599627370496.0).floor());
+  Expect.equals(-4503599627370497, (-4503599627370497.0).floor());
+  Expect.equals(-4503599627370498, (-4503599627370498.0).floor());
+  Expect.equals(-4503599627370499, (-4503599627370499.0).floor());
+  Expect.equals(-9007199254740991, (-9007199254740991.0).floor());
+  Expect.equals(-9007199254740992, (-9007199254740992.0).floor());
+  Expect.equals(-179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368,
+                (-double.MAX_FINITE).floor());
+
+  Expect.isTrue(0.0.floor() is int);
+  Expect.isTrue(double.MIN_POSITIVE.floor() is int);
+  Expect.isTrue((2.0 * double.MIN_POSITIVE).floor() is int);
+  Expect.isTrue((1.18e-38).floor() is int);
+  Expect.isTrue((1.18e-38 * 2).floor() is int);
+  Expect.isTrue(0.49999999999999994.floor() is int);
+  Expect.isTrue(0.5.floor() is int);
+  Expect.isTrue(0.9999999999999999.floor() is int);
+  Expect.isTrue(1.0.floor() is int);
+  Expect.isTrue(1.000000000000001.floor() is int);
+  Expect.isTrue(4503599627370496.0.floor() is int);
+  Expect.isTrue(4503599627370497.0.floor() is int);
+  Expect.isTrue(4503599627370498.0.floor() is int);
+  Expect.isTrue(4503599627370499.0.floor() is int);
+  Expect.isTrue(9007199254740991.0.floor() is int);
+  Expect.isTrue(9007199254740992.0.floor() is int);
+  Expect.isTrue(double.MAX_FINITE.floor() is int);
+
+  Expect.isTrue((-double.MIN_POSITIVE).floor() is int);
+  Expect.isTrue((2.0 * -double.MIN_POSITIVE).floor() is int);
+  Expect.isTrue((-1.18e-38).floor() is int);
+  Expect.isTrue((-1.18e-38 * 2).floor() is int);
+  Expect.isTrue((-0.49999999999999994).floor() is int);
+  Expect.isTrue((-0.5).floor() is int);
+  Expect.isTrue((-0.9999999999999999).floor() is int);
+  Expect.isTrue((-1.0).floor() is int);
+  Expect.isTrue((-1.000000000000001).floor() is int);
+  Expect.isTrue((-4503599627370496.0).floor() is int);
+  Expect.isTrue((-4503599627370497.0).floor() is int);
+  Expect.isTrue((-4503599627370498.0).floor() is int);
+  Expect.isTrue((-4503599627370499.0).floor() is int);
+  Expect.isTrue((-9007199254740991.0).floor() is int);
+  Expect.isTrue((-9007199254740992.0).floor() is int);
+  Expect.isTrue((-double.MAX_FINITE).floor() is int);
+}
\ No newline at end of file
diff --git a/tests/corelib/double_floor_to_double_test.dart b/tests/corelib/double_floor_to_double_test.dart
new file mode 100644
index 0000000..cfcc908
--- /dev/null
+++ b/tests/corelib/double_floor_to_double_test.dart
@@ -0,0 +1,83 @@
+// 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.
+
+main() {
+  Expect.equals(0.0, 0.0.floorToDouble());
+  Expect.equals(0.0, double.MIN_POSITIVE.floorToDouble());
+  Expect.equals(0.0, (2.0 * double.MIN_POSITIVE).floorToDouble());
+  Expect.equals(0.0, (1.18e-38).floorToDouble());
+  Expect.equals(0.0, (1.18e-38 * 2).floorToDouble());
+  Expect.equals(0.0, 0.49999999999999994.floorToDouble());
+  Expect.equals(0.0, 0.5.floorToDouble());
+  Expect.equals(0.0, 0.9999999999999999.floorToDouble());
+  Expect.equals(1.0, 1.0.floorToDouble());
+  Expect.equals(1.0, 1.000000000000001.floorToDouble());
+  // The following numbers are on the border of 52 bits.
+  // For example: 4503599627370499 + 0.5 => 4503599627370500.
+  Expect.equals(4503599627370496.0, 4503599627370496.0.floorToDouble());
+  Expect.equals(4503599627370497.0, 4503599627370497.0.floorToDouble());
+  Expect.equals(4503599627370498.0, 4503599627370498.0.floorToDouble());
+  Expect.equals(4503599627370499.0, 4503599627370499.0.floorToDouble());
+
+  Expect.equals(9007199254740991.0, 9007199254740991.0.floorToDouble());
+  Expect.equals(9007199254740992.0, 9007199254740992.0.floorToDouble());
+  Expect.equals(double.MAX_FINITE, double.MAX_FINITE.floorToDouble());
+
+  Expect.equals(-1.0, (-double.MIN_POSITIVE).floorToDouble());
+  Expect.equals(-1.0, (2.0 * -double.MIN_POSITIVE).floorToDouble());
+  Expect.equals(-1.0, (-1.18e-38).floorToDouble());
+  Expect.equals(-1.0, (-1.18e-38 * 2).floorToDouble());
+  Expect.equals(-1.0, (-0.49999999999999994).floorToDouble());
+  Expect.equals(-1.0, (-0.5).floorToDouble());
+  Expect.equals(-1.0, (-0.9999999999999999).floorToDouble());
+  Expect.equals(-1.0, (-1.0).floorToDouble());
+  Expect.equals(-2.0, (-1.000000000000001).floorToDouble());
+  Expect.equals(-4503599627370496.0, (-4503599627370496.0).floorToDouble());
+  Expect.equals(-4503599627370497.0, (-4503599627370497.0).floorToDouble());
+  Expect.equals(-4503599627370498.0, (-4503599627370498.0).floorToDouble());
+  Expect.equals(-4503599627370499.0, (-4503599627370499.0).floorToDouble());
+  Expect.equals(-9007199254740991.0, (-9007199254740991.0).floorToDouble());
+  Expect.equals(-9007199254740992.0, (-9007199254740992.0).floorToDouble());
+  Expect.equals(-double.MAX_FINITE, (-double.MAX_FINITE).floorToDouble());
+
+  Expect.equals(double.INFINITY, double.INFINITY.floorToDouble());
+  Expect.equals(double.NEGATIVE_INFINITY,
+                double.NEGATIVE_INFINITY.floorToDouble());
+  Expect.isTrue(double.NAN.floorToDouble().isNaN);
+
+  Expect.isTrue(0.0.floorToDouble() is double);
+  Expect.isTrue(double.MIN_POSITIVE.floorToDouble() is double);
+  Expect.isTrue((2.0 * double.MIN_POSITIVE).floorToDouble() is double);
+  Expect.isTrue((1.18e-38).floorToDouble() is double);
+  Expect.isTrue((1.18e-38 * 2).floorToDouble() is double);
+  Expect.isTrue(0.49999999999999994.floorToDouble() is double);
+  Expect.isTrue(0.5.floorToDouble() is double);
+  Expect.isTrue(0.9999999999999999.floorToDouble() is double);
+  Expect.isTrue(1.0.floorToDouble() is double);
+  Expect.isTrue(1.000000000000001.floorToDouble() is double);
+  Expect.isTrue(4503599627370496.0.floorToDouble() is double);
+  Expect.isTrue(4503599627370497.0.floorToDouble() is double);
+  Expect.isTrue(4503599627370498.0.floorToDouble() is double);
+  Expect.isTrue(4503599627370499.0.floorToDouble() is double);
+  Expect.isTrue(9007199254740991.0.floorToDouble() is double);
+  Expect.isTrue(9007199254740992.0.floorToDouble() is double);
+  Expect.isTrue(double.MAX_FINITE.floorToDouble() is double);
+
+  Expect.isTrue((-double.MIN_POSITIVE).floorToDouble() is double);
+  Expect.isTrue((2.0 * -double.MIN_POSITIVE).floorToDouble() is double);
+  Expect.isTrue((-1.18e-38).floorToDouble() is double);
+  Expect.isTrue((-1.18e-38 * 2).floorToDouble() is double);
+  Expect.isTrue((-0.49999999999999994).floorToDouble() is double);
+  Expect.isTrue((-0.5).floorToDouble() is double);
+  Expect.isTrue((-0.9999999999999999).floorToDouble() is double);
+  Expect.isTrue((-1.0).floorToDouble() is double);
+  Expect.isTrue((-1.000000000000001).floorToDouble() is double);
+  Expect.isTrue((-4503599627370496.0).floorToDouble() is double);
+  Expect.isTrue((-4503599627370497.0).floorToDouble() is double);
+  Expect.isTrue((-4503599627370498.0).floorToDouble() is double);
+  Expect.isTrue((-4503599627370499.0).floorToDouble() is double);
+  Expect.isTrue((-9007199254740991.0).floorToDouble() is double);
+  Expect.isTrue((-9007199254740992.0).floorToDouble() is double);
+  Expect.isTrue((-double.MAX_FINITE).floorToDouble() is double);
+}
\ No newline at end of file
diff --git a/tests/corelib/double_round2_test.dart b/tests/corelib/double_round2_test.dart
new file mode 100644
index 0000000..09978ab
--- /dev/null
+++ b/tests/corelib/double_round2_test.dart
@@ -0,0 +1,10 @@
+// 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.
+
+main() {
+  Expect.throws(() => double.INFINITY.round(), (e) => e is UnsupportedError);
+  Expect.throws(() => double.NEGATIVE_INFINITY.round(),
+                (e) => e is UnsupportedError);
+  Expect.throws(() => double.NAN.round(), (e) => e is UnsupportedError);
+}
diff --git a/tests/corelib/double_round3_test.dart b/tests/corelib/double_round3_test.dart
new file mode 100644
index 0000000..cd1b0a6
--- /dev/null
+++ b/tests/corelib/double_round3_test.dart
@@ -0,0 +1,10 @@
+// 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.
+
+main() {
+  Expect.equals(0, 0.49999999999999994.round());
+  Expect.equals(0, (-0.49999999999999994).round());
+  Expect.isTrue(0.49999999999999994.round() is int);
+  Expect.isTrue((-0.49999999999999994).round() is int);
+}
\ No newline at end of file
diff --git a/tests/corelib/double_round4_test.dart b/tests/corelib/double_round4_test.dart
new file mode 100644
index 0000000..ab546ae
--- /dev/null
+++ b/tests/corelib/double_round4_test.dart
@@ -0,0 +1,36 @@
+// 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.
+
+main() {
+  // The following numbers are on the border of 52 bits.
+  // For example: 4503599627370499 + 0.5 => 4503599627370500.
+  Expect.equals(4503599627370496, 4503599627370496.0.round());
+  Expect.equals(4503599627370497, 4503599627370497.0.round());
+  Expect.equals(4503599627370498, 4503599627370498.0.round());
+  Expect.equals(4503599627370499, 4503599627370499.0.round());
+
+  Expect.equals(9007199254740991, 9007199254740991.0.round());
+  Expect.equals(9007199254740992, 9007199254740992.0.round());
+
+  Expect.equals(-4503599627370496, (-4503599627370496.0).round());
+  Expect.equals(-4503599627370497, (-4503599627370497.0).round());
+  Expect.equals(-4503599627370498, (-4503599627370498.0).round());
+  Expect.equals(-4503599627370499, (-4503599627370499.0).round());
+
+  Expect.equals(-9007199254740991, (-9007199254740991.0).round());
+  Expect.equals(-9007199254740992, (-9007199254740992.0).round());
+
+  Expect.isTrue(4503599627370496.0.round() is int);
+  Expect.isTrue(4503599627370497.0.round() is int);
+  Expect.isTrue(4503599627370498.0.round() is int);
+  Expect.isTrue(4503599627370499.0.round() is int);
+  Expect.isTrue(9007199254740991.0.round() is int);
+  Expect.isTrue(9007199254740992.0.round() is int);
+  Expect.isTrue((-4503599627370496.0).round() is int);
+  Expect.isTrue((-4503599627370497.0).round() is int);
+  Expect.isTrue((-4503599627370498.0).round() is int);
+  Expect.isTrue((-4503599627370499.0).round() is int);
+  Expect.isTrue((-9007199254740991.0).round() is int);
+  Expect.isTrue((-9007199254740992.0).round() is int);
+}
\ No newline at end of file
diff --git a/tests/corelib/double_round_test.dart b/tests/corelib/double_round_test.dart
new file mode 100644
index 0000000..b63887c
--- /dev/null
+++ b/tests/corelib/double_round_test.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.
+
+main() {
+  Expect.equals(0, 0.0.round());
+  Expect.equals(0, double.MIN_POSITIVE.round());
+  Expect.equals(0, (2.0 * double.MIN_POSITIVE).round());
+  Expect.equals(0, (1.18e-38).round());
+  Expect.equals(0, (1.18e-38 * 2).round());
+  Expect.equals(1, 0.5.round());
+  Expect.equals(1, 0.9999999999999999.round());
+  Expect.equals(1, 1.0.round());
+  Expect.equals(1, 1.000000000000001.round());
+
+  Expect.equals(179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368,
+                double.MAX_FINITE.round());
+
+  Expect.equals(0, (-double.MIN_POSITIVE).round());
+  Expect.equals(0, (2.0 * -double.MIN_POSITIVE).round());
+  Expect.equals(0, (-1.18e-38).round());
+  Expect.equals(0, (-1.18e-38 * 2).round());
+  Expect.equals(-1, (-0.5).round());
+  Expect.equals(-1, (-0.9999999999999999).round());
+  Expect.equals(-1, (-1.0).round());
+  Expect.equals(-1, (-1.000000000000001).round());
+  Expect.equals(-179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368,
+                (-double.MAX_FINITE).round());
+
+  Expect.isTrue(0.0.round() is int);
+  Expect.isTrue(double.MIN_POSITIVE.round() is int);
+  Expect.isTrue((2.0 * double.MIN_POSITIVE).round() is int);
+  Expect.isTrue((1.18e-38).round() is int);
+  Expect.isTrue((1.18e-38 * 2).round() is int);
+  Expect.isTrue(0.5.round() is int);
+  Expect.isTrue(0.9999999999999999.round() is int);
+  Expect.isTrue(1.0.round() is int);
+  Expect.isTrue(1.000000000000001.round() is int);
+  Expect.isTrue(double.MAX_FINITE.round() is int);
+
+  Expect.isTrue((-double.MIN_POSITIVE).round() is int);
+  Expect.isTrue((2.0 * -double.MIN_POSITIVE).round() is int);
+  Expect.isTrue((-1.18e-38).round() is int);
+  Expect.isTrue((-1.18e-38 * 2).round() is int);
+  Expect.isTrue((-0.5).round() is int);
+  Expect.isTrue((-0.9999999999999999).round() is int);
+  Expect.isTrue((-1.0).round() is int);
+  Expect.isTrue((-1.000000000000001).round() is int);
+  Expect.isTrue((-double.MAX_FINITE).round() is int);
+}
\ No newline at end of file
diff --git a/tests/corelib/double_round_to_double2_test.dart b/tests/corelib/double_round_to_double2_test.dart
new file mode 100644
index 0000000..9d5d11e
--- /dev/null
+++ b/tests/corelib/double_round_to_double2_test.dart
@@ -0,0 +1,11 @@
+// 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.
+
+main() {
+  Expect.equals(0.0, 0.49999999999999994.roundToDouble());
+  Expect.equals(0.0, (-0.49999999999999994).roundToDouble());
+  Expect.isTrue(0.49999999999999994.roundToDouble() is double);
+  Expect.isTrue((-0.49999999999999994).roundToDouble().isNegative);
+  Expect.isTrue((-0.49999999999999994).roundToDouble() is double);
+}
\ No newline at end of file
diff --git a/tests/corelib/double_round_to_double3_test.dart b/tests/corelib/double_round_to_double3_test.dart
new file mode 100644
index 0000000..6183ed0
--- /dev/null
+++ b/tests/corelib/double_round_to_double3_test.dart
@@ -0,0 +1,32 @@
+// 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.
+
+main() {
+  // The following numbers are on the border of 52 bits.
+  // For example: 4503599627370499 + 0.5 => 4503599627370500.
+  Expect.equals(4503599627370496.0, 4503599627370496.0.roundToDouble());
+  Expect.equals(4503599627370497.0, 4503599627370497.0.roundToDouble());
+  Expect.equals(4503599627370498.0, 4503599627370498.0.roundToDouble());
+  Expect.equals(4503599627370499.0, 4503599627370499.0.roundToDouble());
+  Expect.equals(9007199254740991.0, 9007199254740991.0.roundToDouble());
+  Expect.equals(9007199254740992.0, 9007199254740992.0.roundToDouble());
+  Expect.equals(-4503599627370496.0, (-4503599627370496.0).roundToDouble());
+  Expect.equals(-4503599627370497.0, (-4503599627370497.0).roundToDouble());
+  Expect.equals(-4503599627370498.0, (-4503599627370498.0).roundToDouble());
+  Expect.equals(-4503599627370499.0, (-4503599627370499.0).roundToDouble());
+  Expect.equals(-9007199254740991.0, (-9007199254740991.0).roundToDouble());
+  Expect.equals(-9007199254740992.0, (-9007199254740992.0).roundToDouble());
+  Expect.isTrue(4503599627370496.0.roundToDouble() is double);
+  Expect.isTrue(4503599627370497.0.roundToDouble() is double);
+  Expect.isTrue(4503599627370498.0.roundToDouble() is double);
+  Expect.isTrue(4503599627370499.0.roundToDouble() is double);
+  Expect.isTrue(9007199254740991.0.roundToDouble() is double);
+  Expect.isTrue(9007199254740992.0.roundToDouble() is double);
+  Expect.isTrue((-4503599627370496.0).roundToDouble() is double);
+  Expect.isTrue((-4503599627370497.0).roundToDouble() is double);
+  Expect.isTrue((-4503599627370498.0).roundToDouble() is double);
+  Expect.isTrue((-4503599627370499.0).roundToDouble() is double);
+  Expect.isTrue((-9007199254740991.0).roundToDouble() is double);
+  Expect.isTrue((-9007199254740992.0).roundToDouble() is double);
+}
\ No newline at end of file
diff --git a/tests/corelib/double_round_to_double_test.dart b/tests/corelib/double_round_to_double_test.dart
new file mode 100644
index 0000000..a678248
--- /dev/null
+++ b/tests/corelib/double_round_to_double_test.dart
@@ -0,0 +1,60 @@
+// 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.
+
+main() {
+  Expect.equals(0.0, 0.0.roundToDouble());
+  Expect.equals(0.0, double.MIN_POSITIVE.roundToDouble());
+  Expect.equals(0.0, (2.0 * double.MIN_POSITIVE).roundToDouble());
+  Expect.equals(0.0, (1.18e-38).roundToDouble());
+  Expect.equals(0.0, (1.18e-38 * 2).roundToDouble());
+  Expect.equals(1.0, 0.5.roundToDouble());
+  Expect.equals(1.0, 0.9999999999999999.roundToDouble());
+  Expect.equals(1.0, 1.0.roundToDouble());
+  Expect.equals(1.0, 1.000000000000001.roundToDouble());
+  Expect.equals(2.0, 1.5.roundToDouble());
+
+  Expect.equals(double.MAX_FINITE, double.MAX_FINITE.roundToDouble());
+
+  Expect.equals(0.0, (-double.MIN_POSITIVE).roundToDouble());
+  Expect.equals(0.0, (2.0 * -double.MIN_POSITIVE).roundToDouble());
+  Expect.equals(0.0, (-1.18e-38).roundToDouble());
+  Expect.equals(0.0, (-1.18e-38 * 2).roundToDouble());
+  Expect.equals(-1.0, (-0.5).roundToDouble());
+  Expect.equals(-1.0, (-0.9999999999999999).roundToDouble());
+  Expect.equals(-1.0, (-1.0).roundToDouble());
+  Expect.equals(-1.0, (-1.000000000000001).roundToDouble());
+  Expect.equals(-2.0, (-1.5).roundToDouble());
+  Expect.equals(-double.MAX_FINITE, (-double.MAX_FINITE).roundToDouble());
+
+  Expect.equals(double.INFINITY, double.INFINITY.roundToDouble());
+  Expect.equals(double.NEGATIVE_INFINITY,
+                double.NEGATIVE_INFINITY.roundToDouble());
+  Expect.isTrue(double.NAN.roundToDouble().isNaN);
+
+  Expect.isTrue(0.0.roundToDouble() is double);
+  Expect.isTrue(double.MIN_POSITIVE.roundToDouble() is double);
+  Expect.isTrue((2.0 * double.MIN_POSITIVE).roundToDouble() is double);
+  Expect.isTrue((1.18e-38).roundToDouble() is double);
+  Expect.isTrue((1.18e-38 * 2).roundToDouble() is double);
+  Expect.isTrue(0.5.roundToDouble() is double);
+  Expect.isTrue(0.9999999999999999.roundToDouble() is double);
+  Expect.isTrue(1.0.roundToDouble() is double);
+  Expect.isTrue(1.000000000000001.roundToDouble() is double);
+  Expect.isTrue(double.MAX_FINITE.roundToDouble() is double);
+
+  Expect.isTrue((-double.MIN_POSITIVE).roundToDouble().isNegative);
+  Expect.isTrue((2.0 * -double.MIN_POSITIVE).roundToDouble().isNegative);
+  Expect.isTrue((-1.18e-38).roundToDouble().isNegative);
+  Expect.isTrue((-1.18e-38 * 2).roundToDouble().isNegative);
+
+  Expect.isTrue((-double.MIN_POSITIVE).roundToDouble() is double);
+  Expect.isTrue((2.0 * -double.MIN_POSITIVE).roundToDouble() is double);
+  Expect.isTrue((-1.18e-38).roundToDouble() is double);
+  Expect.isTrue((-1.18e-38 * 2).roundToDouble() is double);
+  Expect.isTrue((-0.5).roundToDouble() is double);
+  Expect.isTrue((-0.9999999999999999).roundToDouble() is double);
+  Expect.isTrue((-1.0).roundToDouble() is double);
+  Expect.isTrue((-1.000000000000001).roundToDouble() is double);
+  Expect.isTrue((-double.MAX_FINITE).roundToDouble() is double);
+}
\ No newline at end of file
diff --git a/tests/corelib/double_truncate2_test.dart b/tests/corelib/double_truncate2_test.dart
new file mode 100644
index 0000000..08355b4
--- /dev/null
+++ b/tests/corelib/double_truncate2_test.dart
@@ -0,0 +1,10 @@
+// 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.
+
+main() {
+  Expect.throws(() => double.INFINITY.truncate(), (e) => e is UnsupportedError);
+  Expect.throws(() => double.NEGATIVE_INFINITY.truncate(),
+                (e) => e is UnsupportedError);
+  Expect.throws(() => double.NAN.truncate(), (e) => e is UnsupportedError);
+}
diff --git a/tests/corelib/double_truncate_test.dart b/tests/corelib/double_truncate_test.dart
new file mode 100644
index 0000000..8a27ff5
--- /dev/null
+++ b/tests/corelib/double_truncate_test.dart
@@ -0,0 +1,88 @@
+// 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.
+
+main() {
+  Expect.equals(0, 0.0.truncate());
+  Expect.equals(0, double.MIN_POSITIVE.truncate());
+  Expect.equals(0, (2.0 * double.MIN_POSITIVE).truncate());
+  Expect.equals(0, (1.18e-38).truncate());
+  Expect.equals(0, (1.18e-38 * 2).truncate());
+  Expect.equals(0, 0.49999999999999994.truncate());
+  Expect.equals(0, 0.5.truncate());
+  Expect.equals(0, 0.9999999999999999.truncate());
+  Expect.equals(1, 1.0.truncate());
+  Expect.equals(1, 1.000000000000001.truncate());
+  // The following numbers are on the border of 52 bits.
+  // For example: 4503599627370499 + 0.5 => 4503599627370500.
+  Expect.equals(4503599627370496, 4503599627370496.0.truncate());
+  Expect.equals(4503599627370497, 4503599627370497.0.truncate());
+  Expect.equals(4503599627370498, 4503599627370498.0.truncate());
+  Expect.equals(4503599627370499, 4503599627370499.0.truncate());
+
+  Expect.equals(9007199254740991, 9007199254740991.0.truncate());
+  Expect.equals(9007199254740992, 9007199254740992.0.truncate());
+  Expect.equals(179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368,
+                double.MAX_FINITE.truncate());
+
+  Expect.equals(0, (-double.MIN_POSITIVE).truncate());
+  Expect.equals(0, (2.0 * -double.MIN_POSITIVE).truncate());
+  Expect.equals(0, (-1.18e-38).truncate());
+  Expect.equals(0, (-1.18e-38 * 2).truncate());
+  Expect.equals(0, (-0.49999999999999994).truncate());
+  Expect.equals(0, (-0.5).truncate());
+  Expect.equals(0, (-0.9999999999999999).truncate());
+  Expect.equals(-1, (-1.0).truncate());
+  Expect.equals(-1, (-1.000000000000001).truncate());
+  Expect.equals(-4503599627370496, (-4503599627370496.0).truncate());
+  Expect.equals(-4503599627370497, (-4503599627370497.0).truncate());
+  Expect.equals(-4503599627370498, (-4503599627370498.0).truncate());
+  Expect.equals(-4503599627370499, (-4503599627370499.0).truncate());
+  Expect.equals(-9007199254740991, (-9007199254740991.0).truncate());
+  Expect.equals(-9007199254740992, (-9007199254740992.0).truncate());
+  Expect.equals(-179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368,
+                (-double.MAX_FINITE).truncate());
+
+  Expect.isTrue(0.0.truncate() is int);
+  Expect.isTrue(double.MIN_POSITIVE.truncate() is int);
+  Expect.isTrue((2.0 * double.MIN_POSITIVE).truncate() is int);
+  Expect.isTrue((1.18e-38).truncate() is int);
+  Expect.isTrue((1.18e-38 * 2).truncate() is int);
+  Expect.isTrue(0.49999999999999994.truncate() is int);
+  Expect.isTrue(0.5.truncate() is int);
+  Expect.isTrue(0.9999999999999999.truncate() is int);
+  Expect.isTrue(1.0.truncate() is int);
+  Expect.isTrue(1.000000000000001.truncate() is int);
+  Expect.isTrue(4503599627370496.0.truncate() is int);
+  Expect.isTrue(4503599627370497.0.truncate() is int);
+  Expect.isTrue(4503599627370498.0.truncate() is int);
+  Expect.isTrue(4503599627370499.0.truncate() is int);
+  Expect.isTrue(9007199254740991.0.truncate() is int);
+  Expect.isTrue(9007199254740992.0.truncate() is int);
+  Expect.isTrue(double.MAX_FINITE.truncate() is int);
+
+  Expect.isTrue((-double.MIN_POSITIVE).truncateToDouble().isNegative);
+  Expect.isTrue((2.0 * -double.MIN_POSITIVE).truncateToDouble().isNegative);
+  Expect.isTrue((-1.18e-38).truncateToDouble().isNegative);
+  Expect.isTrue((-1.18e-38 * 2).truncateToDouble().isNegative);
+  Expect.isTrue((-0.49999999999999994).truncateToDouble().isNegative);
+  Expect.isTrue((-0.5).truncateToDouble().isNegative);
+  Expect.isTrue((-0.9999999999999999).truncateToDouble().isNegative);
+
+  Expect.isTrue((-double.MIN_POSITIVE).truncate() is int);
+  Expect.isTrue((2.0 * -double.MIN_POSITIVE).truncate() is int);
+  Expect.isTrue((-1.18e-38).truncate() is int);
+  Expect.isTrue((-1.18e-38 * 2).truncate() is int);
+  Expect.isTrue((-0.49999999999999994).truncate() is int);
+  Expect.isTrue((-0.5).truncate() is int);
+  Expect.isTrue((-0.9999999999999999).truncate() is int);
+  Expect.isTrue((-1.0).truncate() is int);
+  Expect.isTrue((-1.000000000000001).truncate() is int);
+  Expect.isTrue((-4503599627370496.0).truncate() is int);
+  Expect.isTrue((-4503599627370497.0).truncate() is int);
+  Expect.isTrue((-4503599627370498.0).truncate() is int);
+  Expect.isTrue((-4503599627370499.0).truncate() is int);
+  Expect.isTrue((-9007199254740991.0).truncate() is int);
+  Expect.isTrue((-9007199254740992.0).truncate() is int);
+  Expect.isTrue((-double.MAX_FINITE).truncate() is int);
+}
\ No newline at end of file
diff --git a/tests/corelib/double_truncate_to_double_test.dart b/tests/corelib/double_truncate_to_double_test.dart
new file mode 100644
index 0000000..5689aba
--- /dev/null
+++ b/tests/corelib/double_truncate_to_double_test.dart
@@ -0,0 +1,83 @@
+// 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.
+
+main() {
+  Expect.equals(0.0, 0.0.truncateToDouble());
+  Expect.equals(0.0, double.MIN_POSITIVE.truncateToDouble());
+  Expect.equals(0.0, (2.0 * double.MIN_POSITIVE).truncateToDouble());
+  Expect.equals(0.0, (1.18e-38).truncateToDouble());
+  Expect.equals(0.0, (1.18e-38 * 2).truncateToDouble());
+  Expect.equals(0.0, 0.49999999999999994.truncateToDouble());
+  Expect.equals(0.0, 0.5.truncateToDouble());
+  Expect.equals(0.0, 0.9999999999999999.truncateToDouble());
+  Expect.equals(1.0, 1.0.truncateToDouble());
+  Expect.equals(1.0, 1.000000000000001.truncateToDouble());
+  // The following numbers are on the border of 52 bits.
+  // For example: 4503599627370499 + 0.5 => 4503599627370500.
+  Expect.equals(4503599627370496.0, 4503599627370496.0.truncateToDouble());
+  Expect.equals(4503599627370497.0, 4503599627370497.0.truncateToDouble());
+  Expect.equals(4503599627370498.0, 4503599627370498.0.truncateToDouble());
+  Expect.equals(4503599627370499.0, 4503599627370499.0.truncateToDouble());
+
+  Expect.equals(9007199254740991.0, 9007199254740991.0.truncateToDouble());
+  Expect.equals(9007199254740992.0, 9007199254740992.0.truncateToDouble());
+  Expect.equals(double.MAX_FINITE, double.MAX_FINITE.truncateToDouble());
+
+  Expect.equals(0.0, (-double.MIN_POSITIVE).truncateToDouble());
+  Expect.equals(0.0, (2.0 * -double.MIN_POSITIVE).truncateToDouble());
+  Expect.equals(0.0, (-1.18e-38).truncateToDouble());
+  Expect.equals(0.0, (-1.18e-38 * 2).truncateToDouble());
+  Expect.equals(0.0, (-0.49999999999999994).truncateToDouble());
+  Expect.equals(0.0, (-0.5).truncateToDouble());
+  Expect.equals(0.0, (-0.9999999999999999).truncateToDouble());
+  Expect.equals(-1.0, (-1.0).truncateToDouble());
+  Expect.equals(-1.0, (-1.000000000000001).truncateToDouble());
+  Expect.equals(-4503599627370496.0, (-4503599627370496.0).truncateToDouble());
+  Expect.equals(-4503599627370497.0, (-4503599627370497.0).truncateToDouble());
+  Expect.equals(-4503599627370498.0, (-4503599627370498.0).truncateToDouble());
+  Expect.equals(-4503599627370499.0, (-4503599627370499.0).truncateToDouble());
+  Expect.equals(-9007199254740991.0, (-9007199254740991.0).truncateToDouble());
+  Expect.equals(-9007199254740992.0, (-9007199254740992.0).truncateToDouble());
+  Expect.equals(-double.MAX_FINITE, (-double.MAX_FINITE).truncateToDouble());
+
+  Expect.equals(double.INFINITY, double.INFINITY.truncateToDouble());
+  Expect.equals(double.NEGATIVE_INFINITY,
+                double.NEGATIVE_INFINITY.truncateToDouble());
+  Expect.isTrue(double.NAN.truncateToDouble().isNaN);
+
+  Expect.isTrue(0.0.truncateToDouble() is double);
+  Expect.isTrue(double.MIN_POSITIVE.truncateToDouble() is double);
+  Expect.isTrue((2.0 * double.MIN_POSITIVE).truncateToDouble() is double);
+  Expect.isTrue((1.18e-38).truncateToDouble() is double);
+  Expect.isTrue((1.18e-38 * 2).truncateToDouble() is double);
+  Expect.isTrue(0.49999999999999994.truncateToDouble() is double);
+  Expect.isTrue(0.5.truncateToDouble() is double);
+  Expect.isTrue(0.9999999999999999.truncateToDouble() is double);
+  Expect.isTrue(1.0.truncateToDouble() is double);
+  Expect.isTrue(1.000000000000001.truncateToDouble() is double);
+  Expect.isTrue(4503599627370496.0.truncateToDouble() is double);
+  Expect.isTrue(4503599627370497.0.truncateToDouble() is double);
+  Expect.isTrue(4503599627370498.0.truncateToDouble() is double);
+  Expect.isTrue(4503599627370499.0.truncateToDouble() is double);
+  Expect.isTrue(9007199254740991.0.truncateToDouble() is double);
+  Expect.isTrue(9007199254740992.0.truncateToDouble() is double);
+  Expect.isTrue(double.MAX_FINITE.truncateToDouble() is double);
+
+  Expect.isTrue((-double.MIN_POSITIVE).truncateToDouble() is double);
+  Expect.isTrue((2.0 * -double.MIN_POSITIVE).truncateToDouble() is double);
+  Expect.isTrue((-1.18e-38).truncateToDouble() is double);
+  Expect.isTrue((-1.18e-38 * 2).truncateToDouble() is double);
+  Expect.isTrue((-0.49999999999999994).truncateToDouble() is double);
+  Expect.isTrue((-0.5).truncateToDouble() is double);
+  Expect.isTrue((-0.9999999999999999).truncateToDouble() is double);
+  Expect.isTrue((-1.0).truncateToDouble() is double);
+  Expect.isTrue((-1.000000000000001).truncateToDouble() is double);
+  Expect.isTrue((-4503599627370496.0).truncateToDouble() is double);
+  Expect.isTrue((-4503599627370497.0).truncateToDouble() is double);
+  Expect.isTrue((-4503599627370498.0).truncateToDouble() is double);
+  Expect.isTrue((-4503599627370499.0).truncateToDouble() is double);
+  Expect.isTrue((-9007199254740991.0).truncateToDouble() is double);
+  Expect.isTrue((-9007199254740992.0).truncateToDouble() is double);
+  Expect.isTrue((-double.MAX_FINITE).truncateToDouble() is double);
+}
\ No newline at end of file
diff --git a/tests/corelib/int_ceil_test.dart b/tests/corelib/int_ceil_test.dart
new file mode 100644
index 0000000..ab10766
--- /dev/null
+++ b/tests/corelib/int_ceil_test.dart
@@ -0,0 +1,37 @@
+// 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.
+
+main() {
+  Expect.equals(0, 0.ceil());
+  Expect.equals(1, 1.ceil());
+  Expect.equals(0x1234, 0x1234.ceil());
+  Expect.equals(0x12345678, 0x12345678.ceil());
+  Expect.equals(0x123456789AB, 0x123456789AB.ceil());
+  Expect.equals(0x123456789ABCDEF, 0x123456789ABCDEF.ceil());
+  Expect.equals(0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF,
+                0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.ceil());
+  Expect.equals(-1, -1.ceil());
+  Expect.equals(-0x1234, -0x1234.ceil());
+  Expect.equals(-0x12345678, -0x12345678.ceil());
+  Expect.equals(-0x123456789AB, -0x123456789AB.ceil());
+  Expect.equals(-0x123456789ABCDEF, -0x123456789ABCDEF.ceil());
+  Expect.equals(-0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF,
+                -0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.ceil());
+
+  Expect.isTrue(0.ceil() is int);
+  Expect.isTrue(1.ceil() is int);
+  Expect.isTrue(0x1234.ceil() is int);
+  Expect.isTrue(0x12345678.ceil() is int);
+  Expect.isTrue(0x123456789AB.ceil() is int);
+  Expect.isTrue(0x123456789ABCDEF.ceil() is int);
+  Expect.isTrue(
+     0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.ceil() is int);
+  Expect.isTrue(-1.ceil() is int);
+  Expect.isTrue(-0x1234.ceil() is int);
+  Expect.isTrue(-0x12345678.ceil() is int);
+  Expect.isTrue(-0x123456789AB.ceil() is int);
+  Expect.isTrue(-0x123456789ABCDEF.ceil() is int);
+  Expect.isTrue(
+     -0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.ceil() is int);
+}
\ No newline at end of file
diff --git a/tests/corelib/int_ceil_to_double_test.dart b/tests/corelib/int_ceil_to_double_test.dart
new file mode 100644
index 0000000..0c0e097
--- /dev/null
+++ b/tests/corelib/int_ceil_to_double_test.dart
@@ -0,0 +1,41 @@
+// 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.
+
+main() {
+  Expect.equals(0.0, 0.ceilToDouble());
+  Expect.equals(1.0, 1.ceilToDouble());
+  Expect.equals(0x1234, 0x1234.ceilToDouble());
+  Expect.equals(0x12345678, 0x12345678.ceilToDouble());
+  Expect.equals(0x123456789AB, 0x123456789AB.ceilToDouble());
+  Expect.equals(81985529216486900.0, 0x123456789ABCDEF.ceilToDouble());
+  Expect.equals(
+      2.7898229935051914e+55,
+      0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.ceilToDouble());
+  Expect.equals(-1.0, -1.ceilToDouble());
+  Expect.equals(-0x1234, -0x1234.ceilToDouble());
+  Expect.equals(-0x12345678, -0x12345678.ceilToDouble());
+  Expect.equals(-0x123456789AB, -0x123456789AB.ceilToDouble());
+  Expect.equals(-81985529216486900.0, -0x123456789ABCDEF.ceilToDouble());
+  Expect.equals(
+      -2.7898229935051914e+55,
+      -0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.ceilToDouble());
+
+  Expect.isTrue(0.ceilToDouble() is double);
+  Expect.isTrue(1.ceilToDouble() is double);
+  Expect.isTrue(0x1234.ceilToDouble() is double);
+  Expect.isTrue(0x12345678.ceilToDouble() is double);
+  Expect.isTrue(0x123456789AB.ceilToDouble() is double);
+  Expect.isTrue(0x123456789ABCDEF.ceilToDouble() is double);
+  Expect.isTrue(
+     0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.ceilToDouble()
+     is double);
+  Expect.isTrue(-1.ceilToDouble() is double);
+  Expect.isTrue(-0x1234.ceilToDouble() is double);
+  Expect.isTrue(-0x12345678.ceilToDouble() is double);
+  Expect.isTrue(-0x123456789AB.ceilToDouble() is double);
+  Expect.isTrue(-0x123456789ABCDEF.ceilToDouble() is double);
+  Expect.isTrue(
+     -0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.ceilToDouble()
+     is double);
+}
\ No newline at end of file
diff --git a/tests/corelib/int_floor_test.dart b/tests/corelib/int_floor_test.dart
new file mode 100644
index 0000000..2f6bc53
--- /dev/null
+++ b/tests/corelib/int_floor_test.dart
@@ -0,0 +1,37 @@
+// 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.
+
+main() {
+  Expect.equals(0, 0.floor());
+  Expect.equals(1, 1.floor());
+  Expect.equals(0x1234, 0x1234.floor());
+  Expect.equals(0x12345678, 0x12345678.floor());
+  Expect.equals(0x123456789AB, 0x123456789AB.floor());
+  Expect.equals(0x123456789ABCDEF, 0x123456789ABCDEF.floor());
+  Expect.equals(0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF,
+                0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.floor());
+  Expect.equals(-1, -1.floor());
+  Expect.equals(-0x1234, -0x1234.floor());
+  Expect.equals(-0x12345678, -0x12345678.floor());
+  Expect.equals(-0x123456789AB, -0x123456789AB.floor());
+  Expect.equals(-0x123456789ABCDEF, -0x123456789ABCDEF.floor());
+  Expect.equals(-0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF,
+                -0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.floor());
+
+  Expect.isTrue(0.floor() is int);
+  Expect.isTrue(1.floor() is int);
+  Expect.isTrue(0x1234.floor() is int);
+  Expect.isTrue(0x12345678.floor() is int);
+  Expect.isTrue(0x123456789AB.floor() is int);
+  Expect.isTrue(0x123456789ABCDEF.floor() is int);
+  Expect.isTrue(
+      0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.floor() is int);
+  Expect.isTrue(-1.floor() is int);
+  Expect.isTrue(-0x1234.floor() is int);
+  Expect.isTrue(-0x12345678.floor() is int);
+  Expect.isTrue(-0x123456789AB.floor() is int);
+  Expect.isTrue(-0x123456789ABCDEF.floor() is int);
+  Expect.isTrue(
+      -0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.floor() is int);
+}
\ No newline at end of file
diff --git a/tests/corelib/int_floor_to_double_test.dart b/tests/corelib/int_floor_to_double_test.dart
new file mode 100644
index 0000000..506092a
--- /dev/null
+++ b/tests/corelib/int_floor_to_double_test.dart
@@ -0,0 +1,41 @@
+// 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.
+
+main() {
+  Expect.equals(0.0, 0.floorToDouble());
+  Expect.equals(1.0, 1.floorToDouble());
+  Expect.equals(0x1234, 0x1234.floorToDouble());
+  Expect.equals(0x12345678, 0x12345678.floorToDouble());
+  Expect.equals(0x123456789AB, 0x123456789AB.floorToDouble());
+  Expect.equals(81985529216486900.0, 0x123456789ABCDEF.floorToDouble());
+  Expect.equals(
+      2.7898229935051914e+55,
+      0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.floorToDouble());
+  Expect.equals(-1.0, -1.floorToDouble());
+  Expect.equals(-0x1234, -0x1234.floorToDouble());
+  Expect.equals(-0x12345678, -0x12345678.floorToDouble());
+  Expect.equals(-0x123456789AB, -0x123456789AB.floorToDouble());
+  Expect.equals(-81985529216486900.0, -0x123456789ABCDEF.floorToDouble());
+  Expect.equals(
+      -2.7898229935051914e+55,
+      -0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.floorToDouble());
+
+  Expect.isTrue(0.floorToDouble() is double);
+  Expect.isTrue(1.floorToDouble() is double);
+  Expect.isTrue(0x1234.floorToDouble() is double);
+  Expect.isTrue(0x12345678.floorToDouble() is double);
+  Expect.isTrue(0x123456789AB.floorToDouble() is double);
+  Expect.isTrue(0x123456789ABCDEF.floorToDouble() is double);
+  Expect.isTrue(
+      0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.floorToDouble()
+      is double);
+  Expect.isTrue(-1.floorToDouble() is double);
+  Expect.isTrue(-0x1234.floorToDouble() is double);
+  Expect.isTrue(-0x12345678.floorToDouble() is double);
+  Expect.isTrue(-0x123456789AB.floorToDouble() is double);
+  Expect.isTrue(-0x123456789ABCDEF.floorToDouble() is double);
+  Expect.isTrue(
+      -0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.floorToDouble()
+      is double);
+}
\ No newline at end of file
diff --git a/tests/corelib/int_round_test.dart b/tests/corelib/int_round_test.dart
new file mode 100644
index 0000000..c2edc73
--- /dev/null
+++ b/tests/corelib/int_round_test.dart
@@ -0,0 +1,37 @@
+// 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.
+
+main() {
+  Expect.equals(0, 0.round());
+  Expect.equals(1, 1.round());
+  Expect.equals(0x1234, 0x1234.round());
+  Expect.equals(0x12345678, 0x12345678.round());
+  Expect.equals(0x123456789AB, 0x123456789AB.round());
+  Expect.equals(0x123456789ABCDEF, 0x123456789ABCDEF.round());
+  Expect.equals(0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF,
+                0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.round());
+  Expect.equals(-1, -1.round());
+  Expect.equals(-0x1234, -0x1234.round());
+  Expect.equals(-0x12345678, -0x12345678.round());
+  Expect.equals(-0x123456789AB, -0x123456789AB.round());
+  Expect.equals(-0x123456789ABCDEF, -0x123456789ABCDEF.round());
+  Expect.equals(-0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF,
+                -0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.round());
+
+  Expect.isTrue(0.round() is int);
+  Expect.isTrue(1.round() is int);
+  Expect.isTrue(0x1234.round() is int);
+  Expect.isTrue(0x12345678.round() is int);
+  Expect.isTrue(0x123456789AB.round() is int);
+  Expect.isTrue(0x123456789ABCDEF.round() is int);
+  Expect.isTrue(
+      0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.round() is int);
+  Expect.isTrue(-1.round() is int);
+  Expect.isTrue(-0x1234.round() is int);
+  Expect.isTrue(-0x12345678.round() is int);
+  Expect.isTrue(-0x123456789AB.round() is int);
+  Expect.isTrue(-0x123456789ABCDEF.round() is int);
+  Expect.isTrue(
+      -0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.round() is int);
+}
\ No newline at end of file
diff --git a/tests/corelib/int_round_to_double_test.dart b/tests/corelib/int_round_to_double_test.dart
new file mode 100644
index 0000000..39122a4
--- /dev/null
+++ b/tests/corelib/int_round_to_double_test.dart
@@ -0,0 +1,41 @@
+// 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.
+
+main() {
+  Expect.equals(0.0, 0.roundToDouble());
+  Expect.equals(1.0, 1.roundToDouble());
+  Expect.equals(0x1234, 0x1234.roundToDouble());
+  Expect.equals(0x12345678, 0x12345678.roundToDouble());
+  Expect.equals(0x123456789AB, 0x123456789AB.roundToDouble());
+  Expect.equals(81985529216486900.0, 0x123456789ABCDEF.roundToDouble());
+  Expect.equals(
+      2.7898229935051914e+55,
+      0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.roundToDouble());
+  Expect.equals(-1.0, -1.roundToDouble());
+  Expect.equals(-0x1234, -0x1234.roundToDouble());
+  Expect.equals(-0x12345678, -0x12345678.roundToDouble());
+  Expect.equals(-0x123456789AB, -0x123456789AB.roundToDouble());
+  Expect.equals(-81985529216486900.0, -0x123456789ABCDEF.roundToDouble());
+  Expect.equals(
+      -2.7898229935051914e+55,
+      -0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.roundToDouble());
+
+  Expect.isTrue(0.roundToDouble() is double);
+  Expect.isTrue(1.roundToDouble() is double);
+  Expect.isTrue(0x1234.roundToDouble() is double);
+  Expect.isTrue(0x12345678.roundToDouble() is double);
+  Expect.isTrue(0x123456789AB.roundToDouble() is double);
+  Expect.isTrue(0x123456789ABCDEF.roundToDouble() is double);
+  Expect.isTrue(
+      0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.roundToDouble()
+      is double);
+  Expect.isTrue(-1.roundToDouble() is double);
+  Expect.isTrue(-0x1234.roundToDouble() is double);
+  Expect.isTrue(-0x12345678.roundToDouble() is double);
+  Expect.isTrue(-0x123456789AB.roundToDouble() is double);
+  Expect.isTrue(-0x123456789ABCDEF.roundToDouble() is double);
+  Expect.isTrue(
+      -0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.roundToDouble()
+      is double);
+}
\ No newline at end of file
diff --git a/tests/corelib/int_to_int_test.dart b/tests/corelib/int_to_int_test.dart
new file mode 100644
index 0000000..7a16e4a
--- /dev/null
+++ b/tests/corelib/int_to_int_test.dart
@@ -0,0 +1,37 @@
+// 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.
+
+main() {
+  Expect.equals(0, 0.toInt());
+  Expect.equals(1, 1.toInt());
+  Expect.equals(0x1234, 0x1234.toInt());
+  Expect.equals(0x12345678, 0x12345678.toInt());
+  Expect.equals(0x123456789AB, 0x123456789AB.toInt());
+  Expect.equals(0x123456789ABCDEF, 0x123456789ABCDEF.toInt());
+  Expect.equals(0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF,
+                0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.toInt());
+  Expect.equals(-1, -1.toInt());
+  Expect.equals(-0x1234, -0x1234.toInt());
+  Expect.equals(-0x12345678, -0x12345678.toInt());
+  Expect.equals(-0x123456789AB, -0x123456789AB.toInt());
+  Expect.equals(-0x123456789ABCDEF, -0x123456789ABCDEF.toInt());
+  Expect.equals(-0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF,
+                -0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.toInt());
+
+  Expect.isTrue(0.toInt() is int);
+  Expect.isTrue(1.toInt() is int);
+  Expect.isTrue(0x1234.toInt() is int);
+  Expect.isTrue(0x12345678.toInt() is int);
+  Expect.isTrue(0x123456789AB.toInt() is int);
+  Expect.isTrue(0x123456789ABCDEF.toInt() is int);
+  Expect.isTrue(
+      0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.toInt() is int);
+  Expect.isTrue(-1.toInt() is int);
+  Expect.isTrue(-0x1234.toInt() is int);
+  Expect.isTrue(-0x12345678.toInt() is int);
+  Expect.isTrue(-0x123456789AB.toInt() is int);
+  Expect.isTrue(-0x123456789ABCDEF.toInt() is int);
+  Expect.isTrue(
+      -0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.toInt() is int);
+}
\ No newline at end of file
diff --git a/tests/corelib/int_truncate_test.dart b/tests/corelib/int_truncate_test.dart
new file mode 100644
index 0000000..67bdef6
--- /dev/null
+++ b/tests/corelib/int_truncate_test.dart
@@ -0,0 +1,37 @@
+// 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.
+
+main() {
+  Expect.equals(0, 0.truncate());
+  Expect.equals(1, 1.truncate());
+  Expect.equals(0x1234, 0x1234.truncate());
+  Expect.equals(0x12345678, 0x12345678.truncate());
+  Expect.equals(0x123456789AB, 0x123456789AB.truncate());
+  Expect.equals(0x123456789ABCDEF, 0x123456789ABCDEF.truncate());
+  Expect.equals(0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF,
+                0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.truncate());
+  Expect.equals(-1, -1.truncate());
+  Expect.equals(-0x1234, -0x1234.truncate());
+  Expect.equals(-0x12345678, -0x12345678.truncate());
+  Expect.equals(-0x123456789AB, -0x123456789AB.truncate());
+  Expect.equals(-0x123456789ABCDEF, -0x123456789ABCDEF.truncate());
+  Expect.equals(-0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF,
+                -0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.truncate());
+
+  Expect.isTrue(0.truncate() is int);
+  Expect.isTrue(1.truncate() is int);
+  Expect.isTrue(0x1234.truncate() is int);
+  Expect.isTrue(0x12345678.truncate() is int);
+  Expect.isTrue(0x123456789AB.truncate() is int);
+  Expect.isTrue(0x123456789ABCDEF.truncate() is int);
+  Expect.isTrue(
+      0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.truncate() is int);
+  Expect.isTrue(-1.truncate() is int);
+  Expect.isTrue(-0x1234.truncate() is int);
+  Expect.isTrue(-0x12345678.truncate() is int);
+  Expect.isTrue(-0x123456789AB.truncate() is int);
+  Expect.isTrue(-0x123456789ABCDEF.truncate() is int);
+  Expect.isTrue(
+      -0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.truncate() is int);
+}
\ No newline at end of file
diff --git a/tests/corelib/int_truncate_to_double_test.dart b/tests/corelib/int_truncate_to_double_test.dart
new file mode 100644
index 0000000..628fa8a
--- /dev/null
+++ b/tests/corelib/int_truncate_to_double_test.dart
@@ -0,0 +1,41 @@
+// 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.
+
+main() {
+  Expect.equals(0.0, 0.truncateToDouble());
+  Expect.equals(1.0, 1.truncateToDouble());
+  Expect.equals(0x1234, 0x1234.truncateToDouble());
+  Expect.equals(0x12345678, 0x12345678.truncateToDouble());
+  Expect.equals(0x123456789AB, 0x123456789AB.truncateToDouble());
+  Expect.equals(81985529216486900.0, 0x123456789ABCDEF.truncateToDouble());
+  Expect.equals(
+      2.7898229935051914e+55,
+      0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.truncateToDouble());
+  Expect.equals(-1.0, -1.truncateToDouble());
+  Expect.equals(-0x1234, -0x1234.truncateToDouble());
+  Expect.equals(-0x12345678, -0x12345678.truncateToDouble());
+  Expect.equals(-0x123456789AB, -0x123456789AB.truncateToDouble());
+  Expect.equals(-81985529216486900.0, -0x123456789ABCDEF.truncateToDouble());
+  Expect.equals(
+      -2.7898229935051914e+55,
+      -0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.truncateToDouble());
+
+  Expect.isTrue(0.truncateToDouble() is double);
+  Expect.isTrue(1.truncateToDouble() is double);
+  Expect.isTrue(0x1234.truncateToDouble() is double);
+  Expect.isTrue(0x12345678.truncateToDouble() is double);
+  Expect.isTrue(0x123456789AB.truncateToDouble() is double);
+  Expect.isTrue(0x123456789ABCDEF.truncateToDouble() is double);
+  Expect.isTrue(
+      0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.truncateToDouble()
+      is double);
+  Expect.isTrue(-1.truncateToDouble() is double);
+  Expect.isTrue(-0x1234.truncateToDouble() is double);
+  Expect.isTrue(-0x12345678.truncateToDouble() is double);
+  Expect.isTrue(-0x123456789AB.truncateToDouble() is double);
+  Expect.isTrue(-0x123456789ABCDEF.truncateToDouble() is double);
+  Expect.isTrue(
+      -0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF.truncateToDouble()
+      is double);
+}
\ No newline at end of file
diff --git a/tests/corelib/iterable_first_matching_test.dart b/tests/corelib/iterable_first_matching_test.dart
deleted file mode 100644
index e542912..0000000
--- a/tests/corelib/iterable_first_matching_test.dart
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-main() {
-  List<int> list1 = <int>[1, 2, 3];
-  List<int> list2 = const <int>[4, 5];
-  List<String> list3 = <String>[];
-  Set<int> set1 = new Set<int>();
-  set1..add(11)
-      ..add(12)
-      ..add(13);
-  Set set2 = new Set();
-
-  Expect.equals(2, list1.firstMatching((x) => x.isEven));
-  Expect.equals(1, list1.firstMatching((x) => x.isOdd));
-  Expect.throws(() => list1.firstMatching((x) => x > 3),
-                (e) => e is StateError);
-  Expect.equals(null, list1.firstMatching((x) => x > 3, orElse: () => null));
-  Expect.equals(499, list1.firstMatching((x) => x > 3, orElse: () => 499));
-
-  Expect.equals(4, list2.firstMatching((x) => x.isEven));
-  Expect.equals(5, list2.firstMatching((x) => x.isOdd));
-  Expect.throws(() => list2.firstMatching((x) => x == 0),
-                (e) => e is StateError);
-  Expect.equals(null, list2.firstMatching((x) => false, orElse: () => null));
-  Expect.equals(499, list2.firstMatching((x) => false, orElse: () => 499));
-
-  Expect.throws(() => list3.firstMatching((x) => x == 0),
-                (e) => e is StateError);
-  Expect.throws(() => list3.firstMatching((x) => true), (e) => e is StateError);
-  Expect.equals(null, list3.firstMatching((x) => true, orElse: () => null));
-  Expect.equals("str", list3.firstMatching((x) => false, orElse: () => "str"));
-
-  Expect.equals(12, set1.firstMatching((x) => x.isEven));
-  var odd = set1.firstMatching((x) => x.isOdd);
-  Expect.isTrue(odd == 11 || odd == 13);
-  Expect.throws(() => set1.firstMatching((x) => false), (e) => e is StateError);
-  Expect.equals(null, set1.firstMatching((x) => false, orElse: () => null));
-  Expect.equals(499, set1.firstMatching((x) => false, orElse: () => 499));
-
-  Expect.throws(() => set2.firstMatching((x) => false), (e) => e is StateError);
-  Expect.throws(() => set2.firstMatching((x) => true), (e) => e is StateError);
-  Expect.equals(null, set2.firstMatching((x) => true, orElse: () => null));
-  Expect.equals(499, set2.firstMatching((x) => false, orElse: () => 499));
-}
diff --git a/tests/corelib/iterable_first_where_test.dart b/tests/corelib/iterable_first_where_test.dart
new file mode 100644
index 0000000..2b70053
--- /dev/null
+++ b/tests/corelib/iterable_first_where_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() {
+  List<int> list1 = <int>[1, 2, 3];
+  List<int> list2 = const <int>[4, 5];
+  List<String> list3 = <String>[];
+  Set<int> set1 = new Set<int>();
+  set1..add(11)
+      ..add(12)
+      ..add(13);
+  Set set2 = new Set();
+
+  Expect.equals(2, list1.firstWhere((x) => x.isEven));
+  Expect.equals(1, list1.firstWhere((x) => x.isOdd));
+  Expect.throws(() => list1.firstWhere((x) => x > 3),
+                (e) => e is StateError);
+  Expect.equals(null, list1.firstWhere((x) => x > 3, orElse: () => null));
+  Expect.equals(499, list1.firstWhere((x) => x > 3, orElse: () => 499));
+
+  Expect.equals(4, list2.firstWhere((x) => x.isEven));
+  Expect.equals(5, list2.firstWhere((x) => x.isOdd));
+  Expect.throws(() => list2.firstWhere((x) => x == 0),
+                (e) => e is StateError);
+  Expect.equals(null, list2.firstWhere((x) => false, orElse: () => null));
+  Expect.equals(499, list2.firstWhere((x) => false, orElse: () => 499));
+
+  Expect.throws(() => list3.firstWhere((x) => x == 0),
+                (e) => e is StateError);
+  Expect.throws(() => list3.firstWhere((x) => true), (e) => e is StateError);
+  Expect.equals(null, list3.firstWhere((x) => true, orElse: () => null));
+  Expect.equals("str", list3.firstWhere((x) => false, orElse: () => "str"));
+
+  Expect.equals(12, set1.firstWhere((x) => x.isEven));
+  var odd = set1.firstWhere((x) => x.isOdd);
+  Expect.isTrue(odd == 11 || odd == 13);
+  Expect.throws(() => set1.firstWhere((x) => false), (e) => e is StateError);
+  Expect.equals(null, set1.firstWhere((x) => false, orElse: () => null));
+  Expect.equals(499, set1.firstWhere((x) => false, orElse: () => 499));
+
+  Expect.throws(() => set2.firstWhere((x) => false), (e) => e is StateError);
+  Expect.throws(() => set2.firstWhere((x) => true), (e) => e is StateError);
+  Expect.equals(null, set2.firstWhere((x) => true, orElse: () => null));
+  Expect.equals(499, set2.firstWhere((x) => false, orElse: () => 499));
+}
diff --git a/tests/corelib/iterable_last_matching_test.dart b/tests/corelib/iterable_last_matching_test.dart
deleted file mode 100644
index bf6d20d..0000000
--- a/tests/corelib/iterable_last_matching_test.dart
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-main() {
-  List<int> list1 = <int>[1, 2, 3];
-  List<int> list2 = const <int>[4, 5, 6];
-  List<String> list3 = <String>[];
-  Set<int> set1 = new Set<int>();
-  set1..add(11)
-      ..add(12)
-      ..add(13);
-  Set set2 = new Set();
-
-  Expect.equals(2, list1.lastMatching((x) => x.isEven));
-  Expect.equals(3, list1.lastMatching((x) => x.isOdd));
-  Expect.throws(() => list1.lastMatching((x) => x > 3),
-                (e) => e is StateError);
-  Expect.equals(null, list1.lastMatching((x) => x > 3, orElse: () => null));
-  Expect.equals(499, list1.lastMatching((x) => x > 3, orElse: () => 499));
-
-  Expect.equals(6, list2.lastMatching((x) => x.isEven));
-  Expect.equals(5, list2.lastMatching((x) => x.isOdd));
-  Expect.throws(() => list2.lastMatching((x) => x == 0),
-                (e) => e is StateError);
-  Expect.equals(null, list2.lastMatching((x) => false, orElse: () => null));
-  Expect.equals(499, list2.lastMatching((x) => false, orElse: () => 499));
-
-  Expect.throws(() => list3.lastMatching((x) => x == 0),
-                (e) => e is StateError);
-  Expect.throws(() => list3.lastMatching((x) => true), (e) => e is StateError);
-  Expect.equals(null, list3.lastMatching((x) => true, orElse: () => null));
-  Expect.equals("str", list3.lastMatching((x) => false, orElse: () => "str"));
-
-  Expect.equals(12, set1.lastMatching((x) => x.isEven));
-  var odd = set1.lastMatching((x) => x.isOdd);
-  Expect.isTrue(odd == 11 || odd == 13);
-  Expect.throws(() => set1.lastMatching((x) => false), (e) => e is StateError);
-  Expect.equals(null, set1.lastMatching((x) => false, orElse: () => null));
-  Expect.equals(499, set1.lastMatching((x) => false, orElse: () => 499));
-
-  Expect.throws(() => set2.lastMatching((x) => false), (e) => e is StateError);
-  Expect.throws(() => set2.lastMatching((x) => true), (e) => e is StateError);
-  Expect.equals(null, set2.lastMatching((x) => true, orElse: () => null));
-  Expect.equals(499, set2.lastMatching((x) => false, orElse: () => 499));
-}
diff --git a/tests/corelib/iterable_last_where_test.dart b/tests/corelib/iterable_last_where_test.dart
new file mode 100644
index 0000000..5544cd3
--- /dev/null
+++ b/tests/corelib/iterable_last_where_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() {
+  List<int> list1 = <int>[1, 2, 3];
+  List<int> list2 = const <int>[4, 5, 6];
+  List<String> list3 = <String>[];
+  Set<int> set1 = new Set<int>();
+  set1..add(11)
+      ..add(12)
+      ..add(13);
+  Set set2 = new Set();
+
+  Expect.equals(2, list1.lastWhere((x) => x.isEven));
+  Expect.equals(3, list1.lastWhere((x) => x.isOdd));
+  Expect.throws(() => list1.lastWhere((x) => x > 3),
+                (e) => e is StateError);
+  Expect.equals(null, list1.lastWhere((x) => x > 3, orElse: () => null));
+  Expect.equals(499, list1.lastWhere((x) => x > 3, orElse: () => 499));
+
+  Expect.equals(6, list2.lastWhere((x) => x.isEven));
+  Expect.equals(5, list2.lastWhere((x) => x.isOdd));
+  Expect.throws(() => list2.lastWhere((x) => x == 0),
+                (e) => e is StateError);
+  Expect.equals(null, list2.lastWhere((x) => false, orElse: () => null));
+  Expect.equals(499, list2.lastWhere((x) => false, orElse: () => 499));
+
+  Expect.throws(() => list3.lastWhere((x) => x == 0),
+                (e) => e is StateError);
+  Expect.throws(() => list3.lastWhere((x) => true), (e) => e is StateError);
+  Expect.equals(null, list3.lastWhere((x) => true, orElse: () => null));
+  Expect.equals("str", list3.lastWhere((x) => false, orElse: () => "str"));
+
+  Expect.equals(12, set1.lastWhere((x) => x.isEven));
+  var odd = set1.lastWhere((x) => x.isOdd);
+  Expect.isTrue(odd == 11 || odd == 13);
+  Expect.throws(() => set1.lastWhere((x) => false), (e) => e is StateError);
+  Expect.equals(null, set1.lastWhere((x) => false, orElse: () => null));
+  Expect.equals(499, set1.lastWhere((x) => false, orElse: () => 499));
+
+  Expect.throws(() => set2.lastWhere((x) => false), (e) => e is StateError);
+  Expect.throws(() => set2.lastWhere((x) => true), (e) => e is StateError);
+  Expect.equals(null, set2.lastWhere((x) => true, orElse: () => null));
+  Expect.equals(499, set2.lastWhere((x) => false, orElse: () => 499));
+}
diff --git a/tests/corelib/iterable_single_matching_test.dart b/tests/corelib/iterable_single_matching_test.dart
deleted file mode 100644
index d51d6ee..0000000
--- a/tests/corelib/iterable_single_matching_test.dart
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-main() {
-  List<int> list1 = <int>[1, 2, 3];
-  List<int> list2 = const <int>[4, 5, 6];
-  List<String> list3 = <String>[];
-  Set<int> set1 = new Set<int>();
-  set1..add(11)
-      ..add(12)
-      ..add(13);
-  Set set2 = new Set();
-
-  Expect.equals(2, list1.singleMatching((x) => x.isEven));
-  Expect.equals(3, list1.singleMatching((x) => x == 3));
-  Expect.throws(() => list1.singleMatching((x) => x.isOdd),
-                (e) => e is StateError);
-
-  Expect.equals(6, list2.singleMatching((x) => x == 6));
-  Expect.equals(5, list2.singleMatching((x) => x.isOdd));
-  Expect.throws(() => list2.singleMatching((x) => x.isEven),
-                (e) => e is StateError);
-
-  Expect.throws(() => list3.singleMatching((x) => x == 0),
-                (e) => e is StateError);
-
-  Expect.equals(12, set1.singleMatching((x) => x.isEven));
-  Expect.equals(11, set1.singleMatching((x) => x == 11));
-  Expect.throws(() => set1.singleMatching((x) => x.isOdd));
-
-  Expect.throws(() => set2.singleMatching((x) => true), (e) => e is StateError);
-}
diff --git a/tests/corelib/iterable_single_where_test.dart b/tests/corelib/iterable_single_where_test.dart
new file mode 100644
index 0000000..ded576b
--- /dev/null
+++ b/tests/corelib/iterable_single_where_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() {
+  List<int> list1 = <int>[1, 2, 3];
+  List<int> list2 = const <int>[4, 5, 6];
+  List<String> list3 = <String>[];
+  Set<int> set1 = new Set<int>();
+  set1..add(11)
+      ..add(12)
+      ..add(13);
+  Set set2 = new Set();
+
+  Expect.equals(2, list1.singleWhere((x) => x.isEven));
+  Expect.equals(3, list1.singleWhere((x) => x == 3));
+  Expect.throws(() => list1.singleWhere((x) => x.isOdd),
+                (e) => e is StateError);
+
+  Expect.equals(6, list2.singleWhere((x) => x == 6));
+  Expect.equals(5, list2.singleWhere((x) => x.isOdd));
+  Expect.throws(() => list2.singleWhere((x) => x.isEven),
+                (e) => e is StateError);
+
+  Expect.throws(() => list3.singleWhere((x) => x == 0),
+                (e) => e is StateError);
+
+  Expect.equals(12, set1.singleWhere((x) => x.isEven));
+  Expect.equals(11, set1.singleWhere((x) => x == 11));
+  Expect.throws(() => set1.singleWhere((x) => x.isOdd));
+
+  Expect.throws(() => set2.singleWhere((x) => true), (e) => e is StateError);
+}
diff --git a/tests/corelib/list_get_range_test.dart b/tests/corelib/list_get_range_test.dart
index 88baeb6..07ffa56 100644
--- a/tests/corelib/list_get_range_test.dart
+++ b/tests/corelib/list_get_range_test.dart
@@ -3,43 +3,54 @@
 // BSD-style license that can be found in the LICENSE file.
 
 main() {
-  Expect.listEquals([], [].getRange(0, 0));
-  Expect.listEquals([], const [].getRange(0, 0));
+  Expect.listEquals([], [].sublist(0, 0));
+  Expect.listEquals([], const [].sublist(0, 0));
 
-  Expect.listEquals([], [].getRange(-1, 0));
-  Expect.listEquals([], const [].getRange(-1, 0));
 
-  Expect.listEquals([1, 2], [1, 2].getRange(0, 2));
-  Expect.listEquals([1, 2], const [1, 2].getRange(0, 2));
+  Expect.listEquals([1, 2], [1, 2].sublist(0, 2));
+  Expect.listEquals([1, 2], const [1, 2].sublist(0, 2));
 
-  Expect.listEquals([1], [1, 2].getRange(0, 1));
-  Expect.listEquals([1], const [1, 2].getRange(0, 1));
+  Expect.listEquals([1], [1, 2].sublist(0, 1));
+  Expect.listEquals([1], const [1, 2].sublist(0, 1));
 
-  Expect.listEquals([2], [1, 2].getRange(1, 1));
-  Expect.listEquals([2], const [1, 2].getRange(1, 1));
+  Expect.listEquals([2], [1, 2].sublist(1, 2));
+  Expect.listEquals([2], const [1, 2].sublist(1, 2));
 
-  Expect.listEquals([], [1, 2].getRange(0, 0));
-  Expect.listEquals([], const [1, 2].getRange(0, 0));
+  Expect.listEquals([], [1, 2].sublist(0, 0));
+  Expect.listEquals([], const [1, 2].sublist(0, 0));
 
-  Expect.listEquals([2, 3], [1, 2, 3, 4].getRange(1, 2));
-  Expect.listEquals([2, 3], const [1, 2, 3, 4].getRange(1, 2));
+  Expect.listEquals([2, 3], [1, 2, 3, 4].sublist(1, 3));
+  Expect.listEquals([2, 3], const [1, 2, 3, 4].sublist(1, 3));
 
-  Expect.listEquals([2, 3], [1, 2, 3, 4].getRange(1, 2));
-  Expect.listEquals([2, 3], const [1, 2, 3, 4].getRange(1, 2));
+  Expect.listEquals([2, 3], [1, 2, 3, 4].sublist(1, 3));
+  Expect.listEquals([2, 3], const [1, 2, 3, 4].sublist(1, 3));
 
-  expectIAE(() => [].getRange(0, -1));
-  expectIAE(() => const [].getRange(-1, -1));
+  expectAE(() => [].sublist(-1, null));
+  expectAE(() => const [].sublist(-1, null));
+  expectAE(() => [].sublist(-1, 0));
+  expectAE(() => const [].sublist(-1, 0));
+  expectAE(() => [].sublist(-1, -1));
+  expectAE(() => const [].sublist(-1, -1));
+  expectAE(() => [].sublist(-1, 1));
+  expectAE(() => const [].sublist(-1, 1));
+  expectAE(() => [].sublist(0, -1));
+  expectAE(() => const [].sublist(0, -1));
+  expectAE(() => [].sublist(0, 1));
+  expectAE(() => const [].sublist(0, 1));
+  expectAE(() => [].sublist(1, null));
+  expectAE(() => const [].sublist(1, null));
+  expectAE(() => [].sublist(1, 0));
+  expectAE(() => const [].sublist(1, 0));
+  expectAE(() => [].sublist(1, -1));
+  expectAE(() => const [].sublist(1, -1));
+  expectAE(() => [].sublist(1, 1));
+  expectAE(() => const [].sublist(1, 1));
 
-  expectIOORE(() => [].getRange(-1, 1));
-  expectIOORE(() => [].getRange(1, 1));
-  expectIOORE(() => [1].getRange(0, 2));
-  expectIOORE(() => [1].getRange(1, 1));
+  expectAE(() => [1].sublist(0, 2));
+  expectAE(() => [1].sublist(1, 2));
+  expectAE(() => [1].sublist(1, 0));
 }
 
-void expectIOORE(Function f) {
-  Expect.throws(f, (e) => e is RangeError);
-}
-
-void expectIAE(Function f) {
+void expectAE(Function f) {
   Expect.throws(f, (e) => e is ArgumentError);
 }
diff --git a/tests/corelib/list_insert_test.dart b/tests/corelib/list_insert_test.dart
new file mode 100644
index 0000000..7d3a722
--- /dev/null
+++ b/tests/corelib/list_insert_test.dart
@@ -0,0 +1,51 @@
+// 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.
+
+void main() {
+  // Normal modifiable list.
+  var l1 = [0, 1, 2, 3, 4];
+
+  bool checkedMode = false;
+  assert(checkedMode = true);
+
+  // Index must be integer and in range.
+  Expect.throws(() { l1.insert(-1, 5); },
+                (e) => e is RangeError,
+                "negative");
+  Expect.throws(() { l1.insert(6, 5); },
+                (e) => e is RangeError,
+                "too large");
+  Expect.throws(() { l1.insert(null, 5); });
+  Expect.throws(() { l1.insert("1", 5); });
+  Expect.throws(() { l1.insert(1.5, 5); });
+
+  l1.insert(5, 5);
+  Expect.equals(6, l1.length);
+  Expect.equals(5, l1[5]);
+  Expect.equals("[0, 1, 2, 3, 4, 5]", l1.toString());
+
+  l1.insert(0, -1);
+  Expect.equals(7, l1.length);
+  Expect.equals(-1, l1[0]);
+  Expect.equals("[-1, 0, 1, 2, 3, 4, 5]", l1.toString());
+
+  // Fixed size list.
+  var l2 = new List(5);
+  for (var i = 0; i < 5; i++) l2[i] = i;
+  Expect.throws(() { l2.insert(2, 5); },
+                (e) => e is UnsupportedError,
+                "fixed-length");
+
+  // Unmodifiable list.
+  var l3 = const [0, 1, 2, 3, 4];
+  Expect.throws(() { l3.insert(2, 5); },
+                (e) => e is UnsupportedError,
+                "unmodifiable");
+
+  // Empty list is not special.
+  var l4 = [];
+  l4.insert(0, 499);
+  Expect.equals(1, l4.length);
+  Expect.equals(499, l4[0]);
+}
diff --git a/tests/corelib/list_map_test.dart b/tests/corelib/list_map_test.dart
index 92aa331..ca30d4a 100644
--- a/tests/corelib/list_map_test.dart
+++ b/tests/corelib/list_map_test.dart
@@ -95,18 +95,18 @@
     testOp((i) => i.first, "first");
     testOp((i) => i.last, "last");
     testOp((i) => i.single, "single");
-    testOp((i) => i.firstMatching((n) => false), "firstMatching<false");
-    testOp((i) => i.firstMatching((n) => n < 10), "firstMatching<10");
-    testOp((i) => i.firstMatching((n) => n < 5), "firstMatching<5");
-    testOp((i) => i.firstMatching((n) => true), "firstMatching<true");
-    testOp((i) => i.lastMatching((n) => false), "lastMatching<false");
-    testOp((i) => i.lastMatching((n) => n < 5), "lastMatching<5");
-    testOp((i) => i.lastMatching((n) => n < 10), "lastMatching<10");
-    testOp((i) => i.lastMatching((n) => true), "lastMatching<true");
-    testOp((i) => i.singleMatching((n) => false), "singleMatching<false");
-    testOp((i) => i.singleMatching((n) => n < 5), "singelMatching<5");
-    testOp((i) => i.singleMatching((n) => n < 10), "singelMatching<10");
-    testOp((i) => i.singleMatching((n) => true), "singleMatching<true");
+    testOp((i) => i.firstWhere((n) => false), "firstWhere<false");
+    testOp((i) => i.firstWhere((n) => n < 10), "firstWhere<10");
+    testOp((i) => i.firstWhere((n) => n < 5), "firstWhere<5");
+    testOp((i) => i.firstWhere((n) => true), "firstWhere<true");
+    testOp((i) => i.lastWhere((n) => false), "lastWhere<false");
+    testOp((i) => i.lastWhere((n) => n < 5), "lastWhere<5");
+    testOp((i) => i.lastWhere((n) => n < 10), "lastWhere<10");
+    testOp((i) => i.lastWhere((n) => true), "lastWhere<true");
+    testOp((i) => i.singleWhere((n) => false), "singleWhere<false");
+    testOp((i) => i.singleWhere((n) => n < 5), "singelWhere<5");
+    testOp((i) => i.singleWhere((n) => n < 10), "singelWhere<10");
+    testOp((i) => i.singleWhere((n) => true), "singleWhere<true");
     testOp((i) => i.contains(5), "contains(5)");
     testOp((i) => i.contains(10), "contains(10)");
     testOp((i) => i.any((n) => n < 5), "any<5");
diff --git a/tests/corelib/list_reversed_test.dart b/tests/corelib/list_reversed_test.dart
index d6c8484..6055b3a 100644
--- a/tests/corelib/list_reversed_test.dart
+++ b/tests/corelib/list_reversed_test.dart
@@ -92,12 +92,12 @@
     testOp((i) => i.first, "first");
     testOp((i) => i.last, "last");
     testOp((i) => i.single, "single");
-    testOp((i) => i.firstMatching((n) => n < 5), "firstMatching<5");
-    testOp((i) => i.firstMatching((n) => n < 10), "firstMatching<10");
-    testOp((i) => i.lastMatching((n) => n < 5), "lastMatching<5");
-    testOp((i) => i.lastMatching((n) => n < 10), "lastMatching<10");
-    testOp((i) => i.singleMatching((n) => n < 5), "singelMatching<5");
-    testOp((i) => i.singleMatching((n) => n < 10), "singelMatching<10");
+    testOp((i) => i.firstWhere((n) => n < 5), "firstWhere<5");
+    testOp((i) => i.firstWhere((n) => n < 10), "firstWhere<10");
+    testOp((i) => i.lastWhere((n) => n < 5), "lastWhere<5");
+    testOp((i) => i.lastWhere((n) => n < 10), "lastWhere<10");
+    testOp((i) => i.singleWhere((n) => n < 5), "singelWhere<5");
+    testOp((i) => i.singleWhere((n) => n < 10), "singelWhere<10");
     testOp((i) => i.contains(5), "contains(5)");
     testOp((i) => i.contains(10), "contains(10)");
     testOp((i) => i.any((n) => n < 5), "any<5");
diff --git a/tests/corelib/queue_test.dart b/tests/corelib/queue_test.dart
index a269db9..51356e7 100644
--- a/tests/corelib/queue_test.dart
+++ b/tests/corelib/queue_test.dart
@@ -117,6 +117,7 @@
     Expect.isTrue(queue.isEmpty);
 
     testAddAll();
+    testLengthChanges();
     testLarge();
     testFromListToList();
   }
@@ -131,20 +132,27 @@
     Expect.equals(expectedSum, sum);
   }
 
+  testLength(int length, Queue queue) {
+    Expect.equals(length, queue.length);
+    ((length == 0) ? Expect.isTrue : Expect.isFalse)(queue.isEmpty);
+  }
+
   void testAddAll() {
     Set<int> set = new Set<int>.from([1, 2, 4]);
+    Expect.equals(3, set.length);
 
     Queue queue1 = newQueueFrom(set);
     Queue queue2 = newQueue();
     Queue queue3 = newQueue();
+    testLength(3, queue1);
+    testLength(0, queue2);
+    testLength(0, queue3);
 
     queue2.addAll(set);
-    queue3.addAll(queue1);
+    testLength(3, queue2);
 
-    Expect.equals(3, set.length);
-    Expect.equals(3, queue1.length);
-    Expect.equals(3, queue2.length);
-    Expect.equals(3, queue3.length);
+    queue3.addAll(queue1);
+    testLength(3, queue3);
 
     int sum = 0;
     void f(e) { sum += e; };
@@ -179,6 +187,58 @@
     Expect.equals(0, queue3.length);
   }
 
+  void testLengthChanges() {
+    // Test that the length property is updated properly by
+    // modifications;
+    Queue queue = newQueue();
+    testLength(0, queue);
+
+    for (int i = 1; i <= 10; i++) {
+      queue.add(i);
+      testLength(i, queue);
+    }
+
+    for (int i = 1; i <= 10; i++) {
+      queue.addFirst(11 - i);
+      testLength(10 + i, queue);
+    }
+
+    for (int i = 1; i <= 10; i++) {
+      queue.addLast(i);
+      testLength(20 + i, queue);
+    }
+
+    queue.addAll([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
+    testLength(40, queue);
+
+    for (int i = 1; i <= 5; i++) {
+      Expect.equals(i, queue.removeFirst());
+      testLength(40 - i, queue);
+    }
+
+    for (int i = 1; i <= 5; i++) {
+      Expect.equals(11 - i, queue.removeLast());
+      testLength(35 - i, queue);
+    }
+
+    queue.remove(10);
+    testLength(29, queue);
+
+    queue.removeAll([4, 6]);
+    testLength(23, queue);
+
+    queue.retainAll([1, 3, 5, 7, 9, 10]);  // Remove 2 and 8.
+    testLength(17, queue);
+
+    queue.removeWhere((x) => x == 7);
+    testLength(14, queue);
+
+    queue.retainWhere((x) => x != 3);
+    testLength(11, queue);
+
+    Expect.listEquals([9, 1, 5, 9, 10, 1, 5, 9, 10, 1, 5], queue.toList());
+  }
+
   void testLarge() {
     int N = 10000;
     Set set = new Set();
@@ -262,6 +322,62 @@
 class ListQueueTest extends QueueTest {
   Queue newQueue() => new ListQueue();
   Queue newQueueFrom(Iterable elements) => new ListQueue.from(elements);
+
+  void testMain() {
+    super.testMain();
+    trickyTest();
+  }
+
+  void trickyTest() {
+    // Test behavior around the know growing capacities of a ListQueue.
+    Queue q = new ListQueue();
+
+    for (int i = 0; i < 255; i++) {
+      q.add(i);
+    }
+    for (int i = 0; i < 128; i++) {
+      Expect.equals(i, q.removeFirst());
+    }
+    q.add(255);
+    for (int i = 0; i < 127; i++) {
+      q.add(i);
+    }
+
+    Expect.equals(255, q.length);
+
+    // Remove element at end of internal buffer.
+    q.removeWhere((v) => v == 255);
+    // Remove element at beginning of internal buffer.
+    q.removeWhere((v) => v == 0);
+    // Remove element at both ends of internal buffer.
+    q.removeWhere((v) => v == 254 || v == 1);
+
+    Expect.equals(251, q.length);
+
+    Iterable i255 = new Iterable.generate(255, (x) => x);
+
+    q = new ListQueue();
+    q.addAll(i255);
+    Expect.listEquals(i255.toList(), q.toList());
+
+    q = new ListQueue();
+    q.addAll(i255.toList());
+    Expect.listEquals(i255.toList(), q.toList());
+
+    q = new ListQueue.from(i255);
+    for (int i = 0; i < 128; i++) q.removeFirst();
+    q.add(256);
+    q.add(0);
+    q.addAll(i255.toList());
+    Expect.equals(129 + 255, q.length);
+
+    // Test addAll that requires the queue to grow.
+    q = new ListQueue();
+    q.addAll(i255.take(35));
+    q.addAll(i255.skip(35).take(96));
+    q.addAll(i255.skip(35 + 96));
+    Expect.listEquals(i255.toList(), q.toList());
+  }
 }
 
 class DoubleLinkedQueueTest extends QueueTest {
@@ -290,58 +406,8 @@
   }
 }
 
-void trickyTest() {
-  Queue q = new ListQueue();
-
-  for (int i = 0; i < 255; i++) {
-    q.add(i);
-  }
-  for (int i = 0; i < 128; i++) {
-    Expect.equals(i, q.removeFirst());
-  }
-  q.add(255);
-  for (int i = 0; i < 127; i++) {
-    q.add(i);
-  }
-
-  Expect.equals(255, q.length);
-
-  // Remove element at end of internal buffer.
-  q.removeMatching((v) => v == 255);
-  // Remove element at beginning of internal buffer.
-  q.removeMatching((v) => v == 0);
-  // Remove element at both ends of internal buffer.
-  q.removeMatching((v) => v == 254 || v == 1);
-
-  Expect.equals(251, q.length);
-
-  Iterable i255 = new Iterable.generate(255, (x) => x);
-
-  q = new ListQueue();
-  q.addAll(i255);
-  Expect.listEquals(i255.toList(), q.toList());
-
-  q = new ListQueue();
-  q.addAll(i255.toList());
-  Expect.listEquals(i255.toList(), q.toList());
-
-  q = new ListQueue.from(i255);
-  for (int i = 0; i < 128; i++) q.removeFirst();
-  q.add(256);
-  q.add(0);
-  q.addAll(i255.toList());
-  Expect.equals(129 + 255, q.length);
-
-  // Test addAll that requires the queue to grow.
-  q = new ListQueue();
-  q.addAll(i255.take(35));
-  q.addAll(i255.skip(35).take(96));
-  q.addAll(i255.skip(35 + 96));
-  Expect.listEquals(i255.toList(), q.toList());
-}
 
 main() {
   new DoubleLinkedQueueTest().testMain();
   new ListQueueTest().testMain();
-  trickyTest();
 }
diff --git a/tests/corelib/reg_exp_all_matches_test.dart b/tests/corelib/reg_exp_all_matches_test.dart
index bc31c0b..3e85114 100644
--- a/tests/corelib/reg_exp_all_matches_test.dart
+++ b/tests/corelib/reg_exp_all_matches_test.dart
@@ -33,7 +33,7 @@
     var matches = new RegExp("foo").allMatches("foo foo");
     var strbuf = new StringBuffer();
     matches.forEach((Match m) {
-      strbuf.add(m.group(0));
+      strbuf.write(m.group(0));
     });
     Expect.equals("foofoo", strbuf.toString());
   }
@@ -44,7 +44,7 @@
     Expect.equals(4, mapped.length);
     var strbuf = new StringBuffer();
     for (String s in mapped) {
-      strbuf.add(s);
+      strbuf.write(s);
     }
     Expect.equals("foobarfobarfoobarfobar", strbuf.toString());
   }
@@ -57,7 +57,7 @@
     Expect.equals(2, filtered.length);
     var strbuf = new StringBuffer();
     for (Match m in filtered) {
-      strbuf.add(m.group(0));
+      strbuf.write(m.group(0));
     }
     Expect.equals("foofoo", strbuf.toString());
   }
diff --git a/tests/corelib/set_test.dart b/tests/corelib/set_test.dart
index 3be91d5..940e427 100644
--- a/tests/corelib/set_test.dart
+++ b/tests/corelib/set_test.dart
@@ -11,15 +11,15 @@
   Expect.equals(0, set.length);
   set.add(1);
   Expect.equals(1, set.length);
-  Expect.equals(true, set.contains(1));
+  Expect.isTrue(set.contains(1));
 
   set.add(1);
   Expect.equals(1, set.length);
-  Expect.equals(true, set.contains(1));
+  Expect.isTrue(set.contains(1));
 
   set.remove(1);
   Expect.equals(0, set.length);
-  Expect.equals(false, set.contains(1));
+  Expect.isFalse(set.contains(1));
 
   for (int i = 0; i < 10; i++) {
     set.add(i);
@@ -27,13 +27,13 @@
 
   Expect.equals(10, set.length);
   for (int i = 0; i < 10; i++) {
-    Expect.equals(true, set.contains(i));
+    Expect.isTrue(set.contains(i));
   }
 
   Expect.equals(10, set.length);
 
   for (int i = 10; i < 20; i++) {
-    Expect.equals(false, set.contains(i));
+    Expect.isFalse(set.contains(i));
   }
 
   // Test Set.forEach.
@@ -45,8 +45,8 @@
   set.forEach(testForEach);
   Expect.equals(10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1, sum);
 
-  Expect.equals(true, set.isSubsetOf(set));
-  Expect.equals(true, set.containsAll(set));
+  Expect.isTrue(set.isSubsetOf(set));
+  Expect.isTrue(set.containsAll(set));
 
   // Test Set.map.
   testMap(int val) {
@@ -56,16 +56,16 @@
   Set mapped = set.map(testMap).toSet();
   Expect.equals(10, mapped.length);
 
-  Expect.equals(true, mapped.contains(0));
-  Expect.equals(true, mapped.contains(1));
-  Expect.equals(true, mapped.contains(4));
-  Expect.equals(true, mapped.contains(9));
-  Expect.equals(true, mapped.contains(16));
-  Expect.equals(true, mapped.contains(25));
-  Expect.equals(true, mapped.contains(36));
-  Expect.equals(true, mapped.contains(49));
-  Expect.equals(true, mapped.contains(64));
-  Expect.equals(true, mapped.contains(81));
+  Expect.isTrue(mapped.contains(0));
+  Expect.isTrue(mapped.contains(1));
+  Expect.isTrue(mapped.contains(4));
+  Expect.isTrue(mapped.contains(9));
+  Expect.isTrue(mapped.contains(16));
+  Expect.isTrue(mapped.contains(25));
+  Expect.isTrue(mapped.contains(36));
+  Expect.isTrue(mapped.contains(49));
+  Expect.isTrue(mapped.contains(64));
+  Expect.isTrue(mapped.contains(81));
 
   sum = 0;
   set.forEach(testForEach);
@@ -85,59 +85,76 @@
 
   Expect.equals(5, filtered.length);
 
-  Expect.equals(true, filtered.contains(0));
-  Expect.equals(true, filtered.contains(2));
-  Expect.equals(true, filtered.contains(4));
-  Expect.equals(true, filtered.contains(6));
-  Expect.equals(true, filtered.contains(8));
+  Expect.isTrue(filtered.contains(0));
+  Expect.isTrue(filtered.contains(2));
+  Expect.isTrue(filtered.contains(4));
+  Expect.isTrue(filtered.contains(6));
+  Expect.isTrue(filtered.contains(8));
 
   sum = 0;
   filtered.forEach(testForEach);
   Expect.equals(1 + 3 + 5 + 7 + 9, sum);
 
-  Expect.equals(true, set.containsAll(filtered));
-  Expect.equals(true, filtered.isSubsetOf(set));
+  Expect.isTrue(set.containsAll(filtered));
+  Expect.isTrue(filtered.isSubsetOf(set));
 
   // Test Set.every.
   testEvery(int val) {
     return (val < 10);
   }
 
-  Expect.equals(true, set.every(testEvery));
-  Expect.equals(true, filtered.every(testEvery));
+  Expect.isTrue(set.every(testEvery));
+  Expect.isTrue(filtered.every(testEvery));
 
   filtered.add(10);
-  Expect.equals(false, filtered.every(testEvery));
+  Expect.isFalse(filtered.every(testEvery));
 
   // Test Set.some.
   testSome(int val) {
     return (val == 4);
   }
 
-  Expect.equals(true, set.any(testSome));
-  Expect.equals(true, filtered.any(testSome));
+  Expect.isTrue(set.any(testSome));
+  Expect.isTrue(filtered.any(testSome));
   filtered.remove(4);
-  Expect.equals(false, filtered.any(testSome));
+  Expect.isFalse(filtered.any(testSome));
 
   // Test Set.intersection.
   Set intersection = set.intersection(filtered);
-  Expect.equals(true, set.contains(0));
-  Expect.equals(true, set.contains(2));
-  Expect.equals(true, set.contains(6));
-  Expect.equals(true, set.contains(8));
-  Expect.equals(false, intersection.contains(1));
-  Expect.equals(false, intersection.contains(3));
-  Expect.equals(false, intersection.contains(4));
-  Expect.equals(false, intersection.contains(5));
-  Expect.equals(false, intersection.contains(7));
-  Expect.equals(false, intersection.contains(9));
-  Expect.equals(false, intersection.contains(10));
+  Expect.isTrue(set.contains(0));
+  Expect.isTrue(set.contains(2));
+  Expect.isTrue(set.contains(6));
+  Expect.isTrue(set.contains(8));
+  Expect.isFalse(intersection.contains(1));
+  Expect.isFalse(intersection.contains(3));
+  Expect.isFalse(intersection.contains(4));
+  Expect.isFalse(intersection.contains(5));
+  Expect.isFalse(intersection.contains(7));
+  Expect.isFalse(intersection.contains(9));
+  Expect.isFalse(intersection.contains(10));
   Expect.equals(4, intersection.length);
 
-  Expect.equals(true, set.containsAll(intersection));
-  Expect.equals(true, filtered.containsAll(intersection));
-  Expect.equals(true, intersection.isSubsetOf(set));
-  Expect.equals(true, intersection.isSubsetOf(filtered));
+  Expect.isTrue(set.containsAll(intersection));
+  Expect.isTrue(filtered.containsAll(intersection));
+  Expect.isTrue(intersection.isSubsetOf(set));
+  Expect.isTrue(intersection.isSubsetOf(filtered));
+
+  // Test Set.union.
+  Set twice = create()..addAll([0, 2, 4, 6, 8, 10, 12, 14]);
+  Set thrice = create()..addAll([0, 3, 6, 9, 12, 15]);
+  Set union = twice.union(thrice);
+  Expect.equals(11, union.length);
+  for (int i = 0; i < 16; i++) {
+    Expect.equals(i.isEven || (i % 3) == 0, union.contains(i));
+  }
+
+  // Test Set.difference.
+  Set difference = twice.difference(thrice);
+  Expect.equals(5, difference.length);
+  for (int i = 0; i < 16; i++) {
+    Expect.equals(i.isEven && (i % 3) != 0, difference.contains(i));
+  }
+  Expect.isTrue(twice.difference(thrice).difference(twice).isEmpty);
 
   // Test Set.addAll.
   List list = new List.fixedLength(10);
@@ -147,17 +164,17 @@
   set.addAll(list);
   Expect.equals(20, set.length);
   for (int i = 0; i < 20; i++) {
-    Expect.equals(true, set.contains(i));
+    Expect.isTrue(set.contains(i));
   }
 
   // Test Set.removeAll
   set.removeAll(list);
   Expect.equals(10, set.length);
   for (int i = 0; i < 10; i++) {
-    Expect.equals(true, set.contains(i));
+    Expect.isTrue(set.contains(i));
   }
   for (int i = 10; i < 20; i++) {
-    Expect.equals(false, set.contains(i));
+    Expect.isFalse(set.contains(i));
   }
 
   // Test Set.clear.
diff --git a/tests/corelib/string_base_vm_test.dart b/tests/corelib/string_base_vm_test.dart
index 1acf12e..5e6f682 100644
--- a/tests/corelib/string_base_vm_test.dart
+++ b/tests/corelib/string_base_vm_test.dart
@@ -37,6 +37,8 @@
       String s4 = new String.fromCharCodes([0.0]);
     } on ArgumentError catch (ex) {
       exception_caught = true;
+    } on TypeError catch (ex) {
+      exception_caught = true;
     }
     Expect.equals(true, exception_caught);
     exception_caught = false;
diff --git a/tests/corelib/string_buffer_test.dart b/tests/corelib/string_buffer_test.dart
index 5fcde73..68c5301 100644
--- a/tests/corelib/string_buffer_test.dart
+++ b/tests/corelib/string_buffer_test.dart
@@ -4,148 +4,180 @@
 
 // TODO(srdjan): Move StringBuffer to visible names.
 
-class StringBufferTest {
-  static testConstructor() {
-    StringBuffer bf = new StringBuffer("");
-    Expect.equals(true, bf.isEmpty);
+void testConstructor() {
+  StringBuffer bf = new StringBuffer("");
+  Expect.equals(true, bf.isEmpty);
 
-    bf = new StringBuffer("abc");
-    Expect.equals(3, bf.length);
-    Expect.equals("abc", bf.toString());
-  }
+  bf = new StringBuffer("abc");
+  Expect.equals(3, bf.length);
+  Expect.equals("abc", bf.toString());
 
-  static testAdd() {
-    StringBuffer bf = new StringBuffer("");
-    Expect.equals(true, bf.isEmpty);
-
-    bf.add("a");
-    Expect.equals(1, bf.length);
-    Expect.equals("a", bf.toString());
-
-    bf = new StringBuffer("");
-    bf.add("a");
-    bf.add("b");
-    Expect.equals("ab", bf.toString());
-
-    bf = new StringBuffer("abc");
-    bf.add("d");
-    bf.add("e");
-    bf.add("f");
-    bf.add("g");
-    bf.add("h");
-    bf.add("i");
-    bf.add("j");
-    bf.add("k");
-    bf.add("l");
-    bf.add("m");
-    bf.add("n");
-    bf.add("o");
-    bf.add("p");
-    bf.add("q");
-    bf.add("r");
-    bf.add("s");
-    bf.add("t");
-    bf.add("u");
-    bf.add("v");
-    bf.add("w");
-    bf.add("x");
-    bf.add("y");
-    bf.add("z");
-    bf.add("\n");
-    bf.add("thequickbrownfoxjumpsoverthelazydog");
-    Expect.equals("abcdefghijklmnopqrstuvwxyz\n"
-                  "thequickbrownfoxjumpsoverthelazydog",
-                  bf.toString());
-
-    bf = new StringBuffer("");
-    for (int i = 0; i < 100000; i++) {
-      bf.add('');
-      bf.add("");
-    }
-    Expect.equals("", bf.toString());
-  }
-
-  static testLength() {
-    StringBuffer bf = new StringBuffer("");
-    Expect.equals(0, bf.length);
-    bf.add("foo");
-    Expect.equals(3, bf.length);
-    bf.add("bar");
-    Expect.equals(6, bf.length);
-    bf.add("");
-    Expect.equals(6, bf.length);
-  }
-
-  static testIsEmpty() {
-    StringBuffer bf = new StringBuffer("");
-    Expect.equals(true, bf.isEmpty);
-    bf.add("foo");
-    Expect.equals(false, bf.isEmpty);
-  }
-
-  static testAddAll() {
-    StringBuffer bf = new StringBuffer("");
-    bf.addAll(["foo", "bar", "a", "b", "c"]);
-    Expect.equals("foobarabc", bf.toString());
-
-    bf.addAll([]);
-    Expect.equals("foobarabc", bf.toString());
-
-    bf.addAll(["", "", ""]);
-    Expect.equals("foobarabc", bf.toString());
-  }
-
-  static testClear() {
-    StringBuffer bf = new StringBuffer("");
-    bf.add("foo");
-    bf.clear();
-    Expect.equals("", bf.toString());
-    Expect.equals(0, bf.length);
-
-    bf.add("bar");
-    Expect.equals("bar", bf.toString());
-    Expect.equals(3, bf.length);
-    bf.clear();
-    Expect.equals("", bf.toString());
-    Expect.equals(0, bf.length);
-  }
-
-  static testToString() {
-    StringBuffer bf = new StringBuffer("");
-    Expect.equals("", bf.toString());
-
-    bf = new StringBuffer("foo");
-    Expect.equals("foo", bf.toString());
-
-    bf = new StringBuffer("foo");
-    bf.add("bar");
-    Expect.equals("foobar", bf.toString());
-  }
-
-  static testChaining() {
-    StringBuffer bf = new StringBuffer("");
-    StringBuffer bf2 = new StringBuffer("");
-    bf2.add("bf2");
-    bf..add("foo")
-      ..add("bar")
-      ..add(bf2)
-      ..add(bf2)
-      ..add("toto");
-    Expect.equals("foobarbf2bf2toto", bf.toString());
-  }
-
-  static testMain() {
-    testToString();
-    testConstructor();
-    testLength();
-    testIsEmpty();
-    testAdd();
-    testAddAll();
-    testClear();
-    testChaining();
-  }
+  bf = new StringBuffer("\x00");
 }
 
-main() {
-  StringBufferTest.testMain();
+void testWrite() {
+  StringBuffer bf = new StringBuffer("");
+  Expect.equals(true, bf.isEmpty);
+
+  bf.write("a");
+  Expect.equals(1, bf.length);
+  Expect.equals("a", bf.toString());
+
+  bf = new StringBuffer("");
+  bf.write("a");
+  bf.write("b");
+  Expect.equals("ab", bf.toString());
+
+  bf = new StringBuffer("abc");
+  bf.write("d");
+  bf.write("e");
+  bf.write("f");
+  bf.write("g");
+  bf.write("h");
+  bf.write("i");
+  bf.write("j");
+  bf.write("k");
+  bf.write("l");
+  bf.write("m");
+  bf.write("n");
+  bf.write("o");
+  bf.write("p");
+  bf.write("q");
+  bf.write("r");
+  bf.write("s");
+  bf.write("t");
+  bf.write("u");
+  bf.write("v");
+  bf.write("w");
+  bf.write("x");
+  bf.write("y");
+  bf.write("z");
+  bf.write("\n");
+  bf.write("thequickbrownfoxjumpsoverthelazydog");
+  Expect.equals("abcdefghijklmnopqrstuvwxyz\n"
+                "thequickbrownfoxjumpsoverthelazydog",
+                bf.toString());
+
+  bf = new StringBuffer("");
+  for (int i = 0; i < 100000; i++) {
+    bf.write('');
+    bf.write("");
+  }
+  Expect.equals("", bf.toString());
+}
+
+void testLength() {
+  StringBuffer bf = new StringBuffer("");
+  Expect.equals(0, bf.length);
+  bf.write("foo");
+  Expect.equals(3, bf.length);
+  bf.write("bar");
+  Expect.equals(6, bf.length);
+  bf.write("");
+  Expect.equals(6, bf.length);
+}
+
+void testIsEmpty() {
+  StringBuffer bf = new StringBuffer("");
+  Expect.equals(true, bf.isEmpty);
+  bf.write("foo");
+  Expect.equals(false, bf.isEmpty);
+}
+
+void testWriteAll() {
+  StringBuffer bf = new StringBuffer("");
+  bf.writeAll(["foo", "bar", "a", "b", "c"]);
+  Expect.equals("foobarabc", bf.toString());
+
+  bf.writeAll([]);
+  Expect.equals("foobarabc", bf.toString());
+
+  bf.writeAll(["", "", ""]);
+  Expect.equals("foobarabc", bf.toString());
+}
+
+void testClear() {
+  StringBuffer bf = new StringBuffer("");
+  bf.write("foo");
+  bf.clear();
+  Expect.equals("", bf.toString());
+  Expect.equals(0, bf.length);
+
+  bf.write("bar");
+  Expect.equals("bar", bf.toString());
+  Expect.equals(3, bf.length);
+  bf.clear();
+  Expect.equals("", bf.toString());
+  Expect.equals(0, bf.length);
+}
+
+void testToString() {
+  StringBuffer bf = new StringBuffer("");
+  Expect.equals("", bf.toString());
+
+  bf = new StringBuffer("foo");
+  Expect.equals("foo", bf.toString());
+
+  bf = new StringBuffer("foo");
+  bf.write("bar");
+  Expect.equals("foobar", bf.toString());
+}
+
+void testChaining() {
+  StringBuffer bf = new StringBuffer("");
+  StringBuffer bf2 = new StringBuffer("");
+  bf2.write("bf2");
+  bf..write("foo")
+    ..write("bar")
+    ..write(bf2)
+    ..write(bf2)
+    ..write("toto");
+  Expect.equals("foobarbf2bf2toto", bf.toString());
+}
+
+void testWriteCharCode() {
+  StringBuffer bf1 = new StringBuffer();
+  StringBuffer bf2 = new StringBuffer();
+  bf1.write("a");
+  bf2.writeCharCode(0x61);  // a
+  bf1.write("b");
+  bf2.writeCharCode(0x62);  // b
+  bf1.write("c");
+  bf2.writeCharCode(0x63);  // c
+  bf1.write(new String.fromCharCode(0xD823));
+  bf2.writeCharCode(0xD823);
+  bf1.write(new String.fromCharCode(0xDC23));
+  bf2.writeCharCode(0xDC23);
+  bf1.write("\u{1d49e}");
+  bf2.writeCharCode(0x1d49e);
+  bf1.write("\x00");
+  bf2.writeCharCode(0);
+  Expect.equals(bf1.toString(), bf2.toString());
+  Expect.equals("abc\u{18c23}\u{1d49e}\x00", bf2.toString());
+
+  // Mixing strings and char-codes.
+  bf1.clear();
+  bf1.write("abcde");
+  bf1.writeCharCode(0x61);
+  bf1.writeCharCode(0x62);
+  bf1.writeCharCode(0x63);
+  bf1.write("d");
+  bf1.writeCharCode(0x65);
+  Expect.equals("abcdeabcde", bf1.toString());
+
+  // Out-of-range character codes are not allowed.
+  Expect.throws(() { bf2.writeCharCode(-1); });
+  Expect.throws(() { bf2.writeCharCode(0x110000); });
+}
+
+void main() {
+  testToString();
+  testConstructor();
+  testLength();
+  testIsEmpty();
+  testWrite();
+  testWriteCharCode();
+  testWriteAll();
+  testClear();
+  testChaining();
 }
diff --git a/tests/corelib/string_codeunits_test.dart b/tests/corelib/string_codeunits_test.dart
index ac6eb97..28b9df4 100644
--- a/tests/corelib/string_codeunits_test.dart
+++ b/tests/corelib/string_codeunits_test.dart
@@ -31,7 +31,7 @@
       Expect.throws(() => units.last, (e) => e is StateError);
       Expect.throws(() => units[0], (e) => e is RangeError);
       Expect.throws(() => units[0] = 499, (e) => e is UnsupportedError);
-      Expect.listEquals([], units.getRange(0, 0));
+      Expect.listEquals([], units.sublist(0, 0));
       Expect.equals(-1, units.indexOf(42));
       Expect.equals(-1, units.lastIndexOf(499));
     } else {
@@ -39,7 +39,7 @@
       Expect.equals(s.codeUnitAt(s.length - 1), units.last);
       Expect.equals(s.codeUnitAt(0), units[0]);
       Expect.throws(() { units[0] = 499; }, (e) => e is UnsupportedError);
-      List<int> sub = units.getRange(1, units.length - 1);
+      List<int> sub = units.sublist(1);
       Expect.listEquals(s.substring(1, s.length).codeUnits, sub);
       Expect.equals(-1, units.indexOf(-1));
       Expect.equals(0, units.indexOf(units[0]));
diff --git a/tests/corelib/string_from_list_test.dart b/tests/corelib/string_from_list_test.dart
index 23c90f2..e58b677 100644
--- a/tests/corelib/string_from_list_test.dart
+++ b/tests/corelib/string_from_list_test.dart
@@ -2,46 +2,84 @@
 // 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 StringFromListTest {
-  static testMain() {
-    Expect.equals("", new String.fromCharCodes(new List(0)));
-    Expect.equals("", new String.fromCharCodes([]));
-    Expect.equals("", new String.fromCharCodes(const []));
-    Expect.equals("AB", new String.fromCharCodes([65, 66]));
-    Expect.equals("AB", new String.fromCharCodes(const [65, 66]));
-    Expect.equals("Ærø", new String.fromCharCodes(const [0xc6, 0x72, 0xf8]));
-    Expect.equals("\u{1234}", new String.fromCharCodes([0x1234]));
-    Expect.equals("\u{12345}*", new String.fromCharCodes([0x12345, 42]));
-    Expect.equals("", new String.fromCharCodes(new List()));
-    {
-      var a = new List();
-      a.add(65);
-      a.add(66);
-      Expect.equals("AB", new String.fromCharCodes(a));
-    }
-
-    // Long list (bug 6919).
-    for (int len in [499, 500, 501, 999, 100000]) {
-      List<int> list = new List(len);
-      for (int i = 0; i < len; i++) {
-        list[i] = 65 + (i % 26);
-      }
-      for (int i = len - 9; i < len; i++) {
-        list[i] = 48 + (len - i);
-      }
-      // We should not throw a stack overflow here.
-      String long = new String.fromCharCodes(list);
-      // Minimal sanity checking on the string.
-      Expect.isTrue(long.startsWith('ABCDE'));
-      Expect.isTrue(long.endsWith('987654321'));
-      int middle = len ~/ 2;
-      middle -= middle % 26;
-      Expect.equals('XYZABC', long.substring(middle - 3, middle + 3));
-      Expect.equals(len, long.length);
-    }
+void main() {
+  Expect.equals("", new String.fromCharCodes(new List(0)));
+  Expect.equals("", new String.fromCharCodes([]));
+  Expect.equals("", new String.fromCharCodes(const []));
+  Expect.equals("AB", new String.fromCharCodes([65, 66]));
+  Expect.equals("AB", new String.fromCharCodes(const [65, 66]));
+  Expect.equals("Ærø", new String.fromCharCodes(const [0xc6, 0x72, 0xf8]));
+  Expect.equals("\u{1234}", new String.fromCharCodes([0x1234]));
+  Expect.equals("\u{12345}*", new String.fromCharCodes([0x12345, 42]));
+  Expect.equals("", new String.fromCharCodes(new List()));
+  {
+    var a = new List();
+    a.add(65);
+    a.add(66);
+    Expect.equals("AB", new String.fromCharCodes(a));
   }
-}
 
-main() {
-  StringFromListTest.testMain();
+  // Long list (bug 6919).
+  for (int len in [499, 500, 501, 999, 100000]) {
+    List<int> list = new List(len);
+    for (int i = 0; i < len; i++) {
+      list[i] = 65 + (i % 26);
+    }
+    for (int i = len - 9; i < len; i++) {
+      list[i] = 48 + (len - i);
+    }
+    // We should not throw a stack overflow here.
+    String long = new String.fromCharCodes(list);
+    // Minimal sanity checking on the string.
+    Expect.isTrue(long.startsWith('ABCDE'));
+    Expect.isTrue(long.endsWith('987654321'));
+    int middle = len ~/ 2;
+    middle -= middle % 26;
+    Expect.equals('XYZABC', long.substring(middle - 3, middle + 3));
+    Expect.equals(len, long.length);
+  }
+
+
+  // Should work with iterables and non-default-lists (http://dartbug.com/8922)
+  Expect.equals("CBA", new String.fromCharCodes([65, 66, 67].reversed));
+  Expect.equals("BCD",
+                new String.fromCharCodes([65, 66, 67].map((x) => x + 1)));
+  Expect.equals("AC",
+                new String.fromCharCodes([0x41, 0x42, 0x43].where(
+                    (x) => x.isOdd)));
+  Expect.equals("CE",
+                new String.fromCharCodes(
+                     [0x41, 0x42, 0x43].where((x) => x.isOdd)
+                                       .map((x) => x + 2)));
+  Expect.equals("ABC", new String.fromCharCodes(
+                           new Iterable.generate(3, (x) => 65 + x)));
+  Expect.equals("ABC", new String.fromCharCodes("ABC".codeUnits));
+  Expect.equals("BCD",
+                new String.fromCharCodes("ABC".codeUnits.map((x) => x + 1)));
+  Expect.equals("BCD",
+                new String.fromCharCodes("ABC".runes.map((x) => x + 1)));
+
+  var nonBmpCharCodes = [0, 0xD812, 0xDC34, 0x14834, 0xDC34, 0xD812];
+  var nonBmp = new String.fromCharCodes(nonBmpCharCodes);
+  Expect.equals(7, nonBmp.length);
+  Expect.equals(0, nonBmp.codeUnitAt(0));
+  Expect.equals(0xD812, nonBmp.codeUnitAt(1));  // Separated surrogate pair
+  Expect.equals(0xDC34, nonBmp.codeUnitAt(2));
+  Expect.equals(0xD812, nonBmp.codeUnitAt(3));  // Single non-BMP code point.
+  Expect.equals(0xDC34, nonBmp.codeUnitAt(4));
+  Expect.equals(0xDC34, nonBmp.codeUnitAt(5));  // Unmatched surrogate.
+  Expect.equals(0xD812, nonBmp.codeUnitAt(6));  // Unmatched surrogate.
+
+  var reversedNonBmp = new String.fromCharCodes(nonBmpCharCodes.reversed);
+  Expect.equals(7, reversedNonBmp.length);
+  Expect.equals(0, reversedNonBmp.codeUnitAt(6));
+  Expect.equals(0xD812, reversedNonBmp.codeUnitAt(5));
+  Expect.equals(0xDC34, reversedNonBmp.codeUnitAt(4));
+  Expect.equals(0xDC34, reversedNonBmp.codeUnitAt(3));
+  Expect.equals(0xD812, reversedNonBmp.codeUnitAt(2));
+  Expect.equals(0xDC34, reversedNonBmp.codeUnitAt(1));
+  Expect.equals(0xD812, reversedNonBmp.codeUnitAt(0));
+
+  Expect.equals(nonBmp, new String.fromCharCodes(nonBmp.codeUnits));
+  Expect.equals(nonBmp, new String.fromCharCodes(nonBmp.runes));
 }
diff --git a/tests/corelib/string_test.dart b/tests/corelib/string_test.dart
index 2dd329c..d0879bd 100644
--- a/tests/corelib/string_test.dart
+++ b/tests/corelib/string_test.dart
@@ -65,7 +65,7 @@
   static testConcat() {
     var a = "One";
     var b = "Four";
-    var c = a.concat(b);
+    var c = a + b;
     Expect.equals(7, c.length);
     Expect.equals("OneFour", c);
   }
@@ -73,8 +73,8 @@
   static testEquals() {
     Expect.equals("str", "str");
 
-    Expect.equals("str", "s".concat("t").concat("r"));
-    Expect.equals("s".concat("t").concat("r"), "str");
+    Expect.equals("str", "s" + "t" + "r");
+    Expect.equals("s" + "t" + "r", "str");
 
     Expect.equals(false, "str" == "s");
     Expect.equals(false, "str" == "r");
diff --git a/tests/html/async_window_test.dart b/tests/html/async_window_test.dart
index 7410e49..6cdb5dd 100644
--- a/tests/html/async_window_test.dart
+++ b/tests/html/async_window_test.dart
@@ -9,10 +9,10 @@
   test('Timer', () {
     new Timer(const Duration(milliseconds: 10), expectAsync0((){}));
   });
-  test('Timer.repeating', () {
+  test('Timer.periodic', () {
     int counter = 0;
     int id = null;
-    new Timer.repeating(const Duration(milliseconds: 10),
+    new Timer.periodic(const Duration(milliseconds: 10),
         expectAsyncUntil1(
         (timer) {
           if (counter == 3) {
diff --git a/tests/html/canvasrenderingcontext2d_test.dart b/tests/html/canvasrenderingcontext2d_test.dart
index 495e5e4..5069680 100644
--- a/tests/html/canvasrenderingcontext2d_test.dart
+++ b/tests/html/canvasrenderingcontext2d_test.dart
@@ -2,10 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library url_test;
+library canvas_rendering_context_2d_test;
 import '../../pkg/unittest/lib/unittest.dart';
 import '../../pkg/unittest/lib/html_config.dart';
 import 'dart:html';
+import 'dart:math';
 
 // Some rounding errors in the browsers.
 checkPixel(List<int> pixel, List<int> expected) {
@@ -17,102 +18,517 @@
 
 main() {
   useHtmlConfiguration();
-  var canvas = new CanvasElement();
-  canvas.width = 100;
-  canvas.height = 100;
 
-  var context = canvas.context2d;
+  group('canvasRenderingContext2d', () {
+    var canvas;
+    var context;
+    var otherCanvas;
+    var otherContext;
 
-  List<int> readPixel() {
-    var imageData = context.getImageData(2, 2, 1, 1);
-    return imageData.data;
-  }
+    void createOtherCanvas() {
+      otherCanvas = new CanvasElement();
+      otherCanvas.width = 10;
+      otherCanvas.height = 10;
+      otherContext = otherCanvas.context2d;
+      otherContext.fillStyle = "red";
+      otherContext.fillRect(0, 0, otherCanvas.width, otherCanvas.height);
+    }
 
-  test('setFillColorRgb', () {
-    context.setFillColorRgb(255, 0, 255, 1);
-    context.fillRect(0, 0, canvas.width, canvas.height);
-    expect(readPixel(), [255, 0, 255, 255]);
-  });
+    setUp(() {
+      canvas = new CanvasElement();
+      canvas.width = 100;
+      canvas.height = 100;
 
-  test('setFillColorHsl hue', () {
-    context.setFillColorHsl(0, 100, 50);
-    context.fillRect(0, 0, canvas.width, canvas.height);
-    checkPixel(readPixel(), [255, 0, 0, 255]);
-  });
+      context = canvas.context2d;
 
-  test('setFillColorHsl hue 2', () {
-    context.setFillColorHsl(240, 100, 50);
-    context.fillRect(0, 0, canvas.width, canvas.height);
-    checkPixel(readPixel(), [0, 0, 255, 255]);
-  });
+      createOtherCanvas();
+    });
 
-  test('setFillColorHsl sat', () {
-    context.setFillColorHsl(0, 0, 50);
-    context.fillRect(0, 0, canvas.width, canvas.height);
-    checkPixel(readPixel(), [127, 127, 127, 255]);
-  });
+    tearDown(() {
+      canvas = null;
+      context = null;
+      otherCanvas = null;
+      otherContext = null;
+    });
 
-  test('setStrokeColorRgb', () {
-    context.setStrokeColorRgb(255, 0, 255, 1);
-    context.lineWidth = 10;
-    context.strokeRect(0, 0, canvas.width, canvas.height);
-    expect(readPixel(), [255, 0, 255, 255]);
-  });
+    List<int> readPixel(int x, int y) {
+      var imageData = context.getImageData(x, y, 1, 1);
+      return imageData.data;
+    }
 
-  test('setStrokeColorHsl hue', () {
-    context.setStrokeColorHsl(0, 100, 50);
-    context.lineWidth = 10;
-    context.strokeRect(0, 0, canvas.width, canvas.height);
-    expect(readPixel(), [255, 0, 0, 255]);
-  });
+    /// Returns true if the pixel has some data in it, false otherwise.
+    bool isPixelFilled(int x, int y) => readPixel(x,y).any((p) => p != 0);
 
-  test('setStrokeColorHsl hue 2', () {
-    context.setStrokeColorHsl(240, 100, 50);
-    context.lineWidth = 10;
-    context.strokeRect(0, 0, canvas.width, canvas.height);
-    expect(readPixel(), [0, 0, 255, 255]);
-  });
+    String pixelDataToString(int x, int y) {
+      var data = readPixel(x, y);
 
-  test('setStrokeColorHsl sat', () {
-    context.setStrokeColorHsl(0, 0, 50);
-    context.lineWidth = 10;
-    context.strokeRect(0, 0, canvas.width, canvas.height);
-    checkPixel(readPixel(), [127, 127, 127, 255]);
-  });
+      return '[${data.join(", ")}]';
+    }
 
-  test('fillStyle', () {
-    context.fillStyle = "red";
-    context.fillRect(0, 0, canvas.width, canvas.height);
-    checkPixel(readPixel(), [255, 0, 0, 255]);
-  });
+    String _filled(bool v) => v ? "filled" : "unfilled";
 
-  test('strokeStyle', () {
-    context.strokeStyle = "blue";
-    context.lineWidth = 10;
-    context.strokeRect(0, 0, canvas.width, canvas.height);
-    expect(readPixel(), [0, 0, 255, 255]);
-  });
+    void expectPixelFilled(int x, int y, [bool filled = true]) {
+      expect(isPixelFilled(x, y), filled, reason:
+          'Pixel at ($x, $y) was expected to'
+          ' be: <${_filled(filled)}> but was: <${_filled(!filled)}> with data: '
+          '${pixelDataToString(x,y)}');
+    }
 
-  test('fillStyle linearGradient', () {
-    var gradient = context.createLinearGradient(0,0,20,20);
-    gradient.addColorStop(0,'red');
-    gradient.addColorStop(1,'blue');
-    context.fillStyle = gradient;
-    context.fillRect(0, 0, canvas.width, canvas.height);
-    expect(context.fillStyle is CanvasGradient, isTrue);
-  });
+    void expectPixelUnfilled(int x, int y) {
+      expectPixelFilled(x, y, false);
+    }
 
-  test('putImageData', () {
-    ImageData expectedData = context.getImageData(0, 0, 10, 10);
-    expectedData.data[0] = 25;
-    expectedData.data[2] = 255;
-    context.fillStyle = 'green';
-    context.fillRect(0, 0, canvas.width, canvas.height);
 
-    context.putImageData(expectedData, 0, 0);
+    test('setFillColorRgb', () {
+      context.setFillColorRgb(255, 0, 255, 1);
+      context.fillRect(0, 0, canvas.width, canvas.height);
+      expect(readPixel(2, 2), [255, 0, 255, 255]);
+    });
 
-    var resultingData = context.getImageData(0, 0, 10, 10);
-    // Make sure that we read back what we wrote.
-    expect(resultingData.data, expectedData.data);
+    test('setFillColorHsl hue', () {
+      context.setFillColorHsl(0, 100, 50);
+      context.fillRect(0, 0, canvas.width, canvas.height);
+      checkPixel(readPixel(2, 2), [255, 0, 0, 255]);
+    });
+
+    test('setFillColorHsl hue 2', () {
+      context.setFillColorHsl(240, 100, 50);
+      context.fillRect(0, 0, canvas.width, canvas.height);
+      checkPixel(readPixel(2, 2), [0, 0, 255, 255]);
+    });
+
+    test('setFillColorHsl sat', () {
+      context.setFillColorHsl(0, 0, 50);
+      context.fillRect(0, 0, canvas.width, canvas.height);
+      checkPixel(readPixel(2, 2), [127, 127, 127, 255]);
+    });
+
+    test('setStrokeColorRgb', () {
+      context.setStrokeColorRgb(255, 0, 255, 1);
+      context.lineWidth = 10;
+      context.strokeRect(0, 0, canvas.width, canvas.height);
+      expect(readPixel(2, 2), [255, 0, 255, 255]);
+    });
+
+    test('setStrokeColorHsl hue', () {
+      context.setStrokeColorHsl(0, 100, 50);
+      context.lineWidth = 10;
+      context.strokeRect(0, 0, canvas.width, canvas.height);
+      expect(readPixel(2, 2), [255, 0, 0, 255]);
+    });
+
+    test('setStrokeColorHsl hue 2', () {
+      context.setStrokeColorHsl(240, 100, 50);
+      context.lineWidth = 10;
+      context.strokeRect(0, 0, canvas.width, canvas.height);
+      expect(readPixel(2, 2), [0, 0, 255, 255]);
+    });
+
+    test('setStrokeColorHsl sat', () {
+      context.setStrokeColorHsl(0, 0, 50);
+      context.lineWidth = 10;
+      context.strokeRect(0, 0, canvas.width, canvas.height);
+      checkPixel(readPixel(2, 2), [127, 127, 127, 255]);
+    });
+
+    test('fillStyle', () {
+      context.fillStyle = "red";
+      context.fillRect(0, 0, canvas.width, canvas.height);
+      checkPixel(readPixel(2, 2), [255, 0, 0, 255]);
+    });
+
+    test('strokeStyle', () {
+      context.strokeStyle = "blue";
+      context.lineWidth = 10;
+      context.strokeRect(0, 0, canvas.width, canvas.height);
+      expect(readPixel(2, 2), [0, 0, 255, 255]);
+    });
+
+    test('fillStyle linearGradient', () {
+      var gradient = context.createLinearGradient(0,0,20,20);
+      gradient.addColorStop(0,'red');
+      gradient.addColorStop(1,'blue');
+      context.fillStyle = gradient;
+      context.fillRect(0, 0, canvas.width, canvas.height);
+      expect(context.fillStyle is CanvasGradient, isTrue);
+    });
+
+    test('putImageData', () {
+      ImageData expectedData = context.getImageData(0, 0, 10, 10);
+      expectedData.data[0] = 25;
+      expectedData.data[1] = 65;
+      expectedData.data[2] = 255;
+      // Set alpha to 255 to make the pixels show up.
+      expectedData.data[3] = 255;
+      context.fillStyle = 'green';
+      context.fillRect(0, 0, canvas.width, canvas.height);
+
+      context.putImageData(expectedData, 0, 0);
+
+      var resultingData = context.getImageData(0, 0, 10, 10);
+      // Make sure that we read back what we wrote.
+      expect(resultingData.data, expectedData.data);
+    });
+
+    test('default arc should be clockwise', () {
+      context.beginPath();
+      final r = 10;
+
+      // Center of arc.
+      final cx = 20;
+      final cy = 20;
+      // Arc centered at (20, 20) with radius 10 will go clockwise
+      // from (20 + r, 20) to (20, 20 + r), which is 1/4 of a circle.
+      context.arc(cx, cy, r, 0, PI/2);
+
+      context.strokeStyle = 'green';
+      context.lineWidth = 2;
+      context.stroke();
+
+      // Center should not be filled.
+      expectPixelUnfilled(cx, cy);
+
+      // (cx + r, cy) should be filled.
+      expectPixelFilled(cx + r, cy, true);
+      // (cx, cy + r) should be filled.
+      expectPixelFilled(cx, cy + r, true);
+      // (cx - r, cy) should be empty.
+      expectPixelFilled(cx - r, cy, false);
+      // (cx, cy - r) should be empty.
+      expectPixelFilled(cx, cy - r, false);
+
+      // (cx + r/SQRT2, cy + r/SQRT2) should be filled.
+      expectPixelFilled((cx + r/SQRT2).toInt(), (cy + r/SQRT2).toInt(), true);
+
+      // (cx - r/SQRT2, cy - r/SQRT2) should be empty.
+      expectPixelFilled((cx - r/SQRT2).toInt(), (cy + r/SQRT2).toInt(), false);
+
+      // (cx + r/SQRT2, cy + r/SQRT2) should be empty.
+      expectPixelFilled((cx - r/SQRT2).toInt(), (cy - r/SQRT2).toInt(), false);
+
+      // (cx - r/SQRT2, cy - r/SQRT2) should be empty.
+      expectPixelFilled((cx + r/SQRT2).toInt(), (cy - r/SQRT2).toInt(), false);
+    });
+
+    test('arc anticlockwise', () {
+      context.beginPath();
+      final r = 10;
+
+      // Center of arc.
+      final cx = 20;
+      final cy = 20;
+      // Arc centered at (20, 20) with radius 10 will go anticlockwise
+      // from (20 + r, 20) to (20, 20 + r), which is 3/4 of a circle.
+      // Because of the way arc work, when going anti-clockwise, the end points
+      // are not included, so small values are added to radius to make a little
+      // more than a 3/4 circle.
+      context.arc(cx, cy, r, .1, PI/2 - .1, true);
+
+      context.strokeStyle = 'green';
+      context.lineWidth = 2;
+      context.stroke();
+
+      // Center should not be filled.
+      expectPixelUnfilled(cx, cy);
+
+      // (cx + r, cy) should be filled.
+      expectPixelFilled(cx + r, cy, true);
+      // (cx, cy + r) should be filled.
+      expectPixelFilled(cx, cy + r, true);
+      // (cx - r, cy) should be filled.
+      expectPixelFilled(cx - r, cy, true);
+      // (cx, cy - r) should be filled.
+      expectPixelFilled(cx, cy - r, true);
+
+      // (cx + r/SQRT2, cy + r/SQRT2) should be empty.
+      expectPixelFilled((cx + r/SQRT2).toInt(), (cy + r/SQRT2).toInt(), false);
+
+      // (cx - r/SQRT2, cy - r/SQRT2) should be filled.
+      expectPixelFilled((cx - r/SQRT2).toInt(), (cy + r/SQRT2).toInt(), true);
+
+      // (cx + r/SQRT2, cy + r/SQRT2) should be filled.
+      expectPixelFilled((cx - r/SQRT2).toInt(), (cy - r/SQRT2).toInt(), true);
+
+      // (cx - r/SQRT2, cy - r/SQRT2) should be filled.
+      expectPixelFilled((cx + r/SQRT2).toInt(), (cy - r/SQRT2).toInt(), true);
+    });
+
+    // Draw an image to the canvas from an image element.
+    test('drawImage from img element with 3 params', () {
+      var dataUrl = otherCanvas.toDataUrl('image/gif');
+      var img = new ImageElement();
+
+      img.onLoad.listen(expectAsync1((_) {
+        context.drawImage(img, 50, 50);
+
+        expectPixelFilled(50, 50);
+        expectPixelFilled(55, 55);
+        expectPixelFilled(59, 59);
+        expectPixelUnfilled(60, 60);
+        expectPixelUnfilled(0, 0);
+        expectPixelUnfilled(70, 70);
+      }));
+      img.onError.listen((_) {
+        guardAsync(() {
+          fail('URL failed to load.');
+        });
+      });
+      img.src = dataUrl;
+    });
+
+    // Draw an image to the canvas from an image element and scale it.
+    test('drawImage from img element with 5 params', () {
+      var dataUrl = otherCanvas.toDataUrl('image/gif');
+      var img = new ImageElement();
+
+      img.onLoad.listen(expectAsync1((_) {
+        context.drawImageAtScale(img, new Rect(50, 50, 20, 20));
+
+        expectPixelFilled(50, 50);
+        expectPixelFilled(55, 55);
+        expectPixelFilled(59, 59);
+        expectPixelFilled(60, 60);
+        expectPixelFilled(69, 69);
+        expectPixelUnfilled(70, 70);
+        expectPixelUnfilled(0, 0);
+        expectPixelUnfilled(80, 80);
+      }));
+      img.onError.listen((_) {
+        guardAsync(() {
+          fail('URL failed to load.');
+        });
+      });
+      img.src = dataUrl;
+    });
+
+    // Draw an image to the canvas from an image element and scale it.
+    test('drawImage from img element with 9 params', () {
+      otherContext.fillStyle = "blue";
+      otherContext.fillRect(5, 5, 5, 5);
+      var dataUrl = otherCanvas.toDataUrl('image/gif');
+      var img = new ImageElement();
+
+      img.onLoad.listen(expectAsync1((_) {
+        // This will take a 6x6 square from the first canvas from position 2,2
+        // and then scale it to a 20x20 square and place it to the second canvas
+        // at 50,50.
+        context.drawImageAtScale(img, new Rect(50, 50, 20, 20),
+          sourceRect: new Rect(2, 2, 6, 6));
+
+        checkPixel(readPixel(50, 50), [255, 0, 0, 255]);
+        checkPixel(readPixel(55, 55), [255, 0, 0, 255]);
+        checkPixel(readPixel(60, 50), [255, 0, 0, 255]);
+        checkPixel(readPixel(65, 65), [0, 0, 255, 255]);
+        checkPixel(readPixel(69, 69), [0, 0, 255, 255]);
+
+        expectPixelFilled(50, 50);
+        expectPixelFilled(55, 55);
+        expectPixelFilled(59, 59);
+        expectPixelFilled(60, 60);
+        expectPixelFilled(69, 69);
+        expectPixelUnfilled(70, 70);
+        expectPixelUnfilled(0, 0);
+        expectPixelUnfilled(80, 80);
+      }));
+      img.onError.listen((_) {
+        guardAsync(() {
+          fail('URL failed to load.');
+        });
+      });
+      img.src = dataUrl;
+    });
+
+    // These base64 strings are the same video, representing 2 frames of 8x8 red
+    // pixels.
+    // The videos were created with:
+    //   convert -size 8x8 xc:red blank1.jpg
+    //   convert -size 8x8 xc:red blank2.jpg
+    //   avconv -f image2  -i "blank%d.jpg" -c:v libx264 small.mp4
+    //   python -m base64 -e small.mp4
+    //   avconv -i small.mp4 small.webm
+    //   python -m base64 -e small.webm
+    var mp4VideoUrl =
+      'data:video/mp4;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZn'
+      'JlZQAAAsdtZGF0AAACmwYF//+X3EXpvebZSLeWLNgg2SPu73gyNjQgLSBjb3JlIDEyMCByMj'
+      'E1MSBhM2Y0NDA3IC0gSC4yNjQvTVBFRy00IEFWQyBjb2RlYyAtIENvcHlsZWZ0IDIwMDMtMj'
+      'AxMSAtIGh0dHA6Ly93d3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG9wdGlvbnM6IGNhYm'
+      'FjPTEgcmVmPTMgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MToweDExMSBtZT1oZXggc3VibW'
+      'U9NyBwc3k9MSBwc3lfcmQ9MS4wMDowLjAwIG1peGVkX3JlZj0wIG1lX3JhbmdlPTE2IGNocm'
+      '9tYV9tZT0xIHRyZWxsaXM9MSA4eDhkY3Q9MCBjcW09MCBkZWFkem9uZT0yMSwxMSBmYXN0X3'
+      'Bza2lwPTEgY2hyb21hX3FwX29mZnNldD0tMiB0aHJlYWRzPTE4IHNsaWNlZF90aHJlYWRzPT'
+      'AgbnI9MCBkZWNpbWF0ZT0xIGludGVybGFjZWQ9MCBibHVyYXlfY29tcGF0PTAgY29uc3RyYW'
+      'luZWRfaW50cmE9MCBiZnJhbWVzPTMgYl9weXJhbWlkPTAgYl9hZGFwdD0xIGJfYmlhcz0wIG'
+      'RpcmVjdD0xIHdlaWdodGI9MCBvcGVuX2dvcD0xIHdlaWdodHA9MiBrZXlpbnQ9MjUwIGtleW'
+      'ludF9taW49MjUgc2NlbmVjdXQ9NDAgaW50cmFfcmVmcmVzaD0wIHJjX2xvb2thaGVhZD00MC'
+      'ByYz1jcmYgbWJ0cmVlPTEgY3JmPTUxLjAgcWNvbXA9MC42MCBxcG1pbj0wIHFwbWF4PTY5IH'
+      'Fwc3RlcD00IGlwX3JhdGlvPTEuMjUgYXE9MToxLjAwAIAAAAARZYiEB//3aoK5/tP9+8yeuI'
+      'EAAAAHQZoi2P/wgAAAAzxtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAAUAABAAABAA'
+      'AAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAA'
+      'AAAAAAAAAAAAAAAAAAAAAAAAACAAAAGGlvZHMAAAAAEICAgAcAT/////7/AAACUHRyYWsAAA'
+      'BcdGtoZAAAAA8AAAAAAAAAAAAAAAEAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAA'
+      'AAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAACAAAAAgAAAAAACRlZHRzAAAAHGVsc3QAAA'
+      'AAAAAAAQAAAFAAAAABAAEAAAAAAchtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAAAZAAAAAl'
+      'XEAAAAAAAtaGRscgAAAAAAAAAAdmlkZQAAAAAAAAAAAAAAAFZpZGVvSGFuZGxlcgAAAAFzbW'
+      'luZgAAABR2bWhkAAAAAQAAAAAAAAAAAAAAJGRpbmYAAAAcZHJlZgAAAAAAAAABAAAADHVybC'
+      'AAAAABAAABM3N0YmwAAACXc3RzZAAAAAAAAAABAAAAh2F2YzEAAAAAAAAAAQAAAAAAAAAAAA'
+      'AAAAAAAAAACAAIAEgAAABIAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
+      'AAAAAY//8AAAAxYXZjQwFNQAr/4QAYZ01ACuiPyy4C2QAAAwABAAADADIPEiUSAQAGaOvAZS'
+      'yAAAAAGHN0dHMAAAAAAAAAAQAAAAIAAAABAAAAFHN0c3MAAAAAAAAAAQAAAAEAAAAYY3R0cw'
+      'AAAAAAAAABAAAAAgAAAAEAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAEAAAABAAAAHHN0c3oAAA'
+      'AAAAAAAAAAAAIAAAK0AAAACwAAABhzdGNvAAAAAAAAAAIAAAAwAAAC5AAAAGB1ZHRhAAAAWG'
+      '1ldGEAAAAAAAAAIWhkbHIAAAAAAAAAAG1kaXJhcHBsAAAAAAAAAAAAAAAAK2lsc3QAAAAjqX'
+      'RvbwAAABtkYXRhAAAAAQAAAABMYXZmNTMuMjEuMQ==';
+    var webmVideoUrl =
+      'data:video/webm;base64,GkXfowEAAAAAAAAfQoaBAUL3gQFC8oEEQvOBCEKChHdlYm1Ch'
+      '4ECQoWBAhhTgGcBAAAAAAAB/hFNm3RALE27i1OrhBVJqWZTrIHfTbuMU6uEFlSua1OsggEsT'
+      'buMU6uEHFO7a1OsggHk7AEAAAAAAACkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
+      'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
+      'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
+      'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVSalmAQAAAAAAAEEq17GDD0JATYCLTGF2ZjUzL'
+      'jIxLjFXQYtMYXZmNTMuMjEuMXOkkJatuHwTJ7cvFLSzBSmxbp5EiYhAVAAAAAAAABZUrmsBA'
+      'AAAAAAAR64BAAAAAAAAPteBAXPFgQGcgQAitZyDdW5khoVWX1ZQOIOBASPjg4QCYloA4AEAA'
+      'AAAAAASsIEIuoEIVLCBCFS6gQhUsoEDH0O2dQEAAAAAAABZ54EAo72BAACA8AIAnQEqCAAIA'
+      'ABHCIWFiIWEiAICAnWqA/gD+gINTRgA/v0hRf/kb+PnRv/I4//8WE8DijI//FRAo5WBACgAs'
+      'QEAARAQABgAGFgv9AAIAAAcU7trAQAAAAAAAA67jLOBALeH94EB8YIBfw==';
+
+//    test('drawImage from video element with 3 params', () {
+//      var video = new VideoElement();
+//
+//      video.onLoadedData.listen(expectAsync1((_) {
+//        context.drawImage(video, 50, 50);
+//
+//        expectPixelFilled(50, 50);
+//        expectPixelFilled(54, 54);
+//        expectPixelFilled(57, 57);
+//        expectPixelUnfilled(58, 58);
+//        expectPixelUnfilled(0, 0);
+//        expectPixelUnfilled(70, 70);
+//      }));
+//      video.onError.listen((_) {
+//        guardAsync(() {
+//          fail('URL failed to load.');
+//        });
+//      });
+//
+//      if(video.canPlayType('video/webm; codecs="vp8.0, vorbis"', '') != '') {
+//        video.src = webmVideoUrl;
+//      } else if(video.canPlayType('video/mp4; codecs="avc1.4D401E, mp4a.40.2"',
+//            null) != '') {
+//        video.src = mp4VideoUrl;
+//      } else {
+//        logMessage('Video is not supported on this system.');
+//      }
+//    });
+//
+//    test('drawImage from video element with 5 params', () {
+//      var video = new VideoElement();
+//
+//      video.onLoadedData.listen(expectAsync1((_) {
+//        context.drawImageAtScale(video, new Rect(50, 50, 20, 20));
+//
+//        expectPixelFilled(50, 50);
+//        expectPixelFilled(55, 55);
+//        expectPixelFilled(59, 59);
+//        expectPixelFilled(60, 60);
+//        expectPixelFilled(69, 69);
+//        expectPixelUnfilled(70, 70);
+//        expectPixelUnfilled(0, 0);
+//        expectPixelUnfilled(80, 80);
+//      }));
+//      video.onError.listen((_) {
+//        guardAsync(() {
+//          fail('URL failed to load.');
+//        });
+//      });
+//
+//      if(video.canPlayType('video/webm; codecs="vp8.0, vorbis"', '') != '') {
+//        video.src = webmVideoUrl;
+//      } else if(video.canPlayType('video/mp4; codecs="avc1.4D401E, mp4a.40.2"',
+//            null) != '') {
+//        video.src = mp4VideoUrl;
+//      } else {
+//        // TODO(amouravski): Better fallback?
+//        logMessage('Video is not supported on this system.');
+//      }
+//    });
+//
+//    test('drawImage from video element with 9 params', () {
+//      var video = new VideoElement();
+//
+//      video.onLoadedData.listen(expectAsync1((_) {
+//        context.drawImageAtScale(video, new Rect(50, 50, 20, 20),
+//          sourceRect: new Rect(2, 2, 6, 6));
+//
+//        expectPixelFilled(50, 50);
+//        expectPixelFilled(55, 55);
+//        expectPixelFilled(59, 59);
+//        expectPixelFilled(60, 60);
+//        expectPixelFilled(69, 69);
+//        expectPixelUnfilled(70, 70);
+//        expectPixelUnfilled(0, 0);
+//        expectPixelUnfilled(80, 80);
+//      }));
+//      video.onError.listen((_) {
+//        guardAsync(() {
+//          fail('URL failed to load.');
+//        });
+//      });
+//
+//      if(video.canPlayType('video/webm; codecs="vp8.0, vorbis"', '') != '') {
+//        video.src = webmVideoUrl;
+//      } else if(video.canPlayType('video/mp4; codecs="avc1.4D401E, mp4a.40.2"',
+//            null) != '') {
+//        video.src = mp4VideoUrl;
+//      } else {
+//        // TODO(amouravski): Better fallback?
+//        logMessage('Video is not supported on this system.');
+//      }
+//    });
+
+    test('drawImage from canvas element with 3 params', () {
+      // Draw an image to the canvas from a canvas element.
+      context.drawImage(otherCanvas, 50, 50);
+
+      expectPixelFilled(50, 50);
+      expectPixelFilled(55, 55);
+      expectPixelFilled(59, 59);
+      expectPixelUnfilled(60, 60);
+      expectPixelUnfilled(0, 0);
+      expectPixelUnfilled(70, 70);
+    });
+    test('drawImage from canvas element with 5 params', () {
+      // Draw an image to the canvas from a canvas element.
+      context.drawImageAtScale(otherCanvas, new Rect(50, 50, 20, 20));
+
+      expectPixelFilled(50, 50);
+      expectPixelFilled(55, 55);
+      expectPixelFilled(59, 59);
+      expectPixelFilled(60, 60);
+      expectPixelFilled(69, 69);
+      expectPixelUnfilled(70, 70);
+      expectPixelUnfilled(0, 0);
+      expectPixelUnfilled(80, 80);
+    });
+    test('drawImage from canvas element with 9 params', () {
+      // Draw an image to the canvas from a canvas element.
+      otherContext.fillStyle = "blue";
+      otherContext.fillRect(5, 5, 5, 5);
+      context.drawImageAtScale(otherCanvas, new Rect(50, 50, 20, 20),
+          sourceRect: new Rect(2, 2, 6, 6));
+
+      checkPixel(readPixel(50, 50), [255, 0, 0, 255]);
+      checkPixel(readPixel(55, 55), [255, 0, 0, 255]);
+      checkPixel(readPixel(60, 50), [255, 0, 0, 255]);
+      checkPixel(readPixel(65, 65), [0, 0, 255, 255]);
+      checkPixel(readPixel(69, 69), [0, 0, 255, 255]);
+      expectPixelFilled(50, 50);
+      expectPixelFilled(55, 55);
+      expectPixelFilled(59, 59);
+      expectPixelFilled(60, 60);
+      expectPixelFilled(69, 69);
+      expectPixelUnfilled(70, 70);
+      expectPixelUnfilled(0, 0);
+      expectPixelUnfilled(80, 80);
+    });
   });
 }
diff --git a/tests/html/client_rect_test.dart b/tests/html/client_rect_test.dart
index b688908..658449a 100644
--- a/tests/html/client_rect_test.dart
+++ b/tests/html/client_rect_test.dart
@@ -5,8 +5,8 @@
 
 main() {
 
-  var isClientRectList =
-      predicate((x) => x is List<ClientRect>, 'is a List<ClientRect>');
+  var isRectList =
+      predicate((x) => x is List<Rect>, 'is a List<Rect>');
 
   insertTestDiv() {
     var element = new Element.tag('div');
@@ -25,6 +25,6 @@
     insertTestDiv();
     var range = new Range();
     var rects = range.getClientRects();
-    expect(rects, isClientRectList);
+    expect(rects, isRectList);
   });
 }
diff --git a/tests/html/dromaeo_smoke_test.dart b/tests/html/dromaeo_smoke_test.dart
index 0463eff..fd92124 100644
--- a/tests/html/dromaeo_smoke_test.dart
+++ b/tests/html/dromaeo_smoke_test.dart
@@ -45,8 +45,8 @@
   originalTest.main();
 
   test('dromaeo runs', () {
-    new Timer.repeating(new Duration(milliseconds: 500),
-                        expectAsyncUntil1((timer) {
+    new Timer.periodic(new Duration(milliseconds: 500),
+                       expectAsyncUntil1((timer) {
       if (document.query('.alldone') != null) {
         timer.cancel();
         isDone = true;
diff --git a/tests/html/element_classes_test.dart b/tests/html/element_classes_test.dart
index 65fc38f..0af9f3e 100644
--- a/tests/html/element_classes_test.dart
+++ b/tests/html/element_classes_test.dart
@@ -144,20 +144,20 @@
 
   test('isSubsetOf', () {
     final classes = makeClassSet();
-    expect(classes.isSubsetOf(['foo', 'bar', 'baz']), isTrue);
-    expect(classes.isSubsetOf(['foo', 'bar', 'baz', 'qux']), isTrue);
-    expect(classes.isSubsetOf(['foo', 'bar', 'qux']), isFalse);
+    expect(classes.isSubsetOf(['foo', 'bar', 'baz'].toSet()), isTrue);
+    expect(classes.isSubsetOf(['foo', 'bar', 'baz', 'qux'].toSet()), isTrue);
+    expect(classes.isSubsetOf(['foo', 'bar', 'qux'].toSet()), isFalse);
   });
 
   test('containsAll', () {
     final classes = makeClassSet();
-    expect(classes.containsAll(['foo', 'baz']), isTrue);
-    expect(classes.containsAll(['foo', 'qux']), isFalse);
+    expect(classes.containsAll(['foo', 'baz'].toSet()), isTrue);
+    expect(classes.containsAll(['foo', 'qux'].toSet()), isFalse);
   });
 
   test('intersection', () {
     final classes = makeClassSet();
-    expect(classes.intersection(['foo', 'qux', 'baz']),
+    expect(classes.intersection(['foo', 'qux', 'baz'].toSet()),
         unorderedEquals(['foo', 'baz']));
   });
 
diff --git a/tests/html/element_test.dart b/tests/html/element_test.dart
index a255c68..7fc6bfe 100644
--- a/tests/html/element_test.dart
+++ b/tests/html/element_test.dart
@@ -9,7 +9,7 @@
 import 'dart:html';
 import 'dart:svg' as svg;
 
-expectLargeRect(ClientRect rect) {
+expectLargeRect(Rect rect) {
   expect(rect.top, 0);
   expect(rect.left, 0);
   expect(rect.width, greaterThan(100));
@@ -60,10 +60,10 @@
       container.children.add(element);
       document.body.children.add(container);
 
-      expect(element.clientWidth, greaterThan(100));
-      expect(element.clientHeight, greaterThan(100));
-      expect(element.offsetWidth, greaterThan(100));
-      expect(element.offsetHeight, greaterThan(100));
+      expect(element.client.width, greaterThan(100));
+      expect(element.client.height, greaterThan(100));
+      expect(element.offset.width, greaterThan(100));
+      expect(element.offset.height, greaterThan(100));
       expect(element.scrollWidth, greaterThan(100));
       expect(element.scrollHeight, greaterThan(100));
       expect(element.getBoundingClientRect().left, 8);
@@ -439,12 +439,6 @@
       expect(el.children.last, isHRElement);
     });
 
-    test('addLast', () {
-      var el = makeElement();
-      el.children.addLast(new Element.tag('hr'));
-      expect(el.children.last, isHRElement);
-    });
-
     test('iterator', () {
       var els = [];
       var el = makeElementWithChildren();
@@ -485,9 +479,9 @@
       expect(el.children.length, 1);
     });
 
-    test('getRange', () {
+    test('sublist', () {
       var el = makeElementWithChildren();
-      expect(el.children.getRange(1, 1), isElementList);
+      expect(el.children.sublist(1, 2), isElementList);
     });
   });
 
@@ -588,14 +582,12 @@
       expect(els[2], isHRElement);
     });
 
-    test('getRange', () {
-      expect(getQueryAll().getRange(1, 1) is List<Element>, isTrue);
+    test('sublist', () {
+      expect(getQueryAll().sublist(1, 2) is List<Element>, isTrue);
     });
 
     testUnsupported('[]=', () => getQueryAll()[1] = new Element.tag('br'));
     testUnsupported('add', () => getQueryAll().add(new Element.tag('br')));
-    testUnsupported('addLast', () =>
-        getQueryAll().addLast(new Element.tag('br')));
 
     testUnsupported('addAll', () {
       getQueryAll().addAll([
@@ -640,8 +632,8 @@
       expect(filtered, isElementIterable);
     });
 
-    test('getRange', () {
-      var range = makeElList().getRange(1, 2);
+    test('sublist', () {
+      var range = makeElList().sublist(1, 3);
       expect(range, isElementList);
       expect(range[0], isImageElement);
       expect(range[1], isInputElement);
diff --git a/tests/html/event_test.dart b/tests/html/event_test.dart
index c4c4609..c196e64 100644
--- a/tests/html/event_test.dart
+++ b/tests/html/event_test.dart
@@ -115,12 +115,12 @@
           metaKey: true, relatedTarget: new Element.tag('div')),
       (ev) {
     expect(ev.detail, 1);
-    expect(ev.screenX, 2);
-    expect(ev.screenYi, 3);
-    expect(ev.clientX, 4);
-    expect(ev.clientY, 5);
-    expect(ev.offsetX, 4);  // Same as clientX.
-    expect(ev.offsetY, 5);  // Same as clientY.
+    expect(ev.screen.x, 2);
+    expect(ev.screen.y, 3);
+    expect(ev.client.x, 4);
+    expect(ev.client.y, 5);
+    expect(ev.offset.x, 4);  // Same as clientX.
+    expect(ev.offset.y, 5);  // Same as clientY.
     expect(ev.button, 6);
     expect(ev.ctrlKey, isTrue);
     expect(ev.altKey, isTrue);
@@ -212,10 +212,10 @@
     // wheelDelta* properties are multiplied by 120 for some reason
     expect(ev.wheelDeltaX, 120);
     expect(ev.wheelDeltaY, 240);
-    expect(ev.screenX, 3);
-    expect(ev.screenY, 4);
-    expect(ev.clientX, 5);
-    expect(ev.clientY, 6);
+    expect(ev.screen.x, 3);
+    expect(ev.screen.y, 4);
+    expect(ev.client.x, 5);
+    expect(ev.client.y, 6);
     expect(ev.ctrlKey, isTrue);
     expect(ev.altKey, isTrue);
     expect(ev.shiftKey, isTrue);
diff --git a/tests/html/fileapi_test.dart b/tests/html/fileapi_test.dart
index 079197f..681750c 100644
--- a/tests/html/fileapi_test.dart
+++ b/tests/html/fileapi_test.dart
@@ -2,11 +2,12 @@
 import '../../pkg/unittest/lib/unittest.dart';
 import '../../pkg/unittest/lib/html_individual_config.dart';
 import 'dart:html';
+import 'dart:async';
 
-void fail(message) {
-  guardAsync(() {
-    expect(false, isTrue, reason: message);
-  });
+class FileAndDir {
+  FileEntry file;
+  DirectoryEntry dir;
+  FileAndDir(this.file, this.dir);
 }
 
 FileSystem fs;
@@ -21,20 +22,17 @@
   });
 
   getFileSystem() {
-    window.requestFileSystem(Window.TEMPORARY, 100,
-        expectAsync1((FileSystem fileSystem) {
-          fs = fileSystem;
-        }),
-        (e) {
-          fail('Got file error: ${e.code}');
-        });
+    return window.requestFileSystem(Window.TEMPORARY, 100)
+      .then((FileSystem fileSystem) {
+        fs = fileSystem;
+      });
   }
 
   group('unsupported_throws', () {
     test('requestFileSystem', () {
       var expectation = FileSystem.supported ? returnsNormally : throws;
       expect(() {
-        window.requestFileSystem(Window.TEMPORARY, 100, (_) {}, (_) {});
+        window.requestFileSystem(Window.TEMPORARY, 100);
       }, expectation);
     });
   });
@@ -44,27 +42,21 @@
       test('getFileSystem', getFileSystem);
 
       test('directoryDoesntExist', () {
-        fs.root.getDirectory(
+        return fs.root.getDirectory(
             'directory2',
-            options: {},
-            successCallback: (e) {
-              fail('Should not be reached');
-            },
-            errorCallback: expectAsync1((FileError e) {
-              expect(e.code, equals(FileError.NOT_FOUND_ERR));
-            }));
+            options: {})
+              .catchError((e) {
+                expect(e.error.code, equals(FileError.NOT_FOUND_ERR));
+              }, test: (e) => e is FileError);
         });
 
       test('directoryCreate', () {
-        fs.root.getDirectory(
+        return fs.root.getDirectory(
             'directory3',
-            options: {'create': true},
-            successCallback: expectAsync1((DirectoryEntry e) {
-              expect(e.name, equals('directory3'));
-            }),
-            errorCallback: (e) {
-              fail('Got file error: ${e.code}');
-            });
+            options: {'create': true})
+              .then((DirectoryEntry e) {
+                expect(e.name, equals('directory3'));
+              });
         });
     }
   });
@@ -74,35 +66,139 @@
       test('getFileSystem', getFileSystem);
 
       test('fileDoesntExist', () {
-        fs.root.getFile(
+        return fs.root.getFile(
             'file2',
-            options: {},
-            successCallback: (e) {
-              fail('Should not be reached');
-            },
-            errorCallback: expectAsync1((FileError e) {
-              expect(e.code, equals(FileError.NOT_FOUND_ERR));
-            }));
+            options: {})
+          .catchError((e) {
+            expect(e.error.code, equals(FileError.NOT_FOUND_ERR));
+          }, test: (e) => e is FileError);
       });
 
       test('fileCreate', () {
-        fs.root.getFile(
+        return fs.root.getFile(
             'file4',
-            options: {'create': true},
-            successCallback: expectAsync1((FileEntry e) {
-              expect(e.name, equals('file4'));
-              expect(e.isFile, isTrue);
+            options: {'create': true})
+          .then((FileEntry e) {
+            expect(e.name, equals('file4'));
+            expect(e.isFile, isTrue);
+            return e.getMetadata();
+          }).then((Metadata metadata) {
+            var changeTime = metadata.modificationTime;
+            // Upped because our Windows buildbots can sometimes be particularly
+            // slow.
+            expect(new DateTime.now().difference(changeTime).inMinutes,
+                lessThan(4));
+            expect(metadata.size, equals(0));
+          });
+        });
+    }
+  });
 
-              e.getMetadata(expectAsync1((Metadata metadata) {
-                var changeTime = metadata.modificationTime;
-                expect(new DateTime.now().difference(changeTime).inSeconds,
-                  lessThan(60));
-              }));
-            }),
-            errorCallback: (e) {
-              fail('Got file error: ${e.code}');
+  // Do the boilerplate to get several files and directories created to then
+  // test the functions that use those items.
+  Future doDirSetup() {
+    return fs.root.getFile(
+      'file4',
+      options: {'create': true})
+        .then((FileEntry file) {
+          return fs.root.getDirectory(
+              'directory3',
+              options: {'create': true})
+            .then((DirectoryEntry dir) {
+              return new Future.immediate(new FileAndDir(file, dir));
             });
         });
+  }
+
+  group('directoryReader', () {
+    if (FileSystem.supported) {
+      test('getFileSystem', getFileSystem);
+
+      test('readEntries', () {
+        return doDirSetup()
+          .then((fileAndDir) {
+            var reader = fileAndDir.dir.createReader();
+            return reader.readEntries();
+          }).then((entries) {
+            expect(entries is List, true);
+          });
+      });
+    }
+  });
+
+  group('entry', () {
+    if (FileSystem.supported) {
+      test('getFileSystem', getFileSystem);
+
+      test('copyTo', () {
+        return doDirSetup()
+          .then((fileAndDir) {
+            return fileAndDir.file.copyTo(fileAndDir.dir, name: 'copiedFile');
+          }).then((entry) {
+            expect(entry.isFile, true);
+            expect(entry.name, 'copiedFile');
+          });
+      });
+
+      test('getParent', () {
+        return doDirSetup()
+          .then((fileAndDir) {
+             return fileAndDir.file.getParent();
+          }).then((entry) {
+            expect(entry.name, '');
+            expect(entry.isFile, false);
+          });
+      });
+
+      test('moveTo', () {
+        return doDirSetup()
+          .then((fileAndDir) {
+            return fileAndDir.file.moveTo(fileAndDir.dir, name: 'movedFile');
+          }).then((entry) {
+            expect(entry.name, 'movedFile');
+            expect(entry.fullPath, '/directory3/movedFile');
+            return fs.root.getFile('file4', options: {'create': false});
+          }).catchError((e) {
+            expect(e.error.code, equals(FileError.NOT_FOUND_ERR));
+          }, test: (e) => e is FileError);
+      });
+
+      test('remove', () {
+        return doDirSetup()
+          .then((fileAndDir) {
+            return fileAndDir.file.remove().then((_) {});
+          });
+      });
+    }
+  });
+
+  group('fileEntry', () {
+    if (FileSystem.supported) {
+      test('getFileSystem', getFileSystem);
+
+      test('createWriter', () {
+        return doDirSetup()
+          .then((fileAndDir) {
+            return fileAndDir.file.createWriter();
+          }).then((writer) {
+            expect(writer.position, 0);
+            expect(writer.readyState, FileWriter.INIT);
+            expect(writer.length, 0);
+          });
+      });
+
+      test('file', () {
+        return doDirSetup()
+          .then((fileAndDir) {
+            return fileAndDir.file.file()
+              .then((fileObj) {
+                expect(fileObj.name, fileAndDir.file.name);
+                expect(fileObj.relativePath, '');
+                expect(new DateTime.now().difference(
+                    fileObj.lastModifiedDate).inSeconds, lessThan(60));
+              });
+          });
+      });
     }
   });
 }
diff --git a/tests/html/html.status b/tests/html/html.status
index 773dffa..8c14104 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -14,9 +14,6 @@
 *layout_test: Skip
 
 [ $runtime == chrome ]
-input_element_test/supported_date: Pass, Fail      # Chrome stable does not support this input type.
-speechrecognition_test/supported: Pass, Fail       # Chrome stable does not support it.
-speechrecognition_test/types: Pass, Fail
 touchevent_test/supported: Fail
 
 [$runtime == drt || $runtime == dartium || $runtime == chrome]
@@ -47,10 +44,7 @@
 dromaeo_smoke_test: Skip #TODO(efortuna): investigating.
 element_test/click: Fail                # IE does not support firing this event.
 history_test/history: Pass, Fail # issue 8183
-inner_frame_test: Skip
 isolates_test: Skip
-measurement_test: Fail, Pass
-messageevent_test: Fail
 microtask_test: Fail, Pass # Appears to be flaky
 native_gc_test: Fail, Pass # BUG(7774): Untriaged.
 serialized_script_value_test: Fail
@@ -73,7 +67,7 @@
 element_types_test/supported_shadow: Fail
 fileapi_test/supported: Fail
 history_test/supported_HashChangeEvent: Fail
-indexeddb_5_test/supportsDatabaseNames: Fail
+indexeddb_1_test/supportsDatabaseNames: Fail
 input_element_test/supported_date: Fail
 input_element_test/supported_datetime-local: Fail
 input_element_test/supported_month: Fail
@@ -108,10 +102,8 @@
 element_test/click: Fail                # IE does not support firing this event.
 element_test/matches: Fail # IE9 does not support matches
 form_element_test: Fail # Issue 4793.
-inner_frame_test: Skip # Issue 5727 (timeout)
 isolates_test: Skip         # BUG(4016)
 localstorage_test: Fail
-messageevent_test: Fail
 microtask_test: Pass, Fail # http://dartbug.com/8300
 postmessage_structured_test: Skip   # BUG(5685): times out.
 serialized_script_value_test: Fail
@@ -140,7 +132,7 @@
 history_test/supported_HashChangeEvent: Fail
 history_test/supported_state: Fail
 indexeddb_1_test/supported: Fail
-indexeddb_5_test/supportsDatabaseNames: Fail
+indexeddb_1_test/supportsDatabaseNames: Fail
 input_element_test/supported_date: Fail
 input_element_test/supported_datetime-local: Fail
 input_element_test/supported_email: Fail
@@ -211,6 +203,7 @@
 input_element_test/supported_week: Fail, Crash
 webgl_1_test: Pass, Fail # Issue 8219
 wheelevent_test: Fail # Issue: 7414
+xhr_test/xhr_requestBlob: Fail # Issue: 9178 Safari doesn't support Blob responses.
 
 # Safari Feature support statuses-
 # All changes should be accompanied by platform support annotation changes.
@@ -219,7 +212,7 @@
 element_types_test/supported_shadow: Fail
 fileapi_test/supported: Fail
 indexeddb_1_test/supported: Fail
-indexeddb_5_test/supportsDatabaseNames: Fail
+indexeddb_1_test/supportsDatabaseNames: Fail
 input_element_test/supported_date: Fail
 input_element_test/supported_datetime-local: Fail
 media_stream_test/supported_MediaStreamEvent: Fail
@@ -253,7 +246,6 @@
 fileapi_test: Skip # Timeout.
 form_data_test: Fail # Issue: 7413
 htmlelement_test: Fail
-inner_frame_test: Skip # Timeout.
 isolates_test: Skip # Timeout.
 js_interop_3_test: Skip # Timeout.
 js_interop_4_test: Skip # Timeout.
@@ -269,7 +261,7 @@
 css_test/supported_DomPoint: Fail
 document_test/supports_cssCanvasContext: Fail
 indexeddb_1_test/supported: Fail
-indexeddb_5_test/supportsDatabaseNames: Fail
+indexeddb_1_test/supportsDatabaseNames: Fail
 mutationobserver_test/supported: Fail
 notifications_test/supported: Fail
 performance_api_test/supported: Fail
@@ -283,8 +275,8 @@
 audiocontext_test: Fail      # FF only has Audio element
 dart_object_local_storage_test: Skip  # sessionStorage NS_ERROR_DOM_NOT_SUPPORTED_ERR
 dromaeo_smoke_test: Pass, Fail # Issue: 8257
-inner_frame_test: Skip
 webgl_1_test: Pass, Fail   # Issue 8219
+postmessage_structured_test: Fail
 
 # FireFox Feature support statuses-
 # All changes should be accompanied by platform support annotation changes.
@@ -300,7 +292,7 @@
 element_types_test/supported_shadow: Fail
 element_types_test/supported_track: Fail
 fileapi_test/supported: Fail
-indexeddb_5_test/supportsDatabaseNames: Fail
+indexeddb_1_test/supportsDatabaseNames: Fail
 input_element_test/supported_date: Fail
 input_element_test/supported_datetime-local: Fail
 input_element_test/supported_month: Fail
@@ -337,18 +329,9 @@
 [ $compiler == dart2js && ($runtime == drt || $runtime == chrome || $runtime == ff || $runtime == safari) ]
 isolates_test: Skip   # Timeout because leg does not support web workers.
 
-[ $compiler == dart2js && ($runtime == ie9 || $runtime == ie10 || $runtime == safari || $runtime == ff || $runtime == chrome || $runtime == opera || $runtime == drt)]
-element_test/queryAll: Fail # dartbug.com/8496: missing substitution on native classes
-node_test/_NodeList: Fail # dartbug.com/8496: missing substitution on native classes
-node_test/nodes: Fail # dartbug.com/8496: missing substitution on native classes
-typed_arrays_1_test/arrays: Fail # dartbug.com/8496: missing substitution on native classes
-typed_arrays_1_test/supported: Fail # dartbug.com/8496: missing substitution on native classes
-
-[ $compiler == dart2js && $runtime == ff ]
-inner_frame_test: Skip # Timeout
 
 [ $compiler == dart2js && $runtime == drt && $unchecked ]
-indexeddb_5_test/functional: Fail, Pass # http://dartbug.com/8851
+#indexeddb_5_test/functional: Fail, Pass # http://dartbug.com/8851
 
 [ $compiler == dart2js && $csp && ($runtime == drt || $runtime == safari || $runtime == ff || $runtime == chrome) ]
 js_interop_1_test: Skip            # Test cannot run under CSP restrictions (times out).
diff --git a/tests/html/indexeddb_1_test.dart b/tests/html/indexeddb_1_test.dart
index 536253b..3505c2e 100644
--- a/tests/html/indexeddb_1_test.dart
+++ b/tests/html/indexeddb_1_test.dart
@@ -4,7 +4,6 @@
 import 'dart:async';
 import 'dart:html' as html;
 import 'dart:indexed_db' as idb;
-import 'utils.dart';
 
 const String DB_NAME = 'Test';
 const String STORE_NAME = 'TEST';
@@ -95,19 +94,19 @@
 };
 
 tests_dynamic() {
-  futureTest('test1', testReadWrite(123, 'Hoot!', equals('Hoot!')));
-  futureTest('test2', testReadWrite(123, 12345, equals(12345)));
-  futureTest('test3', testReadWrite(123, [1, 2, 3], equals([1, 2, 3])));
-  futureTest('test4', testReadWrite(123, [2, 3, 4], equals([2, 3, 4])));
-  futureTest('test4', testReadWrite(123, false, equals(false)));
+  test('test1', testReadWrite(123, 'Hoot!', equals('Hoot!')));
+  test('test2', testReadWrite(123, 12345, equals(12345)));
+  test('test3', testReadWrite(123, [1, 2, 3], equals([1, 2, 3])));
+  test('test4', testReadWrite(123, [2, 3, 4], equals([2, 3, 4])));
+  test('test4', testReadWrite(123, false, equals(false)));
 }
 
 tests_typed() {
-  futureTest('test1', testReadWriteTyped(123, 'Hoot!', equals('Hoot!')));
-  futureTest('test2', testReadWriteTyped(123, 12345, equals(12345)));
-  futureTest('test3', testReadWriteTyped(123, [1, 2, 3], equals([1, 2, 3])));
-  futureTest('test4', testReadWriteTyped(123, [2, 3, 4], equals([2, 3, 4])));
-  futureTest('test4', testReadWriteTyped(123, false, equals(false)));
+  test('test1', testReadWriteTyped(123, 'Hoot!', equals('Hoot!')));
+  test('test2', testReadWriteTyped(123, 12345, equals(12345)));
+  test('test3', testReadWriteTyped(123, [1, 2, 3], equals([1, 2, 3])));
+  test('test4', testReadWriteTyped(123, [2, 3, 4], equals([2, 3, 4])));
+  test('test4', testReadWriteTyped(123, false, equals(false)));
 }
 
 main() {
@@ -122,6 +121,12 @@
     });
   });
 
+  group('supportsDatabaseNames', () {
+    test('supported', () {
+      expect(html.window.indexedDB.supportsDatabaseNames, isTrue);
+    });
+  });
+
   group('functional', () {
     test('throws when unsupported', () {
       var expectation = idb.IdbFactory.supported ? returnsNormally : throws;
@@ -134,7 +139,7 @@
 
     // Don't bother with these tests if it's unsupported.
     if (idb.IdbFactory.supported) {
-      futureTest('upgrade', testUpgrade);
+      test('upgrade', testUpgrade);
       tests_dynamic();
       tests_typed();
     }
diff --git a/tests/html/indexeddb_2_test.dart b/tests/html/indexeddb_2_test.dart
index 2ec96a5..8faf23d 100644
--- a/tests/html/indexeddb_2_test.dart
+++ b/tests/html/indexeddb_2_test.dart
@@ -64,7 +64,7 @@
   var cyclic_list = [1, 2, 3];
   cyclic_list[1] = cyclic_list;
 
-  go(name, data) => futureTest(name,
+  go(name, data) => test(name,
     () => testReadWrite(123, data, verifyGraph));
 
   test('test_verifyGraph', () {
diff --git a/tests/html/indexeddb_3_test.dart b/tests/html/indexeddb_3_test.dart
index 486da88..7b0b36c 100644
--- a/tests/html/indexeddb_3_test.dart
+++ b/tests/html/indexeddb_3_test.dart
@@ -4,7 +4,6 @@
 import 'dart:async';
 import 'dart:html' as html;
 import 'dart:indexed_db';
-import 'utils.dart';
 
 // Read with cursor.
 
@@ -100,14 +99,14 @@
   // Support is tested in indexeddb_1_test
   if (IdbFactory.supported) {
     var db;
-    futureTest('prepare', () {
+    test('prepare', () {
       return setupDb().then((result) { db = result; });
     });
-    futureTest('readAll1', () {
+    test('readAll1', () {
       return readAllViaCursor(db);
     });
 
-    futureTest('readAll2', () {
+    test('readAll2', () {
       return readAllReversedViaCursor(db);
     });
   }
diff --git a/tests/html/indexeddb_4_test.dart b/tests/html/indexeddb_4_test.dart
index e331734..8cfd420 100644
--- a/tests/html/indexeddb_4_test.dart
+++ b/tests/html/indexeddb_4_test.dart
@@ -4,7 +4,6 @@
 import 'dart:async';
 import 'dart:html' as html;
 import 'dart:indexed_db';
-import 'utils.dart';
 
 // Test for KeyRange and Cursor.
 
@@ -82,40 +81,40 @@
   // Support is tested in indexeddb_1_test
   if (IdbFactory.supported) {
     var db;
-    futureTest('prepare', () {
+    test('prepare', () {
       return setupDb().then((result) {
           db = result;
         });
     });
 
-    futureTest('only1', () => testRange(db, new KeyRange.only(55), 55, 55));
+    test('only1', () => testRange(db, new KeyRange.only(55), 55, 55));
 
-    futureTest('only1', () => testRange(db, new KeyRange.only(55), 55, 55));
-    futureTest('only2', () => testRange(db, new KeyRange.only(100), null, null));
-    futureTest('only3', () => testRange(db, new KeyRange.only(-1), null, null));
+    test('only1', () => testRange(db, new KeyRange.only(55), 55, 55));
+    test('only2', () => testRange(db, new KeyRange.only(100), null, null));
+    test('only3', () => testRange(db, new KeyRange.only(-1), null, null));
 
-    futureTest('lower1', () =>
+    test('lower1', () =>
         testRange(db, new KeyRange.lowerBound(40), 40, 99));
     // OPTIONALS lower2() => testRange(db, new KeyRange.lowerBound(40, open: true), 41, 99);
-    futureTest('lower2', () =>
+    test('lower2', () =>
         testRange(db, new KeyRange.lowerBound(40, true), 41, 99));
     // OPTIONALS lower3() => testRange(db, new KeyRange.lowerBound(40, open: false), 40, 99);
-    futureTest('lower3', () =>
+    test('lower3', () =>
         testRange(db, new KeyRange.lowerBound(40, false), 40, 99));
 
-    futureTest('upper1', () =>
+    test('upper1', () =>
         testRange(db, new KeyRange.upperBound(40), 0, 40));
     // OPTIONALS upper2() => testRange(db, new KeyRange.upperBound(40, open: true), 0, 39);
-    futureTest('upper2', () =>
+    test('upper2', () =>
         testRange(db, new KeyRange.upperBound(40, true), 0, 39));
     // upper3() => testRange(db, new KeyRange.upperBound(40, open: false), 0, 40);
-    futureTest('upper3', () =>
+    test('upper3', () =>
         testRange(db, new KeyRange.upperBound(40, false), 0, 40));
 
-    futureTest('bound1', () =>
+    test('bound1', () =>
         testRange(db, new KeyRange.bound(20, 30), 20, 30));
 
-    futureTest('bound2', () =>
+    test('bound2', () =>
         testRange(db, new KeyRange.bound(-100, 200), 0, 99));
 
     bound3() =>
diff --git a/tests/html/indexeddb_5_test.dart b/tests/html/indexeddb_5_test.dart
index 6b58ed0..826b9d18 100644
--- a/tests/html/indexeddb_5_test.dart
+++ b/tests/html/indexeddb_5_test.dart
@@ -1,192 +1,183 @@
 library IndexedDB1Test;
 import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import '../../pkg/unittest/lib/html_config.dart';
 import 'dart:async';
 import 'dart:html' as html;
 import 'dart:indexed_db' as idb;
-import 'utils.dart';
 
 main() {
-  useHtmlIndividualConfiguration();
-
-  group('supportsDatabaseNames', () {
-    test('supported', () {
-      expect(html.window.indexedDB.supportsDatabaseNames, isTrue);
-    });
-  });
+  useHtmlConfiguration();
 
   if (!idb.IdbFactory.supported) {
     return;
   }
 
-  group('functional', () {
-    var dbName = 'test_db';
-    var storeName = 'test_store';
-    var indexName = 'name_index';
-    var db;
+  var dbName = 'test_db_5';
+  var storeName = 'test_store';
+  var indexName = 'name_index';
+  var db;
 
-    futureTest('init', () {
-      return html.window.indexedDB.deleteDatabase(dbName).then((_) {
-        return html.window.indexedDB.open(dbName, version: 1,
-          onUpgradeNeeded: (e) {
-            var db = e.target.result;
-            var objectStore = db.createObjectStore(storeName,
-                autoIncrement: true);
-            var index = objectStore.createIndex(indexName, 'name_index',
-                unique: false);
-          });
-      }).then((database) {
-        db = database;
-      });
-    });
-
-    if (html.window.indexedDB.supportsDatabaseNames) {
-      futureTest('getDatabaseNames', () {
-        return html.window.indexedDB.getDatabaseNames().then((names) {
-          expect(names.contains(dbName), isTrue);
+  test('init', () {
+    return html.window.indexedDB.deleteDatabase(dbName).then((_) {
+      return html.window.indexedDB.open(dbName, version: 1,
+        onUpgradeNeeded: (e) {
+          var db = e.target.result;
+          var objectStore = db.createObjectStore(storeName,
+              autoIncrement: true);
+          var index = objectStore.createIndex(indexName, 'name_index',
+              unique: false);
         });
-      });
-    }
+    }).then((database) {
+      db = database;
+    });
+  });
 
-    var value = {'name_index': 'one', 'value': 'add_value'};
-    futureTest('add/delete', () {
-      var transaction = db.transaction([storeName], 'readwrite');
-      var key;
-      return transaction.objectStore(storeName).add(value).then((addedKey) {
-        key = addedKey;
-      }).then((_) {
-        return transaction.completed;
-      }).then((_) {
-        transaction = db.transaction([storeName], 'readonly');
-        return transaction.objectStore(storeName).getObject(key);
-      }).then((readValue) {
-        expect(readValue['value'], value['value']);
-        return transaction.completed;
-      }).then((_) {
-        transaction = db.transaction([storeName], 'readwrite');
-        return transaction.objectStore(storeName).delete(key);
-      }).then((_) {
-        return transaction.completed;
-      }).then((_) {
-        var transaction = db.transaction([storeName], 'readonly');
-        return transaction.objectStore(storeName).count();
-      }).then((count) {
-        expect(count, 0);
+  if (html.window.indexedDB.supportsDatabaseNames) {
+    test('getDatabaseNames', () {
+      return html.window.indexedDB.getDatabaseNames().then((names) {
+        expect(names.contains(dbName), isTrue);
       });
     });
+  }
 
-    futureTest('clear/count', () {
-      var transaction = db.transaction([storeName], 'readwrite');
-      transaction.objectStore(storeName).add(value);
-
-      return transaction.completed.then((_) {
-        transaction = db.transaction([storeName], 'readonly');
-        return transaction.objectStore(storeName).count();
-      }).then((count) {
-        expect(count, 1);
-      }).then((_) {
-        return transaction.completed;
-      }).then((_) {
-        transaction = db.transaction([storeName], 'readwrite');
-        transaction.objectStore(storeName).clear();
-        return transaction.completed;
-      }).then((_) {
-        var transaction = db.transaction([storeName], 'readonly');
-        return transaction.objectStore(storeName).count();
-      }).then((count) {
-        expect(count, 0);
-      });
+  var value = {'name_index': 'one', 'value': 'add_value'};
+  test('add/delete', () {
+    var transaction = db.transaction([storeName], 'readwrite');
+    var key;
+    return transaction.objectStore(storeName).add(value).then((addedKey) {
+      key = addedKey;
+    }).then((_) {
+      return transaction.completed;
+    }).then((_) {
+      transaction = db.transaction([storeName], 'readonly');
+      return transaction.objectStore(storeName).getObject(key);
+    }).then((readValue) {
+      expect(readValue['value'], value['value']);
+      return transaction.completed;
+    }).then((_) {
+      transaction = db.transaction([storeName], 'readwrite');
+      return transaction.objectStore(storeName).delete(key);
+    }).then((_) {
+      return transaction.completed;
+    }).then((_) {
+      var transaction = db.transaction([storeName], 'readonly');
+      return transaction.objectStore(storeName).count();
+    }).then((count) {
+      expect(count, 0);
     });
+  });
 
-    futureTest('index', () {
-      var transaction = db.transaction([storeName], 'readwrite');
-      transaction.objectStore(storeName).add(value);
-      transaction.objectStore(storeName).add(value);
-      transaction.objectStore(storeName).add(value);
-      transaction.objectStore(storeName).add(value);
+  test('clear/count', () {
+    var transaction = db.transaction([storeName], 'readwrite');
+    transaction.objectStore(storeName).add(value);
 
-      return transaction.completed.then((_) {
-        transaction = db.transaction([storeName], 'readonly');
-        var index = transaction.objectStore(storeName).index(indexName);
-        return index.count();
-      }).then((count) {
-        expect(count, 4);
-        return transaction.completed;
-      }).then((_) {
-        transaction = db.transaction([storeName], 'readonly');
-        var index = transaction.objectStore(storeName).index(indexName);
-        return index.openCursor(autoAdvance: true).length;
-      }).then((cursorsLength) {
-        expect(cursorsLength, 4);
-        return transaction.completed;
-      }).then((_) {
-        transaction = db.transaction([storeName], 'readonly');
-        var index = transaction.objectStore(storeName).index(indexName);
-        return index.openKeyCursor(autoAdvance: true).length;
-      }).then((cursorsLength) {
-        expect(cursorsLength, 4);
-        return transaction.completed;
-      }).then((_) {
-        transaction = db.transaction([storeName], 'readonly');
-        var index = transaction.objectStore(storeName).index(indexName);
-        return index.get('one');
-      }).then((readValue) {
-        expect(readValue['value'], value['value']);
-        return transaction.completed;
-      }).then((_) {
-        transaction = db.transaction([storeName], 'readwrite');
-        transaction.objectStore(storeName).clear();
-        return transaction.completed;
-      });
+    return transaction.completed.then((_) {
+      transaction = db.transaction([storeName], 'readonly');
+      return transaction.objectStore(storeName).count();
+    }).then((count) {
+      expect(count, 1);
+    }).then((_) {
+      return transaction.completed;
+    }).then((_) {
+      transaction = db.transaction([storeName], 'readwrite');
+      transaction.objectStore(storeName).clear();
+      return transaction.completed;
+    }).then((_) {
+      var transaction = db.transaction([storeName], 'readonly');
+      return transaction.objectStore(storeName).count();
+    }).then((count) {
+      expect(count, 0);
     });
+  });
 
-    var deleteValue = {'name_index': 'two', 'value': 'delete_value'};
-    var updateValue = {'name_index': 'three', 'value': 'update_value'};
-    var updatedValue = {'name_index': 'three', 'value': 'updated_value'};
-    futureTest('cursor', () {
-      var transaction = db.transaction([storeName], 'readwrite');
-      transaction.objectStore(storeName).add(value);
-      transaction.objectStore(storeName).add(deleteValue);
-      transaction.objectStore(storeName).add(updateValue);
+  test('index', () {
+    var transaction = db.transaction([storeName], 'readwrite');
+    transaction.objectStore(storeName).add(value);
+    transaction.objectStore(storeName).add(value);
+    transaction.objectStore(storeName).add(value);
+    transaction.objectStore(storeName).add(value);
 
-      return transaction.completed.then((_) {
-        transaction = db.transaction([storeName], 'readwrite');
-        var index = transaction.objectStore(storeName).index(indexName);
-        var cursors = index.openCursor().asBroadcastStream();
+    return transaction.completed.then((_) {
+      transaction = db.transaction([storeName], 'readonly');
+      var index = transaction.objectStore(storeName).index(indexName);
+      return index.count();
+    }).then((count) {
+      expect(count, 4);
+      return transaction.completed;
+    }).then((_) {
+      transaction = db.transaction([storeName], 'readonly');
+      var index = transaction.objectStore(storeName).index(indexName);
+      return index.openCursor(autoAdvance: true).length;
+    }).then((cursorsLength) {
+      expect(cursorsLength, 4);
+      return transaction.completed;
+    }).then((_) {
+      transaction = db.transaction([storeName], 'readonly');
+      var index = transaction.objectStore(storeName).index(indexName);
+      return index.openKeyCursor(autoAdvance: true).length;
+    }).then((cursorsLength) {
+      expect(cursorsLength, 4);
+      return transaction.completed;
+    }).then((_) {
+      transaction = db.transaction([storeName], 'readonly');
+      var index = transaction.objectStore(storeName).index(indexName);
+      return index.get('one');
+    }).then((readValue) {
+      expect(readValue['value'], value['value']);
+      return transaction.completed;
+    }).then((_) {
+      transaction = db.transaction([storeName], 'readwrite');
+      transaction.objectStore(storeName).clear();
+      return transaction.completed;
+    });
+  });
 
-        cursors.listen((cursor) {
-          var value = cursor.value;
-          if (value['value'] == 'delete_value') {
-            cursor.delete().then((_) {
-              cursor.next();
-            });
-          } else if (value['value'] == 'update_value') {
-            cursor.update(updatedValue).then((_) {
-              cursor.next();
-            });
-          } else {
+  var deleteValue = {'name_index': 'two', 'value': 'delete_value'};
+  var updateValue = {'name_index': 'three', 'value': 'update_value'};
+  var updatedValue = {'name_index': 'three', 'value': 'updated_value'};
+  test('cursor', () {
+    var transaction = db.transaction([storeName], 'readwrite');
+    transaction.objectStore(storeName).add(value);
+    transaction.objectStore(storeName).add(deleteValue);
+    transaction.objectStore(storeName).add(updateValue);
+
+    return transaction.completed.then((_) {
+      transaction = db.transaction([storeName], 'readwrite');
+      var index = transaction.objectStore(storeName).index(indexName);
+      var cursors = index.openCursor().asBroadcastStream();
+
+      cursors.listen((cursor) {
+        var value = cursor.value;
+        if (value['value'] == 'delete_value') {
+          cursor.delete().then((_) {
             cursor.next();
-          }
-        });
-        return cursors.last;
-
-      }).then((_) {
-        return transaction.completed;
-      }).then((_) {
-        transaction = db.transaction([storeName], 'readonly');
-        var index = transaction.objectStore(storeName).index(indexName);
-        return index.get('three');
-      }).then((readValue) {
-        expect(readValue['value'], 'updated_value');
-        return transaction.completed;
-      }).then((_) {
-        transaction = db.transaction([storeName], 'readonly');
-        var index = transaction.objectStore(storeName).index(indexName);
-        return index.get('two');
-      }).then((readValue) {
-        expect(readValue, isNull);
-        return transaction.completed;
+          });
+        } else if (value['value'] == 'update_value') {
+          cursor.update(updatedValue).then((_) {
+            cursor.next();
+          });
+        } else {
+          cursor.next();
+        }
       });
+      return cursors.last;
+
+    }).then((_) {
+      return transaction.completed;
+    }).then((_) {
+      transaction = db.transaction([storeName], 'readonly');
+      var index = transaction.objectStore(storeName).index(indexName);
+      return index.get('three');
+    }).then((readValue) {
+      expect(readValue['value'], 'updated_value');
+      return transaction.completed;
+    }).then((_) {
+      transaction = db.transaction([storeName], 'readonly');
+      var index = transaction.objectStore(storeName).index(indexName);
+      return index.get('two');
+    }).then((readValue) {
+      expect(readValue, isNull);
+      return transaction.completed;
     });
   });
 }
diff --git a/tests/html/inner_frame_test.dart b/tests/html/inner_frame_test.dart
deleted file mode 100644
index 3001925..0000000
--- a/tests/html/inner_frame_test.dart
+++ /dev/null
@@ -1,120 +0,0 @@
-library InnerFrameTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
-import 'dart:html';
-
-main() {
-  if (window != window.top) {
-    // Child frame.
-
-    // The child's frame should not be able to access its parent's
-    // document.
-
-    window.onMessage.listen((Event e) {
-      switch (e.data) {
-      case 'frameElement': {
-        // Check window.frameElement.
-        try {
-          var parentDocument = window.frameElement.document;
-          var div = parentDocument.$dom_createElement("div");
-          div.id = "illegalFrameElement";
-          parentDocument.body.nodes.add(div);
-          expect(false, isTrue, reason: 'Should not reach here.');
-        } on NoSuchMethodError catch (e) {
-          // Expected.
-          window.top.postMessage('pass_frameElement', '*');
-        } catch (e) {
-          window.top.postMessage('fail_frameElement', '*');
-        }
-        return;
-      }
-      case 'top': {
-        // Check window.top.
-        try {
-          final top = window.top;
-          var parentDocument = top.document;
-          var div = parentDocument.$dom_createElement("div");
-          div.id = "illegalTop";
-          parentDocument.body.nodes.add(div);
-          expect(false, isTrue, reason: 'Should not reach here.');
-        } on NoSuchMethodError catch (e) {
-          // Expected.
-          window.top.postMessage('pass_top', '*');
-        } catch (e) {
-          window.top.postMessage('fail_top', '*');
-        }
-        return;
-      }
-      case 'parent': {
-        // Check window.parent.
-        try {
-          final parent = window.parent;
-          var parentDocument = parent.document;
-          var div = parentDocument.$dom_createElement("div");
-          div.id = "illegalParent";
-          parentDocument.body.nodes.add(div);
-          expect(false, isTrue, reason: 'Should not reach here.');
-        } on NoSuchMethodError catch (e) {
-          // Expected.
-          window.top.postMessage('pass_parent', '*');
-        } catch (e) {
-          window.top.postMessage('fail_parent', '*');
-        }
-        return;
-      }
-      }
-      });
-  }
-
-  // Parent / test frame
-  useHtmlConfiguration();
-
-  final iframe = new Element.tag('iframe');
-  iframe.src = window.location.href;
-  var child;
-
-  test('prepare', () {
-      iframe.onLoad.listen(expectAsync1((e) { child = iframe.contentWindow;}));
-      document.body.nodes.add(iframe);
-    });
-
-  final validate = (testName, verify) {
-    final expectedVerify = expectAsync0(verify);
-    window.onMessage.listen((e) {
-      guardAsync(() {
-          if (e.data == 'pass_$testName') {
-            expectedVerify();
-          }
-          expect(e.data, isNot(equals('fail_$testName')));
-        });
-      });
-    child.postMessage(testName, '*');
-  };
-
-  test('frameElement', () {
-      validate('frameElement', () {
-        var div = document.query('#illegalFrameElement');
-
-        // Ensure that this parent frame was not modified by its child.
-        expect(div, isNull);
-      });
-    });
-
-  test('top', () {
-      validate('top', () {
-        var div = document.query('#illegalTop');
-
-        // Ensure that this parent frame was not modified by its child.
-        expect(div, isNull);
-      });
-    });
-
-  test('parent', () {
-      validate('parent', () {
-        var div = document.query('#illegalParent');
-
-        // Ensure that this parent frame was not modified by its child.
-        expect(div, isNull);
-      });
-    });
-}
diff --git a/tests/html/messageevent_test.dart b/tests/html/messageevent_test.dart
index 9ed4288..c2c832a 100644
--- a/tests/html/messageevent_test.dart
+++ b/tests/html/messageevent_test.dart
@@ -15,7 +15,8 @@
       expect(event.cancelable, isTrue);
       expect(event.data, equals('data'));
       expect(event.origin, equals('origin'));
-      expect(event.lastEventId, equals('lastEventId'));
+      // IE allows setting this but just ignores it.
+      // expect(event.lastEventId, equals('lastEventId'));
       expect(event.source, same(window));
       // TODO(antonm): accessing ports is not supported yet.
   });
diff --git a/tests/html/node_model_test.dart b/tests/html/node_model_test.dart
new file mode 100644
index 0000000..64cab4b
--- /dev/null
+++ b/tests/html/node_model_test.dart
@@ -0,0 +1,169 @@
+// 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 node_model_test;
+import 'dart:async';
+import 'dart:html';
+import '../../pkg/unittest/lib/unittest.dart';
+import '../../pkg/unittest/lib/html_config.dart';
+
+Future get nextStep {
+  return new Future.delayed(new Duration());
+}
+
+class ModelTracker {
+  Element element = new DivElement();
+  List models = [];
+
+  ModelTracker() {
+    element.onModelChanged.listen((node) {
+      models.add(node.model);
+    });
+  }
+
+  void append(ModelTracker other) {
+    element.append(other.element);
+  }
+
+  get model => element.model;
+  void set model(value) {
+    element.model = value;
+  }
+
+  void clearModel() {
+    element.clearModel();
+  }
+}
+
+main() {
+  useHtmlConfiguration();
+
+  test('basic top down', () {
+    var a = new DivElement();
+    var b = new SpanElement();
+    var c = new DivElement();
+    var d = new DivElement();
+    var e = new DivElement();
+    var model = {};
+    var model2 = {};
+    var model3 = {};
+
+    document.body.append(a);
+    a.append(b);
+
+    a.model = model;
+    expect(a.model, model);
+    expect(b.model, model);
+
+    b.append(c);
+
+    return nextStep.then((_) {
+      expect(c.model, model);
+
+      d.append(e);
+      c.append(d);
+
+      return nextStep;
+    }).then((_) {
+      expect(e.model, model);
+
+      b.remove();
+      return nextStep;
+    }).then((_) {
+      expect(b.model, isNull);
+      expect(e.model, isNull);
+
+      return nextStep;
+    }).then((_) {
+      a.append(b);
+      a.model = model2;
+
+      return nextStep;
+    }).then((_) {
+      expect(e.model, model2);
+
+      c.model = model3;
+      expect(c.model, model3);
+      expect(b.model, model2);
+      expect(e.model, model3);
+
+      return nextStep;
+    }).then((_) {
+      d.remove();
+      c.append(d);
+
+      return nextStep;
+    }).then((_) {
+      expect(d.model, model3);
+
+      c.clearModel();
+      expect(d.model, model2);
+    });
+  });
+
+  test('changes', () {
+    var a = new ModelTracker();
+    var b = new ModelTracker();
+    var c = new ModelTracker();
+    var d = new ModelTracker();
+
+    var model = {};
+    var cModel = {};
+
+    document.body.append(a.element);
+
+    a.append(b);
+
+    return nextStep.then((_) {
+      expect(a.models, []);
+      expect(b.models.length, 0);
+
+      a.model = model;
+
+      expect(a.models, [model]);
+      expect(b.models, [model]);
+
+      b.append(c);
+      return nextStep;
+    }).then((_) {
+      expect(c.models, [model]);
+
+      c.append(d);
+      return nextStep;
+    }).then((_) {
+      c.model = cModel;
+      expect(b.models, [model]);
+      expect(c.models, [model, cModel]);
+      expect(d.models, [model, cModel]);
+
+      c.clearModel();
+      expect(c.models, [model, cModel, model]);
+      expect(d.models, [model, cModel, model]);
+    });
+  });
+
+  test('bottom up', () {
+    var a = new ModelTracker();
+    var b = new ModelTracker();
+    var c = new ModelTracker();
+    var d = new ModelTracker();
+
+    var aModel = {};
+    var cModel = {};
+
+    c.append(d);
+    c.model = cModel;
+    b.append(c);
+    a.append(b);
+    a.model = aModel;
+    document.body.append(a.element);
+
+    return nextStep.then((_) {
+      expect(a.models, [aModel]);
+      expect(b.models, [aModel]);
+      expect(c.models, [cModel]);
+      expect(d.models, [cModel]);
+    });
+  });
+}
diff --git a/tests/html/node_test.dart b/tests/html/node_test.dart
index fe31ed7..3eab98e 100644
--- a/tests/html/node_test.dart
+++ b/tests/html/node_test.dart
@@ -25,33 +25,77 @@
   var isInputElement =
       predicate((x) => x is InputElement, 'is an InputElement');
 
-  test('replaceWith', () {
-    final node = makeNodeWithChildren();
-    final subnode = node.nodes[1];
-    final out = subnode.replaceWith(new Text('Bar'));
-    expect(out, equals(subnode), reason: '#replaceWith should be chainable');
-    expect(node.nodes.length, 3);
-    expect(node.nodes[0], isText);
-    expect(node.nodes[0].text, 'Foo');
-    expect(node.nodes[1], isText);
-    expect(node.nodes[1].text, 'Bar');
-    expect(node.nodes[2], isComment);
-  });
+  group('functional', () {
+    test('replaceWith', () {
+      final node = makeNodeWithChildren();
+      final subnode = node.nodes[1];
+      final out = subnode.replaceWith(new Text('Bar'));
+      expect(out, equals(subnode), reason: '#replaceWith should be chainable');
+      expect(node.nodes.length, 3);
+      expect(node.nodes[0], isText);
+      expect(node.nodes[0].text, 'Foo');
+      expect(node.nodes[1], isText);
+      expect(node.nodes[1].text, 'Bar');
+      expect(node.nodes[2], isComment);
+    });
 
-  test('remove', () {
-    final node = makeNodeWithChildren();
-    final subnode = node.nodes[1];
-    subnode.remove();
-    expect(node.nodes.length, 2);
-    expect(node.nodes[0], isText);
-    expect(node.nodes[1], isComment);
-  });
+    test('append', () {
+      var node = makeNode();
+      node.append(new Element.tag('hr'));
+      expect(node.nodes.last, isHRElement);
+    });
 
-  test('contains', () {
-    final Node node = new Element.html("<div>Foo<span>Bar</span></div>");
-    expect(node.contains(node.nodes.first), isTrue);
-    expect(node.contains(node.nodes[1].nodes.first), isTrue);
-    expect(node.contains(new Text('Foo')), isFalse);
+    test('remove', () {
+      final node = makeNodeWithChildren();
+      final subnode = node.nodes[1];
+      subnode.remove();
+      expect(node.nodes.length, 2);
+      expect(node.nodes[0], isText);
+      expect(node.nodes[1], isComment);
+    });
+
+    test('contains', () {
+      final Node node =
+          new Element.html("<div>Foo<span><div>Bar<div></span></div>");
+      // IE10 returns false for contains of nodes.
+      //expect(node.contains(node.nodes.first), isTrue);
+      expect(node.contains(node.nodes[1].nodes.first), isTrue);
+      expect(node.contains(new Text('Foo')), isFalse);
+    });
+
+    test('insertAllBefore', () {
+      var node = makeNodeWithChildren();
+      var b = new DivElement();
+      b.nodes.addAll([
+        new HRElement(),
+        new ImageElement(),
+        new InputElement()
+      ]);
+      node.insertAllBefore(b.nodes, node.nodes[1]);
+      expect(node.nodes[0], isText);
+      expect(node.nodes[1], isHRElement);
+      expect(node.nodes[2], isImageElement);
+      expect(node.nodes[3], isInputElement);
+      expect(node.nodes[4], isBRElement);
+      expect(node.nodes[5], isComment);
+
+      var nodes = [
+        new HRElement(),
+        new ImageElement(),
+        new InputElement()
+      ];
+      node.insertAllBefore(nodes, node.nodes[5]);
+
+      expect(node.nodes[0], isText);
+      expect(node.nodes[1], isHRElement);
+      expect(node.nodes[2], isImageElement);
+      expect(node.nodes[3], isInputElement);
+      expect(node.nodes[4], isBRElement);
+      expect(node.nodes[5], isHRElement);
+      expect(node.nodes[6], isImageElement);
+      expect(node.nodes[7], isInputElement);
+      expect(node.nodes[8], isComment);
+    });
   });
 
   group('nodes', () {
@@ -62,6 +106,11 @@
     test('first', () {
       var node = makeNodeWithChildren();
       expect(node.nodes.first, isText);
+
+      node = new DivElement();
+      expect(() {
+        node = node.nodes.first;
+      }, throwsStateError);
     });
 
     test('last', () {
@@ -192,9 +241,9 @@
       expect(node.nodes.length, 1);
     });
 
-    test('getRange', () {
+    test('sublist', () {
       var node = makeNodeWithChildren();
-      expect(node.nodes.getRange(1, 2), isNodeList);
+      expect(node.nodes.sublist(1, 3), isNodeList);
     });
   });
 
@@ -214,8 +263,8 @@
       expect(filtered, isNodeList);
     });
 
-    test('getRange', () {
-      var range = makeNodeList().getRange(1, 2);
+    test('sublist', () {
+      var range = makeNodeList().sublist(1, 3);
       expect(range, isNodeList);
       expect(range[0], isBRElement);
       expect(range[1], isComment);
diff --git a/tests/html/non_instantiated_is_test.dart b/tests/html/non_instantiated_is_test.dart
new file mode 100644
index 0000000..bf1ece1
--- /dev/null
+++ b/tests/html/non_instantiated_is_test.dart
@@ -0,0 +1,20 @@
+// 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.
+
+// Regression test for dart2js, that used to emit wrong code on is
+// checks of native classes that are not instantiated.
+
+import 'dart:html';
+import '../../pkg/unittest/lib/unittest.dart';
+import '../../pkg/unittest/lib/html_config.dart';
+
+var a = [new Object()];
+
+main() {
+  useHtmlConfiguration();
+
+  test('is', () {
+    expect(a[0] is Node, isFalse);
+  });
+}
diff --git a/tests/html/point_test.dart b/tests/html/point_test.dart
new file mode 100644
index 0000000..74a0646
--- /dev/null
+++ b/tests/html/point_test.dart
@@ -0,0 +1,106 @@
+// 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 point_test;
+
+import 'dart:html';
+import '../../pkg/unittest/lib/unittest.dart';
+import '../../pkg/unittest/lib/html_config.dart';
+
+main() {
+  useHtmlConfiguration();
+
+  test('constructor', () {
+    var point = new Point();
+    expect(point.x, 0);
+    expect(point.y, 0);
+    expect('$point', '(0, 0)');
+  });
+
+  test('constructor X', () {
+    var point = new Point(10);
+    expect(point.x, 10);
+    expect(point.y, 0);
+    expect('$point', '(10, 0)');
+  });
+
+  test('constructor X Y', () {
+    var point = new Point(10, 20);
+    expect(point.x, 10);
+    expect(point.y, 20);
+    expect('$point', '(10, 20)');
+  });
+
+  test('constructor X Y double', () {
+    var point = new Point(10.5, 20.897);
+    expect(point.x, 10.5);
+    expect(point.y, 20.897);
+    expect('$point', '(10.5, 20.897)');
+  });
+
+  test('constructor X Y NaN', () {
+    var point = new Point(double.NAN, 1000);
+    expect(point.x.isNaN, isTrue);
+    expect(point.y, 1000);
+    expect('$point', '(NaN, 1000)');
+  });
+
+  test('squaredDistanceTo', () {
+    var a = new Point(7, 11);
+    var b = new Point(3, -1);
+    expect(a.squaredDistanceTo(b), 160);
+    expect(b.squaredDistanceTo(a), 160);
+  });
+
+  test('distanceTo', () {
+    var a = new Point(-2, -3);
+    var b = new Point(2, 0);
+    expect(a.distanceTo(b), 5);
+    expect(b.distanceTo(a), 5);
+  });
+
+  test('subtract', () {
+    var a = new Point(5, 10);
+    var b = new Point(2, 50);
+    expect(a - b, new Point(3, -40));
+  });
+
+  test('add', () {
+    var a = new Point(5, 10);
+    var b = new Point(2, 50);
+    expect(a + b, new Point(7, 60));
+  });
+
+  test('ceil', () {
+    var a = new Point(5.1, 10.8);
+    expect(a.ceil(), new Point(6.0, 11.0));
+
+    var b = new Point(5, 10);
+    expect(b.ceil(), new Point(5, 10));
+  });
+
+  test('floor', () {
+    var a = new Point(5.1, 10.8);
+    expect(a.floor(), new Point(5.0, 10.0));
+
+    var b = new Point(5, 10);
+    expect(b.floor(), new Point(5, 10));
+  });
+
+  test('round', () {
+    var a = new Point(5.1, 10.8);
+    expect(a.round(), new Point(5.0, 11.0));
+
+    var b = new Point(5, 10);
+    expect(b.round(), new Point(5, 10));
+  });
+
+  test('toInt', () {
+    var a = new Point(5.1, 10.8);
+    var b = a.toInt();
+    expect(b, new Point(5, 10));
+    expect(b.x is int, isTrue);
+    expect(b.y is int, isTrue);
+  });
+}
diff --git a/tests/html/postmessage_structured_test.dart b/tests/html/postmessage_structured_test.dart
index 0eb79f4..76860ea 100644
--- a/tests/html/postmessage_structured_test.dart
+++ b/tests/html/postmessage_structured_test.dart
@@ -122,6 +122,11 @@
   var cyclic_list = [1, 2, 3];
   cyclic_list[1] = cyclic_list;
 
+  var array_buffer = new ArrayBuffer(16);
+  var view_a = new Float32Array.fromBuffer(array_buffer, 0, 4);
+  var view_b = new Uint8Array.fromBuffer(array_buffer, 1, 13);
+  var typed_arrays_list = [view_a, array_buffer, view_b];
+
   go('test_simple_list', [1, 2, 3]);
   go('test_map', obj1);
   go('test_DAG', obj2);
@@ -132,4 +137,5 @@
   go('array_deferred_copy', [1,2,3, obj3, obj3, 6]);
   go('array_deferred_copy_2', [1,2,3, [4, 5, obj3], [obj3, 6]]);
   go('cyclic_list', cyclic_list);
+  go('typed_arrays_list', typed_arrays_list);
 }
diff --git a/tests/html/rect_test.dart b/tests/html/rect_test.dart
new file mode 100644
index 0000000..fd1935a
--- /dev/null
+++ b/tests/html/rect_test.dart
@@ -0,0 +1,150 @@
+// 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 rect_test;
+
+import 'dart:html';
+import '../../pkg/unittest/lib/unittest.dart';
+import '../../pkg/unittest/lib/html_config.dart';
+
+main() {
+  useHtmlConfiguration();
+
+  Rect createRect(List<num> a) {
+    return a != null ? new Rect(a[0], a[1], a[2] - a[0], a[3] - a[1]) : null;
+  }
+
+  test('construction', () {
+    var r0 = new Rect(10, 20, 30, 40);
+    expect(r0.toString(), '(10, 20, 30, 40)');
+    expect(r0.right, 40);
+    expect(r0.bottom, 60);
+
+    var r1 = new Rect.fromPoints(r0.topLeft, r0.bottomRight);
+    expect(r1, r0);
+
+    var r2 = new Rect.fromPoints(r0.bottomRight, r0.topLeft);
+    expect(r2, r0);
+  });
+
+  test('intersection', () {
+    var tests = [
+        [[10, 10, 20, 20], [15, 15, 25, 25], [15, 15, 20, 20]],
+        [[10, 10, 20, 20], [20, 0, 30, 10], [20, 10, 20, 10]],
+        [[0, 0, 1, 1], [10, 11, 12, 13], null],
+        [[11, 12, 98, 99], [22, 23, 34, 35], [22, 23, 34, 35]]];
+
+    for (var test in tests) {
+      var r0 = createRect(test[0]);
+      var r1 = createRect(test[1]);
+      var expected = createRect(test[2]);
+
+      expect(r0.intersection(r1), expected);
+      expect(r1.intersection(r0), expected);
+    }
+  });
+
+  test('intersects', () {
+    var r0 = new Rect(10, 10, 20, 20);
+    var r1 = new Rect(15, 15, 25, 25);
+    var r2 = new Rect(0, 0, 1, 1);
+
+    expect(r0.intersects(r1), isTrue);
+    expect(r1.intersects(r0), isTrue);
+
+    expect(r0.intersects(r2), isFalse);
+    expect(r2.intersects(r0), isFalse);
+  });
+
+  test('union', () {
+    var tests = [
+        [[10, 10, 20, 20], [15, 15, 25, 25], [10, 10, 25, 25]],
+        [[10, 10, 20, 20], [20, 0, 30, 10], [10, 0, 30, 20]],
+        [[0, 0, 1, 1], [10, 11, 12, 13], [0, 0, 12, 13]],
+        [[11, 12, 98, 99], [22, 23, 34, 35], [11, 12, 98, 99]]];
+
+    for (var test in tests) {
+      var r0 = createRect(test[0]);
+      var r1 = createRect(test[1]);
+      var expected = createRect(test[2]);
+
+      expect(r0.union(r1), expected);
+      expect(r1.union(r0), expected);
+    }
+  });
+
+  test('containsRect', () {
+    var r = new Rect(-10, 0, 20, 10);
+    expect(r.containsRect(r), isTrue);
+
+    expect(r.containsRect(
+        new Rect(double.NAN, double.NAN, double.NAN, double.NAN)), isFalse);
+
+    var r2 = new Rect(0, 2, 5, 5);
+    expect(r.containsRect(r2), isTrue);
+    expect(r2.containsRect(r), isFalse);
+
+    r2 = new Rect(-11, 2, 5, 5);
+    expect(r.containsRect(r2), isFalse);
+    r2 = new Rect(0, 2, 15, 5);
+    expect(r.containsRect(r2), isFalse);
+    r2 = new Rect(0, 2, 5, 10);
+    expect(r.containsRect(r2), isFalse);
+    r2 = new Rect(0, 0, 5, 10);
+    expect(r.containsRect(r2), isTrue);
+  });
+
+  test('containsPoint', () {
+    var r = new Rect(20, 40, 60, 80);
+
+    // Test middle.
+    expect(r.containsPoint(new Point(50, 80)), isTrue);
+
+    // Test edges.
+    expect(r.containsPoint(new Point(20, 40)), isTrue);
+    expect(r.containsPoint(new Point(50, 40)), isTrue);
+    expect(r.containsPoint(new Point(80, 40)), isTrue);
+    expect(r.containsPoint(new Point(80, 80)), isTrue);
+    expect(r.containsPoint(new Point(80, 120)), isTrue);
+    expect(r.containsPoint(new Point(50, 120)), isTrue);
+    expect(r.containsPoint(new Point(20, 120)), isTrue);
+    expect(r.containsPoint(new Point(20, 80)), isTrue);
+
+    // Test outside.
+    expect(r.containsPoint(new Point(0, 0)), isFalse);
+    expect(r.containsPoint(new Point(50, 0)), isFalse);
+    expect(r.containsPoint(new Point(100, 0)), isFalse);
+    expect(r.containsPoint(new Point(100, 80)), isFalse);
+    expect(r.containsPoint(new Point(100, 160)), isFalse);
+    expect(r.containsPoint(new Point(50, 160)), isFalse);
+    expect(r.containsPoint(new Point(0, 160)), isFalse);
+    expect(r.containsPoint(new Point(0, 80)), isFalse);
+  });
+
+  test('ceil', () {
+    var rect = new Rect(11.4, 26.6, 17.8, 9.2);
+    expect(rect.ceil(), new Rect(12.0, 27.0, 18.0, 10.0));
+  });
+
+  test('floor', () {
+    var rect = new Rect(11.4, 26.6, 17.8, 9.2);
+    expect(rect.floor(), new Rect(11.0, 26.0, 17.0, 9.0));
+  });
+
+  test('round', () {
+    var rect = new Rect(11.4, 26.6, 17.8, 9.2);
+    expect(rect.round(), new Rect(11.0, 27.0, 18.0, 9.0));
+  });
+
+  test('toInt', () {
+    var rect = new Rect(11.4, 26.6, 17.8, 9.2);
+    var b = rect.toInt();
+    expect(b, new Rect(11, 26, 17, 9));
+
+    expect(b.left is int, isTrue);
+    expect(b.top is int, isTrue);
+    expect(b.width is int, isTrue);
+    expect(b.height is int, isTrue);
+  });
+}
diff --git a/tests/html/streams_test.dart b/tests/html/streams_test.dart
index 3c3f5a2..843e1c7 100644
--- a/tests/html/streams_test.dart
+++ b/tests/html/streams_test.dart
@@ -267,16 +267,16 @@
     stream.single.then((_) {});
   });
 
-  test('firstMatching', () {
-    stream.firstMatching((_) => true).then((_) {});
+  test('firstWhere', () {
+    stream.firstWhere((_) => true).then((_) {});
   });
 
-  test('lastMatching', () {
-    stream.lastMatching((_) => true).then((_) {});
+  test('lastWhere', () {
+    stream.lastWhere((_) => true).then((_) {});
   });
 
-  test('singleMatching', () {
-    stream.singleMatching((_) => true).then((_) {});
+  test('singleWhere', () {
+    stream.singleWhere((_) => true).then((_) {});
   });
 
   test('elementAt', () {
diff --git a/tests/html/transferables_test.dart b/tests/html/transferables_test.dart
index a487ada..a00a6e4 100644
--- a/tests/html/transferables_test.dart
+++ b/tests/html/transferables_test.dart
@@ -24,7 +24,7 @@
         'buffer': buffer
       }, '*', [buffer]);
 
-    return window.onMessage.firstMatching(
+    return window.onMessage.firstWhere(
       (e) {
         return e.data is Map && e.data['id'] == 'transferable data';
       }).then((messageEvent) {
diff --git a/tests/html/utils.dart b/tests/html/utils.dart
index 2669fa7..3257661 100644
--- a/tests/html/utils.dart
+++ b/tests/html/utils.dart
@@ -1,5 +1,7 @@
 library TestUtils;
+
 import 'dart:async';
+import 'dart:html';
 import '../../pkg/unittest/lib/unittest.dart';
 
 /**
@@ -38,6 +40,27 @@
     eItems.add(expected);
     aItems.add(actual);
 
+    if (expected is ArrayBuffer) {
+      expect(actual is ArrayBuffer, isTrue,
+          reason: '$actual is ArrayBuffer');
+      expect(expected.byteLength, equals(actual.byteLength),
+          reason: message(path, '.byteLength'));
+      // TODO(antonm): one can create a view on top of those
+      // and check if contents identical.  Let's do it later.
+      return;
+    }
+
+    if (expected is ArrayBufferView) {
+      expect(actual is ArrayBufferView, isTrue,
+          reason: '$actual is ArrayBufferView');
+      walk('$path/.buffer', expected.buffer, actual.buffer);
+      expect(expected.byteOffset, equals(actual.byteOffset),
+          reason: message(path, '.byteOffset'));
+      expect(expected.byteLength, equals(actual.byteLength),
+          reason: message(path, '.byteLength'));
+      // And also fallback to elements check below.
+    }
+
     if (expected is List) {
       expect(actual, isList, reason: message(path, '$actual is List'));
       expect(actual.length, expected.length,
@@ -69,9 +92,3 @@
 
   walk('', expected, actual);
 }
-
-void futureTest(spec, Future body()) {
-  test(spec, () {
-    expect(body(), completes);
-  });
-}
diff --git a/tests/html/websql_test.dart b/tests/html/websql_test.dart
index 601ab1a..27b11a8 100644
--- a/tests/html/websql_test.dart
+++ b/tests/html/websql_test.dart
@@ -4,7 +4,6 @@
 import 'dart:web_sql';
 import '../../pkg/unittest/lib/unittest.dart';
 import '../../pkg/unittest/lib/html_individual_config.dart';
-import 'utils.dart';
 
 void fail(message) {
   guardAsync(() {
@@ -108,7 +107,7 @@
       }, expectation);
 
     });
-    futureTest('Web Database', () {
+    test('Web Database', () {
       // Skip if not supported.
       if (!SqlDatabase.supported) {
         return new Future.immediate(null);
diff --git a/tests/html/wheelevent_test.dart b/tests/html/wheelevent_test.dart
index 2dc9adc..ce801f5 100644
--- a/tests/html/wheelevent_test.dart
+++ b/tests/html/wheelevent_test.dart
@@ -17,7 +17,7 @@
     var eventType = Element.mouseWheelEvent.getEventType(element);
 
     element.onMouseWheel.listen(expectAsync1((e) {
-      expect(e.screenX, 100);
+      expect(e.screen.x, 100);
       expect(e.deltaX, 0);
       expect(e.deltaY, 240);
       expect(e.deltaMode, isNotNull);
@@ -34,7 +34,7 @@
     var eventType = Element.mouseWheelEvent.getEventType(element);
 
     element.onMouseWheel.listen(expectAsync1((e) {
-      expect(e.screenX, 100);
+      expect(e.screen.x, 100);
       expect(e.deltaX, 0);
       expect(e.deltaY, 240);
     }));
diff --git a/tests/html/xhr_cross_origin_test.dart b/tests/html/xhr_cross_origin_test.dart
index 5f22ee7..d4dbecd 100644
--- a/tests/html/xhr_cross_origin_test.dart
+++ b/tests/html/xhr_cross_origin_test.dart
@@ -33,7 +33,7 @@
     var url = "http://localhost:$port/"
               "root_dart/tests/html/xhr_cross_origin_data.txt";
     var xhr = new HttpRequest();
-    xhr.open('GET', url, true);
+    xhr.open('GET', url, async: true);
     var validate = expectAsync1((data) {
       expect(data, contains('feed'));
       expect(data['feed'], contains('entry'));
diff --git a/tests/html/xhr_test.dart b/tests/html/xhr_test.dart
index 91e86d5..6214581 100644
--- a/tests/html/xhr_test.dart
+++ b/tests/html/xhr_test.dart
@@ -53,7 +53,7 @@
   group('xhr', () {
     test('XHR No file', () {
       HttpRequest xhr = new HttpRequest();
-      xhr.open("GET", "NonExistingFile", true);
+      xhr.open("GET", "NonExistingFile", async: true);
       xhr.onReadyStateChange.listen(expectAsyncUntil1((event) {
         if (xhr.readyState == HttpRequest.DONE) {
           validate404(xhr);
@@ -66,7 +66,7 @@
       var loadEndCalled = false;
 
       var xhr = new HttpRequest();
-      xhr.open('GET', url, true);
+      xhr.open('GET', url, async: true);
       xhr.onReadyStateChange.listen(expectAsyncUntil1((e) {
         if (xhr.readyState == HttpRequest.DONE) {
           validate200Response(xhr);
@@ -142,7 +142,7 @@
         }));
     });
 
-    test('XHR.request responseType', () {
+    test('XHR.request responseType arraybuffer', () {
       if (ArrayBuffer.supported) {
         HttpRequest.request(url, responseType: 'arraybuffer').then(
           expectAsync1((xhr) {
@@ -163,4 +163,18 @@
       }, expectation);
     });
   });
+
+  group('xhr_requestBlob', () {
+    test('XHR.request responseType blob', () {
+      if (ArrayBuffer.supported) {
+        return HttpRequest.request(url, responseType: 'blob').then(
+          (xhr) {
+            expect(xhr.status, equals(200));
+            var blob = xhr.response;
+            expect(blob is Blob, isTrue);
+            expect(blob, isNotNull);
+          });
+      }
+    });
+  });
 }
diff --git a/tests/isolate/compute_this_script_browser_test.dart b/tests/isolate/compute_this_script_browser_test.dart
index 49fbf2d..e91d4a9 100644
--- a/tests/isolate/compute_this_script_browser_test.dart
+++ b/tests/isolate/compute_this_script_browser_test.dart
@@ -21,8 +21,8 @@
 
 main() {
   useHtmlConfiguration();
-  var script = document.$dom_createElement('script');
-  document.body.$dom_appendChild(script);
+  var script = new ScriptElement();
+  document.body.append(script);
   test('spawn with other script tags in page', () {
     ReceivePort port = new ReceivePort();
     port.receive(expectAsync2((msg, _) {
diff --git a/tests/isolate/global_error_handler_test.dart b/tests/isolate/global_error_handler_test.dart
new file mode 100644
index 0000000..cbb659a
--- /dev/null
+++ b/tests/isolate/global_error_handler_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:isolate';
+
+var firstFunction;
+var finishFunction;
+
+void runFunctions() {
+  try {
+    firstFunction();
+  } catch (e) {
+    new Timer(Duration.ZERO, finishFunction);
+    throw;
+  }
+}
+
+void startTest(SendPort finishPort, replyPort) {
+  firstFunction = () { throw new RuntimeError("ignore exception"); };
+  finishFunction = () { finishPort.send("done"); };
+  new Timer(Duration.ZERO, runFunctions);
+}
+
+runTest() {
+  port.receive(startTest);
+}
+
+bool globalErrorHandler(IsolateUnhandledException e) {
+  return e.source is RuntimeError && e.source.message == "ignore exception";
+}
+
+main() {
+  var port = new ReceivePort();
+  var timer;
+  SendPort otherIsolate = spawnFunction(runTest, globalErrorHandler);
+  otherIsolate.send(port.toSendPort());
+  port.receive((msg, replyPort) { port.close(); timer.cancel(); });
+  timer = new Timer(const Duration(seconds: 2), () { throw "failed"; });
+}
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index b3faa8c..d6d1368 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -13,6 +13,7 @@
                                    # implement timer (currently only in d8)
 timer_isolate_test: Skip # See Issue 4997
 unresolved_ports_negative_test: Skip # See Issue 6839
+global_error_handler_test: Fail # See Issue 9013.
 
 [ $compiler == none && $runtime == drt ]
 isolate2_negative_test: Skip  # Inherited from VM.
@@ -25,6 +26,7 @@
 timer_isolate_test: Skip # See Issue 4997
 timer_not_available_test: Skip # only meant to test when there is no way to
                                # implement timer (currently only in d8)
+global_error_handler_test: Fail # See Issue 9013.
 
 [ $compiler == dartc ]
 isolate_negative_test: Fail    # status change with --check-only
@@ -43,6 +45,9 @@
 serialization_test: Fail # Tries to access class TestingOnly declared in isolate_patch.dart
 illegal_msg_test: Fail # Issue 6750
 
+[ $compiler == dart2js ]
+global_error_handler_test: Pass, Fail # http://dartbug.com/9012 and http://dartbug.com/9024
+
 [ $runtime == safari ]
 cross_isolate_message_test: Skip      # Depends on 32/64 bit Safari. See Issue 1120
 mixed_test: Pass,Fail               # Depends on 32/64 bit Safari. See Issue 1120
diff --git a/tests/isolate/mandel_isolate_test.dart b/tests/isolate/mandel_isolate_test.dart
index abc4d83..3e03544 100644
--- a/tests/isolate/mandel_isolate_test.dart
+++ b/tests/isolate/mandel_isolate_test.dart
@@ -67,10 +67,10 @@
     for (int i = 0; i < _result.length; i++) {
       List<int> line = _result[i];
       for (int j = 0; j < line.length; j++) {
-        if (line[j] < 10) output.add("0");
-        output.add(line[j]);
+        if (line[j] < 10) output.write("0");
+        output.write(line[j]);
       }
-      output.add("\n");
+      output.write("\n");
     }
     // print(output);
   }
diff --git a/tests/isolate/timer_cancel2_test.dart b/tests/isolate/timer_cancel2_test.dart
index 16768afd..b684af5 100644
--- a/tests/isolate/timer_cancel2_test.dart
+++ b/tests/isolate/timer_cancel2_test.dart
@@ -16,7 +16,7 @@
       cancelTimer.cancel();
     }
 
-    cancelTimer = new Timer.repeating(const Duration(milliseconds: 1),
-                                      expectAsync1(cancelHandler));
+    cancelTimer = new Timer.periodic(const Duration(milliseconds: 1),
+                                     expectAsync1(cancelHandler));
   });
 }
diff --git a/tests/isolate/timer_cancel_test.dart b/tests/isolate/timer_cancel_test.dart
index a159abc..88acbb1 100644
--- a/tests/isolate/timer_cancel_test.dart
+++ b/tests/isolate/timer_cancel_test.dart
@@ -33,7 +33,7 @@
     new Timer(ms * 1000, expectAsync0(handler));
     cancelTimer = new Timer(ms * 2000, expectAsync0(unreachable, count: 0));
     repeatTimer = 0;
-    new Timer.repeating(ms * 1500, expectAsync1(repeatHandler));
+    new Timer.periodic(ms * 1500, expectAsync1(repeatHandler));
   });
 
   test("cancel timer with same time", () {
diff --git a/tests/isolate/timer_not_available_test.dart b/tests/isolate/timer_not_available_test.dart
index 554c91b..d0efd1f 100644
--- a/tests/isolate/timer_not_available_test.dart
+++ b/tests/isolate/timer_not_available_test.dart
@@ -17,7 +17,7 @@
   Expect.isTrue(failed);
   failed = false;
   try {
-    var t = new Timer.repeating(ms * 10, (_) { });
+    var t = new Timer.periodic(ms * 10, (_) { });
     t.cancel();
   } on UnsupportedError catch (e) {
     failed = true;
diff --git a/tests/isolate/timer_repeat_test.dart b/tests/isolate/timer_repeat_test.dart
index d0c3a11..0c299d4 100644
--- a/tests/isolate/timer_repeat_test.dart
+++ b/tests/isolate/timer_repeat_test.dart
@@ -29,7 +29,7 @@
   test("timer_repeat", () {
     iteration = 0;
     startTime = new DateTime.now().millisecondsSinceEpoch;
-    timer = new Timer.repeating(TIMEOUT, 
+    timer = new Timer.periodic(TIMEOUT,
         expectAsync1(timeoutHandler, count: ITERATIONS));
   });
 }
diff --git a/tests/language/argument_definition6_test.dart b/tests/language/argument_definition6_test.dart
new file mode 100644
index 0000000..5dc8748
--- /dev/null
+++ b/tests/language/argument_definition6_test.dart
@@ -0,0 +1,26 @@
+// 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.
+
+// Regression test for
+// https://code.google.com/p/dart/issues/detail?id=9090.
+// Parameters used to be passed in the wrong order in a constructor in the
+// presence of parameter checks.
+
+
+class A {
+  A(expect1, expect2, value1, value2, {layers, serviceUrl}) {
+    Expect.equals(expect1, ?layers);
+    Expect.equals(expect2, ?serviceUrl);
+    Expect.equals(value1, layers);
+    Expect.equals(value2, serviceUrl);
+  }
+}
+
+main() {
+  new A(false, false, null, null);
+  new A(true, false, 42, null, layers: 42);
+  new A(false, true, null, 43, serviceUrl: 43);
+  new A(true, true, 42, 43, layers: 42, serviceUrl: 43);
+  new A(true, true, 42, 43, serviceUrl: 43, layers: 42);
+}
diff --git a/tests/language/arithmetic_test.dart b/tests/language/arithmetic_test.dart
index 4ee0080..f6abde7 100644
--- a/tests/language/arithmetic_test.dart
+++ b/tests/language/arithmetic_test.dart
@@ -81,7 +81,7 @@
     Expect.equals(26.0, a + b);
     Expect.equals(18.0, a - b);
     Expect.equals(88.0, a * b);
-    Expect.equals(5.0, a ~/ b);
+    Expect.equals(5, a ~/ b);
     Expect.equals(5.5, a / b);
     Expect.equals(2.0, a % b);
     Expect.equals(2.0, a.remainder(b));
@@ -206,19 +206,18 @@
     Expect.equals(big, big.ceil());
     Expect.equals(-big, (-big).ceil());
     // Double.
-    Expect.equals(0.0, (0.0).ceil());
+    Expect.equals(0, (0.0).ceil());
     Expect.equals(false, (0.0).ceil().isNegative);
-    Expect.equals(1.0, (0.1).ceil());
-    Expect.equals(1.0, double.MIN_POSITIVE.ceil());
-    Expect.equals(1.0, (0.49999999999999994).ceil());
-    Expect.equals(-0.0, (-0.0).ceil());
-    Expect.equals(-0.0, (-0.3).ceil());
-    Expect.isTrue((-0.0).ceil().isNegative);
-    Expect.isTrue((-0.3).ceil().isNegative);
-    Expect.equals(-0.0, (-0.49999999999999994).ceil());
-    Expect.isTrue((-0.49999999999999994).ceil().isNegative);
-    Expect.equals(3.0, (2.1).ceil());
-    Expect.equals(-2.0, (-2.1).ceil());
+    Expect.equals(1, (0.1).ceil());
+    Expect.equals(1, double.MIN_POSITIVE.ceil());
+    Expect.equals(1, (0.49999999999999994).ceil());
+    Expect.equals(0, (-0.0).ceil());
+    Expect.equals(0, (-0.3).ceil());
+    Expect.isTrue((-0.0).ceil() is int);
+    Expect.isTrue((-0.3).ceil() is int);
+    Expect.equals(0, (-0.49999999999999994).ceil());
+    Expect.equals(3, (2.1).ceil());
+    Expect.equals(-2, (-2.1).ceil());
 
     // -- floor --.
     // Smi.
@@ -229,18 +228,18 @@
     Expect.equals(big, big.floor());
     Expect.equals(-big, (-big).floor());
     // Double.
-    Expect.equals(0.0, (0.0).floor());
-    Expect.equals(0.0, (0.1).floor());
-    Expect.equals(0.0, (0.49999999999999994).floor());
-    Expect.equals(0.0, double.MIN_POSITIVE.floor());
-    Expect.equals(false, (0.0).floor().isNegative);
-    Expect.equals(false, (0.1).floor().isNegative);
-    Expect.equals(-0.0, (-0.0).floor());
-    Expect.equals(true, (-0.0).floor().isNegative);
-    Expect.equals(-1.0, (-0.1).floor());
+    Expect.equals(0, (0.0).floor());
+    Expect.equals(0, (0.1).floor());
+    Expect.equals(0, (0.49999999999999994).floor());
+    Expect.equals(0, double.MIN_POSITIVE.floor());
+    Expect.isTrue((0.0).floor() is int);
+    Expect.isTrue((0.1).floor() is int);
+    Expect.equals(0, (-0.0).floor());
+    Expect.isTrue((-0.0).floor() is int);
+    Expect.equals(-1, (-0.1).floor());
+    Expect.equals(2, (2.1).floor());
+    Expect.equals(-3, (-2.1).floor());
     Expect.equals(-1.0, (-0.49999999999999994).floor());
-    Expect.equals(2.0, (2.1).floor());
-    Expect.equals(-3.0, (-2.1).floor());
     Expect.equals(-3.0, (-2.1).floor());
 
 
@@ -253,19 +252,19 @@
     Expect.equals(big, big.truncate());
     Expect.equals(-big, (-big).truncate());
     // Double.
-    Expect.equals(0.0, (0.0).truncate());
-    Expect.equals(0.0, (0.1).truncate());
-    Expect.equals(false, (0.0).truncate().isNegative);
-    Expect.equals(false, (0.1).truncate().isNegative);
-    Expect.equals(-0.0, (-0.0).truncate());
-    Expect.equals(-0.0, (-0.3).truncate());
-    Expect.equals(true, (-0.0).truncate().isNegative);
-    Expect.equals(true, (-0.3).truncate().isNegative);
-    Expect.equals(2.0, (2.1).truncate());
-    Expect.equals(-2.0, (-2.1).truncate());
+    Expect.equals(0, (0.0).truncate());
+    Expect.equals(0, (0.1).truncate());
+    Expect.isTrue((0.0).truncate() is int);
+    Expect.isTrue((0.1).truncate() is int);
+    Expect.equals(0, (-0.0).truncate());
+    Expect.equals(0, (-0.3).truncate());
+    Expect.isTrue((-0.0).truncate() is int);
+    Expect.isTrue((-0.3).truncate() is int);
+    Expect.equals(2, (2.1).truncate());
+    Expect.equals(-2, (-2.1).truncate());
 
-    double b1 = (1234567890123.0).truncate();
-    double b2 = (1234567890124.0).truncate();
+    int b1 = (1234567890123.0).truncate();
+    int b2 = (1234567890124.0).truncate();
     Expect.equals(b2, b1 + 1.0);
 
     // -- round --.
@@ -277,30 +276,30 @@
     Expect.equals(big, big.round());
     Expect.equals(-big, (-big).round());
     // Double.
-    Expect.equals(3.0, (2.6).round());
-    Expect.equals(-3.0, (-2.6).round());
-    Expect.equals(3.0, (2.5).round());
-    Expect.equals(-3.0, (-2.5).round());
-    Expect.equals(0.0, (0.0).round());
-    Expect.equals(0.0, (0.1).round());
-    Expect.equals(false, (0.0).round().isNegative);
-    Expect.equals(false, (0.1).round().isNegative);
-    Expect.equals(-0.0, (-0.0).round());
-    Expect.equals(-0.0, (-0.3).round());
-    Expect.equals(2.0, (2.1).round());
-    Expect.equals(-2.0, (-2.1).round());
-    Expect.equals(1.0, (0.5).round());
-    Expect.equals(0.0, (0.49999999999999994).round());
-    Expect.equals(-0.0, (-0.49999999999999994).round());
-    Expect.equals(-1.0, (-0.5).round());
-    Expect.equals(true, (-0.0).round().isNegative);
-    Expect.equals(true, (-0.3).round().isNegative);
-    Expect.equals(true, (-0.5).round().isNegative);
-    Expect.equals(2.0, (1.5).round());
-    Expect.equals(-2.0, (-1.5).round());
-    Expect.equals(1.0, (0.99).round());
-    Expect.equals(9007199254740991.0, (9007199254740991.0).round());
-    Expect.equals(-9007199254740991.0, (-9007199254740991.0).round());
+    Expect.equals(3, (2.6).round());
+    Expect.equals(-3, (-2.6).round());
+    Expect.equals(0, (0.0).round());
+    Expect.equals(0, (0.1).round());
+    Expect.equals(3, (2.5).round());
+    Expect.equals(-3, (-2.5).round());
+    Expect.isFalse((0.0).round().isNegative);
+    Expect.isFalse((0.1).round().isNegative);
+    Expect.equals(0, (-0.0).round());
+    Expect.equals(0, (-0.3).round());
+    Expect.equals(2, (2.1).round());
+    Expect.equals(-2, (-2.1).round());
+    Expect.equals(1, (0.5).round());
+    Expect.equals(0, (0.49999999999999994).round());
+    Expect.equals(0, (-0.49999999999999994).round());
+    Expect.equals(-1, (-0.5).round());
+    Expect.isTrue((-0.0).round() is int);
+    Expect.isTrue((-0.3).round() is int);
+    Expect.isTrue((-0.5).round() is int);
+    Expect.equals(2, (1.5).round());
+    Expect.equals(-2, (-1.5).round());
+    Expect.equals(1, (0.99).round());
+    Expect.equals(9007199254740991, (9007199254740991.0).round());
+    Expect.equals(-9007199254740991, (-9007199254740991.0).round());
 
     // -- toInt --.
     // Smi.
diff --git a/tests/language/block_scope_test.dart b/tests/language/block_scope_test.dart
index 1929958..6ae0495 100644
--- a/tests/language/block_scope_test.dart
+++ b/tests/language/block_scope_test.dart
@@ -29,11 +29,11 @@
 
 void testShadowingCapture2() {
   var f = null;
-  // this one uses a reentrent block
+  // this one uses a reentrant block
   for (int i = 0; i < 2; i++) {
     var foo = i + 888;
     if (f == null) f = () => foo;
-  } while(false);
+  }
   var foo = -888;
 
   // this could break if it doesn't bind the right "foo"
diff --git a/tests/language/call_operator_test.dart b/tests/language/call_operator_test.dart
index 2dc7070..c3e2858 100644
--- a/tests/language/call_operator_test.dart
+++ b/tests/language/call_operator_test.dart
@@ -32,9 +32,9 @@
   String call(String str, {int count: 1}) {
     StringBuffer buffer = new StringBuffer();
     for (var i = 0; i < count; i++) {
-      buffer.add(str);
+      buffer.write(str);
       if (i < count - 1) {
-        buffer.add(":");
+        buffer.write(":");
       }
     }
     return buffer.toString();
diff --git a/tests/language/call_through_getter_test.dart b/tests/language/call_through_getter_test.dart
index 11a11d7..fc24d4d 100644
--- a/tests/language/call_through_getter_test.dart
+++ b/tests/language/call_through_getter_test.dart
@@ -155,7 +155,7 @@
   get y { _mark('y'); return 1; }
   get z { _mark('z'); return 2; }
 
-  _mark(m) { _order.add(m); return _order.toString(); }
+  _mark(m) { _order.write(m); return _order.toString(); }
   StringBuffer _order;
 
 }
diff --git a/tests/language/constructor2_test.dart b/tests/language/constructor2_test.dart
index cdddebc..c4e9f37 100644
--- a/tests/language/constructor2_test.dart
+++ b/tests/language/constructor2_test.dart
@@ -10,7 +10,7 @@
 String trace = "";
 
 int E(int i) {
-  trace = trace.concat("$i-");
+  trace += "$i-";
   return i;
 }
 
diff --git a/tests/language/constructor3_test.dart b/tests/language/constructor3_test.dart
index 0b235c4..c8916e0 100644
--- a/tests/language/constructor3_test.dart
+++ b/tests/language/constructor3_test.dart
@@ -10,7 +10,7 @@
 String trace = "";
 
 int E(int i) {
-  trace = trace.concat("$i-");
+  trace += "$i-";
   return i;
 }
 
diff --git a/tests/language/constructor4_test.dart b/tests/language/constructor4_test.dart
index fbef085..ad16fb3 100644
--- a/tests/language/constructor4_test.dart
+++ b/tests/language/constructor4_test.dart
@@ -10,7 +10,7 @@
 String trace = "";
 
 int E(int i) {
-  trace = trace.concat("$i-");
+  trace += "$i-";
   return i;
 }
 
diff --git a/tests/language/constructor7_test.dart b/tests/language/constructor7_test.dart
index 1d96394..25468f8 100644
--- a/tests/language/constructor7_test.dart
+++ b/tests/language/constructor7_test.dart
@@ -11,7 +11,7 @@
 String trace = "";
 
 int E(int i) {
-  trace = trace.concat("$i-");
+  trace += "$i-";
   return i;
 }
 
diff --git a/tests/language/constructor_named_arguments_test.dart b/tests/language/constructor_named_arguments_test.dart
index b799473..c320179 100644
--- a/tests/language/constructor_named_arguments_test.dart
+++ b/tests/language/constructor_named_arguments_test.dart
@@ -6,12 +6,12 @@
 String message;
 
 foo() {
-  message = message.concat('foo');
+  message += 'foo';
   return 1;
 }
 
 bar() {
-  message = message.concat('bar');
+  message += 'bar';
   return 2;
 }
 
diff --git a/tests/language/deopt_hoisted_smi_check_test.dart b/tests/language/deopt_hoisted_smi_check_test.dart
deleted file mode 100644
index 5ed5337..0000000
--- a/tests/language/deopt_hoisted_smi_check_test.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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.
-// Test deoptimization on an optimistically hoisted smi check.
-
-sum(a, b) {
-  var sum = 0;
-  for (var j = 1; j < 10; j++) {
-    for (var i = a; i < b; i++) {
-      sum++;
-    }
-  }
-  return sum;
-}
-
-main() {
-  for (var i = 0; i < 2000; i++) Expect.equals(9, sum(1, 2));
-  Expect.equals(9, sum(1.0, 2.0));  // Passing double causes deoptimization.
-}
\ No newline at end of file
diff --git a/tests/language/deopt_hoisted_smi_check_vm_test.dart b/tests/language/deopt_hoisted_smi_check_vm_test.dart
new file mode 100644
index 0000000..6fab79c
--- /dev/null
+++ b/tests/language/deopt_hoisted_smi_check_vm_test.dart
@@ -0,0 +1,32 @@
+// 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 deoptimization on an optimistically hoisted smi check.
+
+sum(a, b) {
+  var sum = 0;
+  for (var j = 1; j < 10; j++) {
+    for (var i = a; i < b; i++) {
+      sum++;
+    }
+  }
+  return sum;
+}
+
+mask(x) {
+  for (var i = 0; i < 10; i++) {
+    if (i == 1) {
+      return x;
+    }
+    x = x & 0xFF;
+  }
+}
+
+main() {
+  for (var i = 0; i < 2000; i++) {
+    Expect.equals(9, sum(1, 2));
+    Expect.equals(0xAB, mask(0xAB));
+  }
+  Expect.equals(9, sum(1.0, 2.0));  // Passing double causes deoptimization.
+  Expect.equals(0xAB, mask(0x1000000AB));
+}
\ No newline at end of file
diff --git a/tests/language/example_constructor_test.dart b/tests/language/example_constructor_test.dart
index 40d5e89..6ae7b48 100644
--- a/tests/language/example_constructor_test.dart
+++ b/tests/language/example_constructor_test.dart
@@ -6,7 +6,7 @@
 var trace = "";
 
 int rec(int i) {
-  trace = trace.concat("$i ");
+  trace += "$i ";
   return i;
 }
 
diff --git a/tests/language/field_initialization_order_test.dart b/tests/language/field_initialization_order_test.dart
index 6890895..3bf24b6 100644
--- a/tests/language/field_initialization_order_test.dart
+++ b/tests/language/field_initialization_order_test.dart
@@ -9,7 +9,7 @@
 class Mark {
   static StringBuffer buffer;
   Mark(value) {
-    buffer.add('$value.');
+    buffer.write('$value.');
   }
 }
 
diff --git a/tests/language/final_field_initialization_order_test.dart b/tests/language/final_field_initialization_order_test.dart
index bd7c053..8735046 100644
--- a/tests/language/final_field_initialization_order_test.dart
+++ b/tests/language/final_field_initialization_order_test.dart
@@ -10,7 +10,7 @@
 class Mark {
   static StringBuffer buffer;
   Mark(value) {
-    buffer.add('$value.');
+    buffer.write('$value.');
   }
 }
 
diff --git a/tests/language/generic_is_check_test.dart b/tests/language/generic_is_check_test.dart
new file mode 100644
index 0000000..4e13c1f
--- /dev/null
+++ b/tests/language/generic_is_check_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A<T> {
+  foo() => this is A<int>;
+}
+
+main() {
+  Expect.isTrue(new A().foo());
+  Expect.isTrue(new A<int>().foo());
+  Expect.isFalse(new A<String>().foo());
+}
diff --git a/tests/language/illegal_invocation_test.dart b/tests/language/illegal_invocation_test.dart
index 51d722d..e0329ce 100644
--- a/tests/language/illegal_invocation_test.dart
+++ b/tests/language/illegal_invocation_test.dart
@@ -3,34 +3,13 @@
 // BSD-style license that can be found in the LICENSE file.
 // Dart test program for constructors and initializers.
 //
-// Test for issue 1393.  Invoking a type alias or library prefix name caused
-// an internal error in dartc
-//
-import "illegal_invocation_lib.dart" as foo;  /// 02: compile-time error
+// Test for issue 1393.  Invoking a library prefix name caused an internal error
+// in dartc.
 
-typedef void a();                 /// 01: compile-time error
-
-class Foo {}                      /// 04: compile-time error
-
-class Bar<T> {
-  method() {
-    T();                          /// 05: compile-time error
-  }
-}
+import "illegal_invocation_lib.dart" as foo;  /// 01: compile-time error
 
 main() {
-  a();                           /// 01: continued
-
   // probably what the user meant was foo.foo(), but the qualifier refers
   // to the library prefix, not the method defined within the library.
-  foo();                         /// 02: continued
-
-  outer: for (int i =0 ; i < 1; i++) {
-    outer();                     /// 03: compile-time error
-  }
-
-  Foo();                         /// 04: continued
-
-  var bar = new Bar<int>();
-  bar.method();                  /// 05: continued
+  foo();                         /// 01: continued
 }
diff --git a/tests/language/interceptor7_test.dart b/tests/language/interceptor7_test.dart
new file mode 100644
index 0000000..853523a
--- /dev/null
+++ b/tests/language/interceptor7_test.dart
@@ -0,0 +1,14 @@
+// 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 dart2js uses the right interceptor when call a method on
+// something that has type number.
+
+var array = [];
+
+main() {
+  array.add(false);
+  var x = array[0] ? 1.5 : 2;
+  Expect.isTrue(x.isEven);
+}
diff --git a/tests/language/invocation_mirror2_test.dart b/tests/language/invocation_mirror2_test.dart
index de6fcc2..e320835 100644
--- a/tests/language/invocation_mirror2_test.dart
+++ b/tests/language/invocation_mirror2_test.dart
@@ -2,6 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+class GetName {
+  set flif(_) => "flif=";
+}
+
+String getName(im) => im.invokeOn(new GetName());
+
 class C {
   var im;
   noSuchMethod(im) => this.im = im;
@@ -11,6 +17,6 @@
 main() {
  var c = new C();
  c.flif = 42;
- Expect.equals('flif=', c.im.memberName);
+ Expect.equals('flif=', getName(c.im));
  Expect.equals(42, c.im.positionalArguments[0]);
 }
diff --git a/tests/language/language.status b/tests/language/language.status
index cf89e4a7..c767089 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -58,13 +58,13 @@
 
 on_catch_malformed_type_test: Fail # Issue 8601
 
-mixin_illegal_syntax_test/none: Fail
-mixin_type_parameters_mixin_test: Fail
-mixin_type_parameters_super_test: Fail
-mixin_type_parameters_super_extends_test: Fail
+mixin_mixin_test: Fail
 mixin_lib_extends_field_test: Fail
 
-type_variable_field_initializer_closure_test: Crash # issue 8847 
+type_variable_field_initializer_closure_test: Crash # issue 8847
+
+super_getter_setter_test: Fail # Issue 8917
+super_operator_index7_test: Fail # Issue 8918
 
 [ $compiler == none && ($system == macos || $system == linux) && $arch == ia32 && $checked ]
 gc_test: Skip  # Issue 1487, flaky.
@@ -90,9 +90,6 @@
 compile_time_constant_checked3_test/05: Fail, OK
 compile_time_constant_checked3_test/06: Fail, OK
 
-[ $compiler == none && $checked ]
-default_factory2_test/01: Fail # Issue 7075.
-
 [ $compiler == dartc ]
 class_literal_test/none : Fail # Issue 7630.
 import_private_test/01: Fail # Issue 8365.
@@ -305,7 +302,7 @@
 
 
 [ $compiler == none && $runtime == drt ]
-type_variable_field_initializer_closure_test: Fail # issue 8847 
+type_variable_field_initializer_closure_test: Fail # issue 8847
 final_variable_assignment_test/01: Fail
 final_variable_assignment_test/02: Fail
 final_variable_assignment_test/03: Fail
@@ -358,11 +355,9 @@
 on_catch_malformed_type_test: Fail # Issue 8601
 
 # Mixins fail on the VM.
-mixin_illegal_syntax_test/none: Fail            # VM issue
-mixin_illegal_constructor_test/none: Fail       # VM issue
-mixin_type_parameters_mixin_test: Fail          # VM issue
-mixin_type_parameters_super_test: Fail          # VM issue
-mixin_type_parameters_super_extends_test: Fail  # VM issue
+mixin_mixin_test: Fail                      # VM issue
+mixin_illegal_constructor_test/none: Fail   # VM issue
+
 
 # Malformed types not handled as unresolved:
 import_core_prefix_test: Fail
@@ -376,9 +371,6 @@
 
 bad_override_test/01: Fail
 bad_override_test/02: Fail
-illegal_invocation_test/01: Fail, OK # Typedef literals are expressions now.
-illegal_invocation_test/04: Fail, OK # Class literals are expressions now.
-illegal_invocation_test/05: Fail, OK # Type variables are expressions now.
 
 first_class_types_constants_test: Fail # Issue 6282
 
@@ -414,7 +406,6 @@
 final_syntax_test/04: Fail # http://dartbug.com/5519
 getter_no_setter_test/01: Fail # http://dartbug.com/5519
 getter_no_setter2_test/01: Fail # http://dartbug.com/5519
-illegal_invocation_test/03: Fail # http://dartbug.com/5519
 isnot_malformed_type_test/01: Fail # http://dartbug.com/5519
 method_override2_test/01: Fail # http://dartbug.com/5519
 named_parameters_aggregated_test/01: Fail # http://dartbug.com/5519
@@ -483,8 +474,6 @@
 function_type_alias5_test/01: Fail
 function_type_alias5_test/02: Fail
 function_type_alias7_test/00: Fail
-function_type_parameter2_test: Fail
-function_type_parameter_test: Fail
 implicit_scope_test: Fail
 instanceof3_test: Fail
 parameter_initializer6_negative_test: Fail # Issue 3502
@@ -543,7 +532,10 @@
 type_error_test: Fail, OK # VM bug: http://dartbug.com/5280
 type_parameter_literal_test: Fail
 
-type_variable_field_initializer_closure_test: Crash # VM bug: issue 8847 
+type_variable_field_initializer_closure_test: Crash # VM bug: issue 8847
+
+super_getter_setter_test: Fail # VM bug: issue 8917
+super_operator_index7_test: Fail # VM bug: issue 8918
 
 [ $compiler == dart2dart && $minified ]
 
@@ -553,7 +545,6 @@
 import_core_prefix_test: Pass
 prefix22_test: Pass
 invocation_mirror_test: Fail, OK # hardcoded names.
-invocation_mirror2_test: Fail, OK # hardcoded names.
 super_call4_test: Fail, OK # hardcoded names.
 
 [ $arch == arm ]
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index ccd4b5c..356649c 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -54,6 +54,7 @@
 type_variable_bounds2_test/03: Fail
 type_variable_bounds2_test/05: Fail
 type_variable_bounds2_test/06: Pass # For the wrong reasons.
+type_variable_bounds3_test/00: Fail
 f_bounded_quantification_test/01: Fail
 f_bounded_quantification_test/02: Fail
 closure_type_test: Fail # does not detect type error in checked mode.
@@ -97,10 +98,8 @@
 compile_time_constant_checked3_test/06: Fail, OK
 
 [ $compiler == dart2js ]
-type_variable_field_initializer_closure_test: Fail # Issue 8848
 branch_canonicalization_test: Fail # Issue 638.
 div_with_power_of_two_test: Fail # Issue 8301.
-call_operator_test: Fail # Issue 7622.
 class_literal_test: Fail # Issue 7626.
 identical_closure2_test: Fail # Issues 563, 1533
 invocation_mirror_test: Fail
@@ -127,13 +126,10 @@
 constructor_named_arguments_test/01: Fail # http://dartbug.com/5519
 getter_no_setter2_test/01: Fail # http://dartbug.com/5519
 getter_no_setter_test/01: Fail # http://dartbug.com/5519
-illegal_invocation_test/03: Fail # http://dartbug.com/5519
 isnot_malformed_type_test/01: Fail # http://dartbug.com/5519
 not_enough_positional_arguments_test/01: Fail # http://dartbug.com/5519
 
 constructor_negative_test: Pass # Wrong reason: the expression 'C()' is valid with class literals.
-illegal_invocation_test/01: Fail, OK # Typedef literals are expressions now.
-illegal_invocation_test/04: Fail, OK # Class literals are expressions now.
 
 throw_expr_test: Fail
 metadata_test: Fail # Metadata on type parameters not supported.
@@ -142,7 +138,6 @@
 
 compile_time_constant8_test: Fail # We don't take the generic type into account yet.
 canonical_const_test: Fail # We don't take the generic type into account yet.
-type_parameter_literal_test: Fail # Type parameters aren't supported as literals yet.
 
 # Support for optional parameters not conform to latest spec.
 function_type_alias_test: Fail
@@ -172,8 +167,6 @@
 function_type_alias5_test/02: Fail # visitIs for typedefs not implemented
 function_type_alias7_test/00: Fail # wrongly accepts default values in typedef
 function_type_alias_test: Fail # cannot resolve type Fun
-function_type_parameter2_test: Fail # Internal Error: expected optional parameters
-function_type_parameter_test: Fail # Internal Error: expected optional parameters
 generic_test: Fail # cannot resolve type T
 get_set_syntax_test/00: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
 get_set_syntax_test/01: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
@@ -203,7 +196,6 @@
 named_parameters_aggregated_test/05: Fail # Absence of positional parameters before named parameters does not trigger static type warning.
 pseudo_kw_test: Fail # Unexpected token '('
 super_implicit_closure_test: Fail # internal error: super property read not implemented
-super_operator_test: Fail # internal error: super property store not implemented
 switch_label_test: Fail # error: target of continue is not a loop or switch case
 on_catch_malformed_type_test: Fail # Malformed types cause compile-time errors.
 
@@ -306,7 +298,6 @@
 const_syntax_test/03: Fail # Missing error for uninitialized final field.
 
 canonical_const2_test: Fail, OK # Dart2js only has doubles.
-div_by_zero_test: Fail, OK # Dart2js only has doubles.
 
 bit_operations_test: Fail, OK # Tests bit operations outside the 32 bit range.
 # The following test will start to fail again once dart2js implements the
@@ -322,9 +313,6 @@
 
 assign_top_method_test: Fail
 
-super_operator_index2_test: Fail # Issue 8800
-super_operator_index_test/01: Fail # Issue 8800
-
 [ $compiler == dart2js && $runtime == none ]
 *: Fail, Pass # TODO(ahe): Triage these tests.
 
@@ -334,7 +322,6 @@
 
 
 [ $compiler == dart2js && $runtime == ie9 ]
-div_by_zero_test: Fail
 double_to_string_as_exponential3_test: Fail
 double_to_string_as_fixed_test: Fail
 double_to_string_as_precision3_test: Fail
diff --git a/tests/language/list_test.dart b/tests/language/list_test.dart
index 1a9986f..58000c7 100644
--- a/tests/language/list_test.dart
+++ b/tests/language/list_test.dart
@@ -57,6 +57,11 @@
 
     Expect.throws(() {
       List a = new List(4);
+      a.setRange(1, 1, const [1, 2, 3, 4], null);
+    });
+
+    Expect.throws(() {
+      List a = new List(4);
       a.setRange(10, 1, a, 1);
     }, (e) => e is RangeError);
 
diff --git a/tests/language/no_such_method_test.dart b/tests/language/no_such_method_test.dart
index 0bd9da3..e23ca5b 100644
--- a/tests/language/no_such_method_test.dart
+++ b/tests/language/no_such_method_test.dart
@@ -3,6 +3,13 @@
 // BSD-style license that can be found in the LICENSE file.
 // Dart test program testing that NoSuchMethod is properly called.
 
+class GetName {
+  foo({a, b}) => "foo";
+  moo({b}) => "moo";
+}
+
+String getName(im) => im.invokeOn(new GetName());
+
 class NoSuchMethodTest {
 
   foo({a : 10, b : 20}) {
@@ -10,7 +17,7 @@
   }
 
   noSuchMethod(InvocationMirror im) {
-    Expect.equals("moo", im.memberName);
+    Expect.equals("moo", getName(im));
     Expect.equals(0, im.positionalArguments.length);
     Expect.equals(1, im.namedArguments.length);
     return foo(b:im.namedArguments["b"]);
diff --git a/tests/language/null_method_test.dart b/tests/language/null_method_test.dart
new file mode 100644
index 0000000..97befa1
--- /dev/null
+++ b/tests/language/null_method_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+// Regression test for dart2js that used to not compile null methods
+// in the presence of typed selectors.
+
+class C {
+  foo(s) {
+    return s.hashCode;
+  }
+}
+
+main() {
+  var c = new C();
+  Expect.isNotNull(c.foo('foo'));
+  Expect.isNotNull(c.foo(null));
+}
diff --git a/tests/language/overridden_no_such_method.dart b/tests/language/overridden_no_such_method.dart
index b06fc5c..127a53d 100644
--- a/tests/language/overridden_no_such_method.dart
+++ b/tests/language/overridden_no_such_method.dart
@@ -3,12 +3,18 @@
 // BSD-style license that can be found in the LICENSE file.
 // Dart test program testing overridden messageNotUnderstood.
 
+class GetName {
+  foo(a, b) => "foo";
+}
+
+String getName(im) => im.invokeOn(new GetName());
+
 class OverriddenNoSuchMethod {
 
   OverriddenNoSuchMethod() {}
 
   noSuchMethod(InvocationMirror mirror) {
-    Expect.equals("foo", mirror.memberName);
+    Expect.equals("foo", getName(mirror));
     // 'foo' was called with two parameters (not counting receiver).
     List args = mirror.positionalArguments;
     Expect.equals(2, args.length);
diff --git a/tests/language/string_interpolation_and_buffer.dart b/tests/language/string_interpolation_and_buffer.dart
index 1ce359d..ddcdd4e 100644
--- a/tests/language/string_interpolation_and_buffer.dart
+++ b/tests/language/string_interpolation_and_buffer.dart
@@ -41,13 +41,13 @@
     var sb;
     if (checkedMode && object != null) {
       try {
-        sb = new StringBuffer().add(wrap(object));
+        sb = new StringBuffer()..write(wrap(object));
       } on TypeError {
         return 'Error';
       }
     } else {
       try {
-        sb = new StringBuffer().add(wrap(object));
+        sb = new StringBuffer()..write(wrap(object));
       } on ArgumentError {
         return 'Error';
       }
diff --git a/tests/language/super_field_test.dart b/tests/language/super_field_test.dart
index 88f6c2d..7245d4c 100644
--- a/tests/language/super_field_test.dart
+++ b/tests/language/super_field_test.dart
@@ -18,7 +18,7 @@
 class B extends A {
   B() : super() {}
   String greeting() {
-    return "Hola ".concat(super.greeting());
+    return "Hola " + super.greeting();
   }
 }
 
@@ -26,10 +26,10 @@
 class C extends B {
   C() : super() {}
   String greeting() {
-    return "Servus ".concat(super.greeting());
+    return "Servus " + super.greeting();
   }
   String get city {
-    return "Basel ".concat(super.city);
+    return "Basel " + super.city;
   }
 }
 
diff --git a/tests/language/super_getter_setter_test.dart b/tests/language/super_getter_setter_test.dart
new file mode 100644
index 0000000..80ac380
--- /dev/null
+++ b/tests/language/super_getter_setter_test.dart
@@ -0,0 +1,103 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+  var missingSetterField;
+  var missingGetterField;
+  var getterInSuperClassField;
+  var setterInSuperClassField;
+  var getterSetterField;
+  var missingAllField;
+  var indexField = new List(2);
+
+  set setterInSuperClass(a) { setterInSuperClassField = a; }
+  get getterInSuperClass => getterInSuperClassField;
+}
+
+class B extends A {
+  get missingSetter => missingSetterField;
+  get setterInSuperClass => setterInSuperClassField;
+
+  set missingGetter(a) { missingGetterField = a; }
+  set getterInSuperClass(a) { getterInSuperClassField = a; }
+
+  get getterSetter => getterSetterField;
+  set getterSetter(a) { getterSetterField = a; }
+
+  operator[](index) => indexField[index];
+  operator[]=(index, value) { indexField[index] = value; }
+
+  noSuchMethod(InvocationMirror im) {
+    if (im.memberName.startsWith('missingSetter')) {
+      Expect.isTrue(im.isSetter);
+      missingSetterField = im.positionalArguments[0];
+    } else if (im.memberName.startsWith('missingGetter')) {
+      Expect.isTrue(im.isGetter);
+      return missingGetterField;
+    } else if (im.memberName.startsWith('missingAll') && im.isGetter) {
+      return missingAllField;
+    } else if (im.memberName.startsWith('missingAll') && im.isSetter) {
+      missingAllField = im.positionalArguments[0];
+    } else {
+      Expect.fail('Should not reach here');
+    }
+  }
+}
+
+class C extends B {
+  test() {
+    Expect.equals(42, super.missingSetter = 42);
+    Expect.equals(42, super.missingSetter);
+    Expect.equals(43, super.missingSetter += 1);
+    Expect.equals(43, super.missingSetter);
+    Expect.equals(43, super.missingSetter++);
+    Expect.equals(44, super.missingSetter);
+
+    Expect.equals(42, super.missingGetter = 42);
+    Expect.equals(42, super.missingGetter);
+    Expect.equals(43, super.missingGetter += 1);
+    Expect.equals(43, super.missingGetter);
+    Expect.equals(43, super.missingGetter++);
+    Expect.equals(44, super.missingGetter);
+
+    Expect.equals(42, super.setterInSuperClass = 42);
+    Expect.equals(42, super.setterInSuperClass);
+    Expect.equals(43, super.setterInSuperClass += 1);
+    Expect.equals(43, super.setterInSuperClass);
+    Expect.equals(43, super.setterInSuperClass++);
+    Expect.equals(44, super.setterInSuperClass);
+
+    Expect.equals(42, super.getterInSuperClass = 42);
+    Expect.equals(42, super.getterInSuperClass);
+    Expect.equals(43, super.getterInSuperClass += 1);
+    Expect.equals(43, super.getterInSuperClass);
+    Expect.equals(43, super.getterInSuperClass++);
+    Expect.equals(44, super.getterInSuperClass);
+
+    Expect.equals(42, super.missingAll = 42);
+    Expect.equals(42, super.missingAll);
+    Expect.equals(43, super.missingAll += 1);
+    Expect.equals(43, super.missingAll);
+    Expect.equals(43, super.missingAll++);
+    Expect.equals(44, super.missingAll);
+
+    Expect.equals(42, super[0] = 42);
+    Expect.equals(42, super[0]);
+    Expect.equals(43, super[0] += 1);
+    Expect.equals(43, super[0]);
+    Expect.equals(43, super[0]++);
+    Expect.equals(44, super[0]);
+
+    Expect.equals(2, super[0] = 2);
+    Expect.equals(2, super[0]);
+    Expect.equals(3, super[0] += 1);
+    Expect.equals(3, super[0]);
+    Expect.equals(3, super[0]++);
+    Expect.equals(4, super[0]);
+  }
+}
+
+main() {
+  new C().test();
+}
diff --git a/tests/language/super_operator_index3_test.dart b/tests/language/super_operator_index3_test.dart
new file mode 100644
index 0000000..f456ba7
--- /dev/null
+++ b/tests/language/super_operator_index3_test.dart
@@ -0,0 +1,36 @@
+// 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 for operator[]= resolved in super class.
+
+class A {
+  var indexField = new List(2);
+  operator[]=(index, value) { indexField[index] = value; }
+}
+
+class B extends A {
+  operator[](index) => indexField[index];
+}
+
+class C extends B {
+  test() {
+    Expect.equals(42, super[0] = 42);
+    Expect.equals(42, super[0]);
+    Expect.equals(43, super[0] += 1);
+    Expect.equals(43, super[0]);
+    Expect.equals(43, super[0]++);
+    Expect.equals(44, super[0]);
+
+    Expect.equals(2, super[0] = 2);
+    Expect.equals(2, super[0]);
+    Expect.equals(3, super[0] += 1);
+    Expect.equals(3, super[0]);
+    Expect.equals(3, super[0]++);
+    Expect.equals(4, super[0]);
+  }
+}
+
+main() {
+  new C().test();
+}
diff --git a/tests/language/super_operator_index4_test.dart b/tests/language/super_operator_index4_test.dart
new file mode 100644
index 0000000..bb31116
--- /dev/null
+++ b/tests/language/super_operator_index4_test.dart
@@ -0,0 +1,36 @@
+// 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 for operator[] resolved in the super class.
+
+class A {
+  var indexField = new List(2);
+  operator[](index) => indexField[index];
+}
+
+class B extends A {
+  operator[]=(index, value) { indexField[index] = value; }
+}
+
+class C extends B {
+  test() {
+    Expect.equals(42, super[0] = 42);
+    Expect.equals(42, super[0]);
+    Expect.equals(43, super[0] += 1);
+    Expect.equals(43, super[0]);
+    Expect.equals(43, super[0]++);
+    Expect.equals(44, super[0]);
+
+    Expect.equals(2, super[0] = 2);
+    Expect.equals(2, super[0]);
+    Expect.equals(3, super[0] += 1);
+    Expect.equals(3, super[0]);
+    Expect.equals(3, super[0]++);
+    Expect.equals(4, super[0]);
+  }
+}
+
+main() {
+  new C().test();
+}
diff --git a/tests/language/super_operator_index5_test.dart b/tests/language/super_operator_index5_test.dart
new file mode 100644
index 0000000..ca14bb7
--- /dev/null
+++ b/tests/language/super_operator_index5_test.dart
@@ -0,0 +1,41 @@
+// 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 for unresolved super[]=.
+
+class A {
+  var indexField = new List(2);
+  operator[](index) => indexField[index];
+
+  noSuchMethod(InvocationMirror im) {
+    if (im.memberName == '[]=') {
+      Expect.equals(2, im.positionalArguments.length);
+      indexField[im.positionalArguments[0]] = im.positionalArguments[1];
+    } else {
+      Expect.fail('Should not reach here');
+    }
+  }
+}
+
+class B extends A {
+  test() {
+    Expect.equals(42, super[0] = 42);
+    Expect.equals(42, super[0]);
+    Expect.equals(43, super[0] += 1);
+    Expect.equals(43, super[0]);
+    Expect.equals(43, super[0]++);
+    Expect.equals(44, super[0]);
+
+    Expect.equals(2, super[0] = 2);
+    Expect.equals(2, super[0]);
+    Expect.equals(3, super[0] += 1);
+    Expect.equals(3, super[0]);
+    Expect.equals(3, super[0]++);
+    Expect.equals(4, super[0]);
+  }
+}
+
+main() {
+  new B().test();
+}
diff --git a/tests/language/super_operator_index6_test.dart b/tests/language/super_operator_index6_test.dart
new file mode 100644
index 0000000..70e2bcb
--- /dev/null
+++ b/tests/language/super_operator_index6_test.dart
@@ -0,0 +1,41 @@
+// 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 for unresolved super[].
+
+class A {
+  var indexField = new List(2);
+  operator[]=(index, value) { indexField[index] = value; }
+
+  noSuchMethod(InvocationMirror im) {
+    if (im.memberName == '[]') {
+      Expect.equals(1, im.positionalArguments.length);
+      return indexField[im.positionalArguments[0]];
+    } else {
+      Expect.fail('Should not reach here');
+    }
+  }
+}
+
+class B extends A {
+  test() {
+    Expect.equals(42, super[0] = 42);
+    Expect.equals(42, super[0]);
+    Expect.equals(43, super[0] += 1);
+    Expect.equals(43, super[0]);
+    Expect.equals(43, super[0]++);
+    Expect.equals(44, super[0]);
+
+    Expect.equals(2, super[0] = 2);
+    Expect.equals(2, super[0]);
+    Expect.equals(3, super[0] += 1);
+    Expect.equals(3, super[0]);
+    Expect.equals(3, super[0]++);
+    Expect.equals(4, super[0]);
+  }
+}
+
+main() {
+  new B().test();
+}
diff --git a/tests/language/super_operator_index7_test.dart b/tests/language/super_operator_index7_test.dart
new file mode 100644
index 0000000..112d882
--- /dev/null
+++ b/tests/language/super_operator_index7_test.dart
@@ -0,0 +1,43 @@
+// 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 for unresolved super[] and super[]=.
+
+class A {
+  var indexField = new List(2);
+
+  noSuchMethod(InvocationMirror im) {
+    if (im.memberName == '[]=') {
+      Expect.equals(2, im.positionalArguments.length);
+      indexField[im.positionalArguments[0]] = im.positionalArguments[1];
+    } else if (im.memberName == '[]') {
+      Expect.equals(1, im.positionalArguments.length);
+      return indexField[im.positionalArguments[0]];
+    } else {
+      Expect.fail('Should not reach here');
+    }
+  }
+}
+
+class B extends A {
+  test() {
+    Expect.equals(42, super[0] = 42);
+    Expect.equals(42, super[0]);
+    Expect.equals(43, super[0] += 1);
+    Expect.equals(43, super[0]);
+    Expect.equals(43, super[0]++);
+    Expect.equals(44, super[0]);
+
+    Expect.equals(2, super[0] = 2);
+    Expect.equals(2, super[0]);
+    Expect.equals(3, super[0] += 1);
+    Expect.equals(3, super[0]);
+    Expect.equals(3, super[0]++);
+    Expect.equals(4, super[0]);
+  }
+}
+
+main() {
+  new B().test();
+}
diff --git a/tests/language/super_setter_interceptor_test.dart b/tests/language/super_setter_interceptor_test.dart
new file mode 100644
index 0000000..d9ef157
--- /dev/null
+++ b/tests/language/super_setter_interceptor_test.dart
@@ -0,0 +1,36 @@
+// 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 we correctly intercept super getter and setter calls.
+
+var expected;
+
+class A {
+  set length(a) { Expect.equals(expected, a); }
+  get length => 41;
+}
+
+class B extends A {
+  test() {
+    expected = 42;
+    Expect.equals(42, super.length = 42);
+    expected = 42;
+    Expect.equals(42, super.length += 1);
+    expected = 42;
+    Expect.equals(42, ++super.length);
+    expected = 40;
+    Expect.equals(40, --super.length);
+    expected = 42;
+    Expect.equals(41, super.length++);
+    expected = 40;
+    Expect.equals(41, super.length--);
+    Expect.equals(41, super.length);
+  }
+}
+
+main() {
+  // Ensures the list class is instantiated.
+  print([]);
+  new B().test();
+}
diff --git a/tests/language/type_guard_conversion_test.dart b/tests/language/type_guard_conversion_test.dart
index 451fbae..a008b62 100644
--- a/tests/language/type_guard_conversion_test.dart
+++ b/tests/language/type_guard_conversion_test.dart
@@ -12,7 +12,7 @@
   } while (b != 'r');
 
   if (a is Comparable) {
-    a = a.concat(a);
+    a += a;
   }
   Expect.equals('barbar', a);
 }
diff --git a/tests/language/type_intersection_test.dart b/tests/language/type_intersection_test.dart
new file mode 100644
index 0000000..a6e2603
--- /dev/null
+++ b/tests/language/type_intersection_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+// Regression test for dart2js that used to consider that the
+// intersection of [Comparable] and [num] is conflicting.
+
+class A {
+  foo(a, Comparable b) => a == b;
+  bar(a, Comparable b) => b == a;
+}
+
+main() {
+  Expect.isFalse(new A().foo(1, 'foo'));
+  Expect.isTrue(new A().foo(1, 1));
+  Expect.isFalse(new A().bar(1, 'foo'));
+  Expect.isTrue(new A().bar(1, 1));
+}
diff --git a/tests/language/type_variable_bounds3_test.dart b/tests/language/type_variable_bounds3_test.dart
new file mode 100644
index 0000000..876ed94
--- /dev/null
+++ b/tests/language/type_variable_bounds3_test.dart
@@ -0,0 +1,19 @@
+// 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 of parameterized types with invalid bounds.
+
+class A<K extends int> {
+}
+
+class B<X, Y> {
+  foo(x) {
+    return x is A<X>;  /// 00: dynamic type error
+  }
+}
+
+main() {
+  var b = new B<double, double>();
+  b.foo(new A());
+}
diff --git a/tests/language/type_variable_nested_test.dart b/tests/language/type_variable_nested_test.dart
new file mode 100644
index 0000000..5611ea74
--- /dev/null
+++ b/tests/language/type_variable_nested_test.dart
@@ -0,0 +1,31 @@
+// 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.
+
+// Regression test for
+// http://code.google.com/p/dart/issues/detail?id=9050.
+
+class A<T> {
+}
+
+class B<T> {
+  var _copy;
+  B() {
+    // We used to not register the dependency between List and B.
+    _copy = new List<A<T>>();
+  }
+}
+
+main() {
+  var a = new B();
+  Expect.isFalse(a._copy is List<int>);
+  Expect.isTrue(a._copy is List<A>);
+  Expect.isTrue(a._copy is List<A<int>>);
+
+  a = new B<String>();
+  Expect.isFalse(a._copy is List<String>);
+  Expect.isTrue(a._copy is List<A>);
+  Expect.isTrue(a._copy is List<A<String>>);
+  Expect.isTrue(a._copy is List<A<Object>>);
+  Expect.isFalse(a._copy is List<A<int>>);
+}
diff --git a/tests/language/value_range3_test.dart b/tests/language/value_range3_test.dart
new file mode 100644
index 0000000..6b5e169
--- /dev/null
+++ b/tests/language/value_range3_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+  copy(array, index1, index2) {
+    if (index1 < index2 + index2) {
+      // dart2js used to remove the bounds check.
+      return array[index1];
+    }
+  }
+}
+
+main() {
+  Expect.throws(() => new A().copy(new List(0), 0, 1), (e) => e is RangeError);
+}
diff --git a/tests/lib/analyzer/analyze_library.status b/tests/lib/analyzer/analyze_library.status
new file mode 100644
index 0000000..bfa469b
--- /dev/null
+++ b/tests/lib/analyzer/analyze_library.status
@@ -0,0 +1,3 @@
+# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
diff --git a/tests/lib/analyzer/test_config.dart b/tests/lib/analyzer/test_config.dart
new file mode 100644
index 0000000..2189bcf
--- /dev/null
+++ b/tests/lib/analyzer/test_config.dart
@@ -0,0 +1,31 @@
+// 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 analyze_library_test_config;
+
+import 'dart:io';
+import '../../../tools/testing/dart/test_suite.dart';
+
+class AnalyzeLibraryTestSuite extends DartcCompilationTestSuite {
+  final libraries = [ 'async', 'core', 'crypto', 'io', 'isolate', 'json',
+                      'math', 'mirrors', 'scalarlist', 'typeddata', 'uri',
+                      'utf' ];
+
+  AnalyzeLibraryTestSuite(Map configuration)
+      : super(configuration,
+              'analyze_library',
+              'sdk',
+              [ 'lib' ],
+              ['tests/lib/analyzer/analyze_library.status'],
+              allStaticClean: true);
+
+  bool isTestFile(String filename) {
+    var sep = Platform.pathSeparator;
+    return libraries.any((String lib) {
+      return filename.endsWith('lib$sep$lib$sep$lib.dart');
+    });
+  }
+
+  bool get listRecursively => true;
+}
diff --git a/tests/lib/async/event_helper.dart b/tests/lib/async/event_helper.dart
index c8a3cb2..db5189c 100644
--- a/tests/lib/async/event_helper.dart
+++ b/tests/lib/async/event_helper.dart
@@ -7,7 +7,7 @@
 import 'dart:async';
 
 abstract class Event {
-  void replay(StreamSink sink);
+  void replay(EventSink sink);
 }
 
 class DataEvent implements Event {
@@ -15,7 +15,7 @@
 
   DataEvent(this.data);
 
-  void replay(StreamSink sink) { sink.add(data); }
+  void replay(EventSink sink) { sink.add(data); }
 
   int get hashCode => data.hashCode;
 
@@ -33,7 +33,7 @@
 
   ErrorEvent(this.error);
 
-  void replay(StreamSink sink) { sink.signalError(error); }
+  void replay(EventSink sink) { sink.addError(error); }
 
   int get hashCode => error.error.hashCode;
 
@@ -49,7 +49,7 @@
 class DoneEvent implements Event {
   const DoneEvent();
 
-  void replay(StreamSink sink) { sink.close(); }
+  void replay(EventSink sink) { sink.close(); }
 
   int get hashCode => 42;
 
@@ -59,7 +59,7 @@
 }
 
 /** Collector of events. */
-class Events implements StreamSink {
+class Events implements EventSink {
   final List<Event> events = [];
 
   Events();
@@ -72,10 +72,12 @@
   factory Events.capture(Stream stream,
                          { bool unsubscribeOnError: false }) = CaptureEvents;
 
-  // StreamSink interface.
-  add(var value) { events.add(new DataEvent(value)); }
+  // EventSink interface.
+  void add(var value) {
+    events.add(new DataEvent(value));
+  }
 
-  void signalError(AsyncError error) {
+  void addError(AsyncError error) {
     events.add(new ErrorEvent(error));
   }
 
@@ -84,10 +86,10 @@
   }
 
   // Error helper for creating errors manually..
-  void error(var value) { signalError(new AsyncError(value, null)); }
+  void error(var value) { addError(new AsyncError(value, null)); }
 
   /** Replay the captured events on a sink. */
-  void replay(StreamSink sink) {
+  void replay(EventSink sink) {
     for (int i = 0; i < events.length; i++) {
       events[i].replay(sink);
     }
@@ -139,13 +141,13 @@
       : onDoneSignal = new Completer() {
     this.unsubscribeOnError = unsubscribeOnError;
     subscription = stream.listen(add,
-                                 onError: signalError,
+                                 onError: addError,
                                  onDone: close,
                                  unsubscribeOnError: unsubscribeOnError);
   }
 
-  void signalError(AsyncError error) {
-    super.signalError(error);
+  void addError(AsyncError error) {
+    super.addError(error);
     if (unsubscribeOnError) onDoneSignal.complete(null);
   }
 
diff --git a/tests/lib/async/run_async2_test.dart b/tests/lib/async/run_async2_test.dart
new file mode 100644
index 0000000..0343c79
--- /dev/null
+++ b/tests/lib/async/run_async2_test.dart
@@ -0,0 +1,21 @@
+// 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 run_async_test;
+
+import 'dart:async';
+import '../../../pkg/unittest/lib/unittest.dart';
+
+main() {
+  // Check that the callbacks are executed in order.
+  test("run async in order test", () {
+    int lastCallback = -1;
+    for (int i = 0; i < 100; i++) {
+      runAsync(expectAsync0(() {
+        Expect.equals(lastCallback, i - 1);
+        lastCallback = i;
+      }));
+    }
+  });
+}
diff --git a/tests/lib/async/run_async3_test.dart b/tests/lib/async/run_async3_test.dart
new file mode 100644
index 0000000..00eaf9b
--- /dev/null
+++ b/tests/lib/async/run_async3_test.dart
@@ -0,0 +1,38 @@
+// 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 run_async_test;
+
+import 'dart:async';
+import '../../../pkg/unittest/lib/unittest.dart';
+
+main() {
+  test("run async timer after async test", () {
+    // Check that Timers don't run before the async callbacks.
+    bool timerCallbackExecuted = false;
+
+    Timer.run(expectAsync0(() { timerCallbackExecuted = true; }));
+
+    runAsync(expectAsync0(() {
+      Expect.isFalse(timerCallbackExecuted);
+    }));
+
+    runAsync(expectAsync0(() {
+      // Busy loop.
+      var sum = 1;
+      var sw = new Stopwatch()..start();
+      while (sw.elapsedMilliseconds < 5) {
+        sum++;
+      }
+      if (sum == 0) throw "bad";  // Just to use the result.
+      runAsync(expectAsync0(() {
+        Expect.isFalse(timerCallbackExecuted);
+      }));
+    }));
+
+    runAsync(expectAsync0(() {
+      Expect.isFalse(timerCallbackExecuted);
+    }));
+  });
+}
diff --git a/tests/lib/async/run_async4_test.dart b/tests/lib/async/run_async4_test.dart
new file mode 100644
index 0000000..46967df
--- /dev/null
+++ b/tests/lib/async/run_async4_test.dart
@@ -0,0 +1,37 @@
+// 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 run_async_test;
+
+import 'dart:async';
+import 'dart:isolate';
+
+void startTest(SendPort finishPort, replyPort) {
+  int invokedCallbacks = 0;
+
+  for (int i = 0; i < 100; i++) {
+    runAsync(() {
+      invokedCallbacks++;
+      if (invokedCallbacks == 100) finishPort.send("done");
+      if (i == 50) throw new RuntimeError("ignore exception");
+    });
+  }
+}
+
+runTest() {
+  port.receive(startTest);
+}
+
+bool globalErrorHandler(IsolateUnhandledException e) {
+  return e.source is RuntimeError && e.source.message == "ignore exception";
+}
+
+main() {
+  var port = new ReceivePort();
+  var timer;
+  SendPort otherIsolate = spawnFunction(runTest, globalErrorHandler);
+  otherIsolate.send(port.toSendPort());
+  port.receive((msg, replyPort) { port.close(); timer.cancel(); });
+  timer = new Timer(const Duration(seconds: 2), () { throw "failed"; });
+}
diff --git a/tests/lib/async/run_async5_test.dart b/tests/lib/async/run_async5_test.dart
new file mode 100644
index 0000000..4565282
--- /dev/null
+++ b/tests/lib/async/run_async5_test.dart
@@ -0,0 +1,42 @@
+// 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 run_async_test;
+
+import 'dart:async';
+import '../../../pkg/unittest/lib/unittest.dart';
+
+main() {
+  test("run async timer after async test", () {
+    // Check that Timers don't run before the async callbacks.
+    bool timerCallbackExecuted = false;
+
+    runAsync(expectAsync0(() {
+      Expect.isFalse(timerCallbackExecuted);
+    }));
+
+    Timer.run(expectAsync0(() { timerCallbackExecuted = true; }));
+
+    runAsync(expectAsync0(() {
+      Expect.isFalse(timerCallbackExecuted);
+    }));
+
+    runAsync(expectAsync0(() {
+      // Busy loop.
+      var sum = 1;
+      var sw = new Stopwatch()..start();
+      while (sw.elapsedMilliseconds < 5) {
+        sum++;
+      }
+      if (sum == 0) throw "bad";  // Just to use the result.
+      runAsync(expectAsync0(() {
+        Expect.isFalse(timerCallbackExecuted);
+      }));
+    }));
+
+    runAsync(expectAsync0(() {
+      Expect.isFalse(timerCallbackExecuted);
+    }));
+  });
+}
diff --git a/tests/lib/async/run_async_test.dart b/tests/lib/async/run_async_test.dart
new file mode 100644
index 0000000..0ec7afa
--- /dev/null
+++ b/tests/lib/async/run_async_test.dart
@@ -0,0 +1,14 @@
+// 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 run_async_test;
+
+import 'dart:async';
+import '../../../pkg/unittest/lib/unittest.dart';
+
+main() {
+  test("run async test", () {
+    runAsync(expectAsync0(() {}));
+  });
+}
diff --git a/tests/lib/async/slow_consumer2_test.dart b/tests/lib/async/slow_consumer2_test.dart
index a040256..a239a91 100644
--- a/tests/lib/async/slow_consumer2_test.dart
+++ b/tests/lib/async/slow_consumer2_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// VMOptions=--old_gen_heap_size=32
+// VMOptions=--old_gen_heap_size=64
 
 library slow_consumer2_test;
 
diff --git a/tests/lib/async/stream_controller_async_test.dart b/tests/lib/async/stream_controller_async_test.dart
index 36278bd..2e329d3 100644
--- a/tests/lib/async/stream_controller_async_test.dart
+++ b/tests/lib/async/stream_controller_async_test.dart
@@ -86,7 +86,7 @@
 
   test("Single-subscription StreamController subscription changes", () {
     StreamController c = new StreamController();
-    StreamSink sink = c.sink;
+    EventSink sink = c.sink;
     Stream stream = c.stream;
     int counter = 0;
     var subscription;
@@ -110,7 +110,7 @@
        " there is no subscriber",
        () {
     StreamController c = new StreamController();
-    StreamSink sink = c.sink;
+    EventSink sink = c.sink;
     Stream stream = c.stream;
     int counter = 0;
     sink.add(1);
@@ -129,7 +129,7 @@
   test("Single-subscription StreamController subscription changes while firing",
        () {
     StreamController c = new StreamController();
-    StreamSink sink = c.sink;
+    EventSink sink = c.sink;
     Stream stream = c.stream;
     int counter = 0;
     var subscription = stream.listen(null);
@@ -156,59 +156,59 @@
 testExtraMethods() {
   Events sentEvents = new Events()..add(7)..add(9)..add(13)..add(87)..close();
 
-  test("firstMatching", () {
+  test("firstWhere", () {
     StreamController c = new StreamController();
-    Future f = c.stream.firstMatching((x) => (x % 3) == 0);
+    Future f = c.stream.firstWhere((x) => (x % 3) == 0);
     f.then(expectAsync1((v) { Expect.equals(9, v); }));
     sentEvents.replay(c);
   });
 
-  test("firstMatching 2", () {
+  test("firstWhere 2", () {
     StreamController c = new StreamController();
-    Future f = c.stream.firstMatching((x) => (x % 4) == 0);
+    Future f = c.stream.firstWhere((x) => (x % 4) == 0);
     f.catchError(expectAsync1((e) {}));
     sentEvents.replay(c);
   });
 
-  test("firstMatching 3", () {
+  test("firstWhere 3", () {
     StreamController c = new StreamController();
-    Future f = c.stream.firstMatching((x) => (x % 4) == 0, defaultValue: () => 999);
+    Future f = c.stream.firstWhere((x) => (x % 4) == 0, defaultValue: () => 999);
     f.then(expectAsync1((v) { Expect.equals(999, v); }));
     sentEvents.replay(c);
   });
 
 
-  test("lastMatching", () {
+  test("lastWhere", () {
     StreamController c = new StreamController();
-    Future f = c.stream.lastMatching((x) => (x % 3) == 0);
+    Future f = c.stream.lastWhere((x) => (x % 3) == 0);
     f.then(expectAsync1((v) { Expect.equals(87, v); }));
     sentEvents.replay(c);
   });
 
-  test("lastMatching 2", () {
+  test("lastWhere 2", () {
     StreamController c = new StreamController();
-    Future f = c.stream.lastMatching((x) => (x % 4) == 0);
+    Future f = c.stream.lastWhere((x) => (x % 4) == 0);
     f.catchError(expectAsync1((e) {}));
     sentEvents.replay(c);
   });
 
-  test("lastMatching 3", () {
+  test("lastWhere 3", () {
     StreamController c = new StreamController();
-    Future f = c.stream.lastMatching((x) => (x % 4) == 0, defaultValue: () => 999);
+    Future f = c.stream.lastWhere((x) => (x % 4) == 0, defaultValue: () => 999);
     f.then(expectAsync1((v) { Expect.equals(999, v); }));
     sentEvents.replay(c);
   });
 
-  test("singleMatching", () {
+  test("singleWhere", () {
     StreamController c = new StreamController();
-    Future f = c.stream.singleMatching((x) => (x % 9) == 0);
+    Future f = c.stream.singleWhere((x) => (x % 9) == 0);
     f.then(expectAsync1((v) { Expect.equals(9, v); }));
     sentEvents.replay(c);
   });
 
-  test("singleMatching 2", () {
+  test("singleWhere 2", () {
     StreamController c = new StreamController();
-    Future f = c.stream.singleMatching((x) => (x % 3) == 0);  // Matches both 9 and 87..
+    Future f = c.stream.singleWhere((x) => (x % 3) == 0);  // Matches both 9 and 87..
     f.catchError(expectAsync1((e) { Expect.isTrue(e.error is StateError); }));
     sentEvents.replay(c);
   });
@@ -420,7 +420,7 @@
       Stream s = streamErrorTransform(c.stream, (e) { throw error; });
       s.listen((_) { Expect.fail("unexpected value"); }, onError: expectAsync1(
           (AsyncError e) { Expect.identical(error, e); }));
-      c.signalError(null);
+      c.addError(null);
       c.close();
     });
   }
diff --git a/tests/lib/async/stream_controller_test.dart b/tests/lib/async/stream_controller_test.dart
index 9593e96..20a05fd 100644
--- a/tests/lib/async/stream_controller_test.dart
+++ b/tests/lib/async/stream_controller_test.dart
@@ -94,7 +94,7 @@
       new Events()..error("a")..add(42)..error("b")..add("foo")..close();
   actualEvents = new Events.capture(c.stream.transform(
       new StreamTransformer(
-          handleData: (v, s) { s.signalError(new AsyncError(v)); },
+          handleData: (v, s) { s.addError(new AsyncError(v)); },
           handleError: (e, s) { s.add(e.error); },
           handleDone: (s) {
             s.add("foo");
@@ -283,7 +283,7 @@
       new Events()..error("a")..add(42)..error("b")..add("foo")..close();
   actualEvents = new Events.capture(c.stream.transform(
       new StreamTransformer(
-          handleData: (v, s) { s.signalError(new AsyncError(v)); },
+          handleData: (v, s) { s.addError(new AsyncError(v)); },
           handleError: (e, s) { s.add(e.error); },
           handleDone: (s) {
             s.add("foo");
@@ -398,7 +398,7 @@
     Expect.isFalse(c.isClosed);
     c.add(42);
     Expect.isFalse(c.isClosed);
-    c.signalError("bad");
+    c.addError("bad");
     Expect.isFalse(c.isClosed);
     c.close();
     Expect.isTrue(c.isClosed);
diff --git a/tests/lib/async/stream_event_transform_test.dart b/tests/lib/async/stream_event_transform_test.dart
index debc2c0c..1f79f99 100644
--- a/tests/lib/async/stream_event_transform_test.dart
+++ b/tests/lib/async/stream_event_transform_test.dart
@@ -8,37 +8,37 @@
 import '../../../pkg/unittest/lib/unittest.dart';
 import 'event_helper.dart';
 
-void handleData(int data, StreamSink<int> sink) {
-  sink.signalError(new AsyncError("$data"));
+void handleData(int data, EventSink<int> sink) {
+  sink.addError(new AsyncError("$data"));
   sink.add(data + 1);
 }
 
-void handleError(AsyncError e, StreamSink<int> sink) {
+void handleError(AsyncError e, EventSink<int> sink) {
   String value = e.error;
   int data = int.parse(value);
   sink.add(data);
-  sink.signalError(new AsyncError("${data + 1}"));
+  sink.addError(new AsyncError("${data + 1}"));
 }
 
-void handleDone(StreamSink<int> sink) {
+void handleDone(EventSink<int> sink) {
   sink.add(99);
   sink.close();
 }
 
 class EventTransformer extends StreamEventTransformer<int,int> {
-  void handleData(int data, StreamSink<int> sink) {
-    sink.signalError(new AsyncError("$data"));
+  void handleData(int data, EventSink<int> sink) {
+    sink.addError(new AsyncError("$data"));
     sink.add(data + 1);
   }
 
-  void handleError(AsyncError e, StreamSink<int> sink) {
+  void handleError(AsyncError e, EventSink<int> sink) {
     String value = e.error;
     int data = int.parse(value);
     sink.add(data);
-    sink.signalError(new AsyncError("${data + 1}"));
+    sink.addError(new AsyncError("${data + 1}"));
   }
 
-  void handleDone(StreamSink<int> sink) {
+  void handleDone(EventSink<int> sink) {
     sink.add(99);
     sink.close();
   }
diff --git a/tests/lib/async/stream_periodic2_test.dart b/tests/lib/async/stream_periodic2_test.dart
new file mode 100644
index 0000000..b9a17f8
--- /dev/null
+++ b/tests/lib/async/stream_periodic2_test.dart
@@ -0,0 +1,23 @@
+// 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 merging streams.
+library dart.test.stream_from_iterable;
+
+import "dart:async";
+import '../../../pkg/unittest/lib/unittest.dart';
+
+main() {
+  test("stream-periodic2", () {
+    Stream stream = new Stream.periodic(const Duration(milliseconds: 1),
+                                        (x) => x);
+    int receivedCount = 0;
+    var subscription;
+    subscription = stream.listen(expectAsync1((data) {
+      expect(data, receivedCount);
+      receivedCount++;
+      if (receivedCount == 5) subscription.cancel();
+    }, count: 5));
+  });
+}
diff --git a/tests/lib/async/stream_periodic3_test.dart b/tests/lib/async/stream_periodic3_test.dart
new file mode 100644
index 0000000..e46e29d
--- /dev/null
+++ b/tests/lib/async/stream_periodic3_test.dart
@@ -0,0 +1,23 @@
+// 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 merging streams.
+library dart.test.stream_from_iterable;
+
+import "dart:async";
+import '../../../pkg/unittest/lib/unittest.dart';
+
+main() {
+  test("stream-periodic3", () {
+    Stopwatch watch = new Stopwatch()..start();
+    Stream stream = new Stream.periodic(const Duration(milliseconds: 1),
+                                        (x) => x);
+    stream.take(10).listen((_) { }, onDone: expectAsync0(() {
+      int microsecs = watch.elapsedMicroseconds;
+      // Give it some slack. The Stopwatch is more precise than the timers.
+      int millis = (microsecs + 200) ~/ 1000;
+      expect(millis, greaterThan(10));
+    }));
+  });
+}
diff --git a/tests/lib/async/stream_periodic4_test.dart b/tests/lib/async/stream_periodic4_test.dart
new file mode 100644
index 0000000..518673f
--- /dev/null
+++ b/tests/lib/async/stream_periodic4_test.dart
@@ -0,0 +1,39 @@
+// 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 merging streams.
+library dart.test.stream_from_iterable;
+
+import "dart:async";
+import '../../../pkg/unittest/lib/unittest.dart';
+
+watchMs(Stopwatch watch) {
+  int microsecs = watch.elapsedMicroseconds;
+  // Give it some slack. The Stopwatch is more precise than the timers. This
+  // means that we sometimes get 3995 microseconds instead of 4+ milliseconds.
+  // 200 microseconds should largely account for this discrepancy.
+  return (microsecs + 200) ~/ 1000;
+}
+
+main() {
+  test("stream-periodic4", () {
+    Stopwatch watch = new Stopwatch()..start();
+    Stream stream = new Stream.periodic(const Duration(milliseconds: 5),
+                                        (x) => x);
+    var subscription;
+    subscription = stream.take(10).listen((i) {
+      int ms = watchMs(watch);
+      expect(ms, lessThan(100));
+      watch.reset();
+      if (i == 2) {
+        subscription.pause();
+        watch.stop();
+        new Timer(const Duration(milliseconds: 150), () {
+          watch.start();
+          subscription.resume();
+        });
+      }
+    }, onDone: expectAsync0(() { }));
+  });
+}
diff --git a/tests/lib/async/stream_periodic5_test.dart b/tests/lib/async/stream_periodic5_test.dart
new file mode 100644
index 0000000..a2403b2
--- /dev/null
+++ b/tests/lib/async/stream_periodic5_test.dart
@@ -0,0 +1,46 @@
+// 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 merging streams.
+library dart.test.stream_from_iterable;
+
+import "dart:async";
+import '../../../pkg/unittest/lib/unittest.dart';
+
+watchMs(Stopwatch watch) {
+  int microsecs = watch.elapsedMicroseconds;
+  // Give it some slack. The Stopwatch is more precise than the timers. This
+  // means that we sometimes get 3995 microseconds instead of 4+ milliseconds.
+  // 200 microseconds should largely account for this discrepancy.
+  return (microsecs + 200) ~/ 1000;
+}
+
+main() {
+  test("stream-periodic4", () {
+    Stream stream = new Stream.periodic(const Duration(milliseconds: 5),
+                                        (x) => x);
+    Stopwatch watch = new Stopwatch()..start();
+    var subscription;
+    subscription = stream.take(10).listen((i) {
+      int ms = watchMs(watch);
+      watch.reset();
+      if (i == 2) {
+        Stopwatch watch2 = new Stopwatch()..start();
+        // Busy wait.
+        while (watch2.elapsedMilliseconds < 15) { }
+        // Make sure the stream can be paused when it has overdue events.
+        // We just busy waited for 15ms, even though the stream is supposed to
+        // emit events every 5ms.
+        subscription.pause();
+        watch.stop();
+        new Timer(const Duration(milliseconds: 150), () {
+          watch.start();
+          subscription.resume();
+        });
+      } else {
+        expect(ms, lessThan(100));
+      }
+    }, onDone: expectAsync0(() { }));
+  });
+}
diff --git a/tests/lib/async/stream_periodic_test.dart b/tests/lib/async/stream_periodic_test.dart
new file mode 100644
index 0000000..32359f6
--- /dev/null
+++ b/tests/lib/async/stream_periodic_test.dart
@@ -0,0 +1,22 @@
+// 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 merging streams.
+library dart.test.stream_from_iterable;
+
+import "dart:async";
+import '../../../pkg/unittest/lib/unittest.dart';
+
+main() {
+  test("stream-periodic1", () {
+    Stream stream = new Stream.periodic(const Duration(milliseconds: 1));
+    int receivedCount = 0;
+    var subscription;
+    subscription = stream.listen(expectAsync1((data) {
+      expect(data, isNull);
+      receivedCount++;
+      if (receivedCount == 5) subscription.cancel();
+    }, count: 5));
+  });
+}
diff --git a/tests/lib/async/stream_state_helper.dart b/tests/lib/async/stream_state_helper.dart
index 86d71a1..8f9b33f 100644
--- a/tests/lib/async/stream_state_helper.dart
+++ b/tests/lib/async/stream_state_helper.dart
@@ -33,7 +33,7 @@
 
   // Actions on the stream and controller.
   void add(var data) { _controller.add(data); }
-  void error(var error) { _controller.signalError(error); }
+  void error(var error) { _controller.addError(error); }
   void close() { _controller.close(); }
 
   void subscribe({bool unsubscribeOnError : false}) {
diff --git a/tests/lib/async/stream_transform_test.dart b/tests/lib/async/stream_transform_test.dart
index abd6f53..6bc4db8 100644
--- a/tests/lib/async/stream_transform_test.dart
+++ b/tests/lib/async/stream_transform_test.dart
@@ -48,7 +48,6 @@
 
   test("closing after done", () {
     var controller = new StreamController();
-    var buffer = new StringBuffer();
     controller.stream.map((e) => e).transform(new StreamTransformer(
         handleData: (element, sink) { sink.add(element); },
         handleDone: (sink) { sink.close(); })
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 52f322a..8e729b4 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -2,11 +2,16 @@
 # 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.
 
-async/slow_consumer_test: Skip # Issue 8647
+
+# The scalarlist library is not supported by dart2js or dart2dart yet.
+[ $compiler == dart2js  || $compiler == dart2dart ]
+scalarlist/*: Skip
 
 [ $compiler == dart2js ]
 math/*: Skip
 mirrors/*: Skip
+async/run_async3_test: Fail # _enqueueImmediate runs after Timer. http://dartbug.com/9002
+async/run_async4_test: Pass, Fail # no global exception handler in isolates. http://dartbug.com/9012
 
 [ $compiler == dart2js && $checked ]
 async/stream_event_transform_test: Fail # Issue 7733.
@@ -19,6 +24,13 @@
 async/stream_from_iterable_test: Fail # Timer interface not supported; dartbug.com/7728.
 async/stream_state_nonzero_timer_test: Fail # Timer interface not supported; dartbug.com/7728.
 
+[ $compiler == dart2js && ($jscl || $runtime == d8) ]
+async/stream_periodic_test: Fail # Timer interface not supported; dartbug.com/7728.
+async/stream_periodic2_test: Fail # Timer interface not supported; dartbug.com/7728.
+async/stream_periodic3_test: Fail # Timer interface not supported; dartbug.com/7728.
+async/stream_periodic4_test: Fail # Timer interface not supported; dartbug.com/7728.
+async/stream_periodic5_test: Fail # Timer interface not supported; dartbug.com/7728.
+
 [ $compiler == dart2js && $browser ]
 crypto/sha256_test: Slow, Pass
 crypto/sha1_test: Slow, Pass
@@ -36,8 +48,10 @@
  # Bug in JSC: the test only passes when being debugged.
 crypto/hmac_md5_test: Fail, Pass
 
-[ $runtime == vm && $arch == x64 ]
-async/slow_consumer2_test: Fail # Issue 7726
+
+[ $runtime == vm || ($compiler == none && $runtime == drt) ]
+async/run_async3_test: Fail # _enqueueImmediate runs after Timer. http://dartbug.com/9001.
+async/run_async4_test: Pass, Fail # http://dartbug.com/9013
 
 [ $compiler == none && $runtime == drt ]
 async/deferred/deferred_api_test: Fail # http://dartbug.com/2264
diff --git a/tests/lib/math/coin_test.dart b/tests/lib/math/coin_test.dart
index 181024d..c5dcb16 100644
--- a/tests/lib/math/coin_test.dart
+++ b/tests/lib/math/coin_test.dart
@@ -10,9 +10,9 @@
 import 'dart:math';
 
 main() {
-  var seed = new Random().nextInt((1<<32) - 1);
+  var seed = new Random().nextInt(1<<16);
   print("coin_test seed: $seed");
-  var rnd = new Random();
+  var rnd = new Random(seed);
   var heads = 0;
   var tails = 0;
   for (var i = 0; i < 10000; i++) {
diff --git a/tests/lib/math/low_test.dart b/tests/lib/math/low_test.dart
index cae369f..cb261d0 100644
--- a/tests/lib/math/low_test.dart
+++ b/tests/lib/math/low_test.dart
@@ -16,7 +16,7 @@
   
   var iterations = 200000;
 
-  var seed = new Random().nextInt((1<<32) - 1);
+  var seed = new Random().nextInt(1<<16);
   print("low_test seed: $seed");
   var prng = new Random(seed);
 
diff --git a/tests/lib/math/pi_test.dart b/tests/lib/math/pi_test.dart
index 9b1147b..c042b4b 100644
--- a/tests/lib/math/pi_test.dart
+++ b/tests/lib/math/pi_test.dart
@@ -11,7 +11,7 @@
 import 'dart:math';
 
 void main() {
-  var seed = new Random().nextInt((1<<32) - 1);
+  var seed = new Random().nextInt(1<<16);
   print("pi_test seed: $seed");
   var prng = new Random(seed);
   var outside = 0;
diff --git a/tests/lib/math/random_test.dart b/tests/lib/math/random_test.dart
new file mode 100644
index 0000000..88b67a9
--- /dev/null
+++ b/tests/lib/math/random_test.dart
@@ -0,0 +1,51 @@
+// 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 a coin toss with Random.nextBool() is fair.
+
+// Library tag to allow Dartium to run the test.
+library random_test;
+
+import 'dart:math';
+
+main() {
+  var rnd = new Random(20130307);
+  // Make sure we do not break the random number generation.
+  var i = 0;
+  Expect.equals(         0, rnd.nextInt(1 << ++i));
+  Expect.equals(         2, rnd.nextInt(1 << ++i));
+  Expect.equals(         7, rnd.nextInt(1 << ++i));
+  Expect.equals(         8, rnd.nextInt(1 << ++i));
+  Expect.equals(         1, rnd.nextInt(1 << ++i));
+  Expect.equals(        61, rnd.nextInt(1 << ++i));
+  Expect.equals(        31, rnd.nextInt(1 << ++i));
+  Expect.equals(       230, rnd.nextInt(1 << ++i));
+  Expect.equals(       390, rnd.nextInt(1 << ++i));
+  Expect.equals(       443, rnd.nextInt(1 << ++i));
+  Expect.equals(      1931, rnd.nextInt(1 << ++i));
+  Expect.equals(      3028, rnd.nextInt(1 << ++i));
+  Expect.equals(      5649, rnd.nextInt(1 << ++i));
+  Expect.equals(      4603, rnd.nextInt(1 << ++i));
+  Expect.equals(     27684, rnd.nextInt(1 << ++i));
+  Expect.equals(     54139, rnd.nextInt(1 << ++i));
+  Expect.equals(     83454, rnd.nextInt(1 << ++i));
+  Expect.equals(    106708, rnd.nextInt(1 << ++i));
+  Expect.equals(    112143, rnd.nextInt(1 << ++i));
+  Expect.equals(    875266, rnd.nextInt(1 << ++i));
+  Expect.equals(    971126, rnd.nextInt(1 << ++i));
+  Expect.equals(   1254573, rnd.nextInt(1 << ++i));
+  Expect.equals(   4063839, rnd.nextInt(1 << ++i));
+  Expect.equals(   7854646, rnd.nextInt(1 << ++i));
+  Expect.equals(  29593843, rnd.nextInt(1 << ++i));
+  Expect.equals(  17672573, rnd.nextInt(1 << ++i));
+  Expect.equals(  80223657, rnd.nextInt(1 << ++i));
+  Expect.equals( 142194155, rnd.nextInt(1 << ++i));
+  Expect.equals(  31792146, rnd.nextInt(1 << ++i));
+  Expect.equals(1042196170, rnd.nextInt(1 << ++i));
+  Expect.equals(1589656273, rnd.nextInt(1 << ++i));
+  Expect.equals(1547294578, rnd.nextInt(1 << ++i));
+  Expect.equals(32, i);
+  // If max is too large expect an ArgumentError. 
+  Expect.throws(() => rnd.nextInt((1 << i)+1), (e) => e is ArgumentError);
+}
diff --git a/runtime/tests/vm/dart/simd128float32_array_test.dart b/tests/lib/scalarlist/float32x4_list_test.dart
similarity index 97%
rename from runtime/tests/vm/dart/simd128float32_array_test.dart
rename to tests/lib/scalarlist/float32x4_list_test.dart
index 44f4591..2073aff 100644
--- a/runtime/tests/vm/dart/simd128float32_array_test.dart
+++ b/tests/lib/scalarlist/float32x4_list_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 // Library tag to be able to run in html test framework.
-library simd128float32_array_test;
+library float32x4_list_test;
 
 import 'dart:scalarlist';
 
diff --git a/runtime/tests/vm/dart/simd128float32_test.dart b/tests/lib/scalarlist/float32x4_test.dart
similarity index 98%
rename from runtime/tests/vm/dart/simd128float32_test.dart
rename to tests/lib/scalarlist/float32x4_test.dart
index cac2b63..943f28b 100644
--- a/runtime/tests/vm/dart/simd128float32_test.dart
+++ b/tests/lib/scalarlist/float32x4_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 // Library tag to be able to run in html test framework.
-library simd128_float32_test;
+library float32x4_test;
 
 import 'dart:scalarlist';
 
diff --git a/tests/standalone/byte_array_view_optimized_test.dart b/tests/standalone/byte_array_view_optimized_test.dart
new file mode 100644
index 0000000..2d9f646
--- /dev/null
+++ b/tests/standalone/byte_array_view_optimized_test.dart
@@ -0,0 +1,22 @@
+// 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 optimization of byte array views on external data.
+
+// Library tag to be able to run in html test framework.
+library ByteArrayViewOptimizedTest;
+
+import "dart:scalarlist";
+
+li16(v) => v[0];
+
+main() {
+  var a = new Uint8List.transferable(2);
+  a[0] = a[1] = 0xff;
+  var b = new Int16List.view(a.asByteArray());
+  Expect.equals(-1, li16(b));
+  for (var i=0; i<10000; i++) li16(b);
+  Expect.equals(-1, li16(b));
+}
+
diff --git a/tests/standalone/debugger/debug_lib.dart b/tests/standalone/debugger/debug_lib.dart
index d71f3e6..0d13f7a 100644
--- a/tests/standalone/debugger/debug_lib.dart
+++ b/tests/standalone/debugger/debug_lib.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -29,7 +29,7 @@
     if (buffer == null || buffer.length == 0) {
       buffer = s;
     } else {
-      buffer = buffer.concat(s);
+      buffer += s;
     }
   }
 
@@ -460,7 +460,7 @@
   void sendMessage(Map<String,dynamic> msg) {
     String jsonMsg = JSON.stringify(msg);
     if (verboseWire) print("SEND: $jsonMsg");
-    socket.addString(jsonMsg);
+    socket.write(jsonMsg);
   }
 
   bool get errorsDetected => errors.length > 0;
diff --git a/tests/standalone/float_array_test.dart b/tests/standalone/float_array_test.dart
index 99ffcab..085593a 100644
--- a/tests/standalone/float_array_test.dart
+++ b/tests/standalone/float_array_test.dart
@@ -7,7 +7,7 @@
 // Library tag to be able to run in html test framework.
 library FloatArrayTest;
 
-import 'dart:scalarlist';
+import 'dart:typeddata';
 
 void testCreateFloat32Array() {
   Float32List floatArray;
diff --git a/tests/standalone/int_array_deopt.dart b/tests/standalone/int_array_deopt.dart
index 4f4bf89..8897f1e 100644
--- a/tests/standalone/int_array_deopt.dart
+++ b/tests/standalone/int_array_deopt.dart
@@ -4,7 +4,7 @@
 //
 // Dart deoptimization of Uint32Array and Int32Array loads.
 
-import 'dart:scalarlist';
+import 'dart:typeddata';
 
 loadI32(a) => a[0] + 1;
 loadUi32(a) => a[0] + 1;
diff --git a/tests/standalone/int_array_load_elimination_test.dart b/tests/standalone/int_array_load_elimination_test.dart
index 9dc3523..55997a9 100644
--- a/tests/standalone/int_array_load_elimination_test.dart
+++ b/tests/standalone/int_array_load_elimination_test.dart
@@ -7,7 +7,7 @@
 // TODO: remove once bug 2264 fixed.
 library int_array_load_elimination;
 
-import 'dart:scalarlist';
+import 'dart:typeddata';
 
 void testUint16() {
   Uint16List intArray = new Uint16List(1);
diff --git a/tests/standalone/int_array_test.dart b/tests/standalone/int_array_test.dart
index f02fdf7..bebc2ef 100644
--- a/tests/standalone/int_array_test.dart
+++ b/tests/standalone/int_array_test.dart
@@ -7,7 +7,7 @@
 // Library tag to be able to run in html test framework.
 library IntArrayTest;
 
-import 'dart:scalarlist';
+import 'dart:typeddata';
 
 void testInt16() {
   Int16List intArray = new Int16List(4);
diff --git a/tests/standalone/io/dart_std_io_pipe_test.dart b/tests/standalone/io/dart_std_io_pipe_test.dart
index 325e41b..daf5c09 100644
--- a/tests/standalone/io/dart_std_io_pipe_test.dart
+++ b/tests/standalone/io/dart_std_io_pipe_test.dart
@@ -30,12 +30,13 @@
 }
 
 
-void test(String shellScript, String dartScript, String type) {
+void test(String shellScript, String dartScript, String type, bool devNull) {
   Directory dir = new Directory("").createTempSync();
 
   // The shell script will run the dart executable passed with a
   // number of different redirections of stdio.
   String pipeOutFile = "${dir.path}/pipe";
+  if (devNull) pipeOutFile = "/dev/null";
   String redirectOutFile = "${dir.path}/redirect";
   String executable = new Options().executable;
   List args =
@@ -47,21 +48,34 @@
 
       // Check the expected file contents.
       if (type == "0") {
-        checkFileContent("${pipeOutFile}", "Hello\n");
+        if (devNull) {
+          checkFileEmpty("${redirectOutFile}.stdout");
+        } else {
+          checkFileContent("${pipeOutFile}", "Hello\n");
+          checkFileContent("${redirectOutFile}.stdout", "Hello\nHello\n");
+        }
         checkFileEmpty("${redirectOutFile}.stderr");
-        checkFileContent("${redirectOutFile}.stdout", "Hello\nHello\n");
       }
       if (type == "1") {
-        checkFileContent("${pipeOutFile}", "Hello\n");
+        if (devNull) {
+          checkFileEmpty("${redirectOutFile}.stderr");
+        } else {
+          checkFileContent("${pipeOutFile}", "Hello\n");
+          checkFileContent("${redirectOutFile}.stderr", "Hello\nHello\n");
+        }
         checkFileEmpty("${redirectOutFile}.stdout");
-        checkFileContent("${redirectOutFile}.stderr", "Hello\nHello\n");
       }
       if (type == "2") {
-        checkFileContent("${pipeOutFile}", "Hello\nHello\n");
-        checkFileContent("${redirectOutFile}.stdout",
-                         "Hello\nHello\nHello\nHello\n");
-        checkFileContent("${redirectOutFile}.stderr",
-                         "Hello\nHello\nHello\nHello\n");
+        if (devNull) {
+          checkFileEmpty("${redirectOutFile}.stdout");
+          checkFileEmpty("${redirectOutFile}.stderr");
+        } else {
+          checkFileContent("${pipeOutFile}", "Hello\nHello\n");
+          checkFileContent("${redirectOutFile}.stdout",
+                           "Hello\nHello\nHello\nHello\n");
+          checkFileContent("${redirectOutFile}.stderr",
+                           "Hello\nHello\nHello\nHello\n");
+        }
       }
 
       // Cleanup test directory.
@@ -97,7 +111,10 @@
   }
 
   // Run the shell script.
-  test(shellScript.path, scriptFile.path, "0");
-  test(shellScript.path, scriptFile.path, "1");
-  test(shellScript.path, scriptFile.path, "2");
+  test(shellScript.path, scriptFile.path, "0", false);
+  test(shellScript.path, scriptFile.path, "0", true);
+  test(shellScript.path, scriptFile.path, "1", false);
+  test(shellScript.path, scriptFile.path, "1", true);
+  test(shellScript.path, scriptFile.path, "2", false);
+  test(shellScript.path, scriptFile.path, "2", true);
 }
diff --git a/tests/standalone/io/directory_list_nonexistent_test.dart b/tests/standalone/io/directory_list_nonexistent_test.dart
index e07cb22..3ee62ac 100644
--- a/tests/standalone/io/directory_list_nonexistent_test.dart
+++ b/tests/standalone/io/directory_list_nonexistent_test.dart
@@ -31,9 +31,9 @@
       // Construct a long string of the form
       // 'tempdir/subdir/../subdir/../subdir'.
       var buffer = new StringBuffer();
-      buffer.add(subDir.path);
+      buffer.write(subDir.path);
       for (var i = 0; i < 1000; i++) {
-        buffer.add("/../${subDirName}");
+        buffer.write("/../${subDirName}");
       }
       var long = new Directory("${buffer.toString()}");
       Expect.throws(() => long.listSync(),
diff --git a/tests/standalone/io/directory_test.dart b/tests/standalone/io/directory_test.dart
index 47a7b38..d6eac48 100644
--- a/tests/standalone/io/directory_test.dart
+++ b/tests/standalone/io/directory_test.dart
@@ -124,9 +124,9 @@
         // Construct a long string of the form
         // 'tempdir/subdir/../subdir/../subdir'.
         var buffer = new StringBuffer();
-        buffer.add(subDir.path);
+        buffer.write(subDir.path);
         for (var i = 0; i < 1000; i++) {
-          buffer.add("/../${subDirName}");
+          buffer.write("/../${subDirName}");
         }
         var long = new Directory("${buffer.toString()}");
         setupListHandlers(long.list());
@@ -162,9 +162,9 @@
           // Construct a long string of the form
           // 'tempdir/subdir/../subdir/../subdir'.
           var buffer = new StringBuffer();
-          buffer.add(subDir.path);
+          buffer.write(subDir.path);
           for (var i = 0; i < 1000; i++) {
-            buffer.add("/../${subDirName}");
+            buffer.write("/../${subDirName}");
           }
           var long = new Directory("${buffer.toString()}");
           var errors = 0;
@@ -196,9 +196,9 @@
     // Construct a long string of the form
     // 'tempdir/subdir/../subdir/../subdir'.
     var buffer = new StringBuffer();
-    buffer.add(subDir.path);
+    buffer.write(subDir.path);
     for (var i = 0; i < 1000; i++) {
-      buffer.add("/../${subDirName}");
+      buffer.write("/../${subDirName}");
     }
     var long = new Directory("${buffer.toString()}");
     Expect.throws(long.deleteSync);
diff --git a/tests/standalone/io/echo_server_stream_test.dart b/tests/standalone/io/echo_server_stream_test.dart
index b3a1868..6cd0f37 100644
--- a/tests/standalone/io/echo_server_stream_test.dart
+++ b/tests/standalone/io/echo_server_stream_test.dart
@@ -63,7 +63,7 @@
       _socket.listen(onData,
                      onError: errorHandler,
                      onDone: onClosed);
-      _socket.add(_buffer);
+      _socket.writeBytes(_buffer);
       _socket.close();
       data = new List<int>(MSGSIZE);
     }
@@ -120,7 +120,7 @@
           Expect.equals(EchoServerGame.FIRSTCHAR + i, buffer[i]);
         }
         if (offset == MSGSIZE) {
-          connection.add(buffer);
+          connection.writeBytes(buffer);
           connection.close();
         }
       }
diff --git a/tests/standalone/io/file_fuzz_test.dart b/tests/standalone/io/file_fuzz_test.dart
index ffc32d9..9e4ff73 100644
--- a/tests/standalone/io/file_fuzz_test.dart
+++ b/tests/standalone/io/file_fuzz_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -28,7 +28,7 @@
       doItSync(f.readAsLinesSync);
       typeMapping.forEach((k2, v2) {
         doItSync(() => f.openSync(v2));
-        doItSync(() => f.openWrite(v2));
+        doItSync(() => f.openWrite(mode: v2));
         doItSync(() => f.readAsStringSync(v2));
         doItSync(() => f.readAsLinesSync(v2));
       });
diff --git a/tests/standalone/io/file_input_stream_test.dart b/tests/standalone/io/file_input_stream_test.dart
index e9de0c5..babd948 100644
--- a/tests/standalone/io/file_input_stream_test.dart
+++ b/tests/standalone/io/file_input_stream_test.dart
@@ -53,7 +53,7 @@
   file.createSync();
   StringBuffer buffer = new StringBuffer();
   for (var i = 0; i < 10000; i++) {
-    buffer.add("Hello, world");
+    buffer.write("Hello, world");
   }
   file.writeAsStringSync(buffer.toString());
   var length = file.lengthSync();
diff --git a/tests/standalone/io/file_invalid_arguments_test.dart b/tests/standalone/io/file_invalid_arguments_test.dart
index 26c9557..b4c1720 100644
--- a/tests/standalone/io/file_invalid_arguments_test.dart
+++ b/tests/standalone/io/file_invalid_arguments_test.dart
@@ -62,7 +62,7 @@
 void testWriteByteInvalidArgs(value) {
   var port = new ReceivePort();
   String filename = getFilename("tests/vm/data/fixed_length_file");
-  var file = (new File(filename.concat("_out"))).openSync(FileMode.WRITE);
+  var file = (new File("${filename}_out")).openSync(FileMode.WRITE);
   try {
     file.writeByteSync(value);
     Expect.fail('exception expected');
@@ -86,7 +86,7 @@
 void testWriteListInvalidArgs(buffer, offset, bytes) {
   var port = new ReceivePort();
   String filename = getFilename("tests/vm/data/fixed_length_file");
-  var file = (new File(filename.concat("_out"))).openSync(FileMode.WRITE);
+  var file = (new File("${filename}_out")).openSync(FileMode.WRITE);
   try {
     file.writeListSync(buffer, offset, bytes);
     Expect.fail('exception expected');
@@ -110,7 +110,7 @@
 void testWriteStringInvalidArgs(string) {
   var port = new ReceivePort();
   String filename = getFilename("tests/vm/data/fixed_length_file");
-  var file = new File(filename.concat("_out"));
+  var file = new File("${filename}_out");
   file.openSync(FileMode.WRITE);
   try {
     file.writeString(string);
diff --git a/tests/standalone/io/file_output_stream_test.dart b/tests/standalone/io/file_output_stream_test.dart
index 645399a..b1d81fc 100644
--- a/tests/standalone/io/file_output_stream_test.dart
+++ b/tests/standalone/io/file_output_stream_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 // Testing file input stream, VM-only, standalone test.
@@ -21,7 +21,7 @@
   file.createSync();
   IOSink x = file.openWrite();
   var data = [65, 66, 67];
-  x.add(data);
+  x.writeBytes(data);
   x.close();
   x.done.then((_) {
     Expect.listEquals(file.readAsBytesSync(), data);
diff --git a/tests/standalone/io/file_system_links_test.dart b/tests/standalone/io/file_system_links_test.dart
index 652bf78..d2e6796 100644
--- a/tests/standalone/io/file_system_links_test.dart
+++ b/tests/standalone/io/file_system_links_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -6,19 +6,8 @@
 import "dart:isolate";
 
 
-createLink(String dst, String link, bool symbolic, void callback()) {
-  var args = [ symbolic ? '-s' : '', dst, link ];
-  var script = 'tests/standalone/io/ln.sh';
-  if (!new File(script).existsSync()) {
-    script = '../$script';
-  }
-  Process.run(script, args).then((result) {
-    if (result.exitCode == 0) {
-      callback();
-    } else {
-      throw new Exception('link creation failed');
-    }
-  });
+createLink(String dst, String link, void callback()) {
+  new Link(link).create(dst).then((_) => callback());
 }
 
 
@@ -26,12 +15,49 @@
   var temp = new Directory('').createTempSync();
   var x = '${temp.path}${Platform.pathSeparator}x';
   var y = '${temp.path}${Platform.pathSeparator}y';
-  createLink(x, y, true, () {
-    Expect.isFalse(new File(x).existsSync());
+  createLink(x, y, () {
     Expect.isFalse(new File(y).existsSync());
+    Expect.isFalse(new File(x).existsSync());
+    Expect.isTrue(FileSystemEntity.isLinkSync(y));
+    Expect.isFalse(FileSystemEntity.isLinkSync(x));
+    Expect.equals(FileSystemEntityType.NOT_FOUND, FileSystemEntity.typeSync(y));
+    Expect.equals(FileSystemEntityType.NOT_FOUND, FileSystemEntity.typeSync(x));
+    Expect.equals(FileSystemEntityType.LINK,
+                  FileSystemEntity.typeSync(y, followLinks: false));
+    Expect.equals(FileSystemEntityType.NOT_FOUND,
+                  FileSystemEntity.typeSync(x, followLinks: false));
+
     new File(y).createSync();
-    Expect.isTrue(new File(x).existsSync());
     Expect.isTrue(new File(y).existsSync());
+    Expect.isTrue(new File(x).existsSync());
+    Expect.isTrue(FileSystemEntity.isLinkSync(y));
+    Expect.isFalse(FileSystemEntity.isLinkSync(x));
+    Expect.isTrue(FileSystemEntity.isFileSync(y));
+    Expect.isTrue(FileSystemEntity.isFileSync(x));
+    Expect.equals(FileSystemEntityType.FILE, FileSystemEntity.typeSync(y));
+    Expect.equals(FileSystemEntityType.FILE, FileSystemEntity.typeSync(x));
+    Expect.equals(FileSystemEntityType.LINK,
+                  FileSystemEntity.typeSync(y, followLinks: false));
+    Expect.equals(FileSystemEntityType.FILE,
+                  FileSystemEntity.typeSync(x, followLinks: false));
+    new File(x).deleteSync();
+    new Directory(x).createSync();
+    Expect.isTrue(FileSystemEntity.isLinkSync(y));
+    Expect.isFalse(FileSystemEntity.isLinkSync(x));
+    Expect.isTrue(FileSystemEntity.isDirectorySync(y));
+    Expect.isTrue(FileSystemEntity.isDirectorySync(x));
+    Expect.equals(FileSystemEntityType.DIRECTORY, FileSystemEntity.typeSync(y));
+    Expect.equals(FileSystemEntityType.DIRECTORY, FileSystemEntity.typeSync(x));
+    Expect.equals(FileSystemEntityType.LINK,
+                  FileSystemEntity.typeSync(y, followLinks: false));
+    Expect.equals(FileSystemEntityType.DIRECTORY,
+                  FileSystemEntity.typeSync(x, followLinks: false));
+    new File(y).deleteSync();
+    Expect.isFalse(FileSystemEntity.isLinkSync(y));
+    Expect.isFalse(FileSystemEntity.isLinkSync(x));
+    Expect.equals(FileSystemEntityType.NOT_FOUND, FileSystemEntity.typeSync(y));
+    Expect.equals(FileSystemEntityType.DIRECTORY, FileSystemEntity.typeSync(x));
+
     temp.deleteSync(recursive: true);
   });
 }
@@ -42,13 +68,13 @@
   var x = '${temp.path}${Platform.pathSeparator}x';
   var y = '${temp.path}${Platform.pathSeparator}y';
   new File(x).createSync();
-  createLink(x, y, true, () {
+  createLink(x, y, () {
     Expect.isTrue(new File(x).existsSync());
     Expect.isTrue(new File(y).existsSync());
     new File(y).deleteSync();
     Expect.isTrue(new File(x).existsSync());
     Expect.isFalse(new File(y).existsSync());
-    createLink(x, y, false, () {
+    createLink(x, y, () {
       Expect.isTrue(new File(x).existsSync());
       Expect.isTrue(new File(y).existsSync());
       new File(y).deleteSync();
@@ -65,10 +91,10 @@
   var x = '${temp.path}${Platform.pathSeparator}x';
   var y = '${temp.path}${Platform.pathSeparator}y';
   new File(x).createSync();
-  createLink(x, y, true, () {
+  createLink(x, y, () {
     var data = "asdf".codeUnits;
-    var output = new File(y).openWrite(FileMode.WRITE);
-    output.add(data);
+    var output = new File(y).openWrite(mode: FileMode.WRITE);
+    output.writeBytes(data);
     output.close();
     output.done.then((_) {
       var read = new File(y).readAsBytesSync();
@@ -85,7 +111,7 @@
   var temp = new Directory('').createTempSync();
   var x = '${temp.path}${Platform.pathSeparator}x';
   var y = '${temp.path}${Platform.pathSeparator}y';
-  createLink(x, y, true, () {
+  createLink(x, y, () {
     Expect.isFalse(new Directory(x).existsSync());
     Expect.isFalse(new Directory(y).existsSync());
     Expect.throws(new Directory(y).createSync);
@@ -100,14 +126,14 @@
   var y = '${temp.path}${Platform.pathSeparator}y';
   var x = '${temp2.path}${Platform.pathSeparator}x';
   new File(x).createSync();
-  createLink(temp2.path, y, true, () {
+  createLink(temp2.path, y, () {
     var link = new Directory(y);
     Expect.isTrue(link.existsSync());
     Expect.isTrue(temp2.existsSync());
     link.deleteSync();
     Expect.isFalse(link.existsSync());
     Expect.isTrue(temp2.existsSync());
-    createLink(temp2.path, y, true, () {
+    createLink(temp2.path, y, () {
       Expect.isTrue(link.existsSync());
       temp.deleteSync(recursive: true);
       Expect.isFalse(link.existsSync());
@@ -126,7 +152,7 @@
   var y = '${temp.path}${Platform.pathSeparator}y';
   var x = '${temp2.path}${Platform.pathSeparator}x';
   new File(x).createSync();
-  createLink(temp2.path, y, true, () {
+  createLink(temp2.path, y, () {
     var files = [];
     var dirs = [];
     for (var entry in temp.listSync(recursive:true)) {
@@ -173,7 +199,7 @@
   var link = '${temp.path}${Platform.pathSeparator}link';
   var doesNotExist = 'this_thing_does_not_exist';
   new File(x).createSync();
-  createLink(doesNotExist, link, true, () {
+  createLink(doesNotExist, link, () {
     Expect.throws(() => temp.listSync(recursive: true),
                   (e) => e is DirectoryIOException);
     var files = [];
diff --git a/tests/standalone/io/file_test.dart b/tests/standalone/io/file_test.dart
index 6f97138..122a4cd 100644
--- a/tests/standalone/io/file_test.dart
+++ b/tests/standalone/io/file_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 //
@@ -88,10 +88,10 @@
         Expect.equals(42, buffer.length);
         // Write the contents of the file just read into another file.
         String outFilename =
-            tempDirectory.path.concat("/out_read_write_stream");
+            tempDirectory.path + "/out_read_write_stream";
         var file2 = new File(outFilename);
         var output = file2.openWrite();
-        output.add(buffer);
+        output.writeBytes(buffer);
         output.close();
         output.done.then((_) {
           // Now read the contents of the file just written.
@@ -126,11 +126,11 @@
       buffer[i] = i % 256;
     }
     String filename =
-        tempDirectory.path.concat("/out_read_write_stream_large_file");
+        tempDirectory.path + "/out_read_write_stream_large_file";
     File file = new File(filename);
     IOSink output = file.openWrite();
-    output.add(buffer);
-    output.add(buffer);
+    output.writeBytes(buffer);
+    output.writeBytes(buffer);
     output.close();
     output.done.then((_) {
       Stream input = file.openRead();
@@ -268,7 +268,7 @@
         Expect.equals(42, bytes_read);
         openedFile.close().then((ignore) {
           // Write the contents of the file just read into another file.
-          String outFilename = tempDirectory.path.concat("/out_read_write");
+          String outFilename = tempDirectory.path + "/out_read_write";
           final File file2 = new File(outFilename);
           file2.create().then((ignore) {
             file2.fullPath().then((s) {
@@ -315,7 +315,7 @@
 
   static void testWriteAppend() {
     String content = "foobar";
-    String filename = tempDirectory.path.concat("/write_append");
+    String filename = tempDirectory.path + "/write_append";
     File file = new File(filename);
     file.createSync();
     Expect.isTrue(new File(filename).existsSync());
@@ -339,17 +339,17 @@
 
   static void testOutputStreamWriteAppend() {
     String content = "foobar";
-    String filename = tempDirectory.path.concat("/outstream_write_append");
+    String filename = tempDirectory.path + "/outstream_write_append";
     File file = new File(filename);
     file.createSync();
     List<int> buffer = content.codeUnits;
     var output = file.openWrite();
-    output.add(buffer);
+    output.writeBytes(buffer);
     output.close();
     output.done.then((_) {
       File file2 = new File(filename);
-      var appendingOutput = file2.openWrite(FileMode.APPEND);
-      appendingOutput.add(buffer);
+      var appendingOutput = file2.openWrite(mode: FileMode.APPEND);
+      appendingOutput.writeBytes(buffer);
       appendingOutput.close();
       appendingOutput.done.then((_) {
         File file3 = new File(filename);
@@ -371,16 +371,20 @@
   // Test for file read and write functionality.
   static void testOutputStreamWriteString() {
     String content = "foobar";
-    String filename = tempDirectory.path.concat("/outstream_write_string");
+    String filename = tempDirectory.path + "/outstream_write_string";
     File file = new File(filename);
     file.createSync();
     List<int> buffer = content.codeUnits;
     var output = file.openWrite();
-    output.addString("abcdABCD");
-    output.addString("abcdABCD", Encoding.UTF_8);
-    output.addString("abcdABCD", Encoding.ISO_8859_1);
-    output.addString("abcdABCD", Encoding.ASCII);
-    output.addString("æøå", Encoding.UTF_8);
+    output.write("abcdABCD");
+    output.encoding = Encoding.UTF_8;
+    output.write("abcdABCD");
+    output.encoding = Encoding.ISO_8859_1;
+    output.write("abcdABCD");
+    output.encoding = Encoding.ASCII;
+    output.write("abcdABCD");
+    output.encoding = Encoding.UTF_8;
+    output.write("æøå");
     output.close();
     output.done.then((_) {
       RandomAccessFile raf = file.openSync();
@@ -404,7 +408,7 @@
     Expect.equals(42, bytes_read);
     file.closeSync();
     // Write the contents of the file just read into another file.
-    String outFilename = tempDirectory.path.concat("/out_read_write_sync");
+    String outFilename = tempDirectory.path + "/out_read_write_sync";
     File outFile = new File(outFilename);
     outFile.createSync();
     String path = outFile.fullPathSync();
@@ -432,7 +436,7 @@
   }
 
   static void testReadEmptyFileSync() {
-    String fileName = tempDirectory.path.concat("/empty_file_sync");
+    String fileName = tempDirectory.path + "/empty_file_sync";
     File file = new File(fileName);
     file.createSync();
     RandomAccessFile openedFile = file.openSync();
@@ -442,7 +446,7 @@
   }
 
   static void testReadEmptyFile() {
-    String fileName = tempDirectory.path.concat("/empty_file");
+    String fileName = tempDirectory.path + "/empty_file";
     File file = new File(fileName);
     asyncTestStarted();
     file.create().then((ignore) {
@@ -623,7 +627,7 @@
   }
 
   static void testTruncate() {
-    File file = new File(tempDirectory.path.concat("/out_truncate"));
+    File file = new File(tempDirectory.path + "/out_truncate");
     List buffer = const [65, 65, 65, 65, 65, 65, 65, 65, 65, 65];
     file.open(FileMode.WRITE).then((RandomAccessFile openedFile) {
       openedFile.writeList(buffer, 0, 10).then((ignore) {
@@ -649,7 +653,7 @@
   }
 
   static void testTruncateSync() {
-    File file = new File(tempDirectory.path.concat("/out_truncate_sync"));
+    File file = new File(tempDirectory.path + "/out_truncate_sync");
     List buffer = const [65, 65, 65, 65, 65, 65, 65, 65, 65, 65];
     RandomAccessFile openedFile = file.openSync(FileMode.WRITE);
     openedFile.writeListSync(buffer, 0, 10);
@@ -665,7 +669,7 @@
   static void testCloseException() {
     bool exceptionCaught = false;
     bool wrongExceptionCaught = false;
-    File input = new File(tempDirectory.path.concat("/out_close_exception"));
+    File input = new File(tempDirectory.path + "/out_close_exception");
     RandomAccessFile openedFile = input.openSync(FileMode.WRITE);
     openedFile.closeSync();
     try {
@@ -757,11 +761,11 @@
     asyncTestStarted();
     List<int> buffer = new List<int>(42);
     File file =
-        new File(tempDirectory.path.concat("/out_close_exception_stream"));
+        new File(tempDirectory.path + "/out_close_exception_stream");
     file.createSync();
     var output = file.openWrite();
     output.close();
-    Expect.throws(() => output.add(buffer));
+    Expect.throws(() => output.writeBytes(buffer));
     output.done.then((_) {
       file.deleteSync();
       asyncTestDone("testCloseExceptionStream");
@@ -773,7 +777,7 @@
     bool exceptionCaught = false;
     bool wrongExceptionCaught = false;
     File file =
-        new File(tempDirectory.path.concat("/out_buffer_out_of_bounds"));
+        new File(tempDirectory.path + "/out_buffer_out_of_bounds");
     RandomAccessFile openedFile = file.openSync(FileMode.WRITE);
     try {
       List<int> buffer = new List<int>(10);
diff --git a/tests/standalone/io/http_10_test.dart b/tests/standalone/io/http_10_test.dart
index a923562..bf88a9a 100644
--- a/tests/standalone/io/http_10_test.dart
+++ b/tests/standalone/io/http_10_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// (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.
 
@@ -25,10 +25,10 @@
           response.done
               .then((_) => Expect.fail("Unexpected response completion"))
               .catchError((e) => Expect.isTrue(e.error is HttpException));
-          response.addString("Z");
-          response.addString("Z");
+          response.write("Z");
+          response.write("Z");
           response.close();
-          Expect.throws(() => response.addString("x"),
+          Expect.throws(() => response.write("x"),
                         (e) => e is StateError);
         },
         onError: (e) => Expect.fail("Unexpected error $e"));
@@ -36,7 +36,7 @@
     int count = 0;
     makeRequest() {
       Socket.connect("127.0.0.1", server.port).then((socket) {
-          socket.addString("GET / HTTP/1.0\r\n\r\n");
+          socket.write("GET / HTTP/1.0\r\n\r\n");
 
           List<int> response = [];
           socket.listen(
@@ -45,7 +45,6 @@
                 count++;
                 socket.destroy();
                 String s = new String.fromCharCodes(response).toLowerCase();
-                Expect.equals("z", s[s.length - 1]);
                 Expect.isTrue(s.indexOf("\r\ncontent-length: 1\r\n") > 0);
                 Expect.equals(-1, s.indexOf("keep-alive"));
                 if (count < 10) {
@@ -70,18 +69,20 @@
         (HttpRequest request) {
           Expect.isNull(request.headers.value('content-length'));
           Expect.equals(-1, request.contentLength);
-          var response = request.response;
-          Expect.equals("1.0", request.protocolVersion);
-          response.addString("Z");
-          response.close();
+          request.listen((_) {}, onDone: () {
+            var response = request.response;
+            Expect.equals("1.0", request.protocolVersion);
+            response.write("Z");
+            response.close();
+          });
         },
         onError: (e) => Expect.fail("Unexpected error $e"));
 
     int count = 0;
     makeRequest() {
       Socket.connect("127.0.0.1", server.port).then((socket) {
-        socket.addString("GET / HTTP/1.0\r\n\r\n");
-        socket.addString("Connection: Keep-Alive\r\n\r\n");
+        socket.write("GET / HTTP/1.0\r\n");
+        socket.write("Connection: Keep-Alive\r\n\r\n");
 
         List<int> response = [];
         socket.listen(
@@ -90,7 +91,6 @@
               socket.destroy();
               count++;
               String s = new String.fromCharCodes(response).toLowerCase();
-              print(s);
               Expect.equals("z", s[s.length - 1]);
               Expect.equals(-1, s.indexOf("content-length:"));
               Expect.equals(-1, s.indexOf("keep-alive"));
@@ -99,7 +99,8 @@
               } else {
                 server.close();
               }
-                      },onError: (e) => print(e));
+            },
+            onError: (e) => print(e));
       });
     }
     makeRequest();
@@ -119,15 +120,15 @@
           var response = request.response;
           response.contentLength = 1;
           Expect.equals("1.0", request.protocolVersion);
-          response.addString("Z");
+          response.write("Z");
           response.close();
         },
         onError: (e) => Expect.fail("Unexpected error $e"));
 
     Socket.connect("127.0.0.1", server.port).then((socket) {
       void sendRequest() {
-        socket.addString("GET / HTTP/1.0\r\n");
-        socket.addString("Connection: Keep-Alive\r\n\r\n");
+        socket.write("GET / HTTP/1.0\r\n");
+        socket.write("Connection: Keep-Alive\r\n\r\n");
       }
 
       List<int> response = [];
@@ -169,7 +170,7 @@
           Expect.equals(-1, request.contentLength);
           var response = request.response;
           Expect.equals("1.0", request.protocolVersion);
-          response.addString("Z");
+          response.write("Z");
           response.close();
         },
         onError: (e) => Expect.fail("Unexpected error $e"));
@@ -177,8 +178,8 @@
     int count = 0;
     makeRequest() {
       Socket.connect("127.0.0.1", server.port).then((socket) {
-        socket.addString("GET / HTTP/1.0\r\n");
-        socket.addString("Connection: Keep-Alive\r\n\r\n");
+        socket.write("GET / HTTP/1.0\r\n");
+        socket.write("Connection: Keep-Alive\r\n\r\n");
 
         List<int> response = [];
         socket.listen(
@@ -205,8 +206,7 @@
 
 void main() {
   testHttp10NoKeepAlive();
-  // TODO(8871): This test fails with short socket writes.
-  //testHttp10ServerClose();
+  testHttp10ServerClose();
   testHttp10KeepAlive();
   testHttp10KeepAliveServerCloses();
 }
diff --git a/tests/standalone/io/http_advanced_test.dart b/tests/standalone/io/http_advanced_test.dart
index e19365f..56b51e8 100644
--- a/tests/standalone/io/http_advanced_test.dart
+++ b/tests/standalone/io/http_advanced_test.dart
@@ -145,8 +145,7 @@
     Expect.equals("html", request.headers.contentType.subType);
     Expect.equals("utf-8", request.headers.contentType.parameters["charset"]);
 
-    ContentType contentType = new ContentType("text", "html");
-    contentType.parameters["charset"] = "utf-8";
+    ContentType contentType = new ContentType("text", "html", charset: "utf-8");
     response.headers.contentType = contentType;
     response.close();
   }
@@ -347,10 +346,8 @@
 
     httpClient.get("127.0.0.1", port, "/contenttype1")
         .then((request) {
-          ContentType contentType = new ContentType();
-          contentType.value = "text/html";
-          contentType.parameters["charset"] = "utf-8";
-          request.headers.contentType = contentType;
+          request.headers.contentType =
+              new ContentType("text", "html", charset: "utf-8");
           return request.close();
         })
         .then(processResponse);
diff --git a/tests/standalone/io/http_basic_test.dart b/tests/standalone/io/http_basic_test.dart
index eff6f5d..670a649 100644
--- a/tests/standalone/io/http_basic_test.dart
+++ b/tests/standalone/io/http_basic_test.dart
@@ -110,7 +110,7 @@
     var response = request.response;
     Expect.equals("GET", request.method);
     request.listen((_) {}, onDone: () {
-        response.addString("01234567890");
+        response.write("01234567890");
         response.close();
       });
   }
@@ -120,7 +120,7 @@
     var response = request.response;
     response.statusCode = HttpStatus.NOT_FOUND;
     response.headers.set("Content-Type", "text/html; charset=UTF-8");
-    response.addString("Page not found");
+    response.write("Page not found");
     response.close();
   }
 
@@ -204,7 +204,7 @@
           Expect.equals(HttpStatus.OK, response.statusCode);
           StringBuffer body = new StringBuffer();
           response.listen(
-            (data) => body.add(new String.fromCharCodes(data)),
+            (data) => body.write(new String.fromCharCodes(data)),
             onDone: () {
               Expect.equals("01234567890", body.toString());
               httpClient.close();
@@ -228,11 +228,11 @@
       httpClient.post("127.0.0.1", port, "/echo")
           .then((request) {
             if (chunkedEncoding) {
-              request.addString(data.substring(0, 10));
-              request.addString(data.substring(10, data.length));
+              request.write(data.substring(0, 10));
+              request.write(data.substring(10, data.length));
             } else {
               request.contentLength = data.length;
-              request.addString(data);
+              request.write(data);
             }
             return request.close();
           })
@@ -240,7 +240,7 @@
             Expect.equals(HttpStatus.OK, response.statusCode);
             StringBuffer body = new StringBuffer();
             response.listen(
-              (data) => body.add(new String.fromCharCodes(data)),
+              (data) => body.write(new String.fromCharCodes(data)),
               onDone: () {
                 Expect.equals(data, body.toString());
                 count++;
@@ -274,7 +274,7 @@
           Expect.equals(HttpStatus.NOT_FOUND, response.statusCode);
           var body = new StringBuffer();
           response.listen(
-              (data) => body.add(new String.fromCharCodes(data)),
+              (data) => body.write(new String.fromCharCodes(data)),
               onDone: () {
                 Expect.equals("Page not found", body.toString());
                 httpClient.close();
diff --git a/tests/standalone/io/http_client_connect_test.dart b/tests/standalone/io/http_client_connect_test.dart
index 93bd7fa..3f466dd 100644
--- a/tests/standalone/io/http_client_connect_test.dart
+++ b/tests/standalone/io/http_client_connect_test.dart
@@ -32,7 +32,7 @@
   HttpServer.bind().then((server) {
     var data = "lalala".codeUnits;
     server.listen((request) {
-      request.response.add(data);
+      request.response.writeBytes(data);
       request.pipe(request.response);
     });
 
@@ -84,8 +84,8 @@
   HttpServer.bind().then((server) {
     server.listen((request) {
       request.response.contentLength = 100;
-      request.response.addString("data");
-      request.response.addString("more data");
+      request.response.write("data");
+      request.response.write("more data");
       completer.future.then((_) => server.close());
     });
 
diff --git a/tests/standalone/io/http_client_request_test.dart b/tests/standalone/io/http_client_request_test.dart
index 02d0a86..84e7b2d 100644
--- a/tests/standalone/io/http_client_request_test.dart
+++ b/tests/standalone/io/http_client_request_test.dart
@@ -46,7 +46,8 @@
   testClientRequest((request) {
     var port = new ReceivePort();
     request.contentLength = 0;
-    request.add([0]);
+    request.writeBytes([0]);
+    request.close();
     request.done.catchError((error) {
       port.close();
     }, test: (e) => e is HttpException);
@@ -56,8 +57,9 @@
   testClientRequest((request) {
     var port = new ReceivePort();
     request.contentLength = 5;
-    request.add([0, 0, 0]);
-    request.add([0, 0, 0]);
+    request.writeBytes([0, 0, 0]);
+    request.writeBytes([0, 0, 0]);
+    request.close();
     request.done.catchError((error) {
       port.close();
     }, test: (e) => e is HttpException);
@@ -67,9 +69,10 @@
   testClientRequest((request) {
     var port = new ReceivePort();
     request.contentLength = 0;
-    request.add(new Uint8List(64 * 1024));
-    request.add(new Uint8List(64 * 1024));
-    request.add(new Uint8List(64 * 1024));
+    request.writeBytes(new Uint8List(64 * 1024));
+    request.writeBytes(new Uint8List(64 * 1024));
+    request.writeBytes(new Uint8List(64 * 1024));
+    request.close();
     request.done.catchError((error) {
       port.close();
     }, test: (e) => e is HttpException);
@@ -91,7 +94,7 @@
   testClientRequest((request) {
     var port = new ReceivePort();
     request.contentLength = 5;
-    request.add([0]);
+    request.writeBytes([0]);
     request.close();
     request.done.catchError((error) {
       port.close();
diff --git a/tests/standalone/io/http_close_test.dart b/tests/standalone/io/http_close_test.dart
index de467d5..056ec0e 100644
--- a/tests/standalone/io/http_close_test.dart
+++ b/tests/standalone/io/http_close_test.dart
@@ -91,7 +91,7 @@
       client.post("localhost", server.port, "/")
           .then((request) {
             req = request;
-            request.add(new Uint8List(1024));
+            request.writeBytes(new Uint8List(1024));
             return request.response;
           })
           .then((response) {
@@ -123,8 +123,8 @@
       }
     }
     server.listen((request) {
-      var timer = new Timer.repeating(const Duration(milliseconds: 20), (_) {
-        request.response.add(new Uint8List(16 * 1024));
+      var timer = new Timer.periodic(const Duration(milliseconds: 20), (_) {
+        request.response.writeBytes(new Uint8List(16 * 1024));
       });
       request.response.done
           .catchError((_) {})
diff --git a/tests/standalone/io/http_compression_test.dart b/tests/standalone/io/http_compression_test.dart
new file mode 100644
index 0000000..7720063
--- /dev/null
+++ b/tests/standalone/io/http_compression_test.dart
@@ -0,0 +1,93 @@
+// 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.
+//
+// VMOptions=
+// VMOptions=--short_socket_read
+// VMOptions=--short_socket_write
+// VMOptions=--short_socket_read --short_socket_write
+
+import 'dart:io';
+import 'dart:scalarlist';
+
+void testServerCompress() {
+  void test(List<int> data) {
+    HttpServer.bind().then((server) {
+      server.listen((request) {
+        request.response.writeBytes(data);
+        request.response.close();
+      });
+      var client = new HttpClient();
+      client.get("localhost", server.port, "/")
+          .then((request) {
+            request.headers.set(HttpHeaders.ACCEPT_ENCODING, "gzip,deflate");
+            return request.close();
+          })
+          .then((response) {
+            Expect.equals("gzip",
+                          response.headers.value(HttpHeaders.CONTENT_ENCODING));
+            response
+                .transform(new ZLibInflater())
+                .reduce([], (list, b) {
+                  list.addAll(b);
+                  return list;
+                }).then((list) {
+                  Expect.listEquals(data, list);
+                  server.close();
+                  client.close();
+                });
+          });
+    });
+  }
+  test("My raw server provided data".codeUnits);
+  var longBuffer = new Uint8List(1024 * 1024);
+  for (int i = 0; i < longBuffer.length; i++) {
+    longBuffer[i] = i & 0xFF;
+  }
+  test(longBuffer);
+}
+
+void testAcceptEncodingHeader() {
+  void test(String encoding, bool valid) {
+    HttpServer.bind().then((server) {
+      server.listen((request) {
+        request.response.write("data");
+        request.response.close();
+      });
+      var client = new HttpClient();
+      client.get("localhost", server.port, "/")
+          .then((request) {
+            request.headers.set(HttpHeaders.ACCEPT_ENCODING, encoding);
+            return request.close();
+          })
+          .then((response) {
+            Expect.equals(
+              valid,
+              ("gzip" == response.headers.value(HttpHeaders.CONTENT_ENCODING)));
+            response.listen(
+                (_) {},
+                onDone: () {
+                  server.close();
+                  client.close();
+                });
+          });
+    });
+  }
+  test('gzip', true);
+  test('deflate', false);
+  test('gzip, deflate', true);
+  test('gzip ,deflate', true);
+  test('gzip  ,  deflate', true);
+  test('deflate,gzip', true);
+  test('deflate, gzip', true);
+  test('deflate ,gzip', true);
+  test('deflate  ,  gzip', true);
+  test('abc,deflate  ,  gzip,def,,,ghi  ,jkl', true);
+  test('xgzip', false);
+  test('gzipx;', false);
+}
+
+void main() {
+  testServerCompress();
+  testAcceptEncodingHeader();
+}
diff --git a/tests/standalone/io/http_connection_close_test.dart b/tests/standalone/io/http_connection_close_test.dart
index a2a11c7..7225ef7 100644
--- a/tests/standalone/io/http_connection_close_test.dart
+++ b/tests/standalone/io/http_connection_close_test.dart
@@ -15,7 +15,7 @@
 
     Socket.connect("127.0.0.1", server.port)
       .then((socket) {
-        socket.addString("GET / HTTP/1.0\r\n\r\n");
+        socket.write("GET / HTTP/1.0\r\n\r\n");
         socket.listen(
           (data) {},
           onDone: () {
@@ -36,7 +36,7 @@
     Socket.connect("127.0.0.1", server.port)
       .then((socket) {
         List<int> buffer = new List<int>(1024);
-        socket.addString("GET / HTTP/1.1\r\nConnection: close\r\n\r\n");
+        socket.write("GET / HTTP/1.1\r\nConnection: close\r\n\r\n");
         socket.listen(
           (data) {},
           onDone: () {
@@ -51,11 +51,15 @@
 void testStreamResponse() {
   HttpServer.bind().then((server) {
     server.listen((request) {
-      // TODO(ajohnsen): Use timer (see old version).
-      for (int i = 0; i < 10; i++) {
-        request.response.addString(
+      var timer = new Timer.periodic(const Duration(milliseconds: 0), (_) {
+        request.response.write(
             'data:${new DateTime.now().millisecondsSinceEpoch}\n\n');
-      }
+      });
+      request.response.done
+          .whenComplete(() {
+            timer.cancel();
+          })
+          .catchError((_) {});
     });
 
     var client = new HttpClient();
diff --git a/tests/standalone/io/http_content_length_test.dart b/tests/standalone/io/http_content_length_test.dart
index 16a1d03..cbe04ea 100644
--- a/tests/standalone/io/http_content_length_test.dart
+++ b/tests/standalone/io/http_content_length_test.dart
@@ -21,16 +21,16 @@
             .catchError((e) {
               Expect.isTrue(e.error is HttpException);
             });
-          // addString with content length 0 closes the connection and
+          // write with content length 0 closes the connection and
           // reports an error.
-          response.addString("x");
-          // Subsequent addString are ignored as there is already an
+          response.write("x");
+          // Subsequent write are ignored as there is already an
           // error.
-          response.addString("x");
-          // After an explicit close, addString becomes a state error
+          response.write("x");
+          // After an explicit close, write becomes a state error
           // because we have said we will not add more.
           response.close();
-          Expect.throws(() => response.addString("x"),
+          Expect.throws(() => response.write("x"),
                         (e) => e is StateError);
         },
         onError: (e) {
@@ -82,11 +82,11 @@
           request.listen(
               (d) {},
               onDone: () {
-                response.addString("x");
+                response.write("x");
                 Expect.throws(() => response.contentLength = 3,
                               (e) => e is HttpException);
-                response.addString("x");
-                response.addString("x");
+                response.write("x");
+                response.write("x");
                 response.done
                     .then((_) {
                       Expect.fail("Unexpected successful response completion");
@@ -98,7 +98,7 @@
                       }
                     });
                 response.close();
-                Expect.throws(() => response.addString("x"),
+                Expect.throws(() => response.write("x"),
                               (e) => e is StateError);
               });
         },
@@ -115,10 +115,10 @@
               request.headers.add(HttpHeaders.CONTENT_LENGTH, "7");
               request.headers.add(HttpHeaders.CONTENT_LENGTH, "2");
             }
-            request.addString("x");
+            request.write("x");
             Expect.throws(() => request.contentLength = 3,
                           (e) => e is HttpException);
-            request.addString("x");
+            request.write("x");
             return request.close();
           })
           .then((response) {
@@ -130,6 +130,9 @@
                   if (++clientCount == totalConnections) {
                     client.close();
                   }
+                },
+                onError: (error) {
+                  // Undefined what server response sends.
                 });
           });
     }
@@ -153,14 +156,14 @@
           request.listen(
               (d) {},
               onDone: () {
-                response.addString("x");
+                response.write("x");
                 Expect.throws(
                     () => response.headers.chunkedTransferEncoding = false,
                     (e) => e is HttpException);
-                response.addString("x");
-                response.addString("x");
+                response.write("x");
+                response.write("x");
                 response.close();
-                Expect.throws(() => response.addString("x"),
+                Expect.throws(() => response.write("x"),
                               (e) => e is StateError);
               });
         },
@@ -178,11 +181,11 @@
               request.headers.add(HttpHeaders.CONTENT_LENGTH, "2");
               request.headers.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
             }
-            request.addString("x");
+            request.write("x");
             Expect.throws(() => request.headers.chunkedTransferEncoding = false,
                           (e) => e is HttpException);
-            request.addString("x");
-            request.addString("x");
+            request.write("x");
+            request.write("x");
             return request.close();
           })
           .then((response) {
@@ -212,7 +215,7 @@
           response.headers.set("content-length", 3);
           Expect.equals("3", response.headers.value('content-length'));
           Expect.equals(3, response.contentLength);
-          response.addString("xxx");
+          response.write("xxx");
           response.close();
         });
 
diff --git a/tests/standalone/io/http_detach_socket_test.dart b/tests/standalone/io/http_detach_socket_test.dart
index e3a5ad5..9c6f8c3 100644
--- a/tests/standalone/io/http_detach_socket_test.dart
+++ b/tests/standalone/io/http_detach_socket_test.dart
@@ -19,21 +19,21 @@
         Expect.isNotNull(socket);
         var body = new StringBuffer();
         socket.listen(
-          (data) => body.add(new String.fromCharCodes(data)),
+          (data) => body.write(new String.fromCharCodes(data)),
           onDone: () => Expect.equals("Some data", body.toString()));
-        socket.addString("Test!");
+        socket.write("Test!");
         socket.close();
       });
       server.close();
     });
 
     Socket.connect("127.0.0.1", server.port).then((socket) {
-      socket.addString("GET / HTTP/1.1\r\n"
+      socket.write("GET / HTTP/1.1\r\n"
                        "content-length: 0\r\n\r\n"
                        "Some data");
       var body = new StringBuffer();
       socket.listen(
-        (data) => body.add(new String.fromCharCodes(data)),
+        (data) => body.write(new String.fromCharCodes(data)),
         onDone: () {
           Expect.equals("HTTP/1.1 200 OK\r\n"
                         "content-length: 0\r\n"
@@ -57,7 +57,7 @@
     });
 
     Socket.connect("127.0.0.1", server.port).then((socket) {
-      socket.addString("GET / HTTP/1.1\r\n"
+      socket.write("GET / HTTP/1.1\r\n"
                        "content-length: 0\r\n\r\n");
       socket.listen((_) {}, onDone: () {
           socket.close();
@@ -69,12 +69,12 @@
 void testClientDetachSocket() {
   ServerSocket.bind().then((server) {
     server.listen((socket) {
-      socket.addString("HTTP/1.1 200 OK\r\n"
+      socket.write("HTTP/1.1 200 OK\r\n"
                        "\r\n"
                        "Test!");
       var body = new StringBuffer();
       socket.listen(
-        (data) => body.add(new String.fromCharCodes(data)),
+        (data) => body.write(new String.fromCharCodes(data)),
         onDone: () {
           Expect.equals("GET / HTTP/1.1\r\n"
                         "content-length: 0\r\n"
@@ -93,13 +93,13 @@
         response.detachSocket().then((socket) {
           var body = new StringBuffer();
           socket.listen(
-            (data) => body.add(new String.fromCharCodes(data)),
+            (data) => body.write(new String.fromCharCodes(data)),
             onDone: () {
               Expect.equals("Test!",
                             body.toString());
               client.close();
             });
-          socket.addString("Some data");
+          socket.write("Some data");
           socket.close();
         });
       });
diff --git a/tests/standalone/io/http_head_test.dart b/tests/standalone/io/http_head_test.dart
index 9325ceb..bb33ad3 100644
--- a/tests/standalone/io/http_head_test.dart
+++ b/tests/standalone/io/http_head_test.dart
@@ -14,7 +14,15 @@
         } else if (request.uri.path == "/test200") {
           response.contentLength = 200;
           List<int> data = new List<int>.filled(200, 0);
-          response.add(data);
+          response.writeBytes(data);
+          response.close();
+        } else if (request.uri.path == "/testChunked100") {
+          List<int> data = new List<int>.filled(100, 0);
+          response.writeBytes(data);
+          response.close();
+        } else if (request.uri.path == "/testChunked200") {
+          List<int> data = new List<int>.filled(200, 0);
+          response.writeBytes(data);
           response.close();
         } else {
           assert(false);
@@ -24,6 +32,15 @@
     HttpClient client = new HttpClient();
 
     int count = 0;
+
+    requestDone() {
+      count++;
+      if (count == totalConnections * 2) {
+        client.close();
+        server.close();
+      }
+    }
+
     for (int i = 0; i < totalConnections; i++) {
       int len = (i % 2 == 0) ? 100 : 200;
       client.open("HEAD", "127.0.0.1", server.port, "/test$len")
@@ -32,13 +49,17 @@
           Expect.equals(len, response.contentLength);
           response.listen(
             (_) => Expect.fail("Data from HEAD request"),
-            onDone: () {
-              count++;
-              if (count == totalConnections) {
-                client.close();
-                server.close();
-              }
-            });
+            onDone: requestDone);
+        });
+
+      client.open("HEAD", "127.0.0.1", server.port, "/testChunked$len")
+        .then((request) => request.close())
+        .then((HttpClientResponse response) {
+            print(response.headers);
+          Expect.equals(-1, response.contentLength);
+          response.listen(
+            (_) => Expect.fail("Data from HEAD request"),
+            onDone: requestDone);
         });
     }
   });
diff --git a/tests/standalone/io/http_headers_state_test.dart b/tests/standalone/io/http_headers_state_test.dart
index 73754c7..a685eb6 100644
--- a/tests/standalone/io/http_headers_state_test.dart
+++ b/tests/standalone/io/http_headers_state_test.dart
@@ -19,7 +19,7 @@
         // Can still mutate response headers as long as no data has been sent.
         response.headers.add("X-Response-Header", "value");
         if (body != null) {
-          response.addString(body);
+          response.write(body);
           // Cannot mutate response headers when data has been sent.
           Expect.throws(() => request.headers.add("X-Request-Header", "value2"),
                         (e) => e is HttpException);
@@ -42,7 +42,7 @@
           // Can still mutate request headers as long as no data has been sent.
           request.headers.add("X-Request-Header", "value");
           if (body != null) {
-            request.addString(body);
+            request.write(body);
             // Cannot mutate request headers when data has been sent.
             Expect.throws(
                 () => request.headers.add("X-Request-Header", "value2"),
diff --git a/tests/standalone/io/http_headers_test.dart b/tests/standalone/io/http_headers_test.dart
index 19829e7..5d94173 100644
--- a/tests/standalone/io/http_headers_test.dart
+++ b/tests/standalone/io/http_headers_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -205,6 +205,10 @@
   headerValue = new HeaderValue.fromString(
       "xxx; aaa=bbb; ccc=\"\\\";\\a\"; ddd=\"    \"");
   check(headerValue, "xxx", {"aaa": "bbb", "ccc": '\";a', "ddd": "    "});
+  headerValue = new HeaderValue("xxx",
+                                {"aaa": "bbb", "ccc": '\";a', "ddd": "    "});
+  check(headerValue, "xxx", {"aaa": "bbb", "ccc": '\";a', "ddd": "    "});
+
   headerValue = new HeaderValue.fromString(
     "attachment; filename=genome.jpeg;"
     "modification-date=\"Wed, 12 February 1997 16:29:51 -0500\"");
@@ -213,6 +217,8 @@
       "modification-date": "Wed, 12 February 1997 16:29:51 -0500"
   };
   check(headerValue, "attachment", parameters);
+  headerValue = new HeaderValue("attachment", parameters);
+  check(headerValue, "attachment", parameters);
   headerValue = new HeaderValue.fromString(
     "  attachment  ;filename=genome.jpeg  ;"
     "modification-date = \"Wed, 12 February 1997 16:29:51 -0500\""  );
@@ -238,47 +244,56 @@
   }
 
   ContentType contentType;
-  contentType = new ContentType();
+  contentType = new ContentType("", "");
   Expect.equals("", contentType.primaryType);
   Expect.equals("", contentType.subType);
   Expect.equals("/", contentType.value);
-  contentType.value = "text/html";
-  Expect.equals("text", contentType.primaryType);
-  Expect.equals("html", contentType.subType);
-  Expect.equals("text/html", contentType.value);
 
-  contentType = new _ContentType.fromString("text/html");
+  contentType = new ContentType.fromString("text/html");
   check(contentType, "text", "html");
   Expect.equals("text/html", contentType.toString());
-  contentType.parameters["charset"] = "utf-8";
+  contentType = new ContentType("text", "html", charset: "utf-8");
   check(contentType, "text", "html", {"charset": "utf-8"});
   Expect.equals("text/html; charset=utf-8", contentType.toString());
-  contentType.parameters["xxx"] = "yyy";
+
+  contentType = new ContentType("text",
+                                "html",
+                                parameters: {"CHARSET": "UTF-8", "xxx": "yyy"});
   check(contentType, "text", "html", {"charset": "utf-8", "xxx": "yyy"});
   String s = contentType.toString();
   bool expectedToString = (s == "text/html; charset=utf-8; xxx=yyy" ||
                            s == "text/html; xxx=yyy; charset=utf-8");
   Expect.isTrue(expectedToString);
 
-  contentType = new _ContentType.fromString("text/html");
+  contentType = new ContentType("text",
+                                "html",
+                                charset: "ISO-8859-1",
+                                parameters: {"CHARSET": "UTF-8", "xxx": "yyy"});
+  check(contentType, "text", "html", {"charset": "iso-8859-1", "xxx": "yyy"});
+  s = contentType.toString();
+  expectedToString = (s == "text/html; charset=iso-8859-1; xxx=yyy" ||
+                      s == "text/html; xxx=yyy; charset=iso-8859-1");
+  Expect.isTrue(expectedToString);
+
+  contentType = new ContentType.fromString("text/html");
   check(contentType, "text", "html");
-  contentType = new _ContentType.fromString(" text/html  ");
+  contentType = new ContentType.fromString(" text/html  ");
   check(contentType, "text", "html");
-  contentType = new _ContentType.fromString("text/html; charset=utf-8");
+  contentType = new ContentType.fromString("text/html; charset=utf-8");
   check(contentType, "text", "html", {"charset": "utf-8"});
-  contentType = new _ContentType.fromString(
+  contentType = new ContentType.fromString(
       "  text/html  ;  charset  =  utf-8  ");
   check(contentType, "text", "html", {"charset": "utf-8"});
-  contentType = new _ContentType.fromString(
+  contentType = new ContentType.fromString(
       "text/html; charset=utf-8; xxx=yyy");
   check(contentType, "text", "html", {"charset": "utf-8", "xxx": "yyy"});
-  contentType = new _ContentType.fromString(
+  contentType = new ContentType.fromString(
       "  text/html  ;  charset  =  utf-8  ;  xxx=yyy  ");
   check(contentType, "text", "html", {"charset": "utf-8", "xxx": "yyy"});
-  contentType = new _ContentType.fromString(
+  contentType = new ContentType.fromString(
       'text/html; charset=utf-8; xxx="yyy"');
   check(contentType, "text", "html", {"charset": "utf-8", "xxx": "yyy"});
-  contentType = new _ContentType.fromString(
+  contentType = new ContentType.fromString(
       "  text/html  ;  charset  =  utf-8  ;  xxx=yyy  ");
   check(contentType, "text", "html", {"charset": "utf-8", "xxx": "yyy"});
 }
@@ -294,9 +309,7 @@
   Expect.equals("plain", headers.contentType.subType);
   Expect.equals("text/plain", headers.contentType.value);
   headers.removeAll(HttpHeaders.CONTENT_TYPE);
-  Expect.equals("", headers.contentType.primaryType);
-  Expect.equals("", headers.contentType.subType);
-  Expect.equals("/", headers.contentType.value);
+  Expect.isNull(headers.contentType);
 }
 
 void testCookie() {
diff --git a/tests/standalone/io/http_keep_alive_test.dart b/tests/standalone/io/http_keep_alive_test.dart
index c89b4ee..30373e8 100644
--- a/tests/standalone/io/http_keep_alive_test.dart
+++ b/tests/standalone/io/http_keep_alive_test.dart
@@ -28,7 +28,7 @@
       int length = int.parse(request.queryParameters["length"]);
       var buffer = new List<int>.filled(length, 0);
       if (!chunked) request.response.contentLength = length;
-      request.response.add(buffer);
+      request.response.writeBytes(buffer);
       request.response.close();
     });
     return server;
diff --git a/tests/standalone/io/http_parser_test.dart b/tests/standalone/io/http_parser_test.dart
index ab02206..cc4cc4d 100644
--- a/tests/standalone/io/http_parser_test.dart
+++ b/tests/standalone/io/http_parser_test.dart
@@ -116,9 +116,8 @@
       if (chunkSize == -1) chunkSize = requestData.length;
       reset();
       for (int pos = 0; pos < requestData.length; pos += chunkSize) {
-        int remaining = requestData.length - pos;
-        int writeLength = min(chunkSize, remaining);
-        controller.add(requestData.getRange(pos, writeLength));
+        int end = min(requestData.length, pos + chunkSize);
+        controller.add(requestData.sublist(pos, end));
       }
       controller.close();
     }
@@ -160,9 +159,8 @@
       for (int pos = 0;
            pos < requestData.length && !errorCalled;
            pos += chunkSize) {
-        int remaining = requestData.length - pos;
-        int writeLength = min(chunkSize, remaining);
-        controller.add(requestData.getRange(pos, writeLength));
+        int end = min(requestData.length, pos + chunkSize);
+        controller.add(requestData.sublist(pos, end));
       }
       controller.close();
     }
@@ -260,9 +258,8 @@
       if (chunkSize == -1) chunkSize = requestData.length;
       reset();
       for (int pos = 0; pos < requestData.length; pos += chunkSize) {
-        int remaining = requestData.length - pos;
-        int writeLength = min(chunkSize, remaining);
-        controller.add(requestData.getRange(pos, writeLength));
+        int end = min(requestData.length, pos + chunkSize);
+        controller.add(requestData.sublist(pos, end));
 
       }
       if (close) controller.close();
@@ -311,9 +308,8 @@
       for (int pos = 0;
            pos < requestData.length && !errorCalled;
            pos += chunkSize) {
-        int remaining = requestData.length - pos;
-        int writeLength = min(chunkSize, remaining);
-        controller.add(requestData.getRange(pos, writeLength));
+        int end = min(requestData.length, pos + chunkSize);
+        controller.add(requestData.sublist(pos, end));
       }
       controller.close();
     }
diff --git a/tests/standalone/io/http_proxy_test.dart b/tests/standalone/io/http_proxy_test.dart
index af8cdff..dd87619 100644
--- a/tests/standalone/io/http_proxy_test.dart
+++ b/tests/standalone/io/http_proxy_test.dart
@@ -43,13 +43,13 @@
         var body = new StringBuffer();
         request.listen(
             (data) {
-              body.add(new String.fromCharCodes(data));
+              body.write(new String.fromCharCodes(data));
             },
             onDone: () {
               String path = request.uri.path.substring(1);
               String content = "$path$path$path";
               Expect.equals(content, body.toString());
-              response.addString(request.uri.path);
+              response.write(request.uri.path);
               response.close();
             });
       });
@@ -165,7 +165,7 @@
         .then((HttpClientRequest clientRequest) {
           String content = "$i$i$i";
           clientRequest.contentLength = content.length;
-          clientRequest.addString(content);
+          clientRequest.write(content);
           return clientRequest.close();
         })
        .then((HttpClientResponse response) {
@@ -224,7 +224,7 @@
         client.postUrl(Uri.parse(url))
           .then((HttpClientRequest clientRequest) {
             String content = "$i$i$i";
-            clientRequest.addString(content);
+            clientRequest.write(content);
             return clientRequest.close();
           })
           .then((HttpClientResponse response) {
@@ -290,7 +290,7 @@
         .then((HttpClientRequest clientRequest) {
           String content = "$i$i$i";
           clientRequest.contentLength = content.length;
-          clientRequest.addString(content);
+          clientRequest.write(content);
           return clientRequest.close();
         })
         .then((HttpClientResponse response) {
@@ -333,7 +333,7 @@
         .then((HttpClientRequest clientRequest) {
           String content = "$i$i$i";
           clientRequest.contentLength = content.length;
-          clientRequest.addString(content);
+          clientRequest.write(content);
           return clientRequest.close();
         })
         .then((HttpClientResponse response) {
diff --git a/tests/standalone/io/http_read_test.dart b/tests/standalone/io/http_read_test.dart
index 6cba2b5..32226c6 100644
--- a/tests/standalone/io/http_read_test.dart
+++ b/tests/standalone/io/http_read_test.dart
@@ -111,7 +111,7 @@
     var response = request.response;
     response.statusCode = HttpStatus.NOT_FOUND;
     response.headers.set("Content-Type", "text/html; charset=UTF-8");
-    response.addString("Page not found");
+    response.write("Page not found");
     response.close();
   }
 
@@ -170,11 +170,11 @@
       httpClient.post("127.0.0.1", port, "/echo")
           .then((request) {
             if (chunkedEncoding) {
-              request.addString(data.substring(0, 10));
-              request.addString(data.substring(10, data.length));
+              request.write(data.substring(0, 10));
+              request.write(data.substring(10, data.length));
             } else {
               request.contentLength = data.length;
-              request.add(data.codeUnits);
+              request.writeBytes(data.codeUnits);
             }
             return request.close();
           })
diff --git a/tests/standalone/io/http_request_pipeling_test.dart b/tests/standalone/io/http_request_pipeling_test.dart
index a96fa88..b12cb48 100644
--- a/tests/standalone/io/http_request_pipeling_test.dart
+++ b/tests/standalone/io/http_request_pipeling_test.dart
@@ -16,7 +16,7 @@
   HttpServer.bind().then((server) {
     server.listen((HttpRequest request) {
       count++;
-      request.response.addString(request.uri.path);
+      request.response.write(request.uri.path);
       request.response.close();
       if (request.uri.path == "/done") {
         request.response.done.then((_) {
@@ -28,9 +28,9 @@
     Socket.connect("127.0.0.1", server.port).then((s) {
       s.listen((data) { });
       for (int i = 0; i < REQUEST_COUNT; i++) {
-        s.addString("GET /$i HTTP/1.1\r\nX-Header-1: 111\r\n\r\n");
+        s.write("GET /$i HTTP/1.1\r\nX-Header-1: 111\r\n\r\n");
       }
-      s.addString("GET /done HTTP/1.1\r\nConnection: close\r\n\r\n");
+      s.write("GET /done HTTP/1.1\r\nConnection: close\r\n\r\n");
       s.close();
     });
   });
diff --git a/tests/standalone/io/http_server_early_client_close_test.dart b/tests/standalone/io/http_server_early_client_close_test.dart
index 2f75862..72324e2 100644
--- a/tests/standalone/io/http_server_early_client_close_test.dart
+++ b/tests/standalone/io/http_server_early_client_close_test.dart
@@ -11,7 +11,7 @@
     socket.listen((data) {
         Expect.fail("No data response was expected");
       });
-    socket.add(data);
+    socket.writeBytes(data);
     socket.close();
     socket.done.then((_) {
       socket.destroy();
@@ -109,15 +109,15 @@
     server.listen(
       (request) {
         String name = new Options().script;
-        new File(name).openRead().pipe(request.response);
-      },
-      onError: (e) { /* ignore */ });
+        new File(name).openRead().pipe(request.response)
+            .catchError((e) { /* ignore */ });
+      });
 
     var count = 0;
     makeRequest() {
       Socket.connect("127.0.0.1", server.port).then((socket) {
-        var data = "GET / HTTP/1.1\r\nContent-Length: 0\r\n\r\n".codeUnits;
-        socket.add(data);
+        var data = "GET / HTTP/1.1\r\nContent-Length: 0\r\n\r\n";
+        socket.write(data);
         socket.close();
         socket.done.then((_) {
           socket.destroy();
@@ -133,7 +133,32 @@
   });
 }
 
+void testEarlyClose3() {
+  HttpServer.bind().then((server) {
+    server.listen((request) {
+      var subscription;
+      subscription = request.listen(
+          (_) {},
+          onError: (error) {
+            // subscription.cancel should not trigger an error.
+            subscription.cancel();
+            server.close();
+          });
+    });
+    Socket.connect("localhost", server.port)
+        .then((socket) {
+          socket.write("GET / HTTP/1.1\r\n");
+          socket.write("Content-Length: 10\r\n");
+          socket.write("\r\n");
+          socket.write("data");
+          socket.close();
+          socket.listen((_) {});
+        });
+  });
+}
+
 void main() {
   testEarlyClose1();
-//  testEarlyClose2();
+  testEarlyClose2();
+  testEarlyClose3();
 }
diff --git a/tests/standalone/io/http_server_response_test.dart b/tests/standalone/io/http_server_response_test.dart
index fc94876..be1dfff 100644
--- a/tests/standalone/io/http_server_response_test.dart
+++ b/tests/standalone/io/http_server_response_test.dart
@@ -55,7 +55,7 @@
   int bytes = new File(new Options().script).lengthSync();
 
   testServerRequest((server, request) {
-    request.response.addStream(new File(new Options().script).openRead())
+    request.response.writeStream(new File(new Options().script).openRead())
         .then((response) {
           response.close();
           response.done.then((_) => server.close());
@@ -63,9 +63,9 @@
   }, bytes: bytes);
 
   testServerRequest((server, request) {
-    request.response.addStream(new File(new Options().script).openRead())
+    request.response.writeStream(new File(new Options().script).openRead())
         .then((response) {
-          request.response.addStream(new File(new Options().script).openRead())
+          request.response.writeStream(new File(new Options().script).openRead())
               .then((response) {
                 response.close();
                 response.done.then((_) => server.close());
@@ -75,7 +75,7 @@
 
   testServerRequest((server, request) {
     var controller = new StreamController();
-    request.response.addStream(controller.stream)
+    request.response.writeStream(controller.stream)
         .then((response) {
           response.close();
           response.done.then((_) => server.close());
@@ -87,7 +87,8 @@
 void testBadResponseAdd() {
   testServerRequest((server, request) {
     request.response.contentLength = 0;
-    request.response.add([0]);
+    request.response.writeBytes([0]);
+    request.response.close();
     request.response.done.catchError((error) {
       server.close();
     }, test: (e) => e is HttpException);
@@ -95,8 +96,9 @@
 
   testServerRequest((server, request) {
     request.response.contentLength = 5;
-    request.response.add([0, 0, 0]);
-    request.response.add([0, 0, 0]);
+    request.response.writeBytes([0, 0, 0]);
+    request.response.writeBytes([0, 0, 0]);
+    request.response.close();
     request.response.done.catchError((error) {
       server.close();
     }, test: (e) => e is HttpException);
@@ -104,9 +106,10 @@
 
   testServerRequest((server, request) {
     request.response.contentLength = 0;
-    request.response.add(new Uint8List(64 * 1024));
-    request.response.add(new Uint8List(64 * 1024));
-    request.response.add(new Uint8List(64 * 1024));
+    request.response.writeBytes(new Uint8List(64 * 1024));
+    request.response.writeBytes(new Uint8List(64 * 1024));
+    request.response.writeBytes(new Uint8List(64 * 1024));
+    request.response.close();
     request.response.done.catchError((error) {
       server.close();
     }, test: (e) => e is HttpException);
@@ -124,7 +127,7 @@
 
   testServerRequest((server, request) {
     request.response.contentLength = 5;
-    request.response.add([0]);
+    request.response.writeBytes([0]);
     request.response.close();
     request.response.done.catchError((error) {
       server.close();
diff --git a/tests/standalone/io/http_shutdown_test.dart b/tests/standalone/io/http_shutdown_test.dart
index 8c91797..6c3612a 100644
--- a/tests/standalone/io/http_shutdown_test.dart
+++ b/tests/standalone/io/http_shutdown_test.dart
@@ -40,7 +40,7 @@
   // Server which responds without waiting for request body.
   HttpServer.bind().then((server) {
     server.listen((HttpRequest request) {
-      request.response.addString("!dlrow ,olleH");
+      request.response.write("!dlrow ,olleH");
       request.response.close();
     });
 
@@ -51,7 +51,7 @@
         .then((HttpClientRequest request) {
           request.contentLength = -1;
           for (int i = 0; i < outputStreamWrites; i++) {
-            request.addString("Hello, world!");
+            request.write("Hello, world!");
           }
           request.done.catchError((_) {});
           return request.close();
@@ -86,7 +86,7 @@
 
   server.listen((HttpRequest request) {
     request.listen((_) {}, onDone: () {
-      request.response.addString("!dlrow ,olleH");
+      request.response.write("!dlrow ,olleH");
       request.response.close();
     });
   });
@@ -97,7 +97,7 @@
     client.get("127.0.0.1", server.port, "/")
       .then((HttpClientRequest request) {
         request.contentLength = -1;
-        request.addString("Hello, world!");
+        request.write("Hello, world!");
         return request.close();
       })
       .then((HttpClientResponse response) {
@@ -120,7 +120,7 @@
 
   server.listen((var request) {
     request.listen((_) {}, onDone: () {
-      new Timer.repeating(new Duration(milliseconds: 100), (timer) {
+      new Timer.periodic(new Duration(milliseconds: 100), (timer) {
         if (server.connectionsInfo().total == 0) {
           server.close();
           timer.cancel();
@@ -164,7 +164,7 @@
     for (int i = 0; i < totalConnections; i++) {
       client.post("127.0.0.1", server.port, "/")
         .then((request) {
-            request.add([0]);
+            request.writeBytes([0]);
             // TODO(sgjesse): Make this test work with
             //request.response instead of request.close() return
             //return request.response;
@@ -175,7 +175,7 @@
         .catchError((e) { }, test: (e) => e is HttpParserException);
     }
     bool clientClosed = false;
-    new Timer.repeating(new Duration(milliseconds: 100), (timer) {
+    new Timer.periodic(new Duration(milliseconds: 100), (timer) {
       if (!clientClosed) {
         if (server.connectionsInfo().total == totalConnections) {
           clientClosed = true;
diff --git a/tests/standalone/io/http_stream_close_test.dart b/tests/standalone/io/http_stream_close_test.dart
index 6cf73d6..b47209e 100644
--- a/tests/standalone/io/http_stream_close_test.dart
+++ b/tests/standalone/io/http_stream_close_test.dart
@@ -29,7 +29,7 @@
               serverOnClosed = true;
               checkDone();
             });
-            request.response.addString("hello!");
+            request.response.write("hello!");
             request.response.close();
           });
       });
@@ -41,7 +41,7 @@
             clientOnClosed = true;
             checkDone();
           });
-          request.addString("hello!");
+          request.write("hello!");
           return request.close();
         })
         .then((response) {
diff --git a/tests/standalone/io/https_client_certificate_test.dart b/tests/standalone/io/https_client_certificate_test.dart
index 9c519eb..1066c01 100644
--- a/tests/standalone/io/https_client_certificate_test.dart
+++ b/tests/standalone/io/https_client_certificate_test.dart
@@ -21,7 +21,7 @@
     server.listen((HttpRequest request) {
       Expect.isNotNull(request.certificate);
       Expect.equals('CN=localhost', request.certificate.subject);
-      request.response.addString("Hello");
+      request.response.write("Hello");
       request.response.close();
     });
 
diff --git a/tests/standalone/io/link_test.dart b/tests/standalone/io/link_test.dart
new file mode 100644
index 0000000..afcffb8
--- /dev/null
+++ b/tests/standalone/io/link_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:io";
+import "dart:isolate";
+
+// Test the dart:io Link class.
+
+testCreateSync() {
+  Path base = new Path(new Directory('').createTempSync().path);
+  String link = base.append('link').toNativePath();
+  String target = base.append('target').toNativePath();
+  new Directory(target).createSync();
+  new Link(link).createSync(target);
+
+  Expect.equals(FileSystemEntityType.DIRECTORY,
+                FileSystemEntity.typeSync(link));
+  Expect.equals(FileSystemEntityType.DIRECTORY,
+                FileSystemEntity.typeSync(target));
+  Expect.equals(FileSystemEntityType.LINK,
+                FileSystemEntity.typeSync(link, followLinks: false));
+  Expect.equals(FileSystemEntityType.DIRECTORY,
+                FileSystemEntity.typeSync(target, followLinks: false));
+  Expect.isTrue(FileSystemEntity.isLinkSync(link));
+  Expect.isFalse(FileSystemEntity.isLinkSync(target));
+  Expect.isTrue(new Directory(link).existsSync());
+  Expect.isTrue(new Directory(target).existsSync());
+  Expect.isTrue(new Link(link).existsSync());
+  Expect.isFalse(new Link(target).existsSync());
+
+  String createdThroughLink =
+      base.append('link/createdThroughLink').toNativePath();
+  String createdDirectly = base.append('target/createdDirectly').toNativePath();
+  new Directory(createdThroughLink).createSync();
+  new Directory(createdDirectly).createSync();
+  Expect.isTrue(new Directory(createdThroughLink).existsSync());
+  Expect.isTrue(new Directory(createdDirectly).existsSync());
+  Expect.isTrue(new Directory.fromPath(base.append('link/createdDirectly'))
+                .existsSync());
+  Expect.isTrue(new Directory.fromPath(base.append('target/createdThroughLink'))
+                .existsSync());
+  Expect.equals(FileSystemEntityType.DIRECTORY,
+                FileSystemEntity.typeSync(createdThroughLink,
+                                          followLinks: false));
+  Expect.equals(FileSystemEntityType.DIRECTORY,
+                FileSystemEntity.typeSync(createdDirectly, followLinks: false));
+
+  new Directory.fromPath(base).deleteSync(recursive: true);
+}
+
+
+main() {
+  testCreateSync();
+}
diff --git a/tests/standalone/io/mime_multipart_parser_test.dart b/tests/standalone/io/mime_multipart_parser_test.dart
index d9457c7..506a46e 100644
--- a/tests/standalone/io/mime_multipart_parser_test.dart
+++ b/tests/standalone/io/mime_multipart_parser_test.dart
@@ -68,15 +68,13 @@
     if (chunkSize == -1) chunkSize = data.length;
     reset();
     int written = 0;
-    int unparsed;
     for (int pos = 0; pos < data.length; pos += chunkSize) {
       int remaining = data.length - pos;
       int writeLength = min(chunkSize, remaining);
-      written += writeLength;
       int parsed =
-          parser.update(data.getRange(pos, writeLength), 0, writeLength);
-      unparsed = writeLength - parsed;
-      Expect.equals(0, unparsed);
+          parser.update(data.sublist(pos, pos + writeLength), 0, writeLength);
+      Expect.equals(writeLength, parsed);
+      written += writeLength;
     }
     Expect.isTrue(lastPartCalled);
   }
diff --git a/tests/standalone/io/options_test.dart b/tests/standalone/io/options_test.dart
index d326ab4..5963046 100644
--- a/tests/standalone/io/options_test.dart
+++ b/tests/standalone/io/options_test.dart
@@ -5,6 +5,7 @@
 // DartOptions=tests/standalone/io/options_test.dart 10 options_test 20
 
 import "dart:math";
+import "dart:io";
 
 main() {
   var opts = new Options();
diff --git a/tests/standalone/io/path_test.dart b/tests/standalone/io/path_test.dart
index 55c5031..99756cb 100644
--- a/tests/standalone/io/path_test.dart
+++ b/tests/standalone/io/path_test.dart
@@ -9,10 +9,12 @@
 void main() {
   testBaseFunctions();
   testRaw();
+  testToNativePath();
   testCanonicalize();
   testJoinAppend();
   testRelativeTo();
   testWindowsShare();
+  testWindowsDrive();
 }
 
 void testBaseFunctions() {
@@ -114,6 +116,12 @@
   Expect.equals(new Path.raw('\\bar\u2603\n.').toString(), '\\bar\u2603\n.');
 }
 
+void testToNativePath() {
+  Expect.equals('.', new Path('').toNativePath());
+  Expect.equals('.', new Path('.').toNativePath());
+  Expect.equals('.', new Path('a_file').directoryPath.toNativePath());
+}
+
 void testCanonicalize() {
   Function t = (input, canonicalized) {
     Expect.equals(canonicalized, new Path(input).canonicalize().toString());
@@ -301,3 +309,32 @@
   Expect.isTrue(directoryPath.isAbsolute);
   Expect.isTrue(directoryPath.isWindowsShare);
 }
+
+// Test that Windows drive information is handled correctly in relative
+// Path operations.
+void testWindowsDrive() {
+  // Windows drive information only makes sense on Windows.
+  if (Platform.operatingSystem != 'windows') return;
+  // Test that case of drive letters is ignored, and that drive letters
+  // are treated specially.
+  var CPath = new Path(r'C:\a\b\..\c');
+  var cPath = new Path(r'c:\a\b\d');
+  var C2Path = new Path(r'C:\a\b\d');
+  var C3Path = new Path(r'C:\a\b');
+  var C4Path = new Path(r'C:\');
+  var DPath = new Path(r'D:\a\b\d\e');
+  var NoPath = new Path(r'\a\b\c\.');
+
+  Expect.throws(() => CPath.relativeTo(DPath));
+  Expect.throws(() => CPath.relativeTo(NoPath));
+  Expect.throws(() => NoPath.relativeTo(CPath));
+  Expect.equals('../../c', CPath.relativeTo(cPath).toString());
+  Expect.equals('../b/d', cPath.relativeTo(CPath).toString());
+  Expect.equals('.', DPath.relativeTo(DPath).toString());
+  Expect.equals('.', NoPath.relativeTo(NoPath).toString());
+  Expect.equals('.', C2Path.relativeTo(cPath).toString());
+  Expect.equals('..', C3Path.relativeTo(cPath).toString());
+  Expect.equals('d', cPath.relativeTo(C3Path).toString());
+  Expect.equals('a/b/d', cPath.relativeTo(C4Path).toString());
+  Expect.equals('../../../', C4Path.relativeTo(cPath).toString());
+}
diff --git a/tests/standalone/io/pipe_server_test.dart b/tests/standalone/io/pipe_server_test.dart
index 2e7c0ea..6fa9f62 100644
--- a/tests/standalone/io/pipe_server_test.dart
+++ b/tests/standalone/io/pipe_server_test.dart
@@ -53,7 +53,7 @@
 
       fileInput.pipe(_socket).then((_) {
         var tempDir = new Directory('').createTempSync();
-        var dstFileName = tempDir.path.concat("/readline_test1.dat");
+        var dstFileName = tempDir.path + "/readline_test1.dat";
         var dstFile = new File(dstFileName);
         dstFile.createSync();
         var fileOutput = dstFile.openWrite();
diff --git a/tests/standalone/io/process_broken_pipe_test.dart b/tests/standalone/io/process_broken_pipe_test.dart
index 3833158..4db19ac9 100644
--- a/tests/standalone/io/process_broken_pipe_test.dart
+++ b/tests/standalone/io/process_broken_pipe_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 //
@@ -24,7 +24,7 @@
     // Write to the stdin after the process is terminated to test
     // writing to a broken pipe.
     process.exitCode.then((code) {
-      process.stdin.add([0]);
+      process.stdin.writeBytes([0]);
     });
   });
 }
diff --git a/tests/standalone/io/process_check_arguments_script.dart b/tests/standalone/io/process_check_arguments_script.dart
index 6e9c086..de5df11 100644
--- a/tests/standalone/io/process_check_arguments_script.dart
+++ b/tests/standalone/io/process_check_arguments_script.dart
@@ -5,6 +5,7 @@
 // Utility script to check that arguments are correctly passed from
 // one dart process to another using the dart:io process interface.
 import "dart:math";
+import "dart:io";
 
 main() {
   var options = new Options();
diff --git a/tests/standalone/io/process_set_exit_code_script.dart b/tests/standalone/io/process_set_exit_code_script.dart
index f247963..9a34f05 100644
--- a/tests/standalone/io/process_set_exit_code_script.dart
+++ b/tests/standalone/io/process_set_exit_code_script.dart
@@ -1,11 +1,11 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
 import "dart:io";
 
 main() {
-  stdout.addString("standard out");
-  stderr.addString("standard error");
+  stdout.write("standard out");
+  stderr.write("standard error");
   exitCode = 25;
 }
diff --git a/tests/standalone/io/process_std_io_script.dart b/tests/standalone/io/process_std_io_script.dart
index 06ee29a..4ca28f4 100644
--- a/tests/standalone/io/process_std_io_script.dart
+++ b/tests/standalone/io/process_std_io_script.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 //
@@ -15,8 +15,8 @@
       stdin.pipe(stderr);
     } else if (options.arguments[0] == "2") {
       stdin.listen((data) {
-        stdout.add(data);
-        stderr.add(data);
+        stdout.writeBytes(data);
+        stderr.writeBytes(data);
       });
     }
   }
diff --git a/tests/standalone/io/process_std_io_script2.dart b/tests/standalone/io/process_std_io_script2.dart
index 5c0501f..b6ff026 100644
--- a/tests/standalone/io/process_std_io_script2.dart
+++ b/tests/standalone/io/process_std_io_script2.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 //
@@ -9,9 +9,11 @@
 
 writeData(data, encoding, stream) {
   if (stream == "stdout") {
-    stdout.addString(data, encoding);
+    stdout.encoding = encoding;
+    stdout.write(data);
   } else if (stream == "stderr") {
-    stderr.addString(data, encoding);
+    stderr.encoding = encoding;
+    stderr.write(data);
   }
 }
 
diff --git a/tests/standalone/io/process_stderr_test.dart b/tests/standalone/io/process_stderr_test.dart
index b38d1a1..38e47f4 100644
--- a/tests/standalone/io/process_stderr_test.dart
+++ b/tests/standalone/io/process_stderr_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 //
@@ -46,7 +46,7 @@
     }
 
     process.stdout.listen((_) {});
-    process.stdin.add(data);
+    process.stdin.writeBytes(data);
     process.stdin.close();
     process.stderr.listen(readData);
   });
diff --git a/tests/standalone/io/process_stdin_transform_unsubscribe_test.dart b/tests/standalone/io/process_stdin_transform_unsubscribe_test.dart
index fddc35b..23736f7 100644
--- a/tests/standalone/io/process_stdin_transform_unsubscribe_test.dart
+++ b/tests/standalone/io/process_stdin_transform_unsubscribe_test.dart
@@ -23,7 +23,7 @@
 
     process.stdout.listen((_) {});
     process.stderr.listen((_) {});
-    process.stdin.addString("Line1\n");
+    process.stdin.writeln("Line1");
   });
 }
 
diff --git a/tests/standalone/io/process_stdout_test.dart b/tests/standalone/io/process_stdout_test.dart
index 1cba732..15b124d 100644
--- a/tests/standalone/io/process_stdout_test.dart
+++ b/tests/standalone/io/process_stdout_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 //
@@ -46,7 +46,7 @@
     }
 
     process.stderr.listen((_) {});
-    process.stdin.add(data);
+    process.stdin.writeBytes(data);
     process.stdin.close();
     process.stdout.listen(readData);
   });
diff --git a/tests/standalone/io/process_test_util.dart b/tests/standalone/io/process_test_util.dart
index 6abf0c6..f60c239 100644
--- a/tests/standalone/io/process_test_util.dart
+++ b/tests/standalone/io/process_test_util.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -17,6 +17,6 @@
   var executable = new Options().executable;
   var dirIndex = executable.lastIndexOf('dart$extension');
   var buffer = new StringBuffer(executable.substring(0, dirIndex));
-  buffer.add('process_test$extension');
+  buffer.write('process_test$extension');
   return buffer.toString();
 }
diff --git a/tests/standalone/io/process_working_directory_test.dart b/tests/standalone/io/process_working_directory_test.dart
index 1529a13..714d2a4 100644
--- a/tests/standalone/io/process_working_directory_test.dart
+++ b/tests/standalone/io/process_working_directory_test.dart
@@ -42,7 +42,7 @@
     Expect.isTrue(directory.existsSync());
 
     var options = new ProcessOptions();
-    options.workingDirectory = directory.path.concat("/subPath");
+    options.workingDirectory = directory.path + "/subPath";
     var future = Process.start(fullTestFilePath,
                                const ["0", "0", "99", "0"],
                                options);
diff --git a/tests/standalone/io/raw_secure_socket_pause_test.dart b/tests/standalone/io/raw_secure_socket_pause_test.dart
index 0a79475..b5081f5 100644
--- a/tests/standalone/io/raw_secure_socket_pause_test.dart
+++ b/tests/standalone/io/raw_secure_socket_pause_test.dart
@@ -23,7 +23,7 @@
         onDone: () {
           request.response.contentLength = 100;
           for (int i = 0; i < 10; i++) {
-            request.response.add([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
+            request.response.writeBytes([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
           }
           request.response.close();
         });
diff --git a/tests/standalone/io/raw_secure_socket_test.dart b/tests/standalone/io/raw_secure_socket_test.dart
index 1a828ce..7375161 100644
--- a/tests/standalone/io/raw_secure_socket_test.dart
+++ b/tests/standalone/io/raw_secure_socket_test.dart
@@ -23,7 +23,7 @@
         onDone: () {
           request.response.contentLength = 100;
           for (int i = 0; i < 10; i++) {
-            request.response.add([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
+            request.response.writeBytes([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
           }
           request.response.close();
         });
diff --git a/tests/standalone/io/raw_server_socket_cancel_test.dart b/tests/standalone/io/raw_server_socket_cancel_test.dart
index 0062a6e..5f0186e 100644
--- a/tests/standalone/io/raw_server_socket_cancel_test.dart
+++ b/tests/standalone/io/raw_server_socket_cancel_test.dart
@@ -11,62 +11,94 @@
 import "dart:io";
 import "dart:isolate";
 
-void testCancelResubscribeServerSocket() {
-  const int socketCount = 10;
+void testCancelResubscribeServerSocket(int socketCount, int backlog) {
   var acceptCount = 0;
   var doneCount = 0;
   var closeCount = 0;
   var errorCount = 0;
+  var earlyErrorCount = 0;
 
   ReceivePort port = new ReceivePort();
 
-  RawServerSocket.bind().then((server) {
+  RawServerSocket.bind("127.0.0.1", 0, backlog).then((server) {
     Expect.isTrue(server.port > 0);
 
     void checkDone() {
-      if (doneCount == socketCount &&
-          closeCount + errorCount == socketCount) {
+      if (doneCount + earlyErrorCount == socketCount &&
+          closeCount + errorCount + earlyErrorCount == socketCount) {
         port.close();
       }
     }
 
-    // Subscribe the server socket. Then cancel subscription and
-    // subscribe again.
     var subscription;
     subscription = server.listen((client) {
+      client.writeEventsEnabled = false;
+      client.listen((event) {
+        switch(event) {
+          case RawSocketEvent.READ:
+            client.read();
+            break;
+          case RawSocketEvent.READ_CLOSED:
+            client.shutdown(SocketDirection.SEND);
+            break;
+          case RawSocketEvent.WRITE:
+            Expect.fail("No write event expected");
+            break;
+        }
+      });
+
       if (++acceptCount == socketCount / 2) {
+        // Cancel subscription and then attempt to resubscribe.
         subscription.cancel();
         Timer.run(() {
           subscription = server.listen((_) {
-            // Close on cancel, so no more events.
+            // Server socket is closed on cancel, so no more events.
             Expect.fail("Event after closed through cancel");
           });
         });
       }
-      // Close the client socket.
-      client.close();
     });
 
     // Connect a number of sockets.
     for (int i = 0; i < socketCount; i++) {
       RawSocket.connect("127.0.0.1", server.port).then((socket) {
-        socket.writeEventsEnabled = false;
         var subscription;
         subscription = socket.listen((event) {
-          Expect.equals(RawSocketEvent.READ_CLOSED, event);
-          socket.close();
-          closeCount++;
+          switch(event) {
+            case RawSocketEvent.READ:
+              Expect.fail("No read event expected");
+              break;
+            case RawSocketEvent.READ_CLOSED:
+              closeCount++;
+              checkDone();
+              break;
+            case RawSocketEvent.WRITE:
+              // We don't care if this write succeeds, so we don't check
+              // the return value (number of bytes written).
+              socket.write([1,2,3]);
+              socket.shutdown(SocketDirection.SEND);
+              break;
+          }
+        },
+        onDone: () {
+          doneCount++;
           checkDone();
         },
-        onDone: () { doneCount++; checkDone(); },
-        onError: (e) { errorCount++; checkDone(); });
+        onError: (e) {
+          // "Connection reset by peer" errors are handled here.
+          errorCount++;
+          checkDone();
+        });
       }).catchError((e) {
-        errorCount++; checkDone();
+        // "Connection actively refused by host" errors are handled here.
+        earlyErrorCount++;
+        checkDone();
       });
     }
   });
 }
 
 void main() {
-  testCancelResubscribeServerSocket();
+  testCancelResubscribeServerSocket(10, 20);
+  testCancelResubscribeServerSocket(20, 5);
 }
diff --git a/tests/standalone/io/regress_6521_test.dart b/tests/standalone/io/regress_6521_test.dart
index 73eb67a..aa8a964 100644
--- a/tests/standalone/io/regress_6521_test.dart
+++ b/tests/standalone/io/regress_6521_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 //
@@ -22,7 +22,7 @@
             .then((request) {
               // Keep a reference to the client request object.
               clientRequest = request;
-              request.add([0]);
+              request.writeBytes([0]);
               return request.response;
             })
             .then((response) {
diff --git a/tests/standalone/io/regress_7191_test.dart b/tests/standalone/io/regress_7191_test.dart
index fa92538..3d46cfa 100644
--- a/tests/standalone/io/regress_7191_test.dart
+++ b/tests/standalone/io/regress_7191_test.dart
@@ -19,9 +19,9 @@
   var scriptDir = new Path(options.script).directoryPath;
   var script = scriptDir.append('regress_7191_script.dart').toNativePath();
   Process.start(executable, [script]).then((process) {
-    process.stdin.add([0]);
+    process.stdin.writeBytes([0]);
       process.stdout.listen((_) { },
-                            onDone: () { process.stdin.add([0]); });
+                            onDone: () { process.stdin.writeBytes([0]); });
     process.stderr.listen((_) { });
     process.exitCode.then((exitCode) => port.close());
   });
diff --git a/tests/standalone/io/regress_8828_test.dart b/tests/standalone/io/regress_8828_test.dart
index be134ac..258d7a6 100644
--- a/tests/standalone/io/regress_8828_test.dart
+++ b/tests/standalone/io/regress_8828_test.dart
@@ -13,9 +13,9 @@
   HttpServer.bind().then((server) {
     server.listen((request) {
       request.response
-        ..addString("first line\n")
-        ..addString("")
-        ..addString("second line\n")
+        ..writeln("first line")
+        ..write("")
+        ..writeln("second line")
         ..close();
     });
 
diff --git a/tests/standalone/io/secure_client_raw_server_test.dart b/tests/standalone/io/secure_client_raw_server_test.dart
index 3049b23..4bf20c1 100644
--- a/tests/standalone/io/secure_client_raw_server_test.dart
+++ b/tests/standalone/io/secure_client_raw_server_test.dart
@@ -61,7 +61,7 @@
   Completer success = new Completer();
   List<String> chunks = <String>[];
   SecureSocket.connect(HOST_NAME, server.port).then((socket) {
-    socket.add("Hello server.".codeUnits);
+    socket.write("Hello server.");
     socket.close();
     socket.listen(
       (List<int> data) {
diff --git a/tests/standalone/io/secure_client_server_test.dart b/tests/standalone/io/secure_client_server_test.dart
index bd6fe43..f0e44a8 100644
--- a/tests/standalone/io/secure_client_server_test.dart
+++ b/tests/standalone/io/secure_client_server_test.dart
@@ -22,7 +22,7 @@
     server.listen((SecureSocket client) {
       client.reduce(<int>[], (message, data) => message..addAll(data))
           .then((message) {
-            client.add(message);
+            client.writeBytes(message);
             client.close();
           });
     });
@@ -32,7 +32,7 @@
 
 Future testClient(server) {
   return SecureSocket.connect(HOST_NAME, server.port).then((socket) {
-    socket.add("Hello server.".codeUnits);
+    socket.write("Hello server.");
     socket.close();
     return socket.reduce(<int>[], (message, data) => message..addAll(data))
         .then((message) {
diff --git a/tests/standalone/io/secure_multiple_client_server_test.dart b/tests/standalone/io/secure_multiple_client_server_test.dart
index 4b7f370..27527b1 100644
--- a/tests/standalone/io/secure_multiple_client_server_test.dart
+++ b/tests/standalone/io/secure_multiple_client_server_test.dart
@@ -25,7 +25,7 @@
             String received = new String.fromCharCodes(message);
             Expect.isTrue(received.contains("Hello from client "));
             String name = received.substring(received.indexOf("client ") + 7);
-            client.add("Welcome, client $name".codeUnits);
+            client.writeBytes("Welcome, client $name".codeUnits);
             client.close();
           });
     });
@@ -35,7 +35,7 @@
 
 Future testClient(server, name) {
   return SecureSocket.connect(HOST_NAME, server.port).then((socket) {
-    socket.add("Hello from client $name".codeUnits);
+    socket.writeBytes("Hello from client $name".codeUnits);
     socket.close();
     return socket.reduce(<int>[], (message, data) => message..addAll(data))
         .then((message) {
diff --git a/tests/standalone/io/secure_server_socket_test.dart b/tests/standalone/io/secure_server_socket_test.dart
index c66019a..ad5f4d3 100644
--- a/tests/standalone/io/secure_server_socket_test.dart
+++ b/tests/standalone/io/secure_server_socket_test.dart
@@ -170,7 +170,7 @@
           bytesRead += buffer.length;
           if (bytesRead == data.length) {
             verifyTestData(data);
-            client.add(data);
+            client.writeBytes(data);
             client.close();
           }
         },
@@ -184,7 +184,7 @@
       int bytesWritten = 0;
       List<int> dataSent = createTestData();
       List<int> dataReceived = new List<int>(dataSent.length);
-      socket.add(dataSent);
+      socket.writeBytes(dataSent);
       socket.close();  // Can also be delayed.
       socket.listen(
         (List<int> buffer) {
diff --git a/tests/standalone/io/secure_session_resume_test.dart b/tests/standalone/io/secure_session_resume_test.dart
index f862c64..97f0ade 100644
--- a/tests/standalone/io/secure_session_resume_test.dart
+++ b/tests/standalone/io/secure_session_resume_test.dart
@@ -34,7 +34,7 @@
             String received = new String.fromCharCodes(message);
             Expect.isTrue(received.contains("Hello from client "));
             String name = received.substring(received.indexOf("client ") + 7);
-            client.add("Welcome, client $name".codeUnits);
+            client.write("Welcome, client $name");
             client.close();
           });
     });
@@ -44,7 +44,7 @@
 
 Future testClient(server, name) {
   return SecureSocket.connect(HOST_NAME, server.port).then((socket) {
-    socket.add("Hello from client $name".codeUnits);
+    socket.write("Hello from client $name");
     socket.close();
     return socket.reduce(<int>[], (message, data) => message..addAll(data))
         .then((message) {
diff --git a/tests/standalone/io/secure_socket_bad_certificate_test.dart b/tests/standalone/io/secure_socket_bad_certificate_test.dart
index 3f2b320..c2581f8 100644
--- a/tests/standalone/io/secure_socket_bad_certificate_test.dart
+++ b/tests/standalone/io/secure_socket_bad_certificate_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 //
@@ -49,7 +49,7 @@
                               onBadCertificate: badCertificateCallback)
       .then((socket) {
         Expect.isTrue(acceptCertificate);
-        socket.add("GET / HTTP/1.0\r\nHost: $host\r\n\r\n".codeUnits);
+        socket.write("GET / HTTP/1.0\r\nHost: $host\r\n\r\n");
         socket.close();
         return socket.reduce(<int>[], (message, data)  => message..addAll(data))
             .then((message) {
diff --git a/tests/standalone/io/secure_socket_test.dart b/tests/standalone/io/secure_socket_test.dart
index abe27b1..0fe4c55 100644
--- a/tests/standalone/io/secure_socket_test.dart
+++ b/tests/standalone/io/secure_socket_test.dart
@@ -22,7 +22,7 @@
         onDone: () {
           request.response.contentLength = 100;
           for (int i = 0; i < 10; i++) {
-            request.response.add([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
+            request.response.writeBytes([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
           }
           request.response.close();
         });
@@ -43,7 +43,7 @@
   List<int> body = <int>[];
   startServer().then((server) {
     SecureSocket.connect("localhost", server.port).then((socket) {
-      socket.add("GET / HTTP/1.0\r\nHost: localhost\r\n\r\n".codeUnits);
+      socket.write("GET / HTTP/1.0\r\nHost: localhost\r\n\r\n");
       socket.close();
       socket.listen(
         (List<int> data) {
diff --git a/tests/standalone/io/socket_close_test.dart b/tests/standalone/io/socket_close_test.dart
index 4d72f3c..a48f5e8 100644
--- a/tests/standalone/io/socket_close_test.dart
+++ b/tests/standalone/io/socket_close_test.dart
@@ -101,7 +101,7 @@
           onError: (error) => errorHandler(socket));
 
       void writeHello() {
-        socket.add("Hello".codeUnits);
+        socket.write("Hello");
       }
 
       _iterations++;
@@ -224,7 +224,7 @@
     }
 
     void writeHello() {
-      connection.add("Hello".codeUnits);
+      connection.write("Hello");
     }
 
     void dataHandler(bytes) {
diff --git a/tests/standalone/io/socket_exception_test.dart b/tests/standalone/io/socket_exception_test.dart
index f2fec68..3b83564 100644
--- a/tests/standalone/io/socket_exception_test.dart
+++ b/tests/standalone/io/socket_exception_test.dart
@@ -88,7 +88,7 @@
         Expect.isFalse(wrongExceptionCaught);
         try {
           List<int> buffer = new List<int>(10);
-          client.add(buffer);
+          client.writeBytes(buffer);
         } on StateError catch (ex) {
           exceptionCaught = true;
         } catch (ex) {
@@ -121,7 +121,7 @@
       });
       Socket.connect("127.0.0.1", server.port).then((client) {
         client.listen((data) {}, onDone: server.close);
-        client.add(new List.filled(1024 * 1024, 0));
+        client.writeBytes(new List.filled(1024 * 1024, 0));
         client.destroy();
       });
     });
@@ -143,7 +143,7 @@
               Expect.equals(SIZE, count);
               server.close();
             });
-        client.add(new List.filled(SIZE, 0));
+        client.writeBytes(new List.filled(SIZE, 0));
         client.close();
         // Start piping now.
         completer.complete(null);
@@ -174,7 +174,7 @@
               Expect.isTrue(errors <= 1);
               server.close();
             });
-        client.add(new List.filled(SIZE, 0));
+        client.writeBytes(new List.filled(SIZE, 0));
         // Destroy other socket now.
         completer.complete(null);
         var port = new ReceivePort();
@@ -199,7 +199,7 @@
       Socket.connect("127.0.0.1", server.port).then((client) {
         const int SIZE = 1024 * 1024;
         int errors = 0;
-        client.add(new List.filled(SIZE, 0));
+        client.writeBytes(new List.filled(SIZE, 0));
         client.close();
         client.done.catchError((error) {
           server.close();
diff --git a/tests/standalone/io/socket_invalid_arguments_test.dart b/tests/standalone/io/socket_invalid_arguments_test.dart
index 7505aaa..b0378a6 100644
--- a/tests/standalone/io/socket_invalid_arguments_test.dart
+++ b/tests/standalone/io/socket_invalid_arguments_test.dart
@@ -39,7 +39,7 @@
             socket.destroy();
             server.close();
           });
-      socket.add(buffer);
+      socket.writeBytes(buffer);
     });
   });
 }
diff --git a/tests/standalone/io/socket_test.dart b/tests/standalone/io/socket_test.dart
index 6ce7a75..8e757c8 100644
--- a/tests/standalone/io/socket_test.dart
+++ b/tests/standalone/io/socket_test.dart
@@ -113,7 +113,7 @@
   ServerSocket.bind().then((server) {
     server.listen((_) { });
     Socket.connect("127.0.0.1", server.port).then((socket) {
-      socket.add([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
+      socket.writeBytes([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
       socket.close();
       socket.done.then((_) {
         socket.destroy();
@@ -155,7 +155,7 @@
   ServerSocket.bind().then((server) {
     server.listen(
         (client) {
-          client.add(sendData);
+          client.writeBytes(sendData);
           if (useDestroy) {
             client.destroy();
           } else {
@@ -171,7 +171,7 @@
                         Expect.isFalse(onDoneCalled);
                         onDoneCalled = true;
                         if (!useDestroy) Expect.listEquals(sendData, data);
-                        socket.add([0]);
+                        socket.writeBytes([0]);
                         socket.close();
                         server.close();
                         port.close();
@@ -186,7 +186,7 @@
   ServerSocket.bind().then((server) {
     server.listen(
         (client) {
-          client.add(sendData);
+          client.writeBytes(sendData);
           if (useDestroy) {
             client.destroy();
           } else {
diff --git a/tests/standalone/io/status_file_parser_test.dart b/tests/standalone/io/status_file_parser_test.dart
index 3769682..aaf9604 100644
--- a/tests/standalone/io/status_file_parser_test.dart
+++ b/tests/standalone/io/status_file_parser_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -37,7 +37,7 @@
   File file = new File(fixedFilePath(filePath));
   if (file.existsSync()) {
     List<Section> sections = new List<Section>();
-    ReadConfigurationInto(file.name, sections, () {
+    ReadConfigurationInto(file.path, sections, () {
       Expect.isTrue(sections.length > 0);
     });
   }
diff --git a/tests/standalone/io/stdout_bad_argument_test.dart b/tests/standalone/io/stdout_bad_argument_test.dart
index 95ce44d..481691f 100644
--- a/tests/standalone/io/stdout_bad_argument_test.dart
+++ b/tests/standalone/io/stdout_bad_argument_test.dart
@@ -1,11 +1,11 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
 import "dart:io";
 
 main() {
-  stdout.add("Hello\n");
+  stdout.writeBytes("Hello\n");
   stdout.done.catchError((e) {
     exit(0);
   });
diff --git a/tests/standalone/io/stdout_stderr_test.dart b/tests/standalone/io/stdout_stderr_test.dart
new file mode 100644
index 0000000..8929ea8
--- /dev/null
+++ b/tests/standalone/io/stdout_stderr_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+import "dart:io";
+
+callIOSink(IOSink sink) {
+  // Call all methods on IOSink.
+  sink.encoding = Encoding.ASCII;
+  Expect.equals(Encoding.ASCII, sink.encoding);
+  sink.write("Hello\n");
+  sink.writeln("Hello");
+  sink.writeAll(["H", "e", "l", "lo\n"]);
+  sink.writeCharCode(72);
+  sink.writeBytes([101, 108, 108, 111, 10]);
+
+  var controller = new StreamController();
+  sink.writeStream(controller.stream);
+  controller.add([72, 101, 108]);
+  controller.add([108, 111, 10]);
+  controller.close();
+
+  controller = new StreamController();
+  controller.stream.pipe(sink);
+  controller.add([72, 101, 108]);
+  controller.add([108, 111, 10]);
+  controller.close();
+}
+
+main() {
+  callIOSink(stdout);
+  stdout.done.then((_) {
+    callIOSink(stderr);
+    stderr.done.then((_) {
+      stdout.close();
+      stderr.close();
+    });
+  });
+}
diff --git a/tests/standalone/io/stream_pipe_test.dart b/tests/standalone/io/stream_pipe_test.dart
index 46590fa..4e77cdf 100644
--- a/tests/standalone/io/stream_pipe_test.dart
+++ b/tests/standalone/io/stream_pipe_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 //
@@ -68,7 +68,7 @@
   var srcStream = new File(srcFileName).openRead();
 
   var tempDir = new Directory('').createTempSync();
-  String dstFileName = tempDir.path.concat("/readline_test1.dat");
+  String dstFileName = tempDir.path + "/readline_test1.dat";
   new File(dstFileName).createSync();
   var output = new File(dstFileName).openWrite();
   srcStream.pipe(output).then((_) {
@@ -95,12 +95,12 @@
   var srcStream = srcFile.openRead();
 
   var tempDir = new Directory('').createTempSync();
-  var dstFileName = tempDir.path.concat("/readline_test1.dat");
+  var dstFileName = tempDir.path + "/readline_test1.dat";
   var dstFile = new File(dstFileName);
   dstFile.createSync();
   var output = dstFile.openWrite();
-  output.addStream(srcStream).then((_) {
-    output.add([32]);
+  output.writeStream(srcStream).then((_) {
+    output.writeBytes([32]);
     output.close();
     output.done.then((_) {
       var src = srcFile.openSync();
@@ -138,13 +138,13 @@
   var srcStream = srcFile.openRead();
 
   var tempDir = new Directory('').createTempSync();
-  var dstFileName = tempDir.path.concat("/readline_test1.dat");
+  var dstFileName = tempDir.path + "/readline_test1.dat";
   var dstFile = new File(dstFileName);
   dstFile.createSync();
   var output = dstFile.openWrite();
-  output.addStream(srcStream).then((_) {
+  output.writeStream(srcStream).then((_) {
     var srcStream2 = srcFile.openRead();
-    output.addStream(srcStream2).then((_) {
+    output.writeStream(srcStream2).then((_) {
       output.close();
       output.done.then((_) {
         var src = srcFile.openSync();
diff --git a/tests/standalone/io/string_decoder_test.dart b/tests/standalone/io/string_decoder_test.dart
index 4952676..5833fd4 100644
--- a/tests/standalone/io/string_decoder_test.dart
+++ b/tests/standalone/io/string_decoder_test.dart
@@ -20,7 +20,7 @@
   stream.reduce(
       new StringBuffer(),
       (b, e) {
-        b.add(e);
+        b.write(e);
         return b;
       })
       .then((b) => b.toString())
diff --git a/tests/standalone/io/string_transformer_test.dart b/tests/standalone/io/string_transformer_test.dart
index 2a9015e..d65fb33 100644
--- a/tests/standalone/io/string_transformer_test.dart
+++ b/tests/standalone/io/string_transformer_test.dart
@@ -200,7 +200,7 @@
         errors++;
         Expect.isTrue(e.error is TestException);
       });
-  controller.signalError(new TestException());
+  controller.addError(new TestException());
   controller.close();
 }
 
diff --git a/tests/standalone/io/test_runner_exit_code_script.dart b/tests/standalone/io/test_runner_exit_code_script.dart
index 7e2542d..1cfe603 100644
--- a/tests/standalone/io/test_runner_exit_code_script.dart
+++ b/tests/standalone/io/test_runner_exit_code_script.dart
@@ -4,6 +4,7 @@
 
 // Simulates a use of test_progress during a failing run of test.dart.
 
+import "dart:io";
 import "../../../tools/testing/dart/test_progress.dart";
 import "../../../tools/testing/dart/test_runner.dart";
 import "../../../tools/testing/dart/test_options.dart";
diff --git a/tests/standalone/io/test_runner_exit_code_test.dart b/tests/standalone/io/test_runner_exit_code_test.dart
deleted file mode 100644
index c398b92a..0000000
--- a/tests/standalone/io/test_runner_exit_code_test.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:io";
-
-void runTests(String executable, String script, Iterator iterator) {
-  if (iterator.moveNext()) {
-    var progressIndicator = iterator.current;
-    Process.run(executable, [script, progressIndicator]).then((result) {
-      Expect.equals(1, result.exitCode);
-      if (progressIndicator == 'buildbot') {
-        Expect.isTrue(result.stdout.contains("@@@STEP_FAILURE@@@"));
-      }
-      runTests(executable, script, iterator);
-    });
-  }
-}
-
-main() {
-  var scriptPath = new Path(new Options().script);
-  var scriptDirPath = scriptPath.directoryPath;
-  var exitCodeScriptPath =
-    scriptDirPath.append('test_runner_exit_code_script.dart');
-  var script = exitCodeScriptPath.toNativePath();
-  var executable = new Options().executable;
-  var progressTypes = ['compact', 'color', 'line', 'verbose',
-                       'status', 'buildbot'];
-  var iterator = progressTypes.iterator;
-  runTests(executable, script, iterator);
-}
diff --git a/tests/standalone/io/test_runner_test.dart b/tests/standalone/io/test_runner_test.dart
index ebf61a8..b9ad2c6 100644
--- a/tests/standalone/io/test_runner_test.dart
+++ b/tests/standalone/io/test_runner_test.dart
@@ -1,7 +1,8 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import "dart:io";
 import "dart:isolate";
 import "dart:async";
 import "dart:utf";
@@ -72,8 +73,8 @@
     var crashCommand = new Command(getProcessTestFileName(),
                                    ["0", "0", "1", "1"]);
     // The crash test sometimes times out. Run it with a large timeout
-    // to help diagnose the delay. 
-    // The test loads a new executable, which may sometimes take a long time. 
+    // to help diagnose the delay.
+    // The test loads a new executable, which may sometimes take a long time.
     // It involves a wait on the VM event loop, and possible system
     // delays.
     return _makeTestCase(name, LONG_TIMEOUT, crashCommand, expectations);
@@ -93,8 +94,8 @@
 void testProcessQueue() {
   var maxProcesses = 2;
   var maxBrowserProcesses = maxProcesses;
-  new ProcessQueue(maxProcesses, maxBrowserProcesses, "silent",
-      new Date.now(), false, [new CustomTestSuite()], TestController.finished);
+  new ProcessQueue(maxProcesses, maxBrowserProcesses,
+      new DateTime.now(), [new CustomTestSuite()], [], TestController.finished);
 }
 
 void main() {
diff --git a/tests/standalone/io/web_socket_protocol_processor_test.dart b/tests/standalone/io/web_socket_protocol_processor_test.dart
index 9c891d6..1490e71 100644
--- a/tests/standalone/io/web_socket_protocol_processor_test.dart
+++ b/tests/standalone/io/web_socket_protocol_processor_test.dart
@@ -2,11 +2,16 @@
 // 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:utf";
 import "dart:math";
 import "dart:async";
+import "dart:collection";
+import "dart:scalarlist";
 
 part "../../../sdk/lib/io/http.dart";
+part "../../../sdk/lib/io/buffer_list.dart";
 part "../../../sdk/lib/io/io_sink.dart";
+part "../../../sdk/lib/io/string_transformer.dart";
 part "../../../sdk/lib/io/websocket.dart";
 part "../../../sdk/lib/io/websocket_impl.dart";
 
@@ -14,33 +19,32 @@
   WebSocketFrame(int opcode, List<int> data);
 }
 
-// Class that when hooked up to the web socket protocol processor will
+// Class that when hooked up to the web socket protocol transformer will
 // collect the message and expect it to be equal to the
 // expectedMessage field when fully received.
 class WebSocketMessageCollector {
-  WebSocketMessageCollector(_WebSocketProtocolProcessor this.processor,
+  List<int> expectedMessage;
+
+  int messageCount = 0;
+  int closeCount = 0;
+
+  var data;
+
+  WebSocketMessageCollector(Stream stream,
                             [List<int> this.expectedMessage = null]) {
-    processor.onMessageStart = onMessageStart;
-    processor.onMessageData = onMessageData;
-    processor.onMessageEnd = onMessageEnd;
-    processor.onClosed = onClosed;
+    stream.listen(onMessageData, onDone: onClosed, onError: onError);
   }
 
-  void onMessageStart(int type) {
-    data = new List<int>();
-  }
-
-  void onMessageData(List<int> buffer, int index, int count) {
-    data.addAll(buffer.getRange(index, count));
-  }
-
-  void onMessageEnd() {
+  void onMessageData(buffer) {
+    if (buffer is String) {
+      buffer = _encodeString(buffer);
+    }
+    Expect.listEquals(expectedMessage, buffer);
     messageCount++;
-    Expect.listEquals(expectedMessage, data);
-    data = null;
+    data = buffer;
   }
 
-  void onClosed(int status, String reason) {
+  void onClosed() {
     closeCount++;
   }
 
@@ -48,12 +52,6 @@
     Expect.fail("Unexpected error $e");
   }
 
-  _WebSocketProtocolProcessor processor;
-  List<int> expectedMessage;
-
-  List<int> data;
-  int messageCount = 0;
-  int closeCount = 0;
 }
 
 
@@ -97,48 +95,56 @@
 
 // Test processing messages which are sent in a single frame.
 void testFullMessages() {
-  // Use the same web socket protocol processor for all frames.
-  _WebSocketProtocolProcessor processor = new _WebSocketProtocolProcessor();
-  WebSocketMessageCollector mc = new WebSocketMessageCollector(processor);
-
-  int messageCount = 0;
-
   void testMessage(int opcode, List<int> message) {
-    mc.expectedMessage = message;
+    int messageCount = 0;
+    // Use the same web socket protocol transformer for all frames.
+    var transformer = new _WebSocketProtocolTransformer();
+    var controller = new StreamController();
+    WebSocketMessageCollector mc = new WebSocketMessageCollector(
+        controller.stream.transform(transformer),
+        message);
+
     List<int> frame = createFrame(
         true, opcode, null, message, 0, message.length);
 
-    // Update the processor with one big chunk.
+    // Update the transformer with one big chunk.
     messageCount++;
-    processor.update(frame, 0, frame.length);
-    Expect.isNull(mc.data);
-    Expect.equals(0, processor._state);
+    controller.add(frame);
+    Expect.isNotNull(mc.data);
+    Expect.equals(0, transformer._state);
+
+    mc.data = null;
 
     // Only run this part on small messages.
     if (message.length < 1000) {
-      // Update the processor one byte at the time.
+      // Update the transformer one byte at the time.
       messageCount++;
       for (int i = 0; i < frame.length; i++) {
-        processor.update(frame, i, 1);
+        controller.add(<int>[frame[i]]);
       }
-      Expect.equals(0, processor._state);
-      Expect.isNull(mc.data);
+      Expect.equals(0, transformer._state);
+      Expect.isNotNull(mc.data);
+      mc.data = null;
 
-      // Update the processor two bytes at the time.
+      // Update the transformer two bytes at the time.
       messageCount++;
       for (int i = 0; i < frame.length; i += 2) {
-        processor.update(frame, i, i + 1 < frame.length ? 2 : 1);
+        controller.add(frame.sublist(i, min(i + 2, frame.length)));
       }
-      Expect.equals(0, processor._state);
-      Expect.isNull(mc.data);
+      Expect.equals(0, transformer._state);
+      Expect.isNotNull(mc.data);
     }
+    Expect.equals(messageCount, mc.messageCount);
+    Expect.equals(0, mc.closeCount);
+    print("Messages test, messages $messageCount");
   }
 
   void runTest(int from, int to, int step) {
     for (int messageLength = from; messageLength < to; messageLength += step) {
       List<int> message = new List<int>(messageLength);
-      for (int i = 0; i < messageLength; i++) message[i] = i & 0xFF;
+      for (int i = 0; i < messageLength; i++) message[i] = i & 0x7F;
       testMessage(FRAME_OPCODE_TEXT, message);
+      for (int i = 0; i < messageLength; i++) message[i] = i & 0xFF;
       testMessage(FRAME_OPCODE_BINARY, message);
     }
   }
@@ -148,17 +154,16 @@
   runTest(120, 130, 1);
   runTest(0, 1000, 100);
   runTest(65534, 65537, 1);
-  print("Messages test, messages $messageCount");
-  Expect.equals(messageCount, mc.messageCount);
-  Expect.equals(0, mc.closeCount);
 }
 
 
 // Test processing of frames which are split into fragments.
 void testFragmentedMessages() {
-  // Use the same web socket protocol processor for all frames.
-  _WebSocketProtocolProcessor processor = new _WebSocketProtocolProcessor();
-  WebSocketMessageCollector mc = new WebSocketMessageCollector(processor);
+  // Use the same web socket protocol transformer for all frames.
+  var transformer = new _WebSocketProtocolTransformer();
+  var controller = new StreamController();
+  WebSocketMessageCollector mc = new WebSocketMessageCollector(
+      controller.stream.transform(transformer));
 
   int messageCount = 0;
   int frameCount = 0;
@@ -180,7 +185,7 @@
                                     payloadSize);
       frameCount++;
       messageIndex += payloadSize;
-      processor.update(frame, 0, frame.length);
+      controller.add(frame);
       remaining -= payloadSize;
       firstFrame = false;
     }
@@ -203,8 +208,9 @@
   void runTest(int from, int to, int step) {
     for (int messageLength = from; messageLength < to; messageLength += step) {
       List<int> message = new List<int>(messageLength);
-      for (int i = 0; i < messageLength; i++) message[i] = i & 0xFF;
+      for (int i = 0; i < messageLength; i++) message[i] = i & 0x7F;
       testMessageFragmentation(FRAME_OPCODE_TEXT, message);
+      for (int i = 0; i < messageLength; i++) message[i] = i & 0xFF;
       testMessageFragmentation(FRAME_OPCODE_BINARY, message);
     }
   }
diff --git a/tests/standalone/io/web_socket_test.dart b/tests/standalone/io/web_socket_test.dart
index 937467a..94cd01d 100644
--- a/tests/standalone/io/web_socket_test.dart
+++ b/tests/standalone/io/web_socket_test.dart
@@ -10,7 +10,7 @@
 import "dart:async";
 import "dart:io";
 import "dart:isolate";
-import "dart:scalarlist";
+import "dart:typeddata";
 import "dart:uri";
 
 const String CERT_NAME = 'localhost_cert';
@@ -121,9 +121,10 @@
                 onDone: () {
                   Expect.equals(closeStatus == null
                                 ? WebSocketStatus.NO_STATUS_RECEIVED
-                                : closeStatus, event.code);
-                  Expect.equals(
-                      closeReason == null ? "" : closeReason, event.reason);
+                                : closeStatus, webSocket.closeCode);
+                  Expect.equals(closeReason == null
+                                ? ""
+                                : closeReason, webSocket.closeReason);
                 });
             });
       }
@@ -185,6 +186,43 @@
   }
 
 
+  void testImmediateCloseServer() {
+    createServer().then((server) {
+      server.listen((request) {
+        WebSocketTransformer.upgrade(request)
+            .then((webSocket) {
+              webSocket.close();
+              webSocket.listen((_) { Expect.fail(); }, onDone: server.close);
+            });
+      });
+
+      createClient(server.port).then((webSocket) {
+          webSocket.listen((_) { Expect.fail(); }, onDone: webSocket.close);
+        });
+    });
+  }
+
+
+  void testImmediateCloseClient() {
+    createServer().then((server) {
+      server.listen((request) {
+        WebSocketTransformer.upgrade(request)
+            .then((webSocket) {
+              webSocket.listen((_) { Expect.fail(); }, onDone: () {
+                server.close();
+                webSocket.close();
+              });
+            });
+      });
+
+      createClient(server.port).then((webSocket) {
+          webSocket.close();
+          webSocket.listen((_) { Expect.fail(); }, onDone: webSocket.close);
+        });
+    });
+  }
+
+
   void testNoUpgrade() {
     createServer().then((server) {
       // Create a server which always responds with NOT_FOUND.
@@ -274,9 +312,8 @@
                 Expect.equals(10, onmessageCalled);
                 Expect.isFalse(oncloseCalled);
                 oncloseCalled = true;
-                Expect.isTrue(event.wasClean);
-                Expect.equals(3002, event.code);
-                Expect.equals("Got tired", event.reason);
+                Expect.equals(3002, webSocket.closeCode);
+                Expect.equals("Got tired", webSocket.closeReason);
                 Expect.equals(WebSocket.CLOSED, webSocket.readyState);
               });
         });
@@ -349,6 +386,8 @@
     testMessageLength(65536);
     testDoubleCloseClient();
     testDoubleCloseServer();
+    testImmediateCloseServer();
+    testImmediateCloseClient();
     testNoUpgrade();
     testUsePOST();
     testConnections(10, 3002, "Got tired");
diff --git a/tests/standalone/io/windows_file_system_links_test.dart b/tests/standalone/io/windows_file_system_links_test.dart
new file mode 100644
index 0000000..a458a5f
--- /dev/null
+++ b/tests/standalone/io/windows_file_system_links_test.dart
@@ -0,0 +1,79 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:io";
+import "dart:isolate";
+
+testJunctionTypeDelete() {
+  var temp = new Directory('').createTempSync();
+  var x = '${temp.path}${Platform.pathSeparator}x';
+  var y = '${temp.path}${Platform.pathSeparator}y';
+
+  new Directory(x).createSync();
+  new Link(y).create(x).then((_) {
+    Expect.isTrue(new Directory(y).existsSync());
+    Expect.isTrue(new Directory(x).existsSync());
+    Expect.isTrue(FileSystemEntity.isLinkSync(y));
+    Expect.isFalse(FileSystemEntity.isLinkSync(x));
+    Expect.isTrue(FileSystemEntity.isDirectorySync(y));
+    Expect.isTrue(FileSystemEntity.isDirectorySync(x));
+    Expect.equals(FileSystemEntityType.DIRECTORY,
+                  FileSystemEntity.typeSync(y));
+    Expect.equals(FileSystemEntityType.DIRECTORY,
+                  FileSystemEntity.typeSync(x));
+    Expect.equals(FileSystemEntityType.LINK,
+                  FileSystemEntity.typeSync(y, followLinks: false));
+    Expect.equals(FileSystemEntityType.DIRECTORY,
+                  FileSystemEntity.typeSync(x, followLinks: false));
+    // Test Junction pointing to a missing directory.
+    new Directory(x).deleteSync();
+    Expect.isTrue(new Directory(y).existsSync());
+    Expect.isFalse(new Directory(x).existsSync());
+    Expect.isTrue(FileSystemEntity.isLinkSync(y));
+    Expect.isFalse(FileSystemEntity.isLinkSync(x));
+    Expect.isFalse(FileSystemEntity.isDirectorySync(y));
+    Expect.isFalse(FileSystemEntity.isDirectorySync(x));
+    Expect.equals(FileSystemEntityType.NOT_FOUND,
+                  FileSystemEntity.typeSync(y));
+    Expect.equals(FileSystemEntityType.NOT_FOUND,
+                  FileSystemEntity.typeSync(x));
+    Expect.equals(FileSystemEntityType.LINK,
+                  FileSystemEntity.typeSync(y, followLinks: false));
+    Expect.equals(FileSystemEntityType.NOT_FOUND,
+                  FileSystemEntity.typeSync(x, followLinks: false));
+
+    // Delete Junction pointing to a missing directory.
+    new Directory(y).deleteSync();
+    Expect.isFalse(FileSystemEntity.isLinkSync(y));
+    Expect.equals(FileSystemEntityType.NOT_FOUND,
+                  FileSystemEntity.typeSync(y));
+
+    new Directory(x).createSync();
+    new Link(y).create(x).then((_) {
+      Expect.equals(FileSystemEntityType.LINK,
+                    FileSystemEntity.typeSync(y, followLinks: false));
+      Expect.equals(FileSystemEntityType.DIRECTORY,
+                    FileSystemEntity.typeSync(x, followLinks: false));
+
+      // Delete Junction pointing to an existing directory.
+      new Directory(y).deleteSync();
+      Expect.equals(FileSystemEntityType.NOT_FOUND,
+                    FileSystemEntity.typeSync(y));
+      Expect.equals(FileSystemEntityType.NOT_FOUND,
+                    FileSystemEntity.typeSync(y, followLinks: false));
+      Expect.equals(FileSystemEntityType.DIRECTORY,
+                    FileSystemEntity.typeSync(x));
+      Expect.equals(FileSystemEntityType.DIRECTORY,
+                    FileSystemEntity.typeSync(x, followLinks: false));
+      temp.deleteSync(recursive: true);
+    });
+  });
+}
+
+
+main() {
+  if (Platform.operatingSystem == 'windows') {
+    testJunctionTypeDelete();
+  }
+}
diff --git a/tests/standalone/io/zlib_test.dart b/tests/standalone/io/zlib_test.dart
new file mode 100644
index 0000000..87626f1
--- /dev/null
+++ b/tests/standalone/io/zlib_test.dart
@@ -0,0 +1,145 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+import 'dart:isolate';
+
+void testZLibDeflate() {
+  test(int level, List<int> expected) {
+    var port = new ReceivePort();
+    var data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+    var controller = new StreamController();
+    controller.stream.transform(new ZLibDeflater(gzip: false, level: level))
+        .reduce([], (buffer, data) {
+          buffer.addAll(data);
+          return buffer;
+        })
+        .then((data) {
+          Expect.listEquals(expected, data);
+          port.close();
+        });
+    controller.add(data);
+    controller.close();
+  }
+  test(0, [120, 1, 0, 10, 0, 245, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0,
+           255, 255]);
+  test(1, [120, 1, 98, 96, 100, 98, 102, 97, 101, 99, 231, 224, 4, 0, 0, 0,
+           255, 255]);
+  test(2, [120, 94, 98, 96, 100, 98, 102, 97, 101, 99, 231, 224, 4, 0, 0, 0,
+           255, 255]);
+  test(3, [120, 94, 98, 96, 100, 98, 102, 97, 101, 99, 231, 224, 4, 0, 0, 0,
+           255, 255]);
+  test(4, [120, 94, 98, 96, 100, 98, 102, 97, 101, 99, 231, 224, 4, 0, 0, 0,
+           255, 255]);
+  test(5, [120, 94, 98, 96, 100, 98, 102, 97, 101, 99, 231, 224, 4, 0, 0, 0,
+           255, 255]);
+  test(6, [120, 156, 98, 96, 100, 98, 102, 97, 101, 99, 231, 224, 4, 0, 0, 0,
+           255, 255]);
+  test(-1, [120, 156, 98, 96, 100, 98, 102, 97, 101, 99, 231, 224, 4, 0, 0, 0,
+            255, 255]);
+  test(7, [120, 218, 98, 96, 100, 98, 102, 97, 101, 99, 231, 224, 4, 0, 0, 0,
+           255, 255]);
+  test(8, [120, 218, 98, 96, 100, 98, 102, 97, 101, 99, 231, 224, 4, 0, 0, 0,
+           255, 255]);
+  test(9, [120, 218, 98, 96, 100, 98, 102, 97, 101, 99, 231, 224, 4, 0, 0, 0,
+           255, 255]);
+}
+
+
+void testZLibDeflateEmpty() {
+  var port = new ReceivePort();
+  var controller = new StreamController();
+  controller.stream.transform(new ZLibDeflater(gzip: false, level: 6))
+      .reduce([], (buffer, data) {
+        buffer.addAll(data);
+        return buffer;
+      })
+      .then((data) {
+        print(data);
+        Expect.listEquals([120, 156, 2, 0, 0, 0, 255, 255], data);
+        port.close();
+      });
+  controller.close();
+}
+
+
+void testZLibDeflateGZip() {
+  var port = new ReceivePort();
+  var data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+  var controller = new StreamController();
+  controller.stream.transform(new ZLibDeflater())
+      .reduce([], (buffer, data) {
+        buffer.addAll(data);
+        return buffer;
+      })
+      .then((data) {
+        Expect.equals(26, data.length);
+        Expect.listEquals([98, 96, 100, 98, 102, 97, 101, 99, 231, 224, 4, 0, 0,
+                           0, 255, 255],
+                          // Skip header, as it can change.
+                          data.sublist(10));
+        port.close();
+      });
+  controller.add(data);
+  controller.close();
+}
+
+void testZLibDeflateInvalidLevel() {
+  test2(gzip, level) {
+    var port = new ReceivePort();
+    try {
+      new ZLibDeflater(gzip: gzip, level: level);
+    } catch (e) {
+      port.close();
+    }
+  }
+  test(level) {
+    test2(false, level);
+    test2(true, level);
+    test2(9, level);
+  }
+  test(-2);
+  test(-20);
+  test(10);
+  test(42);
+  test(null);
+  test("9");
+}
+
+void testZLibInflate() {
+  test2(bool gzip, int level) {
+    var port = new ReceivePort();
+    var data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+    var controller = new StreamController();
+    controller.stream
+      .transform(new ZLibDeflater(gzip: gzip, level: level))
+      .transform(new ZLibInflater())
+        .reduce([], (buffer, data) {
+          buffer.addAll(data);
+          return buffer;
+        })
+        .then((inflated) {
+          Expect.listEquals(data, inflated);
+          port.close();
+        });
+    controller.add(data);
+    controller.close();
+  }
+  void test(int level) {
+    test2(false, level);
+    test2(true, level);
+  }
+  for (int i = -1; i < 10; i++) {
+    test(i);
+  }
+}
+
+void main() {
+  testZLibDeflate();
+  testZLibDeflateEmpty();
+  testZLibDeflateGZip();
+  testZLibDeflateInvalidLevel();
+  testZLibInflate();
+}
diff --git a/tests/standalone/package/packages/lib1.dart b/tests/standalone/package/packages/lib1.dart
index 9cee8e9..18d0bf8 100644
--- a/tests/standalone/package/packages/lib1.dart
+++ b/tests/standalone/package/packages/lib1.dart
@@ -8,6 +8,6 @@
 #import('package:lib2/lib2.dart');
 
 void lib1() {
-  output = output.concat('|lib1');
+  output += '|lib1';
   lib2();
 }
diff --git a/tests/standalone/package/packages/lib2/lib2.dart b/tests/standalone/package/packages/lib2/lib2.dart
index 21ae129..017d8ae 100644
--- a/tests/standalone/package/packages/lib2/lib2.dart
+++ b/tests/standalone/package/packages/lib2/lib2.dart
@@ -8,6 +8,6 @@
 #import('package:lib3/sub/lib3.dart');
 
 void lib2() {
-  output = output.concat('|lib2');
+  output += '|lib2';
   lib3();
 }
diff --git a/tests/standalone/package/packages/lib3/sub/lib3.dart b/tests/standalone/package/packages/lib3/sub/lib3.dart
index 7b6be0f..91a40a0 100644
--- a/tests/standalone/package/packages/lib3/sub/lib3.dart
+++ b/tests/standalone/package/packages/lib3/sub/lib3.dart
@@ -7,5 +7,5 @@
 #import('package:shared.dart');
 
 void lib3() {
-  output = output.concat('|lib3');
+  output += '|lib3';
 }
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index de4b7a4..963802f 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -4,20 +4,13 @@
 
 package/invalid_uri_test: Fail, OK # Fails intentionally
 
-[ $runtime == vm ]
-# Temporarily disabled until the test scripts are rewritten for
-# dart:io v2.
-io/skipping_dart2js_compilations_test: skip # Non-fatal process error.
-io/status_file_parser_test: fail
-io/test_runner_exit_code_test: fail
-io/test_runner_test: fail
-
 [ $runtime == vm && ( $system == windows ) ]
-io/raw_server_socket_cancel_test: Pass, Fail, Timeout # Issue 8675
 io/raw_socket_test: Pass, Fail # Issue 8901
+io/http_shutdown_test: Pass, Fail # Issue  9101
 
 [ $runtime == vm ]
 package/package_isolate_test: Fail # http://dartbug.com/7520.
+io/raw_server_socket_cancel_test: Pass, Fail, Timeout # Issue 8675
 
 # Fails with a connection refused error on the buildbot.
 # Issue 8232.
@@ -88,9 +81,13 @@
 
 [ $compiler == dart2js ]
 number_identity_test: Skip # Bigints and int/double diff. not supported.
+typed_data_test: Skip # This is a VM test
+typed_data_view_test: Skip # This is a VM test
 typed_array_test: Skip # This is a VM test
 float_array_test: Skip # This is a VM test
 int_array_test: Skip  # This is a VM test
+byte_array_view_optimized_test: Skip # This is a VM test
+io/web_socket_protocol_processor_test: Skip  # Importing code with external keyword
 int_array_load_elimination_test: Skip  # This is a VM test
 medium_integer_test: Fail, OK # Test fails with JS number semantics: issue 1533.
 io/process_exit_negative_test: Fail, OK # relies on a static error that is a warning now.
diff --git a/tests/standalone/typed_array_test.dart b/tests/standalone/typed_array_test.dart
index ac4d57f..4532ee1 100644
--- a/tests/standalone/typed_array_test.dart
+++ b/tests/standalone/typed_array_test.dart
@@ -7,7 +7,7 @@
 // Library tag to be able to run in html test framework.
 library TypedArray;
 import 'dart:isolate';
-import 'dart:scalarlist';
+import 'dart:typeddata';
 
 void main() {
   int8_receiver();
@@ -285,7 +285,7 @@
   float32[1] = 2.0;
   return float32;
 }
-Float32List float32 = new Float32List(2);
+Float32List float32 = initFloat32();
 
 void float32_receiver() {
   var sp = spawnFunction(float32_sender);
diff --git a/tests/standalone/typed_data_test.dart b/tests/standalone/typed_data_test.dart
new file mode 100644
index 0000000..9b31a2a
--- /dev/null
+++ b/tests/standalone/typed_data_test.dart
@@ -0,0 +1,339 @@
+// 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.
+//
+// Dart test program for testing typed data.
+
+// Library tag to be able to run in html test framework.
+library TypedDataTest;
+
+import 'dart:typeddata';
+
+void testCreateUint8TypedData() {
+  Uint8List typed_data;
+
+  typed_data = new Uint8List(0);
+  Expect.isTrue(typed_data is Uint8List);
+  Expect.isFalse(typed_data is Uint8ClampedList);
+  Expect.equals(0, typed_data.length);
+
+  typed_data = new Uint8List(10);
+  Expect.equals(10, typed_data.length);
+  for (int i = 0; i < 10; i++) {
+    Expect.equals(0, typed_data[i]);
+  }
+}
+
+void testCreateClampedUint8TypedData() {
+  Uint8ClampedList typed_data;
+
+  typed_data = new Uint8ClampedList(0);
+  Expect.isTrue(typed_data is Uint8ClampedList);
+  Expect.isFalse(typed_data is Uint8List);
+  Expect.equals(0, typed_data.length);
+  Expect.equals(0, typed_data.lengthInBytes);
+
+  typed_data = new Uint8ClampedList(10);
+  Expect.equals(10, typed_data.length);
+  for (int i = 0; i < 10; i++) {
+    Expect.equals(0, typed_data[i]);
+  }
+}
+
+void testCreateExternalClampedUint8TypedData() {
+  List typed_data;
+
+  typed_data = new Uint8ClampedList.transferable(0);
+  Expect.isTrue(typed_data is Uint8ClampedList);
+  Expect.isFalse(typed_data is Uint8List);
+  Expect.equals(0, typed_data.length);
+  Expect.equals(0, typed_data.lengthInBytes);
+
+  typed_data = new Uint8ClampedList.transferable(10);
+  Expect.equals(10, typed_data.length);
+  for (int i = 0; i < 10; i++) {
+    Expect.equals(0, typed_data[i]);
+  }
+
+  typed_data[0] = -1;
+  Expect.equals(0, typed_data[0]);
+
+  for (int i = 0; i < 10; i++) {
+    typed_data[i] = i + 250;
+  }
+  for (int i = 0; i < 10; i++) {
+    Expect.equals(i + 250 > 255 ? 255 : i + 250, typed_data[i]);
+  }
+}
+
+void testTypedDataRange(bool check_throws) {
+  Int8List typed_data;
+  typed_data = new Int8List(10);
+  typed_data[1] = 0;
+  Expect.equals(0, typed_data[1]);
+  typed_data[2] = -128;
+  Expect.equals(-128, typed_data[2]);
+  typed_data[3] = 127;
+  Expect.equals(127, typed_data[3]);
+  // This should eventually throw.
+  typed_data[0] = 128;
+  typed_data[4] = -129;
+  if (check_throws) {
+    Expect.throws(() {
+      typed_data[1] = 1.2;
+    });
+  }
+}
+
+void testUnsignedTypedDataRange(bool check_throws) {
+  Uint8List typed_data;
+  typed_data = new Uint8List(10);
+
+  typed_data[1] = 255;
+  Expect.equals(255, typed_data[1]);
+  typed_data[1] = 0;
+  Expect.equals(0, typed_data[1]);
+
+  for (int i = 0; i < typed_data.length; i++) {
+    typed_data[i] = i;
+  }
+  for (int i = 0; i < typed_data.length; i++) {
+    Expect.equals(i, typed_data[i]);
+  }
+
+  // These should eventually throw.
+  typed_data[1] = 256;
+  typed_data[1] = -1;
+  typed_data[2] = -129;
+  if (check_throws) {
+    Expect.throws(() {
+      typed_data[1] = 1.2;
+    });
+  }
+}
+
+void testClampedUnsignedTypedDataRangeHelper(Uint8ClampedList typed_data,
+                                             bool check_throws) {
+  Uint8ClampedList typed_data;
+  typed_data = new Uint8ClampedList(10);
+
+  typed_data[1] = 255;
+  Expect.equals(255, typed_data[1]);
+  typed_data[1] = 0;
+  Expect.equals(0, typed_data[1]);
+  for (int i = 0; i < typed_data.length; i++) {
+    typed_data[i] = i;
+  }
+  for (int i = 0; i < typed_data.length; i++) {
+    Expect.equals(i, typed_data[i]);
+  }
+
+  // These should eventually throw.
+  typed_data[1] = 256;
+  typed_data[2] = -129;
+  Expect.equals(255, typed_data[1]);
+  Expect.equals(0, typed_data[2]);
+}
+
+void testClampedUnsignedTypedDataRange(bool check_throws) {
+  testClampedUnsignedTypedDataRangeHelper(new Uint8ClampedList(10),
+                                          check_throws);
+}
+
+void testExternalClampedUnsignedTypedDataRange(bool check_throws) {
+  testClampedUnsignedTypedDataRangeHelper(new Uint8ClampedList.transferable(10),
+                                          check_throws);
+}
+
+void testSetRangeHelper(typed_data) {
+  List<int> list = [10, 11, 12];
+  typed_data.setRange(0, 3, list);
+  for (int i = 0; i < 3; i++) {
+    Expect.equals(10 + i, typed_data[i]);
+  }
+
+  typed_data[0] = 20;
+  typed_data[1] = 21;
+  typed_data[2] = 22;
+  list.setRange(0, 3, typed_data);
+  for (int i = 0; i < 3; i++) {
+    Expect.equals(20 + i, list[i]);
+  }
+
+  typed_data.setRange(1, 2, const [8, 9]);
+  Expect.equals(20, typed_data[0]);
+  Expect.equals(8, typed_data[1]);
+  Expect.equals(9, typed_data[2]);
+}
+
+void testSetRange() {
+  testSetRangeHelper(new Uint8List(3));
+  testSetRangeHelper(new Uint8List.transferable(3));
+  testSetRangeHelper(new Uint8ClampedList(3));
+  testSetRangeHelper(new Uint8ClampedList.transferable(3));
+}
+
+void testIndexOutOfRangeHelper(typed_data) {
+  List<int> list = const [0, 1, 2, 3];
+
+  Expect.throws(() {
+    typed_data.setRange(0, 4, list);
+  });
+
+  Expect.throws(() {
+    typed_data.setRange(3, 1, list);
+  });
+}
+
+void testIndexOutOfRange() {
+  testIndexOutOfRangeHelper(new Uint8List(3));
+  testIndexOutOfRangeHelper(new Uint8List.transferable(3));
+  testIndexOutOfRangeHelper(new Uint8ClampedList(3));
+  testIndexOutOfRangeHelper(new Uint8ClampedList.transferable(3));
+}
+
+void testIndexOfHelper(list) {
+  for (int i = 0; i < list.length; i++) {
+    list[i] = i + 10;
+  }
+  Expect.equals(0, list.indexOf(10));
+  Expect.equals(5, list.indexOf(15));
+  Expect.equals(9, list.indexOf(19));
+  Expect.equals(-1, list.indexOf(20));
+
+  list = new Float32List(10);
+  for (int i = 0; i < list.length; i++) {
+    list[i] = i + 10.0;
+  }
+  Expect.equals(0, list.indexOf(10.0));
+  Expect.equals(5, list.indexOf(15.0));
+  Expect.equals(9, list.indexOf(19.0));
+  Expect.equals(-1, list.indexOf(20.0));
+}
+
+void testIndexOf() {
+  testIndexOfHelper(new Uint8List.transferable(10));
+  testIndexOfHelper(new Uint8ClampedList(10));
+  testIndexOfHelper(new Uint8ClampedList.transferable(10));
+}
+
+void testGetAtIndex(TypedData list, num initial_value) {
+  var bdata = new ByteData.view(list);
+  for (int i = 0; i < bdata.lengthInBytes; i++) {
+    Expect.equals(42, bdata.getUint8(i));
+    Expect.equals(42, bdata.getInt8(i));
+  }
+  for (int i = 0; i < bdata.lengthInBytes-1; i+=2) {
+    Expect.equals(10794, bdata.getUint16(i));
+    Expect.equals(10794, bdata.getInt16(i));
+  }
+  for (int i = 0; i < bdata.lengthInBytes-3; i+=4) {
+    Expect.equals(707406378, bdata.getUint32(i));
+    Expect.equals(707406378, bdata.getInt32(i));
+    Expect.equals(1.511366173271439e-13, bdata.getFloat32(i));
+  }
+  for (int i = 0; i < bdata.lengthInBytes-7; i+=8) {
+    Expect.equals(3038287259199220266, bdata.getUint64(i));
+    Expect.equals(3038287259199220266, bdata.getInt64(i));
+    Expect.equals(1.4260258159703532e-105, bdata.getFloat64(i));
+  }
+}
+
+void testSetAtIndex(TypedData list,
+                    num initial_value, [bool use_double = false]) {
+  void validate([reinit = true]) {
+    for (int i = 0; i < list.length; i++) {
+      Expect.equals(initial_value, list[i]);
+      if (reinit) list[i] = use_double? 0.0 : 0;
+    }
+  }
+  var bdata = new ByteData.view(list);
+  for (int i = 0; i < bdata.lengthInBytes; i++) bdata.setUint8(i, 42);
+  validate();
+  for (int i = 0; i < bdata.lengthInBytes; i++) bdata.setInt8(i, 42);
+  validate();
+  for (int i = 0; i < bdata.lengthInBytes-1; i+=2) bdata.setUint16(i, 10794);
+  validate();
+  for (int i = 0; i < bdata.lengthInBytes-1; i+=2) bdata.setInt16(i, 10794);
+  validate();
+  for (int i = 0; i < bdata.lengthInBytes-3; i+=4)
+    bdata.setUint32(i, 707406378);
+  validate();
+  for (int i = 0; i < bdata.lengthInBytes-3; i+=4) bdata.setInt32(i, 707406378);
+  validate();
+  for (int i = 0; i < bdata.lengthInBytes-3; i+=4) {
+    bdata.setFloat32(i, 1.511366173271439e-13);
+  }
+  validate();
+  for (int i = 0; i < bdata.lengthInBytes-7; i+=8) {
+    bdata.setUint64(i, 3038287259199220266);
+  }
+  validate();
+  for (int i = 0; i < bdata.lengthInBytes-7; i+=8) {
+    bdata.setInt64(i, 3038287259199220266);
+  }
+  validate();
+  for (int i = 0; i < bdata.lengthInBytes-7; i+=8) {
+    bdata.setFloat64(i, 1.4260258159703532e-105);
+  }
+  validate(false);
+}
+
+main() {
+  for (int i = 0; i < 2000; i++) {
+    testCreateUint8TypedData();
+    testCreateClampedUint8TypedData();
+    testCreateExternalClampedUint8TypedData();
+    testTypedDataRange(false);
+    testUnsignedTypedDataRange(false);
+    testClampedUnsignedTypedDataRange(false);
+    testExternalClampedUnsignedTypedDataRange(false);
+    testSetRange();
+    testIndexOutOfRange();
+    testIndexOf();
+
+    var int8list = new Int8List(128);
+    testSetAtIndex(int8list, 42);
+    testGetAtIndex(int8list, 42);
+
+    var uint8list = new Uint8List(128);
+    testSetAtIndex(uint8list, 42);
+    testGetAtIndex(uint8list, 42);
+
+    var int16list = new Int16List(64);
+    testSetAtIndex(int16list, 10794);
+    testGetAtIndex(int16list, 10794);
+
+    var uint16list = new Uint16List(64);
+    testSetAtIndex(uint16list, 10794);
+    testGetAtIndex(uint16list, 10794);
+
+    var int32list = new Int32List(32);
+    testSetAtIndex(int32list, 707406378);
+    testGetAtIndex(int32list, 707406378);
+
+    var uint32list = new Uint32List(32);
+    testSetAtIndex(uint32list, 707406378);
+    testGetAtIndex(uint32list, 707406378);
+
+    var int64list = new Int64List(16);
+    testSetAtIndex(int64list, 3038287259199220266);
+    testGetAtIndex(int64list, 3038287259199220266);
+
+    var uint64list = new Uint64List(16);
+    testSetAtIndex(uint64list, 3038287259199220266);
+    testGetAtIndex(uint64list, 3038287259199220266);
+
+    var float32list = new Float32List(32);
+    testSetAtIndex(float32list, 1.511366173271439e-13, true);
+    testGetAtIndex(float32list, 1.511366173271439e-13);
+
+    var float64list = new Float64List(16);
+    testSetAtIndex(float64list, 1.4260258159703532e-105, true);
+    testGetAtIndex(float64list, 1.4260258159703532e-105);
+  }
+  testTypedDataRange(true);
+  testUnsignedTypedDataRange(true);
+  testExternalClampedUnsignedTypedDataRange(true);
+}
+
diff --git a/tests/standalone/typed_data_view_test.dart b/tests/standalone/typed_data_view_test.dart
new file mode 100644
index 0000000..4608923
--- /dev/null
+++ b/tests/standalone/typed_data_view_test.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.
+//
+// Dart test program for testing typed data.
+
+// Library tag to be able to run in html test framework.
+library TypedDataTest;
+
+import 'dart:typeddata';
+
+validate(TypedData list, num expected) {
+  for (int i = 0; i < list.length; i++) {
+    Expect.equals(expected, list[i]);
+  }
+}
+
+main() {
+  var list = new Int8List(128);
+  for (var i = 0; i < list.length; i++) {
+    list[i] = 42;
+  }
+  var ba = list.buffer;
+
+  var slist = new Int16List.view(ba, 0, 32);
+  validate(slist, 10794);
+  var uslist = new Uint16List.view(ba, 0, 32);
+  validate(uslist, 10794);
+
+  var ilist = new Int32List.view(ba, 0, 16);
+  validate(ilist, 707406378);
+  var uilist = new Uint32List.view(ba, 0, 16);
+  validate(uilist, 707406378);
+
+  var llist = new Int64List.view(ba, 0, 8);
+  validate(llist, 3038287259199220266);
+  var ullist = new Uint64List.view(ba, 0, 8);
+  validate(ullist, 3038287259199220266);
+
+  var flist = new Float32List.view(ba, 0, 16);
+  validate(flist, 1.511366173271439e-13);
+  var dlist = new Float64List.view(ba, 0, 8);
+  validate(dlist, 1.4260258159703532e-105);
+}
diff --git a/tests/utils/dummy_compiler_test.dart b/tests/utils/dummy_compiler_test.dart
index c888b73..14ac5bb 100644
--- a/tests/utils/dummy_compiler_test.dart
+++ b/tests/utils/dummy_compiler_test.dart
@@ -45,6 +45,8 @@
                     var removeLast;
                     var add;
                   }
+                  class JSFixedArray {}
+                  class JSExtendableArray {}
                   class JSString {
                     var length;
                     var split;
@@ -59,7 +61,8 @@
                   class JSBool {}
                   var getInterceptor;""";
     } else if (uri.path.endsWith('js_helper.dart')) {
-      source = 'library jshelper; class JSInvocationMirror {}';
+      source = 'library jshelper; class JSInvocationMirror {} '
+               'class ConstantMap {} class TypeImpl {}';
     } else if (uri.path.endsWith('isolate_helper.dart')) {
       source = 'library isolatehelper; class _WorkerStub {}';
     } else {
diff --git a/tests/utils/utils.status b/tests/utils/utils.status
index 8119908..4d6e186 100644
--- a/tests/utils/utils.status
+++ b/tests/utils/utils.status
@@ -11,9 +11,6 @@
 recursive_import_test: Fail # http://dartbug.com/2264
 dart2js_test: Fail # http://dartbug.com/2264
 
-[ $compiler == dartc ]
-dart2js_test: Fail # http://dartbug.com/8802
-
 [ $compiler == dart2js && $browser ]
 *: Skip
 
diff --git a/tools/VERSION b/tools/VERSION
index 0419e66..dbdcb67 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
 MAJOR 0
 MINOR 4
-BUILD 1
+BUILD 2
 PATCH 0
diff --git a/tools/bots/compiler.py b/tools/bots/compiler.py
index 45636c7..ff1eb33 100644
--- a/tools/bots/compiler.py
+++ b/tools/bots/compiler.py
@@ -212,25 +212,15 @@
     # that run the browser tests to cut down on the cycle time.
     TestStep("dart2js_unit", mode, system, 'none', 'vm', ['dart2js'], flags)
 
-  if not (system.startswith('win') and runtime.startswith('ie')):
+  if system.startswith('win') and runtime.startswith('ie10'):
+    TestStep("dart2js", mode, system, 'dart2js', runtime, ['html'], flags)
+  else:
     # Run the default set of test suites.
     TestStep("dart2js", mode, system, 'dart2js', runtime, [], flags)
 
     # TODO(kasperl): Consider running peg and css tests too.
     extras = ['dart2js_extra', 'dart2js_native', 'dart2js_foreign']
     TestStep("dart2js_extra", mode, system, 'dart2js', runtime, extras, flags)
-  else:
-    # TODO(ricow): Enable standard sharding for IE bots when we have more vms.
-    if test_set == 'html':
-      TestStep("dart2js", mode, system, 'dart2js', runtime, ['html'], flags)
-    elif test_set == 'all':
-      TestStep("dart2js", mode, system, 'dart2js', runtime, ['dartc',
-          'samples', 'standalone', 'corelib', 'co19', 'language', 'isolate',
-          'vm', 'json', 'benchmark_smoke', 'dartdoc', 'utils', 'pub', 'lib'],
-          flags)
-      extras = ['dart2js_extra', 'dart2js_native', 'dart2js_foreign']
-      TestStep("dart2js_extra", mode, system, 'dart2js', runtime, extras,
-               flags)
 
 
 def _DeleteTempWebdriverProfiles(directory):
diff --git a/tools/build.py b/tools/build.py
index b60579c..d2bf1bc 100755
--- a/tools/build.py
+++ b/tools/build.py
@@ -59,7 +59,7 @@
 
 def ProcessOptions(options, args):
   if options.arch == 'all':
-    options.arch = 'ia32,x64'
+    options.arch = 'ia32,x64,simarm,simmips'
   if options.mode == 'all':
     options.mode = 'release,debug'
   if options.os == 'all':
diff --git a/tools/create_sdk.py b/tools/create_sdk.py
index e24902a..5843aa5 100755
--- a/tools/create_sdk.py
+++ b/tools/create_sdk.py
@@ -37,6 +37,7 @@
 # ......uri/
 # ......utf/
 # ......scalarlist/
+# ......typeddata/
 # ....pkg/
 # ......args/
 # ......intl/
@@ -205,7 +206,7 @@
                   join('html', 'dart2js'), join('html', 'dartium'),
                   join('html', 'html_common'),
                   join('indexed_db', 'dart2js'), join('indexed_db', 'dartium'),
-                  'json', 'math', 'mirrors', 'scalarlist',
+                  'json', 'math', 'mirrors', 'scalarlist', 'typeddata',
                   join('svg', 'dart2js'), join('svg', 'dartium'),
                   'uri', 'utf',
                   join('web_audio', 'dart2js'), join('web_audio', 'dartium'),
@@ -277,9 +278,14 @@
   # Fix up dartdoc.
   # TODO(dgrove): Remove this once issue 6619 is fixed.
   ReplaceInFiles([join(SDK_tmp, 'lib', '_internal', 'dartdoc',
-                       'bin', 'dartdoc.dart')],
-                 [("../../../../../pkg/args/lib/args.dart",
-                   "../../../../pkg/args/lib/args.dart")])
+                       'bin', 'dartdoc.dart'),
+                  join(SDK_tmp, 'lib', '_internal', 'dartdoc',
+                       'lib', 'universe_serializer.dart')], [
+                  ("../../../../../pkg/args/lib/args.dart",
+                   "../../../../pkg/args/lib/args.dart"),
+                  ("../../../../../pkg/pathos/lib/path.dart",
+                   "../../../../pkg/pathos/lib/path.dart"),
+                 ])
 
   # Write the 'version' file
   versionFile = open(os.path.join(SDK_tmp, 'version'), 'w')
diff --git a/tools/ddbg.dart b/tools/ddbg.dart
index 2295ae8..c92174c 100644
--- a/tools/ddbg.dart
+++ b/tools/ddbg.dart
@@ -69,7 +69,7 @@
   if (verbose) {
     print("sending: '${json.stringify(cmd)}'");
   }
-  vmSock.addString(json.stringify(cmd));
+  vmSock.write(json.stringify(cmd));
   return completer.future;
 }
 
@@ -454,7 +454,7 @@
   if (vmData == null || vmData.length == 0) {
     vmData = data;
   } else {
-    vmData = vmData.concat(data);
+    vmData = vmData + data;
   }
   int msg_len = jsonObjectLength(vmData);
   if (printMessages && msg_len == 0) {
diff --git a/tools/dom/docs/docs.json b/tools/dom/docs/docs.json
index 936da3b..084eca4 100644
--- a/tools/dom/docs/docs.json
+++ b/tools/dom/docs/docs.json
@@ -109,9 +109,6 @@
         "getCSSCanvasContext": [
           "/// Moved to [HtmlDocument]."
         ],
-        "getElementById": [
-          "/// Deprecated: use query(\"#$elementId\") instead."
-        ],
         "head": [
           "/// Moved to [HtmlDocument]."
         ],
@@ -119,7 +116,21 @@
           "/// Moved to [HtmlDocument]."
         ],
         "querySelector": [
-          "/// Deprecated: renamed to the shorter name [query]."
+          "/**",
+          " * Finds the first descendant element of this document that matches the",
+          " * specified group of selectors.",
+          " *",
+          " * Unless your webpage contains multiple documents, the top-level query",
+          " * method behaves the same as this method, so you should use it instead to",
+          " * save typing a few characters.",
+          " *",
+          " * [selectors] should be a string using CSS selector syntax.",
+          " *     var element1 = document.query('.className');",
+          " *     var element2 = document.query('#id');",
+          " *",
+          " * For details about CSS selector syntax, see the",
+          " * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).",
+          " */"
         ],
         "querySelectorAll": [
           "/// Deprecated: use query(\"#$elementId\") instead."
@@ -159,6 +170,29 @@
         ]
       }
     },
+    "Element": {
+      "members": {
+        "querySelector": [
+          "/**",
+          " * Finds the first descendant element of this element that matches the",
+          " * specified group of selectors.",
+          " *",
+          " * [selectors] should be a string using CSS selector syntax.",
+          " *",
+          " *     // Gets the first descendant with the class 'classname'",
+          " *     var element = element.query('.className');",
+          " *     // Gets the element with id 'id'",
+          " *     var element = element.query('#id');",
+          " *     // Gets the first descendant [ImageElement]",
+          " *     var img = element.query('img');",
+          " *",
+          " * See also:",
+          " *",
+          " * * [CSS Selectors](http://docs.webplatform.org/wiki/css/selectors)",
+          " */"
+        ]
+      }
+    },
     "HTMLAreaElement": {
       "comment": [
         "/**",
@@ -549,4 +583,4 @@
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/tools/dom/dom.py b/tools/dom/dom.py
new file mode 100755
index 0000000..e45d820
--- /dev/null
+++ b/tools/dom/dom.py
@@ -0,0 +1,188 @@
+#!/usr/bin/python
+
+# 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.
+
+# A script which makes it easy to execute common DOM-related tasks
+
+import os
+import subprocess
+import sys
+
+sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
+import utils
+
+dart_out_dir = utils.GetBuildRoot(utils.GuessOS(), 'release', 'ia32')
+if utils.IsWindows():
+  dart_bin = os.path.join(dart_out_dir, 'dart.exe')
+else:
+  dart_bin = os.path.join(dart_out_dir, 'dart')
+
+def help():
+  print('Helper script to make it easy to perform common tasks encountered '
+     'during the life of a Dart DOM developer.\n'
+     '\n'
+     'For example, to re-generate DOM classes then run a specific test:\n'
+     '  dom.py gen test_drt html/element_test\n'
+     '\n'
+     'Or re-generate DOM classes and run the Dart analyzer:\n'
+     '  dom.py gen analyze\n')
+  print('Commands: ')
+  for cmd in sorted(commands.keys()):
+    print('\t%s - %s' % (cmd, commands[cmd][1]))
+
+def analyze():
+  ''' Runs the dart analyzer. '''
+  call([
+    os.path.join(dart_out_dir, 'dart-sdk', 'bin', 'dart_analyzer'),
+    os.path.join('tests', 'html', 'element_test.dart'),
+    '--dart-sdk', 'sdk',
+    '--show-sdk-warnings',
+  ])
+
+def build():
+  ''' Builds the Dart binary '''
+  call([
+    os.path.join('tools', 'build.py'),
+    '--mode=release',
+    '--arch=ia32',
+    'runtime',
+  ])
+
+def dart2js():
+  compile_dart2js(argv.pop(0), True)
+
+def dartc():
+  call([
+    os.path.join('tools', 'test.py'),
+    '-m',
+    'release',
+    '-c',
+    'dartc',
+    '-r',
+    'none'
+  ])
+
+def compile_dart2js(dart_file, checked):
+  out_file = dart_file + '.js'
+  dart2js_path = os.path.join(dart_out_dir, 'dart-sdk', 'bin', 'dart2js')
+  args = [
+    dart2js_path,
+    dart_file,
+    '--library-root=sdk/',
+    '--disallow-unsafe-eval',
+    '-o%s' % out_file
+  ]
+  if checked:
+    args.append('--checked')
+
+  call(args)
+  return out_file
+
+def gen():
+  os.chdir(os.path.join('tools', 'dom', 'scripts'))
+  call([
+    'go.sh',
+  ])
+
+def http_server():
+  print('Browse tests at '
+      '\033[94mhttp://localhost:5400/root_build/generated_tests/\033[0m')
+  call([
+    utils.DartBinary(),
+    os.path.join('tools', 'testing', 'dart', 'http_server.dart'),
+    '--port=5400',
+    '--crossOriginPort=5401',
+    '--network=0.0.0.0',
+    '--build-directory=%s' % os.path.join('out', 'ReleaseIA32')
+  ])
+
+def size_check():
+  ''' Displays the dart2js size of swarm. '''
+  dart_file = os.path.join('samples', 'swarm', 'swarm.dart')
+  out_file = compile_dart2js(dart_file, False)
+
+  subprocess.call([
+    'du',
+    '-kh',
+    '--apparent-size',
+    out_file,
+  ])
+
+  os.remove(out_file)
+  os.remove(out_file + '.deps')
+  os.remove(out_file + '.map')
+
+def test_ff():
+  test_dart2js('ff', argv)
+
+def test_drt():
+  test_dart2js('drt', argv)
+
+def test_chrome():
+  test_dart2js('chrome', argv)
+
+def test_dart2js(browser, argv):
+  cmd = [
+    os.path.join('tools', 'test.py'),
+    '-c', 'dart2js',
+    '-r', browser,
+    '--mode=release',
+    '--checked',
+    '--arch=ia32',
+    '-v',
+  ]
+  if argv:
+    cmd.append(argv.pop(0))
+  else:
+    print(
+        'Test commands should be followed by tests to run. Defaulting to html')
+    cmd.append('html')
+  call(cmd)
+
+def call(args):
+  print (' '.join(args))
+  subprocess.call(args)
+
+def init_dir():
+  ''' Makes sure that we're always rooted in the dart root folder.'''
+  dart_dir = os.path.abspath(os.path.join(
+      os.path.dirname(os.path.realpath(__file__)),
+      os.path.pardir, os.path.pardir))
+  os.chdir(dart_dir)
+
+commands = {
+  'analyze': [analyze, 'Run the dart analyzer'],
+  'build': [build, 'Build dart in release mode'],
+  'dart2js': [dart2js, 'Run dart2js on the .dart file specified'],
+  'dartc': [dartc, 'Runs dartc in release mode'],
+  'gen': [gen, 'Re-generate DOM generated files (run go.sh)'],
+  'size_check': [size_check, 'Check the size of dart2js compiled Swarm'],
+  'test_chrome': [test_chrome, 'Run tests in checked mode in Chrome.\n'
+      '\t\tOptionally provide name of test to run.'],
+  'test_drt': [test_drt, 'Run tests in checked mode in DumpRenderTree.\n'
+      '\t\tOptionally provide name of test to run.'],
+  'test_ff': [test_ff, 'Run tests in checked mode in Firefox.\n'
+      '\t\tOptionally provide name of test to run.'],
+  'http_server': [http_server, 'Starts the testing server for manually '
+      'running browser tests.'],
+}
+
+def main(argv):
+  argv.pop(0)
+
+  if not argv:
+    help()
+
+  while (argv):
+    init_dir()
+    command = argv.pop(0)
+
+    if not command in commands:
+      help();
+      return
+    commands[command][0]()
+
+if __name__ == '__main__':
+  main(sys.argv)
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index 20f6905..c84c6e6 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -61,6 +61,10 @@
   'DataView.setUint8',
   'DirectoryEntry.getDirectory',
   'DirectoryEntry.getFile',
+  'Entry.copyTo',
+  'Entry.moveTo',
+  'HTMLInputElement.setRangeText',
+  'XMLHttpRequest.open',
   ])
 
 #
@@ -136,6 +140,12 @@
         self.name, self.type_id, self.is_optional)
     return '<ParamInfo(%s)>' % content
 
+def GetCallbackInfo(interface):
+  """For the given interface, find operations that take callbacks (for use in
+  auto-transforming callbacks into futures)."""
+  callback_handlers = [operation for operation in interface.operations
+      if operation.id == 'handleEvent']
+  return AnalyzeOperation(interface, callback_handlers)
 
 # Given a list of overloaded arguments, render dart arguments.
 def _BuildArguments(args, interface, constructor=False):
@@ -212,8 +222,25 @@
   info.param_infos = _BuildArguments([op.arguments for op in split_operations], interface)
   full_name = '%s.%s' % (interface.id, info.declared_name)
   info.requires_named_arguments = full_name in _methods_with_named_formals
+  # The arguments in that the original operation took as callbacks (for
+  # conversion to futures).
+  info.callback_args = []
   return info
 
+def ConvertToFuture(info):
+  """Given an OperationInfo object, convert the operation's signature so that it
+  instead uses futures instead of callbacks."""
+  new_info = copy.deepcopy(info)
+  def IsNotCallbackType(param):
+    return 'Callback' not in param.type_id
+  # Success callback is the first argument (change if this no longer holds).
+  new_info.callback_args = filter(
+      lambda x: not IsNotCallbackType(x), new_info.param_infos)
+  new_info.param_infos = filter(IsNotCallbackType, new_info.param_infos)
+  new_info.type_name = 'Future'
+
+  return new_info
+
 
 def AnalyzeConstructor(interface):
   """Returns an OperationInfo object for the constructor.
@@ -341,15 +368,19 @@
           right_bracket)
     return ', '.join(argtexts)
 
-  def ParametersAsArgumentList(self, parameter_count = None):
+  def ParametersAsArgumentList(self, parameter_count=None):
     """Returns a string of the parameter names suitable for passing the
     parameters as arguments.
     """
+    def param_name(param_info):
+      if self.requires_named_arguments and param_info.is_optional:
+        return '%s : %s' % (param_info.name, param_info.name)
+      else:
+        return param_info.name
+
     if parameter_count is None:
       parameter_count = len(self.param_infos)
-    return ', '.join(map(
-        lambda param_info: param_info.name,
-        self.param_infos[:parameter_count]))
+    return ', '.join(map(param_name, self.param_infos[:parameter_count]))
 
   def IsStatic(self):
     is_static = self.overloads[0].is_static
@@ -360,6 +391,13 @@
     if self.constructor_name:
       return rename_type(self.type_name) + '.' + self.constructor_name
     else:
+      # TODO(antonm): temporary ugly hack.
+      # While in transition phase we allow both DOM's ArrayBuffer
+      # and dart:typeddata's ByteBuffer for IDLs' ArrayBuffers,
+      # hence ArrayBuffer is mapped to dynamic in arguments and return
+      # values.  To compensate for that when generating ArrayBuffer itself,
+      # we need to lie a bit:
+      if self.type_name == 'ArrayBuffer': return 'ArrayBuffer'
       return rename_type(self.type_name)
 
 def ConstantOutputOrder(a, b):
@@ -515,6 +553,16 @@
 
 dart2js_annotations = monitored.Dict('generator.dart2js_annotations', {
 
+    'ArrayBuffer': [
+      "@Creates('ArrayBuffer')",
+      "@Returns('ArrayBuffer|Null')",
+    ],
+
+    'ArrayBufferView': [
+      "@Creates('ArrayBufferView')",
+      "@Returns('ArrayBufferView|Null')",
+    ],
+
     'CanvasRenderingContext2D.createImageData': [
       "@Creates('ImageData|=Object')",
     ],
@@ -573,7 +621,6 @@
       "@Returns('Element|Document')",
     ],
 
-
     'FileReader.result': ["@Creates('String|ArrayBuffer|Null')"],
 
     # Rather than have the result of an IDBRequest as a union over all possible
@@ -692,6 +739,11 @@
   "@Experimental",
 ]
 
+_shadow_dom_annotations = [
+  "@SupportedBrowser(SupportedBrowser.CHROME, '26')",
+  "@Experimental",
+]
+
 _speech_recognition_annotations = [
   "@SupportedBrowser(SupportedBrowser.CHROME, '25')",
   "@Experimental",
@@ -724,6 +776,7 @@
 dart_annotations = monitored.Dict('generator.dart_annotations', {
   'ArrayBuffer': _all_but_ie9_annotations,
   'ArrayBufferView': _all_but_ie9_annotations,
+  'CSSHostRule': _shadow_dom_annotations,
   'Crypto': _webkit_experimental_annotations,
   'Database': _web_sql_annotations,
   'DatabaseSync': _web_sql_annotations,
@@ -760,10 +813,7 @@
   ],
   'History.pushState': _history_annotations,
   'History.replaceState': _history_annotations,
-  'HTMLContentElement': [
-    "@SupportedBrowser(SupportedBrowser.CHROME, '25')",
-    "@Experimental",
-  ],
+  'HTMLContentElement': _shadow_dom_annotations,
   'HTMLDataListElement': _all_but_ie9_annotations,
   'HTMLDetailsElement': _webkit_experimental_annotations,
   'HTMLEmbedElement': [
@@ -780,10 +830,7 @@
   ],
   'HTMLOutputElement': _no_ie_annotations,
   'HTMLProgressElement': _all_but_ie9_annotations,
-  'HTMLShadowElement': [
-    "@SupportedBrowser(SupportedBrowser.CHROME, '25')",
-    "@Experimental",
-  ],
+  'HTMLShadowElement': _shadow_dom_annotations,
   'HTMLTrackElement': [
     "@SupportedBrowser(SupportedBrowser.CHROME)",
     "@SupportedBrowser(SupportedBrowser.IE, '10')",
@@ -808,10 +855,7 @@
   'RTCIceCandidate': _rtc_annotations,
   'RTCPeerConnection': _rtc_annotations,
   'RTCSessionDescription': _rtc_annotations,
-  'ShadowRoot': [
-    "@SupportedBrowser(SupportedBrowser.CHROME, '25')",
-    "@Experimental",
-  ],
+  'ShadowRoot': _shadow_dom_annotations,
   'SpeechRecognition': _speech_recognition_annotations,
   'SpeechRecognitionAlternative': _speech_recognition_annotations,
   'SpeechRecognitionError': _speech_recognition_annotations,
@@ -1092,9 +1136,11 @@
     self._type_registry = type_registry
 
   def dart_type(self):
+    if self._data.dart_type:
+      return self._data.dart_type
     if self.list_item_type() and not self.has_generated_interface():
       return 'List<%s>' % self._type_registry.TypeInfo(self._data.item_type).dart_type()
-    return self._data.dart_type or self._dart_interface_name
+    return self._dart_interface_name
 
   def narrow_dart_type(self):
     if self.list_item_type():
@@ -1315,7 +1361,13 @@
 
 
 def TypedArrayTypeData(item_type):
-  return TypeData(clazz='Interface', item_type=item_type, is_typed_array=True)
+  return TypeData(
+      clazz='Interface',
+      dart_type='List<%s>' % item_type, # TODO(antonm): proper typeddata interfaces.
+      item_type=item_type,
+      # TODO(antonm): should be autogenerated. Let the dust settle down.
+      custom_to_dart=True, custom_to_native=True,
+      is_typed_array=True)
 
 
 _idl_type_registry = monitored.Dict('generator._idl_type_registry', {
@@ -1345,6 +1397,8 @@
     'any': TypeData(clazz='Primitive', dart_type='Object', native_type='ScriptValue'),
     'Array': TypeData(clazz='Primitive', dart_type='List'),
     'custom': TypeData(clazz='Primitive', dart_type='dynamic'),
+    'ClientRect': TypeData(clazz='Interface',
+        dart_type='Rect', suppress_interface=True),
     'Date': TypeData(clazz='Primitive', dart_type='DateTime', native_type='double'),
     'DOMObject': TypeData(clazz='Primitive', dart_type='Object', native_type='ScriptValue'),
     'DOMString': TypeData(clazz='Primitive', dart_type='String', native_type='String'),
@@ -1379,7 +1433,7 @@
     'SVGElement': TypeData(clazz='Interface', custom_to_dart=True),
 
     'ClientRectList': TypeData(clazz='Interface',
-        item_type='ClientRect', suppress_interface=True),
+        item_type='ClientRect', dart_type='List<Rect>', suppress_interface=True),
     'CSSRuleList': TypeData(clazz='Interface',
         item_type='CSSRule', suppress_interface=True),
     'CSSValueList': TypeData(clazz='Interface',
@@ -1394,6 +1448,7 @@
         suppress_interface=True),
     'FileList': TypeData(clazz='Interface', item_type='File',
         dart_type='List<File>'),
+    'Future': TypeData(clazz='Interface', dart_type='Future'),
     'GamepadList': TypeData(clazz='Interface', item_type='Gamepad',
         suppress_interface=True),
     'HTMLAllCollection': TypeData(clazz='Interface', item_type='Node'),
@@ -1427,6 +1482,15 @@
     'Uint8ClampedArray': TypedArrayTypeData('int'),
     'Uint16Array': TypedArrayTypeData('int'),
     'Uint32Array': TypedArrayTypeData('int'),
+    # TODO(antonm): temporary ugly hack.
+    # While in transition phase we allow both DOM's ArrayBuffer
+    # and dart:typeddata's ByteBuffer for IDLs' ArrayBuffers,
+    # hence ArrayBuffer is mapped to dynamic in arguments and return
+    # values.
+    'ArrayBufferView': TypeData(clazz='Interface', dart_type='dynamic',
+        custom_to_native=True, custom_to_dart=True),
+    'ArrayBuffer': TypeData(clazz='Interface', dart_type='dynamic',
+        custom_to_native=True, custom_to_dart=True),
 
     'SVGAngle': TypeData(clazz='SVGTearOff'),
     'SVGLength': TypeData(clazz='SVGTearOff'),
diff --git a/tools/dom/scripts/htmldartgenerator.py b/tools/dom/scripts/htmldartgenerator.py
index 2b2b084..cebafab 100644
--- a/tools/dom/scripts/htmldartgenerator.py
+++ b/tools/dom/scripts/htmldartgenerator.py
@@ -10,7 +10,8 @@
 from generator import AnalyzeOperation, ConstantOutputOrder, \
     DartDomNameOfAttribute, FindMatchingAttribute, IsDartCollectionType, \
     IsPureInterface, TypeOrNothing, GetAnnotationsAndComments, \
-    FormatAnnotationsAndComments
+    FormatAnnotationsAndComments, ConvertToFuture, GetCallbackInfo
+from htmlrenamer import convert_to_future_members
 
 # Types that are accessible cross-frame in a limited fashion.
 # In these cases, the base type (e.g., WindowBase) provides restricted access
@@ -89,6 +90,9 @@
       operations = operationsById[id]
       info = AnalyzeOperation(interface, operations)
       self.AddOperation(info, declare_only)
+      if ('%s.%s' % (interface.id, info.declared_name) in
+          convert_to_future_members):
+        self.AddOperation(ConvertToFuture(info), declare_only)
 
   def AddSecondaryMembers(self, interface):
     # With multiple inheritance, attributes and operations of non-first
@@ -227,6 +231,25 @@
         argument = signatures[signature_index][i]
         parameter_name = parameter_names[i]
         test_type = self._DartType(argument.type.id)
+        # TODO(antonm): temporary ugly hack to be able to work with existing
+        # typed array types as well as dart:typeddata types until
+        # the transition to dart:typeddata is complete for both dart2js
+        # and dartium.
+        from systemnative import DartiumBackend
+        if isinstance(self, DartiumBackend):
+          if argument.type.id == 'ArrayBufferView':
+            checks.append(
+                '(%(name)s is ArrayBufferView '
+                '|| %(name)s is _typeddata.TypedData '
+                '|| %(name)s == null)' % {'name': parameter_name})
+            continue
+          if argument.type.id == 'ArrayBuffer':
+            checks.append(
+                '(%(name)s is ArrayBuffer '
+                '|| %(name)s is _typeddata.ByteBuffer '
+                '|| %(name)s == null)' % {'name': parameter_name})
+            continue
+        # end of ugly hack.
         if test_type in ['dynamic', 'Object']:
           checks.append('?%s' % parameter_name)
         elif not can_omit_type_check(test_type, i):
@@ -240,8 +263,27 @@
 
     # TODO: Optimize the dispatch to avoid repeated checks.
     if len(signatures) > 1:
+      index_swaps = {}
       for signature_index, signature in enumerate(signatures):
         for argument_position, argument in enumerate(signature):
+          if argument.type.id != 'ArrayBuffer':
+            continue
+          candidates = enumerate(
+              signatures[signature_index + 1:], signature_index + 1)
+          for candidate_index, candidate in candidates:
+            if len(candidate) <= argument_position:
+              continue
+            if candidate[argument_position].type.id != 'ArrayBufferView':
+              continue
+            if len(index_swaps):
+              raise Exception('Cannot deal with more than a single swap')
+            index_swaps[candidate_index] = signature_index
+            index_swaps[signature_index] = candidate_index
+
+      for signature_index in range(len(signatures)):
+        signature_index = index_swaps.get(signature_index, signature_index)
+        signature = signatures[signature_index]
+        for argument_position, argument in enumerate(signature):
           if is_optional(signature_index, argument):
             GenerateChecksAndCall(signature_index, argument_position)
         GenerateChecksAndCall(signature_index, len(signature))
@@ -454,6 +496,50 @@
           GenerateCall,
           IsOptional)
 
+  def _AddFutureifiedOperation(self, info, html_name):
+    """Given a API function that uses callbacks, convert it to using Futures.
+
+    This conversion assumes the success callback is always provided before the
+    error callback (and so far in the DOM API, this is the case)."""
+    callback_info = GetCallbackInfo(
+        self._database.GetInterface(info.callback_args[0].type_id))
+
+    param_list = info.ParametersAsArgumentList()
+    annotations = ''
+    if '_RenamingAnnotation' in dir(self):
+      annotations = (self._RenamingAnnotation(info.declared_name, html_name) +
+          self._Annotations(info.type_name, info.declared_name))
+    self._members_emitter.Emit(
+        '\n'
+        '  $ANNOTATIONS$MODIFIERS$TYPE$FUTURE_GENERIC $NAME($PARAMS) {\n'
+        '    var completer = new Completer$(FUTURE_GENERIC)();\n'
+        '    $ORIGINAL_FUNCTION($PARAMS_LIST\n'
+        '        $NAMED_PARAM($VARIABLE_NAME) { '
+        'completer.complete($VARIABLE_NAME); }'
+        '$ERROR_CALLBACK);\n'
+        '    return completer.future;\n'
+        '  }\n',
+        ANNOTATIONS=annotations,
+        MODIFIERS='static ' if info.IsStatic() else '',
+        TYPE=self.SecureOutputType(info.type_name),
+        NAME=html_name[1:],
+        PARAMS=info.ParametersDeclaration(self._NarrowInputType
+            if '_NarrowInputType' in dir(self) else self._DartType),
+        PARAMS_LIST='' if param_list == '' else param_list + ',',
+        NAMED_PARAM=('%s : ' % info.callback_args[0].name
+            if info.requires_named_arguments and
+              info.callback_args[0].is_optional else ''),
+        VARIABLE_NAME= '' if len(callback_info.param_infos) == 0 else 'value',
+        ERROR_CALLBACK=('' if len(info.callback_args) == 1 else
+            (',\n        %s(error) { completer.completeError(error); }' %
+            ('%s : ' % info.callback_args[1].name
+            if info.requires_named_arguments and
+                info.callback_args[1].is_optional else ''))),
+        FUTURE_GENERIC = ('' if len(callback_info.param_infos) == 0 or
+            not callback_info.param_infos[0].type_id else
+            '<%s>' % self._DartType(callback_info.param_infos[0].type_id)),
+        ORIGINAL_FUNCTION = html_name)
+
   def EmitHelpers(self, base_class):
     pass
 
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py
index 705232a..c855787 100644
--- a/tools/dom/scripts/htmlrenamer.py
+++ b/tools/dom/scripts/htmlrenamer.py
@@ -18,13 +18,27 @@
     'DOMFormData': 'FormData',
     'DOMURL': 'Url',
     'DOMWindow': 'Window',
+    'EntryCallback': '_EntryCallback',
+    'EntriesCallback': '_EntriesCallback',
+    'ErrorCallback': '_ErrorCallback',
+    'FileCallback': '_FileCallback',
+    'FileSystemCallback': '_FileSystemCallback',
+    'FileWriterCallback': '_FileWriterCallback',
     'HTMLDocument' : 'HtmlDocument',
     'IDBFactory': 'IdbFactory', # Manual to avoid name conflicts.
     'NamedNodeMap': '_NamedNodeMap',
     'NavigatorUserMediaErrorCallback': '_NavigatorUserMediaErrorCallback',
     'NavigatorUserMediaSuccessCallback': '_NavigatorUserMediaSuccessCallback',
+    'NotificationPermissionCallback': '_NotificationPermissionCallback',
     'PositionCallback': '_PositionCallback',
     'PositionErrorCallback': '_PositionErrorCallback',
+    'Rect': 'CssRect',
+    'RGBColor': 'CssRgbColor',
+    'RTCErrorCallback': '_RtcErrorCallback',
+    'RTCSessionDescriptionCallback': '_RtcSessionDescriptionCallback',
+    'StorageInfoErrorCallback': '_StorageInfoErrorCallback',
+    'StorageInfoUsageCallback': '_StorageInfoUsageCallback',
+    'StringCallback': '_StringCallback',
     'SVGDocument': 'SvgDocument', # Manual to avoid name conflicts.
     'SVGElement': 'SvgElement', # Manual to avoid name conflicts.
     'SVGException': 'SvgException', # Manual of avoid conflict with Exception.
@@ -79,10 +93,40 @@
 for interface in _removed_html_interfaces:
   html_interface_renames[interface] = '_' + interface
 
+convert_to_future_members = monitored.Set(
+    'htmlrenamer.converted_to_future_members', [
+  'DataTransferItem.getAsString',
+  'DirectoryEntry.getDirectory',
+  'DirectoryEntry.getFile',
+  'DirectoryEntry.removeRecursively',
+  'DirectoryReader.readEntries',
+  'DOMWindow.webkitRequestFileSystem',
+  'DOMWindow.webkitResolveLocalFileSystemURL',
+  'Entry.copyTo',
+  'Entry.getMetadata',
+  'Entry.getParent',
+  'Entry.moveTo',
+  'Entry.remove',
+  'FileEntry.createWriter',
+  'FileEntry.file',
+  'Notification.requestPermission',
+  'NotificationCenter.requestPermission',
+  'RTCPeerConnection.createAnswer',
+  'RTCPeerConnection.createOffer',
+  'RTCPeerConnection.setLocalDescription',
+  'RTCPeerConnection.setRemoteDescription',
+  'StorageInfo.queryUsageAndQuota',
+  'StorageInfo.requestQuota',
+  'WorkerContext.webkitResolveLocalFileSystemURL',
+  'WorkerContext.webkitRequestFileSystem',
+])
+
 # Members from the standard dom that should not be exposed publicly in dart:html
 # but need to be exposed internally to implement dart:html on top of a standard
 # browser.
 _private_html_members = monitored.Set('htmlrenamer._private_html_members', [
+  'CanvasRenderingContext2D.arc',
+  'CanvasRenderingContext2D.drawImage',
   'CompositionEvent.initCompositionEvent',
   'CustomEvent.initCustomEvent',
   'DeviceOrientationEvent.initDeviceOrientationEvent',
@@ -93,11 +137,6 @@
   'Document.createTextNode',
   'Document.createTouch',
   'Document.createTouchList',
-  'Document.getElementById',
-  'Document.getElementsByClassName',
-  'Document.getElementsByName',
-  'Document.getElementsByTagName',
-  'Document.querySelector',
   'Document.querySelectorAll',
 
   # Moved to HTMLDocument.
@@ -127,15 +166,21 @@
   'Element.childElementCount',
   'Element.children',
   'Element.className',
+  'Element.clientHeight',
+  'Element.clientLeft',
+  'Element.clientTop',
+  'Element.clientWidth',
   'Element.firstElementChild',
   'Element.getAttribute',
   'Element.getAttributeNS',
-  'Element.getElementsByClassName',
   'Element.getElementsByTagName',
   'Element.hasAttribute',
   'Element.hasAttributeNS',
   'Element.lastElementChild',
-  'Element.querySelector',
+  'Element.offsetHeight',
+  'Element.offsetLeft',
+  'Element.offsetTop',
+  'Element.offsetWidth',
   'Element.querySelectorAll',
   'Element.removeAttribute',
   'Element.removeAttributeNS',
@@ -188,8 +233,15 @@
   'KeyboardEvent.keyIdentifier',
   'MessageEvent.initMessageEvent',
   'MouseEvent.initMouseEvent',
+  'MouseEvent.clientX',
+  'MouseEvent.clientY',
+  'MouseEvent.webkitMovementX',
+  'MouseEvent.webkitMovementY',
+  'MouseEvent.offsetX',
+  'MouseEvent.offsetY',
+  'MouseEvent.screenX',
+  'MouseEvent.screenY',
   'MutationEvent.initMutationEvent',
-  'Node.appendChild',
   'Node.attributes',
   'Node.childNodes',
   'Node.firstChild',
@@ -198,9 +250,10 @@
   'Node.namespaceURI',
   'Node.removeChild',
   'Node.replaceChild',
-  'ShadowRoot.getElementById',
-  'ShadowRoot.getElementsByClassName',
-  'ShadowRoot.getElementsByTagName',
+  'Screen.availHeight',
+  'Screen.availLeft',
+  'Screen.availTop',
+  'Screen.availWidth',
   'Storage.clear',
   'Storage.getItem',
   'Storage.key',
@@ -209,10 +262,20 @@
   'Storage.setItem',
   'StorageEvent.initStorageEvent',
   'TextEvent.initTextEvent',
+  'Touch.clientX',
+  'Touch.clientY',
+  'Touch.pageX',
+  'Touch.pageY',
+  'Touch.screenX',
+  'Touch.screenY',
   'TouchEvent.initTouchEvent',
   'UIEvent.charCode',
   'UIEvent.initUIEvent',
   'UIEvent.keyCode',
+  'UIEvent.layerX',
+  'UIEvent.layerY',
+  'UIEvent.pageX',
+  'UIEvent.pageY',
   'WheelEvent.wheelDeltaX',
   'WheelEvent.wheelDeltaY',
   'WheelEvent.initWebKitWheelEvent',
@@ -224,6 +287,7 @@
 renamed_html_members = monitored.Dict('htmlrenamer.renamed_html_members', {
     'Document.createCDATASection': 'createCDataSection',
     'Document.defaultView': 'window',
+    'Document.querySelector': 'query',
     'DOMURL.createObjectURL': 'createObjectUrl',
     'DOMURL.revokeObjectURL': 'revokeObjectUrl',
     'DOMWindow.clearTimeout': '_clearTimeout',
@@ -235,18 +299,20 @@
     'DOMWindow.webkitNotifications': 'notifications',
     'DOMWindow.webkitRequestFileSystem': 'requestFileSystem',
     'DOMWindow.webkitResolveLocalFileSystemURL': 'resolveLocalFileSystemUrl',
-    'DOMWindow.webkitRequestFileSystem': 'requestFileSystem',
-    'DOMWindow.webkitResolveLocalFileSystemURL': 'resolveLocalFileSystemUrl',
+    'Element.querySelector': 'query',
     'Element.webkitCreateShadowRoot': 'createShadowRoot',
     'Element.webkitMatchesSelector' : 'matches',
     'Navigator.webkitGetUserMedia': '_getUserMedia',
+    'Node.appendChild': 'append',
     'Node.cloneNode': 'clone',
     'Node.nextSibling': 'nextNode',
     'Node.ownerDocument': 'document',
     'Node.parentElement': 'parent',
     'Node.previousSibling': 'previousNode',
     'Node.textContent': 'text',
+    'SVGComponentTransferFunctionElement.offset': 'gradientOffset',
     'SVGElement.className': '$dom_svgClassName',
+    'SVGStopElement.offset': 'gradientOffset',
     'WorkerContext.webkitRequestFileSystem': 'requestFileSystem',
     'WorkerContext.webkitRequestFileSystemSync': 'requestFileSystemSync',
     'WorkerContext.webkitResolveLocalFileSystemSyncURL':
@@ -255,6 +321,12 @@
         'resolveLocalFileSystemUrl',
 })
 
+for member in convert_to_future_members:
+  if member in renamed_html_members:
+    renamed_html_members[member] = '_' + renamed_html_members[member]
+  else:
+    renamed_html_members[member] = '_' + member[member.find('.') + 1 :]
+
 # Members and classes from the dom that should be removed completely from
 # dart:html.  These could be expressed in the IDL instead but expressing this
 # as a simple table instead is more concise.
diff --git a/tools/dom/scripts/monitored.py b/tools/dom/scripts/monitored.py
index e90330a..06dc4dd 100644
--- a/tools/dom/scripts/monitored.py
+++ b/tools/dom/scripts/monitored.py
@@ -19,7 +19,7 @@
     _monitored_values.append(self)
 
 class Dict(MonitoredCollection):
-  """Wrapper for a read-only dict that reports unused keys."""
+  """Wrapper for a dict that reports unused keys."""
 
   def __init__(self, name, map):
     super(Dict, self).__init__(name)
@@ -50,7 +50,7 @@
 
 
 class Set(MonitoredCollection):
-  """Wrapper for a read-only set that reports unused keys."""
+  """Wrapper for a set that reports unused keys."""
 
   def __init__(self, name, a_set):
     super(Set, self).__init__(name)
@@ -60,6 +60,12 @@
     self._used_keys.add(key)
     return key in self._set
 
+  def __iter__(self):
+    return self._set.__iter__()
+
+  def add(self, key):
+    self._set += [key]
+
   def CheckUsage(self):
     for v in sorted(self._set):
       if v not in self._used_keys:
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 7a0c5dd..0f2de53 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -365,10 +365,10 @@
     'DOMApplicationCache': "JS('bool', '!!(window.applicationCache)')",
     'DOMFileSystem': "JS('bool', '!!(window.webkitRequestFileSystem)')",
     'FormData': "JS('bool', '!!(window.FormData)')",
-    'HashChangeEvent': "Event._isTypeSupported('HashChangeEvent')",
+    'HashChangeEvent': "Device.isEventTypeSupported('HashChangeEvent')",
     'HTMLShadowElement': ElemSupportStr('shadow'),
-    'MediaStreamEvent': "Event._isTypeSupported('MediaStreamEvent')",
-    'MediaStreamTrackEvent': "Event._isTypeSupported('MediaStreamTrackEvent')",
+    'MediaStreamEvent': "Device.isEventTypeSupported('MediaStreamEvent')",
+    'MediaStreamTrackEvent': "Device.isEventTypeSupported('MediaStreamTrackEvent')",
     'NotificationCenter': "JS('bool', '!!(window.webkitNotifications)')",
     'Performance': "JS('bool', '!!(window.performance)')",
     'SpeechRecognition': "JS('bool', '!!(window.SpeechRecognition || "
@@ -382,7 +382,7 @@
         "element, element)"),
     'TouchList': "JS('bool', '!!document.createTouchList')",
     'XMLHttpRequestProgressEvent':
-        "Event._isTypeSupported('XMLHttpRequestProgressEvent')",
+        "Device.isEventTypeSupported('XMLHttpRequestProgressEvent')",
     'WebGLRenderingContext': "JS('bool', '!!(window.WebGLRenderingContext)')",
     'WebKitCSSMatrix': "JS('bool', '!!(window.WebKitCSSMatrix)')",
     'WebKitPoint': "JS('bool', '!!(window.WebKitPoint)')",
@@ -421,9 +421,7 @@
 
   def GenerateCallback(self):
     """Generates a typedef for the callback interface."""
-    handlers = [operation for operation in self._interface.operations
-                if operation.id == 'handleEvent']
-    info = AnalyzeOperation(self._interface, handlers)
+    info = GetCallbackInfo(self._interface)
     code = self._library_emitter.FileEmitter(self._interface.id,
         self._library_name)
     code.Emit(self._template_loader.Load('callback.darttemplate'))
@@ -860,6 +858,8 @@
 
     if IsPureInterface(self._interface.id):
       self._AddInterfaceOperation(info, html_name)
+    elif info.callback_args:
+      self._AddFutureifiedOperation(info, html_name)
     elif any(self._OperationRequiresConversions(op) for op in info.overloads):
       # Any conversions needed?
       self._AddOperationWithConversions(info, html_name)
diff --git a/tools/dom/scripts/systemnative.py b/tools/dom/scripts/systemnative.py
index 06e27a9..b997c41 100644
--- a/tools/dom/scripts/systemnative.py
+++ b/tools/dom/scripts/systemnative.py
@@ -10,7 +10,7 @@
 import os
 from generator import *
 from htmldartgenerator import *
-from systemhtml import js_support_checks
+from systemhtml import js_support_checks, GetCallbackInfo
 
 class DartiumBackend(HtmlDartGenerator):
   """Generates Dart implementation for one DOM IDL interface."""
@@ -475,7 +475,9 @@
     has_optional_arguments = any(self._IsArgumentOptionalInWebCore(operation, argument) for argument in operation.arguments)
     needs_dispatcher = not is_custom and (len(info.operations) > 1 or has_optional_arguments)
 
-    if not needs_dispatcher:
+    if info.callback_args:
+      self._AddFutureifiedOperation(info, html_name)
+    elif not needs_dispatcher:
       # Bind directly to native implementation
       argument_count = (0 if info.IsStatic() else 1) + len(info.param_infos)
       cpp_callback_name = self._GenerateNativeBinding(
diff --git a/tools/dom/src/CanvasImageSource.dart b/tools/dom/src/CanvasImageSource.dart
new file mode 100644
index 0000000..9b4feea
--- /dev/null
+++ b/tools/dom/src/CanvasImageSource.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of html;
+
+/**
+ * An object that can be drawn to a [CanvasRenderingContext2D] object with
+ * [CanvasRenderingContext2D.drawImage] or
+ * [CanvasRenderingContext2D.drawImageAtScale].
+ *
+ * If the CanvasImageSource is an [ImageElement] then the element's image is
+ * used. If the [ImageElement] is an animated image, then the poster frame is
+ * used. If there is no poster frame, then the first frame of animation is used.
+ *
+ * If the CanvasImageSource is a [VideoElement] then the frame at the current
+ * playback position is used as the image.
+ *
+ * If the CanvasImageSource is a [CanvasElement] then the element's bitmap is
+ * used.
+ *
+ * See also:
+ *
+ *  * [CanvasImageSource](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-sources-for-2d-rendering-contexts)
+ * from the WHATWG.
+ */
+abstract class CanvasImageSource {}
diff --git a/tools/dom/src/CssClassSet.dart b/tools/dom/src/CssClassSet.dart
index 65528b4..dbc8afc 100644
--- a/tools/dom/src/CssClassSet.dart
+++ b/tools/dom/src/CssClassSet.dart
@@ -48,7 +48,7 @@
 
   Iterable<String> where(bool f(String element)) => readClasses().where(f);
 
-  Iterable expand(Iterable f(String element)) => readClasses.expand(f);
+  Iterable expand(Iterable f(String element)) => readClasses().expand(f);
 
   bool every(bool f(String element)) => readClasses().every(f);
 
@@ -94,23 +94,29 @@
     _modify((s) => s.retainAll(iterable));
   }
 
-  void removeMatching(bool test(String name)) {
-    _modify((s) => s.removeMatching(test));
+  void removeWhere(bool test(String name)) {
+    _modify((s) => s.removeWhere(test));
   }
 
-  void retainMatching(bool test(String name)) {
-    _modify((s) => s.retainMatching(test));
+  void retainWhere(bool test(String name)) {
+    _modify((s) => s.retainWhere(test));
   }
 
   bool isSubsetOf(Collection<String> collection) =>
     readClasses().isSubsetOf(collection);
 
-  bool containsAll(Collection<String> collection) =>
+  bool containsAll(Iterable<String> collection) =>
     readClasses().containsAll(collection);
 
-  Set<String> intersection(Collection<String> other) =>
+  Set<String> intersection(Set<String> other) =>
     readClasses().intersection(other);
 
+  Set<String> union(Set<String> other) =>
+    readClasses().union(other);
+
+  Set<String> difference(Set<String> other) =>
+    readClasses().difference(other);
+
   String get first => readClasses().first;
   String get last => readClasses().last;
   String get single => readClasses().single;
@@ -127,12 +133,12 @@
   Iterable<String> skip(int n) => readClasses().skip(n);
   Iterable<String> skipWhile(bool test(String value)) =>
       readClasses().skipWhile(test);
-  String firstMatching(bool test(String value), { String orElse() }) =>
-      readClasses().firstMatching(test, orElse: orElse);
-  String lastMatching(bool test(String value), {String orElse()}) =>
-      readClasses().lastMatching(test, orElse: orElse);
-  String singleMatching(bool test(String value)) =>
-      readClasses().singleMatching(test);
+  String firstWhere(bool test(String value), { String orElse() }) =>
+      readClasses().firstWhere(test, orElse: orElse);
+  String lastWhere(bool test(String value), {String orElse()}) =>
+      readClasses().lastWhere(test, orElse: orElse);
+  String singleWhere(bool test(String value)) =>
+      readClasses().singleWhere(test);
   String elementAt(int index) => readClasses().elementAt(index);
 
   void clear() {
diff --git a/tools/dom/src/Device.dart b/tools/dom/src/Device.dart
deleted file mode 100644
index 34dba8a..0000000
--- a/tools/dom/src/Device.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-// 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.
-
-part of html;
-
-/**
- * Utils for device detection.
- */
-class _Device {
-  /**
-   * Gets the browser's user agent. Using this function allows tests to inject
-   * the user agent.
-   * Returns the user agent.
-   */
-  static String get userAgent => window.navigator.userAgent;
-
-  /**
-   * Determines if the current device is running Opera.
-   */
-  static bool get isOpera => userAgent.contains("Opera", 0);
-
-  /**
-   * Determines if the current device is running Internet Explorer.
-   */
-  static bool get isIE => !isOpera && userAgent.contains("MSIE", 0);
-
-  /**
-   * Determines if the current device is running Firefox.
-   */
-  static bool get isFirefox => userAgent.contains("Firefox", 0);
-
-  /**
-   * Determines if the current device is running WebKit.
-   */
-  static bool get isWebKit => !isOpera && userAgent.contains("WebKit", 0);
-}
diff --git a/tools/dom/src/KeyCode.dart b/tools/dom/src/KeyCode.dart
index b2c81b3..417ee82 100644
--- a/tools/dom/src/KeyCode.dart
+++ b/tools/dom/src/KeyCode.dart
@@ -5,9 +5,9 @@
 part of html;
 
 /**
- * Defines the keycode values for keys that are returned by 
+ * Defines the keycode values for keys that are returned by
  * KeyboardEvent.keyCode.
- * 
+ *
  * Important note: There is substantial divergence in how different browsers
  * handle keycodes and their variants in different locales/keyboard layouts. We
  * provide these constants to help make code processing keys more readable.
@@ -15,7 +15,7 @@
 abstract class KeyCode {
   // These constant names were borrowed from Closure's Keycode enumeration
   // class.
-  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keycodes.js.source.html  
+  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keycodes.js.source.html
   static const int WIN_KEY_FF_LINUX = 0;
   static const int MAC_ENTER = 3;
   static const int BACKSPACE = 8;
@@ -210,12 +210,12 @@
         (keyCode >= A && keyCode <= Z)) {
       return true;
     }
- 
+
     // Safari sends zero key code for non-latin characters.
-    if (_Device.isWebKit && keyCode == 0) {
+    if (Device.isWebKit && keyCode == 0) {
       return true;
     }
- 
+
     return (keyCode == SPACE || keyCode == QUESTION_MARK || keyCode == NUM_PLUS
         || keyCode == NUM_MINUS || keyCode == NUM_PERIOD ||
         keyCode == NUM_DIVISION || keyCode == SEMICOLON ||
diff --git a/tools/dom/src/KeyboardEventController.dart b/tools/dom/src/KeyboardEventController.dart
index 4235b75..80e8bf0 100644
--- a/tools/dom/src/KeyboardEventController.dart
+++ b/tools/dom/src/KeyboardEventController.dart
@@ -259,11 +259,11 @@
    * Returns true if the key fires a keypress event in the current browser.
    */
   bool _firesKeyPressEvent(KeyEvent event) {
-    if (!_Device.isIE && !_Device.isWebKit) {
+    if (!Device.isIE && !Device.isWebKit) {
       return true;
     }
 
-    if (_Device.userAgent.contains('Mac') && event.altKey) {
+    if (Device.userAgent.contains('Mac') && event.altKey) {
       return KeyCode.isCharacterKey(event.keyCode);
     }
 
@@ -276,13 +276,13 @@
     if (!event.shiftKey &&
         (_keyDownList.last.keyCode == KeyCode.CTRL ||
          _keyDownList.last.keyCode == KeyCode.ALT ||
-         _Device.userAgent.contains('Mac') &&
+         Device.userAgent.contains('Mac') &&
          _keyDownList.last.keyCode == KeyCode.META)) {
       return false;
     }
 
     // Some keys with Ctrl/Shift do not issue keypress in WebKit.
-    if (_Device.isWebKit && event.ctrlKey && event.shiftKey && (
+    if (Device.isWebKit && event.ctrlKey && event.shiftKey && (
         event.keyCode == KeyCode.BACKSLASH ||
         event.keyCode == KeyCode.OPEN_SQUARE_BRACKET ||
         event.keyCode == KeyCode.CLOSE_SQUARE_BRACKET ||
@@ -298,9 +298,9 @@
     switch (event.keyCode) {
       case KeyCode.ENTER:
         // IE9 does not fire keypress on ENTER.
-        return !_Device.isIE;
+        return !Device.isIE;
       case KeyCode.ESC:
-        return !_Device.isWebKit;
+        return !Device.isWebKit;
     }
 
     return KeyCode.isCharacterKey(event.keyCode);
@@ -312,7 +312,7 @@
    */
   int _normalizeKeyCodes(KeyboardEvent event) {
     // Note: This may change once we get input about non-US keyboards.
-    if (_Device.isFirefox) {
+    if (Device.isFirefox) {
       switch(event.keyCode) {
         case KeyCode.FF_EQUALS:
           return KeyCode.EQUALS;
@@ -335,7 +335,7 @@
     if (_keyDownList.length > 0 &&
         (_keyDownList.last.keyCode == KeyCode.CTRL && !e.ctrlKey ||
          _keyDownList.last.keyCode == KeyCode.ALT && !e.altKey ||
-         _Device.userAgent.contains('Mac') &&
+         Device.userAgent.contains('Mac') &&
          _keyDownList.last.keyCode == KeyCode.META && !e.metaKey)) {
       _keyDownList = [];
     }
@@ -362,13 +362,13 @@
     var e = new KeyEvent(event);
     // IE reports the character code in the keyCode field for keypress events.
     // There are two exceptions however, Enter and Escape.
-    if (_Device.isIE) {
+    if (Device.isIE) {
       if (e.keyCode == KeyCode.ENTER || e.keyCode == KeyCode.ESC) {
         e._shadowCharCode = 0;
       } else {
         e._shadowCharCode = e.keyCode;
       }
-    } else if (_Device.isOpera) {
+    } else if (Device.isOpera) {
       // Opera reports the character code in the keyCode field.
       e._shadowCharCode = KeyCode.isCharacterKey(e.keyCode) ? e.keyCode : 0;
     }
diff --git a/tools/dom/src/ModelTreeObserver.dart b/tools/dom/src/ModelTreeObserver.dart
new file mode 100644
index 0000000..f055795
--- /dev/null
+++ b/tools/dom/src/ModelTreeObserver.dart
@@ -0,0 +1,100 @@
+// 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.
+
+part of html;
+
+class _ModelTreeObserver {
+  static bool _initialized = false;
+
+  /**
+   * Start an observer watching the document for tree changes to automatically
+   * propagate model changes.
+   *
+   * Currently this does not support propagation through Shadow DOMs.
+   */
+  static void initialize() {
+    if (!_initialized) {
+      _initialized = true;
+
+      if (MutationObserver.supported) {
+        var observer = new MutationObserver(_processTreeChange);
+        observer.observe(document, childList: true, subtree: true);
+      } else {
+        document.on['DOMNodeInserted'].listen(_handleNodeInserted);
+        document.on['DOMNodeRemoved'].listen(_handleNodeRemoved);
+      }
+    }
+  }
+
+  static void _processTreeChange(List<MutationRecord> mutations,
+      MutationObserver observer) {
+    for (var record in mutations) {
+      for (var node in record.addedNodes) {
+        // When nodes enter the document we need to make sure that all of the
+        // models are properly propagated through the entire sub-tree.
+        propagateModel(node, _calculatedModel(node), true);
+      }
+      for (var node in record.removedNodes) {
+        propagateModel(node, _calculatedModel(node), false);
+      }
+    }
+  }
+
+  static void _handleNodeInserted(MutationEvent e) {
+    var node = e.target;
+    window.setImmediate(() {
+      propagateModel(node, _calculatedModel(node), true);
+    });
+  }
+
+  static void _handleNodeRemoved(MutationEvent e) {
+    var node = e.target;
+    window.setImmediate(() {
+      propagateModel(node, _calculatedModel(node), false);
+    });
+  }
+
+  /**
+   * Figures out what the model should be for a node, avoiding any cached
+   * model values.
+   */
+  static _calculatedModel(node) {
+    if (node._hasLocalModel == true) {
+      return node._model;
+    } else if (node.parentNode != null) {
+      return node.parentNode._model;
+    }
+    return null;
+  }
+
+  /**
+   * Pushes model changes down through the tree.
+   *
+   * Set fullTree to true if the state of the tree is unknown and model changes
+   * should be propagated through the entire tree.
+   */
+  static void propagateModel(Node node, model, bool fullTree) {
+    // Calling into user code with the != call could generate exceptions.
+    // Catch and report them a global exceptions.
+    try {
+      if (node._hasLocalModel != true && node._model != model &&
+          node._modelChangedStream != null) {
+        node._model = model;
+        node._modelChangedStream.add(node);
+      }
+    } on AsyncError catch (e) {
+      e.throwDelayed();
+    } catch (e, s) {
+      new AsyncError(e, s).throwDelayed();
+    }
+    for (var child = node.$dom_firstChild; child != null;
+        child = child.nextNode) {
+      if (child._hasLocalModel != true) {
+        propagateModel(child, model, fullTree);
+      } else if (fullTree) {
+        propagateModel(child, child._model, true);
+      }
+    }
+  }
+}
diff --git a/tools/dom/src/Point.dart b/tools/dom/src/Point.dart
new file mode 100644
index 0000000..958b731
--- /dev/null
+++ b/tools/dom/src/Point.dart
@@ -0,0 +1,64 @@
+// 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.
+
+part of html;
+
+/**
+ * A utility class for representing two-dimensional positions.
+ */
+class Point {
+  final num x;
+  final num y;
+
+  const Point([num x = 0, num y = 0]): x = x, y = y;
+
+  String toString() => '($x, $y)';
+
+  bool operator ==(other) {
+    if (other is !Point) return false;
+    return x == other.x && y == other.y;
+  }
+
+  Point operator +(Point other) {
+    return new Point(x + other.x, y + other.y);
+  }
+
+  Point operator -(Point other) {
+    return new Point(x - other.x, y - other.y);
+  }
+
+  Point operator *(num factor) {
+    return new Point(x * factor, y * factor);
+  }
+
+  /**
+   * Returns the distance between two points.
+   */
+  double distanceTo(Point other) {
+    var dx = x - other.x;
+    var dy = y - other.y;
+    return sqrt(dx * dx + dy * dy);
+  }
+
+  /**
+   * Returns the squared distance between two points.
+   *
+   * Squared distances can be used for comparisons when the actual value is not
+   * required.
+   */
+  num squaredDistanceTo(Point other) {
+    var dx = x - other.x;
+    var dy = y - other.y;
+    return dx * dx + dy * dy;
+  }
+
+  Point ceil() => new Point(x.ceil(), y.ceil());
+  Point floor() => new Point(x.floor(), y.floor());
+  Point round() => new Point(x.round(), y.round());
+
+  /**
+   * Truncates x and y to integers and returns the result as a new point.
+   */
+  Point toInt() => new Point(x.toInt(), y.toInt());
+}
diff --git a/tools/dom/src/Rectangle.dart b/tools/dom/src/Rectangle.dart
new file mode 100644
index 0000000..e87da11
--- /dev/null
+++ b/tools/dom/src/Rectangle.dart
@@ -0,0 +1,135 @@
+// 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.
+
+part of html;
+
+/**
+ * A class for representing two-dimensional rectangles.
+ */
+class Rect {
+  final num left;
+  final num top;
+  final num width;
+  final num height;
+
+  const Rect(this.left, this.top, this.width, this.height);
+
+  factory Rect.fromPoints(Point a, Point b) {
+    var left;
+    var width;
+    if (a.x < b.x) {
+      left = a.x;
+      width = b.x - left;
+    } else {
+      left = b.x;
+      width = a.x - left;
+    }
+    var top;
+    var height;
+    if (a.y < b.y) {
+      top = a.y;
+      height = b.y - top;
+    } else {
+      top = b.y;
+      height = a.y - top;
+    }
+
+    return new Rect(left, top, width, height);
+  }
+
+  num get right => left + width;
+  num get bottom => top + height;
+
+  // NOTE! All code below should be common with Rect.
+  // TODO: implement with mixins when available.
+
+  String toString() {
+    return '($left, $top, $width, $height)';
+  }
+
+  bool operator ==(other) {
+    if (other is !Rect) return false;
+    return left == other.left && top == other.top && width == other.width &&
+        height == other.height;
+  }
+
+  /**
+   * Computes the intersection of this rectangle and the rectangle parameter.
+   * Returns null if there is no intersection.
+   */
+  Rect intersection(Rect rect) {
+    var x0 = max(left, rect.left);
+    var x1 = min(left + width, rect.left + rect.width);
+
+    if (x0 <= x1) {
+      var y0 = max(top, rect.top);
+      var y1 = min(top + height, rect.top + rect.height);
+
+      if (y0 <= y1) {
+        return new Rect(x0, y0, x1 - x0, y1 - y0);
+      }
+    }
+    return null;
+  }
+
+
+  /**
+   * Returns whether a rectangle intersects this rectangle.
+   */
+  bool intersects(Rect other) {
+    return (left <= other.left + other.width && other.left <= left + width &&
+        top <= other.top + other.height && other.top <= top + height);
+  }
+
+  /**
+   * Returns a new rectangle which completely contains this rectangle and the
+   * input rectangle.
+   */
+  Rect union(Rect rect) {
+    var right = max(this.left + this.width, rect.left + rect.width);
+    var bottom = max(this.top + this.height, rect.top + rect.height);
+
+    var left = min(this.left, rect.left);
+    var top = min(this.top, rect.top);
+
+    return new Rect(left, top, right - left, bottom - top);
+  }
+
+  /**
+   * Tests whether this rectangle entirely contains another rectangle.
+   */
+  bool containsRect(Rect another) {
+    return left <= another.left &&
+           left + width >= another.left + another.width &&
+           top <= another.top &&
+           top + height >= another.top + another.height;
+  }
+
+  /**
+   * Tests whether this rectangle entirely contains a point.
+   */
+  bool containsPoint(Point another) {
+    return another.x >= left &&
+           another.x <= left + width &&
+           another.y >= top &&
+           another.y <= top + height;
+  }
+
+  Rect ceil() => new Rect(left.ceil(), top.ceil(), width.ceil(), height.ceil());
+  Rect floor() => new Rect(left.floor(), top.floor(), width.floor(),
+      height.floor());
+  Rect round() => new Rect(left.round(), top.round(), width.round(),
+      height.round());
+
+  /**
+   * Truncates coordinates to integers and returns the result as a new
+   * rectangle.
+   */
+  Rect toInt() => new Rect(left.toInt(), top.toInt(), width.toInt(),
+      height.toInt());
+
+  Point get topLeft => new Point(this.left, this.top);
+  Point get bottomRight => new Point(this.left + this.width,
+      this.top + this.height);
+}
diff --git a/tools/dom/src/WrappedList.dart b/tools/dom/src/WrappedList.dart
index 7b27218..eb255ce 100644
--- a/tools/dom/src/WrappedList.dart
+++ b/tools/dom/src/WrappedList.dart
@@ -63,13 +63,13 @@
 
   E get single => _list.single;
 
-  E firstMatching(bool test(E value), { E orElse() }) =>
-      _list.firstMatching(test, orElse: orElse);
+  E firstWhere(bool test(E value), { E orElse() }) =>
+      _list.firstWhere(test, orElse: orElse);
 
-  E lastMatching(bool test(E value), {E orElse()}) =>
-      _list.lastMatching(test, orElse: orElse);
+  E lastWhere(bool test(E value), {E orElse()}) =>
+      _list.lastWhere(test, orElse: orElse);
 
-  E singleMatching(bool test(E value)) => _list.singleMatching(test);
+  E singleWhere(bool test(E value)) => _list.singleWhere(test);
 
   E elementAt(int index) => _list.elementAt(index);
 
@@ -85,9 +85,9 @@
 
   void retainAll(Iterable elements) { _list.retainAll(elements); }
 
-  void removeMatching(bool test(E element)) { _list.removeMatching(test); }
+  void removeWhere(bool test(E element)) { _list.removeWhere(test); }
 
-  void retainMatching(bool test(E element)) { _list.retainMatching(test); }
+  void retainWhere(bool test(E element)) { _list.retainWhere(test); }
 
   void clear() { _list.clear(); }
 
@@ -99,7 +99,7 @@
 
   void set length(int newLength) { _list.length = newLength; }
 
-  void addLast(E value) { _list.addLast(value); }
+  void addLast(E value) { _list.add(value); }
 
   Iterable<E> get reversed => _list.reversed;
 
@@ -109,11 +109,15 @@
 
   int lastIndexOf(E element, [int start]) => _list.lastIndexOf(element, start);
 
+  void insert(int index, E element) => _list.insert(index, element);
+
   E removeAt(int index) => _list.removeAt(index);
 
   E removeLast() => _list.removeLast();
 
-  List<E> getRange(int start, int length) => _list.getRange(start, length);
+  List<E> sublist(int start, [int end]) => _list.sublist(start, end);
+
+  List<E> getRange(int start, int length) => sublist(start, start + length);
 
   void setRange(int start, int length, List<E> from, [int startFrom]) {
     _list.setRange(start, length, from, startFrom);
diff --git a/tools/dom/src/dart2js_KeyEvent.dart b/tools/dom/src/dart2js_KeyEvent.dart
index 17e0905..5686b61 100644
--- a/tools/dom/src/dart2js_KeyEvent.dart
+++ b/tools/dom/src/dart2js_KeyEvent.dart
@@ -73,12 +73,10 @@
    * KeyLocation.NUMPAD, KeyLocation.MOBILE, KeyLocation.JOYSTICK).
    */
   int get keyLocation => _parent.keyLocation;
-  int get layerX => _parent.layerX;
-  int get layerY => _parent.layerY;
+  Point get layer => _parent.layer;
   /** True if the Meta (or Mac command) key is pressed during this event. */
   bool get metaKey => _parent.metaKey;
-  int get pageX => _parent.pageX;
-  int get pageY => _parent.pageY;
+  Point get page => _parent.page;
   bool get returnValue => _parent.returnValue;
   void set returnValue(bool value) {
     _parent.returnValue = value;
diff --git a/tools/dom/src/dartium_KeyEvent.dart b/tools/dom/src/dartium_KeyEvent.dart
index a8eff57..5be90c9 100644
--- a/tools/dom/src/dartium_KeyEvent.dart
+++ b/tools/dom/src/dartium_KeyEvent.dart
@@ -73,12 +73,10 @@
    * KeyLocation.NUMPAD, KeyLocation.MOBILE, KeyLocation.JOYSTICK).
    */
   int get keyLocation => _parent.keyLocation;
-  int get layerX => _parent.layerX;
-  int get layerY => _parent.layerY;
+  Point get layer => _parent.layer;
   /** True if the Meta (or Mac command) key is pressed during this event. */
   bool get metaKey => _parent.metaKey;
-  int get pageX => _parent.pageX;
-  int get pageY => _parent.pageY;
+  Point get page => _parent.page;
   bool get returnValue => _parent.returnValue;
   void set returnValue(bool value) {
     _parent.returnValue = value;
diff --git a/tools/dom/src/native_DOMImplementation.dart b/tools/dom/src/native_DOMImplementation.dart
index cd98baf..94ba076 100644
--- a/tools/dom/src/native_DOMImplementation.dart
+++ b/tools/dom/src/native_DOMImplementation.dart
@@ -7,8 +7,15 @@
 class _Utils {
   static double dateTimeToDouble(DateTime dateTime) =>
       dateTime.millisecondsSinceEpoch.toDouble();
-  static DateTime doubleToDateTime(double dateTime) =>
-      new DateTime.fromMillisecondsSinceEpoch(dateTime.toInt());
+  static DateTime doubleToDateTime(double dateTime) {
+    try {
+      return new DateTime.fromMillisecondsSinceEpoch(dateTime.toInt());
+    } catch(_) {
+      // TODO(antonnm): treat exceptions properly in bindings and
+      // find out how to treat NaNs.
+      return null;
+    }
+  }
 
   static List convertToList(List list) {
     // FIXME: [possible optimization]: do not copy the array if Dart_IsArray is fine w/ it.
@@ -40,6 +47,7 @@
 
   static window() native "Utils_window";
   static print(String message) native "Utils_print";
+  static forwardingPrint(String message) native "Utils_forwardingPrint";
   static SendPort spawnDomFunctionImpl(Function topLevelFunction) native "Utils_spawnDomFunction";
   static int _getNewIsolateId() native "Utils_getNewIsolateId";
   static bool shadowRootSupported(Document document) native "Utils_shadowRootSupported";
@@ -119,3 +127,5 @@
     _Utils.print(s);
   }
 };
+
+final _forwardingPrintClosure = _Utils.forwardingPrint;
diff --git a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
index 728b9d0..6a3521e 100644
--- a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
@@ -27,16 +27,19 @@
 $!GENERATED_DART_FILES
 
 part '$AUXILIARY_DIR/AttributeMap.dart';
+part '$AUXILIARY_DIR/CanvasImageSource.dart';
 part '$AUXILIARY_DIR/CrossFrameTypes.dart';
 part '$AUXILIARY_DIR/CssClassSet.dart';
-part '$AUXILIARY_DIR/Device.dart';
 part '$AUXILIARY_DIR/EventListener.dart';
 part '$AUXILIARY_DIR/EventStreamProvider.dart';
 part '$AUXILIARY_DIR/KeyboardEventController.dart';
 part '$AUXILIARY_DIR/KeyCode.dart';
 part '$AUXILIARY_DIR/KeyLocation.dart';
 part '$AUXILIARY_DIR/KeyName.dart';
+part '$AUXILIARY_DIR/ModelTreeObserver.dart';
+part '$AUXILIARY_DIR/Point.dart';
 part '$AUXILIARY_DIR/ReadyState.dart';
+part '$AUXILIARY_DIR/Rectangle.dart';
 part '$AUXILIARY_DIR/Timer.dart';
 part '$AUXILIARY_DIR/_HttpRequestUtils.dart';
 part '$AUXILIARY_DIR/Isolates.dart';
diff --git a/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate b/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate
index d39c3c9..c6affdc 100644
--- a/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate
@@ -22,18 +22,46 @@
   }
 $!MEMBERS
 
-  // TODO(amouravski): Move this documentation out of thise template files and
-  // put it into docs.json. Remember to add @DomName here.
+  @deprecated
+  int get clientX => client.x;
+  @deprecated
+  int get clientY => client.y;
+  @deprecated
+  int get offsetX => offset.x;
+  @deprecated
+  int get offsetY => offset.y;
+  @deprecated
+  int get movementX => movement.x;
+  @deprecated
+  int get movementY => movement.y;
+  @deprecated
+  int get screenX => screen.x;
+  @deprecated
+  int get screenY => screen.y;
+
+  @DomName('MouseEvent.clientX')
+  @DomName('MouseEvent.clientY')
+  Point get client => new Point($dom_clientX, $dom_clientY);
+
+  @DomName('MouseEvent.movementX')
+  @DomName('MouseEvent.movementY')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  Point get movement => new Point($dom_webkitMovementX, $dom_webkitMovementY);
+
   /**
-   * The X coordinate of the mouse pointer in target node coordinates.
+   * The coordinates of the mouse pointer in target node coordinates.
    *
    * This value may vary between platforms if the target node moves
    * after the event has fired or if the element has CSS transforms affecting
    * it.
    */
-  int get offsetX {
-  if (JS('bool', '!!#.offsetX', this)) {
-      return JS('int', '#.offsetX', this);
+  Point get offset {
+    if (JS('bool', '!!#.offsetX', this)) {
+      var x = JS('int', '#.offsetX', this);
+      var y = JS('int', '#.offsetX', this);
+      return new Point(x, y);
     } else {
       // Firefox does not support offsetX.
       var target = this.target;
@@ -41,28 +69,12 @@
         throw new UnsupportedError(
             'offsetX is only supported on elements');
       }
-      return this.clientX - this.target.getBoundingClientRect().left;
+      return (this.client -
+          this.target.getBoundingClientRect().topLeft).toInt();
     }
   }
 
-  /**
-   * The Y coordinate of the mouse pointer in target node coordinates.
-   *
-   * This value may vary between platforms if the target node moves
-   * after the event has fired or if the element has CSS transforms affecting
-   * it.
-   */
-  int get offsetY {
-    if (JS('bool', '!!#.offsetY', this)) {
-      return JS('int', '#.offsetY', this);
-    } else {
-      // Firefox does not support offsetY.
-      var target = this.target;
-      if (!(target is Element)) {
-        throw new UnsupportedError(
-            'offsetY is only supported on elements');
-      }
-      return this.clientY - this.target.getBoundingClientRect().top;
-    }
-  }
+  @DomName('MouseEvent.screenX')
+  @DomName('MouseEvent.screenY')
+  Point get screen => new Point($dom_screenX, $dom_screenY);
 }
diff --git a/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate b/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate
index 8cc027d..2295902 100644
--- a/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate
@@ -8,6 +8,7 @@
 import 'dart:collection';
 import 'dart:html';
 import 'dart:html_common';
+import 'dart:_js_helper' show Creates, Returns;
 import 'dart:_foreign_helper' show JS;
 
 $!GENERATED_DART_FILES
diff --git a/tools/dom/templates/html/dartium/html_dartium.darttemplate b/tools/dom/templates/html/dartium/html_dartium.darttemplate
index 77ca4f5..daaf025 100644
--- a/tools/dom/templates/html/dartium/html_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/html_dartium.darttemplate
@@ -14,7 +14,9 @@
 import 'dart:indexed_db';
 import 'dart:isolate';
 import 'dart:json' as json;
+import 'dart:math';
 import 'dart:nativewrappers';
+import 'dart:typeddata' as _typeddata;
 import 'dart:web_sql';
 // Not actually used, but imported since dart:html can generate these objects.
 import 'dart:svg' as svg;
@@ -23,6 +25,7 @@
 $!GENERATED_DART_FILES
 
 part '$AUXILIARY_DIR/AttributeMap.dart';
+part '$AUXILIARY_DIR/CanvasImageSource.dart';
 part '$AUXILIARY_DIR/CrossFrameTypes.dart';
 part '$AUXILIARY_DIR/CssClassSet.dart';
 part '$AUXILIARY_DIR/EventListener.dart';
@@ -31,14 +34,16 @@
 part '$AUXILIARY_DIR/KeyCode.dart';
 part '$AUXILIARY_DIR/KeyLocation.dart';
 part '$AUXILIARY_DIR/KeyName.dart';
+part '$AUXILIARY_DIR/ModelTreeObserver.dart';
+part '$AUXILIARY_DIR/Point.dart';
 part '$AUXILIARY_DIR/ReadyState.dart';
+part '$AUXILIARY_DIR/Rectangle.dart';
 part '$AUXILIARY_DIR/Timer.dart';
 part '$AUXILIARY_DIR/WrappedList.dart';
 part '$AUXILIARY_DIR/_HttpRequestUtils.dart';
 part '$AUXILIARY_DIR/shared_FactoryProviders.dart';
 part '$AUXILIARY_DIR/dartium_KeyEvent.dart';
 part '$AUXILIARY_DIR/dartium_FactoryProviders.dart';
-part '$AUXILIARY_DIR/Device.dart';
 part '$AUXILIARY_DIR/Isolates.dart';
 part '$AUXILIARY_DIR/Microtask.dart';
 part '$AUXILIARY_DIR/Serialization.dart';
diff --git a/tools/dom/templates/html/dartium/impl_MouseEvent.darttemplate b/tools/dom/templates/html/dartium/impl_MouseEvent.darttemplate
index bb1be2c..6203000 100644
--- a/tools/dom/templates/html/dartium/impl_MouseEvent.darttemplate
+++ b/tools/dom/templates/html/dartium/impl_MouseEvent.darttemplate
@@ -23,4 +23,45 @@
     return event;
   }
 $!MEMBERS
+
+  @deprecated
+  int get clientX => client.x;
+  @deprecated
+  int get clientY => client.y;
+  @deprecated
+  int get offsetX => offset.x;
+  @deprecated
+  int get offsetY => offset.y;
+  @deprecated
+  int get movementX => movement.x;
+  @deprecated
+  int get movementY => movement.y;
+  @deprecated
+  int get screenX => screen.x;
+  @deprecated
+  int get screenY => screen.y;
+
+  @DomName('MouseEvent.clientX')
+  @DomName('MouseEvent.clientY')
+  Point get client => new Point($dom_clientX, $dom_clientY);
+
+  @DomName('MouseEvent.movementX')
+  @DomName('MouseEvent.movementY')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  Point get movement => new Point($dom_webkitMovementX, $dom_webkitMovementY);
+
+  /**
+   * The coordinates of the mouse pointer in target node coordinates.
+   *
+   * This value may vary between platforms if the target node moves
+   * after the event has fired or if the element has CSS transforms affecting
+   * it.
+   */
+  Point get offset => new Point($dom_offsetX, $dom_offsetY);
+
+  @DomName('MouseEvent.screenX')
+  @DomName('MouseEvent.screenY')
+  Point get screen => new Point($dom_screenX, $dom_screenY);
 }
diff --git a/tools/dom/templates/html/dartium/web_audio_dartium.darttemplate b/tools/dom/templates/html/dartium/web_audio_dartium.darttemplate
index b6319de..5c1f4dd 100644
--- a/tools/dom/templates/html/dartium/web_audio_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/web_audio_dartium.darttemplate
@@ -8,5 +8,6 @@
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:nativewrappers';
+import 'dart:typeddata' as _typeddata;
 
 $!GENERATED_DART_FILES
diff --git a/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate b/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
index 040a646..0d0a233 100644
--- a/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
+++ b/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
@@ -4,41 +4,6 @@
 
 part of $LIBRARYNAME;
 
-String _cachedBrowserPrefix;
-
-String get _browserPrefix {
-  if (_cachedBrowserPrefix == null) {
-    if (_Device.isFirefox) {
-      _cachedBrowserPrefix = '-moz-';
-    } else if (_Device.isIE) {
-      _cachedBrowserPrefix = '-ms-';
-    } else if (_Device.isOpera) {
-      _cachedBrowserPrefix = '-o-';
-    } else {
-      _cachedBrowserPrefix = '-webkit-';
-    }
-  }
-  return _cachedBrowserPrefix;
-}
-
-String _cachedBrowserPropertyPrefix;
-
-/// Prefix as used for JS property names.
-String get _browserPropertyPrefix {
-  if (_cachedBrowserPropertyPrefix == null) {
-    if (_Device.isFirefox) {
-      _cachedBrowserPropertyPrefix = 'moz';
-    } else if (_Device.isIE) {
-      _cachedBrowserPropertyPrefix = 'ms';
-    } else if (_Device.isOpera) {
-      _cachedBrowserPropertyPrefix = 'o';
-    } else {
-      _cachedBrowserPropertyPrefix = 'webkit';
-    }
-  }
-  return _cachedBrowserPropertyPrefix;
-}
-
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
   factory $CLASSNAME() => _$(CLASSNAME)FactoryProvider.create$CLASSNAME();
   factory $CLASSNAME.css(String css) =>
@@ -70,7 +35,7 @@
     if (JS('bool', '"transition" in document.body.style')) {
       return true;
     }
-    var propertyName = '${_browserPropertyPrefix}Transition';
+    var propertyName = '${Device.propertyPrefix}Transition';
     return JS('bool', '# in document.body.style', propertyName);
   }
 $else
@@ -83,146 +48,146 @@
   // TODO(jacobr): generate this list of properties using the existing script.
   /** Gets the value of "align-content" */
   String get alignContent =>
-    getPropertyValue('${_browserPrefix}align-content');
+    getPropertyValue('${Device.cssPrefix}align-content');
 
   /** Sets the value of "align-content" */
   void set alignContent(String value) {
-    setProperty('${_browserPrefix}align-content', value, '');
+    setProperty('${Device.cssPrefix}align-content', value, '');
   }
 
   /** Gets the value of "align-items" */
   String get alignItems =>
-    getPropertyValue('${_browserPrefix}align-items');
+    getPropertyValue('${Device.cssPrefix}align-items');
 
   /** Sets the value of "align-items" */
   void set alignItems(String value) {
-    setProperty('${_browserPrefix}align-items', value, '');
+    setProperty('${Device.cssPrefix}align-items', value, '');
   }
 
   /** Gets the value of "align-self" */
   String get alignSelf =>
-    getPropertyValue('${_browserPrefix}align-self');
+    getPropertyValue('${Device.cssPrefix}align-self');
 
   /** Sets the value of "align-self" */
   void set alignSelf(String value) {
-    setProperty('${_browserPrefix}align-self', value, '');
+    setProperty('${Device.cssPrefix}align-self', value, '');
   }
 
   /** Gets the value of "animation" */
   String get animation =>
-    getPropertyValue('${_browserPrefix}animation');
+    getPropertyValue('${Device.cssPrefix}animation');
 
   /** Sets the value of "animation" */
   void set animation(String value) {
-    setProperty('${_browserPrefix}animation', value, '');
+    setProperty('${Device.cssPrefix}animation', value, '');
   }
 
   /** Gets the value of "animation-delay" */
   String get animationDelay =>
-    getPropertyValue('${_browserPrefix}animation-delay');
+    getPropertyValue('${Device.cssPrefix}animation-delay');
 
   /** Sets the value of "animation-delay" */
   void set animationDelay(String value) {
-    setProperty('${_browserPrefix}animation-delay', value, '');
+    setProperty('${Device.cssPrefix}animation-delay', value, '');
   }
 
   /** Gets the value of "animation-direction" */
   String get animationDirection =>
-    getPropertyValue('${_browserPrefix}animation-direction');
+    getPropertyValue('${Device.cssPrefix}animation-direction');
 
   /** Sets the value of "animation-direction" */
   void set animationDirection(String value) {
-    setProperty('${_browserPrefix}animation-direction', value, '');
+    setProperty('${Device.cssPrefix}animation-direction', value, '');
   }
 
   /** Gets the value of "animation-duration" */
   String get animationDuration =>
-    getPropertyValue('${_browserPrefix}animation-duration');
+    getPropertyValue('${Device.cssPrefix}animation-duration');
 
   /** Sets the value of "animation-duration" */
   void set animationDuration(String value) {
-    setProperty('${_browserPrefix}animation-duration', value, '');
+    setProperty('${Device.cssPrefix}animation-duration', value, '');
   }
 
   /** Gets the value of "animation-fill-mode" */
   String get animationFillMode =>
-    getPropertyValue('${_browserPrefix}animation-fill-mode');
+    getPropertyValue('${Device.cssPrefix}animation-fill-mode');
 
   /** Sets the value of "animation-fill-mode" */
   void set animationFillMode(String value) {
-    setProperty('${_browserPrefix}animation-fill-mode', value, '');
+    setProperty('${Device.cssPrefix}animation-fill-mode', value, '');
   }
 
   /** Gets the value of "animation-iteration-count" */
   String get animationIterationCount =>
-    getPropertyValue('${_browserPrefix}animation-iteration-count');
+    getPropertyValue('${Device.cssPrefix}animation-iteration-count');
 
   /** Sets the value of "animation-iteration-count" */
   void set animationIterationCount(String value) {
-    setProperty('${_browserPrefix}animation-iteration-count', value, '');
+    setProperty('${Device.cssPrefix}animation-iteration-count', value, '');
   }
 
   /** Gets the value of "animation-name" */
   String get animationName =>
-    getPropertyValue('${_browserPrefix}animation-name');
+    getPropertyValue('${Device.cssPrefix}animation-name');
 
   /** Sets the value of "animation-name" */
   void set animationName(String value) {
-    setProperty('${_browserPrefix}animation-name', value, '');
+    setProperty('${Device.cssPrefix}animation-name', value, '');
   }
 
   /** Gets the value of "animation-play-state" */
   String get animationPlayState =>
-    getPropertyValue('${_browserPrefix}animation-play-state');
+    getPropertyValue('${Device.cssPrefix}animation-play-state');
 
   /** Sets the value of "animation-play-state" */
   void set animationPlayState(String value) {
-    setProperty('${_browserPrefix}animation-play-state', value, '');
+    setProperty('${Device.cssPrefix}animation-play-state', value, '');
   }
 
   /** Gets the value of "animation-timing-function" */
   String get animationTimingFunction =>
-    getPropertyValue('${_browserPrefix}animation-timing-function');
+    getPropertyValue('${Device.cssPrefix}animation-timing-function');
 
   /** Sets the value of "animation-timing-function" */
   void set animationTimingFunction(String value) {
-    setProperty('${_browserPrefix}animation-timing-function', value, '');
+    setProperty('${Device.cssPrefix}animation-timing-function', value, '');
   }
 
   /** Gets the value of "app-region" */
   String get appRegion =>
-    getPropertyValue('${_browserPrefix}app-region');
+    getPropertyValue('${Device.cssPrefix}app-region');
 
   /** Sets the value of "app-region" */
   void set appRegion(String value) {
-    setProperty('${_browserPrefix}app-region', value, '');
+    setProperty('${Device.cssPrefix}app-region', value, '');
   }
 
   /** Gets the value of "appearance" */
   String get appearance =>
-    getPropertyValue('${_browserPrefix}appearance');
+    getPropertyValue('${Device.cssPrefix}appearance');
 
   /** Sets the value of "appearance" */
   void set appearance(String value) {
-    setProperty('${_browserPrefix}appearance', value, '');
+    setProperty('${Device.cssPrefix}appearance', value, '');
   }
 
   /** Gets the value of "aspect-ratio" */
   String get aspectRatio =>
-    getPropertyValue('${_browserPrefix}aspect-ratio');
+    getPropertyValue('${Device.cssPrefix}aspect-ratio');
 
   /** Sets the value of "aspect-ratio" */
   void set aspectRatio(String value) {
-    setProperty('${_browserPrefix}aspect-ratio', value, '');
+    setProperty('${Device.cssPrefix}aspect-ratio', value, '');
   }
 
   /** Gets the value of "backface-visibility" */
   String get backfaceVisibility =>
-    getPropertyValue('${_browserPrefix}backface-visibility');
+    getPropertyValue('${Device.cssPrefix}backface-visibility');
 
   /** Sets the value of "backface-visibility" */
   void set backfaceVisibility(String value) {
-    setProperty('${_browserPrefix}backface-visibility', value, '');
+    setProperty('${Device.cssPrefix}backface-visibility', value, '');
   }
 
   /** Gets the value of "background" */
@@ -263,11 +228,11 @@
 
   /** Gets the value of "background-composite" */
   String get backgroundComposite =>
-    getPropertyValue('${_browserPrefix}background-composite');
+    getPropertyValue('${Device.cssPrefix}background-composite');
 
   /** Sets the value of "background-composite" */
   void set backgroundComposite(String value) {
-    setProperty('${_browserPrefix}background-composite', value, '');
+    setProperty('${Device.cssPrefix}background-composite', value, '');
   }
 
   /** Gets the value of "background-image" */
@@ -353,11 +318,11 @@
 
   /** Gets the value of "blend-mode" */
   String get blendMode =>
-    getPropertyValue('${_browserPrefix}blend-mode');
+    getPropertyValue('${Device.cssPrefix}blend-mode');
 
   /** Sets the value of "blend-mode" */
   void set blendMode(String value) {
-    setProperty('${_browserPrefix}blend-mode', value, '');
+    setProperty('${Device.cssPrefix}blend-mode', value, '');
   }
 
   /** Gets the value of "border" */
@@ -371,74 +336,74 @@
 
   /** Gets the value of "border-after" */
   String get borderAfter =>
-    getPropertyValue('${_browserPrefix}border-after');
+    getPropertyValue('${Device.cssPrefix}border-after');
 
   /** Sets the value of "border-after" */
   void set borderAfter(String value) {
-    setProperty('${_browserPrefix}border-after', value, '');
+    setProperty('${Device.cssPrefix}border-after', value, '');
   }
 
   /** Gets the value of "border-after-color" */
   String get borderAfterColor =>
-    getPropertyValue('${_browserPrefix}border-after-color');
+    getPropertyValue('${Device.cssPrefix}border-after-color');
 
   /** Sets the value of "border-after-color" */
   void set borderAfterColor(String value) {
-    setProperty('${_browserPrefix}border-after-color', value, '');
+    setProperty('${Device.cssPrefix}border-after-color', value, '');
   }
 
   /** Gets the value of "border-after-style" */
   String get borderAfterStyle =>
-    getPropertyValue('${_browserPrefix}border-after-style');
+    getPropertyValue('${Device.cssPrefix}border-after-style');
 
   /** Sets the value of "border-after-style" */
   void set borderAfterStyle(String value) {
-    setProperty('${_browserPrefix}border-after-style', value, '');
+    setProperty('${Device.cssPrefix}border-after-style', value, '');
   }
 
   /** Gets the value of "border-after-width" */
   String get borderAfterWidth =>
-    getPropertyValue('${_browserPrefix}border-after-width');
+    getPropertyValue('${Device.cssPrefix}border-after-width');
 
   /** Sets the value of "border-after-width" */
   void set borderAfterWidth(String value) {
-    setProperty('${_browserPrefix}border-after-width', value, '');
+    setProperty('${Device.cssPrefix}border-after-width', value, '');
   }
 
   /** Gets the value of "border-before" */
   String get borderBefore =>
-    getPropertyValue('${_browserPrefix}border-before');
+    getPropertyValue('${Device.cssPrefix}border-before');
 
   /** Sets the value of "border-before" */
   void set borderBefore(String value) {
-    setProperty('${_browserPrefix}border-before', value, '');
+    setProperty('${Device.cssPrefix}border-before', value, '');
   }
 
   /** Gets the value of "border-before-color" */
   String get borderBeforeColor =>
-    getPropertyValue('${_browserPrefix}border-before-color');
+    getPropertyValue('${Device.cssPrefix}border-before-color');
 
   /** Sets the value of "border-before-color" */
   void set borderBeforeColor(String value) {
-    setProperty('${_browserPrefix}border-before-color', value, '');
+    setProperty('${Device.cssPrefix}border-before-color', value, '');
   }
 
   /** Gets the value of "border-before-style" */
   String get borderBeforeStyle =>
-    getPropertyValue('${_browserPrefix}border-before-style');
+    getPropertyValue('${Device.cssPrefix}border-before-style');
 
   /** Sets the value of "border-before-style" */
   void set borderBeforeStyle(String value) {
-    setProperty('${_browserPrefix}border-before-style', value, '');
+    setProperty('${Device.cssPrefix}border-before-style', value, '');
   }
 
   /** Gets the value of "border-before-width" */
   String get borderBeforeWidth =>
-    getPropertyValue('${_browserPrefix}border-before-width');
+    getPropertyValue('${Device.cssPrefix}border-before-width');
 
   /** Sets the value of "border-before-width" */
   void set borderBeforeWidth(String value) {
-    setProperty('${_browserPrefix}border-before-width', value, '');
+    setProperty('${Device.cssPrefix}border-before-width', value, '');
   }
 
   /** Gets the value of "border-bottom" */
@@ -515,56 +480,56 @@
 
   /** Gets the value of "border-end" */
   String get borderEnd =>
-    getPropertyValue('${_browserPrefix}border-end');
+    getPropertyValue('${Device.cssPrefix}border-end');
 
   /** Sets the value of "border-end" */
   void set borderEnd(String value) {
-    setProperty('${_browserPrefix}border-end', value, '');
+    setProperty('${Device.cssPrefix}border-end', value, '');
   }
 
   /** Gets the value of "border-end-color" */
   String get borderEndColor =>
-    getPropertyValue('${_browserPrefix}border-end-color');
+    getPropertyValue('${Device.cssPrefix}border-end-color');
 
   /** Sets the value of "border-end-color" */
   void set borderEndColor(String value) {
-    setProperty('${_browserPrefix}border-end-color', value, '');
+    setProperty('${Device.cssPrefix}border-end-color', value, '');
   }
 
   /** Gets the value of "border-end-style" */
   String get borderEndStyle =>
-    getPropertyValue('${_browserPrefix}border-end-style');
+    getPropertyValue('${Device.cssPrefix}border-end-style');
 
   /** Sets the value of "border-end-style" */
   void set borderEndStyle(String value) {
-    setProperty('${_browserPrefix}border-end-style', value, '');
+    setProperty('${Device.cssPrefix}border-end-style', value, '');
   }
 
   /** Gets the value of "border-end-width" */
   String get borderEndWidth =>
-    getPropertyValue('${_browserPrefix}border-end-width');
+    getPropertyValue('${Device.cssPrefix}border-end-width');
 
   /** Sets the value of "border-end-width" */
   void set borderEndWidth(String value) {
-    setProperty('${_browserPrefix}border-end-width', value, '');
+    setProperty('${Device.cssPrefix}border-end-width', value, '');
   }
 
   /** Gets the value of "border-fit" */
   String get borderFit =>
-    getPropertyValue('${_browserPrefix}border-fit');
+    getPropertyValue('${Device.cssPrefix}border-fit');
 
   /** Sets the value of "border-fit" */
   void set borderFit(String value) {
-    setProperty('${_browserPrefix}border-fit', value, '');
+    setProperty('${Device.cssPrefix}border-fit', value, '');
   }
 
   /** Gets the value of "border-horizontal-spacing" */
   String get borderHorizontalSpacing =>
-    getPropertyValue('${_browserPrefix}border-horizontal-spacing');
+    getPropertyValue('${Device.cssPrefix}border-horizontal-spacing');
 
   /** Sets the value of "border-horizontal-spacing" */
   void set borderHorizontalSpacing(String value) {
-    setProperty('${_browserPrefix}border-horizontal-spacing', value, '');
+    setProperty('${Device.cssPrefix}border-horizontal-spacing', value, '');
   }
 
   /** Gets the value of "border-image" */
@@ -713,38 +678,38 @@
 
   /** Gets the value of "border-start" */
   String get borderStart =>
-    getPropertyValue('${_browserPrefix}border-start');
+    getPropertyValue('${Device.cssPrefix}border-start');
 
   /** Sets the value of "border-start" */
   void set borderStart(String value) {
-    setProperty('${_browserPrefix}border-start', value, '');
+    setProperty('${Device.cssPrefix}border-start', value, '');
   }
 
   /** Gets the value of "border-start-color" */
   String get borderStartColor =>
-    getPropertyValue('${_browserPrefix}border-start-color');
+    getPropertyValue('${Device.cssPrefix}border-start-color');
 
   /** Sets the value of "border-start-color" */
   void set borderStartColor(String value) {
-    setProperty('${_browserPrefix}border-start-color', value, '');
+    setProperty('${Device.cssPrefix}border-start-color', value, '');
   }
 
   /** Gets the value of "border-start-style" */
   String get borderStartStyle =>
-    getPropertyValue('${_browserPrefix}border-start-style');
+    getPropertyValue('${Device.cssPrefix}border-start-style');
 
   /** Sets the value of "border-start-style" */
   void set borderStartStyle(String value) {
-    setProperty('${_browserPrefix}border-start-style', value, '');
+    setProperty('${Device.cssPrefix}border-start-style', value, '');
   }
 
   /** Gets the value of "border-start-width" */
   String get borderStartWidth =>
-    getPropertyValue('${_browserPrefix}border-start-width');
+    getPropertyValue('${Device.cssPrefix}border-start-width');
 
   /** Sets the value of "border-start-width" */
   void set borderStartWidth(String value) {
-    setProperty('${_browserPrefix}border-start-width', value, '');
+    setProperty('${Device.cssPrefix}border-start-width', value, '');
   }
 
   /** Gets the value of "border-style" */
@@ -812,11 +777,11 @@
 
   /** Gets the value of "border-vertical-spacing" */
   String get borderVerticalSpacing =>
-    getPropertyValue('${_browserPrefix}border-vertical-spacing');
+    getPropertyValue('${Device.cssPrefix}border-vertical-spacing');
 
   /** Sets the value of "border-vertical-spacing" */
   void set borderVerticalSpacing(String value) {
-    setProperty('${_browserPrefix}border-vertical-spacing', value, '');
+    setProperty('${Device.cssPrefix}border-vertical-spacing', value, '');
   }
 
   /** Gets the value of "border-width" */
@@ -839,92 +804,92 @@
 
   /** Gets the value of "box-align" */
   String get boxAlign =>
-    getPropertyValue('${_browserPrefix}box-align');
+    getPropertyValue('${Device.cssPrefix}box-align');
 
   /** Sets the value of "box-align" */
   void set boxAlign(String value) {
-    setProperty('${_browserPrefix}box-align', value, '');
+    setProperty('${Device.cssPrefix}box-align', value, '');
   }
 
   /** Gets the value of "box-decoration-break" */
   String get boxDecorationBreak =>
-    getPropertyValue('${_browserPrefix}box-decoration-break');
+    getPropertyValue('${Device.cssPrefix}box-decoration-break');
 
   /** Sets the value of "box-decoration-break" */
   void set boxDecorationBreak(String value) {
-    setProperty('${_browserPrefix}box-decoration-break', value, '');
+    setProperty('${Device.cssPrefix}box-decoration-break', value, '');
   }
 
   /** Gets the value of "box-direction" */
   String get boxDirection =>
-    getPropertyValue('${_browserPrefix}box-direction');
+    getPropertyValue('${Device.cssPrefix}box-direction');
 
   /** Sets the value of "box-direction" */
   void set boxDirection(String value) {
-    setProperty('${_browserPrefix}box-direction', value, '');
+    setProperty('${Device.cssPrefix}box-direction', value, '');
   }
 
   /** Gets the value of "box-flex" */
   String get boxFlex =>
-    getPropertyValue('${_browserPrefix}box-flex');
+    getPropertyValue('${Device.cssPrefix}box-flex');
 
   /** Sets the value of "box-flex" */
   void set boxFlex(String value) {
-    setProperty('${_browserPrefix}box-flex', value, '');
+    setProperty('${Device.cssPrefix}box-flex', value, '');
   }
 
   /** Gets the value of "box-flex-group" */
   String get boxFlexGroup =>
-    getPropertyValue('${_browserPrefix}box-flex-group');
+    getPropertyValue('${Device.cssPrefix}box-flex-group');
 
   /** Sets the value of "box-flex-group" */
   void set boxFlexGroup(String value) {
-    setProperty('${_browserPrefix}box-flex-group', value, '');
+    setProperty('${Device.cssPrefix}box-flex-group', value, '');
   }
 
   /** Gets the value of "box-lines" */
   String get boxLines =>
-    getPropertyValue('${_browserPrefix}box-lines');
+    getPropertyValue('${Device.cssPrefix}box-lines');
 
   /** Sets the value of "box-lines" */
   void set boxLines(String value) {
-    setProperty('${_browserPrefix}box-lines', value, '');
+    setProperty('${Device.cssPrefix}box-lines', value, '');
   }
 
   /** Gets the value of "box-ordinal-group" */
   String get boxOrdinalGroup =>
-    getPropertyValue('${_browserPrefix}box-ordinal-group');
+    getPropertyValue('${Device.cssPrefix}box-ordinal-group');
 
   /** Sets the value of "box-ordinal-group" */
   void set boxOrdinalGroup(String value) {
-    setProperty('${_browserPrefix}box-ordinal-group', value, '');
+    setProperty('${Device.cssPrefix}box-ordinal-group', value, '');
   }
 
   /** Gets the value of "box-orient" */
   String get boxOrient =>
-    getPropertyValue('${_browserPrefix}box-orient');
+    getPropertyValue('${Device.cssPrefix}box-orient');
 
   /** Sets the value of "box-orient" */
   void set boxOrient(String value) {
-    setProperty('${_browserPrefix}box-orient', value, '');
+    setProperty('${Device.cssPrefix}box-orient', value, '');
   }
 
   /** Gets the value of "box-pack" */
   String get boxPack =>
-    getPropertyValue('${_browserPrefix}box-pack');
+    getPropertyValue('${Device.cssPrefix}box-pack');
 
   /** Sets the value of "box-pack" */
   void set boxPack(String value) {
-    setProperty('${_browserPrefix}box-pack', value, '');
+    setProperty('${Device.cssPrefix}box-pack', value, '');
   }
 
   /** Gets the value of "box-reflect" */
   String get boxReflect =>
-    getPropertyValue('${_browserPrefix}box-reflect');
+    getPropertyValue('${Device.cssPrefix}box-reflect');
 
   /** Sets the value of "box-reflect" */
   void set boxReflect(String value) {
-    setProperty('${_browserPrefix}box-reflect', value, '');
+    setProperty('${Device.cssPrefix}box-reflect', value, '');
   }
 
   /** Gets the value of "box-shadow" */
@@ -974,11 +939,11 @@
 
   /** Gets the value of "clip-path" */
   String get clipPath =>
-    getPropertyValue('${_browserPrefix}clip-path');
+    getPropertyValue('${Device.cssPrefix}clip-path');
 
   /** Sets the value of "clip-path" */
   void set clipPath(String value) {
-    setProperty('${_browserPrefix}clip-path', value, '');
+    setProperty('${Device.cssPrefix}clip-path', value, '');
   }
 
   /** Gets the value of "color" */
@@ -992,137 +957,137 @@
 
   /** Gets the value of "color-correction" */
   String get colorCorrection =>
-    getPropertyValue('${_browserPrefix}color-correction');
+    getPropertyValue('${Device.cssPrefix}color-correction');
 
   /** Sets the value of "color-correction" */
   void set colorCorrection(String value) {
-    setProperty('${_browserPrefix}color-correction', value, '');
+    setProperty('${Device.cssPrefix}color-correction', value, '');
   }
 
   /** Gets the value of "column-axis" */
   String get columnAxis =>
-    getPropertyValue('${_browserPrefix}column-axis');
+    getPropertyValue('${Device.cssPrefix}column-axis');
 
   /** Sets the value of "column-axis" */
   void set columnAxis(String value) {
-    setProperty('${_browserPrefix}column-axis', value, '');
+    setProperty('${Device.cssPrefix}column-axis', value, '');
   }
 
   /** Gets the value of "column-break-after" */
   String get columnBreakAfter =>
-    getPropertyValue('${_browserPrefix}column-break-after');
+    getPropertyValue('${Device.cssPrefix}column-break-after');
 
   /** Sets the value of "column-break-after" */
   void set columnBreakAfter(String value) {
-    setProperty('${_browserPrefix}column-break-after', value, '');
+    setProperty('${Device.cssPrefix}column-break-after', value, '');
   }
 
   /** Gets the value of "column-break-before" */
   String get columnBreakBefore =>
-    getPropertyValue('${_browserPrefix}column-break-before');
+    getPropertyValue('${Device.cssPrefix}column-break-before');
 
   /** Sets the value of "column-break-before" */
   void set columnBreakBefore(String value) {
-    setProperty('${_browserPrefix}column-break-before', value, '');
+    setProperty('${Device.cssPrefix}column-break-before', value, '');
   }
 
   /** Gets the value of "column-break-inside" */
   String get columnBreakInside =>
-    getPropertyValue('${_browserPrefix}column-break-inside');
+    getPropertyValue('${Device.cssPrefix}column-break-inside');
 
   /** Sets the value of "column-break-inside" */
   void set columnBreakInside(String value) {
-    setProperty('${_browserPrefix}column-break-inside', value, '');
+    setProperty('${Device.cssPrefix}column-break-inside', value, '');
   }
 
   /** Gets the value of "column-count" */
   String get columnCount =>
-    getPropertyValue('${_browserPrefix}column-count');
+    getPropertyValue('${Device.cssPrefix}column-count');
 
   /** Sets the value of "column-count" */
   void set columnCount(String value) {
-    setProperty('${_browserPrefix}column-count', value, '');
+    setProperty('${Device.cssPrefix}column-count', value, '');
   }
 
   /** Gets the value of "column-gap" */
   String get columnGap =>
-    getPropertyValue('${_browserPrefix}column-gap');
+    getPropertyValue('${Device.cssPrefix}column-gap');
 
   /** Sets the value of "column-gap" */
   void set columnGap(String value) {
-    setProperty('${_browserPrefix}column-gap', value, '');
+    setProperty('${Device.cssPrefix}column-gap', value, '');
   }
 
   /** Gets the value of "column-progression" */
   String get columnProgression =>
-    getPropertyValue('${_browserPrefix}column-progression');
+    getPropertyValue('${Device.cssPrefix}column-progression');
 
   /** Sets the value of "column-progression" */
   void set columnProgression(String value) {
-    setProperty('${_browserPrefix}column-progression', value, '');
+    setProperty('${Device.cssPrefix}column-progression', value, '');
   }
 
   /** Gets the value of "column-rule" */
   String get columnRule =>
-    getPropertyValue('${_browserPrefix}column-rule');
+    getPropertyValue('${Device.cssPrefix}column-rule');
 
   /** Sets the value of "column-rule" */
   void set columnRule(String value) {
-    setProperty('${_browserPrefix}column-rule', value, '');
+    setProperty('${Device.cssPrefix}column-rule', value, '');
   }
 
   /** Gets the value of "column-rule-color" */
   String get columnRuleColor =>
-    getPropertyValue('${_browserPrefix}column-rule-color');
+    getPropertyValue('${Device.cssPrefix}column-rule-color');
 
   /** Sets the value of "column-rule-color" */
   void set columnRuleColor(String value) {
-    setProperty('${_browserPrefix}column-rule-color', value, '');
+    setProperty('${Device.cssPrefix}column-rule-color', value, '');
   }
 
   /** Gets the value of "column-rule-style" */
   String get columnRuleStyle =>
-    getPropertyValue('${_browserPrefix}column-rule-style');
+    getPropertyValue('${Device.cssPrefix}column-rule-style');
 
   /** Sets the value of "column-rule-style" */
   void set columnRuleStyle(String value) {
-    setProperty('${_browserPrefix}column-rule-style', value, '');
+    setProperty('${Device.cssPrefix}column-rule-style', value, '');
   }
 
   /** Gets the value of "column-rule-width" */
   String get columnRuleWidth =>
-    getPropertyValue('${_browserPrefix}column-rule-width');
+    getPropertyValue('${Device.cssPrefix}column-rule-width');
 
   /** Sets the value of "column-rule-width" */
   void set columnRuleWidth(String value) {
-    setProperty('${_browserPrefix}column-rule-width', value, '');
+    setProperty('${Device.cssPrefix}column-rule-width', value, '');
   }
 
   /** Gets the value of "column-span" */
   String get columnSpan =>
-    getPropertyValue('${_browserPrefix}column-span');
+    getPropertyValue('${Device.cssPrefix}column-span');
 
   /** Sets the value of "column-span" */
   void set columnSpan(String value) {
-    setProperty('${_browserPrefix}column-span', value, '');
+    setProperty('${Device.cssPrefix}column-span', value, '');
   }
 
   /** Gets the value of "column-width" */
   String get columnWidth =>
-    getPropertyValue('${_browserPrefix}column-width');
+    getPropertyValue('${Device.cssPrefix}column-width');
 
   /** Sets the value of "column-width" */
   void set columnWidth(String value) {
-    setProperty('${_browserPrefix}column-width', value, '');
+    setProperty('${Device.cssPrefix}column-width', value, '');
   }
 
   /** Gets the value of "columns" */
   String get columns =>
-    getPropertyValue('${_browserPrefix}columns');
+    getPropertyValue('${Device.cssPrefix}columns');
 
   /** Sets the value of "columns" */
   void set columns(String value) {
-    setProperty('${_browserPrefix}columns', value, '');
+    setProperty('${Device.cssPrefix}columns', value, '');
   }
 
   /** Gets the value of "content" */
@@ -1163,11 +1128,11 @@
 
   /** Gets the value of "dashboard-region" */
   String get dashboardRegion =>
-    getPropertyValue('${_browserPrefix}dashboard-region');
+    getPropertyValue('${Device.cssPrefix}dashboard-region');
 
   /** Sets the value of "dashboard-region" */
   void set dashboardRegion(String value) {
-    setProperty('${_browserPrefix}dashboard-region', value, '');
+    setProperty('${Device.cssPrefix}dashboard-region', value, '');
   }
 
   /** Gets the value of "direction" */
@@ -1199,74 +1164,74 @@
 
   /** Gets the value of "filter" */
   String get filter =>
-    getPropertyValue('${_browserPrefix}filter');
+    getPropertyValue('${Device.cssPrefix}filter');
 
   /** Sets the value of "filter" */
   void set filter(String value) {
-    setProperty('${_browserPrefix}filter', value, '');
+    setProperty('${Device.cssPrefix}filter', value, '');
   }
 
   /** Gets the value of "flex" */
   String get flex =>
-    getPropertyValue('${_browserPrefix}flex');
+    getPropertyValue('${Device.cssPrefix}flex');
 
   /** Sets the value of "flex" */
   void set flex(String value) {
-    setProperty('${_browserPrefix}flex', value, '');
+    setProperty('${Device.cssPrefix}flex', value, '');
   }
 
   /** Gets the value of "flex-basis" */
   String get flexBasis =>
-    getPropertyValue('${_browserPrefix}flex-basis');
+    getPropertyValue('${Device.cssPrefix}flex-basis');
 
   /** Sets the value of "flex-basis" */
   void set flexBasis(String value) {
-    setProperty('${_browserPrefix}flex-basis', value, '');
+    setProperty('${Device.cssPrefix}flex-basis', value, '');
   }
 
   /** Gets the value of "flex-direction" */
   String get flexDirection =>
-    getPropertyValue('${_browserPrefix}flex-direction');
+    getPropertyValue('${Device.cssPrefix}flex-direction');
 
   /** Sets the value of "flex-direction" */
   void set flexDirection(String value) {
-    setProperty('${_browserPrefix}flex-direction', value, '');
+    setProperty('${Device.cssPrefix}flex-direction', value, '');
   }
 
   /** Gets the value of "flex-flow" */
   String get flexFlow =>
-    getPropertyValue('${_browserPrefix}flex-flow');
+    getPropertyValue('${Device.cssPrefix}flex-flow');
 
   /** Sets the value of "flex-flow" */
   void set flexFlow(String value) {
-    setProperty('${_browserPrefix}flex-flow', value, '');
+    setProperty('${Device.cssPrefix}flex-flow', value, '');
   }
 
   /** Gets the value of "flex-grow" */
   String get flexGrow =>
-    getPropertyValue('${_browserPrefix}flex-grow');
+    getPropertyValue('${Device.cssPrefix}flex-grow');
 
   /** Sets the value of "flex-grow" */
   void set flexGrow(String value) {
-    setProperty('${_browserPrefix}flex-grow', value, '');
+    setProperty('${Device.cssPrefix}flex-grow', value, '');
   }
 
   /** Gets the value of "flex-shrink" */
   String get flexShrink =>
-    getPropertyValue('${_browserPrefix}flex-shrink');
+    getPropertyValue('${Device.cssPrefix}flex-shrink');
 
   /** Sets the value of "flex-shrink" */
   void set flexShrink(String value) {
-    setProperty('${_browserPrefix}flex-shrink', value, '');
+    setProperty('${Device.cssPrefix}flex-shrink', value, '');
   }
 
   /** Gets the value of "flex-wrap" */
   String get flexWrap =>
-    getPropertyValue('${_browserPrefix}flex-wrap');
+    getPropertyValue('${Device.cssPrefix}flex-wrap');
 
   /** Sets the value of "flex-wrap" */
   void set flexWrap(String value) {
-    setProperty('${_browserPrefix}flex-wrap', value, '');
+    setProperty('${Device.cssPrefix}flex-wrap', value, '');
   }
 
   /** Gets the value of "float" */
@@ -1280,20 +1245,20 @@
 
   /** Gets the value of "flow-from" */
   String get flowFrom =>
-    getPropertyValue('${_browserPrefix}flow-from');
+    getPropertyValue('${Device.cssPrefix}flow-from');
 
   /** Sets the value of "flow-from" */
   void set flowFrom(String value) {
-    setProperty('${_browserPrefix}flow-from', value, '');
+    setProperty('${Device.cssPrefix}flow-from', value, '');
   }
 
   /** Gets the value of "flow-into" */
   String get flowInto =>
-    getPropertyValue('${_browserPrefix}flow-into');
+    getPropertyValue('${Device.cssPrefix}flow-into');
 
   /** Sets the value of "flow-into" */
   void set flowInto(String value) {
-    setProperty('${_browserPrefix}flow-into', value, '');
+    setProperty('${Device.cssPrefix}flow-into', value, '');
   }
 
   /** Gets the value of "font" */
@@ -1316,20 +1281,20 @@
 
   /** Gets the value of "font-feature-settings" */
   String get fontFeatureSettings =>
-    getPropertyValue('${_browserPrefix}font-feature-settings');
+    getPropertyValue('${Device.cssPrefix}font-feature-settings');
 
   /** Sets the value of "font-feature-settings" */
   void set fontFeatureSettings(String value) {
-    setProperty('${_browserPrefix}font-feature-settings', value, '');
+    setProperty('${Device.cssPrefix}font-feature-settings', value, '');
   }
 
   /** Gets the value of "font-kerning" */
   String get fontKerning =>
-    getPropertyValue('${_browserPrefix}font-kerning');
+    getPropertyValue('${Device.cssPrefix}font-kerning');
 
   /** Sets the value of "font-kerning" */
   void set fontKerning(String value) {
-    setProperty('${_browserPrefix}font-kerning', value, '');
+    setProperty('${Device.cssPrefix}font-kerning', value, '');
   }
 
   /** Gets the value of "font-size" */
@@ -1343,20 +1308,20 @@
 
   /** Gets the value of "font-size-delta" */
   String get fontSizeDelta =>
-    getPropertyValue('${_browserPrefix}font-size-delta');
+    getPropertyValue('${Device.cssPrefix}font-size-delta');
 
   /** Sets the value of "font-size-delta" */
   void set fontSizeDelta(String value) {
-    setProperty('${_browserPrefix}font-size-delta', value, '');
+    setProperty('${Device.cssPrefix}font-size-delta', value, '');
   }
 
   /** Gets the value of "font-smoothing" */
   String get fontSmoothing =>
-    getPropertyValue('${_browserPrefix}font-smoothing');
+    getPropertyValue('${Device.cssPrefix}font-smoothing');
 
   /** Sets the value of "font-smoothing" */
   void set fontSmoothing(String value) {
-    setProperty('${_browserPrefix}font-smoothing', value, '');
+    setProperty('${Device.cssPrefix}font-smoothing', value, '');
   }
 
   /** Gets the value of "font-stretch" */
@@ -1388,11 +1353,11 @@
 
   /** Gets the value of "font-variant-ligatures" */
   String get fontVariantLigatures =>
-    getPropertyValue('${_browserPrefix}font-variant-ligatures');
+    getPropertyValue('${Device.cssPrefix}font-variant-ligatures');
 
   /** Sets the value of "font-variant-ligatures" */
   void set fontVariantLigatures(String value) {
-    setProperty('${_browserPrefix}font-variant-ligatures', value, '');
+    setProperty('${Device.cssPrefix}font-variant-ligatures', value, '');
   }
 
   /** Gets the value of "font-weight" */
@@ -1406,38 +1371,38 @@
 
   /** Gets the value of "grid-column" */
   String get gridColumn =>
-    getPropertyValue('${_browserPrefix}grid-column');
+    getPropertyValue('${Device.cssPrefix}grid-column');
 
   /** Sets the value of "grid-column" */
   void set gridColumn(String value) {
-    setProperty('${_browserPrefix}grid-column', value, '');
+    setProperty('${Device.cssPrefix}grid-column', value, '');
   }
 
   /** Gets the value of "grid-columns" */
   String get gridColumns =>
-    getPropertyValue('${_browserPrefix}grid-columns');
+    getPropertyValue('${Device.cssPrefix}grid-columns');
 
   /** Sets the value of "grid-columns" */
   void set gridColumns(String value) {
-    setProperty('${_browserPrefix}grid-columns', value, '');
+    setProperty('${Device.cssPrefix}grid-columns', value, '');
   }
 
   /** Gets the value of "grid-row" */
   String get gridRow =>
-    getPropertyValue('${_browserPrefix}grid-row');
+    getPropertyValue('${Device.cssPrefix}grid-row');
 
   /** Sets the value of "grid-row" */
   void set gridRow(String value) {
-    setProperty('${_browserPrefix}grid-row', value, '');
+    setProperty('${Device.cssPrefix}grid-row', value, '');
   }
 
   /** Gets the value of "grid-rows" */
   String get gridRows =>
-    getPropertyValue('${_browserPrefix}grid-rows');
+    getPropertyValue('${Device.cssPrefix}grid-rows');
 
   /** Sets the value of "grid-rows" */
   void set gridRows(String value) {
-    setProperty('${_browserPrefix}grid-rows', value, '');
+    setProperty('${Device.cssPrefix}grid-rows', value, '');
   }
 
   /** Gets the value of "height" */
@@ -1451,56 +1416,56 @@
 
   /** Gets the value of "highlight" */
   String get highlight =>
-    getPropertyValue('${_browserPrefix}highlight');
+    getPropertyValue('${Device.cssPrefix}highlight');
 
   /** Sets the value of "highlight" */
   void set highlight(String value) {
-    setProperty('${_browserPrefix}highlight', value, '');
+    setProperty('${Device.cssPrefix}highlight', value, '');
   }
 
   /** Gets the value of "hyphenate-character" */
   String get hyphenateCharacter =>
-    getPropertyValue('${_browserPrefix}hyphenate-character');
+    getPropertyValue('${Device.cssPrefix}hyphenate-character');
 
   /** Sets the value of "hyphenate-character" */
   void set hyphenateCharacter(String value) {
-    setProperty('${_browserPrefix}hyphenate-character', value, '');
+    setProperty('${Device.cssPrefix}hyphenate-character', value, '');
   }
 
   /** Gets the value of "hyphenate-limit-after" */
   String get hyphenateLimitAfter =>
-    getPropertyValue('${_browserPrefix}hyphenate-limit-after');
+    getPropertyValue('${Device.cssPrefix}hyphenate-limit-after');
 
   /** Sets the value of "hyphenate-limit-after" */
   void set hyphenateLimitAfter(String value) {
-    setProperty('${_browserPrefix}hyphenate-limit-after', value, '');
+    setProperty('${Device.cssPrefix}hyphenate-limit-after', value, '');
   }
 
   /** Gets the value of "hyphenate-limit-before" */
   String get hyphenateLimitBefore =>
-    getPropertyValue('${_browserPrefix}hyphenate-limit-before');
+    getPropertyValue('${Device.cssPrefix}hyphenate-limit-before');
 
   /** Sets the value of "hyphenate-limit-before" */
   void set hyphenateLimitBefore(String value) {
-    setProperty('${_browserPrefix}hyphenate-limit-before', value, '');
+    setProperty('${Device.cssPrefix}hyphenate-limit-before', value, '');
   }
 
   /** Gets the value of "hyphenate-limit-lines" */
   String get hyphenateLimitLines =>
-    getPropertyValue('${_browserPrefix}hyphenate-limit-lines');
+    getPropertyValue('${Device.cssPrefix}hyphenate-limit-lines');
 
   /** Sets the value of "hyphenate-limit-lines" */
   void set hyphenateLimitLines(String value) {
-    setProperty('${_browserPrefix}hyphenate-limit-lines', value, '');
+    setProperty('${Device.cssPrefix}hyphenate-limit-lines', value, '');
   }
 
   /** Gets the value of "hyphens" */
   String get hyphens =>
-    getPropertyValue('${_browserPrefix}hyphens');
+    getPropertyValue('${Device.cssPrefix}hyphens');
 
   /** Sets the value of "hyphens" */
   void set hyphens(String value) {
-    setProperty('${_browserPrefix}hyphens', value, '');
+    setProperty('${Device.cssPrefix}hyphens', value, '');
   }
 
   /** Gets the value of "image-orientation" */
@@ -1532,11 +1497,11 @@
 
   /** Gets the value of "justify-content" */
   String get justifyContent =>
-    getPropertyValue('${_browserPrefix}justify-content');
+    getPropertyValue('${Device.cssPrefix}justify-content');
 
   /** Sets the value of "justify-content" */
   void set justifyContent(String value) {
-    setProperty('${_browserPrefix}justify-content', value, '');
+    setProperty('${Device.cssPrefix}justify-content', value, '');
   }
 
   /** Gets the value of "left" */
@@ -1559,47 +1524,47 @@
 
   /** Gets the value of "line-align" */
   String get lineAlign =>
-    getPropertyValue('${_browserPrefix}line-align');
+    getPropertyValue('${Device.cssPrefix}line-align');
 
   /** Sets the value of "line-align" */
   void set lineAlign(String value) {
-    setProperty('${_browserPrefix}line-align', value, '');
+    setProperty('${Device.cssPrefix}line-align', value, '');
   }
 
   /** Gets the value of "line-box-contain" */
   String get lineBoxContain =>
-    getPropertyValue('${_browserPrefix}line-box-contain');
+    getPropertyValue('${Device.cssPrefix}line-box-contain');
 
   /** Sets the value of "line-box-contain" */
   void set lineBoxContain(String value) {
-    setProperty('${_browserPrefix}line-box-contain', value, '');
+    setProperty('${Device.cssPrefix}line-box-contain', value, '');
   }
 
   /** Gets the value of "line-break" */
   String get lineBreak =>
-    getPropertyValue('${_browserPrefix}line-break');
+    getPropertyValue('${Device.cssPrefix}line-break');
 
   /** Sets the value of "line-break" */
   void set lineBreak(String value) {
-    setProperty('${_browserPrefix}line-break', value, '');
+    setProperty('${Device.cssPrefix}line-break', value, '');
   }
 
   /** Gets the value of "line-clamp" */
   String get lineClamp =>
-    getPropertyValue('${_browserPrefix}line-clamp');
+    getPropertyValue('${Device.cssPrefix}line-clamp');
 
   /** Sets the value of "line-clamp" */
   void set lineClamp(String value) {
-    setProperty('${_browserPrefix}line-clamp', value, '');
+    setProperty('${Device.cssPrefix}line-clamp', value, '');
   }
 
   /** Gets the value of "line-grid" */
   String get lineGrid =>
-    getPropertyValue('${_browserPrefix}line-grid');
+    getPropertyValue('${Device.cssPrefix}line-grid');
 
   /** Sets the value of "line-grid" */
   void set lineGrid(String value) {
-    setProperty('${_browserPrefix}line-grid', value, '');
+    setProperty('${Device.cssPrefix}line-grid', value, '');
   }
 
   /** Gets the value of "line-height" */
@@ -1613,11 +1578,11 @@
 
   /** Gets the value of "line-snap" */
   String get lineSnap =>
-    getPropertyValue('${_browserPrefix}line-snap');
+    getPropertyValue('${Device.cssPrefix}line-snap');
 
   /** Sets the value of "line-snap" */
   void set lineSnap(String value) {
-    setProperty('${_browserPrefix}line-snap', value, '');
+    setProperty('${Device.cssPrefix}line-snap', value, '');
   }
 
   /** Gets the value of "list-style" */
@@ -1658,29 +1623,29 @@
 
   /** Gets the value of "locale" */
   String get locale =>
-    getPropertyValue('${_browserPrefix}locale');
+    getPropertyValue('${Device.cssPrefix}locale');
 
   /** Sets the value of "locale" */
   void set locale(String value) {
-    setProperty('${_browserPrefix}locale', value, '');
+    setProperty('${Device.cssPrefix}locale', value, '');
   }
 
   /** Gets the value of "logical-height" */
   String get logicalHeight =>
-    getPropertyValue('${_browserPrefix}logical-height');
+    getPropertyValue('${Device.cssPrefix}logical-height');
 
   /** Sets the value of "logical-height" */
   void set logicalHeight(String value) {
-    setProperty('${_browserPrefix}logical-height', value, '');
+    setProperty('${Device.cssPrefix}logical-height', value, '');
   }
 
   /** Gets the value of "logical-width" */
   String get logicalWidth =>
-    getPropertyValue('${_browserPrefix}logical-width');
+    getPropertyValue('${Device.cssPrefix}logical-width');
 
   /** Sets the value of "logical-width" */
   void set logicalWidth(String value) {
-    setProperty('${_browserPrefix}logical-width', value, '');
+    setProperty('${Device.cssPrefix}logical-width', value, '');
   }
 
   /** Gets the value of "margin" */
@@ -1694,38 +1659,38 @@
 
   /** Gets the value of "margin-after" */
   String get marginAfter =>
-    getPropertyValue('${_browserPrefix}margin-after');
+    getPropertyValue('${Device.cssPrefix}margin-after');
 
   /** Sets the value of "margin-after" */
   void set marginAfter(String value) {
-    setProperty('${_browserPrefix}margin-after', value, '');
+    setProperty('${Device.cssPrefix}margin-after', value, '');
   }
 
   /** Gets the value of "margin-after-collapse" */
   String get marginAfterCollapse =>
-    getPropertyValue('${_browserPrefix}margin-after-collapse');
+    getPropertyValue('${Device.cssPrefix}margin-after-collapse');
 
   /** Sets the value of "margin-after-collapse" */
   void set marginAfterCollapse(String value) {
-    setProperty('${_browserPrefix}margin-after-collapse', value, '');
+    setProperty('${Device.cssPrefix}margin-after-collapse', value, '');
   }
 
   /** Gets the value of "margin-before" */
   String get marginBefore =>
-    getPropertyValue('${_browserPrefix}margin-before');
+    getPropertyValue('${Device.cssPrefix}margin-before');
 
   /** Sets the value of "margin-before" */
   void set marginBefore(String value) {
-    setProperty('${_browserPrefix}margin-before', value, '');
+    setProperty('${Device.cssPrefix}margin-before', value, '');
   }
 
   /** Gets the value of "margin-before-collapse" */
   String get marginBeforeCollapse =>
-    getPropertyValue('${_browserPrefix}margin-before-collapse');
+    getPropertyValue('${Device.cssPrefix}margin-before-collapse');
 
   /** Sets the value of "margin-before-collapse" */
   void set marginBeforeCollapse(String value) {
-    setProperty('${_browserPrefix}margin-before-collapse', value, '');
+    setProperty('${Device.cssPrefix}margin-before-collapse', value, '');
   }
 
   /** Gets the value of "margin-bottom" */
@@ -1739,29 +1704,29 @@
 
   /** Gets the value of "margin-bottom-collapse" */
   String get marginBottomCollapse =>
-    getPropertyValue('${_browserPrefix}margin-bottom-collapse');
+    getPropertyValue('${Device.cssPrefix}margin-bottom-collapse');
 
   /** Sets the value of "margin-bottom-collapse" */
   void set marginBottomCollapse(String value) {
-    setProperty('${_browserPrefix}margin-bottom-collapse', value, '');
+    setProperty('${Device.cssPrefix}margin-bottom-collapse', value, '');
   }
 
   /** Gets the value of "margin-collapse" */
   String get marginCollapse =>
-    getPropertyValue('${_browserPrefix}margin-collapse');
+    getPropertyValue('${Device.cssPrefix}margin-collapse');
 
   /** Sets the value of "margin-collapse" */
   void set marginCollapse(String value) {
-    setProperty('${_browserPrefix}margin-collapse', value, '');
+    setProperty('${Device.cssPrefix}margin-collapse', value, '');
   }
 
   /** Gets the value of "margin-end" */
   String get marginEnd =>
-    getPropertyValue('${_browserPrefix}margin-end');
+    getPropertyValue('${Device.cssPrefix}margin-end');
 
   /** Sets the value of "margin-end" */
   void set marginEnd(String value) {
-    setProperty('${_browserPrefix}margin-end', value, '');
+    setProperty('${Device.cssPrefix}margin-end', value, '');
   }
 
   /** Gets the value of "margin-left" */
@@ -1784,11 +1749,11 @@
 
   /** Gets the value of "margin-start" */
   String get marginStart =>
-    getPropertyValue('${_browserPrefix}margin-start');
+    getPropertyValue('${Device.cssPrefix}margin-start');
 
   /** Sets the value of "margin-start" */
   void set marginStart(String value) {
-    setProperty('${_browserPrefix}margin-start', value, '');
+    setProperty('${Device.cssPrefix}margin-start', value, '');
   }
 
   /** Gets the value of "margin-top" */
@@ -1802,236 +1767,236 @@
 
   /** Gets the value of "margin-top-collapse" */
   String get marginTopCollapse =>
-    getPropertyValue('${_browserPrefix}margin-top-collapse');
+    getPropertyValue('${Device.cssPrefix}margin-top-collapse');
 
   /** Sets the value of "margin-top-collapse" */
   void set marginTopCollapse(String value) {
-    setProperty('${_browserPrefix}margin-top-collapse', value, '');
+    setProperty('${Device.cssPrefix}margin-top-collapse', value, '');
   }
 
   /** Gets the value of "marquee" */
   String get marquee =>
-    getPropertyValue('${_browserPrefix}marquee');
+    getPropertyValue('${Device.cssPrefix}marquee');
 
   /** Sets the value of "marquee" */
   void set marquee(String value) {
-    setProperty('${_browserPrefix}marquee', value, '');
+    setProperty('${Device.cssPrefix}marquee', value, '');
   }
 
   /** Gets the value of "marquee-direction" */
   String get marqueeDirection =>
-    getPropertyValue('${_browserPrefix}marquee-direction');
+    getPropertyValue('${Device.cssPrefix}marquee-direction');
 
   /** Sets the value of "marquee-direction" */
   void set marqueeDirection(String value) {
-    setProperty('${_browserPrefix}marquee-direction', value, '');
+    setProperty('${Device.cssPrefix}marquee-direction', value, '');
   }
 
   /** Gets the value of "marquee-increment" */
   String get marqueeIncrement =>
-    getPropertyValue('${_browserPrefix}marquee-increment');
+    getPropertyValue('${Device.cssPrefix}marquee-increment');
 
   /** Sets the value of "marquee-increment" */
   void set marqueeIncrement(String value) {
-    setProperty('${_browserPrefix}marquee-increment', value, '');
+    setProperty('${Device.cssPrefix}marquee-increment', value, '');
   }
 
   /** Gets the value of "marquee-repetition" */
   String get marqueeRepetition =>
-    getPropertyValue('${_browserPrefix}marquee-repetition');
+    getPropertyValue('${Device.cssPrefix}marquee-repetition');
 
   /** Sets the value of "marquee-repetition" */
   void set marqueeRepetition(String value) {
-    setProperty('${_browserPrefix}marquee-repetition', value, '');
+    setProperty('${Device.cssPrefix}marquee-repetition', value, '');
   }
 
   /** Gets the value of "marquee-speed" */
   String get marqueeSpeed =>
-    getPropertyValue('${_browserPrefix}marquee-speed');
+    getPropertyValue('${Device.cssPrefix}marquee-speed');
 
   /** Sets the value of "marquee-speed" */
   void set marqueeSpeed(String value) {
-    setProperty('${_browserPrefix}marquee-speed', value, '');
+    setProperty('${Device.cssPrefix}marquee-speed', value, '');
   }
 
   /** Gets the value of "marquee-style" */
   String get marqueeStyle =>
-    getPropertyValue('${_browserPrefix}marquee-style');
+    getPropertyValue('${Device.cssPrefix}marquee-style');
 
   /** Sets the value of "marquee-style" */
   void set marqueeStyle(String value) {
-    setProperty('${_browserPrefix}marquee-style', value, '');
+    setProperty('${Device.cssPrefix}marquee-style', value, '');
   }
 
   /** Gets the value of "mask" */
   String get mask =>
-    getPropertyValue('${_browserPrefix}mask');
+    getPropertyValue('${Device.cssPrefix}mask');
 
   /** Sets the value of "mask" */
   void set mask(String value) {
-    setProperty('${_browserPrefix}mask', value, '');
+    setProperty('${Device.cssPrefix}mask', value, '');
   }
 
   /** Gets the value of "mask-attachment" */
   String get maskAttachment =>
-    getPropertyValue('${_browserPrefix}mask-attachment');
+    getPropertyValue('${Device.cssPrefix}mask-attachment');
 
   /** Sets the value of "mask-attachment" */
   void set maskAttachment(String value) {
-    setProperty('${_browserPrefix}mask-attachment', value, '');
+    setProperty('${Device.cssPrefix}mask-attachment', value, '');
   }
 
   /** Gets the value of "mask-box-image" */
   String get maskBoxImage =>
-    getPropertyValue('${_browserPrefix}mask-box-image');
+    getPropertyValue('${Device.cssPrefix}mask-box-image');
 
   /** Sets the value of "mask-box-image" */
   void set maskBoxImage(String value) {
-    setProperty('${_browserPrefix}mask-box-image', value, '');
+    setProperty('${Device.cssPrefix}mask-box-image', value, '');
   }
 
   /** Gets the value of "mask-box-image-outset" */
   String get maskBoxImageOutset =>
-    getPropertyValue('${_browserPrefix}mask-box-image-outset');
+    getPropertyValue('${Device.cssPrefix}mask-box-image-outset');
 
   /** Sets the value of "mask-box-image-outset" */
   void set maskBoxImageOutset(String value) {
-    setProperty('${_browserPrefix}mask-box-image-outset', value, '');
+    setProperty('${Device.cssPrefix}mask-box-image-outset', value, '');
   }
 
   /** Gets the value of "mask-box-image-repeat" */
   String get maskBoxImageRepeat =>
-    getPropertyValue('${_browserPrefix}mask-box-image-repeat');
+    getPropertyValue('${Device.cssPrefix}mask-box-image-repeat');
 
   /** Sets the value of "mask-box-image-repeat" */
   void set maskBoxImageRepeat(String value) {
-    setProperty('${_browserPrefix}mask-box-image-repeat', value, '');
+    setProperty('${Device.cssPrefix}mask-box-image-repeat', value, '');
   }
 
   /** Gets the value of "mask-box-image-slice" */
   String get maskBoxImageSlice =>
-    getPropertyValue('${_browserPrefix}mask-box-image-slice');
+    getPropertyValue('${Device.cssPrefix}mask-box-image-slice');
 
   /** Sets the value of "mask-box-image-slice" */
   void set maskBoxImageSlice(String value) {
-    setProperty('${_browserPrefix}mask-box-image-slice', value, '');
+    setProperty('${Device.cssPrefix}mask-box-image-slice', value, '');
   }
 
   /** Gets the value of "mask-box-image-source" */
   String get maskBoxImageSource =>
-    getPropertyValue('${_browserPrefix}mask-box-image-source');
+    getPropertyValue('${Device.cssPrefix}mask-box-image-source');
 
   /** Sets the value of "mask-box-image-source" */
   void set maskBoxImageSource(String value) {
-    setProperty('${_browserPrefix}mask-box-image-source', value, '');
+    setProperty('${Device.cssPrefix}mask-box-image-source', value, '');
   }
 
   /** Gets the value of "mask-box-image-width" */
   String get maskBoxImageWidth =>
-    getPropertyValue('${_browserPrefix}mask-box-image-width');
+    getPropertyValue('${Device.cssPrefix}mask-box-image-width');
 
   /** Sets the value of "mask-box-image-width" */
   void set maskBoxImageWidth(String value) {
-    setProperty('${_browserPrefix}mask-box-image-width', value, '');
+    setProperty('${Device.cssPrefix}mask-box-image-width', value, '');
   }
 
   /** Gets the value of "mask-clip" */
   String get maskClip =>
-    getPropertyValue('${_browserPrefix}mask-clip');
+    getPropertyValue('${Device.cssPrefix}mask-clip');
 
   /** Sets the value of "mask-clip" */
   void set maskClip(String value) {
-    setProperty('${_browserPrefix}mask-clip', value, '');
+    setProperty('${Device.cssPrefix}mask-clip', value, '');
   }
 
   /** Gets the value of "mask-composite" */
   String get maskComposite =>
-    getPropertyValue('${_browserPrefix}mask-composite');
+    getPropertyValue('${Device.cssPrefix}mask-composite');
 
   /** Sets the value of "mask-composite" */
   void set maskComposite(String value) {
-    setProperty('${_browserPrefix}mask-composite', value, '');
+    setProperty('${Device.cssPrefix}mask-composite', value, '');
   }
 
   /** Gets the value of "mask-image" */
   String get maskImage =>
-    getPropertyValue('${_browserPrefix}mask-image');
+    getPropertyValue('${Device.cssPrefix}mask-image');
 
   /** Sets the value of "mask-image" */
   void set maskImage(String value) {
-    setProperty('${_browserPrefix}mask-image', value, '');
+    setProperty('${Device.cssPrefix}mask-image', value, '');
   }
 
   /** Gets the value of "mask-origin" */
   String get maskOrigin =>
-    getPropertyValue('${_browserPrefix}mask-origin');
+    getPropertyValue('${Device.cssPrefix}mask-origin');
 
   /** Sets the value of "mask-origin" */
   void set maskOrigin(String value) {
-    setProperty('${_browserPrefix}mask-origin', value, '');
+    setProperty('${Device.cssPrefix}mask-origin', value, '');
   }
 
   /** Gets the value of "mask-position" */
   String get maskPosition =>
-    getPropertyValue('${_browserPrefix}mask-position');
+    getPropertyValue('${Device.cssPrefix}mask-position');
 
   /** Sets the value of "mask-position" */
   void set maskPosition(String value) {
-    setProperty('${_browserPrefix}mask-position', value, '');
+    setProperty('${Device.cssPrefix}mask-position', value, '');
   }
 
   /** Gets the value of "mask-position-x" */
   String get maskPositionX =>
-    getPropertyValue('${_browserPrefix}mask-position-x');
+    getPropertyValue('${Device.cssPrefix}mask-position-x');
 
   /** Sets the value of "mask-position-x" */
   void set maskPositionX(String value) {
-    setProperty('${_browserPrefix}mask-position-x', value, '');
+    setProperty('${Device.cssPrefix}mask-position-x', value, '');
   }
 
   /** Gets the value of "mask-position-y" */
   String get maskPositionY =>
-    getPropertyValue('${_browserPrefix}mask-position-y');
+    getPropertyValue('${Device.cssPrefix}mask-position-y');
 
   /** Sets the value of "mask-position-y" */
   void set maskPositionY(String value) {
-    setProperty('${_browserPrefix}mask-position-y', value, '');
+    setProperty('${Device.cssPrefix}mask-position-y', value, '');
   }
 
   /** Gets the value of "mask-repeat" */
   String get maskRepeat =>
-    getPropertyValue('${_browserPrefix}mask-repeat');
+    getPropertyValue('${Device.cssPrefix}mask-repeat');
 
   /** Sets the value of "mask-repeat" */
   void set maskRepeat(String value) {
-    setProperty('${_browserPrefix}mask-repeat', value, '');
+    setProperty('${Device.cssPrefix}mask-repeat', value, '');
   }
 
   /** Gets the value of "mask-repeat-x" */
   String get maskRepeatX =>
-    getPropertyValue('${_browserPrefix}mask-repeat-x');
+    getPropertyValue('${Device.cssPrefix}mask-repeat-x');
 
   /** Sets the value of "mask-repeat-x" */
   void set maskRepeatX(String value) {
-    setProperty('${_browserPrefix}mask-repeat-x', value, '');
+    setProperty('${Device.cssPrefix}mask-repeat-x', value, '');
   }
 
   /** Gets the value of "mask-repeat-y" */
   String get maskRepeatY =>
-    getPropertyValue('${_browserPrefix}mask-repeat-y');
+    getPropertyValue('${Device.cssPrefix}mask-repeat-y');
 
   /** Sets the value of "mask-repeat-y" */
   void set maskRepeatY(String value) {
-    setProperty('${_browserPrefix}mask-repeat-y', value, '');
+    setProperty('${Device.cssPrefix}mask-repeat-y', value, '');
   }
 
   /** Gets the value of "mask-size" */
   String get maskSize =>
-    getPropertyValue('${_browserPrefix}mask-size');
+    getPropertyValue('${Device.cssPrefix}mask-size');
 
   /** Sets the value of "mask-size" */
   void set maskSize(String value) {
-    setProperty('${_browserPrefix}mask-size', value, '');
+    setProperty('${Device.cssPrefix}mask-size', value, '');
   }
 
   /** Gets the value of "max-height" */
@@ -2045,20 +2010,20 @@
 
   /** Gets the value of "max-logical-height" */
   String get maxLogicalHeight =>
-    getPropertyValue('${_browserPrefix}max-logical-height');
+    getPropertyValue('${Device.cssPrefix}max-logical-height');
 
   /** Sets the value of "max-logical-height" */
   void set maxLogicalHeight(String value) {
-    setProperty('${_browserPrefix}max-logical-height', value, '');
+    setProperty('${Device.cssPrefix}max-logical-height', value, '');
   }
 
   /** Gets the value of "max-logical-width" */
   String get maxLogicalWidth =>
-    getPropertyValue('${_browserPrefix}max-logical-width');
+    getPropertyValue('${Device.cssPrefix}max-logical-width');
 
   /** Sets the value of "max-logical-width" */
   void set maxLogicalWidth(String value) {
-    setProperty('${_browserPrefix}max-logical-width', value, '');
+    setProperty('${Device.cssPrefix}max-logical-width', value, '');
   }
 
   /** Gets the value of "max-width" */
@@ -2090,20 +2055,20 @@
 
   /** Gets the value of "min-logical-height" */
   String get minLogicalHeight =>
-    getPropertyValue('${_browserPrefix}min-logical-height');
+    getPropertyValue('${Device.cssPrefix}min-logical-height');
 
   /** Sets the value of "min-logical-height" */
   void set minLogicalHeight(String value) {
-    setProperty('${_browserPrefix}min-logical-height', value, '');
+    setProperty('${Device.cssPrefix}min-logical-height', value, '');
   }
 
   /** Gets the value of "min-logical-width" */
   String get minLogicalWidth =>
-    getPropertyValue('${_browserPrefix}min-logical-width');
+    getPropertyValue('${Device.cssPrefix}min-logical-width');
 
   /** Sets the value of "min-logical-width" */
   void set minLogicalWidth(String value) {
-    setProperty('${_browserPrefix}min-logical-width', value, '');
+    setProperty('${Device.cssPrefix}min-logical-width', value, '');
   }
 
   /** Gets the value of "min-width" */
@@ -2126,11 +2091,11 @@
 
   /** Gets the value of "nbsp-mode" */
   String get nbspMode =>
-    getPropertyValue('${_browserPrefix}nbsp-mode');
+    getPropertyValue('${Device.cssPrefix}nbsp-mode');
 
   /** Sets the value of "nbsp-mode" */
   void set nbspMode(String value) {
-    setProperty('${_browserPrefix}nbsp-mode', value, '');
+    setProperty('${Device.cssPrefix}nbsp-mode', value, '');
   }
 
   /** Gets the value of "opacity" */
@@ -2144,11 +2109,11 @@
 
   /** Gets the value of "order" */
   String get order =>
-    getPropertyValue('${_browserPrefix}order');
+    getPropertyValue('${Device.cssPrefix}order');
 
   /** Sets the value of "order" */
   void set order(String value) {
-    setProperty('${_browserPrefix}order', value, '');
+    setProperty('${Device.cssPrefix}order', value, '');
   }
 
   /** Gets the value of "orientation" */
@@ -2225,11 +2190,11 @@
 
   /** Gets the value of "overflow-scrolling" */
   String get overflowScrolling =>
-    getPropertyValue('${_browserPrefix}overflow-scrolling');
+    getPropertyValue('${Device.cssPrefix}overflow-scrolling');
 
   /** Sets the value of "overflow-scrolling" */
   void set overflowScrolling(String value) {
-    setProperty('${_browserPrefix}overflow-scrolling', value, '');
+    setProperty('${Device.cssPrefix}overflow-scrolling', value, '');
   }
 
   /** Gets the value of "overflow-wrap" */
@@ -2270,20 +2235,20 @@
 
   /** Gets the value of "padding-after" */
   String get paddingAfter =>
-    getPropertyValue('${_browserPrefix}padding-after');
+    getPropertyValue('${Device.cssPrefix}padding-after');
 
   /** Sets the value of "padding-after" */
   void set paddingAfter(String value) {
-    setProperty('${_browserPrefix}padding-after', value, '');
+    setProperty('${Device.cssPrefix}padding-after', value, '');
   }
 
   /** Gets the value of "padding-before" */
   String get paddingBefore =>
-    getPropertyValue('${_browserPrefix}padding-before');
+    getPropertyValue('${Device.cssPrefix}padding-before');
 
   /** Sets the value of "padding-before" */
   void set paddingBefore(String value) {
-    setProperty('${_browserPrefix}padding-before', value, '');
+    setProperty('${Device.cssPrefix}padding-before', value, '');
   }
 
   /** Gets the value of "padding-bottom" */
@@ -2297,11 +2262,11 @@
 
   /** Gets the value of "padding-end" */
   String get paddingEnd =>
-    getPropertyValue('${_browserPrefix}padding-end');
+    getPropertyValue('${Device.cssPrefix}padding-end');
 
   /** Sets the value of "padding-end" */
   void set paddingEnd(String value) {
-    setProperty('${_browserPrefix}padding-end', value, '');
+    setProperty('${Device.cssPrefix}padding-end', value, '');
   }
 
   /** Gets the value of "padding-left" */
@@ -2324,11 +2289,11 @@
 
   /** Gets the value of "padding-start" */
   String get paddingStart =>
-    getPropertyValue('${_browserPrefix}padding-start');
+    getPropertyValue('${Device.cssPrefix}padding-start');
 
   /** Sets the value of "padding-start" */
   void set paddingStart(String value) {
-    setProperty('${_browserPrefix}padding-start', value, '');
+    setProperty('${Device.cssPrefix}padding-start', value, '');
   }
 
   /** Gets the value of "padding-top" */
@@ -2378,38 +2343,38 @@
 
   /** Gets the value of "perspective" */
   String get perspective =>
-    getPropertyValue('${_browserPrefix}perspective');
+    getPropertyValue('${Device.cssPrefix}perspective');
 
   /** Sets the value of "perspective" */
   void set perspective(String value) {
-    setProperty('${_browserPrefix}perspective', value, '');
+    setProperty('${Device.cssPrefix}perspective', value, '');
   }
 
   /** Gets the value of "perspective-origin" */
   String get perspectiveOrigin =>
-    getPropertyValue('${_browserPrefix}perspective-origin');
+    getPropertyValue('${Device.cssPrefix}perspective-origin');
 
   /** Sets the value of "perspective-origin" */
   void set perspectiveOrigin(String value) {
-    setProperty('${_browserPrefix}perspective-origin', value, '');
+    setProperty('${Device.cssPrefix}perspective-origin', value, '');
   }
 
   /** Gets the value of "perspective-origin-x" */
   String get perspectiveOriginX =>
-    getPropertyValue('${_browserPrefix}perspective-origin-x');
+    getPropertyValue('${Device.cssPrefix}perspective-origin-x');
 
   /** Sets the value of "perspective-origin-x" */
   void set perspectiveOriginX(String value) {
-    setProperty('${_browserPrefix}perspective-origin-x', value, '');
+    setProperty('${Device.cssPrefix}perspective-origin-x', value, '');
   }
 
   /** Gets the value of "perspective-origin-y" */
   String get perspectiveOriginY =>
-    getPropertyValue('${_browserPrefix}perspective-origin-y');
+    getPropertyValue('${Device.cssPrefix}perspective-origin-y');
 
   /** Sets the value of "perspective-origin-y" */
   void set perspectiveOriginY(String value) {
-    setProperty('${_browserPrefix}perspective-origin-y', value, '');
+    setProperty('${Device.cssPrefix}perspective-origin-y', value, '');
   }
 
   /** Gets the value of "pointer-events" */
@@ -2432,11 +2397,11 @@
 
   /** Gets the value of "print-color-adjust" */
   String get printColorAdjust =>
-    getPropertyValue('${_browserPrefix}print-color-adjust');
+    getPropertyValue('${Device.cssPrefix}print-color-adjust');
 
   /** Sets the value of "print-color-adjust" */
   void set printColorAdjust(String value) {
-    setProperty('${_browserPrefix}print-color-adjust', value, '');
+    setProperty('${Device.cssPrefix}print-color-adjust', value, '');
   }
 
   /** Gets the value of "quotes" */
@@ -2450,38 +2415,38 @@
 
   /** Gets the value of "region-break-after" */
   String get regionBreakAfter =>
-    getPropertyValue('${_browserPrefix}region-break-after');
+    getPropertyValue('${Device.cssPrefix}region-break-after');
 
   /** Sets the value of "region-break-after" */
   void set regionBreakAfter(String value) {
-    setProperty('${_browserPrefix}region-break-after', value, '');
+    setProperty('${Device.cssPrefix}region-break-after', value, '');
   }
 
   /** Gets the value of "region-break-before" */
   String get regionBreakBefore =>
-    getPropertyValue('${_browserPrefix}region-break-before');
+    getPropertyValue('${Device.cssPrefix}region-break-before');
 
   /** Sets the value of "region-break-before" */
   void set regionBreakBefore(String value) {
-    setProperty('${_browserPrefix}region-break-before', value, '');
+    setProperty('${Device.cssPrefix}region-break-before', value, '');
   }
 
   /** Gets the value of "region-break-inside" */
   String get regionBreakInside =>
-    getPropertyValue('${_browserPrefix}region-break-inside');
+    getPropertyValue('${Device.cssPrefix}region-break-inside');
 
   /** Sets the value of "region-break-inside" */
   void set regionBreakInside(String value) {
-    setProperty('${_browserPrefix}region-break-inside', value, '');
+    setProperty('${Device.cssPrefix}region-break-inside', value, '');
   }
 
   /** Gets the value of "region-overflow" */
   String get regionOverflow =>
-    getPropertyValue('${_browserPrefix}region-overflow');
+    getPropertyValue('${Device.cssPrefix}region-overflow');
 
   /** Sets the value of "region-overflow" */
   void set regionOverflow(String value) {
-    setProperty('${_browserPrefix}region-overflow', value, '');
+    setProperty('${Device.cssPrefix}region-overflow', value, '');
   }
 
   /** Gets the value of "resize" */
@@ -2504,47 +2469,47 @@
 
   /** Gets the value of "rtl-ordering" */
   String get rtlOrdering =>
-    getPropertyValue('${_browserPrefix}rtl-ordering');
+    getPropertyValue('${Device.cssPrefix}rtl-ordering');
 
   /** Sets the value of "rtl-ordering" */
   void set rtlOrdering(String value) {
-    setProperty('${_browserPrefix}rtl-ordering', value, '');
+    setProperty('${Device.cssPrefix}rtl-ordering', value, '');
   }
 
   /** Gets the value of "shape-inside" */
   String get shapeInside =>
-    getPropertyValue('${_browserPrefix}shape-inside');
+    getPropertyValue('${Device.cssPrefix}shape-inside');
 
   /** Sets the value of "shape-inside" */
   void set shapeInside(String value) {
-    setProperty('${_browserPrefix}shape-inside', value, '');
+    setProperty('${Device.cssPrefix}shape-inside', value, '');
   }
 
   /** Gets the value of "shape-margin" */
   String get shapeMargin =>
-    getPropertyValue('${_browserPrefix}shape-margin');
+    getPropertyValue('${Device.cssPrefix}shape-margin');
 
   /** Sets the value of "shape-margin" */
   void set shapeMargin(String value) {
-    setProperty('${_browserPrefix}shape-margin', value, '');
+    setProperty('${Device.cssPrefix}shape-margin', value, '');
   }
 
   /** Gets the value of "shape-outside" */
   String get shapeOutside =>
-    getPropertyValue('${_browserPrefix}shape-outside');
+    getPropertyValue('${Device.cssPrefix}shape-outside');
 
   /** Sets the value of "shape-outside" */
   void set shapeOutside(String value) {
-    setProperty('${_browserPrefix}shape-outside', value, '');
+    setProperty('${Device.cssPrefix}shape-outside', value, '');
   }
 
   /** Gets the value of "shape-padding" */
   String get shapePadding =>
-    getPropertyValue('${_browserPrefix}shape-padding');
+    getPropertyValue('${Device.cssPrefix}shape-padding');
 
   /** Sets the value of "shape-padding" */
   void set shapePadding(String value) {
-    setProperty('${_browserPrefix}shape-padding', value, '');
+    setProperty('${Device.cssPrefix}shape-padding', value, '');
   }
 
   /** Gets the value of "size" */
@@ -2594,11 +2559,11 @@
 
   /** Gets the value of "tap-highlight-color" */
   String get tapHighlightColor =>
-    getPropertyValue('${_browserPrefix}tap-highlight-color');
+    getPropertyValue('${Device.cssPrefix}tap-highlight-color');
 
   /** Sets the value of "tap-highlight-color" */
   void set tapHighlightColor(String value) {
-    setProperty('${_browserPrefix}tap-highlight-color', value, '');
+    setProperty('${Device.cssPrefix}tap-highlight-color', value, '');
   }
 
   /** Gets the value of "text-align" */
@@ -2612,20 +2577,20 @@
 
   /** Gets the value of "text-align-last" */
   String get textAlignLast =>
-    getPropertyValue('${_browserPrefix}text-align-last');
+    getPropertyValue('${Device.cssPrefix}text-align-last');
 
   /** Sets the value of "text-align-last" */
   void set textAlignLast(String value) {
-    setProperty('${_browserPrefix}text-align-last', value, '');
+    setProperty('${Device.cssPrefix}text-align-last', value, '');
   }
 
   /** Gets the value of "text-combine" */
   String get textCombine =>
-    getPropertyValue('${_browserPrefix}text-combine');
+    getPropertyValue('${Device.cssPrefix}text-combine');
 
   /** Sets the value of "text-combine" */
   void set textCombine(String value) {
-    setProperty('${_browserPrefix}text-combine', value, '');
+    setProperty('${Device.cssPrefix}text-combine', value, '');
   }
 
   /** Gets the value of "text-decoration" */
@@ -2639,74 +2604,74 @@
 
   /** Gets the value of "text-decoration-line" */
   String get textDecorationLine =>
-    getPropertyValue('${_browserPrefix}text-decoration-line');
+    getPropertyValue('${Device.cssPrefix}text-decoration-line');
 
   /** Sets the value of "text-decoration-line" */
   void set textDecorationLine(String value) {
-    setProperty('${_browserPrefix}text-decoration-line', value, '');
+    setProperty('${Device.cssPrefix}text-decoration-line', value, '');
   }
 
   /** Gets the value of "text-decoration-style" */
   String get textDecorationStyle =>
-    getPropertyValue('${_browserPrefix}text-decoration-style');
+    getPropertyValue('${Device.cssPrefix}text-decoration-style');
 
   /** Sets the value of "text-decoration-style" */
   void set textDecorationStyle(String value) {
-    setProperty('${_browserPrefix}text-decoration-style', value, '');
+    setProperty('${Device.cssPrefix}text-decoration-style', value, '');
   }
 
   /** Gets the value of "text-decorations-in-effect" */
   String get textDecorationsInEffect =>
-    getPropertyValue('${_browserPrefix}text-decorations-in-effect');
+    getPropertyValue('${Device.cssPrefix}text-decorations-in-effect');
 
   /** Sets the value of "text-decorations-in-effect" */
   void set textDecorationsInEffect(String value) {
-    setProperty('${_browserPrefix}text-decorations-in-effect', value, '');
+    setProperty('${Device.cssPrefix}text-decorations-in-effect', value, '');
   }
 
   /** Gets the value of "text-emphasis" */
   String get textEmphasis =>
-    getPropertyValue('${_browserPrefix}text-emphasis');
+    getPropertyValue('${Device.cssPrefix}text-emphasis');
 
   /** Sets the value of "text-emphasis" */
   void set textEmphasis(String value) {
-    setProperty('${_browserPrefix}text-emphasis', value, '');
+    setProperty('${Device.cssPrefix}text-emphasis', value, '');
   }
 
   /** Gets the value of "text-emphasis-color" */
   String get textEmphasisColor =>
-    getPropertyValue('${_browserPrefix}text-emphasis-color');
+    getPropertyValue('${Device.cssPrefix}text-emphasis-color');
 
   /** Sets the value of "text-emphasis-color" */
   void set textEmphasisColor(String value) {
-    setProperty('${_browserPrefix}text-emphasis-color', value, '');
+    setProperty('${Device.cssPrefix}text-emphasis-color', value, '');
   }
 
   /** Gets the value of "text-emphasis-position" */
   String get textEmphasisPosition =>
-    getPropertyValue('${_browserPrefix}text-emphasis-position');
+    getPropertyValue('${Device.cssPrefix}text-emphasis-position');
 
   /** Sets the value of "text-emphasis-position" */
   void set textEmphasisPosition(String value) {
-    setProperty('${_browserPrefix}text-emphasis-position', value, '');
+    setProperty('${Device.cssPrefix}text-emphasis-position', value, '');
   }
 
   /** Gets the value of "text-emphasis-style" */
   String get textEmphasisStyle =>
-    getPropertyValue('${_browserPrefix}text-emphasis-style');
+    getPropertyValue('${Device.cssPrefix}text-emphasis-style');
 
   /** Sets the value of "text-emphasis-style" */
   void set textEmphasisStyle(String value) {
-    setProperty('${_browserPrefix}text-emphasis-style', value, '');
+    setProperty('${Device.cssPrefix}text-emphasis-style', value, '');
   }
 
   /** Gets the value of "text-fill-color" */
   String get textFillColor =>
-    getPropertyValue('${_browserPrefix}text-fill-color');
+    getPropertyValue('${Device.cssPrefix}text-fill-color');
 
   /** Sets the value of "text-fill-color" */
   void set textFillColor(String value) {
-    setProperty('${_browserPrefix}text-fill-color', value, '');
+    setProperty('${Device.cssPrefix}text-fill-color', value, '');
   }
 
   /** Gets the value of "text-indent" */
@@ -2765,11 +2730,11 @@
 
   /** Gets the value of "text-orientation" */
   String get textOrientation =>
-    getPropertyValue('${_browserPrefix}text-orientation');
+    getPropertyValue('${Device.cssPrefix}text-orientation');
 
   /** Sets the value of "text-orientation" */
   void set textOrientation(String value) {
-    setProperty('${_browserPrefix}text-orientation', value, '');
+    setProperty('${Device.cssPrefix}text-orientation', value, '');
   }
 
   /** Gets the value of "text-overflow" */
@@ -2837,11 +2802,11 @@
 
   /** Gets the value of "text-security" */
   String get textSecurity =>
-    getPropertyValue('${_browserPrefix}text-security');
+    getPropertyValue('${Device.cssPrefix}text-security');
 
   /** Sets the value of "text-security" */
   void set textSecurity(String value) {
-    setProperty('${_browserPrefix}text-security', value, '');
+    setProperty('${Device.cssPrefix}text-security', value, '');
   }
 
   /** Gets the value of "text-shadow" */
@@ -2855,38 +2820,38 @@
 
   /** Gets the value of "text-size-adjust" */
   String get textSizeAdjust =>
-    getPropertyValue('${_browserPrefix}text-size-adjust');
+    getPropertyValue('${Device.cssPrefix}text-size-adjust');
 
   /** Sets the value of "text-size-adjust" */
   void set textSizeAdjust(String value) {
-    setProperty('${_browserPrefix}text-size-adjust', value, '');
+    setProperty('${Device.cssPrefix}text-size-adjust', value, '');
   }
 
   /** Gets the value of "text-stroke" */
   String get textStroke =>
-    getPropertyValue('${_browserPrefix}text-stroke');
+    getPropertyValue('${Device.cssPrefix}text-stroke');
 
   /** Sets the value of "text-stroke" */
   void set textStroke(String value) {
-    setProperty('${_browserPrefix}text-stroke', value, '');
+    setProperty('${Device.cssPrefix}text-stroke', value, '');
   }
 
   /** Gets the value of "text-stroke-color" */
   String get textStrokeColor =>
-    getPropertyValue('${_browserPrefix}text-stroke-color');
+    getPropertyValue('${Device.cssPrefix}text-stroke-color');
 
   /** Sets the value of "text-stroke-color" */
   void set textStrokeColor(String value) {
-    setProperty('${_browserPrefix}text-stroke-color', value, '');
+    setProperty('${Device.cssPrefix}text-stroke-color', value, '');
   }
 
   /** Gets the value of "text-stroke-width" */
   String get textStrokeWidth =>
-    getPropertyValue('${_browserPrefix}text-stroke-width');
+    getPropertyValue('${Device.cssPrefix}text-stroke-width');
 
   /** Sets the value of "text-stroke-width" */
   void set textStrokeWidth(String value) {
-    setProperty('${_browserPrefix}text-stroke-width', value, '');
+    setProperty('${Device.cssPrefix}text-stroke-width', value, '');
   }
 
   /** Gets the value of "text-transform" */
@@ -2954,56 +2919,56 @@
 
   /** Gets the value of "transform" */
   String get transform =>
-    getPropertyValue('${_browserPrefix}transform');
+    getPropertyValue('${Device.cssPrefix}transform');
 
   /** Sets the value of "transform" */
   void set transform(String value) {
-    setProperty('${_browserPrefix}transform', value, '');
+    setProperty('${Device.cssPrefix}transform', value, '');
   }
 
   /** Gets the value of "transform-origin" */
   String get transformOrigin =>
-    getPropertyValue('${_browserPrefix}transform-origin');
+    getPropertyValue('${Device.cssPrefix}transform-origin');
 
   /** Sets the value of "transform-origin" */
   void set transformOrigin(String value) {
-    setProperty('${_browserPrefix}transform-origin', value, '');
+    setProperty('${Device.cssPrefix}transform-origin', value, '');
   }
 
   /** Gets the value of "transform-origin-x" */
   String get transformOriginX =>
-    getPropertyValue('${_browserPrefix}transform-origin-x');
+    getPropertyValue('${Device.cssPrefix}transform-origin-x');
 
   /** Sets the value of "transform-origin-x" */
   void set transformOriginX(String value) {
-    setProperty('${_browserPrefix}transform-origin-x', value, '');
+    setProperty('${Device.cssPrefix}transform-origin-x', value, '');
   }
 
   /** Gets the value of "transform-origin-y" */
   String get transformOriginY =>
-    getPropertyValue('${_browserPrefix}transform-origin-y');
+    getPropertyValue('${Device.cssPrefix}transform-origin-y');
 
   /** Sets the value of "transform-origin-y" */
   void set transformOriginY(String value) {
-    setProperty('${_browserPrefix}transform-origin-y', value, '');
+    setProperty('${Device.cssPrefix}transform-origin-y', value, '');
   }
 
   /** Gets the value of "transform-origin-z" */
   String get transformOriginZ =>
-    getPropertyValue('${_browserPrefix}transform-origin-z');
+    getPropertyValue('${Device.cssPrefix}transform-origin-z');
 
   /** Sets the value of "transform-origin-z" */
   void set transformOriginZ(String value) {
-    setProperty('${_browserPrefix}transform-origin-z', value, '');
+    setProperty('${Device.cssPrefix}transform-origin-z', value, '');
   }
 
   /** Gets the value of "transform-style" */
   String get transformStyle =>
-    getPropertyValue('${_browserPrefix}transform-style');
+    getPropertyValue('${Device.cssPrefix}transform-style');
 
   /** Sets the value of "transform-style" */
   void set transformStyle(String value) {
-    setProperty('${_browserPrefix}transform-style', value, '');
+    setProperty('${Device.cssPrefix}transform-style', value, '');
   }
 
   /** Gets the value of "transition" */
@@ -3012,7 +2977,7 @@
   @SupportedBrowser(SupportedBrowser.IE, '10')
   @SupportedBrowser(SupportedBrowser.SAFARI)
   String get transition =>
-    getPropertyValue('${_browserPrefix}transition');
+    getPropertyValue('${Device.cssPrefix}transition');
 
   /** Sets the value of "transition" */
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -3020,43 +2985,43 @@
   @SupportedBrowser(SupportedBrowser.IE, '10')
   @SupportedBrowser(SupportedBrowser.SAFARI)
   void set transition(String value) {
-    setProperty('${_browserPrefix}transition', value, '');
+    setProperty('${Device.cssPrefix}transition', value, '');
   }
 
   /** Gets the value of "transition-delay" */
   String get transitionDelay =>
-    getPropertyValue('${_browserPrefix}transition-delay');
+    getPropertyValue('${Device.cssPrefix}transition-delay');
 
   /** Sets the value of "transition-delay" */
   void set transitionDelay(String value) {
-    setProperty('${_browserPrefix}transition-delay', value, '');
+    setProperty('${Device.cssPrefix}transition-delay', value, '');
   }
 
   /** Gets the value of "transition-duration" */
   String get transitionDuration =>
-    getPropertyValue('${_browserPrefix}transition-duration');
+    getPropertyValue('${Device.cssPrefix}transition-duration');
 
   /** Sets the value of "transition-duration" */
   void set transitionDuration(String value) {
-    setProperty('${_browserPrefix}transition-duration', value, '');
+    setProperty('${Device.cssPrefix}transition-duration', value, '');
   }
 
   /** Gets the value of "transition-property" */
   String get transitionProperty =>
-    getPropertyValue('${_browserPrefix}transition-property');
+    getPropertyValue('${Device.cssPrefix}transition-property');
 
   /** Sets the value of "transition-property" */
   void set transitionProperty(String value) {
-    setProperty('${_browserPrefix}transition-property', value, '');
+    setProperty('${Device.cssPrefix}transition-property', value, '');
   }
 
   /** Gets the value of "transition-timing-function" */
   String get transitionTimingFunction =>
-    getPropertyValue('${_browserPrefix}transition-timing-function');
+    getPropertyValue('${Device.cssPrefix}transition-timing-function');
 
   /** Sets the value of "transition-timing-function" */
   void set transitionTimingFunction(String value) {
-    setProperty('${_browserPrefix}transition-timing-function', value, '');
+    setProperty('${Device.cssPrefix}transition-timing-function', value, '');
   }
 
   /** Gets the value of "unicode-bidi" */
@@ -3079,29 +3044,29 @@
 
   /** Gets the value of "user-drag" */
   String get userDrag =>
-    getPropertyValue('${_browserPrefix}user-drag');
+    getPropertyValue('${Device.cssPrefix}user-drag');
 
   /** Sets the value of "user-drag" */
   void set userDrag(String value) {
-    setProperty('${_browserPrefix}user-drag', value, '');
+    setProperty('${Device.cssPrefix}user-drag', value, '');
   }
 
   /** Gets the value of "user-modify" */
   String get userModify =>
-    getPropertyValue('${_browserPrefix}user-modify');
+    getPropertyValue('${Device.cssPrefix}user-modify');
 
   /** Sets the value of "user-modify" */
   void set userModify(String value) {
-    setProperty('${_browserPrefix}user-modify', value, '');
+    setProperty('${Device.cssPrefix}user-modify', value, '');
   }
 
   /** Gets the value of "user-select" */
   String get userSelect =>
-    getPropertyValue('${_browserPrefix}user-select');
+    getPropertyValue('${Device.cssPrefix}user-select');
 
   /** Sets the value of "user-select" */
   void set userSelect(String value) {
-    setProperty('${_browserPrefix}user-select', value, '');
+    setProperty('${Device.cssPrefix}user-select', value, '');
   }
 
   /** Gets the value of "user-zoom" */
@@ -3187,38 +3152,38 @@
 
   /** Gets the value of "wrap" */
   String get wrap =>
-    getPropertyValue('${_browserPrefix}wrap');
+    getPropertyValue('${Device.cssPrefix}wrap');
 
   /** Sets the value of "wrap" */
   void set wrap(String value) {
-    setProperty('${_browserPrefix}wrap', value, '');
+    setProperty('${Device.cssPrefix}wrap', value, '');
   }
 
   /** Gets the value of "wrap-flow" */
   String get wrapFlow =>
-    getPropertyValue('${_browserPrefix}wrap-flow');
+    getPropertyValue('${Device.cssPrefix}wrap-flow');
 
   /** Sets the value of "wrap-flow" */
   void set wrapFlow(String value) {
-    setProperty('${_browserPrefix}wrap-flow', value, '');
+    setProperty('${Device.cssPrefix}wrap-flow', value, '');
   }
 
   /** Gets the value of "wrap-through" */
   String get wrapThrough =>
-    getPropertyValue('${_browserPrefix}wrap-through');
+    getPropertyValue('${Device.cssPrefix}wrap-through');
 
   /** Sets the value of "wrap-through" */
   void set wrapThrough(String value) {
-    setProperty('${_browserPrefix}wrap-through', value, '');
+    setProperty('${Device.cssPrefix}wrap-through', value, '');
   }
 
   /** Gets the value of "writing-mode" */
   String get writingMode =>
-    getPropertyValue('${_browserPrefix}writing-mode');
+    getPropertyValue('${Device.cssPrefix}writing-mode');
 
   /** Sets the value of "writing-mode" */
   void set writingMode(String value) {
-    setProperty('${_browserPrefix}writing-mode', value, '');
+    setProperty('${Device.cssPrefix}writing-mode', value, '');
   }
 
   /** Gets the value of "z-index" */
diff --git a/tools/dom/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate b/tools/dom/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate
index 1e9ba85..93fc2fa 100644
--- a/tools/dom/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate
+++ b/tools/dom/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate
@@ -43,6 +43,107 @@
     this.strokeStyle = 'hsla($h, $s%, $l%, $a)';
   }
 
+  @DomName('CanvasRenderingContext2D.arc')
+  void arc(num x,  num y,  num radius,  num startAngle, num endAngle,
+      [bool anticlockwise = false]) {
+    $dom_arc(x, y, radius, startAngle, endAngle, anticlockwise);
+  }
+
+  /**
+   * Draws an image from a CanvasImageSource to this canvas.
+   *
+   * The entire image from [source] will be drawn to this context with its top
+   * left corner at the point ([destinationX], [destinationY]). If the image is
+   * larger than canvas will allow, the image will be cropped to fit the
+   * available space.
+   *
+   *     CanvasElement canvas = new CanvasElement(width: 600, height: 600);
+   *     CanvasRenderingContext2D ctx = canvas.context2d;
+   *     ImageElement img = document.query('img');
+   *
+   *     ctx.drawImage(img, 100, 100);
+   *
+   *     VideoElement video = document.query('video');
+   *     ctx.drawImage(video, 0, 0);
+   *
+   *     CanvasElement otherCanvas = document.query('canvas');
+   *     otherCanvas.width = 100;
+   *     otherCanvas.height = 100;
+   *     ctx.drawImage(otherCanvas, 590, 590); // will get cropped
+   *
+   * See also:
+   *
+   *   * [CanvasImageSource] for more information on what data is retrieved
+   * from [source].
+   *   * [drawImage](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
+   * from the WHATWG.
+   */
+  @DomName('CanvasRenderingContext2D.drawImage')
+  void drawImage(CanvasImageSource source, num destinationX, num destinationY) {
+    $dom_drawImage(source, destinationX, destinationY);
+  }
+
+  /**
+   * Draws an image from a CanvasImageSource to an area of this canvas.
+   *
+   * The image will be drawn to an area of this canvas defined by
+   * [destinationRect]. If [sourceRect] is not provided, then
+   * the entire rectangular image from [source] will be drawn to this context.
+   * If the dimensions of [source] or [sourceRect]
+   * differ from [destinationRect], then the image will be scaled to fit.
+   * If the image is larger than canvas
+   * will allow, the image will be cropped to fit the available space.
+   *
+   *     CanvasElement canvas = new CanvasElement(width: 600, height: 600);
+   *     CanvasRenderingContext2D ctx = canvas.context2d;
+   *     ImageElement img = document.query('img');
+   *     img.width = 100;
+   *     img.height = 100;
+   *
+   *     // Scale the image to 20x20.
+   *     ctx.drawImageAtScale(img, new Rect(50, 50, 20, 20));
+   *
+   *     VideoElement video = document.query('video');
+   *     video.width = 100;
+   *     video.height = 100;
+   *     // Take the middle 20x20 pixels from the video and stretch them.
+   *     ctx.drawImageAtScale(video, new Rect(50, 50, 100, 100),
+   *         sourceRect: new Rect(40, 40, 20, 20));
+   *
+   *     // Draw the top 100x20 pixels from the otherCanvas.
+   *     CanvasElement otherCanvas = document.query('canvas');
+   *     ctx.drawImageAtScale(otherCanvas, new Rect(0, 0, 100, 20),
+   *         sourceRect: new Rect(0, 0, 100, 20));
+   *
+   * See also:
+   *
+   *   * [CanvasImageSource] for more information on what data is retrieved
+   * from [source].
+   *   * [drawImage](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
+   * from the WHATWG.
+   */
+  @DomName('CanvasRenderingContext2D.drawImage')
+  void drawImageAtScale(CanvasImageSource source, Rect destinationRect,
+      {Rect sourceRect}) {
+    if (sourceRect == null) {
+      $dom_drawImage(source,
+          destinationRect.left,
+          destinationRect.top,
+          destinationRect.width,
+          destinationRect.height);
+    } else {
+      $dom_drawImage(source,
+          sourceRect.left,
+          sourceRect.top,
+          sourceRect.width,
+          sourceRect.height,
+          destinationRect.left,
+          destinationRect.top,
+          destinationRect.width,
+          destinationRect.height);
+    }
+  }
+
 $if DART2JS
   @DomName('CanvasRenderingContext2D.lineDashOffset')
   num get lineDashOffset => JS('num',
diff --git a/tools/dom/templates/html/impl/impl_ClientRect.darttemplate b/tools/dom/templates/html/impl/impl_ClientRect.darttemplate
new file mode 100644
index 0000000..08d49b3
--- /dev/null
+++ b/tools/dom/templates/html/impl/impl_ClientRect.darttemplate
@@ -0,0 +1,101 @@
+// 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.
+
+part of $LIBRARYNAME;
+
+@DocsEditable
+$(ANNOTATIONS)class $CLASSNAME$EXTENDS implements Rect$IMPLEMENTS$NATIVESPEC {
+
+  // NOTE! All code below should be common with Rect.
+  // TODO(blois): implement with mixins when available.
+
+  String toString() {
+    return '($left, $top, $width, $height)';
+  }
+
+  bool operator ==(other) {
+    if (other is !Rect) return false;
+    return left == other.left && top == other.top && width == other.width &&
+        height == other.height;
+  }
+
+  /**
+   * Computes the intersection of this rectangle and the rectangle parameter.
+   * Returns null if there is no intersection.
+   */
+  Rect intersection(Rect rect) {
+    var x0 = max(left, rect.left);
+    var x1 = min(left + width, rect.left + rect.width);
+
+    if (x0 <= x1) {
+      var y0 = max(top, rect.top);
+      var y1 = min(top + height, rect.top + rect.height);
+
+      if (y0 <= y1) {
+        return new Rect(x0, y0, x1 - x0, y1 - y0);
+      }
+    }
+    return null;
+  }
+
+
+  /**
+   * Returns whether a rectangle intersects this rectangle.
+   */
+  bool intersects(Rect other) {
+    return (left <= other.left + other.width && other.left <= left + width &&
+        top <= other.top + other.height && other.top <= top + height);
+  }
+
+  /**
+   * Returns a new rectangle which completely contains this rectangle and the
+   * input rectangle.
+   */
+  Rect union(Rect rect) {
+    var right = max(this.left + this.width, rect.left + rect.width);
+    var bottom = max(this.top + this.height, rect.top + rect.height);
+
+    var left = min(this.left, rect.left);
+    var top = min(this.top, rect.top);
+
+    return new Rect(left, top, right - left, bottom - top);
+  }
+
+  /**
+   * Tests whether this rectangle entirely contains another rectangle.
+   */
+  bool containsRect(Rect another) {
+    return left <= another.left &&
+           left + width >= another.left + another.width &&
+           top <= another.top &&
+           top + height >= another.top + another.height;
+  }
+
+  /**
+   * Tests whether this rectangle entirely contains a point.
+   */
+  bool containsPoint(Point another) {
+    return another.x >= left &&
+           another.x <= left + width &&
+           another.y >= top &&
+           another.y <= top + height;
+  }
+
+  Rect ceil() => new Rect(left.ceil(), top.ceil(), width.ceil(), height.ceil());
+  Rect floor() => new Rect(left.floor(), top.floor(), width.floor(),
+      height.floor());
+  Rect round() => new Rect(left.round(), top.round(), width.round(),
+      height.round());
+
+  /**
+   * Truncates coordinates to integers and returns the result as a new
+   * rectangle.
+   */
+  Rect toInt() => new Rect(left.toInt(), top.toInt(), width.toInt(),
+      height.toInt());
+
+  Point get topLeft => new Point(this.left, this.top);
+  Point get bottomRight => new Point(this.left + this.width,
+      this.top + this.height);
+$!MEMBERS}
diff --git a/tools/dom/templates/html/impl/impl_DOMException.darttemplate b/tools/dom/templates/html/impl/impl_DOMException.darttemplate
index caba0d2..556778d 100644
--- a/tools/dom/templates/html/impl/impl_DOMException.darttemplate
+++ b/tools/dom/templates/html/impl/impl_DOMException.darttemplate
@@ -33,10 +33,10 @@
     var errorName = JS('String', '#.name', this);
     // Although Safari nightly has updated the name to SecurityError, Safari 5
     // and 6 still return SECURITY_ERR.
-    if (_Device.isWebKit && errorName == 'SECURITY_ERR') return 'SecurityError';
+    if (Device.isWebKit && errorName == 'SECURITY_ERR') return 'SecurityError';
     // Chrome release still uses old string, remove this line when Chrome stable
     // also prints out SyntaxError.
-    if (_Device.isWebKit && errorName == 'SYNTAX_ERR') return 'SyntaxError';
+    if (Device.isWebKit && errorName == 'SYNTAX_ERR') return 'SyntaxError';
     return errorName;
   }
 $endif
diff --git a/tools/dom/templates/html/impl/impl_Document.darttemplate b/tools/dom/templates/html/impl/impl_Document.darttemplate
index c1714b0..73b40fa 100644
--- a/tools/dom/templates/html/impl/impl_Document.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Document.darttemplate
@@ -19,30 +19,6 @@
 $!MEMBERS
 
   /**
-   * Finds the first descendant element of this document that matches the
-   * specified group of selectors.
-   *
-   * Unless your webpage contains multiple documents, the top-level query
-   * method behaves the same as this method, so you should use it instead to
-   * save typing a few characters.
-   *
-   * [selectors] should be a string using CSS selector syntax.
-   *     var element1 = document.query('.className');
-   *     var element2 = document.query('#id');
-   *
-   * For details about CSS selector syntax, see the
-   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
-   */
-  Element query(String selectors) {
-    // It is fine for our RegExp to detect element id query selectors to have
-    // false negatives but not false positives.
-    if (new RegExp("^#[_a-zA-Z]\\w*\$").hasMatch(selectors)) {
-      return $dom_getElementById(selectors.substring(1));
-    }
-    return $dom_querySelector(selectors);
-  }
-
-  /**
    * Finds all descendant elements of this document that match the specified
    * group of selectors.
    *
@@ -57,25 +33,6 @@
    * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
    */
   List<Element> queryAll(String selectors) {
-    if (new RegExp("""^\\[name=["'][^'"]+['"]\\]\$""").hasMatch(selectors)) {
-      final mutableMatches = $dom_getElementsByName(
-          selectors.substring(7,selectors.length - 2));
-      int len = mutableMatches.length;
-      final copyOfMatches = new List<Element>(len);
-      for (int i = 0; i < len; ++i) {
-        copyOfMatches[i] = mutableMatches[i];
-      }
-      return new _FrozenElementList._wrap(copyOfMatches);
-    } else if (new RegExp("^[*a-zA-Z0-9]+\$").hasMatch(selectors)) {
-      final mutableMatches = $dom_getElementsByTagName(selectors);
-      int len = mutableMatches.length;
-      final copyOfMatches = new List<Element>(len);
-      for (int i = 0; i < len; ++i) {
-        copyOfMatches[i] = mutableMatches[i];
-      }
-      return new _FrozenElementList._wrap(copyOfMatches);
-    } else {
-      return new _FrozenElementList._wrap($dom_querySelectorAll(selectors));
-    }
+    return new _FrozenElementList._wrap($dom_querySelectorAll(selectors));
   }
 }
diff --git a/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate b/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate
index 4bfdfbc..c2afcde 100644
--- a/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate
+++ b/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate
@@ -42,7 +42,7 @@
 
   String get innerHtml {
     final e = new Element.tag("div");
-    e.nodes.add(this.clone(true));
+    e.append(this.clone(true));
     return e.innerHtml;
   }
 
@@ -60,19 +60,11 @@
   }
 
   /**
-   * Adds the specified element after the last child of this
-   * document fragment.
-   */
-  void append(Element element) {
-    this.children.add(element);
-  }
-
-  /**
    * Adds the specified text as a text node after the last child of this
    * document fragment.
    */
   void appendText(String text) {
-    this.nodes.add(new Text(text));
+    this.append(new Text(text));
   }
 
 
@@ -81,7 +73,7 @@
    * last child of this document fragment.
    */
   void appendHtml(String text) {
-    this.nodes.add(new DocumentFragment.html(text));
+    this.append(new DocumentFragment.html(text));
   }
 
 $!MEMBERS
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index 35e8e2f..a5b8cb6 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -99,16 +99,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Element firstMatching(bool test(Element value), {Element orElse()}) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Element firstWhere(bool test(Element value), {Element orElse()}) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Element lastMatching(bool test(Element value), {Element orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Element lastWhere(bool test(Element value), {Element orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Element singleMatching(bool test(Element value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Element singleWhere(bool test(Element value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Element elementAt(int index) {
@@ -133,7 +133,7 @@
   }
 
   Element add(Element value) {
-    _element.$dom_appendChild(value);
+    _element.append(value);
     return value;
   }
 
@@ -147,7 +147,7 @@
     }
 
     for (Element element in iterable) {
-      _element.$dom_appendChild(element);
+      _element.append(element);
     }
   }
 
@@ -185,12 +185,12 @@
     IterableMixinWorkaround.retainAll(this, elements);
   }
 
-  void removeMatching(bool test(Element element)) {
-    IterableMixinWorkaround.removeMatching(this, test);
+  void removeWhere(bool test(Element element)) {
+    IterableMixinWorkaround.removeWhere(this, test);
   }
 
-  void retainMatching(bool test(Element element)) {
-    IterableMixinWorkaround.retainMatching(this, test);
+  void retainWhere(bool test(Element element)) {
+    IterableMixinWorkaround.retainWhere(this, test);
   }
 
   void removeRange(int start, int rangeLength) {
@@ -201,9 +201,13 @@
     throw new UnimplementedError();
   }
 
+  List sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return new _FrozenElementList._wrap(Lists.getRange(this, start, end, []));
+  }
+
   List getRange(int start, int rangeLength) =>
-    new _FrozenElementList._wrap(Lists.getRange(this, start, rangeLength,
-        []));
+      sublist(start, start + rangeLength);
 
   int indexOf(Element element, [int start = 0]) {
     return Lists.indexOf(this, element, start, this.length);
@@ -214,6 +218,17 @@
     return Lists.lastIndexOf(this, element, start);
   }
 
+  void insert(int index, Element element) {
+    if (index < 0 || index > length) {
+      throw new RangeError.range(index, 0, length);
+    }
+    if (index == length) {
+      _element.append(element);
+    } else {
+      throw new UnimplementedError("insert on ElementLists");
+    }
+  }
+
   void clear() {
     // It is unclear if we want to keep non element nodes?
     _element.text = '';
@@ -342,16 +357,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Element firstMatching(bool test(Element value), {Element orElse()}) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Element firstWhere(bool test(Element value), {Element orElse()}) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Element lastMatching(bool test(Element value), {Element orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Element lastWhere(bool test(Element value), {Element orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Element singleMatching(bool test(Element value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Element singleWhere(bool test(Element value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Element elementAt(int index) {
@@ -411,8 +426,12 @@
     throw new UnsupportedError('');
   }
 
+  List<Element> sublist(int start, [int end]) {
+    return new _FrozenElementList._wrap(_nodeList.sublist(start, end));
+  }
+
   List<Element> getRange(int start, int rangeLength) =>
-    new _FrozenElementList._wrap(_nodeList.getRange(start, rangeLength));
+      sublist(start, start + rangeLength);
 
   int indexOf(Element element, [int start = 0]) =>
     _nodeList.indexOf(element, start);
@@ -444,11 +463,11 @@
     throw new UnsupportedError('');
   }
 
-  void removeMatching(bool test(Element element)) {
+  void removeWhere(bool test(Element element)) {
     throw new UnsupportedError('');
   }
 
-  void retainMatching(bool test(Element element)) {
+  void retainWhere(bool test(Element element)) {
     throw new UnsupportedError('');
   }
 
@@ -616,25 +635,6 @@
   }
 
   /**
-   * Finds the first descendant element of this element that matches the
-   * specified group of selectors.
-   *
-   * [selectors] should be a string using CSS selector syntax.
-   *
-   *     // Gets the first descendant with the class 'classname'
-   *     var element = element.query('.className');
-   *     // Gets the element with id 'id'
-   *     var element = element.query('#id');
-   *     // Gets the first descendant [ImageElement]
-   *     var img = element.query('img');
-   *
-   * See also:
-   *
-   * * [CSS Selectors](http://docs.webplatform.org/wiki/css/selectors)
-   */
-  Element query(String selectors) => $dom_querySelector(selectors);
-
-  /**
    * Finds all descendent elements of this element that match the specified
    * group of selectors.
    *
@@ -731,12 +731,37 @@
     return window.$dom_getComputedStyle(this, pseudoElement);
   }
 
-  /**
-   * Adds the specified element to after the last child of this element.
-   */
-  void append(Element e) {
-    this.children.add(e);
-  }
+  @deprecated
+  int get clientHeight => client.height;
+  @deprecated
+  int get clientLeft => client.left;
+  @deprecated
+  int get clientTop => client.top;
+  @deprecated
+  int get clientWidth => client.width;
+
+  @DomName('Element.clientHeight')
+  @DomName('Element.clientLeft')
+  @DomName('Element.clientTop')
+  @DomName('Element.clientWidth')
+  Rect get client => new Rect($dom_clientLeft, $dom_clientTop, $dom_clientWidth,
+      $dom_clientHeight);
+
+  @deprecated
+  int get offsetHeight => offset.height;
+  @deprecated
+  int get offsetLeft => offset.left;
+  @deprecated
+  int get offsetTop => offset.top;
+  @deprecated
+  int get offsetWidth => offset.width;
+
+  @DomName('Element.offsetHeight')
+  @DomName('Element.offsetLeft')
+  @DomName('Element.offsetTop')
+  @DomName('Element.offsetWidth')
+  Rect get offset => new Rect($dom_offsetLeft, $dom_offsetTop, $dom_offsetWidth,
+      $dom_offsetHeight);
 
   /**
    * Adds the specified text as a text node after the last child of this
@@ -850,9 +875,9 @@
 
   static String _determineTransitionEventType(EventTarget e) {
     // Unfortunately the normal 'ontransitionend' style checks don't work here.
-    if (_Device.isWebKit) {
+    if (Device.isWebKit) {
       return 'webkitTransitionEnd';
-    } else if (_Device.isOpera) {
+    } else if (Device.isOpera) {
       return 'oTransitionEnd';
     }
     return 'transitionend';
@@ -943,7 +968,7 @@
         this.insertBefore(node, first);
         break;
       case 'beforeend':
-        this.nodes.add(node);
+        this.append(node);
         break;
       case 'afterend':
         this.parentNode.insertBefore(node, this.nextNode);
@@ -1018,7 +1043,7 @@
     final match = _START_TAG_REGEXP.firstMatch(html);
     if (match != null) {
       tag = match.group(1).toLowerCase();
-      if (_Device.isIE && _TABLE_TAGS.containsKey(tag)) {
+      if (Device.isIE && _TABLE_TAGS.containsKey(tag)) {
         return _createTableForIE(html, tag);
       }
       parentTag = _CUSTOM_PARENT_TAG_MAP[tag];
@@ -1061,7 +1086,8 @@
     switch (tag) {
       case 'td':
       case 'th':
-        element = _singleNode(_singleNode(table.rows).cells);
+        TableRowElement row = _singleNode(table.rows);
+        element = _singleNode(row.cells);
         break;
       case 'tr':
         element = _singleNode(table.rows);
diff --git a/tools/dom/templates/html/impl/impl_Event.darttemplate b/tools/dom/templates/html/impl/impl_Event.darttemplate
index 70c340a..b08aa32 100644
--- a/tools/dom/templates/html/impl/impl_Event.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Event.darttemplate
@@ -34,16 +34,4 @@
     return e;
   }
 $!MEMBERS
-
-  /**
-   * Checks to see if the event class is supported by the current platform.
-   */
-  static bool _isTypeSupported(String eventType) {
-    // Browsers throw for unsupported event names.
-    try {
-      var e = document.$dom_createEvent(eventType);
-      return e is Event;
-    } catch (_) { }
-    return false;
-  }
 }
diff --git a/tools/dom/templates/html/impl/impl_Geolocation.darttemplate b/tools/dom/templates/html/impl/impl_Geolocation.darttemplate
index 52dac0c..11e52b7 100644
--- a/tools/dom/templates/html/impl/impl_Geolocation.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Geolocation.darttemplate
@@ -62,7 +62,7 @@
                 controller.add(_ensurePosition(position));
               },
               (error) {
-                controller.signalError(error);
+                controller.addError(error);
               },
               options);
         } else {
@@ -75,6 +75,7 @@
   }
 
   Geoposition _ensurePosition(domPosition) {
+$if DART2JS
     try {
       // Firefox may throw on this.
       if (domPosition is Geoposition) {
@@ -82,7 +83,11 @@
       }
     } catch(e) {}
     return new _GeopositionWrapper(domPosition);
+$else
+    return domPosition;
+$endif
   }
+
 $!MEMBERS}
 
 $if DART2JS
diff --git a/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate
index 699a328..02aabe9e 100644
--- a/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate
@@ -4,7 +4,7 @@
 
 part of $LIBRARYNAME;
 
-$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
+$(ANNOTATIONS)class $CLASSNAME$EXTENDS implements CanvasImageSource$IMPLEMENTS$NATIVESPEC {
 $!MEMBERS
   CanvasRenderingContext2D get context2d => getContext('2d');
 
diff --git a/tools/dom/templates/html/impl/impl_HTMLImageElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLImageElement.darttemplate
new file mode 100644
index 0000000..59cd0f7
--- /dev/null
+++ b/tools/dom/templates/html/impl/impl_HTMLImageElement.darttemplate
@@ -0,0 +1,9 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of $LIBRARYNAME;
+
+$(ANNOTATIONS)class $CLASSNAME$EXTENDS implements CanvasImageSource$IMPLEMENTS$NATIVESPEC {
+$!MEMBERS
+}
diff --git a/tools/dom/templates/html/impl/impl_HTMLVideoElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLVideoElement.darttemplate
new file mode 100644
index 0000000..59cd0f7
--- /dev/null
+++ b/tools/dom/templates/html/impl/impl_HTMLVideoElement.darttemplate
@@ -0,0 +1,9 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of $LIBRARYNAME;
+
+$(ANNOTATIONS)class $CLASSNAME$EXTENDS implements CanvasImageSource$IMPLEMENTS$NATIVESPEC {
+$!MEMBERS
+}
diff --git a/tools/dom/templates/html/impl/impl_IDBObjectStore.darttemplate b/tools/dom/templates/html/impl/impl_IDBObjectStore.darttemplate
index 6f22f93..db9f162 100644
--- a/tools/dom/templates/html/impl/impl_IDBObjectStore.darttemplate
+++ b/tools/dom/templates/html/impl/impl_IDBObjectStore.darttemplate
@@ -151,7 +151,7 @@
 
     request.onError.listen((e) {
       //TODO: Report stacktrace once issue 4061 is resolved.
-      controller.signalError(e);
+      controller.addError(e);
     });
 
     request.onSuccess.listen((e) {
@@ -160,7 +160,7 @@
         controller.close();
       } else {
         controller.add(cursor);
-        if (autoAdvance == true) {
+        if (autoAdvance == true && controller.hasSubscribers) {
           cursor.next();
         }
       }
diff --git a/tools/dom/templates/html/impl/impl_Node.darttemplate b/tools/dom/templates/html/impl/impl_Node.darttemplate
index b113a5a..0d6e362 100644
--- a/tools/dom/templates/html/impl/impl_Node.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Node.darttemplate
@@ -17,12 +17,12 @@
 
 $if DART2JS
   Node get first {
-    Node result = JS('Node', '#.firstChild', _this);
+    Node result = JS('Node|Null', '#.firstChild', _this);
     if (result == null) throw new StateError("No elements");
     return result;
   }
   Node get last {
-    Node result = JS('Node', '#.lastChild', _this);
+    Node result = JS('Node|Null', '#.lastChild', _this);
     if (result == null) throw new StateError("No elements");
     return result;
   }
@@ -30,7 +30,7 @@
     int l = this.length;
     if (l == 0) throw new StateError("No elements");
     if (l > 1) throw new StateError("More than one element");
-    return JS('Node', '#.firstChild', _this);
+    return JS('Node|Null', '#.firstChild', _this);
   }
 $else
   Node get first {
@@ -60,26 +60,38 @@
   }
 
   void add(Node value) {
-    _this.$dom_appendChild(value);
+    _this.append(value);
   }
 
   void addLast(Node value) {
-    _this.$dom_appendChild(value);
+    _this.append(value);
   }
 
 
   void addAll(Iterable<Node> iterable) {
     if (iterable is _ChildNodeListLazy) {
-      if (iterable._this != _this) {
+      if (!identical(iterable._this, _this)) {
         // Optimized route for copying between nodes.
         for (var i = 0, len = iterable.length; i < len; ++i) {
-          _this.$dom_appendChild(iterable[0]);
+          // Should use $dom_firstChild, Bug 8886.
+          _this.append(iterable[0]);
         }
       }
       return;
     }
     for (Node node in iterable) {
-      _this.$dom_appendChild(node);
+      _this.append(node);
+    }
+  }
+
+  void insert(int index, Node node) {
+    if (index < 0 || index > length) {
+      throw new RangeError.range(index, 0, length);
+    }
+    if (index == length) {
+      _this.append(node);
+    } else {
+      this_.insertBefore(node, this[index]);
     }
   }
 
@@ -114,12 +126,12 @@
     IterableMixinWorkaround.retainAll(this, elements);
   }
 
-  void removeMatching(bool test(Node node)) {
-    IterableMixinWorkaround.removeMatching(this, test);
+  void removeWhere(bool test(Node node)) {
+    IterableMixinWorkaround.removeWhere(this, test);
   }
 
-  void retainMatching(bool test(Node node)) {
-    IterableMixinWorkaround.retainMatching(this, test);
+  void retainWhere(bool test(Node node)) {
+    IterableMixinWorkaround.retainWhere(this, test);
   }
 
   void clear() {
@@ -187,16 +199,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  Node firstMatching(bool test(Node value), {Node orElse()}) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  Node firstWhere(bool test(Node value), {Node orElse()}) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  Node lastMatching(bool test(Node value), {Node orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  Node lastWhere(bool test(Node value), {Node orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  Node singleMatching(bool test(Node value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  Node singleWhere(bool test(Node value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   Node elementAt(int index) {
@@ -232,8 +244,13 @@
     throw new UnsupportedError(
         "Cannot insertRange on immutable List.");
   }
+  List<Node> sublist(int start, [int end]) {
+    if (end == null) end == length;
+    return Lists.getRange(this, start, end, <Node>[]);
+  }
+
   List<Node> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Node>[]);
+      sublist(start, start + rangeLength);
 
   // -- end List<Node> mixins.
 
@@ -262,7 +279,7 @@
     List copy = new List.from(value);
     text = '';
     for (Node node in copy) {
-      $dom_appendChild(node);
+      append(node);
     }
   }
 
@@ -293,5 +310,113 @@
     return this;
   }
 
+  /**
+   * Inserts all of the nodes into this node directly before refChild.
+   *
+   * See also:
+   *
+   * * [insertBefore]
+   */
+  Node insertAllBefore(Iterable<Node> newNodes, Node refChild) {
+    if (newNodes is _ChildNodeListLazy) {
+      if (identical(newNodes._this, this)) {
+        throw new ArgumentError(newNodes);
+      }
+
+      // Optimized route for copying between nodes.
+      for (var i = 0, len = newNodes.length; i < len; ++i) {
+        // Should use $dom_firstChild, Bug 8886.
+        this.insertBefore(newNodes[0], refChild);
+      }
+    } else {
+      for (var node in newNodes) {
+        this.insertBefore(node, refChild);
+      }
+    }
+  }
+
+  // Note that this may either be the locally set model or a cached value
+  // of the inherited model. This is cached to minimize model change
+  // notifications.
+$if DART2JS
+  @Creates('Null')
+$endif
+  var _model;
+  bool _hasLocalModel;
+  StreamController<Node> _modelChangedStream;
+
+  /**
+   * The data model which is inherited through the tree.
+   *
+   * Setting this will propagate the value to all descendant nodes. If the
+   * model is not set on this node then it will be inherited from ancestor
+   * nodes.
+   *
+   * Currently this does not support propagation through Shadow DOMs.
+   *
+   * [clearModel] must be used to remove the model property from this node
+   * and have the model inherit from ancestor nodes.
+   */
+  @Experimental
+  get model {
+    // If we have a change handler then we've cached the model locally.
+    if (_modelChangedStream != null) {
+      return _model;
+    }
+    // Otherwise start looking up the tree.
+    for (var node = this; node != null; node = node.parentNode) {
+      if (node._hasLocalModel == true) {
+        return node._model;
+      }
+    }
+    return null;
+  }
+
+  @Experimental
+  void set model(value) {
+    var changed = model != value;
+    _model = value;
+    _hasLocalModel = true;
+    _ModelTreeObserver.initialize();
+
+    if (changed) {
+      if (_modelChangedStream != null) {
+        _modelChangedStream.add(this);
+      }
+      // Propagate new model to all descendants.
+      _ModelTreeObserver.propagateModel(this, value, false);
+    }
+  }
+
+  /**
+   * Clears the locally set model and makes this model be inherited from parent
+   * nodes.
+   */
+  @Experimental
+  void clearModel() {
+    if (_hasLocalModel == true) {
+      _hasLocalModel = false;
+
+      // Propagate new model to all descendants.
+      if (parentNode != null) {
+        _ModelTreeObserver.propagateModel(this, parentNode.model, false);
+      } else {
+        _ModelTreeObserver.propagateModel(this, null, false);
+      }
+    }
+  }
+
+  /**
+   * Get a stream of models, whenever the model changes.
+   */
+  Stream<Node> get onModelChanged {
+    if (_modelChangedStream == null) {
+      // Ensure the model is cached locally to minimize change notifications.
+      _model = model;
+      _modelChangedStream = new StreamController.broadcast();
+    }
+    return _modelChangedStream.stream;
+  }
+
 $!MEMBERS
 }
diff --git a/tools/dom/templates/html/impl/impl_RTCPeerConnection.darttemplate b/tools/dom/templates/html/impl/impl_RTCPeerConnection.darttemplate
index 19c394c..edef225 100644
--- a/tools/dom/templates/html/impl/impl_RTCPeerConnection.darttemplate
+++ b/tools/dom/templates/html/impl/impl_RTCPeerConnection.darttemplate
@@ -8,7 +8,7 @@
 $if DART2JS
   factory $CLASSNAME(Map rtcIceServers, [Map mediaConstraints]) {
     var constructorName = JS('RtcPeerConnection', 'window[#]',
-        '${_browserPropertyPrefix}RTCPeerConnection');
+        '${Device.propertyPrefix}RTCPeerConnection');
     if (?mediaConstraints) {
       return JS('RtcPeerConnection', 'new #(#,#)', constructorName,
           convertDartToNative_SerializedScriptValue(rtcIceServers),
@@ -21,18 +21,18 @@
 $endif
 
   /**
-   * Checks if Real Time Communication (RTC) APIs are supported and enabled on 
+   * Checks if Real Time Communication (RTC) APIs are supported and enabled on
    * the current platform.
    */
 $if DART2JS
   static bool get supported {
     // Currently in Firefox some of the RTC elements are defined but throw an
-    // error unless the user has specifically enabled them in their 
+    // error unless the user has specifically enabled them in their
     // about:config. So we have to construct an element to actually test if RTC
     // is supported at at the given time.
     try {
       var c = new RtcPeerConnection({"iceServers": [ {"url":"stun:foo.com"}]});
-      return c is RtcPeerConnection; 
+      return c is RtcPeerConnection;
     } catch (_) {}
     return false;
   }
diff --git a/tools/dom/templates/html/impl/impl_Screen.darttemplate b/tools/dom/templates/html/impl/impl_Screen.darttemplate
new file mode 100644
index 0000000..edcf070
--- /dev/null
+++ b/tools/dom/templates/html/impl/impl_Screen.darttemplate
@@ -0,0 +1,16 @@
+// 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.
+
+part of $LIBRARYNAME;
+
+@DocsEditable
+$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
+
+  @DomName('Screen.availHeight')
+  @DomName('Screen.availLeft')
+  @DomName('Screen.availTop')
+  @DomName('Screen.availWidth')
+  Rect get available => new Rect($dom_availLeft, $dom_availTop, $dom_availWidth,
+      $dom_availHeight);
+$!MEMBERS}
diff --git a/tools/dom/templates/html/impl/impl_Touch.darttemplate b/tools/dom/templates/html/impl/impl_Touch.darttemplate
new file mode 100644
index 0000000..f9efa4a
--- /dev/null
+++ b/tools/dom/templates/html/impl/impl_Touch.darttemplate
@@ -0,0 +1,22 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of $LIBRARYNAME;
+
+@DocsEditable
+$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
+$!MEMBERS
+
+  @DomName('Touch.clientX')
+  @DomName('Touch.clientY')
+  Point get client => new Point($dom_clientX, $dom_clientY);
+
+  @DomName('Touch.pageX')
+  @DomName('Touch.pageY')
+  Point get page => new Point($dom_pageX, $dom_pageY);
+
+  @DomName('Touch.screenX')
+  @DomName('Touch.screenY')
+  Point get screen => new Point($dom_screenX, $dom_screenY);
+}
diff --git a/tools/dom/templates/html/impl/impl_TouchEvent.darttemplate b/tools/dom/templates/html/impl/impl_TouchEvent.darttemplate
index 7223959..26c7939 100644
--- a/tools/dom/templates/html/impl/impl_TouchEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_TouchEvent.darttemplate
@@ -31,14 +31,14 @@
   static bool get supported {
 $if DART2JS
     if (JS('bool', '"ontouchstart" in window')) {
-      return Event._isTypeSupported('TouchEvent');
+      return Device.isEventTypeSupported('TouchEvent');
     }
     return false;
 $else
     // Bug #8186 add equivalent 'ontouchstart' check for Dartium.
     // Basically, this is a fairly common check and it'd be great if it did not
     // throw exceptions.
-    return Event._isTypeSupported('TouchEvent');
+    return Device.isEventTypeSupported('TouchEvent');
 $endif
   }
 }
diff --git a/tools/dom/templates/html/impl/impl_UIEvent.darttemplate b/tools/dom/templates/html/impl/impl_UIEvent.darttemplate
index a4d2830..31e817b 100644
--- a/tools/dom/templates/html/impl/impl_UIEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_UIEvent.darttemplate
@@ -24,4 +24,22 @@
     return e;
   }
 $!MEMBERS
+
+  @deprecated
+  int get layerX => layer.x;
+  @deprecated
+  int get layerY => layer.y;
+
+  @deprecated
+  int get pageX => page.x;
+  @deprecated
+  int get pageY => page.y;
+
+  @DomName('UIEvent.layerX')
+  @DomName('UIEvent.layerY')
+  Point get layer => new Point($dom_layerX, $dom_layerY);
+
+  @DomName('UIEvent.pageX')
+  @DomName('UIEvent.pageY')
+  Point get page => new Point($dom_pageX, $dom_pageY);
 }
diff --git a/tools/dom/templates/html/impl/impl_WheelEvent.darttemplate b/tools/dom/templates/html/impl/impl_WheelEvent.darttemplate
index c49d8f6..93da127 100644
--- a/tools/dom/templates/html/impl/impl_WheelEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_WheelEvent.darttemplate
@@ -17,7 +17,7 @@
       view = window;
     }
     var eventType = 'WheelEvent';
-    if (_Device.isFirefox) {
+    if (Device.isFirefox) {
       eventType = 'MouseScrollEvents';
     }
     final event = document.$dom_createEvent(eventType);
diff --git a/tools/dom/templates/html/impl/impl_Window.darttemplate b/tools/dom/templates/html/impl/impl_Window.darttemplate
index 682813b..d8d90d6 100644
--- a/tools/dom/templates/html/impl/impl_Window.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Window.darttemplate
@@ -58,8 +58,10 @@
    * [animationFrame] again for the animation to continue.
    */
   Future<num> get animationFrame {
-    var completer = new Completer<int>();
-    requestAnimationFrame(completer.complete);
+    var completer = new Completer<num>();
+    requestAnimationFrame((time) {
+      completer.complete(time);
+    });
     return completer.future;
   }
 
diff --git a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
index cc8eef3..eb6f2a9 100644
--- a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
+++ b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
@@ -85,7 +85,7 @@
     if (method == null) {
       method = 'GET';
     }
-    xhr.open(method, url, true);
+    xhr.open(method, url, async: true);
 
     if (withCredentials != null) {
       xhr.withCredentials = withCredentials;
diff --git a/tools/dom/templates/immutable_list_mixin.darttemplate b/tools/dom/templates/immutable_list_mixin.darttemplate
index 7f2497f..11aed32 100644
--- a/tools/dom/templates/immutable_list_mixin.darttemplate
+++ b/tools/dom/templates/immutable_list_mixin.darttemplate
@@ -61,16 +61,16 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  $E firstMatching(bool test($E value), { $E orElse() }) {
-    return IterableMixinWorkaround.firstMatching(this, test, orElse);
+  $E firstWhere(bool test($E value), { $E orElse() }) {
+    return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  $E lastMatching(bool test($E value), {$E orElse()}) {
-    return IterableMixinWorkaround.lastMatchingInList(this, test, orElse);
+  $E lastWhere(bool test($E value), {$E orElse()}) {
+    return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  $E singleMatching(bool test($E value)) {
-    return IterableMixinWorkaround.singleMatching(this, test);
+  $E singleWhere(bool test($E value)) {
+    return IterableMixinWorkaround.singleWhere(this, test);
   }
 
   $E elementAt(int index) {
@@ -144,6 +144,10 @@
   $E max([int compare($E a, $E b)]) =>
       IterableMixinWorkaround.max(this, compare);
 
+  void insert(int index, $E element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
   $E removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -164,11 +168,11 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void removeMatching(bool test($E element)) {
+  void removeWhere(bool test($E element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void retainMatching(bool test($E element)) {
+  void retainWhere(bool test($E element)) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
@@ -184,8 +188,13 @@
     throw new UnsupportedError("Cannot insertRange on immutable List.");
   }
 
+  List<$E> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    return Lists.getRange(this, start, end, <$E>[]);
+  }
+
   List<$E> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <$E>[]);
+      sublist(start, start + rangeLength);
 
   Map<int, $E> asMap() =>
     IterableMixinWorkaround.asMapList(this);
diff --git a/tools/gyp/all.gypi b/tools/gyp/all.gypi
index d75e339..2d056e8 100644
--- a/tools/gyp/all.gypi
+++ b/tools/gyp/all.gypi
@@ -24,11 +24,17 @@
       'target_defaults': {
         'msvs_cygwin_dirs': ['<(DEPTH)/third_party/cygwin'],
       },
+      'includes': [
+        'msvs.gypi',
+      ],
+    }],
+    [ 'OS=="mac"', {
+      'includes': [
+        'xcode.gypi',
+      ],
     }],
   ],
   'includes': [
-    'xcode.gypi',
-    'msvs.gypi',
     'configurations.gypi',
   ],
 }
diff --git a/tools/gyp/common.gypi b/tools/gyp/common.gypi
index adfc1db..3988dfb 100644
--- a/tools/gyp/common.gypi
+++ b/tools/gyp/common.gypi
@@ -27,11 +27,17 @@
       'target_defaults': {
         'msvs_cygwin_dirs': ['<(DEPTH)/../third_party/cygwin'],
       },
+      'includes': [
+        'msvs.gypi',
+      ],
+    }],
+    [ 'OS=="mac"', {
+      'includes': [
+        'xcode.gypi',
+      ],
     }],
   ],
   'includes': [
-    'xcode.gypi',
-    'msvs.gypi',
     'configurations.gypi',
   ],
 }
diff --git a/tools/gyp/find_mac_sdk.py b/tools/gyp/find_mac_sdk.py
new file mode 100755
index 0000000..baf6279
--- /dev/null
+++ b/tools/gyp/find_mac_sdk.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# This file is a copy of Chromium's src/build/mac/find_sdk.py.
+# Revision 180337.
+
+import os
+import re
+import subprocess
+import sys
+
+"""Prints the lowest locally available SDK version greater than or equal to a
+given minimum sdk version to standard output.
+
+Usage:
+  python find_sdk.py 10.6  # Ignores SDKs < 10.6
+"""
+
+from optparse import OptionParser
+
+
+def parse_version(version_str):
+  """'10.6' => [10, 6]"""
+  return map(int, re.findall(r'(\d+)', version_str))
+
+
+def main():
+  parser = OptionParser()
+  parser.add_option("--verify",
+                    action="store_true", dest="verify", default=False,
+                    help="return the sdk argument and warn if it doesn't exist")
+  parser.add_option("--sdk_path",
+                    action="store", type="string", dest="sdk_path", default="",
+                    help="user-specified SDK path; bypasses verification")
+  (options, args) = parser.parse_args()
+  min_sdk_version = args[0]
+
+  job = subprocess.Popen(['xcode-select', '-print-path'],
+                         stdout=subprocess.PIPE,
+                         stderr=subprocess.STDOUT)
+  out, err = job.communicate()
+  if job.returncode != 0:
+    print >>sys.stderr, out
+    print >>sys.stderr, err
+    raise Exception(('Error %d running xcode-select, you might have to run '
+      '|sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer| '
+      'if you are using Xcode 4.') % job.returncode)
+  # The Developer folder moved in Xcode 4.3.
+  xcode43_sdk_path = os.path.join(
+      out.rstrip(), 'Platforms/MacOSX.platform/Developer/SDKs')
+  if os.path.isdir(xcode43_sdk_path):
+    sdk_dir = xcode43_sdk_path
+  else:
+    sdk_dir = os.path.join(out.rstrip(), 'SDKs')
+  sdks = [re.findall('^MacOSX(10\.\d+)\.sdk$', s) for s in os.listdir(sdk_dir)]
+  sdks = [s[0] for s in sdks if s]  # [['10.5'], ['10.6']] => ['10.5', '10.6']
+  sdks = [s for s in sdks  # ['10.5', '10.6'] => ['10.6']
+          if parse_version(s) >= parse_version(min_sdk_version)]
+  if not sdks:
+    raise Exception('No %s+ SDK found' % min_sdk_version)
+  best_sdk = sorted(sdks, key=parse_version)[0]
+
+  if options.verify and best_sdk != min_sdk_version and not options.sdk_path:
+    print >>sys.stderr, ''
+    print >>sys.stderr, '                                           vvvvvvv'
+    print >>sys.stderr, ''
+    print >>sys.stderr, \
+        'This build requires the %s SDK, but it was not found on your system.' \
+        % min_sdk_version
+    print >>sys.stderr, \
+        'Either install it, or explicitly set mac_sdk in your GYP_DEFINES.'
+    print >>sys.stderr, ''
+    print >>sys.stderr, '                                           ^^^^^^^'
+    print >>sys.stderr, ''
+    return min_sdk_version
+
+  return best_sdk
+
+
+if __name__ == '__main__':
+  if sys.platform != 'darwin':
+    raise Exception("This script only runs on Mac")
+  print main()
diff --git a/tools/gyp/xcode.gypi b/tools/gyp/xcode.gypi
index 26afb4a..6197887 100644
--- a/tools/gyp/xcode.gypi
+++ b/tools/gyp/xcode.gypi
@@ -18,8 +18,8 @@
     # Chrome normally builds with the Mac OS X 10.5 SDK and sets the
     # deployment target to 10.5.  Other projects, such as O3D, may override
     # these defaults.
-    'mac_sdk%': '10.5',
-    'mac_deployment_target%': '10.5',
+    'mac_sdk%': '<!(python <(DEPTH)/tools/gyp/find_mac_sdk.py 10.6)',
+    'mac_deployment_target%': '10.6',
   },
   'xcode_settings': {
     # DON'T ADD ANYTHING NEW TO THIS BLOCK UNLESS YOU REALLY REALLY NEED IT!
diff --git a/tools/line_doc_comments.dart b/tools/line_doc_comments.dart
index 50727ee..942881f 100755
--- a/tools/line_doc_comments.dart
+++ b/tools/line_doc_comments.dart
@@ -83,7 +83,7 @@
       }
     }
 
-    if (line != null) buffer.add('$line\n');
+    if (line != null) buffer.write('$line\n');
   }
 
   return buffer.toString();
diff --git a/tools/publish_pkg.py b/tools/publish_pkg.py
index d1629c9..1c4cb59 100755
--- a/tools/publish_pkg.py
+++ b/tools/publish_pkg.py
@@ -160,12 +160,6 @@
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ''');
 
-  # TODO(jmesserly): this is a hack to make analyzer-experimental work.
-  if pkgName.endswith('-experimental'):
-    pkgReplace = (pkgName, pkgName.replace('-', '_'))
-    replaceInDart.append(pkgReplace)
-    replaceInPubspec.append(pkgReplace)
-
   replaceInDart.append(
     (r'(import|part)(\s+)(\'|")(\.\./)+pkg/([^/]+/)lib/', r'\1\2\3package:\5'))
 
diff --git a/tools/release/version.dart b/tools/release/version.dart
index 73ef164..74e1e66 100644
--- a/tools/release/version.dart
+++ b/tools/release/version.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -62,9 +62,10 @@
         completeError("No VERSION file");
         return;
       }
-      StringInputStream input = new StringInputStream(f.openInputStream());
-      input.onLine = () {
-        var line = input.readLine().trim();
+      Stream<String> stream =
+          f.openRead().transform(new StringDecoder())
+                      .transform(new LineTransformer());
+      stream.listen((String line) {
         if (line == null) {
           completeError(
               "VERSION input file seems to be in the wrong format");
@@ -101,8 +102,8 @@
                             "contain one of {MAJOR, MINOR, BUILD, PATCH}");
             return;
         }
-      };
-      input.onClosed = () {
+      },
+      onDone: () {
         // Only complete if we did not already complete with a failure.
         if (!wasCompletedWithError) {
           getRevision().then((revision) {
@@ -117,7 +118,7 @@
             return;
           });
         }
-      };
+      });
     });
     return c.future;
   }
diff --git a/tools/test-runtime.dart b/tools/test-runtime.dart
index 3f30059..f7796a2 100755
--- a/tools/test-runtime.dart
+++ b/tools/test-runtime.dart
@@ -1,5 +1,5 @@
 #!/usr/bin/env dart
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -8,16 +8,18 @@
 // This file is identical to test.dart with test suites in the
 // directories samples, client, compiler, and utils removed.
 
-#library("test");
+library test;
 
-#import("dart:io");
-#import("testing/dart/test_runner.dart");
-#import("testing/dart/test_options.dart");
-#import("testing/dart/test_suite.dart");
-#import("testing/dart/http_server.dart");
+import "dart:io";
+import "testing/dart/test_runner.dart";
+import "testing/dart/test_options.dart";
+import "testing/dart/test_suite.dart";
+import "testing/dart/http_server.dart";
+import "testing/dart/utils.dart";
+import "testing/dart/test_progress.dart";
 
-#import("../tests/co19/test_config.dart");
-#import("../runtime/tests/vm/test_config.dart");
+import "../tests/co19/test_config.dart";
+import "../runtime/tests/vm/test_config.dart";
 
 /**
  * The directories that contain test suites which follow the conventions
@@ -37,7 +39,7 @@
 ];
 
 main() {
-  var startTime = new Date.now();
+  var startTime = new DateTime.now();
   var optionsParser = new TestOptionsParser();
   List<Map> configurations = optionsParser.parse(new Options().arguments);
   if (configurations == null) return;
@@ -50,7 +52,6 @@
   var verbose = firstConf['verbose'];
   var printTiming = firstConf['time'];
   var listTests = firstConf['list'];
-  var useContentSecurityPolicy = firstConf['csp'];
 
   if (!firstConf['append_logs'])  {
     var file = new File(TestUtils.flakyFileName());
@@ -66,30 +67,15 @@
         ['Test configurations:'] : ['Test configuration:'];
     for (Map conf in configurations) {
       List settings = ['compiler', 'runtime', 'mode', 'arch']
-          .mappedBy((name) => conf[name]).toList();
+          .map((name) => conf[name]).toList();
       if (conf['checked']) settings.add('checked');
       output_words.add(settings.join('_'));
     }
     print(output_words.join(' '));
   }
 
-  var runningBrowserTests = configurations.any((config) {
-    return TestUtils.isBrowserRuntime(config['runtime']);
-  });
-
   var testSuites = new List<TestSuite>();
   for (var conf in configurations) {
-    if (!listTests && runningBrowserTests) {
-      // Start global http servers that serve the entire dart repo.
-      // The http server is available on window.location.port, and a second
-      // server for cross-domain tests can be found by calling
-      // getCrossOriginPortNumber().
-      var servers = new TestingServers(new Path(TestUtils.buildDir(conf)),
-                                       useContentSecurityPolicy);
-      servers.startServers('127.0.0.1');
-      conf['_servers_'] = servers;
-    }
-
     if (selectors.containsKey('co19')) {
       testSuites.add(new Co19TestSuite(conf));
     }
@@ -109,24 +95,48 @@
   }
 
   void allTestsFinished() {
-    for (var conf in configurations) {
-      if (conf.containsKey('_servers_')) {
-        conf['_servers_'].stopServers();
-      }
-    }
     DebugLogger.close();
   }
 
   var maxBrowserProcesses = maxProcesses;
 
+  var eventListener = [];
+  if (progressIndicator != 'silent') {
+    var printFailures = true;
+    var formatter = new Formatter();
+    if (progressIndicator == 'color') {
+      progressIndicator = 'compact';
+      formatter = new ColorFormatter();
+    }
+    if (progressIndicator == 'diff') {
+      progressIndicator = 'compact';
+      formatter = new ColorFormatter();
+      printFailures = false;
+      eventListener.add(new StatusFileUpdatePrinter());
+    }
+    eventListener.add(new SummaryPrinter());
+    eventListener.add(new FlakyLogWriter());
+    if (printFailures) {
+      eventListener.add(new TestFailurePrinter(formatter));
+    }
+    eventListener.add(new ProgressIndicator.fromName(progressIndicator,
+                                                     startTime,
+                                                     formatter));
+    if (printTiming) {
+      eventListener.add(new TimingPrinter(startTime));
+    }
+    eventListener.add(new SkippedCompilationsPrinter());
+    eventListener.add(new LeftOverTempDirPrinter());
+  }
+  eventListener.add(new ExitCodeSetter());
+
   // Start process queue.
   new ProcessQueue(
       maxProcesses,
       maxBrowserProcesses,
-      progressIndicator,
       startTime,
-      printTiming,
       testSuites,
+      eventListener,
       allTestsFinished,
       verbose,
       listTests);
diff --git a/tools/test.dart b/tools/test.dart
index 00eb7f1..7300699 100755
--- a/tools/test.dart
+++ b/tools/test.dart
@@ -1,5 +1,5 @@
 #!/usr/bin/env dart
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -24,6 +24,7 @@
 
 library test;
 
+import "dart:async";
 import "dart:io";
 import "testing/dart/test_runner.dart";
 import "testing/dart/test_options.dart";
@@ -36,6 +37,7 @@
 import "../runtime/tests/vm/test_config.dart";
 import "../samples/tests/dartc/test_config.dart";
 import "../tests/co19/test_config.dart";
+import "../tests/lib/analyzer/test_config.dart";
 
 /**
  * The directories that contain test suites which follow the conventions
@@ -70,7 +72,7 @@
 ];
 
 main() {
-  var startTime = new Date.now();
+  var startTime = new DateTime.now();
   var optionsParser = new TestOptionsParser();
   List<Map> configurations = optionsParser.parse(new Options().arguments);
   if (configurations == null || configurations.length == 0) return;
@@ -104,7 +106,7 @@
         ['Test configurations:'] : ['Test configuration:'];
     for (Map conf in configurations) {
       List settings = ['compiler', 'runtime', 'mode', 'arch']
-          .mappedBy((name) => conf[name]).toList();
+          .map((name) => conf[name]).toList();
       if (conf['checked']) settings.add('checked');
       output_words.add(settings.join('_'));
     }
@@ -115,6 +117,7 @@
     return TestUtils.isBrowserRuntime(config['runtime']);
   });
 
+  List<Future> serverFutures = [];
   var testSuites = new List<TestSuite>();
   var maxBrowserProcesses = maxProcesses;
   for (var conf in configurations) {
@@ -125,7 +128,7 @@
       // getCrossOriginPortNumber().
       var servers = new TestingServers(new Path(TestUtils.buildDir(conf)),
                                        useContentSecurityPolicy);
-      servers.startServers('127.0.0.1');
+      serverFutures.add(servers.startServers('127.0.0.1'));
       conf['_servers_'] = servers;
     }
 
@@ -143,9 +146,17 @@
         // vm tests contain both cc tests (added here) and dart tests (added in
         // [TEST_SUITE_DIRECTORIES]).
         testSuites.add(new VMTestSuite(conf));
-      } else if (conf['compiler'] == 'dartc' && key == 'dartc') {
-        testSuites.add(new SamplesDartcTestSuite(conf));
-        testSuites.add(new JUnitDartcTestSuite(conf));
+      } else if (conf['analyzer']) {
+        if (key == 'dartc' && conf['compiler'] == 'dartc') {
+          testSuites.add(new JUnitDartcTestSuite(conf));
+        }
+        // TODO(devoncarew): get these running with the new analyzer
+        if (key == 'dartc' && conf['compiler'] == 'dartc') {
+          testSuites.add(new SamplesDartcTestSuite(conf));
+        }
+        if (key == 'analyze_library') {
+          testSuites.add(new AnalyzeLibraryTestSuite(conf));
+        }
       }
     }
 
@@ -167,14 +178,52 @@
     DebugLogger.close();
   }
 
-  // Start process queue.
-  new ProcessQueue(maxProcesses,
-                   maxBrowserProcesses,
-                   progressIndicator,
-                   startTime,
-                   printTiming,
-                   testSuites,
-                   allTestsFinished,
-                   verbose,
-                   listTests);
+  var eventListener = [];
+  if (progressIndicator != 'silent') {
+    var printFailures = true;
+    var formatter = new Formatter();
+    if (progressIndicator == 'color') {
+      progressIndicator = 'compact';
+      formatter = new ColorFormatter();
+    }
+    if (progressIndicator == 'diff') {
+      progressIndicator = 'compact';
+      formatter = new ColorFormatter();
+      printFailures = false;
+      eventListener.add(new StatusFileUpdatePrinter());
+    }
+    eventListener.add(new SummaryPrinter());
+    eventListener.add(new FlakyLogWriter());
+    if (printFailures) {
+      eventListener.add(new TestFailurePrinter(formatter));
+    }
+    eventListener.add(new ProgressIndicator.fromName(progressIndicator,
+                                                     startTime,
+                                                     formatter));
+    if (printTiming) {
+      eventListener.add(new TimingPrinter(startTime));
+    }
+    eventListener.add(new SkippedCompilationsPrinter());
+    eventListener.add(new LeftOverTempDirPrinter());
+  }
+  eventListener.add(new ExitCodeSetter());
+
+  void startProcessQueue() {
+    // Start process queue.
+    new ProcessQueue(maxProcesses,
+                     maxBrowserProcesses,
+                     startTime,
+                     testSuites,
+                     eventListener,
+                     allTestsFinished,
+                     verbose,
+                     listTests);
+  }
+
+  // Start all the HTTP servers required before starting the process queue.
+  if (serverFutures.isEmpty) {
+    startProcessQueue();
+  } else {
+    Future.wait(serverFutures).then((_) => startProcessQueue());
+  }
 }
diff --git a/tools/testing/dart/co19_test.dart b/tools/testing/dart/co19_test.dart
index bcdf925..8b02ed1 100644
--- a/tools/testing/dart/co19_test.dart
+++ b/tools/testing/dart/co19_test.dart
@@ -41,7 +41,7 @@
       new Path(scriptFile.fullPathSync())
       .directoryPath.directoryPath.directoryPath.append('test.dart');
   TestUtils.testScriptPath = scriptPath.toNativePath();
-  var startTime = new Date.now();
+  var startTime = new DateTime.now();
   var optionsParser = new TestOptionsParser();
   List<Map> configurations = <Map>[];
   for (var commandLine in COMMAND_LINES) {
diff --git a/tools/testing/dart/http_server.dart b/tools/testing/dart/http_server.dart
index d065e0b..4e68894 100644
--- a/tools/testing/dart/http_server.dart
+++ b/tools/testing/dart/http_server.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -71,9 +71,10 @@
     var crossOriginPort = int.parse(args['crossOriginPort']);
     servers.startServers(args['network'],
                          port: port,
-                         crossOriginPort: crossOriginPort);
-    DebugLogger.info('Server listening on port ${servers.port}');
-    DebugLogger.info('Server listening on port ${servers.crossOriginPort}');
+                         crossOriginPort: crossOriginPort).then((_) {
+      DebugLogger.info('Server listening on port ${servers.port}');
+      DebugLogger.info('Server listening on port ${servers.crossOriginPort}');
+    });
   }
 }
 
@@ -101,11 +102,12 @@
    *   "Access-Control-Allow-Origin: client:port1
    *   "Access-Control-Allow-Credentials: true"
    */
-  void startServers(String host, {int port: 0, int crossOriginPort: 0}) {
-    _startHttpServer(host, port: port);
-    _startHttpServer(host,
-                     port: crossOriginPort,
-                     allowedPort:_serverList[0].port);
+  Future startServers(String host, {int port: 0, int crossOriginPort: 0}) {
+    return _startHttpServer(host, port: port).then((server) {
+      return _startHttpServer(host,
+                              port: crossOriginPort,
+                              allowedPort:_serverList[0].port);
+    });
   }
 
   String httpServerCommandline() {
@@ -125,25 +127,27 @@
     }
   }
 
-  void _startHttpServer(String host, {int port: 0, int allowedPort: -1}) {
-    var httpServer = new HttpServer();
-    httpServer.onError = (e) {
-      DebugLogger.error('HttpServer: an error occured: $e');
-    };
-    httpServer.defaultRequestHandler = (request, response) {
-      _handleFileOrDirectoryRequest(request, response, allowedPort);
-    };
-    httpServer.addRequestHandler(
-        (req) => req.path == "/echo", _handleEchoRequest);
-
-    httpServer.listen(host, port);
-    _serverList.add(httpServer);
+  Future _startHttpServer(String host, {int port: 0, int allowedPort: -1}) {
+    return HttpServer.bind(host, port).then((HttpServer httpServer) {
+      httpServer.listen((HttpRequest request) {
+        if (request.uri.path == "/echo") {
+          _handleEchoRequest(request, request.response);
+        } else {
+          _handleFileOrDirectoryRequest(
+              request, request.response, allowedPort);
+        }
+      },
+      onError: (e) {
+        DebugLogger.error('HttpServer: an error occured: $e');
+      });
+      _serverList.add(httpServer);
+    });
   }
 
   void _handleFileOrDirectoryRequest(HttpRequest request,
                                      HttpResponse response,
                                      int allowedPort) {
-    var path = _getFilePathFromRequestPath(request.path);
+    var path = _getFilePathFromRequestPath(request.uri.path);
     if (path != null) {
       var file = new File.fromPath(path);
       file.exists().then((exists) {
@@ -163,7 +167,7 @@
         }
       });
     } else {
-      if (request.path == '/') {
+      if (request.uri.path == '/') {
         var entries = [new _Entry('root_dart', 'root_dart/'),
                        new _Entry('root_build', 'root_build/'),
                        new _Entry('echo', 'echo')];
@@ -176,7 +180,10 @@
 
   void _handleEchoRequest(HttpRequest request, HttpResponse response) {
     response.headers.set("Access-Control-Allow-Origin", "*");
-    request.inputStream.pipe(response.outputStream);
+    request.pipe(response).catchError((e) {
+      DebugLogger.warning(
+          'HttpServer: error while closing the response stream: $e');
+    });
   }
 
   Path _getFilePathFromRequestPath(String urlRequestPath) {
@@ -189,20 +196,18 @@
       if (pathSegments[0] == PREFIX_BUILDDIR) {
         basePath = _buildDirectory;
         relativePath = new Path(
-            pathSegments.getRange(1, pathSegments.length - 1).join('/'));
+            pathSegments.skip(1).join('/'));
       } else if (pathSegments[0] == PREFIX_DARTDIR) {
         basePath = TestUtils.dartDir();
         relativePath = new Path(
-            pathSegments.getRange(1, pathSegments.length - 1).join('/'));
+            pathSegments.skip(1).join('/'));
       }
       var packagesDirName = 'packages';
       var packagesIndex = pathSegments.indexOf(packagesDirName);
       if (packagesIndex != -1) {
         var start = packagesIndex + 1;
-        var length = pathSegments.length - start;
         basePath = _buildDirectory.append(packagesDirName);
-        relativePath = new Path(
-            pathSegments.getRange(start, length).join('/'));
+        relativePath = new Path(pathSegments.skip(start).join('/'));
       }
       if (basePath != null && relativePath != null) {
         return basePath.join(relativePath);
@@ -215,18 +220,18 @@
     var completer = new Completer();
     var entries = [];
 
-    directory.list()
-      ..onFile = (filepath) {
-        var filename = new Path(filepath).filename;
-        entries.add(new _Entry(filename, filename));
-      }
-      ..onDir = (dirpath) {
-        var filename = new Path(dirpath).filename;
-        entries.add(new _Entry(filename, '$filename/'));
-      }
-      ..onDone = (_) {
+    directory.list().listen(
+      (FileSystemEntity fse) {
+        var filename = new Path(fse.path).filename;
+        if (fse is File) {
+          entries.add(new _Entry(filename, filename));
+        } else if (fse is Directory) {
+          entries.add(new _Entry(filename, '$filename/'));
+        }
+      },
+      onDone: () {
         completer.complete(entries);
-      };
+      });
     return completer.future;
   }
 
@@ -237,11 +242,11 @@
     var header = '''<!DOCTYPE html>
     <html>
     <head>
-      <title>${request.path}</title>
+      <title>${request.uri.path}</title>
     </head>
     <body>
       <code>
-        <div>${request.path}</div>
+        <div>${request.uri.path}</div>
         <hr/>
         <ul>''';
     var footer = '''
@@ -252,14 +257,18 @@
 
 
     entries.sort();
-    response.outputStream.writeString(header);
+    response.write(header);
     for (var entry in entries) {
-      response.outputStream.writeString(
-          '<li><a href="${new Path(request.path).append(entry.name)}">'
+      response.write(
+          '<li><a href="${new Path(request.uri.path).append(entry.name)}">'
           '${entry.displayName}</a></li>');
     }
-    response.outputStream.writeString(footer);
-    response.outputStream.close();
+    response.write(footer);
+    response.close();
+    response.done.catchError((e) {
+      DebugLogger.warning(
+          'HttpServer: error while closing the response stream: $e');
+    });
   }
 
   void _sendFileContent(HttpRequest request,
@@ -296,26 +305,26 @@
     } else if (path.filename.endsWith('.dart')) {
       response.headers.set('Content-Type', 'application/dart');
     }
-    file.openInputStream().pipe(response.outputStream);
+    file.openRead().pipe(response).catchError((e) {
+      DebugLogger.warning(
+          'HttpServer: error while closing the response stream: $e');
+    });
   }
 
   void _sendNotFound(HttpRequest request, HttpResponse response) {
     // NOTE: Since some tests deliberately try to access non-existent files.
     // We might want to remove this warning (otherwise it will show
     // up in the debug.log every time).
-    DebugLogger.warning('HttpServer: could not find file for request path: '
-                        '"${request.path}"');
-    response.statusCode = HttpStatus.NOT_FOUND;
-    try {
-      response.outputStream.close();
-    } catch (e) {
-      if (e is StreamException) {
-        DebugLogger.warning('HttpServer: error while closing the response '
-                            'stream: $e');
-      } else {
-        throw e;
-      }
+    if (request.uri.path != "/favicon.ico") {
+      DebugLogger.warning('HttpServer: could not find file for request path: '
+                          '"${request.uri.path}"');
     }
+    response.statusCode = HttpStatus.NOT_FOUND;
+    response.close();
+    response.done.catchError((e) {
+      DebugLogger.warning(
+          'HttpServer: error while closing the response stream: $e');
+    });
   }
 }
 
diff --git a/tools/testing/dart/multitest.dart b/tools/testing/dart/multitest.dart
index 585502c..44ba773 100644
--- a/tools/testing/dart/multitest.dart
+++ b/tools/testing/dart/multitest.dart
@@ -137,12 +137,11 @@
       return null;
     }
     var annotation = new _Annotation();
-    var parts = line.split('///')[1].split(':')
-        .mappedBy((s) => s.trim()).toList();
+    var parts = line.split('///')[1].split(':').map((s) => s.trim()).toList();
     annotation.key = parts[0];
     annotation.rest = parts[1];
     annotation.outcomesList = annotation.rest.split(',')
-        .mappedBy((s) => s.trim()).toList();
+        .map((s) => s.trim()).toList();
     return annotation;
   }
 }
@@ -151,7 +150,7 @@
 // the generated tests.
 Set<Path> _findAllRelativeImports(Path topLibrary) {
   Set<Path> toSearch = new Set<Path>.from([topLibrary]);
-  Set<Path> foundImports = new HashSet<Path>();
+  Set<Path> foundImports = new Set<Path>();
   Path libraryDir = topLibrary.directoryPath;
   // Matches #import( or #source( followed by " or ' followed by anything
   // except dart:, dart-ext: or /, at the beginning of a line.
@@ -159,7 +158,7 @@
       '^#(import|source)[(]["\'](?!(dart:|dart-ext:|/))([^"\']*)["\']');
   while (!toSearch.isEmpty) {
     var thisPass = toSearch;
-    toSearch = new HashSet<Path>();
+    toSearch = new Set<Path>();
     for (Path filename in thisPass) {
       File f = new File.fromPath(filename);
       for (String line in f.readAsLinesSync()) {
@@ -219,8 +218,7 @@
 
       file.createSync();
       RandomAccessFile openedFile = file.openSync(FileMode.WRITE);
-      var bytes = tests[key].charCodes;
-      openedFile.writeListSync(bytes, 0, bytes.length);
+      openedFile.writeStringSync(tests[key]);
       openedFile.closeSync();
       Set<String> outcome = outcomes[key];
       bool enableFatalTypeErrors = outcome.contains('static type warning');
diff --git a/tools/testing/dart/status_file_parser.dart b/tools/testing/dart/status_file_parser.dart
index d314581..dc3d5fe 100644
--- a/tools/testing/dart/status_file_parser.dart
+++ b/tools/testing/dart/status_file_parser.dart
@@ -4,6 +4,7 @@
 
 library status_file_parser;
 
+import "dart:async";
 import "dart:io";
 import "status_expression.dart";
 
@@ -65,49 +66,45 @@
   if (!file.existsSync()) {
     throw new Exception('Cannot find test status file $path');
   }
-  InputStream file_stream = file.openInputStream();
-  StringInputStream lines = new StringInputStream(file_stream);
+  Stream<String> lines =
+      file.openRead()
+          .transform(new StringDecoder())
+          .transform(new LineTransformer());
 
   Section current = new Section.always();
   sections.add(current);
 
-  lines.onLine = () {
-    String line;
-    while ((line = lines.readLine()) != null) {
-      Match match = StripComment.firstMatch(line);
-      line = (match == null) ? "" : match[0];
-      line = line.trim();
-      if (line.isEmpty) continue;
+  lines.listen((String line) {
+    Match match = StripComment.firstMatch(line);
+    line = (match == null) ? "" : match[0];
+    line = line.trim();
+    if (line.isEmpty) return;
 
-      match = HeaderPattern.firstMatch(line);
-      if (match != null) {
-        String condition_string = match[1].trim();
-        List<String> tokens = new Tokenizer(condition_string).tokenize();
-        ExpressionParser parser = new ExpressionParser(new Scanner(tokens));
-        current = new Section(parser.parseBooleanExpression());
-        sections.add(current);
-        continue;
-      }
-
-      match = RulePattern.firstMatch(line);
-      if (match != null) {
-        String name = match[1].trim();
-        // TODO(whesse): Handle test names ending in a wildcard (*).
-        String expression_string = match[2].trim();
-        List<String> tokens = new Tokenizer(expression_string).tokenize();
-        SetExpression expression =
-            new ExpressionParser(new Scanner(tokens)).parseSetExpression();
-        current.testRules.add(new TestRule(name, expression));
-        continue;
-      }
-
-      print("unmatched line: $line");
+    match = HeaderPattern.firstMatch(line);
+    if (match != null) {
+      String condition_string = match[1].trim();
+      List<String> tokens = new Tokenizer(condition_string).tokenize();
+      ExpressionParser parser = new ExpressionParser(new Scanner(tokens));
+      current = new Section(parser.parseBooleanExpression());
+      sections.add(current);
+      return;
     }
-  };
 
-  lines.onClosed = () {
-    onDone();
-  };
+    match = RulePattern.firstMatch(line);
+    if (match != null) {
+      String name = match[1].trim();
+      // TODO(whesse): Handle test names ending in a wildcard (*).
+      String expression_string = match[2].trim();
+      List<String> tokens = new Tokenizer(expression_string).tokenize();
+      SetExpression expression =
+          new ExpressionParser(new Scanner(tokens)).parseSetExpression();
+      current.testRules.add(new TestRule(name, expression));
+      return;
+    }
+
+    print("unmatched line: $line");
+  },
+  onDone: onDone);
 }
 
 
diff --git a/tools/testing/dart/test_options.dart b/tools/testing/dart/test_options.dart
index d6ca633..4a58683 100644
--- a/tools/testing/dart/test_options.dart
+++ b/tools/testing/dart/test_options.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -12,7 +12,7 @@
 List<String> defaultTestSelectors =
     const ['dartc', 'samples', 'standalone', 'corelib', 'co19', 'language',
            'isolate', 'vm', 'html', 'json', 'benchmark_smoke',
-           'utils', 'lib', 'pkg'];
+           'utils', 'lib', 'pkg', 'analyze_library'];
 
 /**
  * Specification of a single test option.
@@ -77,9 +77,12 @@
          safari, ie9, ie10, firefox, opera, none (compile only)),
 
    dartc: Perform static analysis on Dart code by running dartc.
+          (only valid with the following runtimes: none),
+
+   new_analyzer: Perform static analysis on Dart code by running the analyzer.
           (only valid with the following runtimes: none)''',
               ['-c', '--compiler'],
-              ['none', 'dart2dart', 'dart2js', 'dartc'],
+              ['none', 'dart2dart', 'dart2js', 'dartc', 'new_analyzer'],
               'none'),
           new _TestOptionSpecification(
               'runtime',
@@ -156,7 +159,7 @@
               'Progress indication mode',
               ['-p', '--progress'],
               ['compact', 'color', 'line', 'verbose',
-               'silent', 'status', 'buildbot'],
+               'silent', 'status', 'buildbot', 'diff'],
               'compact'),
           new _TestOptionSpecification(
               'step_name',
@@ -432,6 +435,7 @@
                                'opera'];
         break;
       case 'dartc':
+      case 'new_analyzer':
         validRuntimes = const ['none'];
         break;
       case 'none':
@@ -474,7 +478,7 @@
   List<Map> _expandConfigurations(Map configuration) {
     // Expand the pseudo-values such as 'all'.
     if (configuration['arch'] == 'all') {
-      configuration['arch'] = 'ia32,x64';
+      configuration['arch'] = 'ia32,x64,simarm,simmips';
     }
     if (configuration['mode'] == 'all') {
       configuration['mode'] = 'debug,release';
@@ -508,8 +512,10 @@
       configuration['runtime'] == 'ff';
     }
 
+    String compiler = configuration['compiler'];
     configuration['browser'] = TestUtils.isBrowserRuntime(runtime);
-
+    configuration['analyzer'] = TestUtils.isCommandLineAnalyzer(compiler);
+    
     // Set the javascript command line flag for less verbose status files.
     configuration['jscl'] = TestUtils.isJsCommandLineRuntime(runtime);
 
@@ -577,6 +583,7 @@
       var timeout = 60;
       switch (configuration['compiler']) {
         case 'dartc':
+        case 'new_analyzer':
           timeout *= 4;
           break;
         case 'dart2js':
@@ -648,24 +655,24 @@
       for (var name in option.keys) {
         assert(name.startsWith('-'));
         var buffer = new StringBuffer();;
-        buffer.add(name);
+        buffer.write(name);
         if (option.type == 'bool') {
           assert(option.values.isEmpty);
         } else {
-          buffer.add(name.startsWith('--') ? '=' : ' ');
+          buffer.write(name.startsWith('--') ? '=' : ' ');
           if (option.type == 'int') {
             assert(option.values.isEmpty);
-            buffer.add('n (default: ${option.defaultValue})');
+            buffer.write('n (default: ${option.defaultValue})');
           } else {
-            buffer.add('[');
+            buffer.write('[');
             bool first = true;
             for (var value in option.values) {
-              if (!first) buffer.add(", ");
-              if (value == option.defaultValue) buffer.add('*');
-              buffer.add(value);
+              if (!first) buffer.write(", ");
+              if (value == option.defaultValue) buffer.write('*');
+              buffer.write(value);
               first = false;
             }
-            buffer.add(']');
+            buffer.write(']');
           }
         }
         print(buffer.toString());
diff --git a/tools/testing/dart/test_progress.dart b/tools/testing/dart/test_progress.dart
index b6d5d29..20a6646 100644
--- a/tools/testing/dart/test_progress.dart
+++ b/tools/testing/dart/test_progress.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -12,227 +12,141 @@
 import "test_suite.dart";
 import "utils.dart";
 
-class ProgressIndicator {
-  ProgressIndicator(this._startTime, this._printTiming)
-      : _tests = [], _failureSummary = [];
+String _pad(String s, int length) {
+  StringBuffer buffer = new StringBuffer();
+  for (int i = s.length; i < length; i++) {
+    buffer.write(' ');
+  }
+  buffer.write(s);
+  return buffer.toString();
+}
 
-  factory ProgressIndicator.fromName(String name,
-                                     Date startTime,
-                                     bool printTiming) {
-    switch (name) {
-      case 'compact':
-        return new CompactProgressIndicator(startTime, printTiming);
-      case 'color':
-        return new ColorProgressIndicator(startTime, printTiming);
-      case 'line':
-        return new LineProgressIndicator(startTime, printTiming);
-      case 'verbose':
-        return new VerboseProgressIndicator(startTime, printTiming);
-      case 'silent':
-        return new SilentProgressIndicator(startTime, printTiming);
-      case 'status':
-        return new StatusProgressIndicator(startTime, printTiming);
-      case 'buildbot':
-        return new BuildbotProgressIndicator(startTime, printTiming);
-      case 'diff':
-        return new DiffProgressIndicator(startTime, printTiming);
-      default:
-        assert(false);
-        break;
+String _padTime(int time) {
+  if (time == 0) {
+    return '00';
+  } else if (time < 10) {
+    return '0$time';
+  } else {
+    return '$time';
+  }
+}
+
+String _timeString(Duration d) {
+  var min = d.inMinutes;
+  var sec = d.inSeconds % 60;
+  return '${_padTime(min)}:${_padTime(sec)}';
+}
+
+class Formatter {
+  const Formatter();
+  String passed(msg) => msg;
+  String failed(msg) => msg;
+}
+
+class ColorFormatter extends Formatter {
+  static int BOLD = 1;
+  static int GREEN = 32;
+  static int RED = 31;
+  static int NONE = 0;
+  static String ESCAPE = decodeUtf8([27]);
+
+  String passed(String msg) => _color(msg, GREEN);
+  String failed(String msg) => _color(msg, RED);
+
+  static String _color(String msg, int color) {
+    return "$ESCAPE[${color}m$msg$ESCAPE[0m";
+  }
+}
+
+
+List<String> _buildFailureOutput(TestCase test,
+                                 [Formatter formatter = const Formatter()]) {
+  List<String> output = new List<String>();
+  output.add('');
+  output.add(formatter.failed('FAILED: ${test.configurationString}'
+                              ' ${test.displayName}'));
+  StringBuffer expected = new StringBuffer();
+  expected.write('Expected: ');
+  for (var expectation in test.expectedOutcomes) {
+    expected.write('$expectation ');
+  }
+  output.add(expected.toString());
+  output.add('Actual: ${test.lastCommandOutput.result}');
+  if (!test.lastCommandOutput.hasTimedOut && test.info != null) {
+    if (test.lastCommandOutput.incomplete && !test.info.hasCompileError) {
+      output.add('Unexpected compile-time error.');
+    } else {
+      if (test.info.hasCompileError) {
+        output.add('Compile-time error expected.');
+      }
+      if (test.info.hasRuntimeError) {
+        output.add('Runtime error expected.');
+      }
     }
   }
-
-  void testAdded() { _foundTests++; }
-
-  void start(TestCase test) {
-    _printStartProgress(test);
+  if (!test.lastCommandOutput.diagnostics.isEmpty) {
+    String prefix = 'diagnostics:';
+    for (var s in test.lastCommandOutput.diagnostics) {
+      output.add('$prefix ${s}');
+      prefix = '   ';
+    }
   }
+  if (!test.lastCommandOutput.stdout.isEmpty) {
+    output.add('');
+    output.add('stdout:');
+    if (test.lastCommandOutput.command.isPixelTest) {
+      output.add('DRT pixel test failed! stdout is not printed because it '
+                 'contains binary data!');
+    } else {
+      output.add(decodeUtf8(test.lastCommandOutput.stdout));
+    }
+  }
+  if (!test.lastCommandOutput.stderr.isEmpty) {
+    output.add('');
+    output.add('stderr:');
+    output.add(decodeUtf8(test.lastCommandOutput.stderr));
+  }
+  if (test is BrowserTestCase) {
+    // Additional command for rerunning the steps locally after the fact.
+    var command =
+      test.configuration["_servers_"].httpServerCommandline();
+    output.add('To retest, run:  $command');
+  }
+  for (Command c in test.commands) {
+    output.add('');
+    String message = (c == test.commands.last
+        ? "Command line" : "Compilation command");
+    output.add('$message: $c');
+  }
+  return output;
+}
 
+
+class EventListener {
+  void testAdded() { }
+  void start(TestCase test) { }
+  void done(TestCase test) { }
+  void allTestsKnown() { }
+  void allDone() { }
+}
+
+class ExitCodeSetter extends EventListener {
+  void done(TestCase test) {
+    if (test.lastCommandOutput.unexpectedOutput) {
+      io.exitCode = 1;
+    }
+  }
+}
+
+class FlakyLogWriter extends EventListener {
   void done(TestCase test) {
     if (test.isFlaky && test.lastCommandOutput.result != PASS) {
       var buf = new StringBuffer();
       for (var l in _buildFailureOutput(test)) {
-        buf.add("$l\n");
+        buf.write("$l\n");
       }
       _appendToFlakyFile(buf.toString());
     }
-    for (var commandOutput in test.commandOutputs.values) {
-      if (commandOutput.compilationSkipped)
-        _skippedCompilations++;
-    }
-
-    if (test.lastCommandOutput.unexpectedOutput) {
-      _failedTests++;
-      _printFailureOutput(test);
-    } else {
-      _passedTests++;
-    }
-    _printDoneProgress(test);
-    // If we need to print timing information we hold on to all completed
-    // tests.
-    if (_printTiming) _tests.add(test);
-  }
-
-  void allTestsKnown() {
-    if (!_allTestsKnown) SummaryReport.printReport();
-    _allTestsKnown = true;
-  }
-
-  void _printSkippedCompilationInfo() {
-    if (_skippedCompilations > 0) {
-      print('\n$_skippedCompilations compilations were skipped because '
-            'the previous output was already up to date\n');
-    }
-  }
-
-  void _printTimingInformation() {
-    if (_printTiming) {
-      // TODO: We should take all the commands into account
-      Duration d = (new Date.now()).difference(_startTime);
-      print('\n--- Total time: ${_timeString(d)} ---');
-      _tests.sort((a, b) {
-        Duration aDuration = a.lastCommandOutput.time;
-        Duration bDuration = b.lastCommandOutput.time;
-        return bDuration.inMilliseconds - aDuration.inMilliseconds;
-      });
-      for (int i = 0; i < 20 && i < _tests.length; i++) {
-        var name = _tests[i].displayName;
-        var duration = _tests[i].lastCommandOutput.time;
-        var configuration = _tests[i].configurationString;
-        print('${duration} - $configuration $name');
-      }
-    }
-  }
-
-  void allDone() {
-    _printFailureSummary();
-    _printStatus();
-    _printSkippedCompilationInfo();
-    _printTimingInformation();
-    stdout.close();
-    stderr.close();
-    if (_failedTests > 0) {
-      io.exitCode = 1;
-    }
-  }
-
-  void _printStartProgress(TestCase test) {}
-  void _printDoneProgress(TestCase test) {}
-
-  String _pad(String s, int length) {
-    StringBuffer buffer = new StringBuffer();
-    for (int i = s.length; i < length; i++) {
-      buffer.add(' ');
-    }
-    buffer.add(s);
-    return buffer.toString();
-  }
-
-  String _padTime(int time) {
-    if (time == 0) {
-      return '00';
-    } else if (time < 10) {
-      return '0$time';
-    } else {
-      return '$time';
-    }
-  }
-
-  String _timeString(Duration d) {
-    var min = d.inMinutes;
-    var sec = d.inSeconds % 60;
-    return '${_padTime(min)}:${_padTime(sec)}';
-  }
-
-  String _header(String header) => header;
-
-  void _printFailureOutput(TestCase test) {
-    var failureOutput = _buildFailureOutput(test);
-    for (var line in failureOutput) {
-      print(line);
-    }
-    _failureSummary.addAll(failureOutput);
-  }
-
-  List<String> _buildFailureOutput(TestCase test) {
-    List<String> output = new List<String>();
-    output.add('');
-    output.add(_header('FAILED: ${test.configurationString}'
-                       ' ${test.displayName}'));
-    StringBuffer expected = new StringBuffer();
-    expected.add('Expected: ');
-    for (var expectation in test.expectedOutcomes) {
-      expected.add('$expectation ');
-    }
-    output.add(expected.toString());
-    output.add('Actual: ${test.lastCommandOutput.result}');
-    if (!test.lastCommandOutput.hasTimedOut && test.info != null) {
-      if (test.lastCommandOutput.incomplete && !test.info.hasCompileError) {
-        output.add('Unexpected compile-time error.');
-      } else {
-        if (test.info.hasCompileError) {
-          output.add('Compile-time error expected.');
-        }
-        if (test.info.hasRuntimeError) {
-          output.add('Runtime error expected.');
-        }
-      }
-    }
-    if (!test.lastCommandOutput.diagnostics.isEmpty) {
-      String prefix = 'diagnostics:';
-      for (var s in test.lastCommandOutput.diagnostics) {
-        output.add('$prefix ${s}');
-        prefix = '   ';
-      }
-    }
-    if (!test.lastCommandOutput.stdout.isEmpty) {
-      output.add('');
-      output.add('stdout:');
-      if (test.lastCommandOutput.command.isPixelTest) {
-        output.add('DRT pixel test failed! stdout is not printed because it '
-                   'contains binary data!');
-      } else {
-        output.add(decodeUtf8(test.lastCommandOutput.stdout));
-      }
-    }
-    if (!test.lastCommandOutput.stderr.isEmpty) {
-      output.add('');
-      output.add('stderr:');
-      output.add(decodeUtf8(test.lastCommandOutput.stderr));
-    }
-    if (test is BrowserTestCase) {
-      // Additional command for rerunning the steps locally after the fact.
-      var command =
-        test.configuration["_servers_"].httpServerCommandline();
-      output.add('To retest, run:  $command');
-    }
-    for (Command c in test.commands) {
-      output.add('');
-      String message = (c == test.commands.last
-          ? "Command line" : "Compilation command");
-      output.add('$message: $c');
-    }
-    return output;
-  }
-
-  void _printFailureSummary() {
-    for (String line in _failureSummary) {
-      print(line);
-    }
-    print('');
-  }
-
-  void _printStatus() {
-    if (_failedTests == 0) {
-      print('\n===');
-      print('=== All tests succeeded');
-      print('===\n');
-    } else {
-      var pluralSuffix = _failedTests != 1 ? 's' : '';
-      print('\n===');
-      print('=== ${_failedTests} test$pluralSuffix failed');
-      print('===\n');
-    }
   }
 
   void _appendToFlakyFile(String msg) {
@@ -241,213 +155,58 @@
     fd.writeStringSync(msg);
     fd.closeSync();
   }
-
-  int get numFailedTests => _failedTests;
-
-  int _completedTests() => _passedTests + _failedTests;
-
-  int _foundTests = 0;
-  int _passedTests = 0;
-  int _failedTests = 0;
-  int _skippedCompilations = 0;
-  bool _allTestsKnown = false;
-  Date _startTime;
-  bool _printTiming;
-  List<TestCase> _tests;
-  List<String> _failureSummary;
 }
 
-
-class SilentProgressIndicator extends ProgressIndicator {
-  SilentProgressIndicator(Date startTime, bool printTiming)
-      : super(startTime, printTiming);
-  void testAdded() { }
-  void start(TestCase test) { }
-  void done(TestCase test) { }
-  void _printStartProgress(TestCase test) { }
-  void _printDoneProgress(TestCase test) { }
-  void allTestsKnown() { }
-  void allDone() { }
-}
-
-abstract class CompactIndicator extends ProgressIndicator {
-  CompactIndicator(Date startTime, bool printTiming)
-      : super(startTime, printTiming);
-
-  void allDone() {
-    stdout.write('\n'.charCodes);
-    _printFailureSummary();
-    _printSkippedCompilationInfo();
-    _printTimingInformation();
-    if (_failedTests > 0) {
-      // We may have printed many failure logs, so reprint the summary data.
-      _printProgress();
-      print('');
-    }
-    stdout.close();
-    stderr.close();
-    if (_failedTests > 0) {
-      io.exitCode = 1;
-    }
-  }
-
+class SummaryPrinter extends EventListener {
   void allTestsKnown() {
-    if (!_allTestsKnown && SummaryReport.total > 0) {
-      // Clear progress indicator before printing summary report.
-      stdout.write(
-          '\r                                               \r'.charCodes);
+    if (SummaryReport.total > 0) {
       SummaryReport.printReport();
     }
-    _allTestsKnown = true;
-  }
-
-  void _printStartProgress(TestCase test) => _printProgress();
-  void _printDoneProgress(TestCase test) => _printProgress();
-
-  void _printProgress();
-}
-
-
-class CompactProgressIndicator extends CompactIndicator {
-  CompactProgressIndicator(Date startTime, bool printTiming)
-      : super(startTime, printTiming);
-
-  void _printProgress() {
-    var percent = ((_completedTests() / _foundTests) * 100).toInt().toString();
-    var progressPadded = _pad(_allTestsKnown ? percent : '--', 3);
-    var passedPadded = _pad(_passedTests.toString(), 5);
-    var failedPadded = _pad(_failedTests.toString(), 5);
-    Duration d = (new Date.now()).difference(_startTime);
-    var progressLine =
-        '\r[${_timeString(d)} | $progressPadded% | '
-        '+$passedPadded | -$failedPadded]';
-    stdout.write(progressLine.charCodes);
   }
 }
 
+class TimingPrinter extends EventListener {
+  List<TestCase> _tests = <TestCase>[];
+  DateTime _startTime;
 
-class ColorProgressIndicator extends CompactIndicator {
-  ColorProgressIndicator(Date startTime, bool printTiming)
-      : super(startTime, printTiming);
+  TimingPrinter(this._startTime);
 
-  static int BOLD = 1;
-  static int GREEN = 32;
-  static int RED = 31;
-  static int NONE = 0;
-
-  addColorWrapped(List<int> codes, String string, int color) {
-    codes.add(27);
-    codes.addAll('[${color}m'.charCodes);
-    codes.addAll(encodeUtf8(string));
-    codes.add(27);
-    codes.addAll('[0m'.charCodes);
+  void done(TestCase testCase) {
+    _tests.add(testCase);
   }
 
-  void _printProgress() {
-    var percent = ((_completedTests() / _foundTests) * 100).toInt().toString();
-    var progressPadded = _pad(_allTestsKnown ? percent : '--', 3);
-    var passedPadded = _pad(_passedTests.toString(), 5);
-    var failedPadded = _pad(_failedTests.toString(), 5);
-    Duration d = (new Date.now()).difference(_startTime);
-    var progressLine = [];
-    progressLine.addAll('\r[${_timeString(d)} | $progressPadded% | '.charCodes);
-    addColorWrapped(progressLine, '+$passedPadded ', GREEN);
-    progressLine.addAll('| '.charCodes);
-    var failedColor = (_failedTests != 0) ? RED : NONE;
-    addColorWrapped(progressLine, '-$failedPadded', failedColor);
-    progressLine.addAll(']'.charCodes);
-    stdout.write(progressLine);
-  }
-
-  String _header(String header) {
-    var result = [];
-    addColorWrapped(result, header, BOLD);
-    return decodeUtf8(result);
+  void allDone() {
+    // TODO: We should take all the commands into account
+    Duration d = (new DateTime.now()).difference(_startTime);
+    print('\n--- Total time: ${_timeString(d)} ---');
+    _tests.sort((a, b) {
+      Duration aDuration = a.lastCommandOutput.time;
+      Duration bDuration = b.lastCommandOutput.time;
+      return bDuration.inMilliseconds - aDuration.inMilliseconds;
+    });
+    for (int i = 0; i < 20 && i < _tests.length; i++) {
+      var name = _tests[i].displayName;
+      var duration = _tests[i].lastCommandOutput.time;
+      var configuration = _tests[i].configurationString;
+      print('${duration} - $configuration $name');
+    }
   }
 }
 
+class StatusFileUpdatePrinter extends EventListener {
+  var statusToConfigs = new Map<String, List<String>>();
+  var _failureSummary = <String>[];
 
-class LineProgressIndicator extends ProgressIndicator {
-  LineProgressIndicator(Date startTime, bool printTiming)
-      : super(startTime, printTiming);
-
-  void _printStartProgress(TestCase test) {
-  }
-
-  void _printDoneProgress(TestCase test) {
-    var status = 'pass';
+  void done(TestCase test) {
     if (test.lastCommandOutput.unexpectedOutput) {
-      status = 'fail';
+      _printFailureOutput(test);
     }
-    print('Done ${test.configurationString} ${test.displayName}: $status');
-  }
-}
-
-
-class VerboseProgressIndicator extends ProgressIndicator {
-  VerboseProgressIndicator(Date startTime, bool printTiming)
-      : super(startTime, printTiming);
-
-  void _printStartProgress(TestCase test) {
-    print('Starting ${test.configurationString} ${test.displayName}...');
   }
 
-  void _printDoneProgress(TestCase test) {
-    var status = 'pass';
-    if (test.lastCommandOutput.unexpectedOutput) {
-      status = 'fail';
-    }
-    print('Done ${test.configurationString} ${test.displayName}: $status');
-  }
-}
-
-
-class StatusProgressIndicator extends ProgressIndicator {
-  StatusProgressIndicator(Date startTime, bool printTiming)
-      : super(startTime, printTiming);
-
-  void _printStartProgress(TestCase test) {
+  void allDone() {
+    _printFailureSummary();
   }
 
-  void _printDoneProgress(TestCase test) {
-  }
-}
-
-
-class BuildbotProgressIndicator extends ProgressIndicator {
-  static String stepName;
-
-  BuildbotProgressIndicator(Date startTime, bool printTiming)
-      : super(startTime, printTiming);
-
-  void _printStartProgress(TestCase test) {
-  }
-
-  void _printDoneProgress(TestCase test) {
-    var status = 'pass';
-    if (test.lastCommandOutput.unexpectedOutput) {
-      status = 'fail';
-    }
-    var percent = ((_completedTests() / _foundTests) * 100).toInt().toString();
-    print('Done ${test.configurationString} ${test.displayName}: $status');
-    print('@@@STEP_CLEAR@@@');
-    print('@@@STEP_TEXT@ $percent% +$_passedTests -$_failedTests @@@');
-  }
-
-  void _printFailureSummary() {
-    if (!_failureSummary.isEmpty && stepName != null) {
-      print('@@@STEP_FAILURE@@@');
-      print('@@@BUILD_STEP $stepName failures@@@');
-    }
-    super._printFailureSummary();
-  }
-}
-
-class DiffProgressIndicator extends ColorProgressIndicator {
-  Map<String, List<String>> statusToConfigs = new Map<String, List<String>>();
-
-  DiffProgressIndicator(Date startTime, bool printTiming)
-      : super(startTime, printTiming);
 
   void _printFailureOutput(TestCase test) {
     String status = '${test.displayName}: ${test.lastCommandOutput.result}';
@@ -467,13 +226,12 @@
   }
 
   void _printFailureSummary() {
-    Map<String, List<String>> groupedStatuses = new Map<String, List<String>>();
+    var groupedStatuses = new Map<String, List<String>>();
     statusToConfigs.forEach((String status, List<String> configs) {
-      Map<String, List<String>> runtimeToConfiguration =
-          new Map<String, List<String>>();
+      var runtimeToConfiguration = new Map<String, List<String>>();
       for (String config in configs) {
         String runtime = _extractRuntime(config);
-        List<String> runtimeConfigs =
+        var runtimeConfigs =
             runtimeToConfiguration.putIfAbsent(runtime, () => <String>[]);
         runtimeConfigs.add(config);
       }
@@ -486,15 +244,257 @@
         statuses.add(status);
       });
     });
+
+    print('\n\nNecessary status file updates:');
     groupedStatuses.forEach((String config, List<String> statuses) {
       print('');
-      print('');
       print('$config:');
       statuses.sort((a, b) => a.compareTo(b));
       for (String status in statuses) {
         print('  $status');
       }
     });
+  }
+}
+
+class SkippedCompilationsPrinter extends EventListener {
+  int _skippedCompilations = 0;
+
+  void done(TestCase test) {
+    for (var commandOutput in test.commandOutputs.values) {
+      if (commandOutput.compilationSkipped)
+        _skippedCompilations++;
+    }
+  }
+
+  void allDone() {
+    if (_skippedCompilations > 0) {
+      print('\n$_skippedCompilations compilations were skipped because '
+            'the previous output was already up to date\n');
+    }
+  }
+}
+
+class LeftOverTempDirPrinter extends EventListener {
+  final MIN_NUMBER_OF_TEMP_DIRS = 50;
+
+  Path _tempDir() {
+    // Dir will be located in the system temporary directory.
+    var dir = new Directory('').createTempSync();
+    var path = new Path(dir.path).directoryPath;
+    dir.deleteSync();
+    return path;
+  }
+
+  void allDone() {
+    var count = 0;
+    var systemTempDir = _tempDir();
+    var lister = new Directory.fromPath(systemTempDir).list().listen(
+        (FileSystemEntity fse) {
+          if (fse is Directory) count++;
+        },
+        onDone: () {
+          if (count > MIN_NUMBER_OF_TEMP_DIRS) {
+            DebugLogger.warning("There are ${count} directories "
+                                "in the system tempdir ('$systemTempDir')! "
+                                "Maybe left over directories?\n");
+      }
+    });
+  }
+}
+
+class LineProgressIndicator extends EventListener {
+  void done(TestCase test) {
+    var status = 'pass';
+    if (test.lastCommandOutput.unexpectedOutput) {
+      status = 'fail';
+    }
+    print('Done ${test.configurationString} ${test.displayName}: $status');
+  }
+}
+
+class TestFailurePrinter extends EventListener {
+  var _formatter;
+
+  TestFailurePrinter([this._formatter = const Formatter()]);
+
+  void done(TestCase test) {
+    if (test.lastCommandOutput.unexpectedOutput) {
+      for (var line in _buildFailureOutput(test, _formatter)) {
+        print(line);
+      }
+      print('');
+    }
+  }
+}
+
+class ProgressIndicator extends EventListener {
+  ProgressIndicator(this._startTime);
+
+  factory ProgressIndicator.fromName(String name,
+                                     DateTime startTime,
+                                     Formatter formatter) {
+    switch (name) {
+      case 'compact':
+        return new CompactProgressIndicator(startTime, formatter);
+      case 'line':
+        return new LineProgressIndicator();
+      case 'verbose':
+        return new VerboseProgressIndicator(startTime);
+      case 'status':
+        return new ProgressIndicator(startTime);
+      case 'buildbot':
+        return new BuildbotProgressIndicator(startTime);
+      default:
+        assert(false);
+        break;
+    }
+  }
+
+  void testAdded() { _foundTests++; }
+
+  void start(TestCase test) {
+    _printStartProgress(test);
+  }
+
+  void done(TestCase test) {
+    if (test.lastCommandOutput.unexpectedOutput) {
+      _failedTests++;
+    } else {
+      _passedTests++;
+    }
+    _printDoneProgress(test);
+  }
+
+  void allTestsKnown() {
+    _allTestsKnown = true;
+  }
+
+  void allDone() {
     _printStatus();
   }
+
+  void _printStartProgress(TestCase test) {}
+  void _printDoneProgress(TestCase test) {}
+
+  void _printStatus() {
+    if (_failedTests == 0) {
+      print('\n===');
+      print('=== All tests succeeded');
+      print('===\n');
+    } else {
+      var pluralSuffix = _failedTests != 1 ? 's' : '';
+      print('\n===');
+      print('=== ${_failedTests} test$pluralSuffix failed');
+      print('===\n');
+    }
+  }
+
+  int get numFailedTests => _failedTests;
+
+  int _completedTests() => _passedTests + _failedTests;
+
+  int _foundTests = 0;
+  int _passedTests = 0;
+  int _failedTests = 0;
+  bool _allTestsKnown = false;
+  DateTime _startTime;
+}
+
+abstract class CompactIndicator extends ProgressIndicator {
+  CompactIndicator(DateTime startTime)
+      : super(startTime);
+
+  void allDone() {
+    stdout.writeln('');
+    if (_failedTests > 0) {
+      // We may have printed many failure logs, so reprint the summary data.
+      _printProgress();
+      print('');
+    }
+    stdout.close();
+    stderr.close();
+  }
+
+  void _printStartProgress(TestCase test) => _printProgress();
+  void _printDoneProgress(TestCase test) => _printProgress();
+
+  void _printProgress();
+}
+
+
+class CompactProgressIndicator extends CompactIndicator {
+  Formatter _formatter;
+
+  CompactProgressIndicator(DateTime startTime, this._formatter)
+      : super(startTime);
+
+  void _printProgress() {
+    var percent = ((_completedTests() / _foundTests) * 100).toInt().toString();
+    var progressPadded = _pad(_allTestsKnown ? percent : '--', 3);
+    var passedPadded = _pad(_passedTests.toString(), 5);
+    var failedPadded = _pad(_failedTests.toString(), 5);
+    Duration d = (new DateTime.now()).difference(_startTime);
+    var progressLine =
+        '\r[${_timeString(d)} | $progressPadded% | '
+        '+${_formatter.passed(passedPadded)} | '
+        '-${_formatter.failed(failedPadded)}]';
+    stdout.write(progressLine);
+  }
+}
+
+
+class VerboseProgressIndicator extends ProgressIndicator {
+  VerboseProgressIndicator(DateTime startTime)
+      : super(startTime);
+
+  void _printStartProgress(TestCase test) {
+    print('Starting ${test.configurationString} ${test.displayName}...');
+  }
+
+  void _printDoneProgress(TestCase test) {
+    var status = 'pass';
+    if (test.lastCommandOutput.unexpectedOutput) {
+      status = 'fail';
+    }
+    print('Done ${test.configurationString} ${test.displayName}: $status');
+  }
+}
+
+
+class BuildbotProgressIndicator extends ProgressIndicator {
+  static String stepName;
+  var _failureSummary = <String>[];
+
+  BuildbotProgressIndicator(DateTime startTime) : super(startTime);
+
+  void done(TestCase test) {
+    super.done(test);
+    if (test.lastCommandOutput.unexpectedOutput) {
+      _failureSummary.addAll(_buildFailureOutput(test));
+    }
+  }
+
+  void _printDoneProgress(TestCase test) {
+    var status = 'pass';
+    if (test.lastCommandOutput.unexpectedOutput) {
+      status = 'fail';
+    }
+    var percent = ((_completedTests() / _foundTests) * 100).toInt().toString();
+    print('Done ${test.configurationString} ${test.displayName}: $status');
+    print('@@@STEP_CLEAR@@@');
+    print('@@@STEP_TEXT@ $percent% +$_passedTests -$_failedTests @@@');
+  }
+
+  void allDone() {
+    if (!_failureSummary.isEmpty && stepName != null) {
+      print('@@@STEP_FAILURE@@@');
+      print('@@@BUILD_STEP $stepName failures@@@');
+      for (String line in _failureSummary) {
+        print(line);
+      }
+      print('');
+    }
+    super.allDone();
+  }
 }
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index 262440f..9be1651 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -530,7 +530,7 @@
                                           stderr,
                                           time,
                                           compilationSkipped);
-    } else if (testCase.configuration['compiler'] == 'dartc') {
+    } else if (testCase.configuration['analyzer']) {
       return new AnalysisCommandOutputImpl(testCase,
                                            command,
                                            exitCode,
@@ -676,9 +676,9 @@
     var stdout = testCase.commandOutputs[command].stdout;
     var file = new io.File.fromPath(command.expectedOutputFile);
     if (file.existsSync()) {
-      var bytesContentLength = "Content-Length:".charCodes;
-      var bytesNewLine = "\n".charCodes;
-      var bytesEOF = "#EOF\n".charCodes;
+      var bytesContentLength = "Content-Length:".codeUnits;
+      var bytesNewLine = "\n".codeUnits;
+      var bytesEOF = "#EOF\n".codeUnits;
 
       var expectedContent = file.readAsBytesSync();
       if (command.isPixelTest) {
@@ -909,10 +909,10 @@
       escaped = false;
       if (c == '|') {
         result.add(field.toString());
-        field.clear();
+        field = new StringBuffer();
         continue;
       }
-      field.add(c);
+      field.write(c);
     }
     result.add(field.toString());
     return result;
@@ -933,7 +933,7 @@
   TestCase testCase;
   Command command;
   bool timedOut = false;
-  Date startTime;
+  DateTime startTime;
   Timer timeoutTimer;
   List<int> stdout = <int>[];
   List<int> stderr = <int>[];
@@ -946,7 +946,7 @@
     Expect.isFalse(testCase.expectedOutcomes.contains(SKIP));
 
     completer = new Completer<CommandOutput>();
-    startTime = new Date.now();
+    startTime = new DateTime.now();
     _runCommand();
     return completer.future;
   }
@@ -962,16 +962,17 @@
                                                 command.arguments,
                                                 processOptions);
         processFuture.then((io.Process process) {
-          void timeoutHandler(_) {
+          void timeoutHandler() {
             timedOut = true;
             if (process != null) {
               process.kill();
             }
           }
-          process.onExit = _commandComplete;
+          process.exitCode.then(_commandComplete);
           _drainStream(process.stdout, stdout);
           _drainStream(process.stderr, stderr);
-          timeoutTimer = new Timer(1000 * testCase.timeout, timeoutHandler);
+          timeoutTimer = new Timer(new Duration(seconds: testCase.timeout),
+                                   timeoutHandler);
         }).catchError((e) {
           print("Process error:");
           print("  Command: $command");
@@ -1001,24 +1002,13 @@
         timedOut,
         stdout,
         stderr,
-        new Date.now().difference(startTime),
+        new DateTime.now().difference(startTime),
         compilationSkipped);
     return commandOutput;
   }
 
-  void _drainStream(io.InputStream source, List<int> destination) {
-    void onDataHandler () {
-      if (source.closed) {
-        return;  // TODO(whesse): Remove when bug is fixed.
-      }
-      var data = source.read();
-      while (data != null) {
-        destination.addAll(data);
-        data = source.read();
-      }
-    }
-    source.onData = onDataHandler;
-    source.onClosed = onDataHandler;
+  void _drainStream(Stream<List<int>> source, List<int> destination) {
+    source.listen(destination.addAll);
   }
 
   io.ProcessOptions _createProcessOptions() {
@@ -1032,32 +1022,23 @@
   }
 }
 
-/**
- * This class holds a value, that can be changed.  It is used when
- * closures need a shared value, that they can all change and read.
- */
-class MutableValue<T> {
-  MutableValue(T this.value);
-  T value;
-}
-
 class BatchRunnerProcess {
   Command _command;
   String _executable;
   List<String> _batchArguments;
 
   io.Process _process;
-  io.StringInputStream _stdoutStream;
-  io.StringInputStream _stderrStream;
+  Completer _stdoutCompleter;
+  Completer _stderrCompleter;
+  StreamSubscription<String> _stdoutSubscription;
+  StreamSubscription<String> _stderrSubscription;
+  Function _processExitHandler;
 
   TestCase _currentTest;
   List<int> _testStdout;
   List<int> _testStderr;
   String _status;
-  bool _stdoutDrained = false;
-  bool _stderrDrained = false;
-  MutableValue<bool> _ignoreStreams;
-  Date _startTime;
+  DateTime _startTime;
   Timer _timer;
 
   bool _isWebDriver;
@@ -1086,7 +1067,7 @@
       // if needed.
       _executable = testCase.commands.last.executable;
       _batchArguments = testCase.batchRunnerArguments;
-      _process.onExit = (exitCode) {
+      _processExitHandler = (_) {
         _startProcess(() {
           doStartTest(testCase);
         });
@@ -1101,7 +1082,7 @@
     if (_process == null) return new Future.immediate(true);
     Completer completer = new Completer();
     Timer killTimer;
-    _process.onExit = (exitCode) {
+    _processExitHandler = (_) {
       if (killTimer != null) killTimer.cancel();
       completer.complete(true);
     };
@@ -1109,11 +1090,10 @@
       // Use a graceful shutdown so our Selenium script can close
       // the open browser processes. On Windows, signals do not exist
       // and a kill is a hard kill.
-      _process.stdin.write('--terminate\n'.charCodes);
+      _process.stdin.writeln('--terminate');
 
       // In case the run_selenium process didn't close, kill it after 30s
-      int shutdownMillisecs = 30000;
-      killTimer = new Timer(shutdownMillisecs, (e) { _process.kill(); });
+      killTimer = new Timer(new Duration(seconds: 30), _process.kill);
     } else {
       _process.kill();
     }
@@ -1122,16 +1102,14 @@
   }
 
   void doStartTest(TestCase testCase) {
-    _startTime = new Date.now();
+    _startTime = new DateTime.now();
     _testStdout = [];
     _testStderr = [];
     _status = null;
-    _stdoutDrained = false;
-    _stderrDrained = false;
-    _ignoreStreams = new MutableValue<bool>(false);  // Captured by closures.
-    _readStdout(_stdoutStream, _testStdout);
-    _readStderr(_stderrStream, _testStderr);
-    _timer = new Timer(testCase.timeout * 1000, _timeoutHandler);
+    _stdoutCompleter = new Completer();
+    _stderrCompleter = new Completer();
+    _timer = new Timer(new Duration(seconds: testCase.timeout),
+                       _timeoutHandler);
 
     if (testCase.commands.last.environment != null) {
       print("Warning: command.environment != null, but we don't support custom "
@@ -1139,14 +1117,11 @@
     }
 
     var line = _createArgumentsLine(testCase.batchTestArguments);
-    _process.stdin.onError = (err) {
-      print('Error on batch runner input stream stdin');
-      print('  Input line: $line');
-      print('  Previous test\'s status: $_status');
-      print('  Error: $err');
-      throw err;
-    };
-    _process.stdin.write(line.charCodes);
+    _process.stdin.write(line);
+    _stdoutSubscription.resume();
+    _stderrSubscription.resume();
+    Future.wait([_stdoutCompleter.future,
+                 _stderrCompleter.future]).then((_) => _reportResult());
   }
 
   String _createArgumentsLine(List<String> arguments) {
@@ -1168,100 +1143,20 @@
                                (outcome == "TIMEOUT"),
                                _testStdout,
                                _testStderr,
-                               new Date.now().difference(_startTime),
+                               new DateTime.now().difference(_startTime),
                                false);
     var test = _currentTest;
     _currentTest = null;
     test.completed();
   }
 
-  void _stderrDone() {
-    _stderrDrained = true;
-    // Move on when both stdout and stderr has been drained.
-    if (_stdoutDrained) _reportResult();
-  }
-
-  void _stdoutDone() {
-    _stdoutDrained = true;
-    // Move on when both stdout and stderr has been drained.
-    if (_stderrDrained) _reportResult();
-  }
-
-  void _readStdout(io.StringInputStream stream, List<int> buffer) {
-    var ignoreStreams = _ignoreStreams;  // Capture this mutable object.
-    void onLineHandler() {
-      if (ignoreStreams.value) {
-         while (stream.readLine() != null) {
-          // Do nothing.
-        }
-        return;
-      }
-      // Otherwise, process output and call _reportResult() when done.
-      var line = stream.readLine();
-      while (line != null) {
-        if (line.startsWith('>>> TEST')) {
-          _status = line;
-        } else if (line.startsWith('>>> BATCH START')) {
-          // ignore
-        } else if (line.startsWith('>>> ')) {
-          throw new Exception('Unexpected command from dartc batch runner.');
-        } else {
-          buffer.addAll(encodeUtf8(line));
-          buffer.addAll("\n".charCodes);
-        }
-        line = stream.readLine();
-      }
-      if (_status != null) {
-        _timer.cancel();
-        _stdoutDone();
-      }
-    }
-    stream.onLine = onLineHandler;
-  }
-
-  void _readStderr(io.StringInputStream stream, List<int> buffer) {
-    var ignoreStreams = _ignoreStreams;  // Capture this mutable object.
-    void onLineHandler() {
-      if (ignoreStreams.value) {
-        while (stream.readLine() != null) {
-          // Do nothing.
-        }
-        return;
-      }
-      // Otherwise, process output and call _reportResult() when done.
-      var line = stream.readLine();
-      while (line != null) {
-        if (line.startsWith('>>> EOF STDERR')) {
-          _stderrDone();
-        } else {
-          buffer.addAll(encodeUtf8(line));
-          buffer.addAll("\n".charCodes);
-        }
-        line = stream.readLine();
-      }
-    }
-    stream.onLine = onLineHandler;
-  }
-
   ExitCodeEvent makeExitHandler(String status) {
     void handler(int exitCode) {
       if (active) {
         if (_timer != null) _timer.cancel();
         _status = status;
-        // Read current content of streams, ignore any later output.
-        _ignoreStreams.value = true;
-        var line = _stdoutStream.readLine();
-        while (line != null) {
-          _testStdout.add(line);
-          line = _stdoutStream.readLine();
-        }
-        line = _stderrStream.readLine();
-        while (line != null) {
-          _testStderr.add(line);
-          line = _stderrStream.readLine();
-        }
-        _stderrDrained = true;
-        _stdoutDrained = true;
+        _stdoutSubscription.cancel();
+        _stderrSubscription.cancel();
         _startProcess(_reportResult);
       } else {  // No active test case running.
         _process = null;
@@ -1270,8 +1165,8 @@
     return handler;
   }
 
-  void _timeoutHandler(ignore) {
-    _process.onExit = makeExitHandler(">>> TEST TIMEOUT");
+  void _timeoutHandler() {
+    _processExitHandler = makeExitHandler(">>> TEST TIMEOUT");
     _process.kill();
   }
 
@@ -1279,9 +1174,58 @@
     Future processFuture = io.Process.start(_executable, _batchArguments);
     processFuture.then((io.Process p) {
       _process = p;
-      _stdoutStream = new io.StringInputStream(_process.stdout);
-      _stderrStream = new io.StringInputStream(_process.stderr);
-      _process.onExit = makeExitHandler(">>> TEST CRASH");
+
+      var _stdoutStream =
+          _process.stdout
+              .transform(new io.StringDecoder())
+              .transform(new io.LineTransformer());
+      _stdoutSubscription = _stdoutStream.listen((String line) {
+        if (line.startsWith('>>> TEST')) {
+          _status = line;
+        } else if (line.startsWith('>>> BATCH')) {
+          // ignore
+        } else if (line.startsWith('>>> ')) {
+          throw new Exception(
+              'Unexpected command from ${testCase.configuration['compiler']} '
+              'batch runner.');
+        } else {
+          _testStdout.addAll(encodeUtf8(line));
+          _testStdout.addAll("\n".codeUnits);
+        }
+        if (_status != null) {
+          _stdoutSubscription.pause();
+          _timer.cancel();
+          _stdoutCompleter.complete(null);
+        }
+      });
+      _stdoutSubscription.pause();
+
+      var _stderrStream =
+          _process.stderr
+              .transform(new io.StringDecoder())
+              .transform(new io.LineTransformer());
+      _stderrSubscription = _stderrStream.listen((String line) {
+        if (line.startsWith('>>> EOF STDERR')) {
+          _stderrSubscription.pause();
+          _stderrCompleter.complete(null);
+        } else {
+          _testStderr.addAll(encodeUtf8(line));
+          _testStderr.addAll("\n".codeUnits);
+        }
+      });
+      _stderrSubscription.pause();
+
+      _processExitHandler = makeExitHandler(">>> TEST CRASH");
+      _process.exitCode.then((exitCode) {
+        _processExitHandler(exitCode);
+      });
+
+      _process.stdin.done.catchError((err) {
+        print('Error on batch runner input stream stdin');
+        print('  Previous test\'s status: $_status');
+        print('  Error: $err');
+        throw err;
+      });
       callback();
     }).catchError((e) {
       print("Process error:");
@@ -1290,7 +1234,7 @@
       // If there is an error starting a batch process, chances are that
       // it will always fail. So rather than re-trying a 1000+ times, we
       // exit.
-      exit(1);
+      io.exit(1);
       return true;
     });
   }
@@ -1315,6 +1259,7 @@
   int _maxProcesses;
   int _numBrowserProcesses = 0;
   int _maxBrowserProcesses;
+  int _numFailedTests = 0;
   bool _allTestsWereEnqueued = false;
 
   /** The number of tests we allow to actually fail before we stop retrying. */
@@ -1323,7 +1268,7 @@
   bool _listTests;
   Function _allDone;
   Queue<TestCase> _tests;
-  ProgressIndicator _progress;
+  List<EventListener> _eventListener;
 
   // For dartc/selenium batch processing we keep a list of batch processes.
   Map<String, List<BatchRunnerProcess>> _batchProcesses;
@@ -1353,19 +1298,15 @@
 
   ProcessQueue(this._maxProcesses,
                this._maxBrowserProcesses,
-               String progress,
-               Date startTime,
-               bool printTiming,
+               DateTime startTime,
                testSuites,
+               this._eventListener,
                this._allDone,
                [bool verbose = false,
                 bool listTests = false])
       : _verbose = verbose,
         _listTests = listTests,
         _tests = new Queue<TestCase>(),
-        _progress = new ProgressIndicator.fromName(progress,
-                                                   startTime,
-                                                   printTiming),
         _batchProcesses = new Map<String, List<BatchRunnerProcess>>(),
         _testCache = new Map<String, List<TestInformation>>() {
     _runTests(testSuites);
@@ -1380,7 +1321,7 @@
     if (browserUsed != '' && _seleniumServer != null) {
       _seleniumServer.kill();
     }
-    _progress.allDone();
+    eventAllTestsDone();
   }
 
   void _checkDone() {
@@ -1399,7 +1340,7 @@
     void enqueueNextSuite() {
       if (!iterator.moveNext()) {
         _allTestsWereEnqueued = true;
-        _progress.allTestsKnown();
+        eventAllTestsKnown();
         _checkDone();
       } else {
         iterator.current.forEachTest(_runTest, _testCache, enqueueNextSuite);
@@ -1443,29 +1384,26 @@
       Future processFuture = io.Process.start(cmd, arg);
       processFuture.then((io.Process p) {
         // Drain stderr to not leak resources.
-        p.stderr.onData = p.stderr.read;
-        final io.StringInputStream stdoutStringStream =
-            new io.StringInputStream(p.stdout);
-        stdoutStringStream.onLine = () {
-          var line = stdoutStringStream.readLine();
-          while (null != line) {
-            var regexp = new RegExp(r".*selenium-server-standalone.*");
-            if (regexp.hasMatch(line)) {
-              _seleniumAlreadyRunning = true;
-              resumeTesting();
-            }
-            line = stdoutStringStream.readLine();
+        p.stderr.listen((_) {});
+        final Stream<String> stdoutStringStream =
+            p.stdout.transform(new io.StringDecoder())
+                    .transform(new io.LineTransformer());
+        stdoutStringStream.listen((String line) {
+          var regexp = new RegExp(r".*selenium-server-standalone.*");
+          if (regexp.hasMatch(line)) {
+            _seleniumAlreadyRunning = true;
+            resumeTesting();
           }
           if (!_isSeleniumAvailable) {
             _startSeleniumServer();
           }
-        };
+        });
       }).catchError((e) {
         print("Error starting process:");
         print("  Command: $cmd ${arg.join(' ')}");
         print("  Error: $e");
         // TODO(ahe): How to report this as a test failure?
-        exit(1);
+        io.exit(1);
         return true;
       });
     }
@@ -1476,7 +1414,7 @@
       browserUsed = test.configuration['browser'];
       if (_needsSelenium) _ensureSeleniumServerRunning();
     }
-    _progress.testAdded();
+    eventTestAdded(test);
     _tests.add(test);
     _tryRunTest();
   }
@@ -1486,20 +1424,12 @@
    * begin running tests.
    * source: Output(Stream) from the Java server.
    */
-  VoidFunction makeSeleniumServerHandler(io.StringInputStream source) {
-    void handler() {
-      if (source.closed) return;  // TODO(whesse): Remove when bug is fixed.
-      var line = source.readLine();
-      while (null != line) {
-        if (new RegExp(r".*Started.*Server.*").hasMatch(line) ||
-            new RegExp(r"Exception.*Selenium is already running.*").hasMatch(
-            line)) {
-          resumeTesting();
-        }
-        line = source.readLine();
-      }
+  void seleniumServerHandler(String line) {
+    if (new RegExp(r".*Started.*Server.*").hasMatch(line) ||
+        new RegExp(r"Exception.*Selenium is already running.*").hasMatch(
+        line)) {
+      resumeTesting();
     }
-    return handler;
   }
 
   /**
@@ -1512,35 +1442,38 @@
     String pathSep = io.Platform.pathSeparator;
     int index = filePath.lastIndexOf(pathSep);
     filePath = '${filePath.substring(0, index)}${pathSep}testing${pathSep}';
-    var lister = new io.Directory(filePath).list();
-    lister.onFile = (String file) {
-      if (new RegExp(r"selenium-server-standalone-.*\.jar").hasMatch(file)
-          && _seleniumServer == null) {
-        Future processFuture = io.Process.start('java', ['-jar', file]);
-        processFuture.then((io.Process server) {
-          _seleniumServer = server;
-          // Heads up: there seems to an obscure data race of some form in
-          // the VM between launching the server process and launching the test
-          // tasks that disappears when you read IO (which is convenient, since
-          // that is our condition for knowing that the server is ready).
-          io.StringInputStream stdoutStringStream =
-              new io.StringInputStream(_seleniumServer.stdout);
-          io.StringInputStream stderrStringStream =
-              new io.StringInputStream(_seleniumServer.stderr);
-          stdoutStringStream.onLine =
-              makeSeleniumServerHandler(stdoutStringStream);
-          stderrStringStream.onLine =
-              makeSeleniumServerHandler(stderrStringStream);
-        }).catchError((e) {
-          print("Process error:");
-          print("  Command: java -jar $file");
-          print("  Error: $e");
-          // TODO(ahe): How to report this as a test failure?
-          exit(1);
-          return true;
-        });
+    new io.Directory(filePath).list().listen((io.FileSystemEntity fse) {
+      if (fse is io.File) {
+        String file = fse.path;
+        if (new RegExp(r"selenium-server-standalone-.*\.jar").hasMatch(file)
+            && _seleniumServer == null) {
+          Future processFuture = io.Process.start('java', ['-jar', file]);
+          processFuture.then((io.Process server) {
+            _seleniumServer = server;
+            // Heads up: there seems to an obscure data race of some form in
+            // the VM between launching the server process and launching the
+            // test tasks that disappears when you read IO (which is
+            // convenient, since that is our condition for knowing that the
+            // server is ready).
+            Stream<String> stdoutStringStream =
+                _seleniumServer.stdout.transform(new io.StringDecoder())
+                .transform(new io.LineTransformer());
+            Stream<String> stderrStringStream =
+                _seleniumServer.stderr.transform(new io.StringDecoder())
+                .transform(new io.LineTransformer());
+            stdoutStringStream.listen(seleniumServerHandler);
+            stderrStringStream.listen(seleniumServerHandler);
+          }).catchError((e) {
+            print("Process error:");
+            print("  Command: java -jar $file");
+            print("  Error: $e");
+            // TODO(ahe): How to report this as a test failure?
+            io.exit(1);
+            return true;
+          });
+        }
       }
-    };
+    });
   }
 
   Future _terminateBatchRunners() {
@@ -1589,7 +1522,8 @@
         // The test is not yet ready to run. Put the test back in
         // the queue.  Avoid spin-polling by using a timeout.
         _tests.add(test);
-        new Timer(100, (_) => _tryRunTest());  // Don't lose a process.
+        new Timer(new Duration(milliseconds: 100),
+                  _tryRunTest);  // Don't lose a process.
         return;
       }
       // Before running any commands, we print out all commands if '--verbose'
@@ -1615,28 +1549,31 @@
       if (isBrowserCommand && _numBrowserProcesses == _maxBrowserProcesses) {
         // If there is no free browser runner, put it back into the queue.
         _tests.add(test);
-        new Timer(100, (_) => _tryRunTest());  // Don't lose a process.
+        new Timer(new Duration(milliseconds: 100),
+                  _tryRunTest);  // Don't lose a process.
         return;
       }
 
-      _progress.start(test);
+      eventStartTestCase(test);
 
-      // Dartc and browser test commands can be run by a [BatchRunnerProcess]
+      // Analyzer and browser test commands can be run by a [BatchRunnerProcess]
       var nextCommandIndex = test.commandOutputs.keys.length;
       var numberOfCommands = test.commands.length;
-      var useBatchRunnerForDartc = test.configuration['compiler'] == 'dartc' &&
-                                   test.displayName != 'dartc/junit_tests';
+
+      var useBatchRunnerForAnalyzer =
+          test.configuration['analyzer'] &&
+          test.displayName != 'dartc/junit_tests';
       var isWebdriverCommand = nextCommandIndex == (numberOfCommands - 1) &&
                                test.usesWebDriver &&
                                !test.configuration['noBatch'];
-      if (useBatchRunnerForDartc || isWebdriverCommand) {
+      if (useBatchRunnerForAnalyzer || isWebdriverCommand) {
         TestCaseEvent oldCallback = test.completedHandler;
         void testCompleted(TestCase test_arg) {
           _numProcesses--;
           if (isBrowserCommand) {
             _numBrowserProcesses--;
           }
-          _progress.done(test_arg);
+          eventFinishedTestCase(test_arg);
           if (test_arg is BrowserTestCase) test_arg.notifyObservers();
           oldCallback(test_arg);
           _tryRunTest();
@@ -1651,7 +1588,7 @@
         // the developer doesn't waste his or her time trying to fix a bunch of
         // tests that appear to be broken but were actually just flakes that
         // didn't get retried because there had already been one failure.
-        bool allowRetry = _MAX_FAILED_NO_RETRY > _progress.numFailedTests;
+        bool allowRetry = _MAX_FAILED_NO_RETRY > _numFailedTests;
         runNextCommandWithRetries(test, allowRetry).then((TestCase testCase) {
           _numProcesses--;
           if (isBrowserCommand) {
@@ -1659,7 +1596,7 @@
           }
           if (isTestCaseFinished(testCase)) {
             testCase.completed();
-            _progress.done(testCase);
+            eventFinishedTestCase(testCase);
             if (testCase is BrowserTestCase) testCase.notifyObservers();
           } else {
             _tests.addFirst(testCase);
@@ -1751,5 +1688,38 @@
 
     return completer.future;
   }
+
+  void eventStartTestCase(TestCase testCase) {
+    for (var listener in _eventListener) {
+      listener.start(testCase);
+    }
+  }
+
+  void eventFinishedTestCase(TestCase testCase) {
+    if (testCase.lastCommandOutput.unexpectedOutput) {
+      _numFailedTests++;
+    }
+    for (var listener in _eventListener) {
+      listener.done(testCase);
+    }
+  }
+
+  void eventTestAdded(TestCase testCase) {
+    for (var listener in _eventListener) {
+      listener.testAdded();
+    }
+  }
+
+  void eventAllTestsKnown() {
+    for (var listener in _eventListener) {
+      listener.allTestsKnown();
+    }
+  }
+
+  void eventAllTestsDone() {
+    for (var listener in _eventListener) {
+      listener.allDone();
+    }
+  }
 }
 
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index 12e8929..cb9c96f 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -52,9 +52,7 @@
   if (function == null) return new Future.immediate(null);
 
   var completer = new Completer();
-  new Timer(0, (_) {
-    completer.complete(function());
-  });
+  Timer.run(() => completer.complete(function()));
 
   return completer.future;
 }
@@ -81,7 +79,7 @@
     _pending++;
     var handledTaskFuture = task.catchError((e) {
       if (!wasCompleted) {
-        _completer.completeError(e.error, task.stackTrace);
+        _completer.completeError(e.error, e.stackTrace);
         wasCompleted = true;
       }
     }).then((_) {
@@ -142,7 +140,9 @@
     var name;
     switch (configuration['compiler']) {
       case 'dartc':
+      case 'new_analyzer':
         name = executablePath;
+        break;
       case 'dart2js':
       case 'dart2dart':
         var prefix = 'sdk/bin/';
@@ -181,6 +181,8 @@
         return '$buildDir/dart$suffix';
       case 'dartc':
         return '$buildDir/analyzer/bin/dart_analyzer$suffix';
+      case 'new_analyzer':
+        return 'sdk/bin/analyzer$suffix';
       default:
         throw "Unknown executable for: ${configuration['compiler']}";
     }
@@ -253,10 +255,12 @@
 void ccTestLister() {
   port.receive((String runnerPath, SendPort replyTo) {
     Future processFuture = Process.start(runnerPath, ["--list"]);
-    processFuture.then((p) {
+    processFuture.then((Process p) {
       // Drain stderr to not leak resources.
-      p.stderr.onData = p.stderr.read;
-      StringInputStream stdoutStream = new StringInputStream(p.stdout);
+      p.stderr.listen((_) { });
+      Stream<String> stdoutStream =
+          p.stdout.transform(new StringDecoder())
+                  .transform(new LineTransformer());
       var streamDone = false;
       var processExited = false;
       checkDone() {
@@ -264,15 +268,15 @@
           replyTo.send("");
         }
       }
-      stdoutStream.onLine = () {
-        String line = stdoutStream.readLine();
+      stdoutStream.listen((String line) {
         replyTo.send(line);
-      };
-      stdoutStream.onClosed = () {
+      },
+      onDone: () {
         streamDone = true;
         checkDone();
-      };
-      p.onExit = (code) {
+      });
+
+      p.exitCode.then((code) {
         if (code < 0) {
           print("Failed to list tests: $runnerPath --list");
           replyTo.send("");
@@ -280,7 +284,7 @@
           processExited = true;
           checkDone();
         }
-      };
+      });
       port.close();
     }).catchError((e) {
       print("Failed to list tests: $runnerPath --list");
@@ -582,9 +586,11 @@
     var listCompleter = new Completer();
     group.add(listCompleter.future);
 
-    var lister = dir.list(recursive: listRecursively);
-    lister.onFile = (file) => enqueueFile(file, group);
-    lister.onDone = listCompleter.complete;
+    var lister = dir.list(recursive: listRecursively)
+        .listen((FileSystemEntity fse) {
+          if (fse is File) enqueueFile(fse.path, group);
+        },
+        onDone: listCompleter.complete);
   }
 
   void enqueueFile(String filename, FutureGroup group) {
@@ -699,8 +705,8 @@
       isNegative = true;
     }
 
-    if (configuration['compiler'] == 'dartc') {
-      // dartc can detect static type warnings by the
+    if (configuration['analyzer']) {
+      // An analyzer can detect static type warnings by the
       // format of the error line
       if (info.hasFatalTypeErrors) {
         isNegative = true;
@@ -775,6 +781,7 @@
 
     case 'none':
     case 'dartc':
+    case 'new_analyzer':
       var arguments = new List.from(vmOptions);
       arguments.addAll(args);
       return <Command>[new Command(dartShellFileName, arguments)];
@@ -815,7 +822,7 @@
    */
   String _createUrlPathFromFile(Path file) {
     file = TestUtils.absolutePath(file);
-    
+
     var relativeBuildDir = new Path(TestUtils.buildDir(configuration));
     var buildDir = TestUtils.absolutePath(relativeBuildDir);
     var dartDir = TestUtils.absolutePath(TestUtils.dartDir());
@@ -829,10 +836,10 @@
       return "/$PREFIX_DARTDIR/$fileRelativeToDartDir";
     }
     // Unreachable
-    Except.fail('This should be unreachable.');
+    Expect.fail('This should be unreachable.');
   }
 
-  void _getUriForBrowserTest(TestInformation info,
+  String _getUriForBrowserTest(TestInformation info,
                             String pathComponent,
                             subtestNames,
                             subtestIndex) {
@@ -1017,7 +1024,7 @@
           args = [
               dartDir.append('tools/testing/run_selenium.py').toNativePath(),
               '--browser=$runtime',
-              '--timeout=${configuration["timeout"] - 2}',
+              '--timeout=${configuration["timeout"]~/2}',
               '--out=$fullHtmlPath'];
           if (runtime == 'dartium') {
             args.add('--executable=$dartiumFilename');
@@ -1163,6 +1170,7 @@
       case 'dart2dart':
         return 'application/dart';
       case 'dart2js':
+      case 'new_analyzer':
       case 'dartc':
         return 'text/javascript';
       default:
@@ -1223,9 +1231,8 @@
       args.add(packageRoot);
     }
     args.addAll(additionalOptions(filePath));
-    if (configuration['compiler'] == 'dartc') {
-      args.add('--error_format');
-      args.add('machine');
+    if (configuration['analyzer']) {
+      args.add('--machine');
     }
 
     bool isMultitest = optionsFromFile["isMultitest"];
@@ -1324,7 +1331,7 @@
    * This method is static as the map is cached and shared amongst
    * configurations, so it may not use [configuration].
    */
-  static Map readOptionsFromFile(Path filePath) {
+  Map readOptionsFromFile(Path filePath) {
     if (filePath.segments().contains('co19')) {
       return readOptionsFromCo19File(filePath);
     }
@@ -1339,7 +1346,6 @@
     RegExp compileTimeRegExp =
         new RegExp(r"/// ([0-9][0-9]:){0,1}\s*compile-time error");
     RegExp staticCleanRegExp = new RegExp(r"// @static-clean");
-    RegExp leadingHashRegExp = new RegExp(r"^#", multiLine: true);
     RegExp isolateStubsRegExp = new RegExp(r"// IsolateStubs=(.*)");
     // TODO(gram) Clean these up once the old directives are not supported.
     RegExp domImportRegExp =
@@ -1404,7 +1410,6 @@
 
     bool isMultitest = multiTestRegExp.hasMatch(contents);
     bool isMultiHtmlTest = multiHtmlTestRegExp.hasMatch(contents);
-    bool containsLeadingHash = leadingHashRegExp.hasMatch(contents);
     Match isolateMatch = isolateStubsRegExp.firstMatch(contents);
     String isolateStubs = isolateMatch != null ? isolateMatch[1] : '';
     bool containsDomImport = domImportRegExp.hasMatch(contents);
@@ -1443,7 +1448,6 @@
              "isMultitest": isMultitest,
              "isMultiHtmlTest": isMultiHtmlTest,
              "subtestNames": subtestNames,
-             "containsLeadingHash": containsLeadingHash,
              "isolateStubs": isolateStubs,
              "containsDomImport": containsDomImport,
              "isLibraryDefinition": isLibraryDefinition,
@@ -1480,7 +1484,7 @@
    * pass the co19 test suite as is, and not require extra flags,
    * environment variables, configuration files, etc.
    */
-  static Map readOptionsFromCo19File(Path filePath) {
+  Map readOptionsFromCo19File(Path filePath) {
     String contents = decodeUtf8(new File.fromPath(filePath).readAsBytesSync());
 
     bool hasCompileError = contents.contains("@compile-error");
@@ -1499,8 +1503,8 @@
 
       // Using stderr.writeString to avoid breaking dartc/junit_tests
       // which parses the output of the --list option.
-      stderr.writeString(
-          "Warning: deprecated @dynamic-type-error tag used in $filePath\n");
+      stderr.writeln(
+          "Warning: deprecated @dynamic-type-error tag used in $filePath");
     }
 
     return {
@@ -1514,7 +1518,6 @@
       "isMultitest": isMultitest,
       "isMultiHtmlTest": false,
       "subtestNames": <String>[],
-      "containsLeadingHash": false,
       "isolateStubs": '',
       "containsDomImport": false,
       "isLibraryDefinition": false,
@@ -1526,14 +1529,24 @@
 }
 
 
+/// A DartcCompilationTestSuite will run dartc on all of the tests.
+///
+/// Usually, the result of a dartc run is determined by the output of
+/// dartc in connection with annotations in the test file.
+///
+/// If you want each file that you are running as a test to have no
+/// static warnings or errors you can create a DartcCompilationTestSuite
+/// with the optional allStaticClean constructor parameter set to true.
 class DartcCompilationTestSuite extends StandardTestSuite {
   List<String> _testDirs;
+  bool allStaticClean;
 
   DartcCompilationTestSuite(Map configuration,
                             String suiteName,
                             String directoryPath,
                             List<String> this._testDirs,
-                            List<String> expectations)
+                            List<String> expectations,
+                            {bool this.allStaticClean: false})
       : super(configuration,
               suiteName,
               new Path(directoryPath),
@@ -1555,6 +1568,14 @@
 
     return group.future;
   }
+
+  Map readOptionsFromFile(Path p) {
+    Map options = super.readOptionsFromFile(p);
+    if (allStaticClean) {
+      options['isStaticClean'] = true;
+    }
+    return options;
+  }
 }
 
 
@@ -1585,7 +1606,7 @@
     doTest = onTest;
     doDone = onDone;
 
-    if (configuration['compiler'] != 'dartc') {
+    if (!configuration['analyzer']) {
       // Do nothing. Asynchronously report that the suite is enqueued.
       asynchronously(doDone);
       return;
@@ -1607,9 +1628,10 @@
     directoryPath = '$dartDir/$directoryPath';
     Directory dir = new Directory(directoryPath);
 
-    var lister = dir.list(recursive: true);
-    lister.onFile = processFile;
-    lister.onDone = createTest;
+    dir.list(recursive: true).listen((FileSystemEntity fse) {
+      if (fse is File) processFile(fse.path);
+    },
+    onDone: createTest);
   }
 
   void processFile(String filename) {
@@ -1625,7 +1647,7 @@
     }
   }
 
-  void createTest(successIgnored) {
+  void createTest() {
     var sdkDir = "$buildDir/dart-sdk".trim();
     List<String> args = <String>[
         '-ea',
@@ -1671,7 +1693,7 @@
 }
 
 class LastModifiedCache {
-  Map<String, Date> _cache = <String, Date>{};
+  Map<String, DateTime> _cache = <String, DateTime>{};
 
   /**
    * Returns the last modified date of the given [uri].
@@ -1682,7 +1704,7 @@
    * In case [uri] is not a local file, this method will always return
    * the current date.
    */
-  Date getLastModified(Uri uri) {
+  DateTime getLastModified(Uri uri) {
     if (uri.scheme == "file") {
       if (_cache.containsKey(uri.path)) {
         return _cache[uri.path];
@@ -1740,11 +1762,8 @@
    * Assumes that the directory for [dest] already exists.
    */
   static Future copyFile(Path source, Path dest) {
-    var output = new File.fromPath(dest).openOutputStream();
-    new File.fromPath(source).openInputStream().pipe(output);
-    var completer = new Completer();
-    output.onClosed = (){ completer.complete(null); };
-    return completer.future;
+    return new File.fromPath(source).openRead()
+        .pipe(new File.fromPath(dest).openWrite());
   }
 
   static Path debugLogfile() {
@@ -1839,6 +1858,9 @@
   static bool isJsCommandLineRuntime(String runtime) =>
       const ['d8', 'jsshell'].contains(runtime);
 
+  static bool isCommandLineAnalyzer(String compiler) =>
+      compiler == 'dartc' || compiler == 'new_analyzer';
+
   static String buildDir(Map configuration) {
     // FIXME(kustermann,ricow): Our code assumes that the returned 'buildDir'
     // is relative to the current working directory.
diff --git a/tools/testing/dart/utils.dart b/tools/testing/dart/utils.dart
index 7c2bbf7..dc79246 100644
--- a/tools/testing/dart/utils.dart
+++ b/tools/testing/dart/utils.dart
@@ -8,7 +8,7 @@
 import 'dart:utf' as utf;
 
 class DebugLogger {
-  static OutputStream _stream;
+  static IOSink _sink;
 
   /**
    * If [path] was null, the DebugLogger will write messages to stdout.
@@ -16,14 +16,14 @@
   static init(Path path, {append: false}) {
     if (path != null) {
       var mode = append ? FileMode.APPEND : FileMode.WRITE;
-      _stream = new File.fromPath(path).openOutputStream(mode);
+      _sink = new File.fromPath(path).openWrite(mode: mode);
     }
   }
 
   static void close() {
-    if (_stream != null) {
-      _stream.close();
-      _stream = null;
+    if (_sink != null) {
+      _sink.close();
+      _sink = null;
     }
   }
 
@@ -40,9 +40,8 @@
   }
 
   static void _print(String msg) {
-    if (_stream != null) {
-      _stream.write(encodeUtf8(msg));
-      _stream.write([0x0a]);
+    if (_sink != null) {
+      _sink.writeln(msg);
     } else {
       print(msg);
     }
diff --git a/tools/testing/dart/vendored_pkg/args/args.dart b/tools/testing/dart/vendored_pkg/args/args.dart
index 29da1e2..32793dd 100644
--- a/tools/testing/dart/vendored_pkg/args/args.dart
+++ b/tools/testing/dart/vendored_pkg/args/args.dart
@@ -331,7 +331,7 @@
    * that abbreviation.
    */
   Option findByAbbreviation(String abbr) {
-    return options.values.firstMatching((option) => option.abbreviation == abbr,
+    return options.values.firstWhere((option) => option.abbreviation == abbr,
         orElse: () => null);
   }
 }
diff --git a/tools/testing/dart/vendored_pkg/args/src/usage.dart b/tools/testing/dart/vendored_pkg/args/src/usage.dart
index 72525e2..6fb28e1 100644
--- a/tools/testing/dart/vendored_pkg/args/src/usage.dart
+++ b/tools/testing/dart/vendored_pkg/args/src/usage.dart
@@ -170,7 +170,7 @@
   writeLine(int column, String text) {
     // Write any pending newlines.
     while (newlinesNeeded > 0) {
-      buffer.add('\n');
+      buffer.writeln('');
       newlinesNeeded--;
     }
 
@@ -178,19 +178,19 @@
     // to the next line.
     while (currentColumn != column) {
       if (currentColumn < NUM_COLUMNS - 1) {
-        buffer.add(padRight('', columnWidths[currentColumn]));
+        buffer.write(padRight('', columnWidths[currentColumn]));
       } else {
-        buffer.add('\n');
+        buffer.writeln('');
       }
       currentColumn = (currentColumn + 1) % NUM_COLUMNS;
     }
 
     if (column < columnWidths.length) {
       // Fixed-size column, so pad it.
-      buffer.add(padRight(text, columnWidths[column]));
+      buffer.write(padRight(text, columnWidths[column]));
     } else {
       // The last column, so just write it.
-      buffer.add(text);
+      buffer.write(text);
     }
 
     // Advance to the next column.
@@ -210,17 +210,17 @@
 
   buildAllowedList(Option option) {
     var allowedBuffer = new StringBuffer();
-    allowedBuffer.add('[');
+    allowedBuffer.write('[');
     bool first = true;
     for (var allowed in option.allowed) {
-      if (!first) allowedBuffer.add(', ');
-      allowedBuffer.add(allowed);
+      if (!first) allowedBuffer.write(', ');
+      allowedBuffer.write(allowed);
       if (allowed == option.defaultValue) {
-        allowedBuffer.add(' (default)');
+        allowedBuffer.write(' (default)');
       }
       first = false;
     }
-    allowedBuffer.add(']');
+    allowedBuffer.write(']');
     return allowedBuffer.toString();
   }
 }
@@ -228,11 +228,11 @@
 /** Pads [source] to [length] by adding spaces at the end. */
 String padRight(String source, int length) {
   final result = new StringBuffer();
-  result.add(source);
+  result.write(source);
 
   while (result.length < length) {
-    result.add(' ');
+    result.write(' ');
   }
 
   return result.toString();
-}
\ No newline at end of file
+}
diff --git a/tools/utils/textmate/Dart.tmbundle/Syntaxes/Dart.textmate b/tools/utils/textmate/Dart.tmbundle/Syntaxes/Dart.textmate
index d04d533..adfc7fc 100644
--- a/tools/utils/textmate/Dart.tmbundle/Syntaxes/Dart.textmate
+++ b/tools/utils/textmate/Dart.tmbundle/Syntaxes/Dart.textmate
@@ -112,7 +112,7 @@
 					match = '\b(static|final|const)\b';
 				},
 				{	name = 'storage.type.primitive.dart';
-					match = '\b(?:void|bool|num|int|double|Dynamic|var|String)\b';
+					match = '\b(?:void|bool|num|int|double|dynamic|var|String)\b';
 				},
 			);
 		};
diff --git a/tools/utils/textmate/Dart.tmbundle/Syntaxes/Dart.tmLanguage b/tools/utils/textmate/Dart.tmbundle/Syntaxes/Dart.tmLanguage
index 2d6304a..61727e2 100644
--- a/tools/utils/textmate/Dart.tmbundle/Syntaxes/Dart.tmLanguage
+++ b/tools/utils/textmate/Dart.tmbundle/Syntaxes/Dart.tmLanguage
@@ -268,7 +268,7 @@
 				</dict>
 				<dict>
 					<key>match</key>
-					<string>\b(?:void|bool|num|int|double|Dynamic|var|String)\b</string>
+					<string>\b(?:void|bool|num|int|double|dynamic|var|String)\b</string>
 					<key>name</key>
 					<string>storage.type.primitive.dart</string>
 				</dict>
diff --git a/utils/apidoc/apidoc.dart b/utils/apidoc/apidoc.dart
index 802471c..5405e3a 100644
--- a/utils/apidoc/apidoc.dart
+++ b/utils/apidoc/apidoc.dart
@@ -17,11 +17,13 @@
 import 'dart:async';
 import 'dart:io';
 import 'dart:json' as json;
+
 import 'html_diff.dart';
+
 // TODO(rnystrom): Use "package:" URL (#4968).
 import '../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart';
 import '../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart';
-import '../../sdk/lib/_internal/dartdoc/lib/dartdoc.dart' as doc;
+import '../../sdk/lib/_internal/dartdoc/lib/dartdoc.dart';
 import '../../sdk/lib/_internal/libraries.dart';
 
 HtmlDiff _diff;
@@ -29,13 +31,13 @@
 void main() {
   final args = new Options().arguments;
 
-  int mode = doc.MODE_STATIC;
+  int mode = MODE_STATIC;
   Path outputDir = new Path('docs');
   bool generateAppCache = false;
 
   List<String> excludedLibraries = <String>[];
   List<String> includedLibraries = <String>[];
-  var pkgPath;
+  Path pkgPath;
   String version;
 
   // Parse the command-line arguments.
@@ -44,11 +46,11 @@
 
     switch (arg) {
       case '--mode=static':
-        mode = doc.MODE_STATIC;
+        mode = MODE_STATIC;
         break;
 
       case '--mode=live-nav':
-        mode = doc.MODE_LIVE_NAV;
+        mode = MODE_LIVE_NAV;
         break;
 
       case '--generate-app-cache=true':
@@ -63,7 +65,7 @@
         } else if (arg.startsWith('--out=')) {
           outputDir = new Path(arg.substring('--out='.length));
         } else if (arg.startsWith('--pkg=')) {
-          pkgPath = arg.substring('--pkg='.length);
+          pkgPath = new Path(arg.substring('--pkg='.length));
         } else if (arg.startsWith('--version=')) {
           version = arg.substring('--version='.length);
         } else {
@@ -74,30 +76,30 @@
     }
   }
 
-  final libPath = doc.scriptDir.append('../../sdk/');
+  final libPath = scriptDir.append('../../sdk/');
 
-  doc.cleanOutputDirectory(outputDir);
+  cleanOutputDirectory(outputDir);
 
+  print('Copying static files...');
   // The basic dartdoc-provided static content.
-  final copiedStatic = doc.copyDirectory(
-      doc.scriptDir.append('../../sdk/lib/_internal/dartdoc/static'),
+  final copiedStatic = copyDirectory(
+      scriptDir.append('../../sdk/lib/_internal/dartdoc/static'),
       outputDir);
 
   // The apidoc-specific static content.
-  final copiedApiDocStatic = doc.copyDirectory(
-      doc.scriptDir.append('static'),
+  final copiedApiDocStatic = copyDirectory(
+      scriptDir.append('static'),
       outputDir);
 
   print('Parsing MDN data...');
-  final mdnFile = new File.fromPath(doc.scriptDir.append('mdn/database.json'));
+  final mdnFile = new File.fromPath(scriptDir.append('mdn/database.json'));
   final mdn = json.parse(mdnFile.readAsStringSync());
 
   print('Cross-referencing dart:html...');
-  HtmlDiff.initialize(libPath);
+  // TODO(amouravski): move HtmlDiff inside of the future chain below to re-use
+  // the MirrorSystem already analyzed.
   _diff = new HtmlDiff(printWarnings:false);
-  _diff.run();
-
-  // Process libraries.
+  Future htmlDiff = _diff.run(libPath);
 
   // TODO(johnniwinther): Libraries for the compilation seem to be more like
   // URIs. Perhaps Path should have a toURI() method.
@@ -109,57 +111,51 @@
     }
   });
 
-  var lister = new Directory.fromPath(doc.scriptDir.append('../../pkg')).list();
-  lister.listen(
-      (entity) {
-        if (entity is Directory) {
-          var path = new Path(entity.path);
-          var libName = path.filename;
+  // TODO(amouravski): This code is really wonky.
+  var lister = new Directory.fromPath(scriptDir.append('../../pkg')).list();
+  lister.listen((entity) {
+    if (entity is Directory) {
+      var path = new Path(entity.path);
+      var libName = path.filename;
+      var libPath = path.append('lib/$libName.dart');
 
-          // Ignore hidden directories (like .svn) as well as pkg.xcodeproj.
-          if (libName.startsWith('.') || libName.endsWith('.xcodeproj')) {
-            return;
-          }
+      // Ignore some libraries.
+      if (excludedLibraries.contains(libName)) {
+        return;
+      }
 
-          // TODO(rnystrom): Get rid of oldStylePath support when all
-          // packages are using new layout. See #5106.
-          var oldStylePath = path.append('${libName}.dart');
-          var newStylePath = path.append('lib/${libName}.dart');
+      // Ignore hidden directories (like .svn) as well as pkg.xcodeproj.
+      if (libName.startsWith('.') || libName.endsWith('.xcodeproj')) {
+        return;
+      }
 
-          if (new File.fromPath(oldStylePath).existsSync()) {
-            apidocLibraries.add(oldStylePath);
-            includedLibraries.add(libName);
-          } else if (new File.fromPath(newStylePath).existsSync()) {
-            apidocLibraries.add(newStylePath);
-            includedLibraries.add(libName);
-          } else {
-            print('Warning: could not find package at $path');
-          }
-        }
-      },
-      onDone: () {
-        print('Generating docs...');
-        final apidoc = new Apidoc(mdn, outputDir, mode, generateAppCache,
-                                  excludedLibraries, version);
-        apidoc.dartdocPath =
-            doc.scriptDir.append('../../sdk/lib/_internal/dartdoc/');
-        // Select the libraries to include in the produced documentation:
-        apidoc.includeApi = true;
-        apidoc.includedLibraries = includedLibraries;
+      if (new File.fromPath(libPath).existsSync()) {
+        apidocLibraries.add(libPath);
+        includedLibraries.add(libName);
+      } else {
+        print('Warning: could not find package at $path');
+      }
+    }
+  }, onDone: () {
+    final apidoc = new Apidoc(mdn, outputDir, mode, generateAppCache,
+                              excludedLibraries, version);
+    apidoc.dartdocPath =
+        scriptDir.append('../../sdk/lib/_internal/dartdoc/');
+    // Select the libraries to include in the produced documentation:
+    apidoc.includeApi = true;
+    apidoc.includedLibraries = includedLibraries;
 
-        Future.wait([copiedStatic, copiedApiDocStatic]).then((_) {
-          apidoc.documentLibraries(apidocLibraries, libPath, pkgPath);
-
-          final compiled = doc.compileScript(mode, outputDir, libPath);
-
-          Future.wait([compiled, copiedStatic, copiedApiDocStatic]).then((_) {
-            apidoc.cleanup();
-          });
-        });
-      });
+    // TODO(amouravski): make apidoc use roughly the same flow as bin/dartdoc.
+    Future.wait([copiedStatic, copiedApiDocStatic, htmlDiff])
+      .then((_) => apidoc.documentLibraries(apidocLibraries, libPath, pkgPath))
+      .then((_) => compileScript(mode, outputDir, libPath))
+      .then((_) => print(apidoc.status))
+      .catchError((e) => print('Error: generation failed: ${e.error}'))
+      .whenComplete(() => apidoc.cleanup());
+  });
 }
 
-class Apidoc extends doc.Dartdoc {
+class Apidoc extends Dartdoc {
   /** Big ball of JSON containing the scraped MDN documentation. */
   final Map mdn;
 
@@ -249,40 +245,40 @@
   void docIndexLibrary(LibraryMirror library) {
     // TODO(rnystrom): Hackish. The IO libraries reference this but we don't
     // want it in the docs.
-    if (doc.displayName(library) == 'dart:nativewrappers') return;
+    if (displayName(library) == 'dart:nativewrappers') return;
     super.docIndexLibrary(library);
   }
 
   void docLibraryNavigationJson(LibraryMirror library, List libraryList) {
     // TODO(rnystrom): Hackish. The IO libraries reference this but we don't
     // want it in the docs.
-    if (doc.displayName(library) == 'dart:nativewrappers') return;
+    if (displayName(library) == 'dart:nativewrappers') return;
     super.docLibraryNavigationJson(library, libraryList);
   }
 
   void docLibrary(LibraryMirror library) {
     // TODO(rnystrom): Hackish. The IO libraries reference this but we don't
     // want it in the docs.
-    if (doc.displayName(library) == 'dart:nativewrappers') return;
+    if (displayName(library) == 'dart:nativewrappers') return;
     super.docLibrary(library);
   }
 
-  doc.DocComment getLibraryComment(LibraryMirror library) {
+  DocComment getLibraryComment(LibraryMirror library) {
     return super.getLibraryComment(library);
   }
 
-  doc.DocComment getTypeComment(TypeMirror type) {
+  DocComment getTypeComment(TypeMirror type) {
     return _mergeDocs(
         includeMdnTypeComment(type), super.getTypeComment(type));
   }
 
-  doc.DocComment getMemberComment(MemberMirror member) {
+  DocComment getMemberComment(MemberMirror member) {
     return _mergeDocs(
         includeMdnMemberComment(member), super.getMemberComment(member));
   }
 
-  doc.DocComment _mergeDocs(doc.MdnComment mdnComment,
-                            doc.DocComment fileComment) {
+  DocComment _mergeDocs(MdnComment mdnComment,
+                            DocComment fileComment) {
     // Otherwise, prefer comment from the (possibly generated) Dart file.
     if (fileComment != null) return fileComment;
 
@@ -328,7 +324,7 @@
     }
   }
 
-  doc.MdnComment lookupMdnComment(Mirror mirror) { 
+  MdnComment lookupMdnComment(Mirror mirror) {
     if (mirror is TypeMirror) {
       return includeMdnTypeComment(mirror);
     } else if (mirror is MemberMirror) {
@@ -342,14 +338,13 @@
    * Gets the MDN-scraped docs for [type], or `null` if this type isn't
    * scraped from MDN.
    */
-  doc.MdnComment includeMdnTypeComment(TypeMirror type) {
+  MdnComment includeMdnTypeComment(TypeMirror type) {
     if (_mdnTypeNamesToSkip.contains(type.simpleName)) {
-      print('Skipping MDN type ${type.simpleName}');
       return null;
     }
 
     var typeString = '';
-    if (HTML_LIBRARY_NAMES.contains(doc.displayName(type.library))) {
+    if (HTML_LIBRARY_NAMES.contains(displayName(type.library))) {
       // If it's an HTML type, try to map it to a base DOM type so we can find
       // the MDN docs.
       final domTypes = _diff.htmlTypesToDom[type.qualifiedName];
@@ -376,7 +371,7 @@
     if (mdnType['summary'].trim().isEmpty) return null;
 
     // Remember which MDN page we're using so we can attribute it.
-    return new doc.MdnComment(mdnType['summary'], mdnType['srcUrl']);
+    return new MdnComment(mdnType['summary'], mdnType['srcUrl']);
   }
 
   /**
@@ -386,7 +381,7 @@
   MdnComment includeMdnMemberComment(MemberMirror member) {
     var library = findLibrary(member);
     var memberString = '';
-    if (HTML_LIBRARY_NAMES.contains(doc.displayName(library))) {
+    if (HTML_LIBRARY_NAMES.contains(displayName(library))) {
       // If it's an HTML type, try to map it to a DOM type name so we can find
       // the MDN docs.
       final domMembers = _diff.htmlToDom[member.qualifiedName];
@@ -429,7 +424,7 @@
     if (mdnMember['help'].trim().isEmpty) return null;
 
     // Remember which MDN page we're using so we can attribute it.
-    return new doc.MdnComment(mdnMember['help'], mdnType['srcUrl']);
+    return new MdnComment(mdnMember['help'], mdnType['srcUrl']);
   }
 
   /**
diff --git a/utils/apidoc/apidoc.gyp b/utils/apidoc/apidoc.gyp
index dd5d3a7..8c6cc70 100644
--- a/utils/apidoc/apidoc.gyp
+++ b/utils/apidoc/apidoc.gyp
@@ -50,8 +50,10 @@
             'apidoc.dart',
             '--out=<(PRODUCT_DIR)/api_docs',
             '--version=<!@(["python", "../../tools/print_version.py"])',
-            '--pkg=<(PRODUCT_DIR)/packages/',
+            '--pkg=<(PRODUCT_DIR)/packages',
             '--mode=static',
+            '--exclude-lib=analyzer_experimental',
+            '--exclude-lib=browser',
             '--exclude-lib=dartdoc',
             '--exclude-lib=http',
             '--exclude-lib=oauth2',
diff --git a/utils/apidoc/html_diff.dart b/utils/apidoc/html_diff.dart
index 3c8324d..9c3d2ee 100644
--- a/utils/apidoc/html_diff.dart
+++ b/utils/apidoc/html_diff.dart
@@ -8,25 +8,29 @@
  */
 library html_diff;
 
-import 'dart:io';
 import 'dart:async';
-import '../../sdk/lib/html/html_common/metadata.dart';
+import 'dart:io';
+
 import 'lib/metadata.dart';
 
 // TODO(rnystrom): Use "package:" URL (#4968).
-import '../../sdk/lib/_internal/dartdoc/lib/dartdoc.dart';
+import '../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart';
 import '../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart';
 import '../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart';
+import '../../sdk/lib/_internal/dartdoc/lib/dartdoc.dart';
+import '../../sdk/lib/html/html_common/metadata.dart';
 
 // TODO(amouravski): There is currently magic that looks at dart:* libraries
 // rather than the declared library names. This changed due to recent syntax
 // changes. We should only need to look at the library 'html'.
 const List<String> HTML_LIBRARY_NAMES = const [
     'dart:html',
+    'dart:indexed_db',
     'dart:svg',
     'dart:web_audio'];
 const List<String> HTML_DECLARED_NAMES = const [
     'dart.dom.html',
+    'dart.dom.indexed_db',
     'dart.dom.svg',
     'dart.dom.web_audio'];
 
@@ -69,23 +73,8 @@
   /** If true, then print warning messages. */
   final bool _printWarnings;
 
-  static Compilation _compilation;
-  static MirrorSystem _mirrors;
   static LibraryMirror dom;
 
-  /**
-   * Perform static initialization of [world]. This should be run before
-   * calling [HtmlDiff.run].
-   */
-  static void initialize(Path libDir) {
-    var paths = <Path>[];
-    for (var libraryName in HTML_LIBRARY_NAMES) {
-      paths.add(new Path(libraryName));
-    }
-    _compilation = new Compilation.library(paths, libDir);
-    _mirrors = _compilation.mirrors;
-  }
-
   HtmlDiff({bool printWarnings: false}) :
     _printWarnings = printWarnings,
     htmlToDom = new Map<String, Set<String>>(),
@@ -103,24 +92,33 @@
    * should be initialized (via [parseOptions] and [initializeWorld]) and
    * [HtmlDiff.initialize] should be called.
    */
-  void run() {
-    for (var libraryName in HTML_DECLARED_NAMES) {
-      var library = _mirrors.libraries[libraryName];
-      if (library == null) {
-        warn('Could not find $libraryName');
-        return;
-      }
-      for (ClassMirror type in library.classes.values) {
-        final domTypes = htmlToDomTypes(type);
-        if (domTypes.isEmpty) continue;
-
-        htmlTypesToDom.putIfAbsent(type.qualifiedName,
-            () => new Set()).addAll(domTypes);
-
-        type.members.forEach(
-            (_, m) => _addMemberDiff(m, domTypes, library.simpleName));
-      }
+  Future run(Path libDir) {
+    var result = new Completer();
+    var paths = <Path>[];
+    for (var libraryName in HTML_LIBRARY_NAMES) {
+      paths.add(new Path(libraryName));
     }
+    analyze(paths, libDir).then((MirrorSystem mirrors) {
+      for (var libraryName in HTML_DECLARED_NAMES) {
+        var library = mirrors.libraries[libraryName];
+        if (library == null) {
+          warn('Could not find $libraryName');
+          result.complete(false);
+        }
+        for (ClassMirror type in library.classes.values) {
+          final domTypes = htmlToDomTypes(type);
+          if (domTypes.isEmpty) continue;
+
+          htmlTypesToDom.putIfAbsent(type.qualifiedName,
+              () => new Set()).addAll(domTypes);
+
+          type.members.forEach(
+              (_, m) => _addMemberDiff(m, domTypes, library.simpleName));
+        }
+      }
+      result.complete(true);
+    });
+    return result.future;
   }
 
   /**
diff --git a/utils/apidoc/lib/metadata.dart b/utils/apidoc/lib/metadata.dart
index e042d00..c0a848c 100644
--- a/utils/apidoc/lib/metadata.dart
+++ b/utils/apidoc/lib/metadata.dart
@@ -4,7 +4,7 @@
 
 /// Returns the metadata for the given string or null if not found.
 InstanceMirror findMetadata(List<InstanceMirror> metadataList, String find) {
-  return metadataList.firstMatching(
+  return metadataList.firstWhere(
       (metadata) {
         if (metadata is TypeInstanceMirror) {
           return metadata.representedType.simpleName == find;
diff --git a/utils/apidoc/mdn/extract.dart b/utils/apidoc/mdn/extract.dart
index da3a7f3..65d753b 100644
--- a/utils/apidoc/mdn/extract.dart
+++ b/utils/apidoc/mdn/extract.dart
@@ -611,7 +611,7 @@
   if (prop != null && prop.length > 0) {
     // Only expect properties to have HTML.
     for(Element e in fragment.queryAll(IDL_SELECTOR)) {
-      idl.add(e.outerHTML);
+      idl.write(e.outerHTML);
       e.remove();
     }
     // TODO(jacobr) this is a very basic regex to see if text looks like IDL
@@ -621,7 +621,7 @@
       // Check if it looks like idl...
       String txt = e.text.trim();
       if (likelyIdl.hasMatch(txt) && txt.contains("\n") && txt.contains(")")) {
-        idl.add(e.outerHTML);
+        idl.write(e.outerHTML);
         e.remove();
       }
     }
@@ -1273,7 +1273,7 @@
   // safe to include in the summary.
   StringBuffer summary = new StringBuffer();
   for (Element e in root.queryAll("#Summary, #Description")) {
-    summary.add(filteredHtml(root, e, null, removeHeaders).html);
+    summary.write(filteredHtml(root, e, null, removeHeaders).html);
   }
 
   if (summary.length == 0) {
@@ -1288,7 +1288,7 @@
       }
     }
     // Risky... this might add stuff we shouldn't.
-    summary.add(filteredHtml(root, root, null, removeHeaders).html);
+    summary.write(filteredHtml(root, root, null, removeHeaders).html);
   }
 
   if (summary.length > 0) {
diff --git a/utils/apidoc/mdn/prettyPrint.dart b/utils/apidoc/mdn/prettyPrint.dart
index 6d4c323..0071279 100644
--- a/utils/apidoc/mdn/prettyPrint.dart
+++ b/utils/apidoc/mdn/prettyPrint.dart
@@ -31,7 +31,7 @@
       for(final name in sortStringCollection(expected.keys)) {
         if (!members.containsKey(name)) {
           total++;
-        sb.add("""
+        sb.write("""
                 <tr class="missing">
                   <td>$name</td>
                   <td></td>
@@ -71,7 +71,7 @@
 
   // TODO(jacobr): switch to using a real template system instead of string
   // interpolation combined with StringBuffers.
-  sb.add("""
+  sb.write("""
 <html>
   <head>
     <style type="text/css">
@@ -156,7 +156,7 @@
   	final entry = database[type];
     if (entry == null || entry.containsKey('skipped')) {
       numSkipped++;
-      sbSkipped.add("""
+      sbSkipped.write("""
     <li id="$type">
       <a target="_blank" href="http://www.google.com/cse?cx=017193972565947830266%3Awpqsk6dy6ee&ie=UTF-8&q=$type">
         $type
@@ -178,7 +178,7 @@
     StringBuffer sbExamples = new StringBuffer();
     if (entry.containsKey("members")) {
       Map members = getMembersMap(entry);
-      sbMembers.add("""
+      sbMembers.write("""
   	    <div class="members">
           <h3><span class="debug">[dart]</span> Members</h3>
           <table>
@@ -191,7 +191,7 @@
         Map memberData = members[name];
         bool unknown = !hasAny(type, name);
         StringBuffer classes = new StringBuffer();
-        if (unknown) classes.add("unknown ");
+        if (unknown) classes.write("unknown ");
         if (unknown) {
           numExtraMethods++;
         } else {
@@ -201,15 +201,15 @@
         final sbMember = new StringBuffer();
 
         if (memberData.containsKey('url')) {
-          sbMember.add("""
+          sbMember.write("""
 		         <td><a href="${memberData['url']}">$name</a></td>
 """);
         } else {
-          sbMember.add("""
+          sbMember.write("""
 		         <td>$name</td>
 """);
         }
-        sbMember.add("""
+        sbMember.write("""
 		  	     <td>${memberData['help']}</td>
              <td>
                <pre>${orEmpty(memberData['idl'])}</pre>
@@ -217,14 +217,14 @@
              <td>${memberData['obsolete'] == true ? "Obsolete" : ""}</td>
 """);
         if (memberData['obsolete'] == true) {
-          sbObsolete.add("<tr class='$classes'><td>$type</td>$sbMember</tr>");
+          sbObsolete.write("<tr class='$classes'><td>$type</td>$sbMember</tr>");
         }
-        sbMembers.add("<tr class='$classes'>$sbMember</tr>");
+        sbMembers.write("<tr class='$classes'>$sbMember</tr>");
     	}
 
       numMissingMethods += addMissing(sbMembers, type, members);
 
-      sbMembers.add("""
+      sbMembers.write("""
             </tbody>
           </table>
         </div>
@@ -234,7 +234,7 @@
         ["summary", "constructor", "compatibility", "specification",
          "seeAlso"]) {
       if (entry.containsKey(sectionName)) {
-        sbSections.add("""
+        sbSections.write("""
       <div class="$sectionName">
         <h3><span class="debug">[Dart]</span> $sectionName</h3>
         ${entry[sectionName]}
@@ -243,25 +243,25 @@
       }
     }
     if (entry.containsKey("links")) {
-      sbSections.add("""
+      sbSections.write("""
       <div class="links">
         <h3><span class="debug">[Dart]</span> Specification</h3>
         <ul>
 """);
     	List links = entry["links"];
     	for (Map link in links) {
-    	  sbSections.add("""
+    	  sbSections.write("""
       <li><a href="${link['href']}">${link['title']}</a></li>
 """);
       }
-      sbSections.add("""
+      sbSections.write("""
         </ul>
       </div>
 """);
     }
     if (entry.containsKey("examples")) {
     	for (String example in entry["examples"]) {
-  	  sbExamples.add("""
+  	  sbExamples.write("""
 	    <div class="example">
 	  	  <h3><span class="debug">[Dart]</span> Example</h3>
 	  	  $example
@@ -276,7 +276,7 @@
     } else {
       title = '<h2>$title</h2>';
     }
-    sb.add("""
+    sb.write("""
     <div class='type' id="$type">
       <a href='${entry['srcUrl']}'>$title</a>
 $sbSections
@@ -285,7 +285,7 @@
     </div>
 """);
     if (sbExamples.length > 0) {
-      sbAllExamples.add("""
+      sbAllExamples.write("""
     <div class='type' id="$type">
       <a href='${entry['srcUrl']}'>$title</a>
       $sbExamples
@@ -298,7 +298,7 @@
     if (!matchedTypes.contains(type) &&
         !database.containsKey(type)) {
       numSkipped++;
-      sbSkipped.add("""
+      sbSkipped.write("""
     <li class="unknown" id="$type">
       <a target="_blank" href="http://www.google.com/cse?cx=017193972565947830266%3Awpqsk6dy6ee&ie=UTF-8&q=$type">
         $type
@@ -308,7 +308,7 @@
     }
   }
 
-  sb.add("""
+  sb.write("""
 <div id="#dart_summary">
   <h2>Summary</h2>
   <h3>
@@ -332,7 +332,7 @@
   </ul>
 </div>
 """);
-  sb.add("""
+  sb.write("""
   </body>
 </html>
 """);
diff --git a/utils/css/generate.dart b/utils/css/generate.dart
index 076b3aa..2d24845 100644
--- a/utils/css/generate.dart
+++ b/utils/css/generate.dart
@@ -38,26 +38,26 @@
         if (production is StyletDirective) {
           // TODO(terry): Need safer mechanism for stylets in different files
           //              and stylets with colliding names.
-          buff.add('class ${production.dartClassName} {\n');
-          buff.add('  // selector, properties<propertyName, value>\n');
-          buff.add('  static const selectors = const {\n');
+          buff.write('class ${production.dartClassName} {\n');
+          buff.write('  // selector, properties<propertyName, value>\n');
+          buff.write('  static const selectors = const {\n');
 
           for (final ruleset in production.rulesets) {
             for (final selector in ruleset.selectorGroup.selectors) {
               var selSeq = selector.simpleSelectorSquences;
               if (selSeq.length == 1) {
-                buff.add('    \'${selSeq.toString()}\' : const {\n');
+                buff.write('    \'${selSeq.toString()}\' : const {\n');
               }
             }
 
             for (final decl in ruleset.declarationGroup.declarations) {
-              buff.add('      \'${decl.property}\' : ' +
+              buff.write('      \'${decl.property}\' : ' +
                   '\'${decl.expression.toString()}\',\n');
             }
-            buff.add('    },\n');   // End of declarations for stylet class.
+            buff.write('    },\n');   // End of declarations for stylet class.
           }
-          buff.add('  };\n');       // End of static selectors constant.
-          buff.add('}\n\n');        // End of stylet class
+          buff.write('  };\n');       // End of static selectors constant.
+          buff.write('}\n\n');        // End of stylet class
         } else if (production is IncludeDirective) {
           for (final topLevel in production.styleSheet._topLevels) {
             if (topLevel is RuleSet) {
@@ -76,11 +76,11 @@
       '  // CSS class selectors:\n');
     for (final className in knownClasses) {
       String classAsDart = className.replaceAll('-', '_').toUpperCase();
-      classSelectors.add('  static const String ${classAsDart} = ' +
+      classSelectors.write('  static const String ${classAsDart} = ' +
           '\'${className}\';\n');
     }
-    classSelectors.add('}\n');            // End of class selectors.
-    buff.add(classSelectors.toString());
+    classSelectors.write('}\n');            // End of class selectors.
+    buff.write(classSelectors.toString());
 
     // Write Dart file.
     String outFile = '${outPath}CSS.dart';
diff --git a/utils/css/parser.dart b/utils/css/parser.dart
index d799e43..a865bdf 100644
--- a/utils/css/parser.dart
+++ b/utils/css/parser.dart
@@ -924,7 +924,7 @@
     int runningStart = _peekToken.start;
     while (_peek() != stopToken && _peek() != TokenKind.END_OF_FILE) {
       var tok = _next();
-      stringValue.add(tok.text);
+      stringValue.write(tok.text);
     }
 
     if (stopToken != TokenKind.RPAREN) {
diff --git a/utils/css/source.dart b/utils/css/source.dart
index a5e981b..5eeb0e2 100644
--- a/utils/css/source.dart
+++ b/utils/css/source.dart
@@ -80,7 +80,7 @@
     var buf = new StringBuffer(
         '${filename}:${line + 1}:${column + 1}: $message');
     if (includeText) {
-      buf.add('\n');
+      buf.write('\n');
       var textLine;
       // +1 for 0-indexing, +1 again to avoid the last line of the file
       if ((line + 2) < _lineStarts.length) {
@@ -91,25 +91,25 @@
 
       int toColumn = Math.min(column + (end-start), textLine.length);
       if (options.useColors) {
-        buf.add(textLine.substring(0, column));
-        buf.add(_RED_COLOR);
-        buf.add(textLine.substring(column, toColumn));
-        buf.add(_NO_COLOR);
-        buf.add(textLine.substring(toColumn));
+        buf.write(textLine.substring(0, column));
+        buf.write(_RED_COLOR);
+        buf.write(textLine.substring(column, toColumn));
+        buf.write(_NO_COLOR);
+        buf.write(textLine.substring(toColumn));
       } else {
-        buf.add(textLine);
+        buf.write(textLine);
       }
 
       int i = 0;
       for (; i < column; i++) {
-        buf.add(' ');
+        buf.write(' ');
       }
 
-      if (options.useColors) buf.add(_RED_COLOR);
+      if (options.useColors) buf.write(_RED_COLOR);
       for (; i < toColumn; i++) {
-        buf.add('^');
+        buf.write('^');
       }
-      if (options.useColors) buf.add(_NO_COLOR);
+      if (options.useColors) buf.write(_NO_COLOR);
     }
 
     return buf.toString();
diff --git a/utils/css/tokenkind.dart b/utils/css/tokenkind.dart
index 6112e82..fbcebdf 100644
--- a/utils/css/tokenkind.dart
+++ b/utils/css/tokenkind.dart
@@ -487,10 +487,10 @@
     StringBuffer invertResult = new StringBuffer();
     int paddings = minDigits - result.length;
     while (paddings-- > 0) {
-      invertResult.add('0');
+      invertResult.write('0');
     }
     for (int idx = result.length - 1; idx >= 0; idx--) {
-      invertResult.add(result[idx]);
+      invertResult.write(result[idx]);
     }
 
     return invertResult.toString();
diff --git a/utils/css/tool.dart b/utils/css/tool.dart
index 6a96b50..cad31a2 100644
--- a/utils/css/tool.dart
+++ b/utils/css/tool.dart
@@ -72,7 +72,7 @@
       '/* File generated by SCSS from source ${sourceFilename}\n' +
       ' * Do not edit.\n' +
       ' */\n\n');
-    buff.add(stylesheet.toString());
+    buff.write(stylesheet.toString());
 
     files.writeString(outputFullFn, buff.toString());
     print("Generated file ${outputFullFn}");
diff --git a/utils/css/tree.dart b/utils/css/tree.dart
index 901659a..08160e4 100644
--- a/utils/css/tree.dart
+++ b/utils/css/tree.dart
@@ -60,9 +60,9 @@
     int idx = 0;
     for (final selector in _selectors) {
       if (idx++ > 0) {
-        buff.add(', ');
+        buff.write(', ');
       }
-      buff.add(selector.toString());
+      buff.write(selector.toString());
     }
     return buff.toString();
   }
@@ -94,7 +94,7 @@
   String toString() {
     StringBuffer buff = new StringBuffer();
     for (final simpleSelectorSequence in _simpleSelectorSequences) {
-      buff.add(simpleSelectorSequence.toString());
+      buff.write(simpleSelectorSequence.toString());
     }
     return buff.toString();
   }
@@ -301,7 +301,7 @@
   String toString() {
     StringBuffer buff = new StringBuffer();
     for (final topLevel in _topLevels) {
-      buff.add(topLevel.toString());
+      buff.write(topLevel.toString());
     }
     return buff.toString();
   }
@@ -363,13 +363,13 @@
   String toString() {
     StringBuffer buff = new StringBuffer();
 
-    buff.add('@import url(${_import})');
+    buff.write('@import url(${_import})');
 
     int idx = 0;
     for (final medium in _media) {
-      buff.add(idx++ == 0 ? ' $medium' : ',$medium');
+      buff.write(idx++ == 0 ? ' $medium' : ',$medium');
     }
-    buff.add('\n');
+    buff.write('\n');
 
     return buff.toString();
   }
@@ -387,14 +387,14 @@
   String toString() {
     StringBuffer buff = new StringBuffer();
 
-    buff.add('@media');
+    buff.write('@media');
     int idx = 0;
     for (var medium in _media) {
-      buff.add(idx++ == 0 ? ' $medium' : ',$medium');
+      buff.write(idx++ == 0 ? ' $medium' : ',$medium');
     }
-    buff.add(' {\n');
-    buff.add(_ruleset.toString());
-    buff.add('\n\}\n');
+    buff.write(' {\n');
+    buff.write(_ruleset.toString());
+    buff.write('\n\}\n');
 
     return buff.toString();
   }
@@ -415,11 +415,11 @@
   String toString() {
     StringBuffer buff = new StringBuffer();
 
-    buff.add('@page ');
+    buff.write('@page ');
     if (_pseudoPage != null) {
-      buff.add(': ${_pseudoPage} ');
+      buff.write(': ${_pseudoPage} ');
     }
-    buff.add('{\n${_decls.toString()}\n}\n');
+    buff.write('{\n${_decls.toString()}\n}\n');
 
     return buff.toString();
   }
@@ -442,11 +442,11 @@
 
   String toString() {
     StringBuffer buff = new StringBuffer();
-    buff.add('@-webkit-keyframes ${_name} {\n');
+    buff.write('@-webkit-keyframes ${_name} {\n');
     for (final block in _blocks) {
-      buff.add(block.toString());
+      buff.write(block.toString());
     }
-    buff.add('}\n');
+    buff.write('}\n');
     return buff.toString();
   }
 }
@@ -462,9 +462,9 @@
 
   String toString() {
     StringBuffer buff = new StringBuffer();
-    buff.add('  ${_blockSelectors.toString()} {\n');
-    buff.add(_declarations.toString());
-    buff.add('  }\n');
+    buff.write('  ${_blockSelectors.toString()} {\n');
+    buff.write(_declarations.toString());
+    buff.write('  }\n');
     return buff.toString();
   }
 }
@@ -498,9 +498,9 @@
 
   String toString() {
     StringBuffer buff = new StringBuffer();
-    buff.add('/****** @include ${_include} ******/\n');
-    buff.add(_stylesheet != null ? _stylesheet.toString() : '// <EMPTY>');
-    buff.add('/****** End of ${_include} ******/\n\n');
+    buff.write('/****** @include ${_include} ******/\n');
+    buff.write(_stylesheet != null ? _stylesheet.toString() : '// <EMPTY>');
+    buff.write('/****** End of ${_include} ******/\n\n');
     return buff.toString();
   }
 }
@@ -558,7 +558,7 @@
     StringBuffer buff = new StringBuffer();
     int idx = 0;
     for (final declaration in _declarations) {
-      buff.add("  ${declaration.toString()};\n");
+      buff.write("  ${declaration.toString()};\n");
     }
     return buff.toString();
   }
@@ -725,9 +725,9 @@
     // TODO(terry): Optimize rgb to a hexcolor.
     StringBuffer buff = new StringBuffer();
 
-    buff.add('${text}(');
-    buff.add(_params.toString());
-    buff.add(')');
+    buff.write('${text}(');
+    buff.write(_params.toString());
+    buff.write(')');
 
     return buff.toString();
   }
@@ -746,15 +746,15 @@
 
   String toString() {
     StringBuffer buff = new StringBuffer();
-    buff.add('(');
+    buff.write('(');
     int idx = 0;
     for (final term in _terms) {
       if (idx++ > 0) {
-        buff.add(' ');
+        buff.write(' ');
       }
-      buff.add(term.toString());
+      buff.write(term.toString());
     }
-    buff.add(')');
+    buff.write(')');
     return buff.toString();
   }
 }
@@ -788,9 +788,9 @@
       // TODO(terry): Should have a BinaryExpression to solve this problem.
       if (idx > 0 &&
           !(expression is OperatorComma || expression is OperatorSlash)) {
-        buff.add(' ');
+        buff.write(' ');
       }
-      buff.add(expression.toString());
+      buff.write(expression.toString());
       idx++;
     }
     return buff.toString();
diff --git a/utils/css/treebase.dart b/utils/css/treebase.dart
index c5d517a..7bdc3e6 100644
--- a/utils/css/treebase.dart
+++ b/utils/css/treebase.dart
@@ -57,20 +57,20 @@
 
   void write(String s) {
     for (int i=0; i < depth; i++) {
-      buf.add(' ');
+      buf.write(' ');
     }
-    buf.add(s);
+    buf.write(s);
   }
 
   void writeln(String s) {
     write(s);
-    buf.add('\n');
+    buf.write('\n');
   }
 
   void heading(String name, span) {
     write(name);
-    buf.add('  (${span.locationText})');
-    buf.add('\n');
+    buf.write('  (${span.locationText})');
+    buf.write('\n');
   }
 
   String toValue(value) {
@@ -95,14 +95,14 @@
   void writeList(String label, List list) {
     write(label + ': ');
     if (list == null) {
-      buf.add('null');
-      buf.add('\n');
+      buf.write('null');
+      buf.write('\n');
     } else {
       for (var item in list) {
-        buf.add(item.toString());
-        buf.add(', ');
+        buf.write(item.toString());
+        buf.write(', ');
       }
-      buf.add('\n');
+      buf.write('\n');
     }
   }
 
diff --git a/utils/css/uitest.dart b/utils/css/uitest.dart
index 87c913a..bbbbad0 100644
--- a/utils/css/uitest.dart
+++ b/utils/css/uitest.dart
@@ -43,9 +43,9 @@
       Stylesheet stylesheet = parser.parse();
       StringBuffer stylesheetTree = new StringBuffer();
       String prettyStylesheet = stylesheet.toString();
-      stylesheetTree.add("${prettyStylesheet}\n");
-      stylesheetTree.add("\n============>Tree Dump<============\n");
-      stylesheetTree.add(stylesheet.toDebugString());
+      stylesheetTree.write("${prettyStylesheet}\n");
+      stylesheetTree.write("\n============>Tree Dump<============\n");
+      stylesheetTree.write(stylesheet.toDebugString());
       dumpTree = stylesheetTree.toString();
     } catch (cssParseException) {
       templateValid = false;
diff --git a/utils/lib/file_system_memory.dart b/utils/lib/file_system_memory.dart
index f638a41..c1a15b9 100644
--- a/utils/lib/file_system_memory.dart
+++ b/utils/lib/file_system_memory.dart
@@ -17,7 +17,7 @@
   MemoryFileSystem() : this.buffer = new StringBuffer();
 
   void writeString(String outfile, String text) {
-    buffer.add(text);
+    buffer.write(text);
   }
 
   String readAll(String filename) {
diff --git a/utils/peg/pegparser.dart b/utils/peg/pegparser.dart
index bd329c7..ba1526b 100644
--- a/utils/peg/pegparser.dart
+++ b/utils/peg/pegparser.dart
@@ -600,14 +600,14 @@
 
 String _formatMultiRule(String functor, List rules) {
   var sb = new StringBuffer(functor);
-  sb.add('(');
+  sb.write('(');
   var separator = '';
   for (var rule in rules) {
-    sb.add(separator);
-    sb.add(rule);
+    sb.write(separator);
+    sb.write(rule);
     separator = ',';
   }
-  sb.add(')');
+  sb.write(')');
   return sb.toString();
 }
 
diff --git a/utils/pub/command_cache.dart b/utils/pub/command_cache.dart
new file mode 100644
index 0000000..056f383
--- /dev/null
+++ b/utils/pub/command_cache.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 command_cache;
+
+import 'dart:async';
+import 'dart:io';
+import 'dart:json' as json;
+
+import 'exit_codes.dart' as exit_codes;
+import 'log.dart' as log;
+import 'pub.dart';
+
+
+/// Handles the `cache` pub command.
+class CacheCommand extends PubCommand { 
+  String get description => "Inspect the system cache.";
+  String get usage => 'pub cache list';
+  bool get requiresEntrypoint => false;
+  
+  Future onRun() {
+    if (commandOptions.rest.length != 1) {
+      log.error('The cache command expects one argument.');
+      this.printUsage();
+      exit(exit_codes.USAGE);
+    }
+    
+    if ((commandOptions.rest[0] != 'list')) {
+      log.error('Unknown cache command "${commandOptions.rest[0]}".');
+      this.printUsage();
+      exit(exit_codes.USAGE);
+    }
+    
+    // TODO(keertip): Add flag to list packages from non default sources
+    return cache.sources.defaultSource.getCachedPackages().then((packages){
+      var packagesObj = <String, Map>{};
+      for (var package in packages){
+        packagesObj[package.name] = {
+          'version': package.version.toString(),
+          'location': package.dir
+        };
+      }
+      // TODO(keertip): Add support for non-JSON format 
+      // and check for --format flag
+      log.message( json.stringify({'packages': packagesObj}));
+    });
+  }  
+}
+
diff --git a/utils/pub/command_lish.dart b/utils/pub/command_lish.dart
index 356ed52..84afdc0 100644
--- a/utils/pub/command_lish.dart
+++ b/utils/pub/command_lish.dart
@@ -85,13 +85,15 @@
     }).catchError((asyncError) {
       if (asyncError.error is! PubHttpException) throw asyncError;
       var url = asyncError.error.response.request.url;
-      if (url.toString() == cloudStorageUrl.toString()) {
+      if (urisEqual(url, cloudStorageUrl)) {
         // TODO(nweiz): the response may have XML-formatted information about
         // the error. Try to parse that out once we have an easily-accessible
         // XML parser.
         throw 'Failed to upload the package.';
-      } else if (url.origin == server.origin) {
+      } else if (urisEqual(Uri.parse(url.origin), Uri.parse(server.origin))) {
         handleJsonError(asyncError.error.response);
+      } else {
+        throw asyncError;
       }
     });
   }
diff --git a/utils/pub/directory_tree.dart b/utils/pub/directory_tree.dart
index 3610e72..8829655 100644
--- a/utils/pub/directory_tree.dart
+++ b/utils/pub/directory_tree.dart
@@ -75,18 +75,17 @@
 void _drawLine(StringBuffer buffer, String prefix, bool isLastChild,
                String name) {
   // Print lines.
-  buffer.add(prefix);
+  buffer.write(prefix);
   if (name != null) {
     if (isLastChild) {
-      buffer.add("'-- ");
+      buffer.write("'-- ");
     } else {
-      buffer.add("|-- ");
+      buffer.write("|-- ");
     }
   }
 
   // Print name.
-  buffer.add(name);
-  buffer.add('\n');
+  buffer.writeln(name);
 }
 
 String _getPrefix(bool isRoot, bool isLast) {
@@ -121,9 +120,9 @@
     _drawChild(false, childNames[2]);
 
     // Elide the middle ones.
-    buffer.add(prefix);
-    buffer.add(_getPrefix(name == null, isLast));
-    buffer.add('| (${childNames.length - 6} more...)\n');
+    buffer.write(prefix);
+    buffer.write(_getPrefix(name == null, isLast));
+    buffer.writeln('| (${childNames.length - 6} more...)');
 
     // Show the last few.
     _drawChild(false, childNames[childNames.length - 3]);
diff --git a/utils/pub/error_group.dart b/utils/pub/error_group.dart
index 16b96b19..5e6baf8 100644
--- a/utils/pub/error_group.dart
+++ b/utils/pub/error_group.dart
@@ -232,10 +232,6 @@
   /// Whether [this] has any listeners.
   bool get _hasListeners => _controller.hasSubscribers;
 
-  // TODO(nweiz): Remove this when issue 8512 is fixed.
-  /// Whether the subscription has been cancelled.
-  bool _cancelled = false;
-
   /// Creates a new [_ErrorGroupFuture] that's a child of [_group] and wraps
   /// [inner].
   _ErrorGroupStream(this._group, Stream inner)
@@ -243,15 +239,13 @@
           new StreamController.broadcast() :
           new StreamController() {
     _subscription = inner.listen((v) {
-      if (!_cancelled) _controller.add(v);
+      _controller.add(v);
     }, onError: (e) {
-      if (!_cancelled) _group._signalError(e);
+      _group._signalError(e);
     }, onDone: () {
-      if (!_cancelled) {
-        _isDone = true;
-        _group._signalStreamComplete(this);
-        _controller.close();
-      }
+      _isDone = true;
+      _group._signalStreamComplete(this);
+      _controller.close();
     });
   }
 
@@ -268,11 +262,10 @@
   /// unless it's already complete.
   void _signalError(AsyncError e) {
     if (_isDone) return;
-    _cancelled = true;
     _subscription.cancel();
     // Call these asynchronously to work around issue 7913.
     defer(() {
-      _controller.signalError(e.error, e.stackTrace);
+      _controller.addError(e.error, e.stackTrace);
       _controller.close();
     });
   }
diff --git a/utils/pub/git_source.dart b/utils/pub/git_source.dart
index bbe7952..986c48e 100644
--- a/utils/pub/git_source.dart
+++ b/utils/pub/git_source.dart
@@ -116,6 +116,8 @@
     });
   }
 
+  // TODO(keertip): Implement getCachedPackages().
+  
   /// Ensure that the canonical clone of the repository referred to by [id] (the
   /// one in `<system cache>/git/cache`) exists and is up-to-date. Returns a
   /// future that completes once this is finished and throws an exception if it
diff --git a/utils/pub/hosted_source.dart b/utils/pub/hosted_source.dart
index ef64d59..00e489b 100644
--- a/utils/pub/hosted_source.dart
+++ b/utils/pub/hosted_source.dart
@@ -93,7 +93,7 @@
   /// from that site.
   Future<String> systemCacheDirectory(PackageId id) {
     var parsed = _parseDescription(id.description);
-    var url = parsed.last.replaceAll(new RegExp(r"^https?://"), "");
+    var url = _getSourceDirectory(parsed.last);
     var urlDir = replace(url, new RegExp(r'[<>:"\\/|?*%]'), (match) {
       return '%${match[0].codeUnitAt(0)}';
     });
@@ -118,6 +118,19 @@
     return description;
   }
 
+  Future<List<Package>> getCachedPackages() {
+    return defer(() {
+      var cacheDir = path.join(systemCacheRoot, 
+                               _getSourceDirectory(_defaultUrl)); 
+      if (!dirExists(cacheDir)) return [];
+    
+      return listDir(path.join(cacheDir)).then((entries) {
+        return entries.map((entry) => 
+          new Package.load(null, entry, systemCache.sources));
+      });  
+    });
+  }
+  
   /// When an error occurs trying to read something about [package] from [url],
   /// this tries to translate into a more user friendly error message. Always
   /// throws an error, either the original one or a better one.
@@ -145,6 +158,10 @@
 /// The URL of the default package repository.
 final _defaultUrl = "https://pub.dartlang.org";
 
+String _getSourceDirectory(String url) {
+  return url.replaceAll(new RegExp(r"^https?://"), "");
+}
+
 /// Parses [description] into its server and package name components, then
 /// converts that to a Uri given [pattern]. Ensures the package name is
 /// properly URL encoded.
diff --git a/utils/pub/http.dart b/utils/pub/http.dart
index fe80834..59fb586 100644
--- a/utils/pub/http.dart
+++ b/utils/pub/http.dart
@@ -13,6 +13,7 @@
 import '../../pkg/http/lib/http.dart' as http;
 import 'io.dart';
 import 'log.dart' as log;
+import 'oauth2.dart' as oauth2;
 import 'utils.dart';
 
 // TODO(nweiz): make this configurable
@@ -20,6 +21,9 @@
 /// they've failed.
 final HTTP_TIMEOUT = 30 * 1000;
 
+/// Headers and field names that should be censored in the log output.
+final _CENSORED_FIELDS = const ['refresh_token', 'authorization'];
+
 /// An HTTP client that transforms 40* errors and socket exceptions into more
 /// user-friendly error messages.
 class PubHttpClient extends http.BaseClient {
@@ -29,8 +33,7 @@
     : this.inner = inner == null ? new http.Client() : inner;
 
   Future<http.StreamedResponse> send(http.BaseRequest request) {
-    // TODO(rnystrom): Log request body when it's available and plaintext, but
-    // not when it contains OAuth2 credentials.
+    _logRequest(request);
 
     // TODO(nweiz): remove this when issue 4061 is fixed.
     var stackTrace;
@@ -43,13 +46,17 @@
     // TODO(nweiz): Ideally the timeout would extend to reading from the
     // response input stream, but until issue 3657 is fixed that's not feasible.
     return timeout(inner.send(request).then((streamedResponse) {
-      log.fine("Got response ${streamedResponse.statusCode} "
-               "${streamedResponse.reasonPhrase}.");
+      _logResponse(streamedResponse);
 
       var status = streamedResponse.statusCode;
       // 401 responses should be handled by the OAuth2 client. It's very
-      // unlikely that they'll be returned by non-OAuth2 requests.
-      if (status < 400 || status == 401) return streamedResponse;
+      // unlikely that they'll be returned by non-OAuth2 requests. We also want
+      // to pass along 400 responses from the token endpoint.
+      var tokenRequest = urisEqual(
+          streamedResponse.request.url, oauth2.tokenEndpoint);
+      if (status < 400 || status == 401 || (status == 400 && tokenRequest)) {
+        return streamedResponse;
+      }
 
       return http.Response.fromStream(streamedResponse).then((response) {
         throw new PubHttpException(response);
@@ -71,6 +78,65 @@
       throw asyncError;
     }), HTTP_TIMEOUT, 'fetching URL "${request.url}"');
   }
+
+  /// Logs the fact that [request] was sent, and information about it.
+  void _logRequest(http.BaseRequest request) {
+    var requestLog = new StringBuffer();
+    requestLog.writeln("HTTP ${request.method} ${request.url}");
+    request.headers.forEach((name, value) =>
+        requestLog.writeln(_logField(name, value)));
+
+    if (request.method == 'POST') {
+      var contentTypeString = request.headers[HttpHeaders.CONTENT_TYPE];
+      if (contentTypeString == null) contentTypeString = '';
+      var contentType = new ContentType.fromString(contentTypeString);
+      if (request is http.MultipartRequest) {
+        requestLog.writeln();
+        requestLog.writeln("Body fields:");
+        request.fields.forEach((name, value) =>
+            requestLog.writeln(_logField(name, value)));
+
+        // TODO(nweiz): make MultipartRequest.files readable, and log them?
+      } else if (request is http.Request) {
+        if (contentType.value == 'application/x-www-form-urlencoded') {
+          requestLog.writeln();
+          requestLog.writeln("Body fields:");
+          request.bodyFields.forEach((name, value) =>
+              requestLog.writeln(_logField(name, value)));
+        } else if (contentType.value == 'text/plain' ||
+            contentType.value == 'application/json') {
+          requestLog.write(request.body);
+        }
+      }
+    }
+
+    log.fine(requestLog.toString().trim());
+  }
+
+  /// Logs the fact that [response] was received, and information about it.
+  void _logResponse(http.StreamedResponse response) {
+    // TODO(nweiz): Fork the response stream and log the response body. Be
+    // careful not to log OAuth2 private data, though.
+
+    var responseLog = new StringBuffer();
+    var request = response.request;
+    responseLog.writeln("HTTP response ${response.statusCode} "
+        "${response.reasonPhrase} for ${request.method} ${request.url}");
+    response.headers.forEach((name, value) =>
+        responseLog.writeln(_logField(name, value)));
+
+    log.fine(responseLog.toString().trim());
+  }
+
+  /// Returns a log-formatted string for the HTTP field or header with the given
+  /// [name] and [value].
+  String _logField(String name, String value) {
+    if (_CENSORED_FIELDS.contains(name.toLowerCase())) {
+      return "$name: <censored>";
+    } else {
+      return "$name: $value";
+    }
+  }
 }
 
 /// The HTTP client to use for all HTTP requests.
diff --git a/utils/pub/io.dart b/utils/pub/io.dart
index 6e5ef86..1d9b824 100644
--- a/utils/pub/io.dart
+++ b/utils/pub/io.dart
@@ -63,7 +63,7 @@
 
 /// Deletes [file].
 void deleteFile(String file) {
-  new File(file).delete();
+  new File(file).deleteSync();
 }
 
 /// Creates [file] and writes [contents] to it.
@@ -352,15 +352,15 @@
 
 /// A sink that writes to standard output. Errors piped to this stream will be
 /// surfaced to the top-level error handler.
-final StreamSink<List<int>> stdoutSink = _wrapStdio(stdout, "stdout");
+final EventSink<List<int>> stdoutSink = _wrapStdio(stdout, "stdout");
 
 /// A sink that writes to standard error. Errors piped to this stream will be
 /// surfaced to the top-level error handler.
-final StreamSink<List<int>> stderrSink = _wrapStdio(stderr, "stderr");
+final EventSink<List<int>> stderrSink = _wrapStdio(stderr, "stderr");
 
-/// Wrap the standard output or error [stream] in a [StreamSink]. Any errors are
+/// Wrap the standard output or error [stream] in a [EventSink]. Any errors are
 /// logged, and then the program is terminated. [name] is used for debugging.
-StreamSink<List<int>> _wrapStdio(IOSink sink, String name) {
+EventSink<List<int>> _wrapStdio(IOSink sink, String name) {
   var pair = consumerToSink(sink);
   pair.last.catchError((e) {
     // This log may or may not work, depending on how the stream failed. Not
@@ -394,13 +394,13 @@
   return stream.reduce(null, (x, y) {});
 }
 
-/// Returns a [StreamSink] that pipes all data to [consumer] and a [Future] that
-/// will succeed when [StreamSink] is closed or fail with any errors that occur
+/// Returns a [EventSink] that pipes all data to [consumer] and a [Future] that
+/// will succeed when [EventSink] is closed or fail with any errors that occur
 /// while writing.
-Pair<StreamSink, Future> consumerToSink(StreamConsumer consumer) {
+Pair<EventSink, Future> consumerToSink(StreamConsumer consumer) {
   var controller = new StreamController();
   var done = controller.stream.pipe(consumer);
-  return new Pair<StreamSink, Future>(controller.sink, done);
+  return new Pair<EventSink, Future>(controller.sink, done);
 }
 
 // TODO(nweiz): remove this when issue 7786 is fixed.
@@ -413,12 +413,12 @@
 /// more data or errors will be piped from [stream] to [sink]. If
 /// [unsubscribeOnError] and [closeSink] are both true, [sink] will then be
 /// closed.
-Future store(Stream stream, StreamSink sink,
+Future store(Stream stream, EventSink sink,
     {bool unsubscribeOnError: true, closeSink: true}) {
   var completer = new Completer();
   stream.listen(sink.add,
       onError: (e) {
-        sink.signalError(e);
+        sink.addError(e);
         if (unsubscribeOnError) {
           completer.complete();
           if (closeSink) sink.close();
@@ -475,7 +475,7 @@
   final Process _process;
 
   /// The mutable field for [stdin].
-  StreamSink<List<int>> _stdin;
+  EventSink<List<int>> _stdin;
 
   /// The mutable field for [stdinClosed].
   Future _stdinClosed;
@@ -492,7 +492,7 @@
   /// The sink used for passing data to the process's standard input stream.
   /// Errors on this stream are surfaced through [stdinClosed], [stdout],
   /// [stderr], and [exitCode], which are all members of an [ErrorGroup].
-  StreamSink<List<int>> get stdin => _stdin;
+  EventSink<List<int>> get stdin => _stdin;
 
   // TODO(nweiz): write some more sophisticated Future machinery so that this
   // doesn't surface errors from the other streams/futures, but still passes its
@@ -741,7 +741,7 @@
     }).catchError((e) {
       // We don't have to worry about double-signaling here, since the store()
       // above will only be reached if startProcess succeeds.
-      controller.signalError(e.error, e.stackTrace);
+      controller.addError(e.error, e.stackTrace);
       controller.close();
     });
     return new ByteStream(controller.stream);
@@ -778,7 +778,7 @@
   }).catchError((e) {
     // We don't have to worry about double-signaling here, since the store()
     // above will only be reached if everything succeeds.
-    controller.signalError(e.error, e.stackTrace);
+    controller.addError(e.error, e.stackTrace);
     controller.close();
   });
   return new ByteStream(controller.stream);
diff --git a/utils/pub/log.dart b/utils/pub/log.dart
index 5f1c578..870a305 100644
--- a/utils/pub/log.dart
+++ b/utils/pub/log.dart
@@ -208,7 +208,7 @@
   _logToStream(stderrSink, entry, showLabel: true);
 }
 
-void _logToStream(StreamSink<List<int>> sink, Entry entry, {bool showLabel}) {
+void _logToStream(EventSink<List<int>> sink, Entry entry, {bool showLabel}) {
   bool firstLine = true;
   for (var line in entry.lines) {
     if (showLabel) {
diff --git a/utils/pub/oauth2.dart b/utils/pub/oauth2.dart
index cc80d86..55245f3 100644
--- a/utils/pub/oauth2.dart
+++ b/utils/pub/oauth2.dart
@@ -15,6 +15,7 @@
 import 'http.dart';
 import 'io.dart';
 import 'log.dart' as log;
+import 'safe_http_server.dart';
 import 'system_cache.dart';
 import 'utils.dart';
 
@@ -35,14 +36,23 @@
 /// a refresh token from the server. See the [Google OAuth2 documentation][].
 ///
 /// [Google OAuth2 documentation]: https://developers.google.com/accounts/docs/OAuth2WebServer#offline
-final _authorizationEndpoint = Uri.parse(
+final authorizationEndpoint = Uri.parse(
     'https://accounts.google.com/o/oauth2/auth?access_type=offline'
     '&approval_prompt=force');
 
 /// The URL from which the pub client will request an access token once it's
-/// been authorized by the user.
-final _tokenEndpoint = Uri.parse(
-    'https://accounts.google.com/o/oauth2/token');
+/// been authorized by the user. This can be controlled externally by setting
+/// the _PUB_TEST_TOKEN_ENDPOINT environment variable.
+Uri get tokenEndpoint {
+  var tokenEndpoint = Platform.environment['_PUB_TEST_TOKEN_ENDPOINT'];
+  if (tokenEndpoint != null) {
+    return Uri.parse(tokenEndpoint);
+  } else {
+    return _tokenEndpoint;
+  }
+}
+
+final _tokenEndpoint = Uri.parse('https://accounts.google.com/o/oauth2/token');
 
 /// The OAuth2 scopes that the pub client needs. Currently the client only needs
 /// the user's email so that the server can verify their identity.
@@ -152,25 +162,17 @@
 /// Gets the user to authorize pub as a client of pub.dartlang.org via oauth2.
 /// Returns a Future that will complete to a fully-authorized [Client].
 Future<Client> _authorize() {
-  // Allow the tests to inject their own token endpoint URL.
-  var tokenEndpoint = Platform.environment['_PUB_TEST_TOKEN_ENDPOINT'];
-  if (tokenEndpoint != null) {
-    tokenEndpoint = Uri.parse(tokenEndpoint);
-  } else {
-    tokenEndpoint = _tokenEndpoint;
-  }
-
   var grant = new AuthorizationCodeGrant(
       _identifier,
       _secret,
-      _authorizationEndpoint,
+      authorizationEndpoint,
       tokenEndpoint,
       httpClient: httpClient);
 
   // Spin up a one-shot HTTP server to receive the authorization code from the
   // Google OAuth2 server via redirect. This server will close itself as soon as
   // the code is received.
-  return HttpServer.bind('127.0.0.1', 0).then((server) {
+  return SafeHttpServer.bind('127.0.0.1', 0).then((server) {
     var authUrl = grant.getAuthorizationUrl(
         Uri.parse('http://localhost:${server.port}'), scopes: _scopes);
 
diff --git a/utils/pub/pub.dart b/utils/pub/pub.dart
index f18d9c9..1c05c45 100644
--- a/utils/pub/pub.dart
+++ b/utils/pub/pub.dart
@@ -18,6 +18,7 @@
 import 'command_update.dart';
 import 'command_uploader.dart';
 import 'command_version.dart';
+import 'command_cache.dart';
 import 'entrypoint.dart';
 import 'exit_codes.dart' as exit_codes;
 import 'http.dart';
@@ -35,13 +36,14 @@
 /// The commands that Pub understands.
 Map<String, PubCommand> get pubCommands {
   var commands = {
+    'cache': new CacheCommand(),
     'help': new HelpCommand(),
     'install': new InstallCommand(),
     'publish': new LishCommand(),
     'update': new UpdateCommand(),
     'uploader': new UploaderCommand(),
     'version': new VersionCommand()
-  };
+   };
   for (var command in commands.values.toList()) {
     for (var alias in command.aliases) {
       commands[alias] = command;
@@ -135,8 +137,7 @@
       return;
     }
 
-    var commandArgs =
-        globalOptions.rest.getRange(1, globalOptions.rest.length - 1);
+    var commandArgs = globalOptions.rest.sublist(1);
     command.run(cache, globalOptions, commandArgs);
   });
 }
@@ -160,14 +161,14 @@
 void printUsage([String description = 'Pub is a package manager for Dart.']) {
   // Build up a buffer so it shows up as a single log entry.
   var buffer = new StringBuffer();
-  buffer.add(description);
-  buffer.add('\n\n');
-  buffer.add('Usage: pub command [arguments]\n\n');
-  buffer.add('Global options:\n');
-  buffer.add('${pubArgParser.getUsage()}\n\n');
+  buffer.write(description);
+  buffer.write('\n\n');
+  buffer.write('Usage: pub command [arguments]\n\n');
+  buffer.write('Global options:\n');
+  buffer.write('${pubArgParser.getUsage()}\n\n');
 
   // Show the commands sorted.
-  buffer.add('Available commands:\n');
+  buffer.write('Available commands:\n');
 
   // TODO(rnystrom): A sorted map would be nice.
   int length = 0;
@@ -182,12 +183,13 @@
   names.sort((a, b) => a.compareTo(b));
 
   for (var name in names) {
-    buffer.add('  ${padRight(name, length)}   '
+    buffer.write('  ${padRight(name, length)}   '
         '${pubCommands[name].description}\n');
   }
 
-  buffer.add('\n');
-  buffer.add('Use "pub help [command]" for more information about a command.');
+  buffer.write('\n');
+  buffer.write(
+      'Use "pub help [command]" for more information about a command.');
   log.message(buffer.toString());
 }
 
@@ -301,12 +303,12 @@
     if (description == null) description = this.description;
 
     var buffer = new StringBuffer();
-    buffer.add('$description\n\nUsage: $usage');
+    buffer.write('$description\n\nUsage: $usage');
 
     var commandUsage = commandParser.getUsage();
     if (!commandUsage.isEmpty) {
-      buffer.add('\n');
-      buffer.add(commandUsage);
+      buffer.write('\n');
+      buffer.write(commandUsage);
     }
 
     log.message(buffer.toString());
diff --git a/utils/pub/pubspec.dart b/utils/pub/pubspec.dart
index 81678af..f2d34a2 100644
--- a/utils/pub/pubspec.dart
+++ b/utils/pub/pubspec.dart
@@ -25,6 +25,9 @@
   /// The packages this package depends on.
   final List<PackageRef> dependencies;
 
+  /// The packages this package depends on when it is the root package.
+  final List<PackageRef> devDependencies;
+
   /// The environment-related metadata.
   final PubspecEnvironment environment;
 
@@ -55,14 +58,15 @@
     }
   }
 
-  Pubspec(this.name, this.version, this.dependencies, this.environment,
-      [Map<String, Object> fields])
+  Pubspec(this.name, this.version, this.dependencies, this.devDependencies,
+          this.environment, [Map<String, Object> fields])
     : this.fields = fields == null ? {} : fields;
 
   Pubspec.empty()
     : name = null,
       version = Version.none,
       dependencies = <PackageRef>[],
+      devDependencies = <PackageRef>[],
       environment = new PubspecEnvironment(),
       fields = {};
 
@@ -105,6 +109,42 @@
     var dependencies = _parseDependencies(filePath, sources,
         parsedPubspec['dependencies']);
 
+    var devDependencies = _parseDependencies(filePath, sources,
+        parsedPubspec['dev_dependencies']);
+
+    // Make sure the same package doesn't appear as both a regular and dev
+    // dependency.
+    var dependencyNames = dependencies.map((dep) => dep.name).toSet();
+    var collisions = dependencyNames.intersection(
+        devDependencies.map((dep) => dep.name).toSet());
+
+    if (!collisions.isEmpty) {
+      var packageNames;
+      if (collisions.length == 1) {
+        packageNames = 'Package "${collisions.first}"';
+      } else {
+        var names = collisions.toList();
+        names.sort();
+        var buffer = new StringBuffer();
+        buffer.write("Packages ");
+        for (var i = 0; i < names.length; i++) {
+          buffer.write('"');
+          buffer.write(names[i]);
+          buffer.write('"');
+          if (i == names.length - 2) {
+            buffer.write(", ");
+          } else if (i == names.length - 1) {
+            buffer.write(", and ");
+          }
+        }
+
+        packageNames = buffer.toString();
+      }
+      throw new FormatException(
+          '$packageNames cannot appear in both "dependencies" and '
+          '"dev_dependencies".');
+    }
+
     var environmentYaml = parsedPubspec['environment'];
     var sdkConstraint = VersionConstraint.any;
     if (environmentYaml != null) {
@@ -169,7 +209,8 @@
       }
     }
 
-    return new Pubspec(name, version, dependencies, environment, parsedPubspec);
+    return new Pubspec(name, version, dependencies, devDependencies,
+        environment, parsedPubspec);
   }
 }
 
diff --git a/utils/pub/safe_http_server.dart b/utils/pub/safe_http_server.dart
new file mode 100644
index 0000000..64adf5b
--- /dev/null
+++ b/utils/pub/safe_http_server.dart
@@ -0,0 +1,144 @@
+// 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 safe_http_server;
+
+import 'dart:async';
+import 'dart:io';
+import 'dart:uri';
+
+// TODO(nweiz): remove this when issue 9140 is fixed.
+/// A wrapper around [HttpServer] that swallows errors caused by requests
+/// behaving badly. This provides the following guarantees:
+///
+/// * The [SafeHttpServer.listen] onError callback will only emit server-wide
+///   errors. It will not emit errors for requests that were unparseable or
+///   where the connection was closed too soon.
+/// * [HttpResponse.done] will emit no errors.
+///
+/// The [HttpRequest] data stream can still emit errors.
+class SafeHttpServer extends StreamView<HttpRequest> implements HttpServer {
+  final HttpServer _inner;
+
+  static Future<SafeHttpServer> bind([String host = "127.0.0.1",
+      int port = 0, int backlog = 0]) {
+    return HttpServer.bind(host, port, backlog)
+        .then((server) => new SafeHttpServer(server));
+  }
+
+  SafeHttpServer(HttpServer server)
+      : super(server),
+        _inner = server;
+
+  void close() => _inner.close();
+
+  int get port => _inner.port;
+
+  set sessionTimeout(int timeout) {
+    _inner.sessionTimeout = timeout;
+  }
+
+  HttpConnectionsInfo connectionsInfo() => _inner.connectionsInfo();
+
+  StreamSubscription<HttpRequest> listen(void onData(HttpRequest value),
+      {void onError(AsyncError error), void onDone(),
+      bool unsubscribeOnError: false}) {
+    var subscription;
+    subscription = super.listen((request) {
+      onData(new _HttpRequestWrapper(request));
+    }, onError: (e) {
+      var error = e.error;
+      // Ignore socket error 104, which is caused by a request being cancelled
+      // before it writes any headers. There's no reason to care about such
+      // requests.
+      if (error is SocketIOException && error.osError.errorCode == 104) return;
+      // Ignore any parsing errors, which come from malformed requests.
+      if (error is HttpParserException) return;
+      // Manually handle unsubscribeOnError so the above (ignored) errors don't
+      // cause unsubscription.
+      if (unsubscribeOnError) subscription.cancel();
+      if (onError != null) onError(e);
+    }, onDone: onDone);
+    return subscription;
+  }
+}
+
+/// A wrapper around [HttpRequest] for the sole purpose of swallowing errors on
+/// [HttpResponse.done].
+class _HttpRequestWrapper extends StreamView<List<int>> implements HttpRequest {
+  final HttpRequest _inner;
+  final HttpResponse response;
+
+  _HttpRequestWrapper(HttpRequest inner)
+      : super(inner),
+        _inner = inner,
+        response = new _HttpResponseWrapper(inner.response);
+
+  int get contentLength => _inner.contentLength;
+  String get method => _inner.method;
+  Uri get uri => _inner.uri;
+  Map<String, String> get queryParameters => _inner.queryParameters;
+  HttpHeaders get headers => _inner.headers;
+  List<Cookie> get cookies => _inner.cookies;
+  bool get persistentConnection => _inner.persistentConnection;
+  X509Certificate get certificate => _inner.certificate;
+  HttpSession get session => _inner.session;
+  String get protocolVersion => _inner.protocolVersion;
+  HttpConnectionInfo get connectionInfo => _inner.connectionInfo;
+}
+
+/// A wrapper around [HttpResponse] for the sole purpose of swallowing errors on
+/// [done].
+class _HttpResponseWrapper implements HttpResponse {
+  final HttpResponse _inner;
+  Future<HttpResponse> _done;
+
+  _HttpResponseWrapper(this._inner);
+
+  /// Swallows all errors from writing to the response.
+  Future<HttpResponse> get done {
+    if (_done == null) _done = _inner.done.catchError((_) {});
+    return _done;
+  }
+
+  int get contentLength => _inner.contentLength;
+  set contentLength(int value) {
+    _inner.contentLength = value;
+  }
+
+  int get statusCode => _inner.statusCode;
+  set statusCode(int value) {
+    _inner.statusCode = value;
+  }
+
+  String get reasonPhrase => _inner.reasonPhrase;
+  set reasonPhrase(String value) {
+    _inner.reasonPhrase = value;
+  }
+
+  bool get persistentConnection => _inner.persistentConnection;
+  set persistentConnection(bool value) {
+    _inner.persistentConnection = value;
+  }
+
+  Encoding get encoding => _inner.encoding;
+  set encoding(Encoding value) {
+    _inner.encoding = value;
+  }
+
+  HttpHeaders get headers => _inner.headers;
+  List<Cookie> get cookies => _inner.cookies;
+  Future<Socket> detachSocket() => _inner.detachSocket();
+  HttpConnectionInfo get connectionInfo => _inner.connectionInfo;
+  void writeBytes(List<int> data) => _inner.writeBytes(data);
+  Future<HttpResponse> consume(Stream<List<int>> stream) =>
+    _inner.consume(stream);
+  Future<HttpResponse> writeStream(Stream<List<int>> stream) =>
+    _inner.writeStream(stream);
+  void close() => _inner.close();
+  void write(Object obj) => _inner.write(obj);
+  void writeAll(Iterable objects) => _inner.writeAll(objects);
+  void writeCharCode(int charCode) => _inner.writeCharCode(charCode);
+  void writeln([Object obj = ""]) => _inner.writeln(obj);
+}
diff --git a/utils/pub/sdk_source.dart b/utils/pub/sdk_source.dart
deleted file mode 100644
index 1d6a881..0000000
--- a/utils/pub/sdk_source.dart
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library sdk_source;
-
-import 'dart:async';
-
-import '../../pkg/pathos/lib/path.dart' as path;
-
-import 'io.dart';
-import 'package.dart';
-import 'pubspec.dart';
-import 'sdk.dart' as sdk;
-import 'source.dart';
-import 'utils.dart';
-import 'version.dart';
-
-/// A package source that uses libraries from the Dart SDK.
-class SdkSource extends Source {
-  final String name = "sdk";
-  final bool shouldCache = false;
-
-  /// SDK packages are not individually versioned. Instead, their version is
-  /// inferred from the revision number of the SDK itself.
-  Future<Pubspec> describe(PackageId id) {
-    return defer(() {
-      var packageDir = _getPackagePath(id);
-      // TODO(rnystrom): What if packageDir is null?
-      var pubspec = new Pubspec.load(id.name, packageDir, systemCache.sources);
-      // Ignore the pubspec's version, and use the SDK's.
-      return new Pubspec(id.name, sdk.version, pubspec.dependencies,
-          pubspec.environment);
-    });
-  }
-
-  /// Since all the SDK files are already available locally, installation just
-  /// involves symlinking the SDK library into the packages directory.
-  Future<bool> install(PackageId id, String destPath) {
-    return defer(() {
-      var path = _getPackagePath(id);
-      if (path == null) return false;
-
-      return createPackageSymlink(id.name, path, destPath).then((_) => true);
-    });
-  }
-
-  /// Gets the path in the SDK's "pkg" directory to the directory containing
-  /// package [id]. Returns `null` if the package could not be found.
-  String _getPackagePath(PackageId id) {
-    var pkgPath = path.join(sdk.rootDirectory, "pkg", id.description);
-    return dirExists(pkgPath) ? pkgPath : null;
-  }
-}
diff --git a/utils/pub/source.dart b/utils/pub/source.dart
index 0e3af3e..53c56b3 100644
--- a/utils/pub/source.dart
+++ b/utils/pub/source.dart
@@ -215,6 +215,11 @@
   ///
   /// By default, this just returns [id].
   Future<PackageId> resolveId(PackageId id) => new Future.immediate(id);
+  
+  /// Returns the [Package]s that have been installed in the system cache.
+  Future<List<Package>> getCachedPackages() {
+    if (shouldCache) throw "Source $name must implement this.";
+  }
 
   /// Returns the source's name.
   String toString() => name;
diff --git a/utils/pub/system_cache.dart b/utils/pub/system_cache.dart
index 7670b76..e93f8f4 100644
--- a/utils/pub/system_cache.dart
+++ b/utils/pub/system_cache.dart
@@ -17,7 +17,6 @@
 import 'package.dart';
 import 'path_source.dart';
 import 'pubspec.dart';
-import 'sdk_source.dart';
 import 'source.dart';
 import 'source_registry.dart';
 import 'utils.dart';
@@ -26,7 +25,7 @@
 /// The system-wide cache of installed packages.
 ///
 /// This cache contains all packages that are downloaded from the internet.
-/// Packages that are available locally (e.g. from the SDK) don't use this
+/// Packages that are available locally (e.g. path dependencies) don't use this
 /// cache.
 class SystemCache {
   /// The root directory where this package cache is located.
@@ -52,7 +51,6 @@
     cache.register(new GitSource());
     cache.register(new HostedSource());
     cache.register(new PathSource());
-    cache.register(new SdkSource());
     cache.sources.setDefault('hosted');
     return cache;
   }
diff --git a/utils/pub/utils.dart b/utils/pub/utils.dart
index 098916e..1d687f3 100644
--- a/utils/pub/utils.dart
+++ b/utils/pub/utils.dart
@@ -173,24 +173,15 @@
 /// Returns a [Future] that will complete to the first element of [stream].
 /// Unlike [Stream.first], this is safe to use with single-subscription streams.
 Future streamFirst(Stream stream) {
-  // TODO(nweiz): remove this when issue 8512 is fixed.
-  var cancelled = false;
   var completer = new Completer();
   var subscription;
   subscription = stream.listen((value) {
-    if (!cancelled) {
-      cancelled = true;
-      subscription.cancel();
-      completer.complete(value);
-    }
+    subscription.cancel();
+    completer.complete(value);
   }, onError: (e) {
-    if (!cancelled) {
-      completer.completeError(e.error, e.stackTrace);
-    }
+    completer.completeError(e.error, e.stackTrace);
   }, onDone: () {
-    if (!cancelled) {
-      completer.completeError(new StateError("No elements"));
-    }
+    completer.completeError(new StateError("No elements"));
   }, unsubscribeOnError: true);
   return completer.future;
 }
@@ -202,7 +193,7 @@
       new StreamController.broadcast() :
       new StreamController();
   var subscription = stream.listen(controller.add,
-      onError: controller.signalError,
+      onError: controller.addError,
       onDone: controller.close);
   return new Pair<Stream, StreamSubscription>(controller.stream, subscription);
 }
@@ -218,8 +209,8 @@
     controller1.add(value);
     controller2.add(value);
   }, onError: (error) {
-    controller1.signalError(error);
-    controller2.signalError(error);
+    controller1.addError(error);
+    controller2.addError(error);
   }, onDone: () {
     controller1.close();
     controller2.close();
@@ -319,6 +310,24 @@
   }).join("&");
 }
 
+// TODO(nweiz): remove this when issue 9068 has been fixed.
+/// Whether [uri1] and [uri2] are equal. This consider HTTP URIs to default to
+/// port 80, and HTTPs URIs to default to port 443.
+bool urisEqual(Uri uri1, Uri uri2) =>
+  canonicalizeUri(uri1) == canonicalizeUri(uri2);
+
+/// Return [uri] with redundant port information removed.
+Uri canonicalizeUri(Uri uri) {
+  if (uri == null) return null;
+
+  var sansPort = new Uri.fromComponents(
+      scheme: uri.scheme, userInfo: uri.userInfo, domain: uri.domain,
+      path: uri.path, query: uri.query, fragment: uri.fragment);
+  if (uri.scheme == 'http' && uri.port == 80) return sansPort;
+  if (uri.scheme == 'https' && uri.port == 443) return sansPort;
+  return uri;
+}
+
 /// Add all key/value pairs from [source] to [destination], overwriting any
 /// pre-existing values.
 void mapAddAll(Map destination, Map source) =>
diff --git a/utils/pub/validator/dependency.dart b/utils/pub/validator/dependency.dart
index de02738..d66059d 100644
--- a/utils/pub/validator/dependency.dart
+++ b/utils/pub/validator/dependency.dart
@@ -34,13 +34,7 @@
         return new Future.immediate(null);
       }
 
-      if (dependency.constraint.isAny &&
-          // TODO(nweiz): once we have development dependencies (issue 5358), we
-          // should warn about unittest. Until then, it's reasonable not to put
-          // a constraint on it.
-          dependency.name != 'unittest') {
-        _warnAboutConstraint(dependency);
-      }
+      if (dependency.constraint.isAny) _warnAboutConstraint(dependency);
 
       return new Future.immediate(null);
     });
diff --git a/utils/pub/version_solver.dart b/utils/pub/version_solver.dart
index 45d47e8..c00cda5 100644
--- a/utils/pub/version_solver.dart
+++ b/utils/pub/version_solver.dart
@@ -283,8 +283,8 @@
       Version version) {
     // If there is no version, it means no package, so no dependencies.
     if (version == null) {
-      return
-          new Future<Map<String, PackageRef>>.immediate(<String, PackageRef>{});
+      return new Future<Map<String, PackageRef>>.immediate(
+          <String, PackageRef>{});
     }
 
     var id = new PackageId(package, source, version, description);
@@ -293,6 +293,14 @@
       for (var dependency in pubspec.dependencies) {
         dependencies[dependency.name] = dependency;
       }
+
+      // Include dev dependencies only from the root package.
+      if (id.isRoot) {
+        for (var dependency in pubspec.devDependencies) {
+          dependencies[dependency.name] = dependency;
+        }
+      }
+
       return dependencies;
     });
   }
diff --git a/utils/template/codegen.dart b/utils/template/codegen.dart
index 5d8ed2f..d2b07ab 100644
--- a/utils/template/codegen.dart
+++ b/utils/template/codegen.dart
@@ -78,7 +78,7 @@
   String get globalDeclarations {
     StringBuffer buff = new StringBuffer();
     for (final CGStatement stmt in _stmts) {
-      buff.add(stmt.globalDeclaration());
+      buff.write(stmt.globalDeclaration());
     }
 
     return buff.toString();
@@ -98,7 +98,7 @@
   String get globalInitializers {
     StringBuffer buff = new StringBuffer();
     for (final CGStatement stmt in _stmts) {
-      buff.add(stmt.globalInitializers());
+      buff.write(stmt.globalInitializers());
     }
 
     return buff.toString();
@@ -108,7 +108,7 @@
     StringBuffer buff = new StringBuffer();
 
     for (final CGStatement stmt in _stmts) {
-      buff.add(stmt.emitDartStatement());
+      buff.write(stmt.emitDartStatement());
     }
 
     return buff.toString();
@@ -163,7 +163,7 @@
   }
 
   void add(String value) {
-    _buff.add(value);
+    _buff.write(value);
   }
 
   bool get isClosed => _closed;
@@ -270,15 +270,15 @@
     StringBuffer buff = new StringBuffer();
     int injectId = 0;         // Inject function id
 
-    buff.add("// Generated Dart class from HTML template.\n");
-    buff.add("// DO NOT EDIT.\n\n");
+    buff.write("// Generated Dart class from HTML template.\n");
+    buff.write("// DO NOT EDIT.\n\n");
 
     String addStylesheetFuncName = "add_${filename}_templatesStyles";
 
     for (final template in templates) {
       // Emit the template class.
       TemplateSignature sig = template.signature;
-      buff.add(_emitClass(sig.name, sig.params, template.content,
+      buff.write(_emitClass(sig.name, sig.params, template.content,
         addStylesheetFuncName));
     }
 
@@ -286,25 +286,25 @@
     //              bound to this template file not global to the app.
 
     // Emit the stylesheet aggregator.
-    buff.add("\n\n// Inject all templates stylesheet once into the head.\n");
-    buff.add("bool ${filename}_stylesheet_added = false;\n");
-    buff.add("void ${addStylesheetFuncName}() {\n");
-    buff.add("  if (!${filename}_stylesheet_added) {\n");
-    buff.add("    StringBuffer styles = new StringBuffer();\n\n");
+    buff.write("\n\n// Inject all templates stylesheet once into the head.\n");
+    buff.write("bool ${filename}_stylesheet_added = false;\n");
+    buff.write("void ${addStylesheetFuncName}() {\n");
+    buff.write("  if (!${filename}_stylesheet_added) {\n");
+    buff.write("    StringBuffer styles = new StringBuffer();\n\n");
 
-    buff.add("    // All templates stylesheet.\n");
+    buff.write("    // All templates stylesheet.\n");
 
     for (final template in templates) {
       TemplateSignature sig = template.signature;
-      buff.add("    styles.add(${sig.name}.stylesheet);\n");
+      buff.write("    styles.add(${sig.name}.stylesheet);\n");
     }
 
-    buff.add("\n    ${filename}_stylesheet_added = true;\n");
+    buff.write("\n    ${filename}_stylesheet_added = true;\n");
 
-    buff.add("    document.head.elements.add(new Element.html('<style>"
+    buff.write("    document.head.elements.add(new Element.html('<style>"
              "\${styles.toString()}</style>'));\n");
-    buff.add("  }\n");
-    buff.add("}\n");
+    buff.write("  }\n");
+    buff.write("}\n");
 
     return buff.toString();
   }
@@ -347,9 +347,9 @@
     StringBuffer buff = new StringBuffer();
     if (classes.length > 0) {
       assert(classes.length == dartNames.length);
-      buff.add("\n  // CSS class selectors for this template.\n");
+      buff.write("\n  // CSS class selectors for this template.\n");
       for (int i = 0; i < classes.length; i++) {
-        buff.add(
+        buff.write(
           "  static String get ${dartNames[i]} => \"${classes[i]}\";\n");
       }
     }
@@ -364,17 +364,17 @@
     StringBuffer buff = new StringBuffer();
 
     // Emit the template class.
-    buff.add("class ${className} {\n");
+    buff.write("class ${className} {\n");
 
-    buff.add("  Map<String, Object> _scopes;\n");
-    buff.add("  Element _fragment;\n\n");
+    buff.write("  Map<String, Object> _scopes;\n");
+    buff.write("  Element _fragment;\n\n");
 
     bool anyParams = false;
     for (final param in params) {
-      buff.add("  ${param['type']} ${param['name']};\n");
+      buff.write("  ${param['type']} ${param['name']};\n");
       anyParams = true;
     }
-    if (anyParams) buff.add("\n");
+    if (anyParams) buff.write("\n");
 
     ElemCG ecg = new ElemCG();
 
@@ -403,79 +403,79 @@
     // Create all element names marked with var.
     String decls = ecg.globalDeclarations;
     if (decls.length > 0) {
-      buff.add("\n  // Elements bound to a variable:\n");
-      buff.add("${decls}\n");
+      buff.write("\n  // Elements bound to a variable:\n");
+      buff.write("${decls}\n");
     }
 
     // Create the constructor.
-    buff.add("  ${className}(");
+    buff.write("  ${className}(");
     bool firstParam = true;
     for (final param in params) {
       if (!firstParam) {
-        buff.add(", ");
+        buff.write(", ");
       }
-      buff.add("this.${param['name']}");
+      buff.write("this.${param['name']}");
       firstParam = false;
     }
-    buff.add(") : _scopes = new Map<String, Object>() {\n");
+    buff.write(") : _scopes = new Map<String, Object>() {\n");
 
     String initializers = ecg.globalInitializers;
     if (initializers.length > 0) {
-      buff.add("    //Global initializers.\n");
-      buff.add("${initializers}\n");
+      buff.write("    //Global initializers.\n");
+      buff.write("${initializers}\n");
     }
 
-    buff.add("    // Insure stylesheet for template exist in the document.\n");
-    buff.add("    ${addStylesheetFuncName}();\n\n");
+    buff.write("    // Insure stylesheet for template exist in the document.\n");
+    buff.write("    ${addStylesheetFuncName}();\n\n");
 
-    buff.add("    _fragment = new DocumentFragment();\n");
+    buff.write("    _fragment = new DocumentFragment();\n");
 
-    buff.add(ecg.codeBody);     // HTML for constructor to build.
+    buff.write(ecg.codeBody);     // HTML for constructor to build.
 
-    buff.add("  }\n\n");        // End constructor
+    buff.write("  }\n\n");        // End constructor
 
-    buff.add(emitGetters(content.getters));
+    buff.write(emitGetters(content.getters));
 
-    buff.add("  Element get root => _fragment;\n");
+    buff.write("  Element get root => _fragment;\n");
 
     // Emit all CSS class selectors:
-    buff.add(_emitCSSSelectors(content.css));
+    buff.write(_emitCSSSelectors(content.css));
 
     // Emit the injection functions.
-    buff.add("\n  // Injection functions:");
+    buff.write("\n  // Injection functions:");
     for (final expr in ecg.expressions) {
-      buff.add("${expr}");
+      buff.write("${expr}");
     }
 
-    buff.add("\n  // Each functions:\n");
+    buff.write("\n  // Each functions:\n");
     for (var eachFunc in ecg.eachs) {
-      buff.add("${eachFunc}\n");
+      buff.write("${eachFunc}\n");
     }
 
-    buff.add("\n  // With functions:\n");
+    buff.write("\n  // With functions:\n");
     for (var withFunc in ecg.withs) {
-      buff.add("${withFunc}\n");
+      buff.write("${withFunc}\n");
     }
 
-    buff.add("\n  // CSS for this template.\n");
-    buff.add("  static const String stylesheet = ");
+    buff.write("\n  // CSS for this template.\n");
+    buff.write("  static const String stylesheet = ");
 
     if (content.css != null) {
-      buff.add("\'\'\'\n    ${content.css.toString()}\n");
-      buff.add("  \'\'\';\n\n");
+      buff.write("\'\'\'\n    ${content.css.toString()}\n");
+      buff.write("  \'\'\';\n\n");
 
       // TODO(terry): Emit all known selectors for this template.
-      buff.add("  // Stylesheet class selectors:\n");
+      buff.write("  // Stylesheet class selectors:\n");
     } else {
-      buff.add("\"\";\n");
+      buff.write("\"\";\n");
     }
 
-    buff.add("  String safeHTML(String html) {\n");
-    buff.add("    // TODO(terry): Escaping for XSS vulnerabilities TBD.\n");
-    buff.add("    return html;\n");
-    buff.add("  }\n");
+    buff.write("  String safeHTML(String html) {\n");
+    buff.write("    // TODO(terry): Escaping for XSS vulnerabilities TBD.\n");
+    buff.write("    return html;\n");
+    buff.write("  }\n");
 
-    buff.add("}\n");              // End class
+    buff.write("}\n");              // End class
 
     return buff.toString();
   }
@@ -485,14 +485,14 @@
   static String emitGetters(List<TemplateGetter> getters) {
     StringBuffer buff = new StringBuffer();
     for (final TemplateGetter getter in getters) {
-      buff.add('  String ${getter.getterSignatureAsString()} {\n');
-      buff.add('    return \'\'\'');
+      buff.write('  String ${getter.getterSignatureAsString()} {\n');
+      buff.write('    return \'\'\'');
       var docFrag = getter.docFrag.children[0];
       for (final child in docFrag.children) {
-        buff.add(child.toString().trim());
+        buff.write(child.toString().trim());
       }
-      buff.add('\'\'\';\n');
-      buff.add('  }\n\n');
+      buff.write('\'\'\';\n');
+      buff.write('  }\n\n');
     }
 
     return buff.toString();
@@ -982,7 +982,7 @@
     if (item == null) {
       item = "_item";
     }
-    buff.add("${spaces}_scopes[\"${item}\"] = ${item};\n");
+    buff.write("${spaces}_scopes[\"${item}\"] = ${item};\n");
   }
 
   removeScope(int indent, StringBuffer buff, String item) {
@@ -991,7 +991,7 @@
     if (item == null) {
       item = "_item";
     }
-    buff.add("${spaces}_scopes.remove(\"${item}\");\n");
+    buff.write("${spaces}_scopes.remove(\"${item}\");\n");
   }
 
   String defineScopes() {
@@ -1000,11 +1000,11 @@
     // Construct the active scope names for name resolution.
     List<String> names = activeBlocksLocalNames();
     if (names.length > 0) {
-      buff.add("    // Local scoped block names.\n");
+      buff.write("    // Local scoped block names.\n");
       for (String name in names) {
-        buff.add("    var ${name} = _scopes[\"${name}\"];\n");
+        buff.write("    var ${name} = _scopes[\"${name}\"];\n");
       }
-      buff.add("\n");
+      buff.write("\n");
     }
 
     return buff.toString();
diff --git a/utils/template/htmltree.dart b/utils/template/htmltree.dart
index 16db0a9..85453fe 100644
--- a/utils/template/htmltree.dart
+++ b/utils/template/htmltree.dart
@@ -63,13 +63,13 @@
     bool first = true;
     for (final param in params) {
       if (!first) {
-        buff.add(", ");
+        buff.write(", ");
       }
       if (param['type'] != null) {
-        buff.add(param['type']);
-        buff.add(' ');
+        buff.write(param['type']);
+        buff.write(' ');
       }
-      buff.add(param['name']);
+      buff.write(param['name']);
       first = false;
     }
 
@@ -102,7 +102,7 @@
     StringBuffer buff = new StringBuffer();
     if (children != null) {
       for (final child in children) {
-        buff.add(child.toString());
+        buff.write(child.toString());
       }
     }
 
@@ -125,13 +125,13 @@
     bool first = true;
     for (final param in params) {
       if (!first) {
-        buff.add(", ");
+        buff.write(", ");
       }
       if (param['type'] != null && param['type'].length > 0) {
-        buff.add(param['type']);
-        buff.add(' ');
+        buff.write(param['type']);
+        buff.write(' ');
       }
-      buff.add(param['name']);
+      buff.write(param['name']);
       first = false;
     }
 
@@ -182,7 +182,7 @@
 
     if (attributes != null) {
       for (final attr in attributes) {
-        buff.add(' ${attr.toString()}');
+        buff.write(' ${attr.toString()}');
       }
     }
 
@@ -203,10 +203,10 @@
 
     if (children != null) {
       for (final child in children) {
-        buff.add(child.toString());
+        buff.write(child.toString());
       }
 
-      buff.add(tagEndToString());
+      buff.write(tagEndToString());
     }
 
     return buff.toString();
@@ -361,10 +361,10 @@
   void visitTemplateDocument(TemplateDocument node) {
     output.heading('Content', node.span);
     output.depth++;
-    // TODO(terry): Ugly use of 'as Dynamic' instead of children[0] to
+    // TODO(terry): Ugly use of 'as dynamic' instead of children[0] to
     //              surpress warning.
     assert(node.children.length == 1 &&
-        (node.children as Dynamic)[0].tagTokenId == -1);
+        (node.children as dynamic)[0].tagTokenId == -1);
     output.writeNodeList("document", node.children);
     output.depth--;
   }
diff --git a/utils/template/parser.dart b/utils/template/parser.dart
index e0f426c..9f23d8a 100644
--- a/utils/template/parser.dart
+++ b/utils/template/parser.dart
@@ -672,7 +672,7 @@
         _next(false);
       } else if (_peek() != TokenKind.RBRACE) {
         // Yes, grab the chars after the >
-        stringValue.add(_previousToken.source.text.substring(
+        stringValue.write(_previousToken.source.text.substring(
             this._previousToken.end, this._peekToken.start));
       }
     }
@@ -706,7 +706,7 @@
         start = _peekToken.start;
       } else if (tok.kind != TokenKind.START_EXPRESSION) {
         // Only save the the contents between ${ and }
-        stringValue.add(tok.text);
+        stringValue.write(tok.text);
       }
     }
 
diff --git a/utils/template/source.dart b/utils/template/source.dart
index a5e981b..5eeb0e2 100644
--- a/utils/template/source.dart
+++ b/utils/template/source.dart
@@ -80,7 +80,7 @@
     var buf = new StringBuffer(
         '${filename}:${line + 1}:${column + 1}: $message');
     if (includeText) {
-      buf.add('\n');
+      buf.write('\n');
       var textLine;
       // +1 for 0-indexing, +1 again to avoid the last line of the file
       if ((line + 2) < _lineStarts.length) {
@@ -91,25 +91,25 @@
 
       int toColumn = Math.min(column + (end-start), textLine.length);
       if (options.useColors) {
-        buf.add(textLine.substring(0, column));
-        buf.add(_RED_COLOR);
-        buf.add(textLine.substring(column, toColumn));
-        buf.add(_NO_COLOR);
-        buf.add(textLine.substring(toColumn));
+        buf.write(textLine.substring(0, column));
+        buf.write(_RED_COLOR);
+        buf.write(textLine.substring(column, toColumn));
+        buf.write(_NO_COLOR);
+        buf.write(textLine.substring(toColumn));
       } else {
-        buf.add(textLine);
+        buf.write(textLine);
       }
 
       int i = 0;
       for (; i < column; i++) {
-        buf.add(' ');
+        buf.write(' ');
       }
 
-      if (options.useColors) buf.add(_RED_COLOR);
+      if (options.useColors) buf.write(_RED_COLOR);
       for (; i < toColumn; i++) {
-        buf.add('^');
+        buf.write('^');
       }
-      if (options.useColors) buf.add(_NO_COLOR);
+      if (options.useColors) buf.write(_NO_COLOR);
     }
 
     return buf.toString();
diff --git a/utils/template/tool.dart b/utils/template/tool.dart
index 97e1ac6..59a8462 100644
--- a/utils/template/tool.dart
+++ b/utils/template/tool.dart
@@ -93,7 +93,7 @@
     if (world.errors == 0) {
       // Generate the Dart class(es) for all template(s).
       codegenElapsed = time(() {
-        code.add(Codegen.generate(templates, outFilename));
+        code.write(Codegen.generate(templates, outFilename));
       });
     }
 
diff --git a/utils/template/tree.dart b/utils/template/tree.dart
index 8e49645..6fd1cf0 100644
--- a/utils/template/tree.dart
+++ b/utils/template/tree.dart
@@ -41,20 +41,18 @@
 
   void write(String s) {
     for (int i=0; i < depth; i++) {
-      buf.add(' ');
+      buf.write(' ');
     }
-    buf.add(s);
+    buf.write(s);
   }
 
   void writeln(String s) {
-    write(s);
-    buf.add('\n');
+    buf.writeln(s);
   }
 
   void heading(String name, span) {
     write(name);
-    buf.add('  (${span.locationText})');
-    buf.add('\n');
+    buf.writeln('  (${span.locationText})');
   }
 
   String toValue(value) {
@@ -79,14 +77,13 @@
   void writeList(String label, List list) {
     write(label + ': ');
     if (list == null) {
-      buf.add('null');
-      buf.add('\n');
+      buf.writeln('null');
     } else {
       for (var item in list) {
-        buf.add(item.toString());
-        buf.add(', ');
+        buf.write(item.toString());
+        buf.write(', ');
       }
-      buf.add('\n');
+      buf.write('\n');
     }
   }
 
diff --git a/utils/template/uitest.dart b/utils/template/uitest.dart
index ead7770..7aed1ff 100644
--- a/utils/template/uitest.dart
+++ b/utils/template/uitest.dart
@@ -385,12 +385,12 @@
     try {
       List<Template> templates = templateParseAndValidate(htmlTemplate);
       for (var tmpl in templates) {
-        dumpTree.add(tmpl.toDebugString());
+        dumpTree.write(tmpl.toDebugString());
       }
 
       // Generate the Dart class(es) for all template(s).
       // Pass in filename of 'foo' for testing in UITest.
-      code.add(Codegen.generate(templates, 'foo'));
+      code.write(Codegen.generate(templates, 'foo'));
     } catch (htmlException) {
       // TODO(terry): TBD
       print("ERROR unhandled EXCEPTION");
diff --git a/utils/testrunner/layout_test_controller.dart b/utils/testrunner/layout_test_controller.dart
index 622e210..b6c8ff7 100644
--- a/utils/testrunner/layout_test_controller.dart
+++ b/utils/testrunner/layout_test_controller.dart
@@ -242,7 +242,7 @@
         if (idx < 0) break;
         StringBuffer sb = new StringBuffer();
         for (var i = pos; i < idx; i++) {
-          sb.addCharCode(stdout[i]);
+          sb.writeCharCode(stdout[i]);
         }
         var line = sb.toString();
 
diff --git a/utils/tests/peg/peg_test.dart b/utils/tests/peg/peg_test.dart
index 59d2d55..692dc15 100644
--- a/utils/tests/peg/peg_test.dart
+++ b/utils/tests/peg/peg_test.dart
@@ -322,14 +322,14 @@
 printList(item) {
   if (item is List) {
     StringBuffer sb = new StringBuffer();
-    sb.add('[');
+    sb.write('[');
     var sep = '';
     for (var x in item) {
-      sb.add(sep);
-      sb.add(printList(x));
+      sb.write(sep);
+      sb.write(printList(x));
       sep = ',';
     }
-    sb.add(']');
+    sb.write(']');
     return sb.toString();
   }
   if (item == null)
diff --git a/utils/tests/pub/dev_dependency_test.dart b/utils/tests/pub/dev_dependency_test.dart
new file mode 100644
index 0000000..961d208
--- /dev/null
+++ b/utils/tests/pub/dev_dependency_test.dart
@@ -0,0 +1,116 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '../../../pkg/pathos/lib/path.dart' as path;
+
+import 'test_pub.dart';
+
+main() {
+  initConfig();
+  integration("includes root package's dev dependencies", () {
+    dir('foo', [
+      libDir('foo'),
+      libPubspec('foo', '0.0.1')
+    ]).scheduleCreate();
+
+    dir('bar', [
+      libDir('bar'),
+      libPubspec('bar', '0.0.1')
+    ]).scheduleCreate();
+
+    dir(appPath, [
+      pubspec({
+        "name": "myapp",
+        "dev_dependencies": {
+          "foo": {"path": "../foo"},
+          "bar": {"path": "../bar"},
+        }
+      })
+    ]).scheduleCreate();
+
+    schedulePub(args: ["install"],
+        output: new RegExp(r"Dependencies installed!$"));
+
+    dir(packagesPath, [
+      dir("foo", [
+        file("foo.dart", 'main() => "foo";')
+      ]),
+      dir("bar", [
+        file("bar.dart", 'main() => "bar";')
+      ])
+    ]).scheduleValidate();
+  });
+
+  integration("includes dev dependency's transitive dependencies", () {
+    dir('foo', [
+      libDir('foo'),
+      libPubspec('foo', '0.0.1', deps: [
+        {"path": "../bar"}
+      ])
+    ]).scheduleCreate();
+
+    dir('bar', [
+      libDir('bar'),
+      libPubspec('bar', '0.0.1')
+    ]).scheduleCreate();
+
+    dir(appPath, [
+      pubspec({
+        "name": "myapp",
+        "dev_dependencies": {
+          "foo": {"path": "../foo"}
+        }
+      })
+    ]).scheduleCreate();
+
+    schedulePub(args: ["install"],
+        output: new RegExp(r"Dependencies installed!$"));
+
+    dir(packagesPath, [
+      dir("foo", [
+        file("foo.dart", 'main() => "foo";')
+      ]),
+      dir("bar", [
+        file("bar.dart", 'main() => "bar";')
+      ])
+    ]).scheduleValidate();
+  });
+
+  integration("ignores transitive dependency's dev dependencies", () {
+    dir('foo', [
+      libDir('foo'),
+      pubspec({
+        "name": "foo",
+        "version": "0.0.1",
+        "dev_dependencies": {
+          "bar": {"path": "../bar"}
+        }
+      })
+    ]).scheduleCreate();
+
+    dir('bar', [
+      libDir('bar'),
+      libPubspec('bar', '0.0.1')
+    ]).scheduleCreate();
+
+    dir(appPath, [
+      pubspec({
+        "name": "myapp",
+        "dependencies": {
+          "foo": {"path": "../foo"}
+        }
+      })
+    ]).scheduleCreate();
+
+    schedulePub(args: ["install"],
+        output: new RegExp(r"Dependencies installed!$"));
+
+    dir(packagesPath, [
+      dir("foo", [
+        file("foo.dart", 'main() => "foo";')
+      ]),
+      nothing("bar")
+    ]).scheduleValidate();
+  });
+}
\ No newline at end of file
diff --git a/utils/tests/pub/error_group_test.dart b/utils/tests/pub/error_group_test.dart
index c2f10fe..b3e0ba0 100644
--- a/utils/tests/pub/error_group_test.dart
+++ b/utils/tests/pub/error_group_test.dart
@@ -218,14 +218,14 @@
         'listener', () {
       expect(stream.first, throwsFormatException);
       // errorGroup shouldn't top-level the exception
-      controller.signalError(new AsyncError(new FormatException()));
+      controller.addError(new AsyncError(new FormatException()));
     });
 
     test('should notify the error group of an exception from the stream even '
         'if it has a listener', () {
       expect(stream.first, throwsFormatException);
       expect(errorGroup.done, throwsFormatException);
-      controller.signalError(new AsyncError(new FormatException()));
+      controller.addError(new AsyncError(new FormatException()));
     });
 
     test('should pass a signaled exception to the stream if it has a listener '
@@ -262,7 +262,7 @@
     test("should pipe an exception from the stream to .done if the stream "
         "doesn't have a listener", () {
       expect(errorGroup.done, throwsFormatException);
-      controller.signalError(new AsyncError(new FormatException()));
+      controller.addError(new AsyncError(new FormatException()));
 
       // A listener added afterwards should see an empty stream, since it's not
       // single-subscription
@@ -310,7 +310,7 @@
     test("should pipe an exception from the stream to .done if the stream "
         "doesn't have a listener", () {
       expect(errorGroup.done, throwsFormatException);
-      controller.signalError(new AsyncError(new FormatException()));
+      controller.addError(new AsyncError(new FormatException()));
 
       // A listener added afterwards should receive the exception
       expect(errorGroup.done.catchError((_) {
@@ -353,7 +353,7 @@
       expect(stream2.first, throwsFormatException);
       expect(errorGroup.done, throwsFormatException);
 
-      controller1.signalError(new AsyncError(new FormatException()));
+      controller1.addError(new AsyncError(new FormatException()));
     });
 
     test("each future should be able to emit values independently", () {
@@ -372,7 +372,7 @@
 
       expect(stream1.toList().then((_) {
         // shouldn't cause a top-level exception
-        controller2.signalError(new AsyncError(new FormatException()));
+        controller2.addError(new AsyncError(new FormatException()));
       }), completes);
     });
 
@@ -407,7 +407,7 @@
       expect(future, throwsFormatException);
       expect(errorGroup.done, throwsFormatException);
 
-      controller.signalError(new AsyncError(new FormatException()));
+      controller.addError(new AsyncError(new FormatException()));
     });
 
     test("should pipe exceptions from the future to the stream", () {
@@ -435,7 +435,7 @@
 
       expect(future.then((_) {
         // shouldn't cause a top-level exception
-        controller.signalError(new AsyncError(new FormatException()));
+        controller.addError(new AsyncError(new FormatException()));
       }), completes);
     });
 
diff --git a/utils/tests/pub/install/broken_symlink_test.dart b/utils/tests/pub/install/broken_symlink_test.dart
new file mode 100644
index 0000000..07a5530
--- /dev/null
+++ b/utils/tests/pub/install/broken_symlink_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import 'dart:io';
+
+import '../../../../pkg/pathos/lib/path.dart' as path;
+import '../../../../pkg/unittest/lib/unittest.dart';
+
+import '../test_pub.dart';
+
+main() {
+  initConfig();
+  integration('replaces a broken "packages" symlink', () {
+    dir(appPath, [
+      appPubspec([]),
+      libDir('foo'),
+      dir("bin")
+    ]).scheduleCreate();
+
+    // Create a broken "packages" symlink in "bin".
+    scheduleSymlink("nonexistent", path.join(appPath, "packages"));
+
+    schedulePub(args: ['install'],
+        output: new RegExp(r"Dependencies installed!$"));
+
+    dir(appPath, [
+      dir("bin", [
+        dir("packages", [
+          dir("myapp", [
+            file('foo.dart', 'main() => "foo";')
+          ])
+        ])
+      ])
+    ]).scheduleValidate();
+  });
+
+  integration('replaces a broken secondary "packages" symlink', () {
+    dir(appPath, [
+      appPubspec([]),
+      libDir('foo'),
+      dir("bin")
+    ]).scheduleCreate();
+
+    // Create a broken "packages" symlink in "bin".
+    scheduleSymlink("nonexistent", path.join(appPath, "bin", "packages"));
+
+    schedulePub(args: ['install'],
+        output: new RegExp(r"Dependencies installed!$"));
+
+    dir(appPath, [
+      dir("bin", [
+        dir("packages", [
+          dir("myapp", [
+            file('foo.dart', 'main() => "foo";')
+          ])
+        ])
+      ])
+    ]).scheduleValidate();
+  });
+}
diff --git a/utils/tests/pub/install/pub_install_test.dart b/utils/tests/pub/install/pub_install_test.dart
index b82565a..f01bc8f 100644
--- a/utils/tests/pub/install/pub_install_test.dart
+++ b/utils/tests/pub/install/pub_install_test.dart
@@ -67,17 +67,13 @@
   });
 
   integration('does not add a package if it does not have a "lib" directory', () {
-    // Using an SDK source, but this should be true of all sources.
-    dir(sdkPath, [
-      dir('pkg', [
-        dir('foo', [
-          libPubspec('foo', '0.0.0-not.used')
-        ])
-      ])
+    // Using a path source, but this should be true of all sources.
+    dir('foo', [
+      libPubspec('foo', '0.0.0-not.used')
     ]).scheduleCreate();
 
     dir(appPath, [
-      pubspec({"name": "myapp", "dependencies": {"foo": {"sdk": "foo"}}})
+      pubspec({"name": "myapp", "dependencies": {"foo": {"path": "../foo"}}})
     ]).scheduleCreate();
 
     schedulePub(args: ['install'],
diff --git a/utils/tests/pub/install/sdk/check_out_test.dart b/utils/tests/pub/install/sdk/check_out_test.dart
deleted file mode 100644
index 8d2521b..0000000
--- a/utils/tests/pub/install/sdk/check_out_test.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library pub_tests;
-
-import 'dart:io';
-
-import '../../test_pub.dart';
-
-main() {
-  integration('checks out a package from the SDK', () {
-    dir(sdkPath, [
-      dir('pkg', [
-        dir('foo', [
-          libDir('foo', 'foo 0.1.2+3'),
-          libPubspec('foo', '0.0.0-not.used')
-        ])
-      ])
-    ]).scheduleCreate();
-
-    dir(appPath, [
-      pubspec({"name": "myapp", "dependencies": {"foo": {"sdk": "foo"}}})
-    ]).scheduleCreate();
-
-    schedulePub(args: ['install'],
-        output: new RegExp(r"Dependencies installed!$"));
-
-    packagesDir({"foo": "0.1.2+3"}).scheduleValidate();
-  });
-}
diff --git a/utils/tests/pub/install/sdk/check_out_transitive_test.dart b/utils/tests/pub/install/sdk/check_out_transitive_test.dart
deleted file mode 100644
index 88454b0..0000000
--- a/utils/tests/pub/install/sdk/check_out_transitive_test.dart
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library pub_tests;
-
-import 'dart:io';
-
-import '../../test_pub.dart';
-
-main() {
-  integration('includes transitive dependencies', () {
-    dir(sdkPath, [
-      dir('pkg', [
-        dir('foo', [
-          libDir('foo', 'foo 0.1.2+3'),
-          libPubspec('foo', '0.0.0-not.used', deps: [{'sdk': 'bar'}])
-        ]),
-        dir('bar', [
-          libDir('bar', 'bar 0.1.2+3'),
-          libPubspec('bar', '0.0.0-not.used')
-        ])
-      ])
-    ]).scheduleCreate();
-
-    dir(appPath, [
-      appPubspec([{'sdk': 'foo'}])
-    ]).scheduleCreate();
-
-    schedulePub(args: ['install'],
-        output: new RegExp(r"Dependencies installed!$"));
-
-    packagesDir({
-      'foo': '0.1.2+3',
-      'bar': '0.1.2+3'
-    }).scheduleValidate();
-  });
-}
diff --git a/utils/tests/pub/oauth2_test.dart b/utils/tests/pub/oauth2_test.dart
index c4d0873..afeedc6 100644
--- a/utils/tests/pub/oauth2_test.dart
+++ b/utils/tests/pub/oauth2_test.dart
@@ -72,7 +72,7 @@
             new RegExp(r'(^|&)refresh_token=refresh\+token(&|$)')));
 
         response.headers.contentType = new ContentType("application", "json");
-        response.addString(json.stringify({
+        response.write(json.stringify({
           "access_token": "new access token",
           "token_type": "bearer"
         }));
@@ -147,6 +147,40 @@
     credentialsFile(server, 'new access token').scheduleValidate();
   });
 
+  // Regression test for issue 8849.
+  integration('with a server-rejected refresh token, authenticates again and '
+      'saves credentials.json', () {
+    var server = new ScheduledServer();
+    credentialsFile(server, 'access token',
+        refreshToken: 'bad refresh token',
+        expiration: new DateTime.now().subtract(new Duration(hours: 1)))
+        .scheduleCreate();
+
+    var pub = startPubLish(server);
+    confirmPublish(pub);
+
+    server.handle('POST', '/token', (request, response) {
+      return new ByteStream(request).toBytes().then((bytes) {
+        response.statusCode = 400;
+        response.reasonPhrase = 'Bad request';
+        response.headers.contentType = new ContentType("application", "json");
+        response.write(json.stringify({"error": "invalid_request"}));
+        response.close();
+      });
+    });
+
+    authorizePub(pub, server, 'new access token');
+
+    server.handle('GET', '/packages/versions/new.json', (request, response) {
+      expect(request.headers.value('authorization'),
+          equals('Bearer new access token'));
+
+      response.close();
+    });
+
+    pub.kill();
+  });
+
   integration('with server-rejected credentials, authenticates again and saves '
       'credentials.json', () {
     var server = new ScheduledServer();
@@ -159,7 +193,7 @@
       response.statusCode = 401;
       response.headers.set('www-authenticate', 'Bearer error="invalid_token",'
           ' error_description="your token sucks"');
-      response.addString(json.stringify({
+      response.write(json.stringify({
         'error': {'message': 'your token sucks'}
       }));
       response.close();
@@ -210,7 +244,7 @@
       expect(body, matches(new RegExp(r'(^|&)code=access\+code(&|$)')));
 
       response.headers.contentType = new ContentType("application", "json");
-      response.addString(json.stringify({
+      response.write(json.stringify({
         "access_token": accessToken,
         "token_type": "bearer"
       }));
@@ -218,3 +252,4 @@
     });
   });
 }
+
diff --git a/utils/tests/pub/pub.status b/utils/tests/pub/pub.status
index 7184677..f3a3259 100644
--- a/utils/tests/pub/pub.status
+++ b/utils/tests/pub/pub.status
@@ -7,7 +7,8 @@
 pub_uploader_test: Pass,Fail
 
 pub_lish_test: Pass, Fail # Issue 8868
-validator_test: Pass, Fail # Issue 8868
+
+install/broken_symlink_test: Fail # Issue 8343
 
 # Pub only runs on the VM, so just rule out all compilers.
 [ $compiler == dart2js || $compiler == dart2dart ]
diff --git a/utils/tests/pub/pub_cache_test.dart b/utils/tests/pub/pub_cache_test.dart
new file mode 100644
index 0000000..b59717b
--- /dev/null
+++ b/utils/tests/pub/pub_cache_test.dart
@@ -0,0 +1,73 @@
+// 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 pub_cache_test;
+
+import 'dart:io';
+import 'dart:json' as json;
+import 'test_pub.dart';
+import '../../pub/io.dart';
+
+main() {
+  initConfig();
+  
+  integration('running pub cache displays error message', () {
+    schedulePub(args: ['cache'], 
+        output: '''
+          Inspect the system cache.
+
+          Usage: pub cache list
+          ''',
+        error: 'The cache command expects one argument.',
+        exitCode: 64);
+  });
+  
+  integration('running pub cache foo displays error message', () {
+    schedulePub(args: ['cache' ,'foo'], 
+        output: '''
+          Inspect the system cache.
+
+          Usage: pub cache list
+          ''',
+        error: 'Unknown cache command "foo".',
+        exitCode: 64);
+  });
+  
+  integration('running pub cache list when there is no cache', () {      
+    schedulePub(args: ['cache', 'list'], output: '{"packages":{}}');
+  });
+  
+  integration('running pub cache list on empty cache', () {      
+    // Set up a cache.
+    dir(cachePath, [
+      dir('hosted', [
+         dir('pub.dartlang.org', [
+        ])
+      ])
+    ]).scheduleCreate();
+    
+    schedulePub(args: ['cache', 'list'], output: '{"packages":{}}');
+  });
+  
+  integration('running pub cache list', () {
+    // Set up a cache.
+    dir(cachePath, [
+      dir('hosted', [
+         dir('pub.dartlang.org', [
+          dir("foo-1.2.3", [
+            libPubspec("foo", "1.2.3"),
+            libDir("foo")
+          ]),
+          dir("bar-2.0.0", [
+            libPubspec("bar", "2.0.0"),
+            libDir("bar") ])
+        ])
+      ])
+    ]).scheduleCreate();
+    
+    schedulePub(args: ['cache', 'list'], output: 
+      new RegExp(r'\{"packages":\{"bar":\{"version":"2\.0\.0","location":"[^"]+bar-2\.0\.0"\},"foo":\{"version":"1\.2\.3","location":"[^"]+foo-1\.2\.3"\}\}\}$'));
+  });
+  
+}
\ No newline at end of file
diff --git a/utils/tests/pub/pub_lish_test.dart b/utils/tests/pub/pub_lish_test.dart
index 62fcdf8..4950554 100644
--- a/utils/tests/pub/pub_lish_test.dart
+++ b/utils/tests/pub/pub_lish_test.dart
@@ -29,7 +29,7 @@
       }
 
       response.headers.contentType = new ContentType("application", "json");
-      response.addString(json.stringify(body));
+      response.write(json.stringify(body));
       response.close();
     });
   });
@@ -63,7 +63,7 @@
     handleUpload(server);
 
     server.handle('GET', '/create', (request, response) {
-      response.addString(json.stringify({
+      response.write(json.stringify({
         'success': {'message': 'Package test_pkg 1.0.0 uploaded!'}
       }));
       response.close();
@@ -150,7 +150,7 @@
     handleUpload(server);
 
     server.handle('GET', '/create', (request, response) {
-      response.addString(json.stringify({
+      response.write(json.stringify({
         'success': {'message': 'Package test_pkg 1.0.0 uploaded!'}
       }));
       response.close();
@@ -170,7 +170,7 @@
 
     server.handle('GET', '/packages/versions/new.json', (request, response) {
       response.statusCode = 400;
-      response.addString(json.stringify({
+      response.write(json.stringify({
         'error': {'message': 'your request sucked'}
       }));
       response.close();
@@ -188,7 +188,7 @@
     confirmPublish(pub);
 
     server.handle('GET', '/packages/versions/new.json', (request, response) {
-      response.addString('{not json');
+      response.write('{not json');
       response.close();
     });
 
@@ -295,7 +295,7 @@
       return drainStream(request).then((_) {
         response.statusCode = 400;
         response.headers.contentType = new ContentType('application', 'xml');
-        response.addString('<Error><Message>Your request sucked.'
+        response.write('<Error><Message>Your request sucked.'
             '</Message></Error>');
         response.close();
       });
@@ -337,7 +337,7 @@
 
     server.handle('GET', '/create', (request, response) {
       response.statusCode = 400;
-      response.addString(json.stringify({
+      response.write(json.stringify({
         'error': {'message': 'Your package was too boring.'}
       }));
       response.close();
@@ -357,7 +357,7 @@
     handleUpload(server);
 
     server.handle('GET', '/create', (request, response) {
-      response.addString('{not json');
+      response.write('{not json');
       response.close();
     });
 
@@ -378,7 +378,7 @@
     var body = {'error': 'Your package was too boring.'};
     server.handle('GET', '/create', (request, response) {
       response.statusCode = 400;
-      response.addString(json.stringify(body));
+      response.write(json.stringify(body));
       response.close();
     });
 
@@ -398,7 +398,7 @@
 
     var body = {'success': 'Your package was awesome.'};
     server.handle('GET', '/create', (request, response) {
-      response.addString(json.stringify(body));
+      response.write(json.stringify(body));
       response.close();
     });
 
@@ -425,7 +425,7 @@
       handleUpload(server);
 
       server.handle('GET', '/create', (request, response) {
-        response.addString(json.stringify({
+        response.write(json.stringify({
           'success': {'message': 'Package test_pkg 1.0.0 uploaded!'}
         }));
         response.close();
@@ -449,7 +449,7 @@
       handleUpload(server);
 
       server.handle('GET', '/create', (request, response) {
-        response.addString(json.stringify({
+        response.write(json.stringify({
           'success': {'message': 'Package test_pkg 1.0.0 uploaded!'}
         }));
         response.close();
diff --git a/utils/tests/pub/pub_test.dart b/utils/tests/pub/pub_test.dart
index bb38086..0696344 100644
--- a/utils/tests/pub/pub_test.dart
+++ b/utils/tests/pub/pub_test.dart
@@ -27,6 +27,7 @@
     -v, --verbose         Shortcut for "--verbosity=all"
 
     Available commands:
+      cache      Inspect the system cache.
       help       Display help information for Pub.
       install    Install the current package's dependencies.
       publish    Publish the current package to pub.dartlang.org.
diff --git a/utils/tests/pub/pub_uploader_test.dart b/utils/tests/pub/pub_uploader_test.dart
index d8f8721..3cbb997 100644
--- a/utils/tests/pub/pub_uploader_test.dart
+++ b/utils/tests/pub/pub_uploader_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -58,7 +58,7 @@
         expect(new String.fromCharCodes(bodyBytes), equals('email=email'));
 
         response.headers.contentType = new ContentType("application", "json");
-        response.addString(json.stringify({
+        response.write(json.stringify({
           'success': {'message': 'Good job!'}
         }));
         response.close();
@@ -77,7 +77,7 @@
     server.handle('DELETE', '/packages/pkg/uploaders/email.json',
         (request, response) {
       response.headers.contentType = new ContentType("application", "json");
-      response.addString(json.stringify({
+      response.write(json.stringify({
         'success': {'message': 'Good job!'}
       }));
       response.close();
@@ -97,7 +97,7 @@
     server.handle('POST', '/packages/test_pkg/uploaders.json',
         (request, response) {
       response.headers.contentType = new ContentType("application", "json");
-      response.addString(json.stringify({
+      response.write(json.stringify({
         'success': {'message': 'Good job!'}
       }));
       response.close();
@@ -115,7 +115,7 @@
     server.handle('POST', '/packages/pkg/uploaders.json', (request, response) {
       response.statusCode = 400;
       response.headers.contentType = new ContentType("application", "json");
-      response.addString(json.stringify({
+      response.write(json.stringify({
         'error': {'message': 'Bad job!'}
       }));
       response.close();
@@ -135,7 +135,7 @@
         (request, response) {
       response.statusCode = 400;
       response.headers.contentType = new ContentType("application", "json");
-      response.addString(json.stringify({
+      response.write(json.stringify({
         'error': {'message': 'Bad job!'}
       }));
       response.close();
@@ -151,7 +151,7 @@
     var pub = startPubUploader(server, ['--package', 'pkg', 'add', 'email']);
 
     server.handle('POST', '/packages/pkg/uploaders.json', (request, response) {
-      response.addString("{not json");
+      response.write("{not json");
       response.close();
     });
 
@@ -167,7 +167,7 @@
 
     server.handle('DELETE', '/packages/pkg/uploaders/email.json',
         (request, response) {
-      response.addString("{not json");
+      response.write("{not json");
       response.close();
     });
 
diff --git a/utils/tests/pub/pubspec_test.dart b/utils/tests/pub/pubspec_test.dart
index 9813cf5..8b40664 100644
--- a/utils/tests/pub/pubspec_test.dart
+++ b/utils/tests/pub/pubspec_test.dart
@@ -25,154 +25,186 @@
 
 main() {
   initConfig();
-  group('Pubspec', () {
-    group('parse()', () {
-      var sources = new SourceRegistry();
-      sources.register(new MockSource());
+  group('parse()', () {
+    var sources = new SourceRegistry();
+    sources.register(new MockSource());
 
-      expectFormatError(String pubspec) {
-        expect(() => new Pubspec.parse(null, pubspec, sources),
-            throwsFormatException);
-      }
+    expectFormatError(String pubspec) {
+      expect(() => new Pubspec.parse(null, pubspec, sources),
+          throwsFormatException);
+    }
 
-      test("allows a version constraint for dependencies", () {
-        var pubspec = new Pubspec.parse(null, '''
+    test("allows a version constraint for dependencies", () {
+      var pubspec = new Pubspec.parse(null, '''
 dependencies:
   foo:
     mock: ok
     version: ">=1.2.3 <3.4.5"
 ''', sources);
 
-        var foo = pubspec.dependencies[0];
-        expect(foo.name, equals('foo'));
-        expect(foo.constraint.allows(new Version(1, 2, 3)), isTrue);
-        expect(foo.constraint.allows(new Version(1, 2, 5)), isTrue);
-        expect(foo.constraint.allows(new Version(3, 4, 5)), isFalse);
-      });
+      var foo = pubspec.dependencies[0];
+      expect(foo.name, equals('foo'));
+      expect(foo.constraint.allows(new Version(1, 2, 3)), isTrue);
+      expect(foo.constraint.allows(new Version(1, 2, 5)), isTrue);
+      expect(foo.constraint.allows(new Version(3, 4, 5)), isFalse);
+    });
 
-      test("allows an empty dependencies map", () {
-        var pubspec = new Pubspec.parse(null, '''
+    test("allows an empty dependencies map", () {
+      var pubspec = new Pubspec.parse(null, '''
 dependencies:
 ''', sources);
 
-        expect(pubspec.dependencies, isEmpty);
-      });
+      expect(pubspec.dependencies, isEmpty);
+    });
 
-      test("throws if the description isn't valid", () {
-        expectFormatError('''
+    test("allows a version constraint for dev dependencies", () {
+      var pubspec = new Pubspec.parse(null, '''
+dev_dependencies:
+  foo:
+    mock: ok
+    version: ">=1.2.3 <3.4.5"
+''', sources);
+
+      var foo = pubspec.devDependencies[0];
+      expect(foo.name, equals('foo'));
+      expect(foo.constraint.allows(new Version(1, 2, 3)), isTrue);
+      expect(foo.constraint.allows(new Version(1, 2, 5)), isTrue);
+      expect(foo.constraint.allows(new Version(3, 4, 5)), isFalse);
+    });
+
+    test("allows an empty dev dependencies map", () {
+      var pubspec = new Pubspec.parse(null, '''
+dev_dependencies:
+''', sources);
+
+      expect(pubspec.devDependencies, isEmpty);
+    });
+
+    test("throws if a package is in dependencies and dev_dependencies", () {
+      expectFormatError('''
+dependencies:
+  foo:
+    mock: ok
+dev_dependencies:
+  foo:
+    mock: ok
+''');
+    });
+
+    test("throws if the description isn't valid", () {
+      expectFormatError('''
 dependencies:
   foo:
     mock: bad
 ''');
-      });
+    });
 
-      test("throws if 'name' is not a string", () {
-        expectFormatError('name: [not, a, string]');
-      });
+    test("throws if 'name' is not a string", () {
+      expectFormatError('name: [not, a, string]');
+    });
 
-      test("throws if 'homepage' is not a string", () {
-        expectFormatError('homepage:');
-        expectFormatError('homepage: [not, a, string]');
-      });
+    test("throws if 'homepage' is not a string", () {
+      expectFormatError('homepage:');
+      expectFormatError('homepage: [not, a, string]');
+    });
 
-      test("throws if 'homepage' doesn't have an HTTP scheme", () {
-        new Pubspec.parse(null, 'homepage: http://ok.com', sources);
-        new Pubspec.parse(null, 'homepage: https://also-ok.com', sources);
+    test("throws if 'homepage' doesn't have an HTTP scheme", () {
+      new Pubspec.parse(null, 'homepage: http://ok.com', sources);
+      new Pubspec.parse(null, 'homepage: https://also-ok.com', sources);
 
-        expectFormatError('homepage: ftp://badscheme.com');
-        expectFormatError('homepage: javascript:alert("!!!")');
-        expectFormatError('homepage: data:image/png;base64,somedata');
-        expectFormatError('homepage: no-scheme.com');
-      });
+      expectFormatError('homepage: ftp://badscheme.com');
+      expectFormatError('homepage: javascript:alert("!!!")');
+      expectFormatError('homepage: data:image/png;base64,somedata');
+      expectFormatError('homepage: no-scheme.com');
+    });
 
-      test("throws if 'documentation' is not a string", () {
-        expectFormatError('documentation:');
-        expectFormatError('documentation: [not, a, string]');
-      });
+    test("throws if 'documentation' is not a string", () {
+      expectFormatError('documentation:');
+      expectFormatError('documentation: [not, a, string]');
+    });
 
-      test("throws if 'documentation' doesn't have an HTTP scheme", () {
-        new Pubspec.parse(null, 'documentation: http://ok.com', sources);
-        new Pubspec.parse(null, 'documentation: https://also-ok.com', sources);
+    test("throws if 'documentation' doesn't have an HTTP scheme", () {
+      new Pubspec.parse(null, 'documentation: http://ok.com', sources);
+      new Pubspec.parse(null, 'documentation: https://also-ok.com', sources);
 
-        expectFormatError('documentation: ftp://badscheme.com');
-        expectFormatError('documentation: javascript:alert("!!!")');
-        expectFormatError('documentation: data:image/png;base64,somedata');
-        expectFormatError('documentation: no-scheme.com');
-      });
+      expectFormatError('documentation: ftp://badscheme.com');
+      expectFormatError('documentation: javascript:alert("!!!")');
+      expectFormatError('documentation: data:image/png;base64,somedata');
+      expectFormatError('documentation: no-scheme.com');
+    });
 
-      test("throws if 'authors' is not a string or a list of strings", () {
-        new Pubspec.parse(null, 'authors: ok fine', sources);
-        new Pubspec.parse(null, 'authors: [also, ok, fine]', sources);
+    test("throws if 'authors' is not a string or a list of strings", () {
+      new Pubspec.parse(null, 'authors: ok fine', sources);
+      new Pubspec.parse(null, 'authors: [also, ok, fine]', sources);
 
-        expectFormatError('authors: 123');
-        expectFormatError('authors: {not: {a: string}}');
-        expectFormatError('authors: [ok, {not: ok}]');
-      });
+      expectFormatError('authors: 123');
+      expectFormatError('authors: {not: {a: string}}');
+      expectFormatError('authors: [ok, {not: ok}]');
+    });
 
-      test("throws if 'author' is not a string", () {
-        new Pubspec.parse(null, 'author: ok fine', sources);
+    test("throws if 'author' is not a string", () {
+      new Pubspec.parse(null, 'author: ok fine', sources);
 
-        expectFormatError('author: 123');
-        expectFormatError('author: {not: {a: string}}');
-        expectFormatError('author: [not, ok]');
-      });
+      expectFormatError('author: 123');
+      expectFormatError('author: {not: {a: string}}');
+      expectFormatError('author: [not, ok]');
+    });
 
-      test("throws if both 'author' and 'authors' are present", () {
-        expectFormatError('{author: abe, authors: ted}');
-      });
+    test("throws if both 'author' and 'authors' are present", () {
+      expectFormatError('{author: abe, authors: ted}');
+    });
 
-      test("allows comment-only files", () {
-        var pubspec = new Pubspec.parse(null, '''
+    test("allows comment-only files", () {
+      var pubspec = new Pubspec.parse(null, '''
 # No external dependencies yet
 # Including for completeness
 # ...and hoping the spec expands to include details about author, version, etc
 # See http://www.dartlang.org/docs/pub-package-manager/ for details
 ''', sources);
-        expect(pubspec.version, equals(Version.none));
-        expect(pubspec.dependencies, isEmpty);
+      expect(pubspec.version, equals(Version.none));
+      expect(pubspec.dependencies, isEmpty);
+    });
+
+    group("environment", () {
+      test("defaults to any SDK constraint if environment is omitted", () {
+        var pubspec = new Pubspec.parse(null, '', sources);
+        expect(pubspec.environment.sdkVersion, equals(VersionConstraint.any));
       });
 
-      group("environment", () {
-        test("defaults to any SDK constraint if environment is omitted", () {
-          var pubspec = new Pubspec.parse(null, '', sources);
-          expect(pubspec.environment.sdkVersion, equals(VersionConstraint.any));
-        });
-
-        test("allows an empty environment map", () {
-          var pubspec = new Pubspec.parse(null, '''
+      test("allows an empty environment map", () {
+        var pubspec = new Pubspec.parse(null, '''
 environment:
 ''', sources);
-          expect(pubspec.environment.sdkVersion, equals(VersionConstraint.any));
-        });
+        expect(pubspec.environment.sdkVersion, equals(VersionConstraint.any));
+      });
 
-        test("throws if the environment value isn't a map", () {
-          expectFormatError('''
+      test("throws if the environment value isn't a map", () {
+        expectFormatError('''
 environment: []
 ''');
-        });
+      });
 
-        test("allows a version constraint for the sdk", () {
-          var pubspec = new Pubspec.parse(null, '''
+      test("allows a version constraint for the sdk", () {
+        var pubspec = new Pubspec.parse(null, '''
 environment:
   sdk: ">=1.2.3 <2.3.4"
 ''', sources);
-          expect(pubspec.environment.sdkVersion,
-              equals(new VersionConstraint.parse(">=1.2.3 <2.3.4")));
-        });
+        expect(pubspec.environment.sdkVersion,
+            equals(new VersionConstraint.parse(">=1.2.3 <2.3.4")));
+      });
 
-        test("throws if the sdk isn't a string", () {
-          expectFormatError('''
+      test("throws if the sdk isn't a string", () {
+        expectFormatError('''
 environment:
   sdk: []
 ''');
-        });
+      });
 
-        test("throws if the sdk isn't a valid version constraint", () {
-          expectFormatError('''
+      test("throws if the sdk isn't a valid version constraint", () {
+        expectFormatError('''
 environment:
   sdk: "oopies"
 ''');
-        });
       });
     });
   });
diff --git a/utils/tests/pub/sdk_constraint_test.dart b/utils/tests/pub/sdk_constraint_test.dart
index 7032c61..77ea854 100644
--- a/utils/tests/pub/sdk_constraint_test.dart
+++ b/utils/tests/pub/sdk_constraint_test.dart
@@ -44,26 +44,22 @@
     });
 
     integration("gives an error if some dependencies do not match", () {
-      // Using an SDK source, but this should be true of all sources.
-      dir(sdkPath, [
-        dir("pkg", [
-          dir("foo", [
-            libPubspec("foo", "0.0.1", sdk: ">0.1.3"),
-            libDir("foo")
-          ]),
-          dir("bar", [
-            libPubspec("bar", "0.0.1", sdk: ">0.1.1"),
-            libDir("bar")
-          ])
-        ])
+      // Using a path source, but this should be true of all sources.
+      dir("foo", [
+        libPubspec("foo", "0.0.1", sdk: ">0.1.3"),
+        libDir("foo")
+      ]).scheduleCreate();
+      dir("bar", [
+        libPubspec("bar", "0.0.1", sdk: ">0.1.1"),
+        libDir("bar")
       ]).scheduleCreate();
 
       dir(appPath, [
         pubspec({
           "name": "myapp",
           "dependencies": {
-            "foo": { "sdk": "foo" },
-            "bar": { "sdk": "bar" }
+            "foo": {"path": "../foo"},
+            "bar": {"path": "../bar"}
           },
           "environment": {"sdk": ">2.0.0"}
         })
@@ -82,27 +78,23 @@
     });
 
     integration("gives an error if a transitive dependency doesn't match", () {
-      // Using an SDK source, but this should be true of all sources.
-      dir(sdkPath, [
-        dir("pkg", [
-          dir("foo", [
-            libPubspec("foo", "0.0.1", deps: [
-              {"sdk": "bar"}
-            ]),
-            libDir("foo")
-          ]),
-          dir("bar", [
-            libPubspec("bar", "0.0.1", sdk: "<0.1.1"),
-            libDir("bar")
-          ])
-        ])
+      // Using a path source, but this should be true of all sources.
+      dir("foo", [
+        libPubspec("foo", "0.0.1", deps: [
+          {"path": "../bar"}
+        ]),
+        libDir("foo")
+      ]).scheduleCreate();
+      dir("bar", [
+        libPubspec("bar", "0.0.1", sdk: "<0.1.1"),
+        libDir("bar")
       ]).scheduleCreate();
 
       dir(appPath, [
         pubspec({
           "name": "myapp",
           "dependencies": {
-            "foo": { "sdk": "foo" }
+            "foo": {"path": "../foo"}
           }
         })
       ]).scheduleCreate();
@@ -119,23 +111,19 @@
     });
 
     integration("handles a circular dependency on the root package", () {
-      // Using an SDK source, but this should be true of all sources.
-      dir(sdkPath, [
-        dir("pkg", [
-          dir("foo", [
-            libPubspec("foo", "0.0.1", sdk: ">3.0.0", deps: [
-              {"sdk": "myapp"}
-            ]),
-            libDir("foo")
-          ])
-        ])
+      // Using a path source, but this should be true of all sources.
+      dir("foo", [
+        libPubspec("foo", "0.0.1", sdk: ">3.0.0", deps: [
+          {"path": "../myapp"}
+        ]),
+        libDir("foo")
       ]).scheduleCreate();
 
       dir(appPath, [
         pubspec({
           "name": "myapp",
           "dependencies": {
-            "foo": { "sdk": "foo" }
+            "foo": {"path": "../foo"}
           },
           "environment": {"sdk": ">2.0.0"}
         })
diff --git a/utils/tests/pub/test_pub.dart b/utils/tests/pub/test_pub.dart
index 3f56b3d..bf573fd 100644
--- a/utils/tests/pub/test_pub.dart
+++ b/utils/tests/pub/test_pub.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -32,7 +32,7 @@
 import '../../pub/http.dart';
 import '../../pub/io.dart';
 import '../../pub/path_source.dart';
-import '../../pub/sdk_source.dart';
+import '../../pub/safe_http_server.dart';
 import '../../pub/system_cache.dart';
 import '../../pub/utils.dart';
 import '../../pub/validator.dart';
@@ -102,7 +102,7 @@
 
   _schedule((_) {
     return _closeServer().then((_) {
-      return HttpServer.bind("127.0.0.1", 0).then((server) {
+      return SafeHttpServer.bind("127.0.0.1", 0).then((server) {
         _server = server;
         server.listen((request) {
           var response = request.response;
@@ -121,7 +121,7 @@
           stream.toBytes().then((data) {
             response.statusCode = 200;
             response.contentLength = data.length;
-            response.add(data);
+            response.writeBytes(data);
             response.close();
           }).catchError((e) {
             print("Exception while handling ${request.uri}: $e");
@@ -410,9 +410,6 @@
       case "path":
         source = new PathSource();
         break;
-      case "sdk":
-        source = new SdkSource();
-        break;
       default:
         throw 'Unknown source "$sourceName"';
       }
@@ -1024,7 +1021,7 @@
 
     for (var descriptor in contents) {
       if (descriptor.name == path[0]) {
-        return descriptor.load(path.getRange(1, path.length - 1));
+        return descriptor.load(path.sublist(1));
       }
     }
 
@@ -1173,7 +1170,8 @@
   }
 }
 
-/// A descriptor that validates that no file exists with the given name.
+/// A descriptor that validates that no file or directory exists with the given
+/// name.
 class NothingDescriptor extends Descriptor {
   NothingDescriptor(String name) : super(name);
 
@@ -1183,7 +1181,7 @@
   Future validate(String dir) {
     return defer(() {
       if (entryExists(path.join(dir, name))) {
-        throw new TestFailure('File $name in $dir should not exist.');
+        throw new TestFailure('Entry $name in $dir should not exist.');
       }
     });
   }
@@ -1439,7 +1437,7 @@
   /// Writes [line] to the process as stdin.
   void writeLine(String line) {
     _schedule((_) => _processFuture.then(
-        (p) => p.stdin.add('$line\n'.codeUnits)));
+        (p) => p.stdin.add(encodeUtf8('$line\n'))));
   }
 
   /// Kills the process, and waits until it's dead.
@@ -1509,7 +1507,7 @@
   factory ScheduledServer() {
     var scheduledServer;
     scheduledServer = new ScheduledServer._(_scheduleValue((_) {
-      return HttpServer.bind("127.0.0.1", 0).then((server) {
+      return SafeHttpServer.bind("127.0.0.1", 0).then((server) {
         server.listen(scheduledServer._awaitHandle);
         _scheduleCleanup((_) => server.close());
         return server;
diff --git a/utils/tests/pub/update/pub_update_test.dart b/utils/tests/pub/update/pub_update_test.dart
index c28951c..a32b636 100644
--- a/utils/tests/pub/update/pub_update_test.dart
+++ b/utils/tests/pub/update/pub_update_test.dart
@@ -10,6 +10,7 @@
 import '../test_pub.dart';
 
 main() {
+  initConfig();
   group('requires', () {
     integration('a pubspec', () {
       dir(appPath, []).scheduleCreate();
@@ -67,17 +68,13 @@
 
   integration('does not add a package if it does not have a "lib" '
       'directory', () {
-    // Using an SDK source, but this should be true of all sources.
-    dir(sdkPath, [
-      dir('pkg', [
-        dir('foo', [
-          libPubspec('foo', '0.0.0-not.used')
-        ])
-      ])
+    // Using a path source, but this should be true of all sources.
+    dir('foo', [
+      libPubspec('foo', '0.0.0-not.used')
     ]).scheduleCreate();
 
     dir(appPath, [
-      pubspec({"name": "myapp", "dependencies": {"foo": {"sdk": "foo"}}})
+      pubspec({"name": "myapp", "dependencies": {"foo": {"path": "../foo"}}})
     ]).scheduleCreate();
 
     schedulePub(args: ['update'],
diff --git a/utils/tests/pub/validator_test.dart b/utils/tests/pub/validator_test.dart
index c439633..2c36945 100644
--- a/utils/tests/pub/validator_test.dart
+++ b/utils/tests/pub/validator_test.dart
@@ -161,15 +161,6 @@
       expectNoValidationError(lib);
     });
 
-    integration('has an unconstrained dependency on "unittest"', () {
-      dir(appPath, [
-        libPubspec("test_pkg", "1.0.0", deps: [
-          {'hosted': 'unittest'}
-        ])
-      ]).scheduleCreate();
-      expectNoValidationError(dependency);
-    });
-
     integration('has a nested directory named "tools"', () {
       dir(appPath, [
         dir("foo", [dir("tools")])
diff --git a/utils/tests/pub/version_solver_test.dart b/utils/tests/pub/version_solver_test.dart
index 3d4b020..bdec057b 100644
--- a/utils/tests/pub/version_solver_test.dart
+++ b/utils/tests/pub/version_solver_test.dart
@@ -7,6 +7,8 @@
 import 'dart:async';
 import 'dart:io';
 
+import '../../../pkg/unittest/lib/unittest.dart';
+
 import '../../pub/lock_file.dart';
 import '../../pub/package.dart';
 import '../../pub/pubspec.dart';
@@ -16,7 +18,7 @@
 import '../../pub/utils.dart';
 import '../../pub/version.dart';
 import '../../pub/version_solver.dart';
-import '../../../pkg/unittest/lib/unittest.dart';
+import 'test_pub.dart';
 
 Matcher noVersion(List<String> packages) {
   return predicate((x) {
@@ -67,9 +69,10 @@
 
 MockSource source1;
 MockSource source2;
-Source versionlessSource;
 
 main() {
+  initConfig();
+
   testResolve('no dependencies', {
     'myapp 0.0.0': {}
   }, result: {
@@ -147,30 +150,6 @@
     'bang': '1.0.0'
   });
 
-  testResolve('from versionless source', {
-    'myapp 0.0.0': {
-      'foo from versionless': 'any'
-    },
-    'foo 1.2.3 from versionless': {}
-  }, result: {
-    'myapp from root': '0.0.0',
-    'foo from versionless': '1.2.3'
-  });
-
-  testResolve('transitively through versionless source', {
-    'myapp 0.0.0': {
-      'foo from versionless': 'any'
-    },
-    'foo 1.2.3 from versionless': {
-      'bar': '>=1.0.0'
-    },
-    'bar 1.1.0': {}
-  }, result: {
-    'myapp from root': '0.0.0',
-    'foo from versionless': '1.2.3',
-    'bar': '1.1.0'
-  });
-
   testResolve('with compatible locked dependency', {
     'myapp 0.0.0': {
       'foo': 'any'
@@ -369,54 +348,91 @@
     }
   }, error: couldNotSolve);
 
+  group('dev dependencies', () {
+    testResolve("includes root package's dev dependencies", {
+      'myapp 1.0.0': {
+        '(dev) foo': '1.0.0',
+        '(dev) bar': '1.0.0'
+      },
+      'foo 1.0.0': {},
+      'bar 1.0.0': {}
+    }, result: {
+      'myapp from root': '1.0.0',
+      'foo': '1.0.0',
+      'bar': '1.0.0'
+    });
+
+    testResolve("includes dev dependency's transitive dependencies", {
+      'myapp 1.0.0': {
+        '(dev) foo': '1.0.0'
+      },
+      'foo 1.0.0': {
+        'bar': '1.0.0'
+      },
+      'bar 1.0.0': {}
+    }, result: {
+      'myapp from root': '1.0.0',
+      'foo': '1.0.0',
+      'bar': '1.0.0'
+    });
+
+    testResolve("ignores transitive dependency's dev dependencies", {
+      'myapp 1.0.0': {
+        'foo': '1.0.0'
+      },
+      'foo 1.0.0': {
+        '(dev) bar': '1.0.0'
+      },
+      'bar 1.0.0': {}
+    }, result: {
+      'myapp from root': '1.0.0',
+      'foo': '1.0.0'
+    });
+  });
+}
+
 // TODO(rnystrom): More stuff to test:
 // - Depending on a non-existent package.
 // - Test that only a certain number requests are sent to the mock source so we
 //   can keep track of server traffic.
-}
 
 testResolve(description, packages, {lockfile, result, Matcher error}) {
   test(description, () {
     var cache = new SystemCache('.');
     source1 = new MockSource('mock1');
     source2 = new MockSource('mock2');
-    versionlessSource = new MockVersionlessSource();
     cache.register(source1);
     cache.register(source2);
-    cache.register(versionlessSource);
     cache.sources.setDefault(source1.name);
 
     // Build the test package graph.
     var root;
     packages.forEach((nameVersion, dependencies) {
-      var parsed = parseSource(nameVersion);
-      nameVersion = parsed.first;
-      var source = parsed.last;
+      var parsed = parseSource(nameVersion, (isDev, nameVersion, source) {
+        var parts = nameVersion.split(' ');
+        var name = parts[0];
+        var version = parts[1];
 
-      var parts = nameVersion.split(' ');
-      var name = parts[0];
-      var version = parts[1];
-
-      var package = source1.mockPackage(name, version, dependencies);
-      if (name == 'myapp') {
-        // Don't add the root package to the server, so we can verify that Pub
-        // doesn't try to look up information about the local package on the
-        // remote server.
-        root = package;
-      } else {
-        source.addPackage(package);
-      }
+        var package = source1.mockPackage(name, version, dependencies);
+        if (name == 'myapp') {
+          // Don't add the root package to the server, so we can verify that Pub
+          // doesn't try to look up information about the local package on the
+          // remote server.
+          root = package;
+        } else {
+          source.addPackage(package);
+        }
+      });
     });
 
     // Clean up the expectation.
     if (result != null) {
       var newResult = {};
       result.forEach((name, version) {
-        var parsed = parseSource(name);
-        name = parsed.first;
-        var source = parsed.last;
-        version = new Version.parse(version);
-        newResult[name] = new PackageId(name, source, version, name);
+        parseSource(name, (isDev, name, source) {
+          version = new Version.parse(version);
+          newResult[name] = new PackageId(name, source, version, name);
+        });
       });
       result = newResult;
     }
@@ -482,16 +498,24 @@
       Map dependencyStrings) {
     // Build the pubspec dependencies.
     var dependencies = <PackageRef>[];
+    var devDependencies = <PackageRef>[];
+
     dependencyStrings.forEach((name, constraint) {
-      var parsed = parseSource(name);
-      var description = parsed.first;
-      var packageName = description.replaceFirst(new RegExp(r"-[^-]+$"), "");
-      dependencies.add(new PackageRef(packageName, parsed.last,
-          new VersionConstraint.parse(constraint), description));
+      parseSource(name, (isDev, name, source) {
+        var packageName = name.replaceFirst(new RegExp(r"-[^-]+$"), "");
+        var ref = new PackageRef(packageName, source,
+            new VersionConstraint.parse(constraint), name);
+
+        if (isDev) {
+          devDependencies.add(ref);
+        } else {
+          dependencies.add(ref);
+        }
+      });
     });
 
     var pubspec = new Pubspec(
-        description, new Version.parse(version), dependencies,
+        description, new Version.parse(version), dependencies, devDependencies,
         new PubspecEnvironment());
     return new Package.inMemory(pubspec);
   }
@@ -502,38 +526,29 @@
   }
 }
 
-/// A source used for testing that doesn't natively understand versioning,
-/// similar to how the Git and SDK sources work.
-class MockVersionlessSource extends Source {
-  final Map<String, Package> _packages;
+void parseSource(String description,
+    callback(bool isDev, String name, Source source)) {
+  var isDev = false;
 
-  final String name = 'versionless';
-  final bool shouldCache = false;
-
-  MockVersionlessSource()
-    : _packages = <String, Package>{};
-
-  Future<bool> install(PackageId id, String path) {
-    throw 'no';
+  if (description.startsWith("(dev) ")) {
+    description = description.substring("(dev) ".length);
+    isDev = true;
   }
 
-  Future<Pubspec> describe(PackageId id) {
-    return new Future<Pubspec>.immediate(_packages[id.description].pubspec);
+  var name = description;
+  var source = source1;
+
+  var sourceNames = {
+    'mock1': source1,
+    'mock2': source2,
+    'root': null
+  };
+
+  var match = new RegExp(r"(.*) from (.*)").firstMatch(description);
+  if (match != null) {
+    name = match[1];
+    source = sourceNames[match[2]];
   }
 
-  void addPackage(Package package) {
-    _packages[package.name] = package;
-  }
-}
-
-Pair<String, Source> parseSource(String name) {
-  var match = new RegExp(r"(.*) from (.*)").firstMatch(name);
-  if (match == null) return new Pair<String, Source>(name, source1);
-  switch (match[2]) {
-  case 'mock1': return new Pair<String, Source>(match[1], source1);
-  case 'mock2': return new Pair<String, Source>(match[1], source2);
-  case 'root': return new Pair<String, Source>(match[1], null);
-  case 'versionless':
-    return new Pair<String, Source>(match[1], versionlessSource);
-  }
+  callback(isDev, name, source);
 }
diff --git a/utils/tests/string_encoding/benchmark_runner.dart b/utils/tests/string_encoding/benchmark_runner.dart
index 514e87e..0463030 100644
--- a/utils/tests/string_encoding/benchmark_runner.dart
+++ b/utils/tests/string_encoding/benchmark_runner.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+part of BenchmarkTests;
+
 /**
  * The results of a single block of tests (count times run, overall time).
  */
diff --git a/utils/tests/string_encoding/utf8_benchmarks.dart b/utils/tests/string_encoding/utf8_benchmarks.dart
index 6f03e1b..7ea90ca 100755
--- a/utils/tests/string_encoding/utf8_benchmarks.dart
+++ b/utils/tests/string_encoding/utf8_benchmarks.dart
@@ -4,6 +4,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library BenchmarkTests;
+import 'dart:io';
 import 'dart:math' as Math;
 import '../../../lib/utf/utf.dart' as SE;
 part 'benchmark_runner.dart';