Version 0.2.10.0

svn merge -r 16053:16649 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

and cherrypick r16656 from bleeding_edge into trunk.

git-svn-id: http://dart.googlecode.com/svn/trunk@16662 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/.gitignore b/.gitignore
index 41e6819..7562384 100644
--- a/.gitignore
+++ b/.gitignore
@@ -49,3 +49,6 @@
 
 # Vim temporary swap files.
 *.swp
+
+# Generated files.
+tools/out
diff --git a/client/tools/buildbot_annotated_steps.py b/client/tools/buildbot_annotated_steps.py
index 6c30144..4ed1ada 100755
--- a/client/tools/buildbot_annotated_steps.py
+++ b/client/tools/buildbot_annotated_steps.py
@@ -204,18 +204,16 @@
 
   #TODO(sigmund): remove this indirection once we update our bots
   (name, version) = GetBuildInfo()
+  # The buildbot will set a BUILDBOT_JAVA_HOME relative to the dart
+  # root directory, set JAVA_HOME based on that.
+  FixJavaHome()
   if name.startswith('dart-editor'):
-    # TODO (danrubel) Fix dart-editor builds so that we can call FixJavaHome() before the build
-    FixJavaHome()
     status = ProcessTools('release', name, version)
   elif name.startswith('pub-'):
     status = ProcessBot(name, 'pub')
   elif name.startswith('vm-android'):
     status = ProcessBot(name, 'android')
   else:
-    # The buildbot will set a BUILDBOT_JAVA_HOME relative to the dart
-    # root directory, set JAVA_HOME based on that.
-    FixJavaHome()
     status = ProcessBot(name, 'compiler')
 
   if status:
diff --git a/compiler/build.xml b/compiler/build.xml
index c9ccff9..6db056d 100644
--- a/compiler/build.xml
+++ b/compiler/build.xml
@@ -77,7 +77,9 @@
            srcdir="java"
            includes="${java_sources}"
            fork="true"
-           debug="true">
+           debug="true"
+           source="1.6"
+           target="1.6">
       <classpath refid="classpath.compile"/>
     </javac>
     <!--
@@ -97,7 +99,9 @@
            includes="${javatests_sources}"
            excludes="com/google/dart/compiler/vm/**"
            fork="true"
-           debug="true">
+           debug="true"
+           source="1.6"
+           target="1.6">
       <classpath refid="classpath.compile.tests"/>
     </javac>
     <!--
diff --git a/compiler/dart_analyzer.xml b/compiler/dart_analyzer.xml
index ec04b4c..0d3acd6 100644
--- a/compiler/dart_analyzer.xml
+++ b/compiler/dart_analyzer.xml
@@ -72,7 +72,9 @@
            srcdir="java"
            includes="${java_sources}"
            fork="true"
-           debug="true">
+           debug="true"
+           source="1.6"
+           target="1.6">
       <classpath refid="classpath.compile"/>
     </javac>
     <!--
@@ -95,7 +97,9 @@
            includes="${javatests_sources}"
            excludes="com/google/dart/compiler/vm/**"
            fork="true"
-           debug="true">
+           debug="true"
+           source="1.6"
+           target="1.6">
       <classpath refid="classpath.compile.tests"/>
     </javac>
     <!--
diff --git a/compiler/java/com/google/dart/compiler/DartCompiler.java b/compiler/java/com/google/dart/compiler/DartCompiler.java
index 5deca30..98493b2 100644
--- a/compiler/java/com/google/dart/compiler/DartCompiler.java
+++ b/compiler/java/com/google/dart/compiler/DartCompiler.java
@@ -607,7 +607,6 @@
         boolean hasHTML = false;
         for (LibraryNode importNode : lib.getImportPaths()) {
           String libSpec = importNode.getText();
-          String prefix = importNode.getPrefix();
           hasIO |= "dart:io".equals(libSpec);
           hasHTML |= "dart:html".equals(libSpec);
           // "dart:mirrors" are not done yet
@@ -615,11 +614,6 @@
             context.onError(new DartCompilationError(importNode,
                 DartCompilerErrorCode.MIRRORS_NOT_FULLY_IMPLEMENTED));
           }
-          // validate import prefix
-          if (DartParser.PSEUDO_KEYWORDS_SET.contains(prefix)) {
-            context.onError(new DartCompilationError(importNode.getSourceInfo(),
-                ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_IMPORT_PREFIX, prefix));
-          }
           // validate console/web mix
           if (hasIO && hasHTML) {
             context.onError(new DartCompilationError(importNode.getSourceInfo(),
@@ -1386,7 +1380,11 @@
   }
 
   public static LibraryUnit getCoreLib(LibraryUnit libraryUnit) {
-    return findLibrary(libraryUnit, "dart:core", new HashSet<LibraryElement>());
+    LibraryUnit coreLib = findLibrary(libraryUnit, "dart.core", new HashSet<LibraryElement>());
+    if (coreLib == null) {
+      coreLib = findLibrary(libraryUnit, "dart:core", new HashSet<LibraryElement>());
+    }
+    return coreLib;
   }
 
   private static void showVersion(CompilerOptions options) {
diff --git a/compiler/java/com/google/dart/compiler/PackageLibraryManager.java b/compiler/java/com/google/dart/compiler/PackageLibraryManager.java
index ab241ad..9a6dd3e 100644
--- a/compiler/java/com/google/dart/compiler/PackageLibraryManager.java
+++ b/compiler/java/com/google/dart/compiler/PackageLibraryManager.java
@@ -128,7 +128,7 @@
               uri = new URI(PACKAGE_SCHEME + "://" + spec);
             } 
           } catch (URISyntaxException e) {
-            throw new AssertionError();
+            throw new AssertionError(e);
           }
         }       
       }
diff --git a/compiler/java/com/google/dart/compiler/ast/DartAnnotation.java b/compiler/java/com/google/dart/compiler/ast/DartAnnotation.java
index a48cce7..ab44015 100644
--- a/compiler/java/com/google/dart/compiler/ast/DartAnnotation.java
+++ b/compiler/java/com/google/dart/compiler/ast/DartAnnotation.java
@@ -16,7 +16,7 @@
  *     annotation*
  * 
  * annotation ::=
- *     '@' qualified (‘.’ identifier)? arguments?
+ *     '@' qualified ('.' identifier)? arguments?
  * </pre>
  */
 public class DartAnnotation extends DartNode {
diff --git a/compiler/java/com/google/dart/compiler/ast/DartFunction.java b/compiler/java/com/google/dart/compiler/ast/DartFunction.java
index a7693d3..628e45e 100644
--- a/compiler/java/com/google/dart/compiler/ast/DartFunction.java
+++ b/compiler/java/com/google/dart/compiler/ast/DartFunction.java
@@ -12,15 +12,17 @@
 public class DartFunction extends DartNode {
 
   private final NodeList<DartParameter> parameters = NodeList.create(this);
+  private final int parametersOpenParen;
   private final int parametersOptionalOpen;
   private final int parametersOptionalClose;
   private final int parametersCloseParen;
   private DartBlock body;
   private DartTypeNode returnTypeNode;
 
-  public DartFunction(List<DartParameter> parameters, int parametersOptionalOpen,
+  public DartFunction(List<DartParameter> parameters, int parametersOpenParen, int parametersOptionalOpen,
       int parametersOptionalClose, int parametersCloseParen, DartBlock body,
       DartTypeNode returnTypeNode) {
+    this.parametersOpenParen = parametersOpenParen;
     this.parametersOptionalOpen = parametersOptionalOpen;
     this.parametersOptionalClose = parametersOptionalClose;
     if (parameters != null && !parameters.isEmpty()) {
@@ -47,6 +49,10 @@
     return parametersOptionalClose;
   }
   
+  public int getParametersOpenParen() {
+    return parametersOpenParen;
+  }
+  
   public int getParametersCloseParen() {
     return parametersCloseParen;
   }
diff --git a/compiler/java/com/google/dart/compiler/parser/DartParser.java b/compiler/java/com/google/dart/compiler/parser/DartParser.java
index 129eb6a..d0615c5 100644
--- a/compiler/java/com/google/dart/compiler/parser/DartParser.java
+++ b/compiler/java/com/google/dart/compiler/parser/DartParser.java
@@ -332,7 +332,7 @@
         // Check for ABSTRACT_KEYWORD.
         isTopLevelAbstract = false;
         topLevelAbstractModifierPosition = 0;
-        if (optionalPseudoKeyword(ABSTRACT_KEYWORD)) {
+        if (isBuiltInSpecial() && optionalPseudoKeyword(ABSTRACT_KEYWORD)) {
           isTopLevelAbstract = true;
           topLevelAbstractModifierPosition = position();
         }
@@ -349,7 +349,7 @@
           reportError(position(), ParserErrorCode.DEPRECATED_INTERFACE);
           node = done(parseClass());
         } else if (peekPseudoKeyword(0, TYPEDEF_KEYWORD)
-            && (peek(1).equals(Token.IDENTIFIER) || peek(1).equals(Token.VOID) || peek(1).equals(Token.AS))) {
+            && (peek(1).equals(Token.IDENTIFIER) || peek(1).equals(Token.VOID))) {
           consume(Token.IDENTIFIER);
           node = done(parseFunctionTypeAlias());
         } else if (looksLikeDirective()) {
@@ -422,6 +422,9 @@
   }
 
   private boolean looksLikeDirective() {
+    if (!isBuiltInSpecial()) {
+      return false;
+    }
     switch(peek(0)) {
       case LIBRARY:
       case IMPORT:
@@ -694,7 +697,8 @@
     }
     
     DartIdentifier prefix = null;
-    if (optional(Token.AS)) {
+    if (peek(0) == Token.IDENTIFIER && "as".equals(ctx.peekTokenString(0))) {
+      ctx.advance();
       prefix = parseIdentifier();
       if (prefix instanceof DartSyntheticErrorIdentifier) {
         if (peekPseudoKeyword(1, HIDE_KEYWORD) || peekPseudoKeyword(1, SHOW_KEYWORD)
@@ -1090,10 +1094,10 @@
   private boolean isFunctionTypeAliasName() {
     beginFunctionTypeInterface();
     try {
-      if ((peek(0) == Token.IDENTIFIER || peek(0) == Token.AS) && peek(1) == Token.LPAREN) {
+      if (peek(0) == Token.IDENTIFIER && peek(1) == Token.LPAREN) {
         return true;
       }
-      if ((peek(0) == Token.IDENTIFIER || peek(0) == Token.AS) && peek(1) == Token.LT) {
+      if (peek(0) == Token.IDENTIFIER && peek(1) == Token.LT) {
         consume(Token.IDENTIFIER);
         // isTypeParameter leaves the position advanced if it matches
         if (isTypeParameter() && peek(0) == Token.LPAREN) {
@@ -1279,10 +1283,10 @@
   private DartNodeWithMetadata parseFieldOrMethod(boolean allowStatic) {
     beginClassMember();
     Modifiers modifiers = Modifiers.NONE;
-    if (peek(1) != Token.LPAREN && optionalPseudoKeyword(EXTERNAL_KEYWORD)) {
+    if (isBuiltInSpecial() && optionalPseudoKeyword(EXTERNAL_KEYWORD)) {
       modifiers = modifiers.makeExternal();
     }
-    if (peek(1) != Token.LPAREN && optionalPseudoKeyword(STATIC_KEYWORD)) {
+    if (isBuiltInSpecial() && optionalPseudoKeyword(STATIC_KEYWORD)) {
       if (!allowStatic) {
         reportError(position(), ParserErrorCode.TOP_LEVEL_CANNOT_BE_STATIC);
       } else {
@@ -1293,7 +1297,7 @@
         modifiers = modifiers.makeStatic();
       }
     }
-    if (optionalPseudoKeyword(ABSTRACT_KEYWORD)) {
+    if (isBuiltInSpecial() && optionalPseudoKeyword(ABSTRACT_KEYWORD)) {
       if (modifiers.isStatic()) {
         reportError(position(), ParserErrorCode.STATIC_MEMBERS_CANNOT_BE_ABSTRACT);
       }
@@ -1302,7 +1306,7 @@
       }
       modifiers = modifiers.makeAbstract();
     }
-    if (optionalPseudoKeyword(FACTORY_KEYWORD)) {
+    if (isBuiltInSpecial() && optionalPseudoKeyword(FACTORY_KEYWORD)) {
       if (isParsingInterface) {
         reportError(position(), ParserErrorCode.FACTORY_MEMBER_IN_INTERFACE);
       }
@@ -1435,7 +1439,7 @@
           type = parseVoidType();
         } else {
           int nameIndex = skipTypeName(0);
-          if (nameIndex < 0 || (peek(nameIndex) != Token.IDENTIFIER && peek(nameIndex) != Token.AS)) {
+          if (nameIndex < 0 || peek(nameIndex) != Token.IDENTIFIER) {
             // There was no type name.
             type = null;
           } else {
@@ -1495,10 +1499,10 @@
    * @return <code>true</code> if the signature of a method has been found.  No tokens are consumed.
    */
   private boolean looksLikeMethodOrAccessorDefinition() {
-    assert (peek(0).equals(Token.IDENTIFIER));
+    assert (peek(0) == Token.IDENTIFIER );
     beginMethodName(); // begin() equivalent
     try {
-      if (peekPseudoKeyword(0, OPERATOR_KEYWORD)) {
+      if (isBuiltInSpecial() && peekPseudoKeyword(0, OPERATOR_KEYWORD)) {
         next();
         // Using 'operator' as a field name is valid
         if (peek(0).equals(Token.SEMICOLON) || peek(0).equals(Token.ASSIGN)) {
@@ -1599,7 +1603,7 @@
         redirectedConstructorName = parseIdentifier();
       }
       expect(Token.SEMICOLON);
-      DartFunction function = doneWithoutConsuming(new DartFunction(formals.val,
+      DartFunction function = doneWithoutConsuming(new DartFunction(formals.val, formals.openParen,
           formals.optionalOpenOffset, formals.optionalCloseOffset, parametersCloseParen, null, null));
       return DartMethodDefinition.create(name, function, modifiers, redirectedTypeName, 
                                          redirectedConstructorName);
@@ -1609,11 +1613,12 @@
     if (peekPseudoKeyword(0, NATIVE_KEYWORD)) {
       modifiers = modifiers.makeNative();
       function = new DartFunction(formals.val, formals.optionalOpenOffset,
-          formals.optionalCloseOffset, parametersCloseParen, parseNativeBlock(modifiers), null);
+          formals.optionalOpenOffset, formals.optionalCloseOffset, parametersCloseParen,
+          parseNativeBlock(modifiers), null);
     } else {
       function = new DartFunction(formals.val, formals.optionalOpenOffset,
-          formals.optionalCloseOffset, parametersCloseParen, parseFunctionStatementBody(
-              !modifiers.isExternal(), true), null);
+          formals.optionalOpenOffset, formals.optionalCloseOffset, parametersCloseParen,
+          parseFunctionStatementBody(!modifiers.isExternal(), true), null);
     }
     doneWithoutConsuming(function);
     return DartMethodDefinition.create(name, function, modifiers, null);
@@ -1644,7 +1649,7 @@
 
     int arity = -1;
     Token operation = null;
-    if (peek(1) != Token.LPAREN && optionalPseudoKeyword(OPERATOR_KEYWORD)) {
+    if (isBuiltInSpecial() && optionalPseudoKeyword(OPERATOR_KEYWORD)) {
       // Overloaded operator.
       if (modifiers.isStatic()) {
         reportError(position(), ParserErrorCode.OPERATOR_CANNOT_BE_STATIC);
@@ -1733,7 +1738,7 @@
     // Parse the parameters definitions.
     FormalParameters parametersInfo;
     if (modifiers.isGetter()) {
-      parametersInfo = new FormalParameters(new ArrayList<DartParameter>(), -1, -1);
+      parametersInfo = new FormalParameters(new ArrayList<DartParameter>(), -1, -1, -1);
       if (peek(0) == Token.LPAREN) {
         reportError(position(), ParserErrorCode.DEPRECATED_GETTER);
         parametersInfo = parseFormalParameterList();
@@ -1786,8 +1791,8 @@
       }
       expect(Token.SEMICOLON);
       DartFunction function = doneWithoutConsuming(new DartFunction(parameters,
-          parametersInfo.optionalOpenOffset, parametersInfo.optionalCloseOffset,
-          parametersCloseParen, null, returnType));
+          parametersInfo.openParen, parametersInfo.optionalOpenOffset,
+          parametersInfo.optionalCloseOffset, parametersCloseParen, null, returnType));
       return DartMethodDefinition.create(name, function, modifiers, redirectedTypeName, 
                                          redirectedConstructorName);
     }
@@ -1817,8 +1822,8 @@
     }
 
     DartFunction function = doneWithoutConsuming(new DartFunction(parameters,
-        parametersInfo.optionalOpenOffset, parametersInfo.optionalCloseOffset,
-        parametersCloseParen, body, returnType));
+        parametersInfo.openParen, parametersInfo.optionalOpenOffset,
+        parametersInfo.optionalCloseOffset, parametersCloseParen, body, returnType));
     return DartMethodDefinition.create(name, function, modifiers, initializers);
   }
 
@@ -2061,11 +2066,13 @@
   
   private static class FormalParameters {
     private final List<DartParameter> val;
+    private final int openParen;
     private final int optionalOpenOffset;
     private final int optionalCloseOffset;
-    public FormalParameters(List<DartParameter> parameters, int optionalOpenOffset,
+    public FormalParameters(List<DartParameter> parameters, int openParen, int optionalOpenOffset,
         int optionalCloseOffset) {
       this.val = parameters;
+      this.openParen = openParen;
       this.optionalOpenOffset = optionalOpenOffset;
       this.optionalCloseOffset = optionalCloseOffset;
     }
@@ -2105,6 +2112,7 @@
     int optionalCloseOffset = -1;
     expect(Token.LPAREN);
     boolean done = optional(Token.RPAREN);
+    int openParen = ctx.getTokenLocation().getBegin();
     boolean isOptional = false;
     boolean isNamed = false;
     while (!done) {
@@ -2152,7 +2160,7 @@
       }
     }
 
-    return new FormalParameters(done(params), optionalOpenOffset, optionalCloseOffset);
+    return new FormalParameters(done(params), openParen, optionalOpenOffset, optionalCloseOffset);
   }
 
   /**
@@ -2553,11 +2561,11 @@
     beginBinaryExpression();
     DartExpression lastResult = parseUnaryExpression();
     DartExpression result = lastResult;
-    for (int level = peek(0).getPrecedence(); level >= precedence; level--) {
-      while (peek(0).getPrecedence() == level) {
+    for (int level = peekMaybeAS(0).getPrecedence(); level >= precedence; level--) {
+      while (peekMaybeAS(0).getPrecedence() == level) {
         int prevPositionStart = ctx.getTokenLocation().getBegin();
         int prevPositionEnd = ctx.getTokenLocation().getEnd();
-        Token token = next();
+        Token token = nextMaybeAS();
         int tokenOffset = ctx.getTokenLocation().getBegin();
         if (lastResult instanceof DartSuperExpression
             && (token == Token.AND || token == Token.OR)) {
@@ -2598,7 +2606,7 @@
             || token.isRelationalOperator()
             || token.isEqualityOperator()) {
           // The operations cannot be chained.
-          if (match(token)) {
+          if (peekMaybeAS(0) == token) {
             reportError(position(), ParserErrorCode.INVALID_OPERATOR_CHAINING,
               token.toString().toLowerCase());
           }
@@ -2611,6 +2619,35 @@
   }
 
   /**
+   * Use this method where token "as" is expected to be used as built-in identifier.
+   * 
+   * @return the {@link Token} at given position or {@link Token#AS}.
+   */
+  private Token peekMaybeAS(int n) {
+    Token token = ctx.peek(n);
+    String tokenString = ctx.peekTokenString(n);
+    if (token == Token.IDENTIFIER && "as".equals(tokenString)) {
+      return Token.AS;
+    }
+    return token;
+  }
+
+  /**
+   * Use this method where token "as" is expected to be used as built-in identifier.
+   * 
+   * @return the current {@link Token} or {@link Token#AS}.
+   */
+  private Token nextMaybeAS() {
+    ctx.advance();
+    Token token = ctx.getCurrentToken();
+    String tokenString = ctx.getTokenString();
+    if (token == Token.IDENTIFIER && "as".equals(tokenString)) {
+      return Token.AS;
+    }
+    return token;
+  }
+
+  /**
    * Parse the arguments passed to a function or method invocation.
    *
    * <pre>
@@ -3638,8 +3675,9 @@
     FormalParameters params = parseFormalParameterList();
     int parametersCloseParen = ctx.getTokenLocation().getBegin();
     DartBlock body = parseFunctionStatementBody(true, isDeclaration);
-    DartFunction function = new DartFunction(params.val, params.optionalOpenOffset,
-        params.optionalCloseOffset, parametersCloseParen, body, returnType);
+    DartFunction function = new DartFunction(params.val, params.openParen,
+        params.optionalOpenOffset, params.optionalCloseOffset, parametersCloseParen, body,
+        returnType);
     doneWithoutConsuming(function);
     return function;
   }
@@ -4372,16 +4410,15 @@
         }
         break;
 
-      case AS:
       case IDENTIFIER:
         // We have already eliminated function declarations earlier, so check for:
         // a) variable declarations;
         // b) beginning of function literal invocation.
-        if (peek(1) == Token.LT || peek(1) == Token.IDENTIFIER
+        if (peek(1) == Token.LT || peekMaybeAS(1) == Token.IDENTIFIER
             || (peek(1) == Token.PERIOD && peek(2) == Token.IDENTIFIER)) {
           beginTypeFunctionOrVariable();
           DartTypeNode type = tryTypeAnnotation();
-          if (type != null && peek(0) == Token.IDENTIFIER) {
+          if (type != null && peekMaybeAS(0) == Token.IDENTIFIER) {
             List<DartVariable> vars = parseInitializedVariableList();
             if (optional(Token.SEMICOLON)) {
               return done(new DartVariableStatement(vars, type));
@@ -5325,7 +5362,7 @@
   }
 
   private DartTypeNode tryTypeAnnotation() {
-    if (peek(0) != Token.IDENTIFIER && peek(0) != Token.AS) {
+    if (peek(0) != Token.IDENTIFIER) {
       return null;
     }
     List<DartTypeNode> typeArguments = new ArrayList<DartTypeNode>();
@@ -5334,7 +5371,7 @@
     DartNode qualified = parseQualified(false);
 
     if (optional(Token.LT)) {
-      if (peek(0) != Token.IDENTIFIER && peek(0) != Token.AS) {
+      if (peek(0) != Token.IDENTIFIER) {
         rollback();
         return null;
       }
@@ -5375,10 +5412,6 @@
 
   private DartIdentifier parseIdentifier() {
     beginIdentifier();
-    if (peek(0) == Token.AS) {
-      next();
-      return done(new DartIdentifier("as"));
-    }
     if (looksLikeTopLevelKeyword()) {
       reportErrorWithoutAdvancing(ParserErrorCode.EXPECTED_IDENTIFIER);
       return done(new DartSyntheticErrorIdentifier());
@@ -5490,4 +5523,17 @@
   private boolean currentlyParsingToplevel() {
     return   !(isParsingInterface || isTopLevelAbstract || isParsingClass);
   }
+  
+  /**
+   * @return <code>true</code> if current token is built-in identifier which can have special
+   * meaning. For example if it is used as import prefix, this is not special meaning, this is just
+   * normal identifier.
+   */
+  private boolean isBuiltInSpecial() {
+    Token nextToken = peek(1);
+    if (nextToken == Token.LT) {
+      return peek(2) != Token.IDENTIFIER;
+    }
+    return nextToken != Token.PERIOD && nextToken != Token.LPAREN;
+  }
 }
diff --git a/compiler/java/com/google/dart/compiler/parser/Token.java b/compiler/java/com/google/dart/compiler/parser/Token.java
index 59b754e..74e211d 100644
--- a/compiler/java/com/google/dart/compiler/parser/Token.java
+++ b/compiler/java/com/google/dart/compiler/parser/Token.java
@@ -179,6 +179,9 @@
    */
   public static Token lookup(String syntax) {
     Token token = tokens.get(syntax);
+    if ("as".equals(syntax)) {
+      return IDENTIFIER;
+    }
     if (token == null) {
       return IDENTIFIER;
     }
diff --git a/compiler/java/com/google/dart/compiler/resolver/LibraryElementImplementation.java b/compiler/java/com/google/dart/compiler/resolver/LibraryElementImplementation.java
index baffee0..3e2c49c 100644
--- a/compiler/java/com/google/dart/compiler/resolver/LibraryElementImplementation.java
+++ b/compiler/java/com/google/dart/compiler/resolver/LibraryElementImplementation.java
@@ -18,7 +18,7 @@
   private final Map<String, Element> exportedElements = Maps.newHashMap();
   private LibraryUnit libraryUnit;
   private MethodElement entryPoint;
-  private DartObsoleteMetadata metadata;
+  private DartObsoleteMetadata metadata = DartObsoleteMetadata.EMPTY;
 
   public LibraryElementImplementation(LibraryUnit libraryUnit) {
     // TODO(ngeoffray): What should we pass the super? Should a LibraryUnit be a node?
diff --git a/compiler/java/com/google/dart/compiler/resolver/ResolutionContext.java b/compiler/java/com/google/dart/compiler/resolver/ResolutionContext.java
index ee9743b77..b29e6bd 100644
--- a/compiler/java/com/google/dart/compiler/resolver/ResolutionContext.java
+++ b/compiler/java/com/google/dart/compiler/resolver/ResolutionContext.java
@@ -203,7 +203,8 @@
     // Built-in identifier can not be used as a type annotation.
     if (identifier instanceof DartIdentifier) {
       String name = ((DartIdentifier) identifier).getName();
-      if (DartParser.PSEUDO_KEYWORDS_SET.contains(name) && !"dynamic".equals(name)) {
+      if (DartParser.PSEUDO_KEYWORDS_SET.contains(name) && !"dynamic".equals(name)
+          && typeArguments.isEmpty()) {
         onError(identifier, ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, name);
         return Types.newDynamicType();
       }
@@ -223,6 +224,7 @@
       }
       case CLASS:
       case FUNCTION_TYPE_ALIAS:
+      case DYNAMIC:
         return instantiateParameterizedType(
             (ClassElement) element,
             diagnosticNode,
@@ -243,13 +245,9 @@
         onError(identifier, duplicateErrorCode, element.getName(), locations.size(), locations);
         return typeProvider.getDynamicType();
       }
+      case VOID:
+        return typeProvider.getVoidType();
       case NONE:
-        if (Elements.isIdentifierName(identifier, "void")) {
-          return typeProvider.getVoidType();
-        }
-        if (Elements.isIdentifierName(identifier, "dynamic")) {
-          return typeProvider.getDynamicType();
-        }
         onError(identifier, errorCode, identifier);
         return typeProvider.getDynamicType();
       default:
@@ -315,6 +313,12 @@
    * Interpret this node as a name reference,
    */
   Element resolveName(DartNode node) {
+    if (Elements.isIdentifierName(node, "void")) {
+      return typeProvider.getVoidType().getElement();
+    }
+    if (Elements.isIdentifierName(node, "dynamic")) {
+      return typeProvider.getDynamicType().getElement();
+    }
     return node.accept(new Selector());
   }
 
diff --git a/compiler/java/com/google/dart/compiler/resolver/Resolver.java b/compiler/java/com/google/dart/compiler/resolver/Resolver.java
index 89ed7f1..28b7b86 100644
--- a/compiler/java/com/google/dart/compiler/resolver/Resolver.java
+++ b/compiler/java/com/google/dart/compiler/resolver/Resolver.java
@@ -1233,8 +1233,15 @@
     @Override
     public Element visitSuperConstructorInvocation(DartSuperConstructorInvocation x) {
       visit(x.getArguments());
-      String name = x.getName() == null ? "" : x.getName().getName();
+      // check if correct place for super()
+      if (ElementKind.of(currentHolder) != ElementKind.CLASS || currentMethod == null
+          || !currentMethod.isConstructor()) {
+        onError(x, ResolverErrorCode.SUPER_OUTSIDE_OF_CONSTRUCTOR);
+        return recordElement(x, null);
+      }
       InterfaceType supertype = ((ClassElement) currentHolder).getSupertype();
+      // prepare ConstructorElement
+      String name = x.getName() == null ? "" : x.getName().getName();
       ConstructorElement element;
       if (supertype == null) {
         element = null;
@@ -1252,6 +1259,9 @@
       if (element == null) {
         onError(x, ResolverErrorCode.CANNOT_RESOLVE_SUPER_CONSTRUCTOR, name);
       }
+      if (x.getName() != null) {
+        recordElement(x.getName(), element);
+      }
       return recordElement(x, element);
     }
 
diff --git a/compiler/java/com/google/dart/compiler/resolver/ResolverErrorCode.java b/compiler/java/com/google/dart/compiler/resolver/ResolverErrorCode.java
index c2cefc9..9d4a623 100644
--- a/compiler/java/com/google/dart/compiler/resolver/ResolverErrorCode.java
+++ b/compiler/java/com/google/dart/compiler/resolver/ResolverErrorCode.java
@@ -14,7 +14,6 @@
   BLACK_LISTED_EXTENDS("'%s' can not be used as superclass"),
   BLACK_LISTED_IMPLEMENTS("'%s' can not be used as superinterface"),
   BREAK_LABEL_RESOLVES_TO_CASE_OR_DEFAULT("break label resolves to case or default statement"),
-  BUILT_IN_IDENTIFIER_AS_IMPORT_PREFIX("Built-in identifier '%s' cannot be used as a import prefix"),
   BUILT_IN_IDENTIFIER_AS_TYPE("Built-in identifier '%s' cannot be used as a type annotation"),
   CANNOT_ACCESS_FIELD_IN_INIT("Cannot access an instance field in an initializer expression"),
   CANNOT_ACCESS_METHOD(ErrorSeverity.WARNING, "Cannot access private method '%s'"),
@@ -46,7 +45,7 @@
   CANNOT_RESOLVE_METHOD_IN_LIBRARY("cannot resolve method '%s' in library '%s'"),
   // TODO(zundel): To exercise this requires simulating a corrupted SDK?
   CANNOT_RESOLVE_SDK_TYPE("cannot resolve SDK type %s"),
-  CANNOT_RESOLVE_SUPER_CONSTRUCTOR("cannot resolve method '%s'"),
+  CANNOT_RESOLVE_SUPER_CONSTRUCTOR("cannot resolve super constructor '%s'"),
   CANNOT_RESOLVE_IMPLICIT_CALL_TO_SUPER_CONSTRUCTOR(
       "super type %s does not have a default constructor"),
   CANNOT_USE_INSTANCE_FIELD_IN_INSTANCE_FIELD_INITIALIZER(
@@ -118,7 +117,7 @@
   // TODO(zundel): error message needs JUnit test (reachable code?)
   EXPECTED_STATIC_FIELD("expected a static field, but got %s"),
   // TODO(zundel): error message needs JUnit test, (reachable code?)
-  EXTRA_TYPE_ARGUMENT("Type variables may not have type arguments"),
+  EXTRA_TYPE_ARGUMENT(ErrorSeverity.WARNING, "Type variables may not have type arguments"),
   FACTORY_CANNOT_BE_CONST("A factory cannot be const"),
   FIELD_DOES_NOT_HAVE_A_GETTER(ErrorSeverity.WARNING, "Field does not have a getter"),
   FIELD_DOES_NOT_HAVE_A_SETTER(ErrorSeverity.WARNING, "Field does not have a setter"),
@@ -198,8 +197,10 @@
   RETHROW_NOT_IN_CATCH("Re-throw not in a catch block"),
   STATIC_FINAL_REQUIRES_VALUE("Static final fields must have an initial value"),
   STATIC_METHOD_MUST_HAVE_BODY("Static method must have a body"),
+  SUPER_CLASS_IN_IMPLEMENTS("Superclass in implements clause"),
   SUPER_IN_FACTORY_CONSTRUCTOR("Cannot use 'super' in a factory constructor"),
   SUPER_IN_STATIC_METHOD("Cannot use 'super' in a static method"),
+  SUPER_OUTSIDE_OF_CONSTRUCTOR("Cannot use 'super' constructor outside of a constructor"),
   SUPER_OUTSIDE_OF_METHOD("Cannot use 'super' outside of a method"),
   SUPER_ON_TOP_LEVEL("Cannot use 'super' in a top-level element"),
   SWITCH_CASE_FALL_THROUGH(ErrorSeverity.WARNING, "Switch case should end with break, continue, return or throw"),
diff --git a/compiler/java/com/google/dart/compiler/resolver/SupertypeResolver.java b/compiler/java/com/google/dart/compiler/resolver/SupertypeResolver.java
index 0aef7bc..6e1b911 100644
--- a/compiler/java/com/google/dart/compiler/resolver/SupertypeResolver.java
+++ b/compiler/java/com/google/dart/compiler/resolver/SupertypeResolver.java
@@ -4,6 +4,7 @@
 
 package com.google.dart.compiler.resolver;
 
+import com.google.common.base.Objects;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
 import com.google.dart.compiler.DartCompilerContext;
@@ -111,6 +112,10 @@
               topLevelContext.onError(intNode, ResolverErrorCode.DUPLICATE_IMPLEMENTS_TYPE);
               continue;
             }
+            if (Objects.equal(intType, supertype)) {
+              topLevelContext.onError(intNode, ResolverErrorCode.SUPER_CLASS_IN_IMPLEMENTS);
+              continue;
+            }
             seenImplement.add(intType);
           }
           // OK, add
diff --git a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
index 1f2e102..fa1bc57 100644
--- a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
+++ b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
@@ -125,6 +125,7 @@
 import com.google.dart.compiler.type.InterfaceType.Member;
 import com.google.dart.compiler.util.apache.ObjectUtils;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
@@ -1016,8 +1017,8 @@
         setVariableElementType(variable, mergedType, mergedTypeQuality);
       }
     }
-
-    private boolean checkAssignable(DartNode node, Type t, Type s) {
+    
+    private boolean isAssignable(Type t, Type s) {
       t.getClass(); // Null check.
       s.getClass(); // Null check.
       // ignore inferred types, treat them as Dynamic
@@ -1026,15 +1027,18 @@
           return true;
         }
       }
-      // do check and report error
-      if (!types.isAssignable(t, s)) {
+      // do check
+      return types.isAssignable(t, s);
+    }
+
+    private boolean checkAssignable(DartNode node, Type t, Type s) {
+      if (!isAssignable(t, s)) {
         TypeErrorCode errorCode = TypeQuality.isInferred(t) || TypeQuality.isInferred(s)
             ? TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE_INFERRED
-            : TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE;
+                : TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE;
         typeError(node, errorCode, s, t);
         return false;
       }
-      // OK
       return true;
     }
 
@@ -2809,7 +2813,7 @@
           case DYNAMIC:
             return type;
           default:
-            if (types.isAssignable(functionType, type)) {
+            if (isAssignable(functionType, type)) {
               // A subtype of interface Function.
               return dynamicType;
             } else if (name == null || currentClass == null) {
@@ -3163,7 +3167,6 @@
         // cull out duplicate elements in the supertype list - inheriting more than one interface
         // of the same type is valid.
         Set<ClassElement> typesForAbstractMembers = Sets.newHashSet();
-        typesForAbstractMembers.add(currentClass.getElement());
         for (InterfaceType supertype : supertypes) {
           typesForAbstractMembers.add(supertype.getElement());
         }
@@ -3230,7 +3233,9 @@
         }
 
         // All remaining methods are unimplemented.
-        for (String name : superMembers.keys()) {
+        List<String> keys = new ArrayList<String>(superMembers.keys());
+        for (int i = 0; i < keys.size(); i++) {
+          String name = keys.get(i);
           Collection<Element> elements = superMembers.removeAll(name);
           for (Element element : elements) {
             if (!element.getModifiers().isStatic()) {
@@ -3350,7 +3355,6 @@
                   case FIELD:
                     typeError(node.getName(), TypeErrorCode.SUPERTYPE_HAS_FIELD, superElement.getName(),
                         superElement.getEnclosingElement().getName());
-
                     break;
 
                   default:
diff --git a/compiler/java/com/google/dart/compiler/type/Types.java b/compiler/java/com/google/dart/compiler/type/Types.java
index 8ec7a88..021ec43 100644
--- a/compiler/java/com/google/dart/compiler/type/Types.java
+++ b/compiler/java/com/google/dart/compiler/type/Types.java
@@ -24,6 +24,7 @@
 import com.google.dart.compiler.resolver.ResolutionErrorListener;
 import com.google.dart.compiler.resolver.TypeVariableElement;
 import com.google.dart.compiler.resolver.VariableElement;
+import com.google.dart.compiler.type.InterfaceType.Member;
 
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
@@ -309,9 +310,15 @@
       }
       return true;
     }
-    if (t.getKind().equals(TypeKind.FUNCTION_ALIAS)) {
+    if (t.getKind() == TypeKind.FUNCTION_ALIAS) {
       return isSubtypeOfFunction(asFunctionType((FunctionAliasType) t), asFunctionType(s));
     }
+    // class has method call()
+    if (t.getKind() == TypeKind.INTERFACE) {
+      InterfaceType ti = (InterfaceType) t;
+      Member callMember = ti.lookupMember("call");
+      return callMember != null && isSubtype(callMember.getType(), asFunctionType(s));
+    }
     return false;
   }
 
@@ -349,9 +356,18 @@
       return false;
     }
 
+    // class "t" implements call() and "s" is Function
+    if (TypeKind.of(t) == TypeKind.INTERFACE && typeProvider != null
+        && s == typeProvider.getFunctionType()) {
+      InterfaceType ti = (InterfaceType) t;
+      if (ti.lookupMember("call") != null) {
+        return true;
+      }
+    }
+
     // Try to cast "t" to "s".
     final Type sup = asInstanceOf(t, s.getElement());
-    if (TypeKind.of(sup).equals(TypeKind.INTERFACE)) {
+    if (TypeKind.of(sup) == TypeKind.INTERFACE) {
       InterfaceType ti = (InterfaceType) sup;
       assert ti.getElement().equals(s.getElement());
       if (ti.isRaw() || s.isRaw()) {
@@ -520,6 +536,7 @@
         InterfaceType ti = (InterfaceType) t;
         ClassElement tElement = ti.getElement();
         InterfaceType supertype = tElement.getSupertype();
+        // super type
         if (supertype != null) {
           InterfaceType result = checkedAsInstanceOf(asSupertype(ti, supertype), element,
                                                      variablesReferenced, checkedTypes);
@@ -527,6 +544,7 @@
             return result;
           }
         }
+        // interfaces
         for (InterfaceType intrface : tElement.getInterfaces()) {
           InterfaceType result = checkedAsInstanceOf(asSupertype(ti, intrface), element,
                                                      variablesReferenced, checkedTypes);
@@ -534,6 +552,7 @@
             return result;
           }
         }
+        // no
         return null;
       }
       case FUNCTION: {
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilation2Test.java b/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilation2Test.java
index 157cb23..87a941c 100644
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilation2Test.java
+++ b/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilation2Test.java
@@ -1585,8 +1585,10 @@
   /**
    * <p>
    * http://code.google.com/p/dart/issues/detail?id=3531
+   * <p>
+   * Revised 2012-12-12 - specification has no rule about import prefix and built-in identifier.
    */
-  public void test_builtInIdentifier_asTypeAnnotation() throws Exception {
+  public void test_builtInIdentifier_asImportPrefix() throws Exception {
     appSource.setContent(
         "A.dart",
         makeCode(
@@ -1619,12 +1621,7 @@
             ""));
     // do compile, no errors expected
     compile();
-    {
-      assertEquals(15, errors.size());
-      for (DartCompilationError error : errors) {
-        assertEquals(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_IMPORT_PREFIX, error.getErrorCode());
-      }
-    }
+    assertEquals(0, errors.size());
   }
   
   public void test_implicitlyImportCore() throws Exception {
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/ResolverTest.java b/compiler/javatests/com/google/dart/compiler/resolver/ResolverTest.java
index bcad2fa..29826f4 100644
--- a/compiler/javatests/com/google/dart/compiler/resolver/ResolverTest.java
+++ b/compiler/javatests/com/google/dart/compiler/resolver/ResolverTest.java
@@ -463,6 +463,18 @@
         TypeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS);
   }
 
+  public void test_variableStatement_typeArgumentsForDynamic() throws Exception {
+    resolveAndTest(
+        Joiner.on("\n").join(
+            "class Object {}",
+            "class MyClass {",
+            "  bar() {",
+            "    dynamic<Object> v1;",
+            "  }",
+            "}"),
+        TypeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS);
+  }
+
   public void test_noSuchType_classExtends() throws Exception {
     resolveAndTest(Joiner.on("\n").join(
         "class Object {}",
diff --git a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
index 9f8cd3c..4dc6872 100644
--- a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
+++ b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
@@ -31,12 +31,15 @@
 import com.google.dart.compiler.ast.DartNewExpression;
 import com.google.dart.compiler.ast.DartNode;
 import com.google.dart.compiler.ast.DartPropertyAccess;
+import com.google.dart.compiler.ast.DartSuperConstructorInvocation;
 import com.google.dart.compiler.ast.DartTypeNode;
 import com.google.dart.compiler.ast.DartUnaryExpression;
 import com.google.dart.compiler.ast.DartUnit;
 import com.google.dart.compiler.ast.DartUnqualifiedInvocation;
 import com.google.dart.compiler.parser.ParserErrorCode;
 import com.google.dart.compiler.resolver.ClassElement;
+import com.google.dart.compiler.resolver.ConstructorElement;
+import com.google.dart.compiler.resolver.ConstructorNodeElement;
 import com.google.dart.compiler.resolver.Element;
 import com.google.dart.compiler.resolver.ElementKind;
 import com.google.dart.compiler.resolver.EnclosingElement;
@@ -158,6 +161,44 @@
   }
 
   /**
+   * If a type I includes a method named call(), and the type of call() is the function type F, then
+   * I is considered to be a subtype of F.
+   * <p>
+   * http://code.google.com/p/dart/issues/detail?id=7271
+   */
+  public void test_classWithCallMethod_isFunction() throws Exception {
+    AnalyzeLibraryResult libraryResult = analyzeLibrary(
+        "// filler filler filler filler filler filler filler filler filler filler",
+        "class X {",
+        "  call() => 42;",
+        "}",
+        "",
+        "class Y {",
+        "  call(int x) => 87;",
+        "}",
+        "",
+        "typedef F(int x);",
+        "typedef G(String y);",
+        "",
+        "main() {",
+        "  X x = new X();",
+        "  Y y = new Y();",
+        "  Function f = x;", // OK
+        "  Function g = y;", // OK
+        "  F f0 = x;", // WARN
+        "  F f1 = y;", // OK
+        "  G g0 = x;", // WARN
+        "  G g1 = y;", // WARN
+        "}",
+        "");
+    assertErrors(
+        libraryResult.getErrors(),
+        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 18, 10, 1),
+        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 20, 10, 1),
+        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 21, 10, 1));
+  }
+
+  /**
    * It is a compile-time error if a typedef refers to itself via a chain of references that does
    * not include a class or interface type.
    * <p>
@@ -4295,6 +4336,20 @@
         errEx(TypeErrorCode.NOT_A_FUNCTION_TYPE, 11, 3, 9));
   }
   
+  /**
+   * <p>
+   * http://code.google.com/p/dart/issues/detail?id=3223
+   */
+  public void test_invokeNonFunction_inferred() throws Exception {
+    AnalyzeLibraryResult libraryResult = analyzeLibrary(
+        "// filler filler filler filler filler filler filler filler filler filler",
+        "method() {",
+        "  var v = 1;",
+        "  v();",
+        "}");
+    assertErrors(libraryResult.getErrors());
+  }
+  
   public void test_invokeNonFunction_getter() throws Exception {
     AnalyzeLibraryResult libraryResult = analyzeLibrary(
         "// filler filler filler filler filler filler filler filler filler filler",
@@ -5295,6 +5350,20 @@
   }
   
   /**
+   * It is a compile-time error if the superclass of a class C appears in the implements clause of C.
+   * <p>
+   * http://code.google.com/p/dart/issues/detail?id=7469
+   */
+  public void test_superClass_imImplementsClause() throws Exception {
+    AnalyzeLibraryResult result = analyzeLibrary(
+        "// filler filler filler filler filler filler filler filler filler filler",
+        "class A {}",
+        "class B extends A implements A {}",
+        "");
+    assertErrors(result.getErrors(), errEx(ResolverErrorCode.SUPER_CLASS_IN_IMPLEMENTS, 3, 30, 1));
+  }
+  
+  /**
    * We should report only "no such type", but not duplicate.
    * <p>
    * http://code.google.com/p/dart/issues/detail?id=5084
@@ -5394,6 +5463,18 @@
     assertClassMembers(superElements, "method A.foo");
   }
 
+  public void test_getOverridden_methodAbstract() throws Exception {
+    analyzeLibrary(
+        "// filler filler filler filler filler filler filler filler filler filler",
+        "class A {",
+        "  foo();",
+        "}",
+        "");
+    DartMethodDefinition node = findNode(DartMethodDefinition.class, "foo();");
+    Set<Element> superElements = node.getElement().getOverridden();
+    assertTrue(superElements.isEmpty());
+  }
+
   public void test_getOverridden_field_withGetterSetter() throws Exception {
     analyzeLibrary(
         "// filler filler filler filler filler filler filler filler filler filler",
@@ -6016,4 +6097,78 @@
     assertErrors(result.getErrors(),
         errEx(TypeErrorCode.FOR_IN_WITH_INVALID_ITERATOR_RETURN_TYPE, 7, 17, 1));
   }
+
+  public void test_builtInIdentifier_asType() throws Exception {
+    AnalyzeLibraryResult result = analyzeLibrary(
+        "// filler filler filler filler filler filler filler filler filler filler",
+        "main() {",
+        "  abstract v_abstract;",
+        "}",
+        "");
+    assertErrors(result.getErrors(),
+        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 3, 3, 8));
+  }
+
+  public void test_builtInIdentifier_asParameterizedType() throws Exception {
+    AnalyzeLibraryResult result = analyzeLibrary(
+        "// filler filler filler filler filler filler filler filler filler filler",
+        "main() {",
+        "  abstract<int> v_01;",
+        "  as<int> v_02;",
+        "  export<int> v_03;",
+        "  external<int> v_04;",
+        "  factory<int> v_05;",
+        "  get<int> v_06;",
+        "  implements<int> v_07;",
+        "  import<int> v_08;",
+        "  library<int> v_09;",
+        "  operator<int> v_q0;",
+        "  part<int> v_11;",
+        "  set<int> v_12;",
+        "  static<int> v_13;",
+        "  typedef<int> v_14;",
+        "}",
+        "");
+    List<DartCompilationError> errors = result.getErrors();
+    assertEquals(14, errors.size());
+    for (DartCompilationError error : errors) {
+      assertSame(TypeErrorCode.NO_SUCH_TYPE, error.getErrorCode());
+      assertEquals(3, error.getColumnNumber());
+    }
+  }
+
+  public void test_superConstructorInvocation_wrongPlace() throws Exception {
+    AnalyzeLibraryResult result = analyzeLibrary(
+        "// filler filler filler filler filler filler filler filler filler filler",
+        "topLevelMethod() : super() {}",
+        "",
+        "class A {",
+        "  m() : super() {}",
+        "}",
+        "");
+    assertErrors(
+        result.getErrors(),
+        errEx(ResolverErrorCode.SUPER_OUTSIDE_OF_CONSTRUCTOR, 2, 20, 7),
+        errEx(ResolverErrorCode.SUPER_OUTSIDE_OF_CONSTRUCTOR, 5, 9, 7));
+  }
+
+  /**
+   * Test that we set {@link ConstructorElement} for {@link DartSuperConstructorInvocation}.
+   */
+  public void test_superConstructorInvocation_resolveElement() throws Exception {
+    analyzeLibrary(
+        "// filler filler filler filler filler filler filler filler filler filler",
+        "abstract class A {",
+        "  A.named() {}",
+        "}",
+        "abstract class B extends A {",
+        "  B() : super.named();",
+        "}",
+        "");
+    DartIdentifier nameInInvocation = findNode(DartIdentifier.class, "named();");
+    DartSuperConstructorInvocation invocation = (DartSuperConstructorInvocation) nameInInvocation.getParent();
+    ConstructorNodeElement expectedElement = invocation.getElement();
+    assertNotNull(expectedElement);
+    assertSame(nameInInvocation.getElement(), expectedElement);
+  }
 }
diff --git a/compiler/javatests/com/google/dart/compiler/type/TypeTestCase.java b/compiler/javatests/com/google/dart/compiler/type/TypeTestCase.java
index 8dee845..fae289a 100644
--- a/compiler/javatests/com/google/dart/compiler/type/TypeTestCase.java
+++ b/compiler/javatests/com/google/dart/compiler/type/TypeTestCase.java
@@ -82,7 +82,7 @@
 
     DartMethodDefinition iteratorMethod = DartMethodDefinition.create(
         new DartIdentifier("iterator"), new DartFunction(Collections.<DartParameter> emptyList(),
-            -1, -1, 0, new DartBlock(Collections.<DartStatement> emptyList()), returnTypeNode),
+            -1, -1, -1, 0, new DartBlock(Collections.<DartStatement> emptyList()), returnTypeNode),
         Modifiers.NONE, Collections.<DartInitializer> emptyList());
     MethodNodeElement iteratorMethodElement = Elements.methodFromMethodNode(iteratorMethod, element);
     Type returnType = Types.interfaceType(iterElement, Arrays.<Type>asList(typeVar));
diff --git a/compiler/scripts/dart_analyzer.bat b/compiler/scripts/dart_analyzer.bat
index 4653020..acdb4ca 100644
--- a/compiler/scripts/dart_analyzer.bat
+++ b/compiler/scripts/dart_analyzer.bat
@@ -13,7 +13,7 @@
 if %SCRIPT_DIR:~-1%==\ set SCRIPT_DIR=%SCRIPT_DIR:~0,-1%

 

 rem DART_ANALYZER_HOME=$(dirname $SCRIPT_DIR)

-for /f %%i in ('echo %SCRIPT_DIR%') do set DART_ANALYZER_HOME=%%~dpi

+for %%I in ("%SCRIPT_DIR%\..") do set "DART_ANALYZER_HOME=%%~fI"

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

 

 set FOUND_BATCH=0

@@ -45,7 +45,7 @@
 set DART_SDK=""

 if [%FOUND_SDK%] == [0] (

   if exist "%DART_ANALYZER_HOME%\lib\core\core.dart" (

-    set DART_SDK=--dart-sdk %DART_ANALYZER_HOME%

+    set DART_SDK=--dart-sdk "%DART_ANALYZER_HOME%"

   ) else (

     for /f %%i in ('echo %DART_ANALYZER_HOME%') do set DART_SDK_HOME=%%~dpi\dart-sdk

     if exist "!DART_SDK_HOME!" (

diff --git a/dart.gyp b/dart.gyp
index b426feb..72827a0 100644
--- a/dart.gyp
+++ b/dart.gyp
@@ -35,6 +35,7 @@
       'dependencies': [
         'runtime/dart-runtime.gyp:dart',
         'utils/compiler/compiler.gyp:dart2js',
+        'compiler',
       ],
       'actions': [
         {
@@ -45,6 +46,7 @@
             'tools/create_sdk.py',
             '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
             '<(PRODUCT_DIR)/dart2js.snapshot',
+            '<(PRODUCT_DIR)/analyzer/bin/dart_analyzer',
           ],
           'outputs': [
             '<(PRODUCT_DIR)/dart-sdk/README',
@@ -55,22 +57,8 @@
             '<(PRODUCT_DIR)/dart-sdk',
           ],
           'message': 'Creating SDK.',
-          'conditions' : [
-            ['(OS=="linux" or OS=="mac") ', {
-              'inputs' : [
-                '<(PRODUCT_DIR)/analyzer/bin/dart_analyzer'
-              ],
-            }],
-          ],
         },
       ],
-      'conditions' : [
-        ['(OS=="linux" or OS=="mac") ', {
-          'dependencies': [
-            'compiler',
-          ],
-        }],
-      ],
     },
     {
       # Upload the SDK. This target is separate from create_sdk as the
diff --git a/pkg/args/test/args_test.dart b/pkg/args/test/args_test.dart
index 728ff7d..11627f3 100644
--- a/pkg/args/test/args_test.dart
+++ b/pkg/args/test/args_test.dart
@@ -4,8 +4,7 @@
 
 library args_test;
 
-import '../../../pkg/unittest/lib/unittest.dart';
-
+import 'package:unittest/unittest.dart';
 import 'package:args/args.dart';
 
 main() {
@@ -188,47 +187,47 @@
         var args = parser.parse([]);
         expect(a, isNull);
       });
-      
+
       test('for multiple present, allowMultiple, options are invoked with '
            'value as a list', () {
         var a;
         var parser = new ArgParser();
-        parser.addOption('a', allowMultiple: true, 
+        parser.addOption('a', allowMultiple: true,
             callback: (value) => a = value);
-          
+
         var args = parser.parse(['--a=v', '--a=x']);
         expect(a, equals(['v', 'x']));
       });
-      
+
       test('for single present, allowMultiple, options are invoked with '
            ' value as a single element list', () {
         var a;
         var parser = new ArgParser();
         parser.addOption('a', allowMultiple: true,
             callback: (value) => a = value);
-        
+
         var args = parser.parse(['--a=v']);
         expect(a, equals(['v']));
       });
-      
+
       test('for absent, allowMultiple, options are invoked with default '
            'value as a list.', () {
         var a;
         var parser = new ArgParser();
         parser.addOption('a', allowMultiple: true, defaultsTo: 'v',
             callback: (value) => a = value);
-        
+
         var args = parser.parse([]);
         expect(a, equals(['v']));
       });
-      
+
       test('for absent, allowMultiple, options are invoked with value '
            'as an empty list.', () {
         var a;
         var parser = new ArgParser();
         parser.addOption('a', allowMultiple: true,
             callback: (value) => a = value);
-        
+
         var args = parser.parse([]);
         expect(a, isEmpty);
       });
diff --git a/pkg/fixnum/test/int_32_test.dart b/pkg/fixnum/test/int_32_test.dart
index e719fa6..dea6621 100644
--- a/pkg/fixnum/test/int_32_test.dart
+++ b/pkg/fixnum/test/int_32_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library int32test;
-import '../lib/fixnum.dart';
+import 'package:fixnum/fixnum.dart';
 
 void main() {
   Expect.equals("0", new int32.fromInt(0).toString());
diff --git a/pkg/fixnum/test/int_64_test.dart b/pkg/fixnum/test/int_64_test.dart
index f41f45c..a4e2537 100644
--- a/pkg/fixnum/test/int_64_test.dart
+++ b/pkg/fixnum/test/int_64_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library int64test;
-import '../lib/fixnum.dart';
+import 'package:fixnum/fixnum.dart';
 
 void main() {
   testAdditive();
diff --git a/pkg/http/lib/src/client.dart b/pkg/http/lib/src/client.dart
index d60df93..229429f 100644
--- a/pkg/http/lib/src/client.dart
+++ b/pkg/http/lib/src/client.dart
@@ -5,11 +5,13 @@
 library client;
 
 import 'dart:io';
+import 'dart:scalarlist';
 
 import 'base_client.dart';
 import 'base_request.dart';
 import 'io_client.dart';
 import 'streamed_response.dart';
+import 'response.dart';
 import 'utils.dart';
 
 /// The interface for HTTP clients that take care of maintaining persistent
diff --git a/pkg/http/lib/src/multipart_request.dart b/pkg/http/lib/src/multipart_request.dart
index b9adf9c..3cd0dc4 100644
--- a/pkg/http/lib/src/multipart_request.dart
+++ b/pkg/http/lib/src/multipart_request.dart
@@ -81,7 +81,7 @@
   InputStream finalize() {
     // TODO(nweiz): freeze fields and files
     var boundary = _boundaryString(_BOUNDARY_LENGTH);
-    headers['content-type'] = 'multipart/form-data, boundary="$boundary"';
+    headers['content-type'] = 'multipart/form-data; boundary="$boundary"';
     headers['content-transfer-encoding'] = 'binary';
     super.finalize();
 
diff --git a/pkg/http/lib/src/streamed_request.dart b/pkg/http/lib/src/streamed_request.dart
index 3570541..fac5151 100644
--- a/pkg/http/lib/src/streamed_request.dart
+++ b/pkg/http/lib/src/streamed_request.dart
@@ -34,10 +34,11 @@
     : super(method, url),
       stream = new ListOutputStream(),
       _inputStream = new ListInputStream() {
+    ListOutputStream outputStream = stream;
     // TODO(nweiz): pipe errors from the output stream to the input stream once
     // issue 3657 is fixed
-    stream.onData = () => _inputStream.write(stream.read());
-    stream.onClosed = _inputStream.markEndOfStream;
+    outputStream.onData = () => _inputStream.write(outputStream.read());
+    outputStream.onClosed = _inputStream.markEndOfStream;
   }
 
   /// Freezes all mutable fields other than [stream] and returns an [InputStream]
diff --git a/pkg/http/test/client_test.dart b/pkg/http/test/client_test.dart
index 673ba1d..009f147 100644
--- a/pkg/http/test/client_test.dart
+++ b/pkg/http/test/client_test.dart
@@ -6,9 +6,9 @@
 
 import 'dart:io';
 
-import '../../unittest/lib/unittest.dart';
-import '../lib/http.dart' as http;
-import '../lib/src/utils.dart';
+import 'package:unittest/unittest.dart';
+import 'package:http/http.dart' as http;
+import 'package:http/src/utils.dart';
 import 'utils.dart';
 
 void main() {
diff --git a/pkg/http/test/http_test.dart b/pkg/http/test/http_test.dart
index 9085171..d9ffa7d 100644
--- a/pkg/http/test/http_test.dart
+++ b/pkg/http/test/http_test.dart
@@ -6,8 +6,8 @@
 
 import 'dart:io';
 
-import '../../unittest/lib/unittest.dart';
-import '../lib/http.dart' as http;
+import 'package:unittest/unittest.dart';
+import 'package:http/http.dart' as http;
 import 'utils.dart';
 
 main() {
@@ -32,6 +32,7 @@
           'method': 'GET',
           'path': '/',
           'headers': {
+            'content-length': ['0'],
             'x-random-header': ['Value'],
             'x-other-header': ['Other Value']
           },
@@ -55,11 +56,11 @@
             'content-type': [
               'application/x-www-form-urlencoded; charset=UTF-8'
             ],
-            'content-length': ['42'],
+            'content-length': ['40'],
             'x-random-header': ['Value'],
             'x-other-header': ['Other Value']
           },
-          'body': 'some-field=value&other-field=other%20value'
+          'body': 'some-field=value&other-field=other+value'
         })));
       }), completes);
     });
@@ -75,6 +76,7 @@
           'method': 'POST',
           'path': '/',
           'headers': {
+            'content-length': ['0'],
             'content-type': ['text/plain'],
             'x-random-header': ['Value'],
             'x-other-header': ['Other Value']
@@ -99,11 +101,11 @@
             'content-type': [
               'application/x-www-form-urlencoded; charset=UTF-8'
             ],
-            'content-length': ['42'],
+            'content-length': ['40'],
             'x-random-header': ['Value'],
             'x-other-header': ['Other Value']
           },
-          'body': 'some-field=value&other-field=other%20value'
+          'body': 'some-field=value&other-field=other+value'
         })));
       }), completes);
     });
@@ -119,6 +121,7 @@
           'method': 'PUT',
           'path': '/',
           'headers': {
+            'content-length': ['0'],
             'content-type': ['text/plain'],
             'x-random-header': ['Value'],
             'x-other-header': ['Other Value']
@@ -137,6 +140,7 @@
           'method': 'DELETE',
           'path': '/',
           'headers': {
+            'content-length': ['0'],
             'x-random-header': ['Value'],
             'x-other-header': ['Other Value']
           }
@@ -152,6 +156,7 @@
         'method': 'GET',
         'path': '/',
         'headers': {
+          'content-length': ['0'],
           'x-random-header': ['Value'],
           'x-other-header': ['Other Value']
         },
@@ -172,6 +177,7 @@
         'method': 'GET',
         'path': '/',
         'headers': {
+          'content-length': ['0'],
           'x-random-header': ['Value'],
           'x-other-header': ['Other Value']
         },
diff --git a/pkg/http/test/mock_client_test.dart b/pkg/http/test/mock_client_test.dart
index 44d5161..2dab7be 100644
--- a/pkg/http/test/mock_client_test.dart
+++ b/pkg/http/test/mock_client_test.dart
@@ -8,11 +8,10 @@
 import 'dart:json';
 import 'dart:uri';
 
-// TODO(nweiz): make these "package:" imports.
-import '../../unittest/lib/unittest.dart';
-import '../lib/http.dart' as http;
-import '../lib/testing.dart';
-import '../lib/src/utils.dart';
+import 'package:unittest/unittest.dart';
+import 'package:http/http.dart' as http;
+import 'package:http/testing.dart';
+import 'package:http/src/utils.dart';
 import 'utils.dart';
 
 void main() {
diff --git a/pkg/http/test/multipart_test.dart b/pkg/http/test/multipart_test.dart
index 136dfa0..abbd509 100644
--- a/pkg/http/test/multipart_test.dart
+++ b/pkg/http/test/multipart_test.dart
@@ -9,10 +9,9 @@
 
 // TODO(nweiz): get rid of this import before packaging this
 import '../../../tests/utils/test_utils.dart';
-// TODO(nweiz): make these package: imports
-import '../../unittest/lib/unittest.dart';
-import '../lib/http.dart' as http;
-import '../lib/src/utils.dart';
+import 'package:unittest/unittest.dart';
+import 'package:http/http.dart' as http;
+import 'package:http/src/utils.dart';
 
 import 'utils.dart';
 
@@ -183,7 +182,7 @@
         content-type: application/octet-stream
         content-disposition: form-data; name="file"
 
-        
+
         --{{boundary}}--
         '''));
   });
diff --git a/pkg/http/test/request_test.dart b/pkg/http/test/request_test.dart
index 1b3d4ca..bb4cdb0 100644
--- a/pkg/http/test/request_test.dart
+++ b/pkg/http/test/request_test.dart
@@ -6,9 +6,9 @@
 
 import 'dart:io';
 
-import '../../unittest/lib/unittest.dart';
-import '../lib/http.dart' as http;
-import '../lib/src/utils.dart';
+import 'package:unittest/unittest.dart';
+import 'package:http/http.dart' as http;
+import 'package:http/src/utils.dart';
 import 'utils.dart';
 
 void main() {
@@ -21,9 +21,9 @@
       expect(response.statusCode, equals(200));
       return consumeInputStream(response.stream);
     }).transform((bytes) => new String.fromCharCodes(bytes));
-    future.onComplete((_) {
+    future.onComplete(expectAsync1((_) {
       stopServer();
-    });
+    }));
 
     expect(future, completion(parse(equals({
       'method': 'POST',
@@ -196,11 +196,11 @@
       print("#followRedirects test response received");
       expect(response.statusCode, equals(302));
     });
-    future.onComplete((_) {
+    future.onComplete(expectAsync1((_) {
       print("#followRedirects test stopping server...");
       stopServer();
       print("#followRedirects test server stopped");
-    });
+    }));
 
     expect(future, completes);
     print("#followRedirects test started");
@@ -220,11 +220,11 @@
       expect(e, isRedirectLimitExceededException);
       expect(e.redirects.length, equals(2));
     });
-    future.onComplete((_) {
+    future.onComplete(expectAsync1((_) {
       print("#maxRedirects test stopping server...");
       stopServer();
       print("#maxRedirects test server stopped");
-    });
+    }));
 
     expect(future, completes);
     print("#maxRedirects test started");
diff --git a/pkg/http/test/response_test.dart b/pkg/http/test/response_test.dart
index 6062dab..04d3f3b 100644
--- a/pkg/http/test/response_test.dart
+++ b/pkg/http/test/response_test.dart
@@ -6,8 +6,8 @@
 
 import 'dart:io';
 
-import '../../unittest/lib/unittest.dart';
-import '../lib/http.dart' as http;
+import 'package:unittest/unittest.dart';
+import 'package:http/http.dart' as http;
 
 void main() {
   group('()', () {
diff --git a/pkg/http/test/streamed_request_test.dart b/pkg/http/test/streamed_request_test.dart
index e71d50b..4ded631 100644
--- a/pkg/http/test/streamed_request_test.dart
+++ b/pkg/http/test/streamed_request_test.dart
@@ -6,8 +6,8 @@
 
 import 'dart:io';
 
-import '../../unittest/lib/unittest.dart';
-import '../lib/http.dart' as http;
+import 'package:unittest/unittest.dart';
+import 'package:http/http.dart' as http;
 import 'utils.dart';
 
 void main() {
diff --git a/pkg/http/test/utils.dart b/pkg/http/test/utils.dart
index 3548df0..89440f8 100644
--- a/pkg/http/test/utils.dart
+++ b/pkg/http/test/utils.dart
@@ -2,15 +2,15 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library utils;
+library test_utils;
 
 import 'dart:io';
 import 'dart:json';
 import 'dart:uri';
 
-import '../../unittest/lib/unittest.dart';
-import '../lib/http.dart' as http;
-import '../lib/src/utils.dart';
+import 'package:unittest/unittest.dart';
+import 'package:http/http.dart' as http;
+import 'package:http/src/utils.dart';
 
 /// The current server instance.
 HttpServer _server;
diff --git a/pkg/intl/lib/bidi_utils.dart b/pkg/intl/lib/bidi_utils.dart
index 7a8d728..f6cb86c 100644
--- a/pkg/intl/lib/bidi_utils.dart
+++ b/pkg/intl/lib/bidi_utils.dart
@@ -244,11 +244,11 @@
       var startIndex = 0;
       Match match = new RegExp('<\\w+').firstMatch(html);
       if (match != null) {
-        buffer.add(html.substring(
-            startIndex, match.end)).add(' dir=$direction');
+        buffer..add(html.substring(startIndex, match.end))
+              ..add(' dir=$direction');
         startIndex = match.end;
       }
-      return buffer.add(html.substring(startIndex)).toString();
+      return (buffer..add(html.substring(startIndex))).toString();
     }
     // '\n' is important for FF so that it won't incorrectly merge span groups.
     return '\n<span dir=$direction>$html</span>';
@@ -298,11 +298,13 @@
     var startIndex = 0;
     Iterable matches = regexp.allMatches(str);
     for (Match match in matches) {
-      buffer.add(str.substring(startIndex, match.start)).add(before);
-      buffer.add(str.substring(match.start, match.end)).add(after);
+      buffer..add(str.substring(startIndex, match.start))
+            ..add(before)
+            ..add(str.substring(match.start, match.end))
+            ..add(after);
       startIndex = match.end;
     }
-    return buffer.add(str.substring(startIndex)).toString();
+    return (buffer..add(str.substring(startIndex))).toString();
   }
 
   /**
diff --git a/pkg/intl/lib/date_format.dart b/pkg/intl/lib/date_format.dart
index 299132b..9168488 100644
--- a/pkg/intl/lib/date_format.dart
+++ b/pkg/intl/lib/date_format.dart
@@ -4,18 +4,46 @@
 
 part of intl;
 
+// TODO(efortuna): Customized pattern system -- suggested by i18n needs
+// feedback on appropriateness.
 /**
  * DateFormat is for formatting and parsing dates in a locale-sensitive
  * manner.
  * It allows the user to choose from a set of standard date time formats as well
  * as specify a customized pattern under certain locales. Date elements that
  * vary across locales include month name, week name, field order, etc.
- * <!-- TODO(efortuna): Customized pattern system -- suggested by i18n needs
- * feedback on appropriateness. -->
  * We also allow the user to use any customized pattern to parse or format
  * date-time strings under certain locales. Date elements that vary across
  * locales include month name, weekname, field, order, etc.
  *
+ * The actual date for the locales must be obtained. This can currently be done
+ * in one of three ways, determined by which library you import. If you only
+ * want to use en_US formatting you can use it directly, as a copy of that
+ * locale is hard-coded into the formatter. In all other cases,
+ * the [initializeDateFormatting] method must be called and will return a future
+ * that is complete once the locale data is available. The result of the future
+ * isn't important, but the data for that locale is available to the date
+ * formatting and parsing once it completes.
+ *
+ * The easiest option is that the data may be available locally, imported in a
+ * library that contains data for all the locales.
+ *       import 'package:intl/date_symbol_data_local.dart';
+ *       initializeDateFormatting("en_US", null).then((_) => runMyCode());
+ *
+ * If we are running outside of a browser, we may want to read the data
+ * from files in the file system.
+ *       import 'package:intl/date_symbol_data_file.dart';
+ *       initializeDateFormatting("de_DE", null).then((_) => runMyCode());
+ *
+ * If we are running in a browser, we may want to read the data from the
+ * server using the XmlHttpRequest mechanism.
+ *       import 'package:intl/date_symbol_data_http_request.dart';
+ *       initializeDateFormatting("pt_BR", null).then((_) => runMyCode());
+ *
+ * The code in example/basic/basic_example.dart shows a full example of
+ * using this mechanism.
+ *
+ * Once we have the locale data, we need to specify the particular format.
  * This library uses the ICU/JDK date/time pattern specification both for
  * complete format specifications and also the abbreviated "skeleton" form
  * which can also adapt to different locales and is preferred where available.
diff --git a/pkg/intl/lib/date_symbols.dart b/pkg/intl/lib/date_symbols.dart
index acbd988..cd0b9d2 100644
--- a/pkg/intl/lib/date_symbols.dart
+++ b/pkg/intl/lib/date_symbols.dart
@@ -112,4 +112,93 @@
   }
 
   toString() => NAME;
-}
\ No newline at end of file
+}
+
+/**
+ * We hard-code the locale data for en_US here so that there's at least one
+ * locale always available.
+ */
+var en_USSymbols = new DateSymbols(
+    NAME: "en_US",
+    ERAS: const [ 'BC', 'AD'],
+    ERANAMES: const [ 'Before Christ', 'Anno Domini'],
+    NARROWMONTHS: const [ 'J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O',
+         'N', 'D'],
+    STANDALONENARROWMONTHS: const [ 'J', 'F', 'M', 'A', 'M', 'J', 'J', 'A',
+         'S', 'O', 'N', 'D'],
+    MONTHS: const [ 'January', 'February', 'March', 'April', 'May', 'June',
+         'July', 'August', 'September', 'October', 'November', 'December'],
+    STANDALONEMONTHS: const [ 'January', 'February', 'March', 'April', 'May',
+         'June', 'July', 'August', 'September', 'October', 'November',
+         'December'],
+    SHORTMONTHS: const [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul',
+         'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
+    STANDALONESHORTMONTHS: const [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
+         'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
+    WEEKDAYS: const [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday',
+         'Friday', 'Saturday'],
+    STANDALONEWEEKDAYS: const [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday',
+         'Thursday', 'Friday', 'Saturday'],
+    SHORTWEEKDAYS: const [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
+    STANDALONESHORTWEEKDAYS: const [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri',
+         'Sat'],
+    NARROWWEEKDAYS: const [ 'S', 'M', 'T', 'W', 'T', 'F', 'S'],
+    STANDALONENARROWWEEKDAYS: const [ 'S', 'M', 'T', 'W', 'T', 'F', 'S'],
+    SHORTQUARTERS: const [ 'Q1', 'Q2', 'Q3', 'Q4'],
+    QUARTERS: const [ '1st quarter', '2nd quarter', '3rd quarter',
+         '4th quarter'],
+    AMPMS: const [ 'AM', 'PM'],
+    DATEFORMATS: const [ 'EEEE, MMMM d, y', 'MMMM d, y', 'MMM d, y',
+         'M/d/yy'],
+    TIMEFORMATS: const [ 'h:mm:ss a zzzz', 'h:mm:ss a z', 'h:mm:ss a',
+         'h:mm a'],
+    FIRSTDAYOFWEEK: 6,
+    WEEKENDRANGE: const [5, 6],
+    FIRSTWEEKCUTOFFDAY: 5);
+
+var en_USPatterns = const {
+  'd': 'd', // DAY
+  'E': 'EEE', // ABBR_WEEKDAY
+  'EEEE': 'EEEE', // WEEKDAY
+  'LLL': 'LLL', // ABBR_STANDALONE_MONTH
+  'LLLL': 'LLLL', // STANDALONE_MONTH
+  'M': 'L', // NUM_MONTH
+  'Md': 'M/d', // NUM_MONTH_DAY
+  'MEd': 'EEE, M/d', // NUM_MONTH_WEEKDAY_DAY
+  'MMM': 'LLL', // ABBR_MONTH
+  'MMMd': 'MMM d', // ABBR_MONTH_DAY
+  'MMMEd': 'EEE, MMM d', // ABBR_MONTH_WEEKDAY_DAY
+  'MMMM': 'LLLL', // MONTH
+  'MMMMd': 'MMMM d', // MONTH_DAY
+  'MMMMEEEEd': 'EEEE, MMMM d', // MONTH_WEEKDAY_DAY
+  'QQQ': 'QQQ', // ABBR_QUARTER
+  'QQQQ': 'QQQQ', // QUARTER
+  'y': 'y', // YEAR
+  'yM': 'M/y', // YEAR_NUM_MONTH
+  'yMd': 'M/d/y', // YEAR_NUM_MONTH_DAY
+  'yMEd': 'EEE, M/d/y', // YEAR_NUM_MONTH_WEEKDAY_DAY
+  'yMMM': 'MMM y', // YEAR_ABBR_MONTH
+  'yMMMd': 'MMM d, y', // YEAR_ABBR_MONTH_DAY
+  'yMMMEd': 'EEE, MMM d, y', // YEAR_ABBR_MONTH_WEEKDAY_DAY
+  'yMMMM': 'MMMM y', // YEAR_MONTH
+  'yMMMMd': 'MMMM d, y', // YEAR_MONTH_DAY
+  'yMMMMEEEEd': 'EEEE, MMMM d, y', // YEAR_MONTH_WEEKDAY_DAY
+  'yQQQ': 'QQQ y', // YEAR_ABBR_QUARTER
+  'yQQQQ': 'QQQQ y', // YEAR_QUARTER
+  'H': 'HH', // HOUR24
+  'Hm': 'HH:mm', // HOUR24_MINUTE
+  'Hms': 'HH:mm:ss', // HOUR24_MINUTE_SECOND
+  'j': 'h a', // HOUR
+  'jm': 'h:mm a', // HOUR_MINUTE
+  'jms': 'h:mm:ss a', // HOUR_MINUTE_SECOND
+  'jmv': 'h:mm a v', // HOUR_MINUTE_GENERIC_TZ
+  'jmz': 'h:mm a z', // HOUR_MINUTETZ
+  'jz': 'h a z', // HOURGENERIC_TZ
+  'm': 'm', // MINUTE
+  'ms': 'mm:ss', // MINUTE_SECOND
+  's': 's', // SECOND
+  'v': 'v', // ABBR_GENERIC_TZ
+  'z': 'z', // ABBR_SPECIFIC_TZ
+  'zzzz': 'zzzz', // SPECIFIC_TZ
+  'ZZZZ': 'ZZZZ'  // ABBR_UTC_TZ
+};
\ No newline at end of file
diff --git a/pkg/intl/lib/src/date_format_internal.dart b/pkg/intl/lib/src/date_format_internal.dart
index 9205dfb..55be767 100644
--- a/pkg/intl/lib/src/date_format_internal.dart
+++ b/pkg/intl/lib/src/date_format_internal.dart
@@ -14,6 +14,7 @@
 
 library date_format_internal;
 import 'intl_helpers.dart';
+import '../date_symbols.dart';
 
 /**
  * This holds the symbols to be used for date/time formatting, indexed
@@ -23,7 +24,8 @@
  * result in an informative error message.
  */
 var dateTimeSymbols =
-    const UninitializedLocaleData('initializeDateFormatting(<locale>)');
+    new UninitializedLocaleData('initializeDateFormatting(<locale>)',
+        en_USSymbols);
 
 /**
  * This holds the patterns used for date/time formatting, indexed
@@ -33,7 +35,8 @@
  * result in an informative error message.
  */
 var dateTimePatterns =
-    const UninitializedLocaleData('initializeDateFormatting(<locale>)');
+    new UninitializedLocaleData('initializeDateFormatting(<locale>)',
+        en_USPatterns);
 
 /**
  * Initialize the symbols dictionary. This should be passed a function that
diff --git a/pkg/intl/lib/src/intl_helpers.dart b/pkg/intl/lib/src/intl_helpers.dart
index 128acd8..12c8395 100644
--- a/pkg/intl/lib/src/intl_helpers.dart
+++ b/pkg/intl/lib/src/intl_helpers.dart
@@ -8,20 +8,22 @@
  */
 
 library intl_helpers;
+import '../date_symbols.dart';
 
 /**
  * This is used as a marker for a locale data map that hasn't been initialized,
- * and will throw an exception on any usage.
+ * and will throw an exception on any usage that isn't the fallback
+ * patterns/symbols provided.
  */
-class UninitializedLocaleData {
+class UninitializedLocaleData<F> {
   final String message;
-  const UninitializedLocaleData(this.message);
+  final F fallbackData;
+  const UninitializedLocaleData(this.message, this.fallbackData);
 
-  operator [](String key) {
-    _throwException();
-  }
+  operator [](String key) =>
+      (key == 'en_US') ? fallbackData : _throwException();
   List get keys => _throwException();
-  bool containsKey(String key) => _throwException();
+  bool containsKey(String key) => (key == 'en_US') ? true : _throwException();
 
   _throwException() {
     throw new LocaleDataException("Locale data has not been initialized"
@@ -48,7 +50,7 @@
  * implementation.
  */
 var messageLookup = const
-    UninitializedLocaleData('initializeMessages(<locale>)');
+    UninitializedLocaleData('initializeMessages(<locale>)', null);
 
 /**
  * Initialize the message lookup mechanism. This is for internal use only.
diff --git a/pkg/intl/test/date_time_format_test_core.dart b/pkg/intl/test/date_time_format_test_core.dart
index ef13882..f03e0265 100644
--- a/pkg/intl/test/date_time_format_test_core.dart
+++ b/pkg/intl/test/date_time_format_test_core.dart
@@ -227,11 +227,14 @@
   test('Test ALL the supported formats on representative locales', () {
     var aDate = new Date(2012, 1, 27, 20, 58, 59, 0);
     testLocale("en_US", English, aDate);
-    testLocale("de_DE", German, aDate);
-    testLocale("fr_FR", French, aDate);
-    testLocale("ja_JP", Japanese, aDate);
-    testLocale("el_GR", Greek, aDate);
-    testLocale("de_AT", Austrian, aDate);
+    if (subset.length > 1) {
+      // Don't run if we have just one locale, so some of these won't be there.
+      testLocale("de_DE", German, aDate);
+      testLocale("fr_FR", French, aDate);
+      testLocale("ja_JP", Japanese, aDate);
+      testLocale("el_GR", Greek, aDate);
+      testLocale("de_AT", Austrian, aDate);
+    }
   });
 
   test('Test round-trip parsing of dates', () {
@@ -251,6 +254,9 @@
   });
 
   test('Patterns and symbols have the same coverage',() {
+    // Don't run if we have just one locale, so checking coverage isn't
+    // very meaningful.
+    if (subset.length <= 1) return;
     var patterns = new List.from(dateTimePatterns.keys);
     var compare = (a, b) => a.compareTo(b);
     patterns.sort(compare);
@@ -265,6 +271,8 @@
   });
 
   test('Test malformed locales', () {
+    // Don't run if we have just one locale, which may not include these.
+    if (subset.length <= 1) return;
     var aDate = new Date(2012, 1, 27, 20, 58, 59, 0);
     // Austrian is a useful test locale here because it differs slightly
     // from the generic "de" locale so we can tell the difference between
@@ -275,6 +283,8 @@
   });
 
   test('Test format creation via Intl', () {
+    // Don't run if we have just one locale, which may not include these.
+    if (subset.length <= 1) return;
     var intl = new Intl('ja_JP');
     var instanceJP = intl.date('jms');
     var instanceUS = intl.date('jms', 'en_US');
@@ -286,6 +296,8 @@
   });
 
   test('Test explicit format string', () {
+    // Don't run if we have just one locale, which may not include these.
+    if (subset.length <= 1) return;
     var aDate = new Date(2012, 1, 27, 20, 58, 59, 0);
     // An explicit format that doesn't conform to any skeleton
     var us = new DateFormat(r'yy //// :D \\\\ dd:ss ^&@ M');
diff --git a/pkg/intl/test/date_time_format_uninitialized_test.dart b/pkg/intl/test/date_time_format_uninitialized_test.dart
new file mode 100644
index 0000000..afbeb23
--- /dev/null
+++ b/pkg/intl/test/date_time_format_uninitialized_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+/**
+ * Tests date formatting and parsing using locale data read from the
+ * local file system.
+ */
+library date_time_format_file_test;
+
+import '../lib/intl.dart';
+import '../lib/date_symbol_data_local.dart';
+import 'date_time_format_test_core.dart';
+import '../../../pkg/unittest/lib/unittest.dart';
+
+main() {
+  runDateTests(['en_US']);
+}
diff --git a/pkg/logging/test/logging_test.dart b/pkg/logging/test/logging_test.dart
index fe1c4f0..6444e3a 100644
--- a/pkg/logging/test/logging_test.dart
+++ b/pkg/logging/test/logging_test.dart
@@ -5,9 +5,8 @@
 
 library logging_test;
 
-// TODO(rnystrom): Use "package:" import when test.dart supports it (#4968).
-import '../lib/logging.dart';
-import '../../../pkg/unittest/lib/unittest.dart';
+import 'package:logging/logging.dart';
+import 'package:unittest/unittest.dart';
 
 main() {
   test('level comparison is a valid comparator', () {
diff --git a/pkg/oauth2/test/authorization_code_grant_test.dart b/pkg/oauth2/test/authorization_code_grant_test.dart
index c4ccc21..2b80cf4 100644
--- a/pkg/oauth2/test/authorization_code_grant_test.dart
+++ b/pkg/oauth2/test/authorization_code_grant_test.dart
@@ -50,7 +50,7 @@
               '?response_type=code'
               '&client_id=identifier'
               '&redirect_uri=http%3A%2F%2Fexample.com%2Fredirect'
-              '&scope=scope%20other%2Fscope'));
+              '&scope=scope+other%2Fscope'));
     });
 
     test('builds the correct URL with state', () {
diff --git a/utils/pub/path.dart b/pkg/path/lib/path.dart
similarity index 90%
rename from utils/pub/path.dart
rename to pkg/path/lib/path.dart
index 593396d0..99eee7b 100644
--- a/utils/pub/path.dart
+++ b/pkg/path/lib/path.dart
@@ -28,12 +28,20 @@
 ///
 ///     path.basename('path/to/foo.dart'); // -> 'foo.dart'
 ///     path.basename('path/to');          // -> 'to'
+///
+/// Trailing separators are ignored.
+///
+///     builder.dirname('path/to/'); // -> 'to'
 String basename(String path) => _builder.basename(path);
 
 /// Gets the part of [path] after the last separator, and without any trailing
 /// file extension.
 ///
 ///     path.basenameWithoutExtension('path/to/foo.dart'); // -> 'foo'
+///
+/// Trailing separators are ignored.
+///
+///     builder.dirname('path/to/foo.dart/'); // -> 'foo'
 String basenameWithoutExtension(String path) =>
     _builder.basenameWithoutExtension(path);
 
@@ -41,6 +49,10 @@
 ///
 ///     path.dirname('path/to/foo.dart'); // -> 'path/to'
 ///     path.dirname('path/to');          // -> 'to'
+///
+/// Trailing separators are ignored.
+///
+///     builder.dirname('path/to/'); // -> 'path'
 String dirname(String path) => _builder.dirname(path);
 
 /// Gets the file extension of [path]: the portion of [basename] from the last
@@ -190,30 +202,41 @@
   ///
   ///     builder.basename('path/to/foo.dart'); // -> 'foo.dart'
   ///     builder.basename('path/to');          // -> 'to'
+  ///
+  /// Trailing separators are ignored.
+  ///
+  ///     builder.dirname('path/to/'); // -> 'to'
   String basename(String path) => _parse(path).basename;
 
   /// Gets the part of [path] after the last separator on the builder's
   /// platform, and without any trailing file extension.
   ///
   ///     builder.basenameWithoutExtension('path/to/foo.dart'); // -> 'foo'
+  ///
+  /// Trailing separators are ignored.
+  ///
+  ///     builder.dirname('path/to/foo.dart/'); // -> 'foo'
   String basenameWithoutExtension(String path) =>
-      _parse(path).basenameWithoutExtension;
+    _parse(path).basenameWithoutExtension;
 
   /// Gets the part of [path] before the last separator.
   ///
   ///     builder.dirname('path/to/foo.dart'); // -> 'path/to'
-  ///     builder.dirname('path/to');          // -> 'to'
+  ///     builder.dirname('path/to');          // -> 'path'
+  ///
+  /// Trailing separators are ignored.
+  ///
+  ///     builder.dirname('path/to/'); // -> 'path'
   String dirname(String path) {
     var parsed = _parse(path);
+    parsed.removeTrailingSeparators();
     if (parsed.parts.isEmpty) return parsed.root == null ? '.' : parsed.root;
-    if (!parsed.hasTrailingSeparator) {
-      if (parsed.parts.length == 1) {
-        return parsed.root == null ? '.' : parsed.root;
-      }
-      parsed.parts.removeLast();
-      parsed.separators.removeLast();
+    if (parsed.parts.length == 1) {
+      return parsed.root == null ? '.' : parsed.root;
     }
-    parsed.separators[parsed.separators.length - 1] = '';
+    parsed.parts.removeLast();
+    parsed.separators.removeLast();
+    parsed.removeTrailingSeparators();
     return parsed.toString();
   }
 
@@ -294,7 +317,7 @@
         buffer.clear();
         buffer.add(part);
       } else {
-        if (part.length > 0 && style.separatorPattern.hasMatch(part[0])) {
+        if (part.length > 0 && part[0].contains(style.separatorPattern)) {
           // The part starts with a separator, so we don't need to add one.
         } else if (needsSeparator) {
           buffer.add(separator);
@@ -306,7 +329,7 @@
       // Unless this part ends with a separator, we'll need to add one before
       // the next part.
       needsSeparator = part.length > 0 &&
-          !style.separatorPattern.hasMatch(part[part.length - 1]);
+          !part[part.length - 1].contains(style.separatorPattern);
     }
 
     return buffer.toString();
@@ -440,7 +463,7 @@
 
     // Make it relative.
     pathParsed.root = '';
-    pathParsed.removeTrailingSeparator();
+    pathParsed.removeTrailingSeparators();
 
     return pathParsed.toString();
   }
@@ -450,10 +473,12 @@
   ///     builder.withoutExtension('path/to/foo.dart'); // -> 'path/to/foo'
   String withoutExtension(String path) {
     var parsed = _parse(path);
-    if (parsed.hasTrailingSeparator) return parsed.toString();
 
-    if (!parsed.parts.isEmpty) {
-      parsed.parts[parsed.parts.length - 1] = parsed.basenameWithoutExtension;
+    for (var i = parsed.parts.length - 1; i >= 0; i--) {
+      if (!parsed.parts[i].isEmpty) {
+        parsed.parts[i] = parsed.basenameWithoutExtension;
+        break;
+      }
     }
 
     return parsed.toString();
@@ -517,9 +542,10 @@
   /// "\" is the canonical one.
   final Pattern separatorPattern;
 
-  /// The [Pattern] that can be used to match the root prefix of an absolute
+  // TODO(nweiz): make this a Pattern when issue 7080 is fixed.
+  /// The [RegExp] that can be used to match the root prefix of an absolute
   /// path in this style.
-  final Pattern _rootPattern;
+  final RegExp _rootPattern;
 
   /// Gets the root prefix of [path] if path is absolute. If [path] is relative,
   /// returns `null`.
@@ -554,29 +580,31 @@
   /// The file extension of the last part, or "" if it doesn't have one.
   String get extension => _splitExtension()[1];
 
-  /// `true` if the path ends with a trailing separator.
-  bool get hasTrailingSeparator {
-    if (separators.length == 0) return false;
-    return separators[separators.length - 1] != '';
-  }
-
   /// `true` if this is an absolute path.
   bool get isAbsolute => root != null;
 
   _ParsedPath(this.style, this.root, this.parts, this.separators);
 
   String get basename {
-    if (parts.length == 0) return extension;
-    if (hasTrailingSeparator) return '';
-    return parts.last;
+    var copy = this.clone();
+    copy.removeTrailingSeparators();
+    if (copy.parts.isEmpty) return root == null ? '' : root;
+    return copy.parts.last;
   }
 
-  String get basenameWithoutExtension => _splitExtension()[0];
+  String get basenameWithoutExtension {
+    var copy = this.clone();
+    copy.removeTrailingSeparators();
+    if (copy.parts.isEmpty) return root == null ? '' : root;
+    return copy._splitExtension()[0];
+  }
 
-  void removeTrailingSeparator() {
-    if (separators.length > 0) {
-      separators[separators.length - 1] = '';
+  void removeTrailingSeparators() {
+    while (!parts.isEmpty && parts.last == '') {
+      parts.removeLast();
+      separators.removeLast();
     }
+    if (separators.length > 0) separators[separators.length - 1] = '';
   }
 
   void normalize() {
@@ -616,7 +644,7 @@
     parts = newParts;
     separators = newSeparators;
 
-    removeTrailingSeparator();
+    removeTrailingSeparators();
   }
 
   String toString() {
@@ -635,7 +663,6 @@
   /// or "" if it has none.
   List<String> _splitExtension() {
     if (parts.isEmpty) return ['', ''];
-    if (hasTrailingSeparator) return ['', ''];
 
     var file = parts.last;
     if (file == '..') return ['..', ''];
@@ -648,4 +675,7 @@
 
     return [file.substring(0, lastDot), file.substring(lastDot)];
   }
+
+  _ParsedPath clone() => new _ParsedPath(
+      style, root, new List.from(parts), new List.from(separators));
 }
diff --git a/pkg/path/pubspec.yaml b/pkg/path/pubspec.yaml
new file mode 100644
index 0000000..3372302
--- /dev/null
+++ b/pkg/path/pubspec.yaml
@@ -0,0 +1,10 @@
+name: pathos
+author: "Dart Team <misc@dartlang.org>"
+homepage: http://www.dartlang.org
+description: >
+ A string-based path manipulation library. All of the path operations you know
+ and love, with solid support on both Windows and POSIX (Linux and Mac OS X)
+ machines.
+
+ Currently only runs on the standalone VM, but will run in a browser as soon as
+ configuration-specific code is supported by Dart.
diff --git a/utils/tests/pub/path/path_posix_test.dart b/pkg/path/test/path_posix_test.dart
similarity index 92%
rename from utils/tests/pub/path/path_posix_test.dart
rename to pkg/path/test/path_posix_test.dart
index 60ed65a..e1c3942 100644
--- a/utils/tests/pub/path/path_posix_test.dart
+++ b/pkg/path/test/path_posix_test.dart
@@ -6,8 +6,8 @@
 
 import 'dart:io' as io;
 
-import '../../../../pkg/unittest/lib/unittest.dart';
-import '../../../pub/path.dart' as path;
+import 'package:unittest/unittest.dart';
+import 'package:path/path.dart' as path;
 
 main() {
   var builder = new path.Builder(style: path.Style.posix, root: '/root/path');
@@ -47,14 +47,18 @@
     expect(builder.dirname('a/b'), 'a');
     expect(builder.dirname('a/b/c'), 'a/b');
     expect(builder.dirname('a/b.c'), 'a');
-    expect(builder.dirname('a/'), 'a');
+    expect(builder.dirname('a/'), '.');
     expect(builder.dirname('a/.'), 'a');
     expect(builder.dirname(r'a\b/c'), r'a\b');
     expect(builder.dirname('/a'), '/');
+    expect(builder.dirname('///a'), '/');
     expect(builder.dirname('/'), '/');
-    expect(builder.dirname('a/b/'), 'a/b');
+    expect(builder.dirname('///'), '/');
+    expect(builder.dirname('a/b/'), 'a');
     expect(builder.dirname(r'a/b\c'), 'a');
-    expect(builder.dirname('a//'), 'a/');
+    expect(builder.dirname('a//'), '.');
+    expect(builder.dirname('a/b//'), 'a');
+    expect(builder.dirname('a//b'), 'a');
   });
 
   test('basename', () {
@@ -63,15 +67,16 @@
     expect(builder.basename('a/b'), 'b');
     expect(builder.basename('a/b/c'), 'c');
     expect(builder.basename('a/b.c'), 'b.c');
-    expect(builder.basename('a/'), '');
+    expect(builder.basename('a/'), 'a');
     expect(builder.basename('a/.'), '.');
     expect(builder.basename(r'a\b/c'), 'c');
     expect(builder.basename('/a'), 'a');
-    // TODO(nweiz): this should actually return '/'
-    expect(builder.basename('/'), '');
-    expect(builder.basename('a/b/'), '');
+    expect(builder.basename('/'), '/');
+    expect(builder.basename('a/b/'), 'b');
     expect(builder.basename(r'a/b\c'), r'b\c');
-    expect(builder.basename('a//'), '');
+    expect(builder.basename('a//'), 'a');
+    expect(builder.basename('a/b//'), 'b');
+    expect(builder.basename('a//b'), 'b');
   });
 
   test('basenameWithoutExtension', () {
@@ -80,11 +85,16 @@
     expect(builder.basenameWithoutExtension('a/b'), 'b');
     expect(builder.basenameWithoutExtension('a/b/c'), 'c');
     expect(builder.basenameWithoutExtension('a/b.c'), 'b');
-    expect(builder.basenameWithoutExtension('a/'), '');
+    expect(builder.basenameWithoutExtension('a/'), 'a');
     expect(builder.basenameWithoutExtension('a/.'), '.');
     expect(builder.basenameWithoutExtension(r'a/b\c'), r'b\c');
     expect(builder.basenameWithoutExtension('a/.bashrc'), '.bashrc');
     expect(builder.basenameWithoutExtension('a/b/c.d.e'), 'c.d');
+    expect(builder.basenameWithoutExtension('a//'), 'a');
+    expect(builder.basenameWithoutExtension('a/b//'), 'b');
+    expect(builder.basenameWithoutExtension('a//b'), 'b');
+    expect(builder.basenameWithoutExtension('a/b.c/'), 'b');
+    expect(builder.basenameWithoutExtension('a/b.c//'), 'b');
   });
 
   test('isAbsolute', () {
@@ -357,5 +367,7 @@
     expect(builder.withoutExtension(r'a.b\c'), r'a');
     expect(builder.withoutExtension(r'a/b\c'), r'a/b\c');
     expect(builder.withoutExtension(r'a/b\c.d'), r'a/b\c');
+    expect(builder.withoutExtension('a/b.c/'), 'a/b/');
+    expect(builder.withoutExtension('a/b.c//'), 'a/b//');
   });
 }
diff --git a/utils/tests/pub/path/path_test.dart b/pkg/path/test/path_test.dart
similarity index 94%
rename from utils/tests/pub/path/path_test.dart
rename to pkg/path/test/path_test.dart
index 26812a1..eea906a 100644
--- a/utils/tests/pub/path/path_test.dart
+++ b/pkg/path/test/path_test.dart
@@ -6,8 +6,8 @@
 
 import 'dart:io' as io;
 
-import '../../../../pkg/unittest/lib/unittest.dart';
-import '../../../pub/path.dart' as path;
+import 'package:unittest/unittest.dart';
+import 'package:path/path.dart' as path;
 
 main() {
   group('path.Style', () {
diff --git a/utils/tests/pub/path/path_windows_test.dart b/pkg/path/test/path_windows_test.dart
similarity index 92%
rename from utils/tests/pub/path/path_windows_test.dart
rename to pkg/path/test/path_windows_test.dart
index fdad9b0..c3ee6fb 100644
--- a/utils/tests/pub/path/path_windows_test.dart
+++ b/pkg/path/test/path_windows_test.dart
@@ -6,8 +6,8 @@
 
 import 'dart:io' as io;
 
-import '../../../../pkg/unittest/lib/unittest.dart';
-import '../../../pub/path.dart' as path;
+import 'package:unittest/unittest.dart';
+import 'package:path/path.dart' as path;
 
 main() {
   var builder = new path.Builder(style: path.Style.windows,
@@ -53,15 +53,19 @@
     expect(builder.dirname(r'a\b'), 'a');
     expect(builder.dirname(r'a\b\c'), r'a\b');
     expect(builder.dirname(r'a\b.c'), 'a');
-    expect(builder.dirname(r'a\'), 'a');
-    expect(builder.dirname('a/'), 'a');
+    expect(builder.dirname(r'a\'), '.');
+    expect(builder.dirname('a/'), '.');
     expect(builder.dirname(r'a\.'), 'a');
     expect(builder.dirname(r'a\b/c'), r'a\b');
     expect(builder.dirname(r'C:\a'), r'C:\');
-    expect(builder.dirname('C:\\'), r'C:\');
-    expect(builder.dirname(r'a\b\'), r'a\b');
+    expect(builder.dirname(r'C:\\\a'), r'C:\');
+    expect(builder.dirname(r'C:\'), r'C:\');
+    expect(builder.dirname(r'C:\\\'), r'C:\');
+    expect(builder.dirname(r'a\b\'), r'a');
     expect(builder.dirname(r'a/b\c'), 'a/b');
-    expect(builder.dirname(r'a\\'), r'a\');
+    expect(builder.dirname(r'a\\'), r'.');
+    expect(builder.dirname(r'a\b\\'), 'a');
+    expect(builder.dirname(r'a\\b'), 'a');
   });
 
   test('basename', () {
@@ -70,16 +74,17 @@
     expect(builder.basename(r'a\b'), 'b');
     expect(builder.basename(r'a\b\c'), 'c');
     expect(builder.basename(r'a\b.c'), 'b.c');
-    expect(builder.basename(r'a\'), '');
-    expect(builder.basename(r'a/'), '');
+    expect(builder.basename(r'a\'), 'a');
+    expect(builder.basename(r'a/'), 'a');
     expect(builder.basename(r'a\.'), '.');
     expect(builder.basename(r'a\b/c'), r'c');
     expect(builder.basename(r'C:\a'), 'a');
-    // TODO(nweiz): this should actually return 'C:\'
-    expect(builder.basename(r'C:\'), '');
-    expect(builder.basename(r'a\b\'), '');
+    expect(builder.basename(r'C:\'), r'C:\');
+    expect(builder.basename(r'a\b\'), 'b');
     expect(builder.basename(r'a/b\c'), 'c');
-    expect(builder.basename(r'a\\'), '');
+    expect(builder.basename(r'a\\'), 'a');
+    expect(builder.basename(r'a\b\\'), 'b');
+    expect(builder.basename(r'a\\b'), 'b');
   });
 
   test('basenameWithoutExtension', () {
@@ -88,11 +93,16 @@
     expect(builder.basenameWithoutExtension(r'a\b'), 'b');
     expect(builder.basenameWithoutExtension(r'a\b\c'), 'c');
     expect(builder.basenameWithoutExtension(r'a\b.c'), 'b');
-    expect(builder.basenameWithoutExtension(r'a\'), '');
+    expect(builder.basenameWithoutExtension(r'a\'), 'a');
     expect(builder.basenameWithoutExtension(r'a\.'), '.');
     expect(builder.basenameWithoutExtension(r'a\b/c'), r'c');
     expect(builder.basenameWithoutExtension(r'a\.bashrc'), '.bashrc');
     expect(builder.basenameWithoutExtension(r'a\b\c.d.e'), 'c.d');
+    expect(builder.basenameWithoutExtension(r'a\\'), 'a');
+    expect(builder.basenameWithoutExtension(r'a\b\\'), 'b');
+    expect(builder.basenameWithoutExtension(r'a\\b'), 'b');
+    expect(builder.basenameWithoutExtension(r'a\b.c\'), 'b');
+    expect(builder.basenameWithoutExtension(r'a\b.c\\'), 'b');
   });
 
   test('isAbsolute', () {
@@ -391,5 +401,6 @@
     expect(builder.withoutExtension(r'a\b/c'), r'a\b/c');
     expect(builder.withoutExtension(r'a\b/c.d'), r'a\b/c');
     expect(builder.withoutExtension(r'a.b/c'), r'a.b/c');
+    expect(builder.withoutExtension(r'a\b.c\'), r'a\b\');
   });
 }
diff --git a/pkg/pkg.status b/pkg/pkg.status
index a7383e2..c3223fb 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -13,14 +13,16 @@
 *: Skip
 
 # Don't compile tests that use dart:io to JS
-[ $compiler == dart2js || $compiler == dart2dart || $compiler == dartc ]
+[ $compiler == dart2js || $compiler == dart2dart ]
 http/test/*: Skip
 oauth2/test/*: Skip
+path/test/*: Skip
 
 # Skip tests that use local file access if we're running in any browser
 [ $runtime == opera || $runtime == ff || $runtime == ie9 || $runtime == dartium || $runtime == chrome || $runtime == safari || $runtime == drt ]
 http/test/*: Skip
 oauth2/test/*: Skip
+path/test/*: Skip
 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
@@ -50,7 +52,11 @@
 unittest/test/mock_regexp_negative_test: Fail
 unittest/test/mock_stepwise_negative_test: Fail
 
-[ $compiler == dart2js || $compiler == dartc ]
+# pkg/http issue 7458
+http/test/multipart_test: Fail
+
+
+[ $compiler == dart2js ]
 unittest/test/instance_test: Skip
 
 [ $compiler == none && $runtime == drt ]
diff --git a/pkg/serialization/lib/serialization.dart b/pkg/serialization/lib/serialization.dart
index 1c5f070..b5d1074 100644
--- a/pkg/serialization/lib/serialization.dart
+++ b/pkg/serialization/lib/serialization.dart
@@ -45,7 +45,8 @@
  *            excludeFields: ["other", "stuff"]);
  *
  * We can also use a completely non-reflective rule to serialize and
- * de-serialize objects.
+ * de-serialize objects. This can be more cumbersome, but it does work in
+ * dart2js, where mirrors are not yet implemented.
  *
  *      addressToMap(a) => {"number" : a.number, "street" : a.street,
  *          "city" : a.city};
@@ -85,9 +86,9 @@
  * access or a setter, but should be done by calling a method. For example, it
  * may not be possible to set a List field "foo", and you need to call an
  * addFoo() method for each entry in the list. In these cases, if you are using
- * a BasicRule for the object you can call the specialTreatmentFor() method.
+ * a BasicRule for the object you can call the setFieldWith() method.
  *
- *       s..addRuleFor(fooHolderInstance).specialTreatmentFor("foo",
+ *       s..addRuleFor(fooHolderInstance).setFieldWith("foo",
  *           (parent, value) => for (var each in value) parent.addFoo(value));
  *
  * Writing
@@ -148,7 +149,6 @@
 
 import 'src/mirrors_helpers.dart';
 import 'src/serialization_helpers.dart';
-import 'src/polyfill_identity_set.dart';
 import 'dart:json' show JSON;
 
 part 'src/reader_writer.dart';
@@ -166,7 +166,13 @@
    * The serialization is controlled by the list of Serialization rules. These
    * are most commonly added via [addRuleFor].
    */
-  List rules = [];
+  List _rules = [];
+
+  /**
+   * The serialization is controlled by the list of Serialization rules. These
+   * are most commonly added via [addRuleFor].
+   */
+  List get rules => _rules;
 
   /**
    * When reading, we may need to resolve references to existing objects in
@@ -177,13 +183,34 @@
    * the account. Instead we should just connect the de-serialized message
    * object to the account object that already exists there.
    */
-  Map<String, dynamic> externalObjects = {};
+  Map<String, dynamic> namedObjects = {};
 
   /**
    * When we write out data using this serialization, should we also write
-   * out a description of the rules.
+   * out a description of the rules. This is on by default unless using
+   * CustomRule subclasses, in which case it requires additional setup and
+   * is off by default.
    */
-  bool selfDescribing = true;
+  bool _selfDescribing;
+
+  /**
+   * When we write out data using this serialization, should we also write
+   * out a description of the rules. This is on by default unless using
+   * CustomRule subclasses, in which case it requires additional setup and
+   * is off by default.
+   */
+  bool get selfDescribing {
+    if (_selfDescribing != null) return _selfDescribing;
+    return !_rules.some((x) => x is CustomRule);
+  }
+
+  /**
+   * When we write out data using this serialization, should we also write
+   * out a description of the rules. This is on by default unless using
+   * CustomRule subclasses, in which case it requires additional setup and
+   * is off by default.
+   */
+  set selfDescribing(x) => _selfDescribing = x;
 
   /**
    * Creates a new serialization with a default set of rules for primitives
@@ -205,7 +232,9 @@
    * [instanceOfType]. Optionally
    * allows specifying a [constructor] name, the list of [constructorFields],
    * and the list of [fields] not used in the constructor. Returns the new
-   * rule.
+   * rule. Note that [BasicRule] uses reflection, and so will not work with the
+   * current state of dartj2s. If you need to run there, consider using
+   * [CustomRule] instead.
    *
    * If the optional parameters aren't specified, the default constructor will
    * be used, and the list of fields will be computed. Alternatively, you can
@@ -256,8 +285,8 @@
    * method.
    */
   void addRule(SerializationRule rule) {
-    rule.number = rules.length;
-    rules.add(rule);
+    rule.number = _rules.length;
+    _rules.add(rule);
   }
 
   /**
@@ -286,29 +315,19 @@
   }
 
   /**
-   * Read the serialized data from [input] and return a List of the root
-   * objects from the result. If there are objects that need to be resolved
+   * Read the serialized data from [input] and return the root object
+   * from the result. If there are objects that need to be resolved
    * in the current context, they should be provided in [externals] as a
    * Map from names to values. In particular, in the current implementation
    * any class mirrors needed should be provided in [externals] using the
    * class name as a key. In addition to the [externals] map provided here,
    * values will be looked up in the [externalObjects] map.
    */
-  List read(String input, [Map externals = const {}]) {
+  read(String input, [Map externals = const {}]) {
     return newReader().read(input, externals);
   }
 
   /**
-   * In the most common case there is only a single root object to be read,
-   * and this method can be used to return just one object rather than
-   * a List. The [input] and [externals] parameters are the same as for the
-   * general [read] method.
-   */
-  Object readOne(String input, [Map externals = const {}]) {
-    return newReader().readOne(input, externals);
-  }
-
-  /**
    * Return a new [Reader] object for this serialization. This is useful if
    * you want to do something more complex with the reader than just returning
    * the final result.
@@ -319,7 +338,7 @@
    * Return the list of SerializationRule that apply to [object]. For
    * internal use, but public because it's used in testing.
    */
-  List<SerializationRule> rulesFor(object) {
+  List<SerializationRule> rulesFor(object, Writer w) {
     // This has a couple of edge cases.
     // 1) The owning object may have indicated we should use a different
     // rule than the default.
@@ -338,12 +357,13 @@
     var target, candidateRules;
     if (object is DesignatedRuleForObject) {
       target = object.target;
-      candidateRules = object.possibleRules(rules);
+      candidateRules = object.possibleRules(_rules);
     } else {
       target = object;
-      candidateRules = rules;
+      candidateRules = _rules;
     }
-    List applicable = candidateRules.filter((each) => each.appliesTo(target));
+    List applicable = candidateRules.filter(
+        (each) => each.appliesTo(target, w));
 
     if (applicable.isEmpty) {
       return [addRuleFor(target)];
@@ -374,8 +394,7 @@
 
     // Make some bogus rule instances so we have something to feed rule creation
     // and get their types. If only we had class literals implemented...
-    var closureRule = new ClosureToMapRule.stub([].runtimeType);
-    var basicRule = new BasicRule(reflect(null).type, '', [], [], []);
+   var basicRule = new BasicRule(reflect(null).type, '', [], [], []);
 
     var meta = new Serialization()
       ..selfDescribing = false
@@ -383,14 +402,32 @@
       ..addRuleFor(new PrimitiveRule())
       ..addRuleFor(new ListRuleEssential())
       ..addRuleFor(basicRule,
-          constructorFields: ['typeWrapped',
+          constructorFields: ['type',
             'constructorName',
             'constructorFields', 'regularFields', []],
           fields: [])
-      ..addRule(new ClassMirrorRule());
-    meta.externalObjects = externalObjects;
+      ..addRule(new NamedObjectRule())
+      ..addRule(new MirrorRule());
+    meta.namedObjects = namedObjects;
     return meta;
   }
+
+  /** Return true if our [namedObjects] collection has an entry for [object].*/
+  bool _hasNameFor(object) {
+    var sentinel = const _Sentinel();
+    return _nameFor(object, () => sentinel) != sentinel;
+  }
+
+  /**
+   * Return the name we have for [object] in our [namedObjects] collection or
+   * the result of evaluating [ifAbsent] if there is no entry.
+   */
+  _nameFor(object, [ifAbsent]) {
+    for (var key in namedObjects.keys) {
+      if (identical(namedObjects[key], object)) return key;
+    }
+    return ifAbsent == null ? null : ifAbsent();
+  }
 }
 
 /**
diff --git a/pkg/serialization/lib/src/basic_rule.dart b/pkg/serialization/lib/src/basic_rule.dart
index df1cae7..5289a87 100644
--- a/pkg/serialization/lib/src/basic_rule.dart
+++ b/pkg/serialization/lib/src/basic_rule.dart
@@ -86,22 +86,19 @@
    *
    * For example, to serialize a Serialization, we need its rules to be
    * individually added rather than just setting the rules field.
-   *      ..addRuleFor(new Serialization()).specialTreatmentFor('rules',
+   *      ..addRuleFor(new Serialization()).setFieldWith('rules',
    *          (InstanceMirror s, List rules) {
    *            rules.forEach((x) => s.reflectee.addRule(x));
    * Note that the function is passed the owning object as well as the field
    * value, but that it is passed as a mirror.
    */
-  specialTreatmentFor(String fieldName, SetWithFunction setWith) {
+  setFieldWith(String fieldName, SetWithFunction setWith) {
     fields.addAllByName([fieldName]);
-    _Field field = fields.named(fieldName);
+    _NamedField field = fields.named(fieldName);
     Function setter = (setWith == null) ? field.defaultSetter : setWith;
-    field.specialTreatment = setter;
+    field.customSetter = setter;
   }
 
-  // TODO(alanknight): Polyfill for the non-hashability of mirrors. Issue 6880.
-  get typeWrapped => new ClassMirrorWrapper(type);
-
   /** Return the name of the constructor used to create new instances on read.*/
   String get constructorName => constructor.name;
 
@@ -170,7 +167,7 @@
   checkForEssentialLists(index, value) {
     if (value is List && fields.contents[index].isEssential) {
       return new DesignatedRuleForObject(value,
-          (index) => index is ListRuleEssential);
+          (SerializationRule rule) => rule is ListRuleEssential);
     } else {
       return value;
     }
@@ -206,7 +203,7 @@
    * this is true if the type mirrors are the same.
    */
   // TODO(alanknight): This seems likely to be slow. Verify. Other options?
-  bool appliesTo(object) => reflect(object).type == type;
+  bool appliesTo(object, Writer w) => reflect(object).type == type;
 
   /**
    * Given the various field lists provided by the user, construct the list
@@ -226,21 +223,13 @@
    * Extract the value of the field [fieldName] from the object reflected
    * by [mirror].
    */
-  // TODO (alanknight): The "is String" mechanism here should be more tightly
-  // controlled to work on just constructor fields.
   // TODO(alanknight): The framework should be resilient if there are fields
   // it expects that are missing, either for the case of de-serializing to a
   // different definition, or for the case that tree-shaking has removed state.
   // TODO(alanknight): This, and other places, rely on synchronous access to
   // mirrors. Should be changed to use a synchronous API once one is available,
   // or to be async, but that would be extremely ugly.
-  _value(InstanceMirror mirror, _Field field) {
-    if (field.name is String) {
-      return mirror.getField(field.name).value.reflectee;
-    } else {
-      return field.name;
-    }
-  }
+  _value(InstanceMirror mirror, _Field field) => field.valueIn(mirror);
 
   /**
    * When reading from a flat format we are given [stream] and need to pull as
@@ -275,9 +264,7 @@
  * This represents a field in an object. It is intended to be used as part of
  * a [_FieldList].
  */
-class _Field implements Comparable {
-  /** The name of the field (or getter) */
-  final name;
+abstract class _Field implements Comparable {
 
   /** The FieldList that contains us. */
   final _FieldList fieldList;
@@ -291,17 +278,37 @@
   /** Is this field used in the constructor? */
   bool usedInConstructor = false;
 
-  /** The special way to set this value registered, if this has a value. */
-  Function specialTreatment;
+  /**
+   * Create a new [_Field] instance. This will be either a [_NamedField] or a
+   * [_ConstantField] depending on whether or not [value] corresponds to a
+   * field in the class which [fieldList] models.
+   */
+  factory _Field(value, _FieldList fieldList) {
+    if (_isReallyAField(value, fieldList)) {
+      return new _NamedField._internal(value, fieldList);
+    } else {
+      return new _ConstantField._internal(value, fieldList);
+    }
+  }
 
-  _Field(this.name, this.fieldList);
+  /**
+   * Determine if [value] represents a field or getter in the class that
+   * [fieldList] models.
+   */
+  static bool _isReallyAField(value, _FieldList fieldList) {
+    if (!(value is String)) return false;
+    return hasField(value, fieldList.mirror) ||
+        hasGetter(value, fieldList.mirror);
+  }
 
-  operator ==(x) => x is _Field && (name == x.name);
-  int get hashCode => name.hashCode;
+  /** Private constructor. */
+  _Field._internal(this.fieldList);
 
-  // Note that the field 'name' may be an arbitrary constant value, so we have
-  // to convert it to a string for sorting.
-  compareTo(x) => name.toString().compareTo(x.name.toString());
+  /**
+   * Extracts the value for the field that this represents from the instance
+   * mirrored by [mirror] and return it.
+   */
+  valueIn(InstanceMirror mirror);
 
   // TODO(alanknight): Is this the right name, or is it confusing that essential
   // is not the inverse of regular.
@@ -311,18 +318,53 @@
   /**
    * Return true if this field is treated as essential state, either because
    * it is used in the constructor, or because it's been designated
-   * using [specialTreatmentFor].
+   * using [setFieldWith].
    */
-  bool get isEssential => usedInConstructor || specialTreatment != null;
+  bool get isEssential => usedInConstructor;
+
+  /** Set the [value] of our field in the given mirrored [object]. */
+  void setValue(InstanceMirror object, value);
+
+  // Because [x] may not be a named field, we compare the toString. We don't
+  // care that much where constants come in the sort order as long as it's
+  // consistent.
+  compareTo(_Field x) => toString().compareTo(x.toString());
+}
+
+/**
+ * This represents a field in the object, either stored as a field or
+ * accessed via getter/setter/constructor parameter. It has a name and
+ * will attempt to access the state for that name using an [InstanceMirror].
+ */
+class _NamedField extends _Field {
+  /** The name of the field (or getter) */
+  final name;
+
+  /** The special way to set this value registered, if this has a value. */
+  Function customSetter;
+
+  _NamedField._internal(this.name, fieldList) : super._internal(fieldList);
+
+  operator ==(x) => x is _NamedField && (name == x.name);
+  int get hashCode => name.hashCode;
+
+  /**
+   * Return true if this field is treated as essential state, either because
+   * it is used in the constructor, or because it's been designated
+   * using [setFieldWith].
+   */
+  bool get isEssential => super.isEssential || customSetter != null;
 
   /** Set the [value] of our field in the given mirrored [object]. */
   void setValue(InstanceMirror object, value) {
     setter(object, value);
   }
 
+  valueIn(InstanceMirror mirror) => mirror.getField(name).value.reflectee;
+
   /** Return the function to use to set our value. */
   Function get setter =>
-      (specialTreatment != null) ? specialTreatment : defaultSetter;
+      (customSetter != null) ? customSetter : defaultSetter;
 
   /** Return a default setter function. */
   void defaultSetter(InstanceMirror object, value) {
@@ -333,6 +375,31 @@
 }
 
 /**
+ * This represents a constant value that will be passed as a constructor
+ * parameter. Rather than having a name it has a constant value.
+ */
+class _ConstantField extends _Field {
+
+  /** The value we always return.*/
+  final value;
+
+  _ConstantField._internal(this.value, fieldList) : super._internal(fieldList);
+
+  operator ==(x) => x is _ConstantField && (value == x.value);
+  int get hashCode => value.hashCode;
+  String toString() => 'ConstantField($value)';
+  valueIn(InstanceMirror mirror) => value;
+
+  /** We cannot be set, so setValue is a no-op. */
+  void setValue(InstanceMirror object, value) {}
+
+  /** There are places where the code expects us to have an identifier, so
+   * use the value for that.
+   */
+  get name => value;
+}
+
+/**
  * The organization of fields in an object can be reasonably complex, so they
  * are kept in a separate object, which also has the ability to compute the
  * default fields to use reflectively.
@@ -369,10 +436,10 @@
   _Field named(String name) => allFields[name];
 
   /** Set the fields to be used in the constructor. */
-  set constructorFields(List fields) {
-    if (fields == null || fields.isEmpty) return;
+  set constructorFields(List fieldNames) {
+    if (fieldNames == null || fieldNames.isEmpty) return;
     _constructorFields = [];
-    for (var each in fields) {
+    for (var each in fieldNames) {
       var field = new _Field(each, this)..usedInConstructor = true;
       allFields[each] = field;
       _constructorFields.add(field);
@@ -405,7 +472,7 @@
   void addAllNotExplicitlyExcluded(List<String> aCollection) {
     if (aCollection == null) return;
     var names = aCollection;
-    names = names.filter((x) => x is String && !_excludeFields.contains(x));
+    names = names.filter((x) => !_excludeFields.contains(x));
     addAllByName(names);
   }
 
@@ -489,10 +556,10 @@
 }
 
 /**
- *  Provide a typedef for the setWith argument to specialTreatmentFor. It would
+ *  Provide a typedef for the setWith argument to setFieldWith. It would
  * be nice if we could put this closer to the definition.
  */
-typedef SetWithFunction(InstanceMirror m, Object o);
+typedef SetWithFunction(InstanceMirror m, object);
 
 /**
  * This represents a constructor that is to be used when re-creating a
diff --git a/pkg/serialization/lib/src/mirrors_helpers.dart b/pkg/serialization/lib/src/mirrors_helpers.dart
index cc57ecd..b67ecca 100644
--- a/pkg/serialization/lib/src/mirrors_helpers.dart
+++ b/pkg/serialization/lib/src/mirrors_helpers.dart
@@ -28,9 +28,19 @@
   }
 }
 
+/** Return true if the class has a field named [name]. Note that this
+ * includes private fields, but excludes statics. */
+bool hasField(String name, ClassMirror mirror) {
+  var field = mirror.variables[name];
+  if (field != null && !field.isStatic) return true;
+  var superclass = mirror.superclass;
+  if (superclass == mirror) return false;
+  return hasField(name, superclass);
+}
+
 /**
- * Return a list of all the public getters of a class, including inherited
- * getters.
+ * Return a list of all the getters of a class, including inherited
+ * getters. Note that this allows private getters, but excludes statics.
  */
 List<MethodMirror> publicGetters(ClassMirror mirror) {
   var mine = mirror.getters.values.filter((x) => !(x.isPrivate || x.isStatic));
@@ -42,6 +52,15 @@
   }
 }
 
+/** Return true if the class has a getter named [name] */
+bool hasGetter(String name, ClassMirror mirror) {
+  var getter = mirror.getters[name];
+  if (getter != null && !getter.isStatic) return true;
+  var superclass = mirror.superclass;
+  if (superclass == mirror) return false;
+  return hasField(name, superclass);
+}
+
 /**
  * Return a list of all the public getters of a class which have corresponding
  * setters.
@@ -57,17 +76,4 @@
  * as literals, so we have to be passed an instance and then extract a
  * ClassMirror from that. Given a horrible name as an extra reminder to fix it.
  */
-ClassMirror turnInstanceIntoSomethingWeCanUse(x) => reflect(x).type;
-
-/**
- * This is polyfill because we can't hash ClassMirror right now. We
- * don't bother implementing most of its methods because we don't need them.
- */
-// TODO(alanknight): Remove this when you can hash mirrors directly
-class ClassMirrorWrapper implements ClassMirror {
-  ClassMirror mirror;
-  ClassMirrorWrapper(this.mirror);
-  get simpleName => mirror.simpleName;
-  get hashCode => simpleName.hashCode;
-  operator ==(x) => x is ClassMirror && simpleName == x.simpleName;
-}
\ No newline at end of file
+ClassMirror turnInstanceIntoSomethingWeCanUse(x) => reflect(x).type;
\ No newline at end of file
diff --git a/pkg/serialization/lib/src/polyfill_identity_set.dart b/pkg/serialization/lib/src/polyfill_identity_set.dart
index f2c3b4e..56a7865 100644
--- a/pkg/serialization/lib/src/polyfill_identity_set.dart
+++ b/pkg/serialization/lib/src/polyfill_identity_set.dart
@@ -303,5 +303,4 @@
 
   final K key;
   V value;
-}
-
+}
\ No newline at end of file
diff --git a/pkg/serialization/lib/src/reader_writer.dart b/pkg/serialization/lib/src/reader_writer.dart
index 4415e63..ffda209 100644
--- a/pkg/serialization/lib/src/reader_writer.dart
+++ b/pkg/serialization/lib/src/reader_writer.dart
@@ -37,8 +37,8 @@
    * once and stored here for each object. This provides some space-saving,
    * but also serves to record which objects we have already seen.
    */
-  final Map<Object, Reference> references =
-      new IdentityMapPlus<Object, Reference>();
+  final Map<dynamic, Reference> references =
+      new IdentityMap<Object, Reference>();
 
   /**
    * The state of objects that need to be serialized is stored here.
@@ -51,11 +51,11 @@
   final List<List> states = new List<List>();
 
   /** Return the list of rules we use. */
-  List<SerializationRule> get rules => serialization.rules;
+  List<SerializationRule> get rules => serialization._rules;
 
   /**
    * Creates a new [Writer] that uses the rules from its parent
-   * [Serialization]. Serializations are do not keep any state
+   * [Serialization]. Serializations do not keep any state
    * related to a particular read/write, so the same one can be used
    * for multiple different Readers/Writers.
    */
@@ -147,7 +147,7 @@
    */
   void _process(object, Trace trace) {
     var real = (object is DesignatedRuleForObject) ? object.target : object;
-    for (var eachRule in serialization.rulesFor(object)) {
+    for (var eachRule in serialization.rulesFor(object, this)) {
       _record(real, eachRule);
     }
   }
@@ -160,7 +160,7 @@
    * Note that at this point the states are just the same as the fields of the
    * object, and haven't been flattened.
    */
-  void _record(Object object, SerializationRule rule) {
+  void _record(object, SerializationRule rule) {
     if (rule.shouldUseReferenceFor(object, this)) {
       references.putIfAbsent(object, () =>
           new Reference(this, rule.number, _nextObjectNumberFor(rule)));
@@ -177,7 +177,7 @@
   bool shouldUseReferencesForPrimitives = false;
 
   /** Record a [state] entry for a particular rule. */
-  void _addStateForRule(eachRule, Object state) {
+  void _addStateForRule(eachRule, state) {
     _growStates(eachRule);
     states[eachRule.number].add(state);
   }
@@ -206,7 +206,7 @@
    * isn't, it's possible to apply a rule for String, or even for Strings larger
    * than x, which gives them references.
    */
-  bool _hasIndexFor(Object object) {
+  bool _hasIndexFor(object) {
     return _objectNumberFor(object) != -1;
   }
 
@@ -216,7 +216,7 @@
    * this will return the one for the primary rule, defined as the one that
    * is listed in its canonical reference.
    */
-  int _objectNumberFor(Object object) {
+  int _objectNumberFor(object) {
     var reference = references[object];
     return (reference == null) ? -1 : reference.objectNumber;
   }
@@ -247,7 +247,7 @@
       var meta = serialization._ruleSerialization();
       var writer = new Writer(meta);
       writer.selfDescribing = false;
-      savedRules = writer.write(serialization.rules);
+      savedRules = writer.write(serialization._rules);
     }
     result["rules"] = savedRules;
     result["data"] = states;
@@ -268,13 +268,23 @@
    * objects that should have a reference (roughly speaking, non-primitives)
    * can be relied on to have a reference.
    */
-  _referenceFor(Object o) {
-    return references[o];
-  }
+  _referenceFor(object) => references[object];
+
+  /**
+   * Return true if the [namedObjects] collection has a reference to [object].
+   */
+  // TODO(alanknight): Should the writer also have its own namedObjects
+  // collection specific to the particular write, or is that just adding
+  // complexity for little value?
+  hasNameFor(object) => serialization._hasNameFor(object);
+
+  /**
+   * Return the name we have for this object in the [namedObjects] collection.
+   */
+  nameFor(object) => serialization._nameFor(object);
 
   // For debugging/testing purposes. Find what state a reference points to.
-  stateForReference(Reference r) =>
-      states[r.ruleNumber][r.objectNumber];
+  stateForReference(Reference r) => states[r.ruleNumber][r.objectNumber];
 }
 
 /**
@@ -331,15 +341,15 @@
    * look things up can be provided as an argument to read, but we can also
    * provide a map here, and objects will be looked up in both places.
    */
-  Map externalObjects;
+  Map namedObjects;
 
   /**
    * Look up the reference to an external object. This can be held either in
    * the reader-specific list of externals or in the serializer's
    */
-  externalObjectNamed(key) {
-    var map = (externalObjects.containsKey(key))
-        ? externalObjects : serialization.externalObjects;
+  objectNamed(key) {
+    var map = (namedObjects.containsKey(key))
+        ? namedObjects : serialization.namedObjects;
     if (!map.containsKey(key)) {
       throw 'Cannot find named object to link to: $key';
     }
@@ -350,7 +360,7 @@
    * Return the list of rules to be used when writing. These come from the
    * [serialization].
    */
-  List<SerializationRule> get rules => serialization.rules;
+  List<SerializationRule> get rules => serialization._rules;
 
   /**
    * Internal use only, for testing purposes. Set the data for this reader
@@ -365,17 +375,17 @@
   /**
    * This is the primary method for a [Reader]. It takes the input data,
    * currently hard-coded to expect our custom JSON format, and returns
-   * the root objects.
+   * the root object.
    */
   read(String input, [Map externals = const {}]) {
-    externalObjects = externals;
+    namedObjects = externals;
     var topLevel = JSON.parse(input);
     var ruleString = topLevel["rules"];
     readRules(ruleString, externals);
     data = topLevel["data"];
     rules.forEach(inflateForRule);
     var roots = topLevel["roots"];
-    return roots.map(inflateReference);
+    return inflateReference(roots.first);
   }
 
   /**
@@ -385,7 +395,7 @@
   void readRules(String newRules, Map externals) {
     // TODO(alanknight): Replacing the serialization is kind of confusing.
     List rulesWeRead = (newRules == null) ?
-        null : serialization._ruleSerialization().readOne(newRules, externals);
+        null : serialization._ruleSerialization().read(newRules, externals);
     if (rulesWeRead != null && !rulesWeRead.isEmpty) {
       serialization = new Serialization.blank();
       rulesWeRead.forEach(serialization.addRule);
@@ -400,7 +410,7 @@
   readFlat(List input, [Map externals = const {}]) {
     // TODO(alanknight): Way too much code duplication with read. Numerous
     // code smells.
-    externalObjects = externals;
+    namedObjects = externals;
     var topLevel = input;
     var ruleString = topLevel[0];
     readRules(ruleString, externals);
@@ -421,24 +431,9 @@
       roots.add(new Reference(this, rootStream.next(), rootStream.next()));
     }
     var x = inflateReference(roots[0]);
-    return roots.map((x) => inflateReference(x));
+    return inflateReference(roots.first);
   }
 
-
-  /**
-   * A convenient alternative to [read] when you know there is only
-   * one object.
-   */
-  readOne(String input, [Map externals = const {}]) =>
-      read(input, externals).first;
-
-  /**
-   * A convenient alternative to [readFlat] when you know there is only
-   * one object.
-   */
-  readOneFlat(List input, [Map externals = const {}]) =>
-      readFlat(input, externals).first;
-
   /**
    * Inflate all of the objects for [rule]. Does the essential state for all
    * objects first, then the non-essential state. This avoids cycles in
@@ -461,7 +456,7 @@
    * follow references and recursively inflate them, leaving Sentinel objects
    * to detect cycles.
    */
-  Object inflateOne(SerializationRule rule, position, state) {
+  inflateOne(SerializationRule rule, position, state) {
     var existing = allObjectsForRule(rule)[position];
     // We may already be in progress and hitting this in a cycle.
     if (existing is _Sentinel) {
@@ -482,7 +477,7 @@
    * return it. If it is, then inflate the target of the reference and return
    * the resulting object.
    */
-  Object inflateReference(possibleReference) {
+  inflateReference(possibleReference) {
     // If this is a primitive, return it directly.
     // TODO This seems too complicated.
     return asReference(possibleReference,
@@ -498,19 +493,19 @@
    * Given [reference], return what we have stored as an object for it. Note
    * that, depending on the current state, this might be null or a Sentinel.
    */
-  Object _objectFor(Reference reference) =>
+  _objectFor(Reference reference) =>
       objects[reference.ruleNumber][reference.objectNumber];
 
   /** Given [rule], return the storage for its objects. */
   allObjectsForRule(SerializationRule rule) => objects[rule.number];
 
   /** Given [reference], return the the state we have stored for it. */
-  Object _stateFor(Reference reference) =>
+  _stateFor(Reference reference) =>
       _data[reference.ruleNumber][reference.objectNumber];
 
   /** Given a reference, return the rule it references. */
   SerializationRule ruleFor(Reference reference) =>
-      serialization.rules[reference.ruleNumber];
+      serialization._rules[reference.ruleNumber];
 
   /**
    * Given a possible reference [anObject], call either [ifReference] or
@@ -568,8 +563,8 @@
   }
 
   /** A convenience method to add a single root and trace it in one step. */
-  trace(Object o) {
-    addRoot(o);
+  trace(object) {
+    addRoot(object);
     traceAll();
   }
 
@@ -594,7 +589,7 @@
   }
 
   /** Note that we've seen [value], and add it to the queue to be processed. */
-  note(Object value) {
+  note(value) {
     if (value != null) {
       queue.add(value);
     }
@@ -653,4 +648,3 @@
 
   possibleRules(List rules) => rules.filter(rulePredicate);
 }
-
diff --git a/pkg/serialization/lib/src/serialization_helpers.dart b/pkg/serialization/lib/src/serialization_helpers.dart
index df4b2cf..335bc0d 100644
--- a/pkg/serialization/lib/src/serialization_helpers.dart
+++ b/pkg/serialization/lib/src/serialization_helpers.dart
@@ -8,7 +8,6 @@
  * available in the core library.
  */
 library serialization_helpers;
-import 'polyfill_identity_set.dart';
 
 /**
  * A named function of one argument that just returns it. Useful for using
@@ -39,6 +38,12 @@
   return result;
 }
 
+/** Helper function for PrimitiveRule to tell which objects it applies to. */
+bool isPrimitive(object) {
+  return identical(object, null) || object is num || object is String ||
+      identical(object, true) || identical(object, false);
+}
+
 /**
  * Be able to iterate polymorphically between List-like and Map-like things.
  * For example, keysAndValues(["a", "b", "c"]).forEach((key, value) => ...);
@@ -167,39 +172,75 @@
 }
 
 /**
- * This provides an identity map which allows true, false, and null as
- * valid keys. It does this by special casing them and using some other
- * known object as the key instead.
+ * This provides an identity map which also allows true, false, and null
+ * as valid keys. In the interests of avoiding duplicating map code, and
+ * because hashCode for arbitrary objects is currently very slow on the VM,
+ * just do a linear lookup.
  */
-class IdentityMapPlus<K, V> extends IdentityMap {
-  final trueish = const _Sentinel(true);
-  final falseish = const _Sentinel(false);
-  final nullish = const _Sentinel(null);
+class IdentityMap<K, V> implements Map<K, V> {
 
-  wrap(x) {
-    if (x == true) return trueish;
-    if (x == false) return falseish;
-    if (x == null) return nullish;
-    return x;
+  final List<K> keys = <K>[];
+  final List<V> values = <V>[];
+
+  V operator [](K key) {
+    var index =  _indexOf(key);
+    return (index == -1) ? null : values[index];
   }
 
-  unwrap(x) {
-    if (x is _Sentinel) return x._wrappedObject;
-    return x;
+  void operator []=(K key, V value) {
+    var index = _indexOf(key);
+    if (index == -1) {
+      keys.add(key);
+      values.add(value);
+    } else {
+      values[index] = value;
+    }
   }
 
-  operator [](key) => super[wrap(key)];
-  operator []=(key, value) => super[wrap(key)] = value;
+  putIfAbsent(K key, Function ifAbsent) {
+    var index = _indexOf(key);
+    if (index == -1) {
+      keys.add(key);
+      values.add(ifAbsent());
+      return values.last;
+    } else {
+      return values[index];
+    }
+  }
 
-  putIfAbsent(key, ifAbsent) => super.putIfAbsent(wrap(key), ifAbsent);
+  _indexOf(K key) {
+    // Go backwards on the guess that we are most likely to access the most
+    // recently added.
+    // Make strings and primitives unique
+    var compareEquality = isPrimitive(key);
+    for (var i = keys.length - 1; i >= 0; i--) {
+      var equal = compareEquality ? key == keys[i] : identical(key, keys[i]);
+      if (equal) return i;
+    }
+    return -1;
+  }
 
-  containsKey(key) => super.containsKey(wrap(key));
-  forEach(f) => super.forEach((key, value) => f(unwrap(key), value));
-  remove(key) => super.remove(unwrap(key));
-  /**
-   * Note that keys is a very inefficient operation for this type. Don't do it.
-   */
-  get keys => super.keys.map((x) => unwrap(x));
-}
+  bool containsKey(K key) => _indexOf(key) != -1;
+  void forEach(f(K key, V value)) {
+    for (var i = 0; i < keys.length; i++) {
+      f(keys[i], values[i]);
+    }
+  }
 
+  V remove(K key) {
+    var index = _indexOf(key);
+    if (index == -1) return null;
+    keys.removeAt(index);
+    return values.removeAt(index);
+  }
 
+  int get length => keys.length;
+  void clear() {
+    keys.clear();
+    values.clear();
+  }
+  bool get isEmpty => keys.isEmpty;
+
+  // Note that this is doing an equality comparison.
+  bool containsValue(x) => values.contains(x);
+}
\ No newline at end of file
diff --git a/pkg/serialization/lib/src/serialization_rule.dart b/pkg/serialization/lib/src/serialization_rule.dart
index a460237..46f9c57 100644
--- a/pkg/serialization/lib/src/serialization_rule.dart
+++ b/pkg/serialization/lib/src/serialization_rule.dart
@@ -33,8 +33,11 @@
     _number = x;
   }
 
-  /** Return true if this rule applies to this object, false otherwise. */
-  bool appliesTo(object);
+  /**
+   * Return true if this rule applies to this object, in the context
+   * where we're writing it, false otherwise.
+   */
+  bool appliesTo(object, Writer writer);
 
   /**
    * This extracts the state from the object, calling [f] for each value
@@ -42,7 +45,7 @@
    * state at the end. The state that results will still have direct
    * pointers to objects, rather than references.
    */
-  Object extractState(object, void f(value));
+  extractState(object, void f(value));
 
   /**
    * Given the variables representing the state of an object, flatten it
@@ -98,11 +101,11 @@
   inflateNonEssential(state, object, Reader reader);
 
   /**
-   * If we have an object [o] as part of our state, should we represent that
+   * If we have [object] as part of our state, should we represent that
    * directly, or should we make a reference for it. By default we use a
    * reference for everything.
    */
-  bool shouldUseReferenceFor(Object o, Writer w) => true;
+  bool shouldUseReferenceFor(object, Writer w) => true;
 
   /**
    * This writes the data from our internal representation into a List.
@@ -121,9 +124,9 @@
     var intermediate = new List();
     var totalLength = 0;
     for (var eachList in ruleData) {
-      // TODO(alanknight): Abstract this out better, this really won't scale.
-      if (this is ListRule)
+      if (writeLengthInFlatFormat) {
         intermediate.add(eachList.length);
+      }
       for (var eachRef in eachList) {
         if (eachRef == null) {
           intermediate..add(null)..add(null);
@@ -136,10 +139,52 @@
   }
 
   /**
+   * Return true if this rule writes a length value before each entry in
+   * the flat format. Return false if the results are fixed length.
+   */
+  // TODO(alanknight): This should probably go away with more general formats.
+  bool get writeLengthInFlatFormat => false;
+
+  /**
    * The inverse of dumpStateInto, this reads the rule's state from an
    * iterator in a flat format.
    */
-  pullStateFrom(Iterator stream);
+  pullStateFrom(Iterator stream) {
+    var numberOfEntries = stream.next();
+    var ruleData = new List();
+    for (var i = 0; i < numberOfEntries; i++) {
+      var subLength = dataLengthIn(stream);
+      var subList = [];
+      ruleData.add(subList);
+      for (var j = 0; j < subLength; j++) {
+        var a = stream.next();
+        var b = stream.next();
+        if (!(a is int)) {
+          // This wasn't a reference, just use the first object as a literal.
+          // particularly used for the case of null.
+          subList.add(a);
+        } else {
+          subList.add(new Reference(this, a, b));
+        }
+      }
+    }
+    return ruleData;
+  }
+
+  /**
+   * Return the length of the list of data we expect to see on a particular
+   * iterator in a flat format. This may have been encoded in the stream if we
+   * are variable length, or it may be constant. Note that this is expressed in
+   *
+   */
+  dataLengthIn(Iterator stream) =>
+      writeLengthInFlatFormat ? stream.next() : dataLength;
+
+  /**
+   * If the data is fixed length, return it here. Unused in the non-flat
+   * format, or if the data is variable length.
+   */
+  int get dataLength => 0;
 }
 
 /**
@@ -148,7 +193,7 @@
  */
 class ListRule extends SerializationRule {
 
-  appliesTo(object) => object is List;
+  appliesTo(object, Writer w) => object is List;
 
   state(List list) => new List.from(list);
 
@@ -186,9 +231,9 @@
     // TODO(alanknight): This is much too close to the basicRule implementation,
     // and I'd refactor them if I didn't think this whole mechanism needed to
     // change soon.
-    var dataLength = stream.next();
+    var length = stream.next();
     var ruleData = new List();
-    for (var i = 0; i < dataLength; i++) {
+    for (var i = 0; i < length; i++) {
       var subLength = stream.next();
       var subList = new List();
       ruleData.add(subList);
@@ -206,6 +251,14 @@
     }
     return ruleData;
   }
+
+  /**
+   * Return true because we need to write the length of each list in the flat
+   * format. */
+  bool get writeLengthInFlatFormat => true;
+
+  /** Return the length of the next list when reading the flat format. */
+  int dataLengthIn(Iterator stream) => stream.next();
 }
 
 /**
@@ -234,7 +287,7 @@
  * num, String, and bool.
  */
 class PrimitiveRule extends SerializationRule {
-    appliesTo(object) {
+  appliesTo(object, Writer w) {
     return isPrimitive(object);
   }
   extractState(object, Function f) => object;
@@ -242,11 +295,12 @@
   inflateEssential(state, Reader r) => state;
   inflateNonEssential(object, _, Reader r) {}
 
-  /** Indicate whether we should save pointers to this object as references
+  /**
+   * Indicate whether we should save pointers to this object as references
    * or store the object directly. For primitives this depends on the format,
    * so we delegate to the writer.
    */
-  bool shouldUseReferenceFor(Object o, Writer w) =>
+  bool shouldUseReferenceFor(object, Writer w) =>
       w.shouldUseReferencesForPrimitives;
 
   /**
@@ -266,34 +320,29 @@
    * indicating the number of objects and then N simple objects.
    */
   pullStateFrom(Iterator stream) {
-    var dataLength = stream.next();
+    var length = stream.next();
     var ruleData = new List();
-    for (var i = 0; i < dataLength; i++) {
+    for (var i = 0; i < length; i++) {
       ruleData.add(stream.next());
     }
     return ruleData;
   }
 }
 
-/** Helper function for PrimitiveRule to tell which objects it applies to. */
-bool isPrimitive(Object object) {
-  return object is num || object is String || object is bool;
-}
-
-/** Typedef for the object construction closure used in ClosureToMapRule. */
-typedef Object ConstructType(Map m);
+/** Typedef for the object construction closure used in ClosureRule. */
+typedef ConstructType(Map m);
 
 /** Typedef for the state-getting closure used in ClosureToMapRule. */
-typedef Map<String, Object> GetStateType(Object o);
+typedef Map<String, dynamic> GetStateType(object);
 
 /** Typedef for the state-setting closure used in ClosureToMapRule. */
-typedef void NonEssentialStateType(Object o, Map m);
+typedef void NonEssentialStateType(object, Map m);
 
 /**
  * This is a rule where the extraction and creation are hard-coded as
  * closures. The result is expected to be a map indexed by field name.
  */
-class ClosureToMapRule extends SerializationRule {
+class ClosureRule extends CustomRule {
 
   /** The runtimeType of objects that this rule applies to. Used in appliesTo.*/
   final Type type;
@@ -302,7 +351,7 @@
   ConstructType construct;
 
   /** The function for returning an object's state as a Map. */
-  GetStateType getState;
+  GetStateType getStateFunction;
 
   /** The function for setting an object's state from a Map. */
   NonEssentialStateType setNonEssentialState;
@@ -312,56 +361,221 @@
    * state by calling [getState], creates a new object by calling [construct]
    * and sets the new object's state by calling [setNonEssentialState].
    */
-  ClosureToMapRule(this.type, this.getState, this.construct,
+  ClosureRule(this.type, this.getStateFunction, this.construct,
       this.setNonEssentialState);
 
-  /**
-   * If we deserialize a ClosureToMapRule we can't actually use it, because
-   * we don't have the closures, so generate a stub that just returns the
-   * raw state object.
-   */
-  ClosureToMapRule.stub(this.type) {
-    getState = (x) { throw new SerializationException(
-        'Closures cannot be serialized'); };
-    construct = (state) => state;
-    setNonEssentialState = (object, state) {};
-  }
+  bool appliesTo(object, Writer w) => object.runtimeType == type;
 
-  bool appliesTo(object) => object.runtimeType == type;
+  getState(object) => getStateFunction(object);
 
-  extractState(object, Function f) {
-    Map state = getState(object);
-    values(state).forEach(f);
-    return state;
-  }
+  create(state) => construct(state);
 
-  // TODO(alanknight): We're inflating twice here. How to avoid doing
-  // that without giving the user even more stuff to specify.
-  // Worse than that, by inflating everything in advance, we are are
-  // forcing all the state to be essential.
-  Object inflateEssential(Map<String, Object> state, Reader r) {
-    var inflated = values(state).map((x) => r.inflateReference(x));
-    return construct(inflated);
-  }
-
-  void inflateNonEssential(state, object, Reader r) {
+  setState(object, state) {
     if (setNonEssentialState == null) return;
-    var inflated = values(state).map((x) => r.inflateReference(x));
-    setNonEssentialState(inflated, object);
+    setNonEssentialState(object, state);
   }
 }
 
 /**
  * This rule handles things we can't pass directly, but only by reference.
- * It extracts an identifier we can use to pass them.
+ * If objects are listed in the namedObjects in the writer or serialization,
+ * it will save the name rather than saving the state.
  */
-class ClassMirrorRule extends SerializationRule {
-  // TODO(alanknight): This probably generalizes to any named object.
-  bool appliesTo(object) {
-    return object is ClassMirror;
+class NamedObjectRule extends SerializationRule {
+  /**
+   * Return true if this rule applies to the object. Checked by looking up
+   * in the namedObjects collection.
+   */
+  bool appliesTo(object, Writer writer) {
+    return writer.hasNameFor(object);
   }
-  extractState(object, Function f) => f(object.simpleName);
-  void flatten(object, Writer writer) {}
-  inflateEssential(state, Reader r) => r.externalObjectNamed(state);
+
+  /** Extract the state of the named objects as just the object itself. */
+  extractState(object, Function f) => [object];
+
+  /** When we flatten the state we save it as the name. */
+  // TODO(alanknight): This seems questionable. In a truly flat format we may
+  // want to have extracted the name as a string first and flatten it into a
+  // reference to that. But that requires adding the Writer as a parameter to
+  // extractState, and I'm reluctant to add yet another parameter until
+  // proven necessary.
+  void flatten(state, Writer writer) {
+    state[0] = nameFor(state.first, writer);
+  }
+
+  /** Look up the named object and return it. */
+  inflateEssential(state, Reader r) => r.objectNamed(state.first);
+
+  /** Set any non-essential state on the object. For this rule, a no-op. */
   inflateNonEssential(state, object, Reader r) {}
+
+  /** Return the name for this object in the Writer. */
+  nameFor(object, Writer writer) => writer.nameFor(object);
+}
+
+/**
+ * This rule handles the special case of Mirrors, restricted to those that
+ * have a simpleName. It knows that it applies to any such mirror and
+ * automatically uses its simpleName as the key into the namedObjects.
+ * When reading, the user is still responsible for adding the appropriate
+ * mirrors to namedObject.
+ */
+class MirrorRule extends NamedObjectRule {
+  bool appliesTo(object, Writer writer) => object is DeclarationMirror;
+  nameFor(DeclarationMirror object, Writer writer) => object.simpleName;
+}
+
+/**
+ * This provides an abstract superclass for writing your own rules specific to
+ * a class. It makes some assumptions about behaviour, and so can have a
+ * simpler set of methods that need to be implemented in order to subclass it.
+ *
+ */
+abstract class CustomRule extends SerializationRule {
+  // TODO(alanknight): It would be nice if we could provide an implementation
+  // of appliesTo() here. If we add a type parameter to these classes
+  // we can "is" test against it, but we need to be able to rule out subclasses.
+  // => instance.runtimeType == T
+  // should work.
+  /**
+   * Return true if this rule applies to this object, in the context
+   * where we're writing it, false otherwise.
+   */
+  bool appliesTo(instance, Writer w);
+
+  /**
+   * Subclasses should implement this to return a list of the important fields
+   * in the object. The order of the fields doesn't matter, except that the
+   * create and setState methods need to know how to use it.
+   */
+  List getState(instance);
+
+  /**
+   * Given a [List] of the object's [state], re-create the object. This should
+   * do the minimum needed to create the object, just calling the constructor.
+   * Setting the remaining state of the object should be done in the [setState]
+   * method, which will be called only once all the objects are created, so
+   * it won't cause problems with cycles.
+   */
+  create(List state);
+
+  /**
+   * Set any state in [object] which wasn't set in the constructor. Between
+   * this method and [create] all of the information in [state] should be set
+   * in the new object.
+   */
+  void setState(object, List state);
+
+  extractState(instance, Function f) {
+    var state = getState(instance);
+    for (var each in values(state)) {
+      f(each);
+    }
+    return state;
+  }
+
+  inflateEssential(state, Reader r) => create(_lazy(state, r));
+
+  void inflateNonEssential(state, object, Reader r) =>
+      setState(object, _lazy(state, r));
+
+  // We don't want to have to make the end user tell us how long the list is
+  // separately, so write it out for each object, even though they're all
+  // expected to be the same length.
+  get writeLengthInFlatFormat => true;
+}
+
+/** Create a lazy list/map that will inflate its items on demand in [r]. */
+_lazy(l, Reader r) {
+  if (l is List) return new _LazyList(l, r);
+  if (l is Map) return new _LazyMap(l, r);
+  throw new SerializationException("Invalid type: must be Map or List - $l");
+}
+
+/**
+ * This provides an implementation of Map that wraps a list which may
+ * contain references to (potentially) non-inflated objects. If these
+ * are accessed it will inflate them. This allows us to pass something that
+ * looks like it's just a list of objects to a [CustomRule] without needing
+ * to inflate all the references in advance.
+ */
+class _LazyMap implements Map {
+  _LazyMap(this._raw, this._reader);
+
+  Map _raw;
+  Reader _reader;
+
+  // This is the only operation that really matters.
+  operator [](x) => _reader.inflateReference(_raw[x]);
+
+  int get length => _raw.length;
+  bool get isEmpty => _raw.isEmpty;
+  List get keys => _raw.keys;
+  bool containsKey(x) => _raw.containsKey(x);
+
+  // These operations will work, but may be expensive, and are probably
+  // best avoided.
+  get _inflated => keysAndValues(_raw).map(_reader.inflateReference);
+  bool containsValue(x) => _inflated.containsValue(x);
+  List get values => _inflated.values;
+  void forEach(f) => _inflated.forEach(f);
+
+  // These operations are all invalid
+  _throw() => throw new UnsupportedError("Not modifiable");
+  operator []=(x, y) => _throw();
+  putIfAbsent(x, y) => _throw();
+  remove(x) => _throw();
+  clear() => _throw();
+}
+
+/**
+ * This provides an implementation of List that wraps a list which may
+ * contain references to (potentially) non-inflated objects. If these
+ * are accessed it will inflate them. This allows us to pass something that
+ * looks like it's just a list of objects to a [CustomRule] without needing
+ * to inflate all the references in advance.
+ */
+class _LazyList implements List {
+  _LazyList(this._raw, this._reader);
+
+  List _raw;
+  Reader _reader;
+
+  // This is the only operation that really matters.
+  operator [](x) => _reader.inflateReference(_raw[x]);
+
+  int get length => _raw.length;
+  bool get isEmpty => _raw.isEmpty;
+  get first => _reader.inflateReference(_raw.first);
+  get last => _reader.inflateReference(_raw.last);
+
+  // These operations will work, but may be expensive, and are probably
+  // best avoided.
+  get _inflated => _raw.map(_reader.inflateReference);
+  map(f) => _inflated.map(f);
+  filter(f) => _inflated.filter(f);
+  bool contains(element) => _inflated.filter(element);
+  forEach(f) => _inflated.forEach(f);
+  reduce(x, f) => _inflated.reduce(x, f);
+  every(f) => _inflated(f);
+  some(f) => _inflated(f);
+  iterator() => _inflated.iterator();
+  indexOf(x, [pos = 0]) => _inflated.indexOf(x);
+  lastIndexOf(x, [pos]) => _inflated.lastIndexOf(x);
+
+  // These operations are all invalid
+  _throw() => throw new UnsupportedError("Not modifiable");
+  operator []=(x, y) => _throw();
+  add(x) => _throw();
+  addLast(x) => _throw();
+  addAll(x) => _throw();
+  sort([f]) => _throw();
+  clear() => _throw();
+  removeAt(x) => _throw();
+  removeLast() => _throw();
+  getRange(x, y) => _throw();
+  setRange(x, y, z, [a]) => _throw();
+  removeRange(x, y) => _throw();
+  insertRange(x, y, [z]) => _throw();
+  void set length(x) => _throw();
 }
\ No newline at end of file
diff --git a/pkg/serialization/test/polyfill_identity_set_test.dart b/pkg/serialization/test/polyfill_identity_map_test.dart
similarity index 75%
rename from pkg/serialization/test/polyfill_identity_set_test.dart
rename to pkg/serialization/test/polyfill_identity_map_test.dart
index b44d2cd..9988dca 100644
--- a/pkg/serialization/test/polyfill_identity_set_test.dart
+++ b/pkg/serialization/test/polyfill_identity_map_test.dart
@@ -10,8 +10,8 @@
 // Issue 4161.
 library identity_set_test;
 
-import '../../unittest/lib/unittest.dart';
-import '../lib/src/polyfill_identity_set.dart';
+import 'package:unittest/unittest.dart';
+import 'package:serialization/src/serialization_helpers.dart';
 
 class Foo {
   var x;
@@ -36,4 +36,13 @@
       expect(each, one);
     }
   });
+
+  test('uniquing primitives', () {
+    var map = new IdentityMap();
+    var one = 'one';
+    var two = new String.fromCharCodes(one.charCodes);
+    map[one] = 1;
+    expect(map[two], 1);
+    expect(map[one], 1);
+  });
 }
\ No newline at end of file
diff --git a/pkg/serialization/test/serialization_test.dart b/pkg/serialization/test/serialization_test.dart
index 345500a..3a16594 100644
--- a/pkg/serialization/test/serialization_test.dart
+++ b/pkg/serialization/test/serialization_test.dart
@@ -4,10 +4,10 @@
 
 library serialization_test;
 
-import '../../unittest/lib/unittest.dart';
-import '../lib/serialization.dart';
-import '../lib/src/serialization_helpers.dart';
-import '../lib/src/mirrors_helpers.dart';
+import 'package:unittest/unittest.dart';
+import 'package:serialization/serialization.dart';
+import 'package:serialization/src/serialization_helpers.dart';
+import 'package:serialization/src/mirrors_helpers.dart';
 
 part 'test_models.dart';
 
@@ -220,7 +220,7 @@
     runRoundTripTest(nodeSerializerReflective);
   });
 
-  test('round-trip hard-coded', () {
+  test('round-trip ClosureRule', () {
     runRoundTripTest(nodeSerializerNonReflective);
   });
 
@@ -236,6 +236,14 @@
     runRoundTripTest(nodeSerializerUsingMaps);
   });
 
+  test('round-trip with Node CustomRule', () {
+    runRoundTripTestFlat(nodeSerializerCustom);
+  });
+
+  test('round-trip with Node CustomRule, to maps', () {
+    runRoundTripTest(nodeSerializerCustom);
+  });
+
   test('eating your own tail', () {
     // Create a meta-serializer, that serializes serializations, then
     // use it to serialize a basic serialization, then run a test on the
@@ -246,7 +254,7 @@
     var meta = metaSerialization();
     var serialized = meta.write(s);
     var s2 = new Reader(meta)
-        .readOne(serialized, {"Node" : reflect(new Node('')).type});
+        .read(serialized, {"Node" : reflect(new Node('')).type});
     runRoundTripTest((x) => s2);
   });
 
@@ -257,7 +265,7 @@
     n3.parent = n1;
     var s = new Serialization()
       ..addRuleFor(n1, constructorFields: ["name"]).
-          specialTreatmentFor("children", (parent, child) =>
+          setFieldWith("children", (parent, child) =>
               parent.reflectee.children = child);
     var w = new Writer(s);
     w.write(n1);
@@ -285,7 +293,7 @@
       ..addRuleFor(n1, constructorFields: ["name"]);
     var w = new Writer(s);
     var r = new Reader(s);
-    var m1 = r.read(w.write(n1)).first;
+    var m1 = r.read(w.write(n1));
     var m2 = m1.children.first;
     var m3 = m1.children.last;
     expect(m1, m2);
@@ -294,6 +302,21 @@
     expect(identical(m2.parent, m3.parent), isTrue);
   });
 
+  test("Constant values as fields", () {
+    var s = new Serialization()
+      ..selfDescribing = false
+      ..addRuleFor(a1,
+          constructor: 'with',
+          constructorFields: ["street", "Kirkland", "WA", "98103"],
+          fields: []);
+    var out = s.write(a1);
+    var newAddress = s.read(out);
+    expect(newAddress.street, a1.street);
+    expect(newAddress.city, "Kirkland");
+    expect(newAddress.state, "WA");
+    expect(newAddress.zip, "98103");
+  });
+
 }
 
 /******************************************************************************
@@ -305,25 +328,25 @@
 Serialization metaSerialization() {
   // Make some bogus rule instances so we have something to feed rule creation
   // and get their types. If only we had class literals implemented...
-  var closureRule = new ClosureToMapRule.stub([].runtimeType);
   var basicRule = new BasicRule(reflect(null).type, '', [], [], []);
 
   var meta = new Serialization()
     ..selfDescribing = false
     ..addRuleFor(new ListRule())
     ..addRuleFor(new PrimitiveRule())
-    // TODO(alanknight): Handle the ClosureToMapRule as well.
+    // TODO(alanknight): Handle CustomRule as well.
     // Note that we're passing in a constant for one of the fields.
     ..addRuleFor(basicRule,
-        constructorFields: ['typeWrapped',
+        constructorFields: ['type',
           'constructorName',
           'constructorFields', 'regularFields', []],
         fields: [])
-     ..addRuleFor(new Serialization()).specialTreatmentFor('rules',
+     ..addRuleFor(new Serialization()).setFieldWith('rules',
          (InstanceMirror s, List rules) {
              rules.forEach((x) => s.reflectee.addRule(x));
          })
-    ..addRule(new ClassMirrorRule());
+    ..addRule(new NamedObjectRule())
+    ..addRule(new MirrorRule());
   return meta;
 }
 
@@ -332,7 +355,7 @@
  * reader.
  */
 readBackSimple(Serialization s, object, Reader reader) {
-  var rule = s.rulesFor(object)[0];
+  var rule = s.rulesFor(object, null)[0];
   reader.inflateForRule(rule);
   var list2 = reader.allObjectsForRule(rule)[0];
   return list2;
@@ -354,7 +377,7 @@
 Serialization nodeSerializerReflective(Node n) {
   return new Serialization()
     ..addRuleFor(n, constructorFields: ["name"])
-    ..externalObjects['Node'] = reflect(new Node('')).type;
+    ..namedObjects['Node'] = reflect(new Node('')).type;
 }
 
 /**
@@ -364,7 +387,16 @@
 Serialization nodeSerializerUsingMaps(Node n) {
   return new Serialization()
     ..addRuleFor(n, constructorFields: ["name"]).configureForMaps()
-    ..externalObjects['Node'] = reflect(new Node('')).type;
+    ..namedObjects['Node'] = reflect(new Node('')).type;
+}
+
+/**
+ * Return a serialization for Node objects but using Maps for the internal
+ * representation rather than lists.
+ */
+Serialization nodeSerializerCustom(Node n) {
+  return new Serialization()
+    ..addRule(new NodeRule());
 }
 
 /**
@@ -381,18 +413,18 @@
         constructor: "parentEssential",
         constructorFields: ["parent"])
     ..addDefaultRules()
-    ..externalObjects['Node'] = reflect(new Node('')).type
+    ..namedObjects['Node'] = reflect(new Node('')).type
     ..selfDescribing = false;
   return s;
 }
 
 /** Return a serialization for Node objects using a ClosureToMapRule. */
 Serialization nodeSerializerNonReflective(Node n) {
-  var rule = new ClosureToMapRule(
+  var rule = new ClosureRule(
       n.runtimeType,
       (o) => {"name" : o.name, "children" : o.children, "parent" : o.parent},
       (map) => new Node(map["name"]),
-      (map, object) {
+      (object, map) {
         object
           ..children = map["children"]
           ..parent = map["parent"];
@@ -415,7 +447,7 @@
   var output = s.write(n2);
   var s2 = serializerSetUp(n1);
   var reader = new Reader(s2);
-  var m2 = reader.readOne(output);
+  var m2 = reader.read(output);
   var m1 = m2.parent;
   expect(m1 is Node, isTrue);
   var children = m1.children;
@@ -442,7 +474,7 @@
   expect(output is List, isTrue);
   var s2 = serializerSetUp(n1);
   var reader = new Reader(s2);
-  var m2 = reader.readFlat(output).first;
+  var m2 = reader.readFlat(output);
   var m1 = m2.parent;
   expect(m1 is Node, isTrue);
   var children = m1.children;
@@ -456,7 +488,18 @@
 }
 
 /** Extract the state from [object] using the rules in [s] and return it. */
-states(Object object, Serialization s) {
-  var rules = s.rulesFor(object);
+states(object, Serialization s) {
+  var rules = s.rulesFor(object, null);
   return rules.map((x) => x.extractState(object, doNothing));
+}
+
+/** A hard-coded rule for serializing Node instances. */
+class NodeRule extends CustomRule {
+  bool appliesTo(instance, _) => instance is Node;
+  getState(instance) => [instance.parent, instance.name, instance.children];
+  create(state) => new Node(state[1]);
+  setState(Node node, state) {
+    node.parent = state[0];
+    node.children = state[2];
+  }
 }
\ No newline at end of file
diff --git a/pkg/serialization/test/test_models.dart b/pkg/serialization/test/test_models.dart
index 3f1d27c..0f4c417 100644
--- a/pkg/serialization/test/test_models.dart
+++ b/pkg/serialization/test/test_models.dart
@@ -13,6 +13,8 @@
 
 class Address {
   String street, city, state, zip;
+  Address();
+  Address.with(this.street, this.city, this.state, this.zip);
 }
 
 class Various {
diff --git a/pkg/unittest/lib/html_individual_config.dart b/pkg/unittest/lib/html_individual_config.dart
index 662f577..95e0514 100644
--- a/pkg/unittest/lib/html_individual_config.dart
+++ b/pkg/unittest/lib/html_individual_config.dart
@@ -12,15 +12,15 @@
  * start of your set sequence. Important constraint: your group descriptions
  * MUST NOT contain spaces.
  */
-#library('unittest');
+library unittest_html_individual_config;
 
-#import('unittest.dart', prefix: 'unittest');
-#import('html_config.dart', prefix: 'htmlconfig');
-#import('dart:html');
+import 'dart:html';
+import 'unittest.dart' as unittest;
+import 'html_config.dart' as htmlconfig;
 
 class HtmlIndividualConfiguration extends htmlconfig.HtmlConfiguration {
 
-  String _noSuchTest = ''; 
+  String _noSuchTest = '';
   HtmlIndividualConfiguration(isLayoutTest): super(isLayoutTest);
 
   void onStart() {
@@ -32,7 +32,6 @@
       } catch (e) {
         print('tried to match "$testGroupName"');
         print('NO_SUCH_TEST');
-        exit(1);
       }
     }
     super.onStart();
diff --git a/pkg/unittest/lib/src/config.dart b/pkg/unittest/lib/src/config.dart
index cd0f365..e3a788e 100644
--- a/pkg/unittest/lib/src/config.dart
+++ b/pkg/unittest/lib/src/config.dart
@@ -12,6 +12,9 @@
  */
 
 class Configuration {
+  // The VM won't shut down if a receive port is open. Use this to make sure
+  // we correctly wait for asynchronous tests.
+  ReceivePort _receivePort;
   TestCase currentTestCase = null;
 
   /**
@@ -39,6 +42,7 @@
    * wait until they are done.
    */
   void onStart() {
+    _receivePort = new ReceivePort();
     _postMessage('unittest-suite-wait-for-done');
   }
 
@@ -96,7 +100,8 @@
       String uncaughtError) {
     // Print each test's result.
     for (final t in _tests) {
-      print('${t.result.toUpperCase()}: ${t.description}');
+      var resultString = "${t.result}".toUpperCase();
+      print('$resultString: ${t.description}');
 
       if (t.message != '') {
         print(_indent(t.message));
@@ -124,6 +129,7 @@
       print('$passed PASSED, $failed FAILED, $errors ERRORS');
     }
 
+    _receivePort.close();
     if (success) {
       _postMessage('unittest-suite-success');
     } else {
diff --git a/pkg/unittest/test/instance_test.dart b/pkg/unittest/test/instance_test.dart
index 889d078..deb1c21 100644
--- a/pkg/unittest/test/instance_test.dart
+++ b/pkg/unittest/test/instance_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library unittestTests;
-import '../../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
 
 part 'test_utils.dart';
 
diff --git a/pkg/unittest/test/matchers_test.dart b/pkg/unittest/test/matchers_test.dart
index 81be8fb..d1d998a 100644
--- a/pkg/unittest/test/matchers_test.dart
+++ b/pkg/unittest/test/matchers_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library unittestTests;
-import '../../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
 part 'test_utils.dart';
 
 doesNotThrow() {}
diff --git a/pkg/unittest/test/mock_regexp_negative_test.dart b/pkg/unittest/test/mock_regexp_negative_test.dart
index 91811f5..c682e9b 100644
--- a/pkg/unittest/test/mock_regexp_negative_test.dart
+++ b/pkg/unittest/test/mock_regexp_negative_test.dart
@@ -3,14 +3,14 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library mock_regexp_negative_test;
-import '../../../pkg/unittest/lib/unittest.dart';
-import '../../../pkg/unittest/lib/mock.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/mock.dart';
 
 main() {
   test('Mocking: RegExp CallMatcher bad', () {
-    var m = new Mock();           
-    m.when(callsTo(matches('^[A-Z]'))).          
-           alwaysThrow('Method names must start with lower case.');      
-    m.Test();         
+    var m = new Mock();
+    m.when(callsTo(matches('^[A-Z]'))).
+           alwaysThrow('Method names must start with lower case.');
+    m.Test();
   });
 }
diff --git a/pkg/unittest/test/mock_stepwise_negative_test.dart b/pkg/unittest/test/mock_stepwise_negative_test.dart
index b6bbaf8..8bf4955 100644
--- a/pkg/unittest/test/mock_stepwise_negative_test.dart
+++ b/pkg/unittest/test/mock_stepwise_negative_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library mock_stepwise_negative_test;
-import '../../../pkg/unittest/lib/unittest.dart';
-import '../../../pkg/unittest/lib/mock.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/mock.dart';
 
 main() {
   test('Mocking: stepwiseValidate', () {
diff --git a/pkg/unittest/test/mock_test.dart b/pkg/unittest/test/mock_test.dart
index 7a6534d..4989a66 100644
--- a/pkg/unittest/test/mock_test.dart
+++ b/pkg/unittest/test/mock_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library mock_test;
-import '../../../pkg/unittest/lib/unittest.dart';
-import '../../../pkg/unittest/lib/mock.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/mock.dart';
 
 class MockList extends Mock implements List {
 }
@@ -167,11 +167,11 @@
     m.getLogs(null, returning(4)).verify(happenedExactly(2));
   });
 
-  test('Mocking: RegExp CallMatcher good', () {	
-    var m = new Mock();	
-    m.when(callsTo(matches('^[A-Z]'))).	
-           alwaysThrow('Method names must start with lower case.');	
-    m.test();	
+  test('Mocking: RegExp CallMatcher good', () {
+    var m = new Mock();
+    m.when(callsTo(matches('^[A-Z]'))).
+           alwaysThrow('Method names must start with lower case.');
+    m.test();
   });
 
   test('Mocking: No logging', () {
@@ -601,7 +601,7 @@
         expect(log[pos + 1].args[0] - log[pos].args[0], equals(1));
         return 2;
     });
-    expect(total, equals((0 * 1) + (2 * 3) + (4 * 5) + (6 * 7) + (8 * 9))); 
+    expect(total, equals((0 * 1) + (2 * 3) + (4 * 5) + (6 * 7) + (8 * 9)));
   });
 
   test('Mocking: clearLogs', () {
diff --git a/pkg/unittest/test/unittest_test.dart b/pkg/unittest/test/unittest_test.dart
index c7a474f..68d295d 100644
--- a/pkg/unittest/test/unittest_test.dart
+++ b/pkg/unittest/test/unittest_test.dart
@@ -11,7 +11,7 @@
 
 library unittestTest;
 import 'dart:isolate';
-import '../../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
 
 var tests; // array of test names
 var expected; // array of test expected results (from buildStatusString)
diff --git a/pkg/unittest/test_controller.js b/pkg/unittest/test_controller.js
index 5a7db1e..5332c19 100644
--- a/pkg/unittest/test_controller.js
+++ b/pkg/unittest/test_controller.js
@@ -83,12 +83,17 @@
 
 window.addEventListener("DOMContentLoaded", onLoad, false);
 
-// If nobody intercepts the error, finish the test.
-window.addEventListener("error", function(e) {
+// Note: before renaming this function, note that it is also included in an
+// inlined error handler in the HTML files that wrap DRT tests.
+// See: tools/testing/dart/browser_test.dart
+function externalError(e) {
   // needed for dartium compilation errors.
   showErrorAndExit(e && e.message);
   window.postMessage('unittest-suite-external-error', '*');
-}, false);
+}
+
+// If nobody intercepts the error, finish the test.
+window.addEventListener("error", externalError, false);
 
 document.addEventListener('readystatechange', function () {
   if (document.readyState != "loaded") return;
diff --git a/pkg/webdriver/test/webdrivertest.dart b/pkg/webdriver/test/webdrivertest.dart
index 69b8073..8d9c0ac 100644
--- a/pkg/webdriver/test/webdrivertest.dart
+++ b/pkg/webdriver/test/webdrivertest.dart
@@ -1,6 +1,6 @@
 library webdriver_test;
-import '../webdriver.dart';
-import '../../../pkg/unittest/lib/unittest.dart';
+import 'package:webdriver/webdriver.dart';
+import 'package:unittest/unittest.dart';
 
 WebDriver web_driver;
 
diff --git a/runtime/.gitignore b/runtime/.gitignore
index adaa849..ea75f3c 100644
--- a/runtime/.gitignore
+++ b/runtime/.gitignore
@@ -1,5 +1,6 @@
 /Makefile
 /out
+/pkg
 /runtime
 /xcodebuild
 /*.Makefile
diff --git a/runtime/bin/builtin_natives.cc b/runtime/bin/builtin_natives.cc
index 8fedb2d..85bb4d7 100644
--- a/runtime/bin/builtin_natives.cc
+++ b/runtime/bin/builtin_natives.cc
@@ -23,8 +23,8 @@
   V(Directory_CreateTemp, 1)                                                   \
   V(Directory_Delete, 2)                                                       \
   V(Directory_Rename, 2)                                                       \
+  V(Directory_List, 2)                                                         \
   V(Directory_NewServicePort, 0)                                               \
-  V(Exit, 1)                                                                   \
   V(File_Open, 2)                                                              \
   V(File_Exists, 1)                                                            \
   V(File_Close, 1)                                                             \
@@ -104,13 +104,3 @@
   Builtin::PrintString(stdout, Dart_GetNativeArgument(args, 0));
   Dart_ExitScope();
 }
-
-
-void FUNCTION_NAME(Exit)(Dart_NativeArguments args) {
-  Dart_EnterScope();
-  int64_t status = 0;
-  // Ignore result if passing invalid argument and just exit 0.
-  DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 0), &status);
-  Dart_ExitScope();
-  exit(static_cast<int>(status));
-}
diff --git a/runtime/bin/dbg_connection.cc b/runtime/bin/dbg_connection.cc
index 4918d0d..b6f261f 100644
--- a/runtime/bin/dbg_connection.cc
+++ b/runtime/bin/dbg_connection.cc
@@ -108,7 +108,8 @@
   }
   // TODO(hausner): Handle error conditions returned by Read. We may
   // want to close the debugger connection if we get any errors.
-  int bytes_read = Socket::Read(fd_, buf_ + data_length_, max_read);
+  int bytes_read =
+      DebuggerConnectionImpl::Receive(fd_, buf_ + data_length_, max_read);
   if (bytes_read == 0) {
     connection_is_alive_ = false;
     return;
@@ -284,6 +285,11 @@
   // First setup breakpoint, exception and delayed breakpoint handlers.
   DbgMsgQueueList::Initialize();
 
+  // Initialize the socket implementation.
+  if (!Socket::Initialize()) {
+    FATAL("Failed initializing socket implementation.");
+  }
+
   // Now setup a listener socket and start a thread which will
   // listen, accept connections from debuggers, read and handle/dispatch
   // debugger commands received on these connections.
@@ -335,7 +341,7 @@
         piece_len = max_piece_len;
       }
       intptr_t written =
-        Socket::Write(debug_fd, msg->buf() + sent, piece_len);
+          DebuggerConnectionImpl::Send(debug_fd, msg->buf() + sent, piece_len);
       ASSERT(written == piece_len);
       sent += written;
       remaining -= written;
@@ -347,7 +353,8 @@
     }
     return;
   }
-  intptr_t bytes_written = Socket::Write(debug_fd, msg->buf(), msg->length());
+  intptr_t bytes_written =
+      DebuggerConnectionImpl::Send(debug_fd, msg->buf(), msg->length());
   ASSERT(msg->length() == bytes_written);
   // TODO(hausner): Error checking. Probably just shut down the debugger
   // session if we there is an error while writing.
diff --git a/runtime/bin/dbg_connection_android.cc b/runtime/bin/dbg_connection_android.cc
index a0bce37..ce25559 100644
--- a/runtime/bin/dbg_connection_android.cc
+++ b/runtime/bin/dbg_connection_android.cc
@@ -103,3 +103,15 @@
     FATAL1("Failed to start debugger connection handler thread: %d\n", result);
   }
 }
+
+
+intptr_t DebuggerConnectionImpl::Send(intptr_t socket,
+                                      const char* buf,
+                                      int len) {
+  return TEMP_FAILURE_RETRY(write(socket, buf, len));
+}
+
+
+intptr_t DebuggerConnectionImpl::Receive(intptr_t socket, char* buf, int len) {
+  return TEMP_FAILURE_RETRY(read(socket, buf, len));
+}
diff --git a/runtime/bin/dbg_connection_android.h b/runtime/bin/dbg_connection_android.h
index f40ecd3..f762c73 100644
--- a/runtime/bin/dbg_connection_android.h
+++ b/runtime/bin/dbg_connection_android.h
@@ -13,6 +13,8 @@
 class DebuggerConnectionImpl {
  public:
   static void StartHandler(int port_number);
+  static intptr_t Send(intptr_t socket, const char* buf, int len);
+  static intptr_t Receive(intptr_t socket, char* buf, int len);
 
  private:
   static void SetupPollQueue();
diff --git a/runtime/bin/dbg_connection_linux.cc b/runtime/bin/dbg_connection_linux.cc
index a0bce37..ce25559 100644
--- a/runtime/bin/dbg_connection_linux.cc
+++ b/runtime/bin/dbg_connection_linux.cc
@@ -103,3 +103,15 @@
     FATAL1("Failed to start debugger connection handler thread: %d\n", result);
   }
 }
+
+
+intptr_t DebuggerConnectionImpl::Send(intptr_t socket,
+                                      const char* buf,
+                                      int len) {
+  return TEMP_FAILURE_RETRY(write(socket, buf, len));
+}
+
+
+intptr_t DebuggerConnectionImpl::Receive(intptr_t socket, char* buf, int len) {
+  return TEMP_FAILURE_RETRY(read(socket, buf, len));
+}
diff --git a/runtime/bin/dbg_connection_linux.h b/runtime/bin/dbg_connection_linux.h
index 8cab971..12b0395 100644
--- a/runtime/bin/dbg_connection_linux.h
+++ b/runtime/bin/dbg_connection_linux.h
@@ -13,6 +13,8 @@
 class DebuggerConnectionImpl {
  public:
   static void StartHandler(int port_number);
+  static intptr_t Send(intptr_t socket, const char* buf, int len);
+  static intptr_t Receive(intptr_t socket, char* buf, int len);
 
  private:
   static void SetupPollQueue();
diff --git a/runtime/bin/dbg_connection_macos.cc b/runtime/bin/dbg_connection_macos.cc
index 8464abf..675e129 100644
--- a/runtime/bin/dbg_connection_macos.cc
+++ b/runtime/bin/dbg_connection_macos.cc
@@ -157,3 +157,15 @@
     FATAL1("Failed to start debugger connection handler thread: %d\n", result);
   }
 }
+
+
+intptr_t DebuggerConnectionImpl::Send(intptr_t socket,
+                                      const char* buf,
+                                      int len) {
+  return TEMP_FAILURE_RETRY(write(socket, buf, len));
+}
+
+
+intptr_t DebuggerConnectionImpl::Receive(intptr_t socket, char* buf, int len) {
+  return TEMP_FAILURE_RETRY(read(socket, buf, len));
+}
diff --git a/runtime/bin/dbg_connection_macos.h b/runtime/bin/dbg_connection_macos.h
index 0bd8634..f6962ff 100644
--- a/runtime/bin/dbg_connection_macos.h
+++ b/runtime/bin/dbg_connection_macos.h
@@ -13,6 +13,8 @@
 class DebuggerConnectionImpl {
  public:
   static void StartHandler(int port_number);
+  static intptr_t Send(intptr_t socket, const char* buf, int len);
+  static intptr_t Receive(intptr_t socket, char* buf, int len);
 
  private:
   enum MessageType {
diff --git a/runtime/bin/dbg_connection_win.cc b/runtime/bin/dbg_connection_win.cc
index 505e970..1c9bf54 100644
--- a/runtime/bin/dbg_connection_win.cc
+++ b/runtime/bin/dbg_connection_win.cc
@@ -4,7 +4,38 @@
 
 #include "bin/dbg_connection.h"
 
-void DebuggerConnectionImpl::StartHandler(int port_number) {
-  FATAL("Debugger wire protocol not yet implemented on Linux\n");
+#include "bin/eventhandler.h"
+
+void DebuggerConnectionImpl::ThreadEntry(uword args) {
+  ListenSocket* listen_socket =
+      reinterpret_cast<ListenSocket*>(DebuggerConnectionHandler::listener_fd_);
+  SOCKET client_socket = accept(listen_socket->socket(), NULL, NULL);
+  if (client_socket == INVALID_SOCKET) {
+    FATAL("Accepting new debugger connection failed.\n");
+  }
+  ClientSocket* socket = new ClientSocket(client_socket);
+  DebuggerConnectionHandler::AcceptDbgConnection(reinterpret_cast<int>(socket));
 }
 
+
+void DebuggerConnectionImpl::StartHandler(int port_number) {
+  ASSERT(DebuggerConnectionHandler::listener_fd_ != -1);
+  int result = dart::Thread::Start(&DebuggerConnectionImpl::ThreadEntry, 0);
+  if (result != 0) {
+    FATAL1("Failed to start debugger connection handler thread: %d\n", result);
+  }
+}
+
+
+intptr_t DebuggerConnectionImpl::Send(intptr_t socket,
+                                      const char* buf,
+                                      int len) {
+  ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(socket);
+  return send(client_socket->socket(), buf, len, 0);
+}
+
+
+intptr_t DebuggerConnectionImpl::Receive(intptr_t socket, char* buf, int len) {
+  ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(socket);
+  return recv(client_socket->socket(), buf, len, 0);
+}
diff --git a/runtime/bin/dbg_connection_win.h b/runtime/bin/dbg_connection_win.h
index 6b3da1b..24ac711 100644
--- a/runtime/bin/dbg_connection_win.h
+++ b/runtime/bin/dbg_connection_win.h
@@ -5,11 +5,14 @@
 #ifndef BIN_DBG_CONNECTION_WIN_H_
 #define BIN_DBG_CONNECTION_WIN_H_
 
-
-
 class DebuggerConnectionImpl {
  public:
   static void StartHandler(int port_number);
+  static intptr_t Send(intptr_t socket, const char* buf, int len);
+  static intptr_t Receive(intptr_t socket, char* buf, int len);
+
+ private:
+  static void ThreadEntry(uword args);
 };
 
 #endif  // BIN_DBG_CONNECTION_WIN_H_
diff --git a/runtime/bin/dbg_message.cc b/runtime/bin/dbg_message.cc
index 43fa850..112cf96 100644
--- a/runtime/bin/dbg_message.cc
+++ b/runtime/bin/dbg_message.cc
@@ -126,11 +126,10 @@
 
 
 static void FormatErrorMsg(dart::TextBuffer* buf, Dart_Handle err) {
-  // TODO(hausner): Turn message into Dart string and
-  // properly encode the message.
   ASSERT(Dart_IsError(err));
   const char* msg = Dart_GetError(err);
-  buf->Printf("\"%s\"", msg);
+  Dart_Handle str = Dart_NewStringFromCString(msg);
+  FormatEncodedString(buf, str);
 }
 
 
diff --git a/runtime/bin/directory.cc b/runtime/bin/directory.cc
index cc37c28..a4b5e08 100644
--- a/runtime/bin/directory.cc
+++ b/runtime/bin/directory.cc
@@ -107,6 +107,26 @@
 }
 
 
+void FUNCTION_NAME(Directory_List)(Dart_NativeArguments args) {
+  Dart_EnterScope();
+  Dart_Handle path = Dart_GetNativeArgument(args, 0);
+  Dart_Handle recursive = Dart_GetNativeArgument(args, 1);
+  // Create the list to hold the directory listing here, and pass it to the
+  // SyncDirectoryListing object, which adds elements to it.
+  Dart_Handle results =
+      Dart_New(DartUtils::GetDartClass(DartUtils::kCoreLibURL, "List"),
+               Dart_Null(),
+               0,
+               NULL);
+  SyncDirectoryListing sync_listing(results);
+  Directory::List(DartUtils::GetStringValue(path),
+                  DartUtils::GetBooleanValue(recursive),
+                  &sync_listing);
+  Dart_SetReturnValue(args, results);
+  Dart_ExitScope();
+}
+
+
 static CObject* DirectoryCreateRequest(const CObjectArray& request) {
   if (request.Length() == 2 && request[1]->IsString()) {
     CObjectString path(request[1]);
@@ -171,7 +191,8 @@
 static CObject* DirectoryListRequest(const CObjectArray& request,
                                      Dart_Port response_port) {
   if (request.Length() == 3 && request[1]->IsString() && request[2]->IsBool()) {
-    DirectoryListing* dir_listing = new DirectoryListing(response_port);
+    AsyncDirectoryListing* dir_listing =
+        new AsyncDirectoryListing(response_port);
     CObjectString path(request[1]);
     CObjectBool recursive(request[2]);
     bool completed = Directory::List(
@@ -179,21 +200,22 @@
     delete dir_listing;
     CObjectArray* response = new CObjectArray(CObject::NewArray(2));
     response->SetAt(
-        0, new CObjectInt32(CObject::NewInt32(DirectoryListing::kListDone)));
+        0,
+        new CObjectInt32(CObject::NewInt32(AsyncDirectoryListing::kListDone)));
     response->SetAt(1, CObject::Bool(completed));
     return response;
   }
   // Respond with an illegal argument list error message.
   CObjectArray* response = new CObjectArray(CObject::NewArray(3));
   response->SetAt(0, new CObjectInt32(
-      CObject::NewInt32(DirectoryListing::kListError)));
+      CObject::NewInt32(AsyncDirectoryListing::kListError)));
   response->SetAt(1, CObject::Null());
   response->SetAt(2, CObject::IllegalArgumentError());
   Dart_PostCObject(response_port, response->AsApiCObject());
 
   response = new CObjectArray(CObject::NewArray(2));
   response->SetAt(
-      0, new CObjectInt32(CObject::NewInt32(DirectoryListing::kListDone)));
+      0, new CObjectInt32(CObject::NewInt32(AsyncDirectoryListing::kListDone)));
   response->SetAt(1, CObject::False());
   return response;
 }
@@ -289,7 +311,7 @@
 }
 
 
-CObjectArray* DirectoryListing::NewResponse(Response type, char* arg) {
+CObjectArray* AsyncDirectoryListing::NewResponse(Response type, char* arg) {
   CObjectArray* response = new CObjectArray(CObject::NewArray(2));
   response->SetAt(0, new CObjectInt32(CObject::NewInt32(type)));
   response->SetAt(1, new CObjectString(CObject::NewString(arg)));
@@ -297,19 +319,19 @@
 }
 
 
-bool DirectoryListing::HandleDirectory(char* dir_name) {
+bool AsyncDirectoryListing::HandleDirectory(char* dir_name) {
   CObjectArray* response = NewResponse(kListDirectory, dir_name);
   return Dart_PostCObject(response_port_, response->AsApiCObject());
 }
 
 
-bool DirectoryListing::HandleFile(char* file_name) {
+bool AsyncDirectoryListing::HandleFile(char* file_name) {
   CObjectArray* response = NewResponse(kListFile, file_name);
   return Dart_PostCObject(response_port_, response->AsApiCObject());
 }
 
 
-bool DirectoryListing::HandleError(const char* dir_name) {
+bool AsyncDirectoryListing::HandleError(const char* dir_name) {
   CObject* err = CObject::NewOSError();
   CObjectArray* response = new CObjectArray(CObject::NewArray(3));
   response->SetAt(0, new CObjectInt32(CObject::NewInt32(kListError)));
@@ -317,3 +339,31 @@
   response->SetAt(2, err);
   return Dart_PostCObject(response_port_, response->AsApiCObject());
 }
+
+bool SyncDirectoryListing::HandleDirectory(char* dir_name) {
+  Dart_Handle dir_name_dart = DartUtils::NewString(dir_name);
+  Dart_Handle dir = Dart_New(directory_class_, Dart_Null(), 1, &dir_name_dart);
+  Dart_Invoke(results_, add_string_, 1, &dir);
+  return true;
+}
+
+bool SyncDirectoryListing::HandleFile(char* file_name) {
+  Dart_Handle file_name_dart = DartUtils::NewString(file_name);
+  Dart_Handle file = Dart_New(file_class_, Dart_Null(), 1, &file_name_dart);
+  Dart_Invoke(results_, add_string_, 1, &file);
+  return true;
+}
+
+bool SyncDirectoryListing::HandleError(const char* dir_name) {
+  Dart_Handle dart_os_error = DartUtils::NewDartOSError();
+  Dart_Handle args[3];
+  args[0] = DartUtils::NewString("Directory listing failed");
+  args[1] = DartUtils::NewString(dir_name);
+  args[2] = dart_os_error;
+  Dart_ThrowException(Dart_New(
+      DartUtils::GetDartClass(DartUtils::kIOLibURL, "DirectoryIOException"),
+      Dart_Null(),
+      3,
+      args));
+  return true;
+}
diff --git a/runtime/bin/directory.h b/runtime/bin/directory.h
index 9455bbb..b038ad1 100644
--- a/runtime/bin/directory.h
+++ b/runtime/bin/directory.h
@@ -12,6 +12,15 @@
 
 class DirectoryListing {
  public:
+  virtual ~DirectoryListing() {}
+  virtual bool HandleDirectory(char* dir_name) = 0;
+  virtual bool HandleFile(char* file_name) = 0;
+  virtual bool HandleError(const char* dir_name) = 0;
+};
+
+
+class AsyncDirectoryListing : public DirectoryListing {
+ public:
   enum Response {
     kListDirectory = 0,
     kListFile = 1,
@@ -19,17 +28,43 @@
     kListDone = 3
   };
 
-  explicit DirectoryListing(Dart_Port response_port)
+  explicit AsyncDirectoryListing(Dart_Port response_port)
       : response_port_(response_port) {}
-  bool HandleDirectory(char* dir_name);
-  bool HandleFile(char* file_name);
-  bool HandleError(const char* dir_name);
+  virtual ~AsyncDirectoryListing() {}
+  virtual bool HandleDirectory(char* dir_name);
+  virtual bool HandleFile(char* file_name);
+  virtual bool HandleError(const char* dir_name);
 
  private:
   CObjectArray* NewResponse(Response response, char* arg);
   Dart_Port response_port_;
 
-  DISALLOW_IMPLICIT_CONSTRUCTORS(DirectoryListing);
+  DISALLOW_IMPLICIT_CONSTRUCTORS(AsyncDirectoryListing);
+};
+
+
+class SyncDirectoryListing: public DirectoryListing {
+ public:
+  explicit SyncDirectoryListing(Dart_Handle results)
+      : results_(results) {
+    add_string_ = DartUtils::NewString("add");
+    directory_class_ =
+        DartUtils::GetDartClass(DartUtils::kIOLibURL, "Directory");
+    file_class_ =
+        DartUtils::GetDartClass(DartUtils::kIOLibURL, "File");
+  }
+  virtual ~SyncDirectoryListing() {}
+  virtual bool HandleDirectory(char* dir_name);
+  virtual bool HandleFile(char* file_name);
+  virtual bool HandleError(const char* dir_name);
+
+ private:
+  Dart_Handle results_;
+  Dart_Handle add_string_;
+  Dart_Handle directory_class_;
+  Dart_Handle file_class_;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(SyncDirectoryListing);
 };
 
 
diff --git a/runtime/bin/directory_patch.dart b/runtime/bin/directory_patch.dart
index 6d42f8b..cb844f7 100644
--- a/runtime/bin/directory_patch.dart
+++ b/runtime/bin/directory_patch.dart
@@ -11,6 +11,8 @@
       native "Directory_Delete";
   /* patch */ static _rename(String path, String newPath)
       native "Directory_Rename";
+  /* patch */ static List _list(String path, bool recursive)
+      native "Directory_List";
   /* patch */ static SendPort _newServicePort()
       native "Directory_NewServicePort";
 }
diff --git a/runtime/bin/eventhandler_android.cc b/runtime/bin/eventhandler_android.cc
index 878c7eb..9c2b619 100644
--- a/runtime/bin/eventhandler_android.cc
+++ b/runtime/bin/eventhandler_android.cc
@@ -105,6 +105,8 @@
     FATAL("Pipe creation failed");
   }
   FDUtils::SetNonBlocking(interrupt_fds_[0]);
+  FDUtils::SetCloseOnExec(interrupt_fds_[0]);
+  FDUtils::SetCloseOnExec(interrupt_fds_[1]);
   timeout_ = kInfinityTimeout;
   timeout_port_ = 0;
   shutdown_ = false;
@@ -115,6 +117,7 @@
   if (epoll_fd_ == -1) {
     FATAL("Failed creating epoll file descriptor");
   }
+  FDUtils::SetCloseOnExec(epoll_fd_);
   // Register the interrupt_fd with the epoll instance.
   struct epoll_event event;
   event.events = EPOLLIN;
diff --git a/runtime/bin/eventhandler_linux.cc b/runtime/bin/eventhandler_linux.cc
index 49b6ca1..869e8bb 100644
--- a/runtime/bin/eventhandler_linux.cc
+++ b/runtime/bin/eventhandler_linux.cc
@@ -105,6 +105,8 @@
     FATAL("Pipe creation failed");
   }
   FDUtils::SetNonBlocking(interrupt_fds_[0]);
+  FDUtils::SetCloseOnExec(interrupt_fds_[0]);
+  FDUtils::SetCloseOnExec(interrupt_fds_[1]);
   timeout_ = kInfinityTimeout;
   timeout_port_ = 0;
   shutdown_ = false;
@@ -115,6 +117,7 @@
   if (epoll_fd_ == -1) {
     FATAL("Failed creating epoll file descriptor");
   }
+  FDUtils::SetCloseOnExec(epoll_fd_);
   // Register the interrupt_fd with the epoll instance.
   struct epoll_event event;
   event.events = EPOLLIN;
diff --git a/runtime/bin/eventhandler_macos.cc b/runtime/bin/eventhandler_macos.cc
index 3954190..51f1e70 100644
--- a/runtime/bin/eventhandler_macos.cc
+++ b/runtime/bin/eventhandler_macos.cc
@@ -123,6 +123,8 @@
     FATAL("Pipe creation failed");
   }
   FDUtils::SetNonBlocking(interrupt_fds_[0]);
+  FDUtils::SetCloseOnExec(interrupt_fds_[0]);
+  FDUtils::SetCloseOnExec(interrupt_fds_[1]);
   timeout_ = kInfinityTimeout;
   timeout_port_ = 0;
   shutdown_ = false;
@@ -131,6 +133,7 @@
   if (kqueue_fd_ == -1) {
     FATAL("Failed creating kqueue");
   }
+  FDUtils::SetCloseOnExec(kqueue_fd_);
   // Register the interrupt_fd with the kqueue.
   struct kevent event;
   EV_SET(&event, interrupt_fds_[0], EVFILT_READ, EV_ADD, 0, 0, NULL);
diff --git a/runtime/bin/eventhandler_win.cc b/runtime/bin/eventhandler_win.cc
index bc2f480..87706e8 100644
--- a/runtime/bin/eventhandler_win.cc
+++ b/runtime/bin/eventhandler_win.cc
@@ -97,28 +97,30 @@
 
 Handle::Handle(HANDLE handle)
     : handle_(reinterpret_cast<HANDLE>(handle)),
-      flags_(0),
       port_(0),
+      mask_(0),
       completion_port_(INVALID_HANDLE_VALUE),
       event_handler_(NULL),
       data_ready_(NULL),
       pending_read_(NULL),
       pending_write_(NULL),
-      last_error_(NOERROR) {
+      last_error_(NOERROR),
+      flags_(0) {
   InitializeCriticalSection(&cs_);
 }
 
 
 Handle::Handle(HANDLE handle, Dart_Port port)
     : handle_(reinterpret_cast<HANDLE>(handle)),
-      flags_(0),
       port_(port),
+      mask_(0),
       completion_port_(INVALID_HANDLE_VALUE),
       event_handler_(NULL),
       data_ready_(NULL),
       pending_read_(NULL),
       pending_write_(NULL),
-      last_error_(NOERROR) {
+      last_error_(NOERROR),
+      flags_(0) {
   InitializeCriticalSection(&cs_);
 }
 
@@ -258,12 +260,13 @@
       pending_read_ = buffer;
       return true;
     }
-
-    if (GetLastError() != ERROR_BROKEN_PIPE) {
-      Log::PrintErr("ReadFile failed: %d\n", GetLastError());
-    }
-    event_handler_->HandleClosed(this);
     IOBuffer::DisposeBuffer(buffer);
+
+    if (GetLastError() == ERROR_BROKEN_PIPE) {
+      event_handler_->HandleClosed(this);
+    } else {
+      event_handler_->HandleError(this);
+    }
     return false;
   } else {
     // Completing asynchronously through thread.
@@ -297,12 +300,13 @@
     pending_write_ = buffer;
     return true;
   }
-
-  if (GetLastError() != ERROR_BROKEN_PIPE) {
-    Log::PrintErr("WriteFile failed: %d\n", GetLastError());
-  }
-  event_handler_->HandleClosed(this);
   IOBuffer::DisposeBuffer(buffer);
+
+  if (GetLastError() == ERROR_BROKEN_PIPE) {
+    event_handler_->HandleClosed(this);
+  } else {
+    event_handler_->HandleError(this);
+  }
   return false;
 }
 
@@ -558,12 +562,14 @@
     pending_read_ = buffer;
     return true;
   }
-
-  if (WSAGetLastError() != WSAECONNRESET) {
-    Log::PrintErr("WSARecv failed: %d\n", WSAGetLastError());
-  }
-  event_handler_->HandleClosed(this);
   IOBuffer::DisposeBuffer(buffer);
+  pending_read_ = NULL;
+
+  if (WSAGetLastError() == WSAECONNRESET) {
+    event_handler_->HandleClosed(this);
+  } else {
+    event_handler_->HandleError(this);
+  }
   return false;
 }
 
@@ -584,10 +590,14 @@
   if (rc == NO_ERROR || WSAGetLastError() == WSA_IO_PENDING) {
     return true;
   }
-
-  Log::PrintErr("WSASend failed: %d\n", WSAGetLastError());
   IOBuffer::DisposeBuffer(pending_write_);
   pending_write_ = NULL;
+
+  if (WSAGetLastError() == WSAECONNRESET) {
+    event_handler_->HandleClosed(this);
+  } else {
+    event_handler_->HandleError(this);
+  }
   return false;
 }
 
@@ -657,36 +667,41 @@
 
       Handle::ScopedLock lock(handle);
 
-      // If the data available callback has been requested and data are
-      // available post it immediately. Otherwise make sure that a pending
-      // read is issued unless the socket is already closed for read.
-      if ((msg->data & (1 << kInEvent)) != 0) {
-        if (handle->Available() > 0) {
-          int event_mask = (1 << kInEvent);
-          DartUtils::PostInt32(handle->port(), event_mask);
-        } else if (!handle->HasPendingRead() &&
-                   !handle->IsClosedRead()) {
-          handle->IssueRead();
-        }
-      }
-
-      // If can send callback had been requested and there is no pending
-      // send post it immediately.
-      if ((msg->data & (1 << kOutEvent)) != 0) {
-        if (!handle->HasPendingWrite()) {
-          int event_mask = (1 << kOutEvent);
-          DartUtils::PostInt32(handle->port(), event_mask);
-        }
-      }
-
-      if (handle->is_client_socket()) {
-        ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(handle);
-        if ((msg->data & (1 << kShutdownReadCommand)) != 0) {
-          client_socket->Shutdown(SD_RECEIVE);
+      if (!handle->IsError()) {
+        // If in events (data available events) have been requested, and data
+        // is available, post an in event immediately. Otherwise make sure
+        // that a pending read is issued, unless the socket is already closed
+        // for read.
+        if ((msg->data & (1 << kInEvent)) != 0) {
+          if (handle->Available() > 0) {
+            int event_mask = (1 << kInEvent);
+            handle->set_mask(handle->mask() & ~event_mask);
+            DartUtils::PostInt32(handle->port(), event_mask);
+          } else if (!handle->HasPendingRead() &&
+                     !handle->IsClosedRead()) {
+            handle->IssueRead();
+          }
         }
 
-        if ((msg->data & (1 << kShutdownWriteCommand)) != 0) {
-          client_socket->Shutdown(SD_SEND);
+        // If out events (can write events) have been requested, and there
+        // are no pending writes, post an out event immediately.
+        if ((msg->data & (1 << kOutEvent)) != 0) {
+          if (!handle->HasPendingWrite()) {
+            int event_mask = (1 << kOutEvent);
+            handle->set_mask(handle->mask() & ~event_mask);
+            DartUtils::PostInt32(handle->port(), event_mask);
+          }
+        }
+
+        if (handle->is_client_socket()) {
+          ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(handle);
+          if ((msg->data & (1 << kShutdownReadCommand)) != 0) {
+            client_socket->Shutdown(SD_RECEIVE);
+          }
+
+          if ((msg->data & (1 << kShutdownWriteCommand)) != 0) {
+            client_socket->Shutdown(SD_SEND);
+          }
         }
       }
 
@@ -731,6 +746,7 @@
 
 void EventHandlerImplementation::HandleError(Handle* handle) {
   handle->set_last_error(WSAGetLastError());
+  handle->MarkError();
   if (!handle->IsClosing()) {
     int event_mask = 1 << kErrorEvent;
     DartUtils::PostInt32(handle->port(), event_mask);
@@ -771,7 +787,7 @@
   handle->WriteComplete(buffer);
 
   if (bytes > 0) {
-    if (!handle->IsClosing()) {
+    if (!handle->IsError() && !handle->IsClosing()) {
       int event_mask = 1 << kOutEvent;
       if ((handle->mask() & event_mask) != 0) {
         DartUtils::PostInt32(handle->port(), event_mask);
diff --git a/runtime/bin/eventhandler_win.h b/runtime/bin/eventhandler_win.h
index 207c991..1aa2339 100644
--- a/runtime/bin/eventhandler_win.h
+++ b/runtime/bin/eventhandler_win.h
@@ -159,9 +159,11 @@
   bool IsClosing() { return (flags_ & (1 << kClosing)) != 0; }
   bool IsClosedRead() { return (flags_ & (1 << kCloseRead)) != 0; }
   bool IsClosedWrite() { return (flags_ & (1 << kCloseWrite)) != 0; }
+  bool IsError() { return (flags_ & (1 << kError)) != 0; }
   void MarkClosing() { flags_ |= (1 << kClosing); }
   void MarkClosedRead() { flags_ |= (1 << kCloseRead); }
   void MarkClosedWrite() { flags_ |= (1 << kCloseWrite); }
+  void MarkError() { flags_ |= (1 << kError); }
 
   virtual void EnsureInitialized(
     EventHandlerImplementation* event_handler) = 0;
@@ -187,6 +189,7 @@
   bool is_socket() { return type_ == kListenSocket || type_ == kClientSocket; }
   bool is_listen_socket() { return type_ == kListenSocket; }
   bool is_client_socket() { return type_ == kClientSocket; }
+  void set_mask(intptr_t mask) { mask_ = mask; }
   intptr_t mask() { return mask_; }
 
   void MarkDoesNotSupportOverlappedIO() {
@@ -206,7 +209,8 @@
     kClosing = 0,
     kCloseRead = 1,
     kCloseWrite = 2,
-    kDoesNotSupportOverlappedIO = 3
+    kDoesNotSupportOverlappedIO = 3,
+    kError = 4
   };
 
   explicit Handle(HANDLE handle);
diff --git a/runtime/bin/extensions_win.cc b/runtime/bin/extensions_win.cc
index 52edf59..8590d7b 100644
--- a/runtime/bin/extensions_win.cc
+++ b/runtime/bin/extensions_win.cc
@@ -3,12 +3,15 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "bin/extensions.h"
+#include "bin/utils.h"
 
 void* Extensions::LoadExtensionLibrary(const char* library_path,
                                        const char* extension_name) {
   const char* strings[] = { library_path, "/", extension_name, ".dll", NULL };
   char* library_file = Concatenate(strings);
-  void* lib_handle = LoadLibrary(library_file);
+  wchar_t* unicode_library_file = StringUtils::Utf8ToWide(library_file);
+  void* lib_handle = LoadLibraryW(unicode_library_file);
+  free(unicode_library_file);
   free(library_file);
   return lib_handle;
 }
diff --git a/runtime/bin/io_natives.cc b/runtime/bin/io_natives.cc
index 750fde4..a9edf88 100644
--- a/runtime/bin/io_natives.cc
+++ b/runtime/bin/io_natives.cc
@@ -28,6 +28,8 @@
   V(Platform_Environment, 0)                                                   \
   V(Process_Start, 10)                                                         \
   V(Process_Kill, 3)                                                           \
+  V(Process_SetExitCode, 1)                                                    \
+  V(Process_Exit, 1)                                                           \
   V(ServerSocket_CreateBindListen, 4)                                          \
   V(ServerSocket_Accept, 2)                                                    \
   V(Socket_CreateConnect, 3)                                                   \
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index de8aa60..35e68e3 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -27,16 +27,6 @@
 extern const uint8_t* snapshot_buffer;
 
 
-// Global state that indicates whether perf_events symbol information
-// is to be generated or not.
-static File* perf_events_symbols_file = NULL;
-
-
-// Global state that indicates whether pprof symbol information is
-// to be generated or not.
-static const char* generate_pprof_symbols_filename = NULL;
-
-
 // Global state that stores a pointer to the application script snapshot.
 static bool use_script_snapshot = false;
 static File* snapshot_file = NULL;
@@ -154,33 +144,6 @@
 }
 
 
-static bool ProcessPerfEventsOption(const char* option) {
-  ASSERT(option != NULL);
-  if (perf_events_symbols_file == NULL) {
-    // TODO(cshapiro): eliminate the #ifdef by moving this code to a
-    // Linux specific source file.
-#if defined(TARGET_OS_LINUX)
-    const char* format = "/tmp/perf-%ld.map";
-    intptr_t pid = Process::CurrentProcessId();
-    intptr_t len = snprintf(NULL, 0, format, pid);
-    char* filename = new char[len + 1];
-    snprintf(filename, len + 1, format, pid);
-    perf_events_symbols_file = File::Open(filename, File::kWriteTruncate);
-    ASSERT(perf_events_symbols_file != NULL);
-    delete[] filename;
-#endif
-  }
-  return true;
-}
-
-
-static bool ProcessPprofOption(const char* filename) {
-  ASSERT(filename != NULL);
-  generate_pprof_symbols_filename = filename;
-  return true;
-}
-
-
 static bool ProcessScriptSnapshotOption(const char* filename) {
   if (filename != NULL && strlen(filename) != 0) {
     use_script_snapshot = true;
@@ -206,8 +169,6 @@
   { "--break_at=", ProcessBreakpointOption },
   { "--compile_all", ProcessCompileAllOption },
   { "--debug", ProcessDebugOption },
-  { "--generate_perf_events_symbols", ProcessPerfEventsOption },
-  { "--generate_pprof_symbols=", ProcessPprofOption },
   { "--use_script_snapshot=", ProcessScriptSnapshotOption },
   { NULL, NULL }
 };
@@ -304,13 +265,6 @@
     }
   }
 
-  if (perf_events_symbols_file != NULL) {
-    Dart_InitPerfEventsSupport(perf_events_symbols_file);
-  }
-
-  if (generate_pprof_symbols_filename != NULL) {
-    Dart_InitPprofSupport();
-  }
 
   // Get the script name.
   if (i < argc) {
@@ -405,25 +359,6 @@
 }
 
 
-static void DumpPprofSymbolInfo() {
-  if (generate_pprof_symbols_filename != NULL) {
-    Dart_EnterScope();
-    File* pprof_file =
-        File::Open(generate_pprof_symbols_filename, File::kWriteTruncate);
-    ASSERT(pprof_file != NULL);
-    void* buffer;
-    int buffer_size;
-    Dart_GetPprofSymbolInfo(&buffer, &buffer_size);
-    if (buffer_size > 0) {
-      ASSERT(buffer != NULL);
-      pprof_file->WriteFully(buffer, buffer_size);
-    }
-    delete pprof_file;  // Closes the file.
-    Dart_ExitScope();
-  }
-}
-
-
 #define CHECK_RESULT(result)                                                   \
   if (Dart_IsError(result)) {                                                  \
     *error = strdup(Dart_GetError(result));                                    \
@@ -781,8 +716,6 @@
   }
 
   Dart_ExitScope();
-  // Dump symbol information for the profiler.
-  DumpPprofSymbolInfo();
   // Shutdown the isolate.
   Dart_ShutdownIsolate();
   // Terminate process exit-code handler.
@@ -792,5 +725,5 @@
     for (int i = 0; i < argc; i++) free(argv[i]);
   }
 
-  return 0;
+  return Process::GlobalExitCode();
 }
diff --git a/runtime/bin/process.cc b/runtime/bin/process.cc
index 740e4a4..81715ba 100644
--- a/runtime/bin/process.cc
+++ b/runtime/bin/process.cc
@@ -12,6 +12,8 @@
 
 static const int kProcessIdNativeField = 0;
 
+int Process::global_exit_code_ = 0;
+dart::Mutex Process::global_exit_code_mutex_;
 
 // Extract an array of C strings from a list of Dart strings.
 static char** ExtractCStringList(Dart_Handle strings,
@@ -168,6 +170,26 @@
 }
 
 
+void FUNCTION_NAME(Process_Exit)(Dart_NativeArguments args) {
+  Dart_EnterScope();
+  int64_t status = 0;
+  // Ignore result if passing invalid argument and just exit 0.
+  DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 0), &status);
+  Dart_ExitScope();
+  exit(static_cast<int>(status));
+}
+
+
+void FUNCTION_NAME(Process_SetExitCode)(Dart_NativeArguments args) {
+  Dart_EnterScope();
+  int64_t status = 0;
+  // Ignore result if passing invalid argument and just set exit code to 0.
+  DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 0), &status);
+  Process::SetGlobalExitCode(status);
+  Dart_ExitScope();
+}
+
+
 Dart_Handle Process::GetProcessIdNativeField(Dart_Handle process,
                                              intptr_t* pid) {
   return Dart_GetNativeInstanceField(process, kProcessIdNativeField, pid);
diff --git a/runtime/bin/process.h b/runtime/bin/process.h
index 0d3f704..d0ac1bc 100644
--- a/runtime/bin/process.h
+++ b/runtime/bin/process.h
@@ -6,6 +6,7 @@
 #define BIN_PROCESS_H_
 
 #include "bin/builtin.h"
+#include "bin/thread.h"
 #include "platform/globals.h"
 
 
@@ -33,6 +34,16 @@
   // the thread has terminated.
   static void TerminateExitCodeHandler();
 
+  static int GlobalExitCode() {
+    MutexLocker ml(&global_exit_code_mutex_);
+    return global_exit_code_;
+  }
+
+  static void SetGlobalExitCode(int exit_code) {
+    MutexLocker ml(&global_exit_code_mutex_);
+    global_exit_code_ = exit_code;
+  }
+
   static intptr_t CurrentProcessId();
 
   static Dart_Handle GetProcessIdNativeField(Dart_Handle process,
@@ -40,6 +51,10 @@
   static Dart_Handle SetProcessIdNativeField(Dart_Handle process,
                                              intptr_t pid);
 
+ private:
+  static int global_exit_code_;
+  static dart::Mutex global_exit_code_mutex_;
+
   DISALLOW_ALLOCATION();
   DISALLOW_IMPLICIT_CONSTRUCTORS(Process);
 };
diff --git a/runtime/bin/process_android.cc b/runtime/bin/process_android.cc
index d18c92b..f38e100 100644
--- a/runtime/bin/process_android.cc
+++ b/runtime/bin/process_android.cc
@@ -124,6 +124,8 @@
     if (result < 0) {
       return false;
     }
+    FDUtils::SetCloseOnExec(sig_chld_fds_[0]);
+    FDUtils::SetCloseOnExec(sig_chld_fds_[1]);
 
     // Start thread that polls the pipe and handles process exits when
     // data is received on the pipe.
@@ -482,6 +484,8 @@
     Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
     return errno;
   }
+  FDUtils::SetCloseOnExec(event_fds[0]);
+  FDUtils::SetCloseOnExec(event_fds[1]);
 
   ProcessInfoList::AddProcess(pid, event_fds[1]);
   *exit_event = event_fds[0];
diff --git a/runtime/bin/process_linux.cc b/runtime/bin/process_linux.cc
index 01b17a9..cd71267 100644
--- a/runtime/bin/process_linux.cc
+++ b/runtime/bin/process_linux.cc
@@ -125,6 +125,8 @@
     if (result < 0) {
       return false;
     }
+    FDUtils::SetCloseOnExec(sig_chld_fds_[0]);
+    FDUtils::SetCloseOnExec(sig_chld_fds_[1]);
 
     // Start thread that polls the pipe and handles process exits when
     // data is received on the pipe.
@@ -482,6 +484,8 @@
     Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
     return errno;
   }
+  FDUtils::SetCloseOnExec(event_fds[0]);
+  FDUtils::SetCloseOnExec(event_fds[1]);
 
   ProcessInfoList::AddProcess(pid, event_fds[1]);
   *exit_event = event_fds[0];
diff --git a/runtime/bin/process_macos.cc b/runtime/bin/process_macos.cc
index 6256b31..f2d5ca3 100644
--- a/runtime/bin/process_macos.cc
+++ b/runtime/bin/process_macos.cc
@@ -124,6 +124,8 @@
     if (result < 0) {
       return false;
     }
+    FDUtils::SetCloseOnExec(sig_chld_fds_[0]);
+    FDUtils::SetCloseOnExec(sig_chld_fds_[1]);
 
     // Start thread that polls the pipe and handles process exits when
     // data is received on the pipe.
@@ -480,6 +482,8 @@
     Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
     return errno;
   }
+  FDUtils::SetCloseOnExec(event_fds[0]);
+  FDUtils::SetCloseOnExec(event_fds[1]);
 
   ProcessInfoList::AddProcess(pid, event_fds[1]);
   *exit_event = event_fds[0];
diff --git a/runtime/bin/process_patch.dart b/runtime/bin/process_patch.dart
index 6646d07..34ca476 100644
--- a/runtime/bin/process_patch.dart
+++ b/runtime/bin/process_patch.dart
@@ -31,7 +31,8 @@
 
 
 patch class _ProcessUtils {
-  /* patch */ static _exit(int status) native "Exit";
+  /* patch */ static _exit(int status) native "Process_Exit";
+  /* patch */ static _setExitCode(int status) native "Process_SetExitCode";
 }
 
 
@@ -314,7 +315,7 @@
 
     processFuture.then((Process p) {
       // Make sure the process stdin is closed.
-      p.stdin.close;
+      p.stdin.close();
 
       // Setup process exit handling.
       p.onExit = (exitCode) {
diff --git a/runtime/bin/process_win.cc b/runtime/bin/process_win.cc
index 65cc7e6..a073717 100644
--- a/runtime/bin/process_win.cc
+++ b/runtime/bin/process_win.cc
@@ -202,7 +202,7 @@
 // NOTE: If this function returns false the handles might have been allocated
 // and the caller should make sure to close them in case of an error.
 static bool CreateProcessPipe(HANDLE handles[2],
-                              char* pipe_name,
+                              wchar_t* pipe_name,
                               NamedPipeType type) {
   // Security attributes describing an inheritable handle.
   SECURITY_ATTRIBUTES inherit_handle;
@@ -212,14 +212,14 @@
 
   if (type == kInheritRead) {
     handles[kWriteHandle] =
-        CreateNamedPipe(pipe_name,
-                        PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED,
-                        PIPE_TYPE_BYTE | PIPE_WAIT,
-                        1,             // Number of pipes
-                        1024,          // Out buffer size
-                        1024,          // In buffer size
-                        0,             // Timeout in ms
-                        NULL);
+        CreateNamedPipeW(pipe_name,
+                         PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED,
+                         PIPE_TYPE_BYTE | PIPE_WAIT,
+                         1,             // Number of pipes
+                         1024,          // Out buffer size
+                         1024,          // In buffer size
+                         0,             // Timeout in ms
+                         NULL);
 
     if (handles[kWriteHandle] == INVALID_HANDLE_VALUE) {
       Log::PrintErr("CreateNamedPipe failed %d\n", GetLastError());
@@ -227,13 +227,13 @@
     }
 
     handles[kReadHandle] =
-        CreateFile(pipe_name,
-                   GENERIC_READ,
-                   0,
-                   &inherit_handle,
-                   OPEN_EXISTING,
-                   FILE_READ_ATTRIBUTES | FILE_FLAG_OVERLAPPED,
-                   NULL);
+        CreateFileW(pipe_name,
+                    GENERIC_READ,
+                    0,
+                    &inherit_handle,
+                    OPEN_EXISTING,
+                    FILE_READ_ATTRIBUTES | FILE_FLAG_OVERLAPPED,
+                    NULL);
     if (handles[kReadHandle] == INVALID_HANDLE_VALUE) {
       Log::PrintErr("CreateFile failed %d\n", GetLastError());
       return false;
@@ -241,14 +241,14 @@
   } else {
     ASSERT(type == kInheritWrite || type == kInheritNone);
     handles[kReadHandle] =
-        CreateNamedPipe(pipe_name,
-                        PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
-                        PIPE_TYPE_BYTE | PIPE_WAIT,
-                        1,             // Number of pipes
-                        1024,          // Out buffer size
-                        1024,          // In buffer size
-                        0,             // Timeout in ms
-                        NULL);
+        CreateNamedPipeW(pipe_name,
+                         PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
+                         PIPE_TYPE_BYTE | PIPE_WAIT,
+                         1,             // Number of pipes
+                         1024,          // Out buffer size
+                         1024,          // In buffer size
+                         0,             // Timeout in ms
+                         NULL);
 
     if (handles[kReadHandle] == INVALID_HANDLE_VALUE) {
       Log::PrintErr("CreateNamedPipe failed %d\n", GetLastError());
@@ -256,13 +256,13 @@
     }
 
     handles[kWriteHandle] =
-        CreateFile(pipe_name,
-                   GENERIC_WRITE,
-                   0,
-                   (type == kInheritWrite) ? &inherit_handle : NULL,
-                   OPEN_EXISTING,
-                   FILE_WRITE_ATTRIBUTES | FILE_FLAG_OVERLAPPED,
-                   NULL);
+        CreateFileW(pipe_name,
+                    GENERIC_WRITE,
+                    0,
+                    (type == kInheritWrite) ? &inherit_handle : NULL,
+                    OPEN_EXISTING,
+                    FILE_WRITE_ATTRIBUTES | FILE_FLAG_OVERLAPPED,
+                    NULL);
     if (handles[kWriteHandle] == INVALID_HANDLE_VALUE) {
       Log::PrintErr("CreateFile failed %d\n", GetLastError());
       return false;
@@ -375,7 +375,8 @@
   HANDLE exit_handles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE };
 
   // Generate unique pipe names for the four named pipes needed.
-  char pipe_names[4][80];
+  static const int kMaxPipeNameSize = 80;
+  wchar_t pipe_names[4][kMaxPipeNameSize];
   UUID uuid;
   RPC_STATUS status = UuidCreateSequential(&uuid);
   if (status != RPC_S_OK && status != RPC_S_UUID_LOCAL_ONLY) {
@@ -383,20 +384,20 @@
     Log::PrintErr("UuidCreateSequential failed %d\n", status);
     return status;
   }
-  RPC_CSTR uuid_string;
-  status = UuidToString(&uuid, &uuid_string);
+  RPC_WSTR uuid_string;
+  status = UuidToStringW(&uuid, &uuid_string);
   if (status != RPC_S_OK) {
     SetOsErrorMessage(os_error_message);
     Log::PrintErr("UuidToString failed %d\n", status);
     return status;
   }
   for (int i = 0; i < 4; i++) {
-    static const char* prefix = "\\\\.\\Pipe\\dart";
-    snprintf(pipe_names[i],
-             sizeof(pipe_names[i]),
-             "%s_%s_%d", prefix, uuid_string, i + 1);
+    static const wchar_t* prefix = L"\\\\.\\Pipe\\dart";
+    _snwprintf(pipe_names[i],
+               kMaxPipeNameSize,
+               L"%s_%s_%d", prefix, uuid_string, i + 1);
   }
-  status = RpcStringFree(&uuid_string);
+  status = RpcStringFreeW(&uuid_string);
   if (status != RPC_S_OK) {
     SetOsErrorMessage(os_error_message);
     Log::PrintErr("RpcStringFree failed %d\n", status);
diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc
index c9173a8..c4d191e 100644
--- a/runtime/bin/run_vm_tests.cc
+++ b/runtime/bin/run_vm_tests.cc
@@ -59,29 +59,6 @@
 }
 
 
-static void DumpPprofSymbolInfo(const char* pprof_filename) {
-  if (pprof_filename != NULL) {
-    char* err = NULL;
-    Dart_Isolate isolate = Dart_CreateIsolate(NULL, NULL, NULL, NULL, &err);
-    EXPECT(isolate != NULL);
-    Dart_EnterScope();
-    File* pprof_file =
-        File::Open(pprof_filename, File::kWriteTruncate);
-    ASSERT(pprof_file != NULL);
-    void* buffer;
-    int buffer_size;
-    Dart_GetPprofSymbolInfo(&buffer, &buffer_size);
-    if (buffer_size > 0) {
-      ASSERT(buffer != NULL);
-      pprof_file->WriteFully(buffer, buffer_size);
-    }
-    delete pprof_file;  // Closes the file.
-    Dart_ExitScope();
-    Dart_ShutdownIsolate();
-  }
-}
-
-
 static void PrintUsage() {
   fprintf(stderr, "run_vm_tests [--list | --benchmarks | "
                   "--tests | --all | <test name> | <benchmark name>]\n");
@@ -94,7 +71,6 @@
   // Flags being passed to the Dart VM.
   int dart_argc = 0;
   const char** dart_argv = NULL;
-  const char* pprof_filename = NULL;
 
   if (argc < 2) {
     // Bad parameter count.
@@ -119,21 +95,10 @@
   } else {
     // Last argument is the test name, the rest are vm flags.
     run_filter = argv[argc - 1];
-    const char* pprof_option = "--generate_pprof_symbols=";
-    int length = strlen(pprof_option);
-    if (strncmp(pprof_option, argv[1], length) == 0) {
-      pprof_filename = (argv[1] + length);
-      Dart_InitPprofSupport();
-      // Remove the first two values (executable, pprof flag) from the
-      // arguments and exclude the last argument which is the test name.
-      dart_argc = argc - 3;
-      dart_argv = &argv[2];
-    } else {
-      // Remove the first value (executable) from the arguments and
-      // exclude the last argument which is the test name.
-      dart_argc = argc - 2;
-      dart_argv = &argv[1];
-    }
+    // Remove the first value (executable) from the arguments and
+    // exclude the last argument which is the test name.
+    dart_argc = argc - 2;
+    dart_argv = &argv[1];
   }
   bool set_vm_flags_success = Flags::ProcessCommandLineFlags(dart_argc,
                                                              dart_argv);
@@ -150,8 +115,6 @@
     fprintf(stderr, "No tests matched: %s\n", run_filter);
     return 1;
   }
-  // Dump symbol information for the profiler.
-  DumpPprofSymbolInfo(pprof_filename);
   return 0;
 }
 
diff --git a/runtime/bin/secure_socket.cc b/runtime/bin/secure_socket.cc
index c378683..49248d3 100644
--- a/runtime/bin/secure_socket.cc
+++ b/runtime/bin/secure_socket.cc
@@ -264,6 +264,9 @@
 
 
 void SSLFilter::Init(Dart_Handle dart_this) {
+  if (!library_initialized_) {
+    InitializeLibrary(NULL, "", true, false);
+  }
   string_start_ = ThrowIfError(
       Dart_NewPersistentHandle(DartUtils::NewString("start")));
   string_length_ = ThrowIfError(
@@ -320,7 +323,8 @@
 
 void SSLFilter::InitializeLibrary(const char* certificate_database,
                                   const char* password,
-                                  bool use_builtin_root_certificates) {
+                                  bool use_builtin_root_certificates,
+                                  bool report_duplicate_initialization) {
   MutexLocker locker(&mutex_);
   if (!library_initialized_) {
     library_initialized_ = true;
@@ -362,7 +366,8 @@
       ThrowPRException("Failed SSL_ConfigServerSessionIDCache call.");
     }
 
-  } else {
+  } else if (report_duplicate_initialization) {
+    mutex_.Unlock();  // MutexLocker destructor not called when throwing.
     ThrowException("Called SSLFilter::InitializeLibrary more than once");
   }
 }
@@ -412,6 +417,10 @@
     ThrowException("Connect called while already in handshake state.");
   }
 
+  if (!is_server && certificate_name != NULL) {
+    client_certificate_name_ = strdup(certificate_name);
+  }
+
   filter_ = SSL_ImportFD(NULL, filter_);
   if (filter_ == NULL) {
     ThrowPRException("Failed SSL_ImportFD call");
@@ -481,7 +490,7 @@
       status = SSL_GetClientAuthDataHook(
           filter_,
           NSS_GetClientAuthData,
-          static_cast<void*>(const_cast<char*>(certificate_name)));
+          static_cast<void*>(client_certificate_name_));
       if (status != SECSuccess) {
         ThrowPRException("Failed SSL_GetClientAuthDataHook call");
       }
@@ -552,6 +561,7 @@
   if (bad_certificate_callback_ != NULL) {
     Dart_DeletePersistentHandle(bad_certificate_callback_);
   }
+  free(client_certificate_name_);
 
   PR_Close(filter_);
 }
diff --git a/runtime/bin/secure_socket.h b/runtime/bin/secure_socket.h
index f20ca7d..07be8fa 100644
--- a/runtime/bin/secure_socket.h
+++ b/runtime/bin/secure_socket.h
@@ -68,6 +68,7 @@
         handshake_complete_(NULL),
         bad_certificate_callback_(NULL),
         in_handshake_(false),
+        client_certificate_name_(NULL),
         filter_(NULL) { }
 
   void Init(Dart_Handle dart_this);
@@ -85,7 +86,8 @@
   Dart_Handle bad_certificate_callback() { return bad_certificate_callback_; }
   static void InitializeLibrary(const char* certificate_database,
                                 const char* password,
-                                bool use_builtin_root_certificates);
+                                bool use_builtin_root_certificates,
+                                bool report_duplicate_initialization = true);
   intptr_t ProcessBuffer(int bufferIndex);
   Dart_Handle PeerCertificate();
 
@@ -104,6 +106,7 @@
   Dart_Handle bad_certificate_callback_;
   bool in_handshake_;
   bool is_server_;
+  char* client_certificate_name_;
   PRFileDesc* filter_;
 
   void InitializeBuffers(Dart_Handle dart_this);
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index e0e8242..2013e09 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -187,7 +187,7 @@
       Dart_PropagateError(result);
     }
     bytes_written = Socket::Write(socket, buffer, length);
-    total_bytes_written = bytes_written;
+    if (bytes_written > 0) total_bytes_written = bytes_written;
   } else {
     // Send data in chunks of maximum 16KB.
     const intptr_t max_chunk_length =
@@ -206,7 +206,7 @@
       }
       bytes_written =
           Socket::Write(socket, reinterpret_cast<void*>(buffer), chunk_length);
-      total_bytes_written += bytes_written;
+      if (bytes_written > 0) total_bytes_written += bytes_written;
     } while (bytes_written > 0 && total_bytes_written < length);
     delete[] buffer;
   }
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index 23edced..3b502a2 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -66,8 +66,10 @@
 
         var eventHandler = _handlerMap[i];
         if (eventHandler != null || i == _ERROR_EVENT) {
-          // Unregister the out handler before executing it.
-          if (i == _OUT_EVENT) _setHandler(i, null);
+          // Unregister the out handler before executing it. There is
+          // no need to notify the eventhandler as handlers are
+          // disabled while the event is handled.
+          if (i == _OUT_EVENT) _setHandler(i, null, notifyEventhandler: false);
 
           // Don't call the in handler if there is no data available
           // after all.
@@ -87,7 +89,9 @@
     _activateHandlers();
   }
 
-  void _setHandler(int event, Function callback) {
+  void _setHandler(int event,
+                   Function callback,
+                   {bool notifyEventhandler: true}) {
     if (callback == null) {
       _handlerMask &= ~(1 << event);
     } else {
@@ -103,7 +107,7 @@
       _handler.close();
       _handler = null;
     } else {
-      _activateHandlers();
+      if (notifyEventhandler) _activateHandlers();
     }
   }
 
diff --git a/runtime/bin/socket_win.cc b/runtime/bin/socket_win.cc
index adc6aef..0a31298 100644
--- a/runtime/bin/socket_win.cc
+++ b/runtime/bin/socket_win.cc
@@ -67,11 +67,11 @@
   // includes the port in the formatted string.
   socket_address.sin_port = 0;
   DWORD len = INET_ADDRSTRLEN;
-  int err = WSAAddressToString(reinterpret_cast<LPSOCKADDR>(&socket_address),
-                               sizeof(socket_address),
-                               NULL,
-                               host,
-                               &len);
+  int err = WSAAddressToStringA(reinterpret_cast<LPSOCKADDR>(&socket_address),
+                                sizeof(socket_address),
+                                NULL,
+                                host,
+                                &len);
   if (err != 0) {
     Log::PrintErr("Error WSAAddressToString: %d\n", WSAGetLastError());
     return false;
@@ -196,11 +196,11 @@
   // Clear the port before calling WSAAddressToString as WSAAddressToString
   // includes the port in the formatted string.
   DWORD len = INET_ADDRSTRLEN;
-  int err = WSAAddressToString(reinterpret_cast<LPSOCKADDR>(sockaddr),
-                               sizeof(sockaddr_in),
-                               NULL,
-                               buffer,
-                               &len);
+  int err = WSAAddressToStringA(reinterpret_cast<LPSOCKADDR>(sockaddr),
+                                sizeof(sockaddr_in),
+                                NULL,
+                                buffer,
+                                &len);
   if (err != 0) {
     free(buffer);
     return NULL;
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 98032de..f656ec8 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -1479,6 +1479,23 @@
                                           intptr_t* length);
 
 /**
+ * Gets the data corresponding to the string object. This function returns
+ * the data only for Latin-1 (ISO-8859-1) string objects. For all other
+ * string objects it return and error.
+ *
+ * \param str A string.
+ * \param latin1_array An array allocated by the caller, used to return
+ *   the string data.
+ * \param length Used to pass in the length of the provided array.
+ *   Used to return the length of the array which was actually used.
+ *
+ * \return A valid handle if no error occurs during the operation.
+ */
+DART_EXPORT Dart_Handle Dart_StringToLatin1(Dart_Handle str,
+                                            uint8_t* latin1_array,
+                                            intptr_t* length);
+
+/**
  * Gets the UTF-16 encoded representation of a string.
  *
  * \param str A string.
@@ -1517,6 +1534,9 @@
  *
  * \return the converted ExternalString object if no error occurs.
  *   Otherwise returns an error handle.
+ *   If the object is a valid string but if it cannot be externalized
+ *   then Dart_Null() is returned and the string data is copied into
+ *   the external space specified.
  *
  * For example:
  *  intptr_t size;
diff --git a/runtime/lib/array.cc b/runtime/lib/array.cc
index 8b273a4..6be9093 100644
--- a/runtime/lib/array.cc
+++ b/runtime/lib/array.cc
@@ -23,8 +23,8 @@
     const String& error = String::Handle(String::NewFormatted(
         "length (%"Pd") must be in the range [0..%"Pd"]",
         len, Array::kMaxElements));
-    GrowableArray<const Object*> args;
-    args.Add(&error);
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, error);
     Exceptions::ThrowByType(Exceptions::kArgument, args);
   }
   const Array& new_array = Array::Handle(Array::New(length.Value()));
@@ -37,9 +37,9 @@
   const Array& array = Array::CheckedHandle(arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, index, arguments->NativeArgAt(1));
   if ((index.Value() < 0) || (index.Value() >= array.Length())) {
-    GrowableArray<const Object*> arguments;
-    arguments.Add(&index);
-    Exceptions::ThrowByType(Exceptions::kRange, arguments);
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, index);
+    Exceptions::ThrowByType(Exceptions::kRange, args);
   }
   return array.At(index.Value());
 }
@@ -50,9 +50,9 @@
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, index, arguments->NativeArgAt(1));
   const Instance& value = Instance::CheckedHandle(arguments->NativeArgAt(2));
   if ((index.Value() < 0) || (index.Value() >= array.Length())) {
-    GrowableArray<const Object*> arguments;
-    arguments.Add(&index);
-    Exceptions::ThrowByType(Exceptions::kRange, arguments);
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, index);
+    Exceptions::ThrowByType(Exceptions::kRange, args);
   }
   array.SetAt(index.Value(), value);
   return Object::null();
@@ -74,8 +74,7 @@
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, count, arguments->NativeArgAt(4));
   intptr_t icount = count.Value();
   if (icount < 0) {
-    GrowableArray<const Object*> args;
-    Exceptions::ThrowByType(Exceptions::kArgument, args);
+    Exceptions::ThrowByType(Exceptions::kArgument, Object::empty_array());
   }
   if (icount == 0) {
     return Object::null();
@@ -83,14 +82,14 @@
   intptr_t isrc_start = src_start.Value();
   intptr_t idst_start = dst_start.Value();
   if ((isrc_start < 0) || ((isrc_start + icount) > source.Length())) {
-    GrowableArray<const Object*> arguments;
-    arguments.Add(&src_start);
-    Exceptions::ThrowByType(Exceptions::kRange, arguments);
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, src_start);
+    Exceptions::ThrowByType(Exceptions::kRange, args);
   }
   if ((idst_start < 0) || ((idst_start + icount) > dest.Length())) {
-    GrowableArray<const Object*> arguments;
-    arguments.Add(&dst_start);
-    Exceptions::ThrowByType(Exceptions::kRange, arguments);
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, dst_start);
+    Exceptions::ThrowByType(Exceptions::kRange, args);
   }
 
   Object& src_obj = Object::Handle();
diff --git a/runtime/lib/array.dart b/runtime/lib/array.dart
index e63af50..1748654 100644
--- a/runtime/lib/array.dart
+++ b/runtime/lib/array.dart
@@ -33,7 +33,7 @@
     if (length < 0) {
       throw new ArgumentError("negative length $length");
     }
-      if (from is _ObjectArray) {
+    if (from is _ObjectArray) {
       _copyFromObjectArray(from, startFrom, start, length);
     } else {
       Arrays.copy(from, startFrom, this, start, length);
diff --git a/runtime/lib/byte_array.cc b/runtime/lib/byte_array.cc
index 0d98f98..c072619 100644
--- a/runtime/lib/byte_array.cc
+++ b/runtime/lib/byte_array.cc
@@ -23,8 +23,8 @@
     const String& error = String::Handle(String::NewFormatted(
         "index (%"Pd") must be in the range [0..%"Pd")",
         index, (array.ByteLength() / num_bytes)));
-    GrowableArray<const Object*> args;
-    args.Add(&error);
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, error);
     Exceptions::ThrowByType(Exceptions::kRange, args);
   }
 }
@@ -36,8 +36,8 @@
   if (len < 0 || len > max) {
     const String& error = String::Handle(String::NewFormatted(
         "length (%"Pd") must be in the range [0..%"Pd"]", len, max));
-    GrowableArray<const Object*> args;
-    args.Add(&error);
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, error);
     Exceptions::ThrowByType(Exceptions::kArgument, args);
   }
 }
@@ -265,8 +265,8 @@
   if (length_value < 0) {
     const String& error = String::Handle(String::NewFormatted(
         "length (%"Pd") must be non-negative", length_value));
-    GrowableArray<const Object*> args;
-    args.Add(&error);
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, error);
     Exceptions::ThrowByType(Exceptions::kArgument, args);
   }
   RangeCheck(src, src_start_value, length_value);
diff --git a/runtime/lib/date.cc b/runtime/lib/date.cc
index ad66673..154f1fe 100644
--- a/runtime/lib/date.cc
+++ b/runtime/lib/date.cc
@@ -20,8 +20,8 @@
       Integer, dart_seconds, arguments->NativeArgAt(0));
   int64_t seconds = dart_seconds.AsInt64Value();
   if (seconds < 0 || seconds > kMaxAllowedSeconds) {
-    GrowableArray<const Object*> args;
-    args.Add(&dart_seconds);
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, dart_seconds);
     Exceptions::ThrowByType(Exceptions::kArgument, args);
   }
   const char* name = OS::GetTimeZoneName(seconds);
@@ -34,8 +34,8 @@
       Integer, dart_seconds, arguments->NativeArgAt(0));
   int64_t seconds = dart_seconds.AsInt64Value();
   if (seconds < 0 || seconds > kMaxAllowedSeconds) {
-    GrowableArray<const Object*> args;
-    args.Add(&dart_seconds);
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, dart_seconds);
     Exceptions::ThrowByType(Exceptions::kArgument, args);
   }
   int offset = OS::GetTimeZoneOffsetInSeconds(seconds);
diff --git a/runtime/lib/double.cc b/runtime/lib/double.cc
index 350fbde..7a15d5b 100644
--- a/runtime/lib/double.cc
+++ b/runtime/lib/double.cc
@@ -189,9 +189,8 @@
 DEFINE_NATIVE_ENTRY(Double_toInt, 1) {
   const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0));
   if (isinf(arg.value()) || isnan(arg.value())) {
-    GrowableArray<const Object*> args;
-    args.Add(&String::ZoneHandle(String::New(
-        "Infinity or NaN toInt")));
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, String::Handle(String::New("Infinity or NaN toInt")));
     Exceptions::ThrowByType(Exceptions::kFormat, args);
   }
   double result = trunc(arg.value());
@@ -207,8 +206,7 @@
 
 DEFINE_NATIVE_ENTRY(Double_parse, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0));
-  const String& dummy_key = String::Handle(Symbols::Empty());
-  Scanner scanner(value, dummy_key);
+  Scanner scanner(value, Symbols::Empty());
   const Scanner::GrowableTokenStream& tokens = scanner.GetStream();
   String* number_string;
   bool is_positive;
@@ -253,8 +251,8 @@
     }
   }
 
-  GrowableArray<const Object*> args;
-  args.Add(&value);
+  const Array& args = Array::Handle(Array::New(1));
+  args.SetAt(0, value);
   Exceptions::ThrowByType(Exceptions::kFormat, args);
   return Object::null();
 }
@@ -273,9 +271,9 @@
       && kLowerBoundary < d && d < kUpperBoundary) {
     return DoubleToStringAsFixed(d, static_cast<int>(fraction_digits_value));
   } else {
-    GrowableArray<const Object*> args;
-    args.Add(&String::ZoneHandle(String::New(
-        "Illegal arguments to double.toStringAsFixed")));
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, String::Handle(
+        String::New("Illegal arguments to double.toStringAsFixed")));
     Exceptions::ThrowByType(Exceptions::kArgument, args);
     return Object::null();
   }
@@ -291,9 +289,9 @@
     return DoubleToStringAsExponential(
         d, static_cast<int>(fraction_digits_value));
   } else {
-    GrowableArray<const Object*> args;
-    args.Add(&String::ZoneHandle(String::New(
-        "Illegal arguments to double.toStringAsExponential")));
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, String::Handle(
+        String::New("Illegal arguments to double.toStringAsExponential")));
     Exceptions::ThrowByType(Exceptions::kArgument, args);
     return Object::null();
   }
@@ -308,9 +306,9 @@
   if (1 <= precision_value && precision_value <= 21) {
     return DoubleToStringAsPrecision(d, static_cast<int>(precision_value));
   } else {
-    GrowableArray<const Object*> args;
-    args.Add(&String::ZoneHandle(String::New(
-        "Illegal arguments to double.toStringAsPrecision")));
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, String::Handle(
+        String::New("Illegal arguments to double.toStringAsPrecision")));
     Exceptions::ThrowByType(Exceptions::kArgument, args);
     return Object::null();
   }
diff --git a/runtime/lib/error.cc b/runtime/lib/error.cc
index ea39065..f9794a0 100644
--- a/runtime/lib/error.cc
+++ b/runtime/lib/error.cc
@@ -140,42 +140,4 @@
   return Object::null();
 }
 
-
-// TODO(regis): This helper is used to compile a throw when a call cannot be
-// resolved at compile time. The thrown instance of NoSuchMethodError is of a
-// different type than a NoSuchMethodError thrown at runtime. This should be
-// merged.
-//
-// Allocate and throw NoSuchMethodError.
-// Arg0: index of the call that was not resolved at compile time.
-// Arg1: name of the method that was not resolved at compile time.
-// Return value: none, throws an exception.
-DEFINE_NATIVE_ENTRY(NoSuchMethodError_throwNew, 2) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Smi, smi_pos, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(
-      String, function_name, arguments->NativeArgAt(1));
-  intptr_t call_pos = smi_pos.Value();
-  // Allocate a new instance of type NoSuchMethodError.
-  const Instance& error = Instance::Handle(
-      Exceptions::NewInstance("NoSuchMethodErrorImplementation"));
-  ASSERT(!error.IsNull());
-
-  // Initialize 'url', 'line', and 'column' fields.
-  DartFrameIterator iterator;
-  iterator.NextFrame();  // Skip native call.
-  const Script& script = Script::Handle(Exceptions::GetCallerScript(&iterator));
-  const Class& cls = Class::Handle(error.clazz());
-  Exceptions::SetLocationFields(error, cls, script, call_pos);
-  Exceptions::SetField(error, cls, "functionName", function_name);
-
-  intptr_t line, column;
-  script.GetTokenLocation(call_pos, &line, &column);
-  Exceptions::SetField(error, cls, "failedResolutionLine",
-                       String::Handle(script.GetLine(line)));
-
-  Exceptions::Throw(error);
-  UNREACHABLE();
-  return Object::null();
-}
-
 }  // namespace dart
diff --git a/runtime/lib/error.dart b/runtime/lib/error.dart
index 7aa960f..eb93999 100644
--- a/runtime/lib/error.dart
+++ b/runtime/lib/error.dart
@@ -91,28 +91,6 @@
 }
 
 
-// TODO(regis): This class should be removed and the corresponding class in the
-// core lib should be used.
-class NoSuchMethodErrorImplementation implements NoSuchMethodError {
-  factory NoSuchMethodErrorImplementation._uninstantiable() {
-    throw new UnsupportedError(
-        "NoSuchMethodError can only be allocated by the VM");
-  }
-
-  String toString() => "No such method: '$functionName', url '$url' line $line "
-      "pos $column\n$failedResolutionLine\n";
-
-  static _throwNew(int call_pos, String functionName)
-      native "NoSuchMethodError_throwNew";
-
-  final String functionName;
-  final String failedResolutionLine;
-  final String url;
-  final int line;
-  final int column;
-}
-
-
 class AbstractClassInstantiationErrorImplementation
     implements AbstractClassInstantiationError {
 
diff --git a/runtime/lib/errors_patch.dart b/runtime/lib/errors_patch.dart
index 12caead..5fd3e50 100644
--- a/runtime/lib/errors_patch.dart
+++ b/runtime/lib/errors_patch.dart
@@ -8,3 +8,33 @@
   }
 }
 
+patch class NoSuchMethodError {
+  // The compiler emits a call to _throwNew when it cannot resolve a static
+  // method at compile time. The receiver is actually the literal class of the
+  // unresolved method.
+  static void _throwNew(Object receiver,
+                        String memberName,
+                        List arguments,
+                        List argumentNames,
+                        List existingArgumentNames) {
+    int numNamedArguments = argumentNames == null ? 0 : argumentNames.length;
+    int numPositionalArguments = arguments == null ? 0 : arguments.length;
+    numPositionalArguments -= numNamedArguments;
+    List positionalArguments;
+    if (numPositionalArguments == 0) {
+      positionalArguments = [];
+    } else {
+      positionalArguments = arguments.getRange(0, numPositionalArguments);
+    }
+    Map<String, dynamic> namedArguments = new Map<String, dynamic>();
+    for (int i = 0; i < numNamedArguments; i++) {
+      var arg_value = arguments[numPositionalArguments + i];
+      namedArguments[argumentNames[i]] = arg_value;
+    }
+    throw new NoSuchMethodError(receiver,
+                                memberName,
+                                positionalArguments,
+                                namedArguments,
+                                existingArgumentNames);
+  }
+}
diff --git a/runtime/lib/function.cc b/runtime/lib/function.cc
new file mode 100644
index 0000000..b821791
--- /dev/null
+++ b/runtime/lib/function.cc
@@ -0,0 +1,34 @@
+// 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.
+
+#include "vm/bootstrap_natives.h"
+
+#include "vm/compiler.h"
+#include "vm/dart_entry.h"
+#include "vm/exceptions.h"
+#include "vm/native_entry.h"
+#include "vm/object.h"
+#include "vm/symbols.h"
+
+namespace dart {
+
+DEFINE_NATIVE_ENTRY(Function_apply, 2) {
+  const Array& fun_arguments = Array::CheckedHandle(arguments->NativeArgAt(0));
+  const Array& fun_arg_names = Array::CheckedHandle(arguments->NativeArgAt(1));
+  Instance& instance = Instance::Handle();
+  instance ^= fun_arguments.At(0);
+  const Array& fun_args_desc =
+      Array::Handle(ArgumentsDescriptor::New(fun_arguments.Length(),
+                                             fun_arg_names));
+  const Object& result =
+      Object::Handle(DartEntry::InvokeClosure(instance,
+                                              fun_arguments,
+                                              fun_args_desc));
+  if (result.IsError()) {
+    Exceptions::PropagateError(Error::Cast(result));
+  }
+  return result.raw();
+}
+
+}  // namespace dart
diff --git a/runtime/lib/function_patch.dart b/runtime/lib/function_patch.dart
index 581449b..56b817d 100644
--- a/runtime/lib/function_patch.dart
+++ b/runtime/lib/function_patch.dart
@@ -3,9 +3,28 @@
 // BSD-style license that can be found in the LICENSE file.
 
 patch class Function {
+  static _apply(List arguments, List names)
+      native "Function_apply";
+
   /* patch */ static apply(Function function,
                            List positionalArguments,
                            [Map<String,dynamic> namedArguments]) {
-    throw new UnimplementedError('Function.apply not implemented');
+    int numPositionalArguments = 1 +  // Function is first implicit argument.
+        (positionalArguments != null ? positionalArguments.length : 0);
+    int numNamedArguments = namedArguments != null ? namedArguments.length : 0;
+    int numArguments = numPositionalArguments + numNamedArguments;
+    List arguments = new List(numArguments);
+    arguments[0] = function;
+    arguments.setRange(1, numPositionalArguments - 1, positionalArguments);
+    List names = new List(numNamedArguments);
+    int argumentIndex = numPositionalArguments;
+    int nameIndex = 0;
+    if (numNamedArguments > 0) {
+      namedArguments.forEach((name, value) {
+        arguments[argumentIndex++] = value;
+        names[nameIndex++] = name;
+      });
+    }
+    return _apply(arguments, names);
   }
 }
diff --git a/runtime/lib/growable_array.cc b/runtime/lib/growable_array.cc
index ac679af..52278c0 100644
--- a/runtime/lib/growable_array.cc
+++ b/runtime/lib/growable_array.cc
@@ -20,8 +20,8 @@
   GET_NON_NULL_NATIVE_ARGUMENT(Array, data, arguments->NativeArgAt(1));
   if ((data.Length() <= 0)) {
     const Integer& index = Integer::Handle(Integer::New(data.Length()));
-    GrowableArray<const Object*> args;
-    args.Add(&index);
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, index);
     Exceptions::ThrowByType(Exceptions::kRange, args);
   }
   const GrowableObjectArray& new_array =
@@ -36,8 +36,8 @@
       GrowableObjectArray::CheckedHandle(arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, index, arguments->NativeArgAt(1));
   if ((index.Value() < 0) || (index.Value() >= array.Length())) {
-    GrowableArray<const Object*> args;
-    args.Add(&index);
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, index);
     Exceptions::ThrowByType(Exceptions::kRange, args);
   }
   const Instance& obj = Instance::CheckedHandle(array.At(index.Value()));
@@ -50,8 +50,8 @@
       GrowableObjectArray::CheckedHandle(arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, index, arguments->NativeArgAt(1));
   if ((index.Value() < 0) || (index.Value() >= array.Length())) {
-    GrowableArray<const Object*> args;
-    args.Add(&index);
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, index);
     Exceptions::ThrowByType(Exceptions::kRange, args);
   }
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(2));
@@ -79,8 +79,8 @@
       GrowableObjectArray::CheckedHandle(arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(1));
   if ((length.Value() < 0) || (length.Value() > array.Capacity())) {
-    GrowableArray<const Object*> args;
-    args.Add(&length);
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, length);
     Exceptions::ThrowByType(Exceptions::kRange, args);
   }
   array.SetLength(length.Value());
diff --git a/runtime/lib/growable_array.dart b/runtime/lib/growable_array.dart
index 066f4b6..9caad29 100644
--- a/runtime/lib/growable_array.dart
+++ b/runtime/lib/growable_array.dart
@@ -93,10 +93,10 @@
 
   int get length native "GrowableObjectArray_getLength";
 
-  int get capacity native "GrowableObjectArray_getCapacity";
+  int get _capacity native "GrowableObjectArray_getCapacity";
 
   void set length(int new_length) {
-    if (new_length > capacity) {
+    if (new_length > _capacity) {
       _grow(new_length);
     } else {
       for (int i = new_length; i < length; i++) {
@@ -120,7 +120,7 @@
   // doubling its size.
   void add(T value) {
     var len = length;
-    if (len == capacity) {
+    if (len == _capacity) {
       _grow(len * 2);
     }
     _setLength(len + 1);
diff --git a/runtime/lib/identical.cc b/runtime/lib/identical.cc
new file mode 100644
index 0000000..4dc8bac
--- /dev/null
+++ b/runtime/lib/identical.cc
@@ -0,0 +1,31 @@
+// 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.
+
+#include "vm/bootstrap_natives.h"
+
+#include "vm/object.h"
+
+namespace dart {
+
+DEFINE_NATIVE_ENTRY(Identical_comparison, 2) {
+  GET_NATIVE_ARGUMENT(Instance, a, arguments->NativeArgAt(0));
+  GET_NATIVE_ARGUMENT(Instance, b, arguments->NativeArgAt(1));
+  if (a.raw() == b.raw()) return Bool::True().raw();
+  if (a.IsInteger() && b.IsInteger()) {
+    return Bool::Get(a.Equals(b));
+  }
+  if (a.IsDouble() && b.IsDouble()) {
+    if (a.Equals(b)) return Bool::True().raw();
+    // Check for NaN.
+    const Double& a_double = Double::Cast(a);
+    const Double& b_double = Double::Cast(b);
+    if (isnan(a_double.value()) && isnan(b_double.value())) {
+      return Bool::True().raw();
+    }
+  }
+  return Bool::False().raw();
+}
+
+
+}  // namespace dart
diff --git a/runtime/lib/identical_patch.dart b/runtime/lib/identical_patch.dart
index 218b3c8..b7f8f18 100644
--- a/runtime/lib/identical_patch.dart
+++ b/runtime/lib/identical_patch.dart
@@ -2,6 +2,4 @@
 // for 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 bool identical(Object a, Object b) {
-  throw new Error('Should not reach the body of identical');  
-}
+patch bool identical(Object a, Object b) native "Identical_comparison";
diff --git a/runtime/lib/integers.cc b/runtime/lib/integers.cc
index 0b10b38a..5a8fd2e 100644
--- a/runtime/lib/integers.cc
+++ b/runtime/lib/integers.cc
@@ -185,8 +185,7 @@
 
 DEFINE_NATIVE_ENTRY(Integer_parse, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0));
-  const String& dummy_key = String::Handle(Symbols::Empty());
-  Scanner scanner(value, dummy_key);
+  Scanner scanner(value, Symbols::Empty());
   const Scanner::GrowableTokenStream& tokens = scanner.GetStream();
   String* int_string;
   bool is_positive;
@@ -198,12 +197,12 @@
       return Integer::New(*int_string);
     }
     String& temp = String::Handle();
-    temp = String::Concat(String::Handle(Symbols::New("-")), *int_string);
+    temp = String::Concat(Symbols::Dash(), *int_string);
     return Integer::New(temp);
   }
 
-  GrowableArray<const Object*> args;
-  args.Add(&value);
+  const Array& args = Array::Handle(Array::New(1));
+  args.SetAt(0, value);
   Exceptions::ThrowByType(Exceptions::kFormat, args);
   return Object::null();
 }
@@ -213,8 +212,8 @@
                                         const Integer& value,
                                         const Smi& amount) {
   if (amount.Value() < 0) {
-    GrowableArray<const Object*> args;
-    args.Add(&amount);
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, amount);
     Exceptions::ThrowByType(Exceptions::kArgument, args);
   }
   if (value.IsSmi()) {
diff --git a/runtime/lib/invocation_mirror.cc b/runtime/lib/invocation_mirror.cc
new file mode 100644
index 0000000..8e0880a
--- /dev/null
+++ b/runtime/lib/invocation_mirror.cc
@@ -0,0 +1,57 @@
+// 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.
+
+#include "vm/bootstrap_natives.h"
+
+#include "vm/compiler.h"
+#include "vm/dart_entry.h"
+#include "vm/exceptions.h"
+#include "vm/native_entry.h"
+#include "vm/object_store.h"
+#include "vm/resolver.h"
+#include "vm/symbols.h"
+
+namespace dart {
+
+DEFINE_NATIVE_ENTRY(InvocationMirror_invoke, 4) {
+  const Instance& receiver = Instance::CheckedHandle(arguments->NativeArgAt(0));
+  const String& fun_name = String::CheckedHandle(arguments->NativeArgAt(1));
+  const Array& fun_args_desc = Array::CheckedHandle(arguments->NativeArgAt(2));
+  const Array& fun_arguments = Array::CheckedHandle(arguments->NativeArgAt(3));
+
+  // Allocate a fixed-length array duplicating the original function arguments
+  // and replace the receiver.
+  const int num_arguments = fun_arguments.Length();
+  const Array& invoke_arguments = Array::Handle(Array::New(num_arguments));
+  invoke_arguments.SetAt(0, receiver);
+  Object& arg = Object::Handle();
+  for (int i = 1; i < num_arguments; i++) {
+    arg = fun_arguments.At(i);
+    invoke_arguments.SetAt(i, arg);
+  }
+  // Resolve dynamic function given by name.
+  const ArgumentsDescriptor args_desc(fun_args_desc);
+  const Function& function = Function::Handle(
+      Resolver::ResolveDynamic(receiver,
+                               fun_name,
+                               args_desc.Count(),
+                               args_desc.NamedCount()));
+  Object& result = Object::Handle();
+  if (function.IsNull()) {
+    result = DartEntry::InvokeNoSuchMethod(receiver,
+                                           fun_name,
+                                           invoke_arguments,
+                                           fun_args_desc);
+  } else {
+    result = DartEntry::InvokeDynamic(function,
+                                      invoke_arguments,
+                                      fun_args_desc);
+  }
+  if (result.IsError()) {
+    Exceptions::PropagateError(Error::Cast(result));
+  }
+  return result.raw();
+}
+
+}  // namespace dart
diff --git a/runtime/lib/invocation_mirror_patch.dart b/runtime/lib/invocation_mirror_patch.dart
index e81fe50..840b6f0 100644
--- a/runtime/lib/invocation_mirror_patch.dart
+++ b/runtime/lib/invocation_mirror_patch.dart
@@ -3,64 +3,112 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class _InvocationMirror implements InvocationMirror {
-  static final int METHOD = 0;
-  static final int GETTER = 1;
-  static final int SETTER = 2;
+  // Constants describing the invocation type.
+  static final int _METHOD = 0;
+  static final int _GETTER = 1;
+  static final int _SETTER = 2;
 
-  // TODO(regis): Compute lazily the value of these fields, and save the
-  // arguments passed into _allocateInvocationMirror.
+  // Internal representation of the invocation mirror.
+  final String _functionName;
+  final List _argumentsDescriptor;
+  final List _arguments;
 
-  final String memberName;
-  final List positionalArguments;
-  final Map<String, dynamic> namedArguments;
+  // External representation of the invocation mirror; populated on demand.
+  String _memberName;
+  int _type;
+  List _positionalArguments;
+  Map<String, dynamic> _namedArguments;
 
-  final int _type;
-
-  _InvocationMirror(this.memberName,
-                    this._type,
-                    this.positionalArguments,
-                    this.namedArguments);
-
-  static _allocateInvocationMirror(String name,
-                                   List argumentsDescriptor,
-                                   List arguments) {
-    var memberName;
-    var type;
-    if (name.startsWith("get:")) {
-      type = GETTER;
-      memberName = name.substring(4);
-    } else if (name.startsWith("set:")) {
-      type = SETTER;
-      memberName = name.substring(4).concat("=");
+  void _setMemberNameAndType() {
+    if (_functionName.startsWith("get:")) {
+      _type = _GETTER;
+      _memberName = _functionName.substring(4);
+    } else if (_functionName.startsWith("set:")) {
+      _type = _SETTER;
+      _memberName = _functionName.substring(4).concat("=");
     } else {
-      type = METHOD;
-      memberName = name;
+      _type = _METHOD;
+      _memberName = _functionName;
     }
-    // Exclude receiver.
-    int numArguments = argumentsDescriptor[0] - 1;
-    int numPositionalArguments = argumentsDescriptor[1] - 1;
-    int numNamedArguments = numArguments - numPositionalArguments;
-    List positionalArguments = arguments.getRange(1, numPositionalArguments);
-    Map<String, dynamic> namedArguments;
-    if (numNamedArguments > 0) {
-      namedArguments = new Map<String, dynamic>();
-      for (int i = 0; i < numNamedArguments; i++) {
-        String arg_name = argumentsDescriptor[2 + 2*i];
-        var arg_value = arguments[argumentsDescriptor[3 + 2*i]];
-        namedArguments[arg_name] = arg_value;
-      }
-    }
-    return new _InvocationMirror(memberName, type,
-                                 positionalArguments, namedArguments);
   }
 
-  bool get isMethod => _type == METHOD;
-  bool get isAccessor => _type != METHOD;
-  bool get isGetter => _type == GETTER;
-  bool get isSetter => _type == SETTER;
+  String get memberName {
+    if (_memberName == null) {
+      _setMemberNameAndType();
+    }
+    return _memberName;
+  }
+
+  List get positionalArguments {
+    if (_positionalArguments == null) {
+      // Exclude receiver.
+      int numPositionalArguments = _argumentsDescriptor[1] - 1;
+      _positionalArguments = _arguments.getRange(1, numPositionalArguments);
+    }
+    return _positionalArguments;
+  }
+
+  Map<String, dynamic> get namedArguments {
+    if (_namedArguments == null) {
+      _namedArguments = new Map<String, dynamic>();
+      int numArguments = _argumentsDescriptor[0] - 1;  // Exclude receiver.
+      int numPositionalArguments = _argumentsDescriptor[1] - 1;
+      int numNamedArguments = numArguments - numPositionalArguments;
+      for (int i = 0; i < numNamedArguments; i++) {
+        String arg_name = _argumentsDescriptor[2 + 2*i];
+        var arg_value = _arguments[_argumentsDescriptor[3 + 2*i]];
+        _namedArguments[arg_name] = arg_value;
+      }
+    }
+    return _namedArguments;
+  }
+
+  bool get isMethod {
+    if (_type == null) {
+      _setMemberNameAndType();
+    }
+    return _type == _METHOD;
+  }
+
+  bool get isAccessor {
+    if (_type == null) {
+      _setMemberNameAndType();
+    }
+    return _type != _METHOD;
+  }
+
+  bool get isGetter {
+    if (_type == null) {
+      _setMemberNameAndType();
+    }
+    return _type == _GETTER;
+  }
+
+  bool get isSetter {
+    if (_type == null) {
+      _setMemberNameAndType();
+    }
+    return _type == _SETTER;
+  }
+
+  _InvocationMirror(this._functionName,
+                    this._argumentsDescriptor,
+                    this._arguments);
+
+  static _allocateInvocationMirror(String functionName,
+                                   List argumentsDescriptor,
+                                   List arguments) {
+    return new _InvocationMirror(functionName, argumentsDescriptor, arguments);
+  }
+
+  static _invoke(Object receiver,
+                 String functionName,
+                 List argumentsDescriptor,
+                 List arguments)
+      native "InvocationMirror_invoke";
 
   invokeOn(Object receiver) {
-    throw new UnsupportedError("invokeOn not implemented yet");
+    return _invoke(receiver, _functionName, _argumentsDescriptor, _arguments);
   }
 }
 
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index abb15ba..d65246b 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -51,28 +51,29 @@
 
 
 // TODO(turnidge): Move to DartLibraryCalls.
-RawObject* ReceivePortCreate(intptr_t port_id) {
-  Library& isolate_lib = Library::Handle(Library::IsolateLibrary());
-  ASSERT(!isolate_lib.IsNull());
-  const String& public_class_name =
-      String::Handle(Symbols::New("_ReceivePortImpl"));
-  const String& class_name =
-      String::Handle(isolate_lib.PrivateName(public_class_name));
-  const String& function_name =
-      String::Handle(Symbols::New("_get_or_create"));
+static RawObject* ReceivePortCreate(intptr_t port_id) {
+  Isolate* isolate = Isolate::Current();
+  Function& func =
+      Function::Handle(isolate,
+                       isolate->object_store()->receive_port_create_function());
   const int kNumArguments = 1;
-  const Array& kNoArgumentNames = Array::Handle();
-  const Function& function = Function::Handle(
-      Resolver::ResolveStatic(isolate_lib,
-                              class_name,
-                              function_name,
-                              kNumArguments,
-                              kNoArgumentNames,
-                              Resolver::kIsQualified));
-  GrowableArray<const Object*> arguments(kNumArguments);
-  arguments.Add(&Integer::Handle(Integer::New(port_id)));
-  const Object& result = Object::Handle(
-      DartEntry::InvokeStatic(function, arguments, kNoArgumentNames));
+  if (func.IsNull()) {
+    Library& isolate_lib = Library::Handle(Library::IsolateLibrary());
+    ASSERT(!isolate_lib.IsNull());
+    const String& class_name =
+        String::Handle(isolate_lib.PrivateName(Symbols::_ReceivePortImpl()));
+    func = Resolver::ResolveStatic(isolate_lib,
+                                   class_name,
+                                   Symbols::_get_or_create(),
+                                   kNumArguments,
+                                   Object::empty_array(),
+                                   Resolver::kIsQualified);
+    isolate->object_store()->set_receive_port_create_function(func);
+  }
+  const Array& args = Array::Handle(isolate, Array::New(kNumArguments));
+  args.SetAt(0, Integer::Handle(isolate, Integer::New(port_id)));
+  const Object& result =
+      Object::Handle(isolate, DartEntry::InvokeStatic(func, args));
   if (!result.IsError()) {
     PortMap::SetLive(port_id);
   }
@@ -150,15 +151,15 @@
 
 
 static void ThrowIllegalArgException(const String& message) {
-  GrowableArray<const Object*> args(1);
-  args.Add(&message);
+  const Array& args = Array::Handle(Array::New(1));
+  args.SetAt(0, message);
   Exceptions::ThrowByType(Exceptions::kArgument, args);
 }
 
 
 static void ThrowIsolateSpawnException(const String& message) {
-  GrowableArray<const Object*> args(1);
-  args.Add(&message);
+  const Array& args = Array::Handle(Array::New(1));
+  args.SetAt(0, message);
   Exceptions::ThrowByType(Exceptions::kIsolateSpawn, args);
 }
 
@@ -202,11 +203,12 @@
 
 class SpawnState {
  public:
-  explicit SpawnState(const Function& func)
+  SpawnState(const Function& func, const Function& callback_func)
       : isolate_(NULL),
         script_url_(NULL),
         library_url_(NULL),
-        function_name_(NULL) {
+        function_name_(NULL),
+        exception_callback_name_(NULL) {
     script_url_ = strdup(GetRootScriptUri(Isolate::Current()));
     const Class& cls = Class::Handle(func.Owner());
     ASSERT(cls.IsTopLevel());
@@ -216,21 +218,30 @@
 
     const String& func_name = String::Handle(func.name());
     function_name_ = strdup(func_name.ToCString());
+    if (!callback_func.IsNull()) {
+      const String& callback_name = String::Handle(callback_func.name());
+      exception_callback_name_ = strdup(callback_name.ToCString());
+    } else {
+      exception_callback_name_ = strdup("_unhandledExceptionCallback");
+    }
   }
 
   explicit SpawnState(const char* script_url)
       : isolate_(NULL),
         library_url_(NULL),
-        function_name_(NULL) {
+        function_name_(NULL),
+        exception_callback_name_(NULL) {
     script_url_ = strdup(script_url);
     library_url_ = NULL;
     function_name_ = strdup("main");
+    exception_callback_name_ = strdup("_unhandledExceptionCallback");
   }
 
   ~SpawnState() {
     free(script_url_);
     free(library_url_);
     free(function_name_);
+    free(exception_callback_name_);
   }
 
   Isolate* isolate() const { return isolate_; }
@@ -238,6 +249,7 @@
   char* script_url() const { return script_url_; }
   char* library_url() const { return library_url_; }
   char* function_name() const { return function_name_; }
+  char* exception_callback_name() const { return exception_callback_name_; }
 
   RawObject* ResolveFunction() {
     // Resolve the library.
@@ -278,6 +290,7 @@
   char* script_url_;
   char* library_url_;
   char* function_name_;
+  char* exception_callback_name_;
 };
 
 
@@ -319,6 +332,12 @@
       errobj ^= result.raw();
       *error = strdup(errobj.ToErrorCString());
       resolve_error = true;
+    } else {
+      const String& callback_name =
+          String::Handle(child_isolate,
+                         String::New(state->exception_callback_name()));
+      child_isolate->object_store()->
+          set_unhandled_exception_handler(callback_name);
     }
   }
   if (resolve_error) {
@@ -344,8 +363,8 @@
       // Error is in sticky error already.
       return false;
     }
-    Object& result = Object::Handle();
 
+    Object& result = Object::Handle();
     result = state->ResolveFunction();
     delete state;
     state = NULL;
@@ -356,9 +375,7 @@
     ASSERT(result.IsFunction());
     Function& func = Function::Handle(isolate);
     func ^= result.raw();
-    GrowableArray<const Object*> args(0);
-    const Array& kNoArgNames = Array::Handle();
-    result = DartEntry::InvokeStatic(func, args, kNoArgNames);
+    result = DartEntry::InvokeStatic(func, Object::empty_array());
     if (result.IsError()) {
       StoreError(isolate, result);
       return false;
@@ -397,7 +414,7 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(isolate_spawnFunction, 1) {
+DEFINE_NATIVE_ENTRY(isolate_spawnFunction, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0));
   bool throw_exception = false;
   Function& func = Function::Handle();
@@ -417,12 +434,36 @@
     ThrowIllegalArgException(msg);
   }
 
+  GET_NATIVE_ARGUMENT(Instance, callback, arguments->NativeArgAt(1));
+  Function& callback_func = Function::Handle();
+  if (callback.IsClosure()) {
+    callback_func ^= Closure::function(callback);
+    const Class& cls = Class::Handle(callback_func.Owner());
+    if (!callback_func.IsClosureFunction() || !callback_func.is_static() ||
+        !cls.IsTopLevel()) {
+      throw_exception = true;
+    }
+  } else if (!callback.IsNull()) {
+    throw_exception = true;
+  }
+  if (throw_exception) {
+    const String& msg = String::Handle(String::New(
+        "spawnFunction expects to be passed either a unhandled exception "
+        "callback to a top-level static function, or null"));
+    ThrowIllegalArgException(msg);
+  }
+
 #if defined(DEBUG)
-  const Context& ctx = Context::Handle(Closure::context(closure));
+  Context& ctx = Context::Handle();
+  ctx = Closure::context(closure);
   ASSERT(ctx.num_variables() == 0);
+  if (!callback.IsNull()) {
+    ctx = Closure::context(callback);
+    ASSERT(ctx.num_variables() == 0);
+  }
 #endif
 
-  return Spawn(arguments, new SpawnState(func));
+  return Spawn(arguments, new SpawnState(func, callback_func));
 }
 
 
diff --git a/runtime/lib/isolate_patch.dart b/runtime/lib/isolate_patch.dart
index fee97ab..03ec664 100644
--- a/runtime/lib/isolate_patch.dart
+++ b/runtime/lib/isolate_patch.dart
@@ -35,6 +35,7 @@
     }
     return new _ReceivePortImpl._internal(id);
   }
+
   _ReceivePortImpl._internal(int id) : _id = id {
     if (_portMap == null) {
       _portMap = new Map();
@@ -42,10 +43,15 @@
     _portMap[id] = this;
   }
 
-  // Called from the VM to dispatch to the handler.
-  static void _handleMessage(int id, int replyId, var message) {
+  // Called from the VM to retrieve the ReceivePort for a message.
+  static _ReceivePortImpl _lookupReceivePort(int id) {
     assert(_portMap != null);
-    ReceivePort port = _portMap[id];
+    return _portMap[id];
+  }
+
+  // Called from the VM to dispatch to the handler.
+  static void _handleMessage(_ReceivePortImpl port, int replyId, var message) {
+    assert(port != null);
     SendPort replyTo = (replyId == 0) ? null : new _SendPortImpl(replyId);
     (port._onMessage)(message, replyTo);
   }
@@ -123,32 +129,34 @@
   return _portInternal;
 }
 
-patch spawnFunction(void topLevelFunction()) native "isolate_spawnFunction";
+patch spawnFunction(void topLevelFunction(),
+    [bool UnhandledExceptionCallback(IsolateUnhandledException e)]) 
+    native "isolate_spawnFunction";
 
 patch spawnUri(String uri) native "isolate_spawnUri";
 
 patch class Timer {
-  /* patch */ factory Timer(int milliSeconds, void callback(Timer timer)) {
+  /* patch */ factory Timer(int milliseconds, void callback(Timer timer)) {
     if (_TimerFactory._factory == null) {
       throw new UnsupportedError("Timer interface not supported.");
     }
-    return _TimerFactory._factory(milliSeconds, callback, false);
+    return _TimerFactory._factory(milliseconds, callback, false);
   }
 
   /**
    * Creates a new repeating timer. The [callback] is invoked every
-   * [milliSeconds] millisecond until cancelled.
+   * [milliseconds] millisecond until cancelled.
    */
-  /* patch */ factory Timer.repeating(int milliSeconds,
+  /* patch */ factory Timer.repeating(int milliseconds,
                                       void callback(Timer timer)) {
     if (_TimerFactory._factory == null) {
       throw new UnsupportedError("Timer interface not supported.");
     }
-    return _TimerFactory._factory(milliSeconds, callback, true);
+    return _TimerFactory._factory(milliseconds, callback, true);
   }
 }
 
-typedef Timer _TimerFactoryClosure(int milliSeconds,
+typedef Timer _TimerFactoryClosure(int milliseconds,
                                    void callback(Timer timer),
                                    bool repeating);
 
diff --git a/runtime/lib/lib_sources.gypi b/runtime/lib/lib_sources.gypi
index 3de2cde..b6f0032 100644
--- a/runtime/lib/lib_sources.gypi
+++ b/runtime/lib/lib_sources.gypi
@@ -20,14 +20,17 @@
     'errors_patch.dart',
     'error.h',
     'expando_patch.dart',
+    'function.cc',
     'function_patch.dart',
     'growable_array.cc',
     'growable_array.dart',
+    'identical.cc',
     'identical_patch.dart',
     'immutable_map.dart',
     'integers.cc',
     'integers.dart',
     'integers_patch.dart',
+    'invocation_mirror.cc',
     'invocation_mirror_patch.dart',
     'map_patch.dart',
     'object.cc',
diff --git a/runtime/lib/mirrors_patch.dart b/runtime/lib/mirrors_patch.dart
new file mode 100644
index 0000000..9b61edb
--- /dev/null
+++ b/runtime/lib/mirrors_patch.dart
@@ -0,0 +1,28 @@
+// 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.
+
+/**
+ * Returns a [MirrorSystem] for the current isolate.
+ */
+patch MirrorSystem currentMirrorSystem() {
+  return _Mirrors.currentMirrorSystem();
+}
+
+/**
+ * Creates a [MirrorSystem] for the isolate which is listening on
+ * the [SendPort].
+ */
+patch Future<MirrorSystem> mirrorSystemOf(SendPort port) {
+  return _Mirrors.mirrorSystemOf(port);
+}
+
+/**
+ * Returns an [InstanceMirror] for some Dart language object.
+ *
+ * This only works if this mirror system is associated with the
+ * current running isolate.
+ */
+patch InstanceMirror reflect(Object reflectee) {
+  return _Mirrors.reflect(reflectee);
+}
diff --git a/runtime/lib/mirrors_sources.gypi b/runtime/lib/mirrors_sources.gypi
index 8f1f805..a052847 100644
--- a/runtime/lib/mirrors_sources.gypi
+++ b/runtime/lib/mirrors_sources.gypi
@@ -6,9 +6,9 @@
 
 {
   'sources': [
-    '../../sdk/lib/mirrors/mirrors.dart',
     'mirrors.cc',
     'mirrors.h',
+    'mirrors_patch.dart',
     'mirrors_impl.dart',
   ],
 }
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index 3b06b58..dd47381 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -7,6 +7,8 @@
 #include "vm/exceptions.h"
 #include "vm/native_entry.h"
 #include "vm/object.h"
+#include "vm/stack_frame.h"
+#include "vm/symbols.h"
 
 namespace dart {
 
@@ -24,11 +26,11 @@
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, func_args, arguments->NativeArgAt(3));
   GET_NON_NULL_NATIVE_ARGUMENT(
       Instance, func_named_args, arguments->NativeArgAt(4));
-  GrowableArray<const Object*> dart_arguments(5);
-  dart_arguments.Add(&instance);
-  dart_arguments.Add(&member_name);
-  dart_arguments.Add(&func_args);
-  dart_arguments.Add(&func_named_args);
+  const Array& dart_arguments = Array::Handle(Array::New(5));
+  dart_arguments.SetAt(0, instance);
+  dart_arguments.SetAt(1, member_name);
+  dart_arguments.SetAt(2, func_args);
+  dart_arguments.SetAt(3, func_named_args);
 
   if (is_method.value()) {
     // Report if a function with same name (but different arguments) has been
@@ -48,7 +50,7 @@
       for (int i = 1; i < total_num_parameters; i++) {
         array.SetAt(i - 1, String::Handle(function.ParameterNameAt(i)));
       }
-      dart_arguments.Add(&array);
+      dart_arguments.SetAt(4, array);
     }
   }
   Exceptions::ThrowByType(Exceptions::kNoSuchMethod, dart_arguments);
@@ -63,10 +65,43 @@
 }
 
 
+
+DEFINE_NATIVE_ENTRY(Object_instanceOf, 5) {
+  const Instance& instance = Instance::CheckedHandle(arguments->NativeArgAt(0));
+  // Instantiator at position 1 is not used. It is passed along so that the call
+  // can be easily converted to an optimized implementation. Instantiator is
+  // used to populate the subtype cache.
+  const AbstractTypeArguments& instantiator_type_arguments =
+      AbstractTypeArguments::CheckedHandle(arguments->NativeArgAt(2));
+  const AbstractType& type =
+      AbstractType::CheckedHandle(arguments->NativeArgAt(3));
+  const Bool& negate = Bool::CheckedHandle(arguments->NativeArgAt(4));
+  ASSERT(type.IsFinalized());
+  Error& malformed_error = Error::Handle();
+  const bool is_instance_of = instance.IsInstanceOf(type,
+                                                    instantiator_type_arguments,
+                                                    &malformed_error);
+  if (!is_instance_of && !malformed_error.IsNull()) {
+    // Throw a dynamic type error only if the instanceof test fails.
+    DartFrameIterator iterator;
+    StackFrame* caller_frame = iterator.NextFrame();
+    ASSERT(caller_frame != NULL);
+    const intptr_t location = caller_frame->GetTokenPos();
+    String& malformed_error_message =  String::Handle(
+        String::New(malformed_error.ToErrorCString()));
+    Exceptions::CreateAndThrowTypeError(
+        location, Symbols::Empty(), Symbols::Empty(),
+        Symbols::Empty(), malformed_error_message);
+    UNREACHABLE();
+  }
+  return Bool::Get(negate.value() ? !is_instance_of : is_instance_of);
+}
+
+
 DEFINE_NATIVE_ENTRY(AbstractType_toString, 1) {
   const AbstractType& type =
       AbstractType::CheckedHandle(arguments->NativeArgAt(0));
-  return type.Name();
+  return type.UserVisibleName();
 }
 
 }  // namespace dart
diff --git a/runtime/lib/object_patch.dart b/runtime/lib/object_patch.dart
index d29a4ae..9939f29 100644
--- a/runtime/lib/object_patch.dart
+++ b/runtime/lib/object_patch.dart
@@ -36,5 +36,13 @@
                          invocation.namedArguments);
   }
 
+  // Call this function instead of inlining instanceof, thus collecting
+  // type feedback and reducing code size of unoptimized code.
+  _instanceOf(instantiator,
+              instantiator_type_arguments,
+              type,
+              bool negate)
+      native "Object_instanceOf";
+
   /* patch */ Type get runtimeType native "Object_runtimeType";
 }
diff --git a/runtime/lib/regexp.cc b/runtime/lib/regexp.cc
index f55767c..a1e029e 100644
--- a/runtime/lib/regexp.cc
+++ b/runtime/lib/regexp.cc
@@ -20,8 +20,8 @@
       Instance, handle_multi_line, arguments->NativeArgAt(2));
   GET_NON_NULL_NATIVE_ARGUMENT(
       Instance, handle_ignore_case, arguments->NativeArgAt(3));
-  bool ignore_case = handle_ignore_case.raw() == Bool::True();
-  bool multi_line = handle_multi_line.raw() == Bool::True();
+  bool ignore_case = handle_ignore_case.raw() == Bool::True().raw();
+  bool multi_line = handle_multi_line.raw() == Bool::True().raw();
   return Jscre::Compile(pattern, multi_line, ignore_case);
 }
 
@@ -56,9 +56,9 @@
   const String& pattern = String::Handle(regexp.pattern());
   const String& errmsg =
       String::Handle(String::New("Regular expression is not initialized yet"));
-  GrowableArray<const Object*> args;
-  args.Add(&pattern);
-  args.Add(&errmsg);
+  const Array& args = Array::Handle(Array::New(2));
+  args.SetAt(0, pattern);
+  args.SetAt(1, errmsg);
   Exceptions::ThrowByType(Exceptions::kIllegalJSRegExp, args);
   return Object::null();
 }
diff --git a/runtime/lib/regexp_jsc.cc b/runtime/lib/regexp_jsc.cc
index 31cee70..cb3ec68 100644
--- a/runtime/lib/regexp_jsc.cc
+++ b/runtime/lib/regexp_jsc.cc
@@ -44,9 +44,9 @@
     error_msg = "Unknown regexp compile error";
   }
   const String& errmsg = String::Handle(String::New(error_msg));
-  GrowableArray<const Object*> args;
-  args.Add(&pattern);
-  args.Add(&errmsg);
+  const Array& args = Array::Handle(Array::New(2));
+  args.SetAt(0, pattern);
+  args.SetAt(1, errmsg);
   Exceptions::ThrowByType(Exceptions::kIllegalJSRegExp, args);
 }
 
diff --git a/runtime/lib/string.cc b/runtime/lib/string.cc
index 528a179..c636a8b 100644
--- a/runtime/lib/string.cc
+++ b/runtime/lib/string.cc
@@ -26,14 +26,13 @@
   for (intptr_t i = 0; i < array_len; i++) {
     index_object = a.At(i);
     if (!index_object.IsSmi()) {
-      GrowableArray<const Object*> args;
-      args.Add(&index_object);
+      const Array& args = Array::Handle(Array::New(1));
+      args.SetAt(0, index_object);
       Exceptions::ThrowByType(Exceptions::kArgument, args);
     }
     intptr_t value = Smi::Cast(index_object).Value();
     if (Utf::IsOutOfRange(value)) {
-      GrowableArray<const Object*> args;
-      Exceptions::ThrowByType(Exceptions::kArgument, args);
+      Exceptions::ThrowByType(Exceptions::kArgument, Object::empty_array());
     } else {
       if (!Utf::IsLatin1(value)) {
         is_one_byte_string = false;
@@ -128,16 +127,16 @@
     smi ^= index.raw();
     int32_t index = smi.Value();
     if ((index < 0) || (index >= str.Length())) {
-      GrowableArray<const Object*> arguments;
-      arguments.Add(&smi);
-      Exceptions::ThrowByType(Exceptions::kRange, arguments);
+      const Array& args = Array::Handle(Array::New(1));
+      args.SetAt(0, smi);
+      Exceptions::ThrowByType(Exceptions::kRange, args);
     }
     return str.CharAt(index);
   } else {
     // An index larger than Smi is always illegal.
-    GrowableArray<const Object*> arguments;
-    arguments.Add(&index);
-    Exceptions::ThrowByType(Exceptions::kRange, arguments);
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, index);
+    Exceptions::ThrowByType(Exceptions::kRange, args);
     return 0;
   }
 }
@@ -191,8 +190,8 @@
   for (intptr_t i = 0; i < strings.Length(); i++) {
     elem ^= strings.At(i);
     if (!elem.IsString()) {
-      GrowableArray<const Object*> args;
-      args.Add(&elem);
+      const Array& args = Array::Handle(Array::New(1));
+      args.SetAt(0, elem);
       Exceptions::ThrowByType(Exceptions::kArgument, args);
     }
   }
diff --git a/runtime/lib/string_base.dart b/runtime/lib/string_base.dart
index 2d2e90e..3d2484e 100644
--- a/runtime/lib/string_base.dart
+++ b/runtime/lib/string_base.dart
@@ -219,10 +219,11 @@
     Iterator iterator = pattern.allMatches(this).iterator();
     if (iterator.hasNext) {
       Match match = iterator.next();
-      buffer.add(this.substring(startIndex, match.start)).add(replacement);
+      buffer..add(this.substring(startIndex, match.start))
+            ..add(replacement);
       startIndex = match.end;
     }
-    return buffer.add(this.substring(startIndex)).toString();
+    return (buffer..add(this.substring(startIndex))).toString();
   }
 
   String replaceAll(Pattern pattern, String replacement) {
@@ -235,10 +236,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..add(this.substring(startIndex, match.start))
+            ..add(replacement);
       startIndex = match.end;
     }
-    return buffer.add(this.substring(startIndex)).toString();
+    return (buffer..add(this.substring(startIndex))).toString();
   }
 
   /**
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index 3e179be..99e07c3 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -20,7 +20,8 @@
 #define NOSERVICE
 #define NOSOUND
 #define NOMCX
-
+#define _UNICODE
+#define UNICODE
 #include <windows.h>
 #include <winsock2.h>
 #include <Rpc.h>
@@ -175,8 +176,12 @@
 
 // System-wide named constants.
 const intptr_t KB = 1024;
+const intptr_t KBLog2 = 10;
 const intptr_t MB = KB * KB;
-const intptr_t GB = KB * KB * KB;
+const intptr_t MBLog2 = KBLog2 + KBLog2;
+const intptr_t GB = MB * KB;
+const intptr_t GBLog2 = MBLog2 + KBLog2;
+
 const intptr_t kIntptrOne = 1;
 const intptr_t kIntptrMin = (kIntptrOne << (kBitsPerWord - 1));
 const intptr_t kIntptrMax = ~kIntptrMin;
diff --git a/runtime/tests/vm/dart/isolate_unhandled_exception_test.dart b/runtime/tests/vm/dart/isolate_unhandled_exception_test.dart
new file mode 100644
index 0000000..7bab730
--- /dev/null
+++ b/runtime/tests/vm/dart/isolate_unhandled_exception_test.dart
@@ -0,0 +1,48 @@
+// 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 isolate_unhandled_exception_test;
+
+import 'dart:isolate';
+
+// Tests that an isolate's keeps message handling working after
+// throwing an unhandled exception, if it was created with an
+// unhandled exception callback that returns true (continue handling).
+// This test verifies that a callback function specified in
+// Isolate.spawnFunction is called.
+
+// Note: this test will hang if an uncaught exception isn't handled,
+// either by an error in the callback or it returning false.
+
+void entry() {
+  port.receive((message, replyTo) {
+    if (message == 'throw exception') {
+      replyTo.call('throwing exception');
+      throw new RuntimeError('ignore this exception');
+    }
+    replyTo.call('hello');
+    port.close();
+  });
+}
+
+bool exceptionCallback(IsolateUnhandledException e) {
+  return e.source.message == 'ignore this exception';
+}
+
+void main() {
+  var isolate_port = spawnFunction(entry, exceptionCallback);
+
+  // Send a message that will cause an ignorable exception to be thrown.
+  Future f = isolate_port.call('throw exception');
+  f.onComplete((future) {
+    // Exception wasn't ignored as it was supposed to be.
+    Expect.equals(null, future.exception);
+  });
+
+  // Verify that isolate can still handle messages.
+  isolate_port.call('hi').onComplete((future) {
+    Expect.equals(null, future.exception);
+    Expect.equals('hello', future.value);
+  });
+}
diff --git a/runtime/tests/vm/dart/isolate_unhandled_exception_test2.dart b/runtime/tests/vm/dart/isolate_unhandled_exception_test2.dart
new file mode 100644
index 0000000..6fc0a11
--- /dev/null
+++ b/runtime/tests/vm/dart/isolate_unhandled_exception_test2.dart
@@ -0,0 +1,49 @@
+// 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 isolate_unhandled_exception_test2;
+
+import 'dart:isolate';
+
+// Tests that an isolate's keeps message handling working after
+// throwing an unhandled exception, if there is a top level callback
+// method that returns whether to continue handling messages or not.
+// This test verifies that a default-named callback function is called
+// when no callback is specified in Isolate.spawnFunction.
+
+// Note: this test will hang if an uncaught exception isn't handled,
+// either by an error in the callback or it returning false.
+
+void entry() {
+  port.receive((message, replyTo) {
+    if (message == 'throw exception') {
+      replyTo.call('throwing exception');
+      throw new RuntimeError('ignore this exception');
+    }
+    replyTo.call('hello');
+    port.close();
+  });
+}
+
+bool _unhandledExceptionCallback(IsolateUnhandledException e) {
+  return e.source.message == 'ignore this exception';
+}
+
+void main() {
+  var isolate_port = spawnFunction(entry);
+
+  // Send a message that will cause an ignorable exception to be thrown.
+  Future f = isolate_port.call('throw exception');
+  f.onComplete((future) {
+    // Exception wasn't ignored as it was supposed to be.
+    Expect.equals(null, future.exception);
+  });
+
+  // Verify that isolate can still handle messages.
+  isolate_port.call('hi').onComplete((future) {
+    Expect.equals(null, future.exception);
+    Expect.equals('hello', future.value);
+  });
+
+}
diff --git a/runtime/tests/vm/dart/isolate_unhandled_exception_uri_helper.dart b/runtime/tests/vm/dart/isolate_unhandled_exception_uri_helper.dart
new file mode 100644
index 0000000..a994f13
--- /dev/null
+++ b/runtime/tests/vm/dart/isolate_unhandled_exception_uri_helper.dart
@@ -0,0 +1,25 @@
+// 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 isolate_unhandled_exception_uri_helper;
+
+import 'dart:isolate';
+
+// Isolate script that throws an uncaught exception, which is caught by an
+// uncaught exception handler.
+
+void main() {
+  port.receive((message, replyTo) {
+    if (message == 'throw exception') {
+      replyTo.call('throwing exception');
+      throw new RuntimeError('ignore this exception');
+    }
+    replyTo.call('hello');
+    port.close();
+  });
+}
+
+bool _unhandledExceptionCallback(IsolateUnhandledException e) {
+  return e.source.message == 'ignore this exception';
+}
diff --git a/runtime/tests/vm/dart/isolate_unhandled_exception_uri_test.dart b/runtime/tests/vm/dart/isolate_unhandled_exception_uri_test.dart
new file mode 100644
index 0000000..da7ee50
--- /dev/null
+++ b/runtime/tests/vm/dart/isolate_unhandled_exception_uri_test.dart
@@ -0,0 +1,31 @@
+// 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 isolate_unhandled_exception_uri_helper;
+
+import 'dart:isolate';
+
+// Tests that isolate code in another script keeps message handling working
+// after throwing an unhandled exception, if it has a function called
+// unhandledExceptionCallback that returns true (continue handling).
+
+// Note: this test will hang if an uncaught exception isn't handled,
+// either by an error in the callback or it returning false.
+
+void main() {
+  var isolate_port = spawnUri('isolate_unhandled_exception_uri_helper.dart');
+
+  // Send a message that will cause an ignorable exception to be thrown.
+  Future f = isolate_port.call('throw exception');
+  f.onComplete((future) {
+    Expect.equals(null, future.exception);
+  });
+
+  // Verify that isolate can still handle messages.
+  isolate_port.call('hi').onComplete((future) {
+    Expect.equals(null, future.exception);
+    Expect.equals('hello', future.value);
+  });
+
+}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index f5f6038..0288b21 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -6,7 +6,6 @@
 cc/TypeVariableReflection: Crash # Issue 6958.
 cc/LibraryGetClassNames: Fail # Issue 6958.
 cc/ImportLibrary5: Fail # Issue 6958.
-cc/CustomIsolates: Crash # Default factory classes are removed.
 
 # These tests are expected to crash on all platforms.
 cc/ArrayNew_Overflow_Crash: Crash
@@ -32,6 +31,7 @@
 [ $compiler == dart2js || $compiler == dartc ]
 dart/isolate_mirror*: Skip # compilers not aware of dart:mirrors
 dart/byte_array_test: Skip # compilers not aware of byte arrays
+dart/isolate_unhandled*: Skip
 
 [ $compiler == dart2dart ]
 # Skip until we stabilize language tests.
diff --git a/runtime/vm/assembler_ia32.cc b/runtime/vm/assembler_ia32.cc
index 017c98f..7cc2476 100644
--- a/runtime/vm/assembler_ia32.cc
+++ b/runtime/vm/assembler_ia32.cc
@@ -6,7 +6,9 @@
 #if defined(TARGET_ARCH_IA32)
 
 #include "vm/assembler.h"
+#include "vm/code_generator.h"
 #include "vm/heap.h"
+#include "vm/heap_trace.h"
 #include "vm/memory_region.h"
 #include "vm/runtime_entry.h"
 #include "vm/stub_code.h"
@@ -1551,7 +1553,7 @@
 
 
 void Assembler::LoadObject(Register dst, const Object& object) {
-  if (object.IsSmi() || object.IsNull()) {
+  if (object.IsSmi() || object.InVMHeap()) {
     movl(dst, Immediate(reinterpret_cast<int32_t>(object.raw())));
   } else {
     ASSERT(object.IsNotTemporaryScopedHandle());
@@ -1564,7 +1566,7 @@
 
 
 void Assembler::PushObject(const Object& object) {
-  if (object.IsSmi() || object.IsNull()) {
+  if (object.IsSmi() || object.InVMHeap()) {
     pushl(Immediate(reinterpret_cast<int32_t>(object.raw())));
   } else {
     ASSERT(object.IsNotTemporaryScopedHandle());
@@ -1577,7 +1579,7 @@
 
 
 void Assembler::CompareObject(Register reg, const Object& object) {
-  if (object.IsSmi() || object.IsNull()) {
+  if (object.IsSmi() || object.InVMHeap()) {
     cmpl(reg, Immediate(reinterpret_cast<int32_t>(object.raw())));
   } else {
     ASSERT(object.IsNotTemporaryScopedHandle());
@@ -1620,6 +1622,7 @@
                                 const FieldAddress& dest,
                                 Register value) {
   ASSERT(object != value);
+  TraceStoreIntoObject(object, dest, value);
   movl(dest, value);
   Label done;
   StoreIntoObjectFilter(object, value, &done);
@@ -1635,6 +1638,7 @@
 void Assembler::StoreIntoObjectNoBarrier(Register object,
                                          const FieldAddress& dest,
                                          Register value) {
+  TraceStoreIntoObject(object, dest, value);
   movl(dest, value);
 #if defined(DEBUG)
   Label done;
@@ -1651,9 +1655,10 @@
 void Assembler::StoreIntoObjectNoBarrier(Register object,
                                          const FieldAddress& dest,
                                          const Object& value) {
-  if (value.IsSmi()) {
+  if (value.IsSmi() || value.InVMHeap()) {
     movl(dest, Immediate(reinterpret_cast<int32_t>(value.raw())));
   } else {
+    // No heap trace for an old object store.
     ASSERT(value.IsOld());
     AssemblerBuffer::EnsureCapacity ensured(&buffer_);
     EmitUint8(0xC7);
@@ -1664,6 +1669,23 @@
 }
 
 
+void Assembler::TraceStoreIntoObject(Register object,
+                                     const FieldAddress& dest,
+                                     Register value) {
+  if (HeapTrace::is_enabled()) {
+    pushal();
+    EnterCallRuntimeFrame(3 * kWordSize);
+    movl(Address(ESP, 0 * kWordSize), object);
+    leal(EAX, dest);
+    movl(Address(ESP, 1 * kWordSize), EAX);
+    movl(Address(ESP, 2 * kWordSize), value);
+    CallRuntime(kHeapTraceStoreRuntimeEntry);
+    LeaveCallRuntimeFrame();
+    popal();
+  }
+}
+
+
 void Assembler::LoadDoubleConstant(XmmRegister dst, double value) {
   // TODO(5410843): Need to have a code constants table.
   int64_t constant = bit_cast<int64_t, double>(value);
diff --git a/runtime/vm/assembler_ia32.h b/runtime/vm/assembler_ia32.h
index 78afb8f..e683375 100644
--- a/runtime/vm/assembler_ia32.h
+++ b/runtime/vm/assembler_ia32.h
@@ -554,6 +554,10 @@
                                 const FieldAddress& dest,
                                 const Object& value);
 
+  void TraceStoreIntoObject(Register object,
+                            const FieldAddress& dest,
+                            Register value);
+
   void DoubleNegate(XmmRegister d);
   void FloatNegate(XmmRegister f);
 
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc
index 075a73c..4f0d563 100644
--- a/runtime/vm/assembler_x64.cc
+++ b/runtime/vm/assembler_x64.cc
@@ -1649,7 +1649,7 @@
 
 
 void Assembler::LoadObject(Register dst, const Object& object) {
-  if (object.IsSmi() || object.IsNull()) {
+  if (object.IsSmi() || object.InVMHeap()) {
     movq(dst, Immediate(reinterpret_cast<int64_t>(object.raw())));
   } else {
     ASSERT(object.IsNotTemporaryScopedHandle());
@@ -1663,7 +1663,7 @@
 
 
 void Assembler::StoreObject(const Address& dst, const Object& object) {
-  if (object.IsSmi() || object.IsNull()) {
+  if (object.IsSmi() || object.InVMHeap()) {
     movq(dst, Immediate(reinterpret_cast<int64_t>(object.raw())));
   } else {
     ASSERT(object.IsNotTemporaryScopedHandle());
@@ -1675,7 +1675,7 @@
 
 
 void Assembler::PushObject(const Object& object) {
-  if (object.IsSmi() || object.IsNull()) {
+  if (object.IsSmi() || object.InVMHeap()) {
     pushq(Immediate(reinterpret_cast<int64_t>(object.raw())));
   } else {
     LoadObject(TMP, object);
@@ -1685,7 +1685,7 @@
 
 
 void Assembler::CompareObject(Register reg, const Object& object) {
-  if (object.IsSmi() || object.IsNull()) {
+  if (object.IsSmi() || object.InVMHeap()) {
     cmpq(reg, Immediate(reinterpret_cast<int64_t>(object.raw())));
   } else {
     ASSERT(reg != TMP);
diff --git a/runtime/vm/ast.cc b/runtime/vm/ast.cc
index f7c9aee..c88bdba 100644
--- a/runtime/vm/ast.cc
+++ b/runtime/vm/ast.cc
@@ -132,7 +132,7 @@
     case Token::kGTE:
       if ((left_val->IsNumber() || left_val->IsNull()) &&
           (right_val->IsNumber() || right_val->IsNull())) {
-        return &Bool::ZoneHandle(Bool::False());
+        return &Bool::False();
       }
       return NULL;
     case Token::kEQ:
@@ -149,7 +149,7 @@
           right_val->IsString() ||
           right_val->IsBool() ||
           right_val->IsNull())) {
-        return &Bool::ZoneHandle(Bool::False());
+        return &Bool::False();
       }
       return NULL;
     default:
@@ -293,6 +293,21 @@
 }
 
 
+AstNode* ClosureNode::MakeAssignmentNode(AstNode* rhs) {
+  if (scope() == NULL) {
+    // This is an implicit closure node created because a static getter was not
+    // found. Change the getter into a setter. If it does not exist,
+    // noSuchMethod will be called.
+    return new StaticSetterNode(token_pos(),
+                                receiver(),
+                                Class::ZoneHandle(function().Owner()),
+                                String::ZoneHandle(function().name()),
+                                rhs);
+  }
+  return NULL;
+}
+
+
 const char* UnaryOpNode::Name() const {
   return Token::Str(kind_);
 }
@@ -345,60 +360,50 @@
   const String& setter_name = String::Handle(Field::SetterName(field_name()));
 
   if (is_super_getter_) {
-    // Resolve the (dynamic) setter method.
     ASSERT(receiver() != NULL);
-    const Function& super_setter = Function::ZoneHandle(
-        Resolver::ResolveDynamicAnyArgs(cls(), setter_name));
-    if (!super_setter.IsNull()) {
-      return new StaticSetterNode(token_pos(),
-                                  receiver(),
-                                  cls(),
-                                  field_name(),
-                                  rhs);
-    }
-    // If setter is found in the superclass, do not turn this into an
-    // instance setter resolved at runtime, since a super getter/setter
-    // explicitly refers to the static superclass of the enclosing function.
-    return NULL;
-  } else {
-    const Function& setter =
-        Function::ZoneHandle(cls().LookupStaticFunction(setter_name));
-    if (!setter.IsNull()) {
+    // If the static setter is not found in the superclass, noSuchMethod will be
+    // called at runtime.
+    return new StaticSetterNode(token_pos(),
+                                receiver(),
+                                cls(),
+                                field_name(),
+                                rhs);
+  }
+  const Function& setter =
+      Function::ZoneHandle(cls().LookupStaticFunction(setter_name));
+  if (!setter.IsNull()) {
+    return new StaticSetterNode(token_pos(), NULL, cls(), field_name(), rhs);
+  }
+  // Could not find a static setter. Look for a field.
+  // Access to a lazily initialized static field that has not yet been
+  // initialized is compiled to a static implicit getter.
+  // A setter may not exist for such a field.
+  const Field& field = Field::ZoneHandle(cls().LookupStaticField(field_name()));
+  if (!field.IsNull()) {
+    if (field.is_final()) {
+      // Attempting to assign to a final variable will cause a NoSuchMethodError
+      // to be thrown. Change static getter to non-existent static setter in
+      // order to trigger the throw at runtime.
       return new StaticSetterNode(token_pos(), NULL, cls(), field_name(), rhs);
     }
-    // Could not find a static setter. Look for a field.
-    // Access to a lazily initialized static field that has not yet been
-    // initialized is compiled to a static implicit getter.
-    // A setter may not exist for such a field.
-    const Field& field =
-        Field::ZoneHandle(cls().LookupStaticField(field_name()));
-    if (!field.IsNull()) {
-      if (field.is_final()) {
-        return NULL;
-      }
 #if defined(DEBUG)
-      const String& getter_name =
-          String::Handle(Field::GetterName(field_name()));
-      const Function& getter =
-          Function::ZoneHandle(cls().LookupStaticFunction(getter_name));
-      ASSERT(!getter.IsNull() &&
-             (getter.kind() == RawFunction::kConstImplicitGetter));
+    const String& getter_name = String::Handle(Field::GetterName(field_name()));
+    const Function& getter =
+        Function::Handle(cls().LookupStaticFunction(getter_name));
+    ASSERT(!getter.IsNull() &&
+           (getter.kind() == RawFunction::kConstImplicitGetter));
 #endif
-      return new StoreStaticFieldNode(token_pos(), field, rhs);
-    }
-    // Didn't find a static setter or a static field.
-    // If this static getter is in an instance function where
-    // a receiver is available, we turn this static getter
-    // into an instance setter (and will get an error at runtime if an
-    // instance setter cannot be found either).
-    if (receiver() != NULL) {
-      return new InstanceSetterNode(token_pos(),
-                                    receiver(),
-                                    field_name(),
-                                    rhs);
-    }
-    return NULL;
+    return new StoreStaticFieldNode(token_pos(), field, rhs);
   }
+  // Didn't find a static setter or a static field.
+  // If this static getter is in an instance function where
+  // a receiver is available, we turn this static getter
+  // into an instance setter (and will get an error at runtime if an
+  // instance setter cannot be found either).
+  if (receiver() != NULL) {
+    return new InstanceSetterNode(token_pos(), receiver(), field_name(), rhs);
+  }
+  return new StaticSetterNode(token_pos(), NULL, cls(), field_name(), rhs);
 }
 
 
@@ -408,10 +413,8 @@
   const Class& cls = Class::Handle(function().Owner());
   const String& cls_name = String::Handle(cls.Name());
   const String& func_name = String::Handle(function().name());
-  const String& error_cls_name = String::Handle(Symbols::NoSuchMethodError());
-  const String& error_func_name = String::Handle(Symbols::ThrowNew());
-  if (cls_name.Equals(error_cls_name) &&
-      func_name.StartsWith(error_func_name)) {
+  if (cls_name.Equals(Symbols::NoSuchMethodError()) &&
+      func_name.StartsWith(Symbols::ThrowNew())) {
     return this;
   }
   return NULL;
@@ -426,12 +429,8 @@
   if (getter_func.IsNull() || !getter_func.is_const()) {
     return NULL;
   }
-  GrowableArray<const Object*> arguments;
-  const Array& kNoArgumentNames = Array::Handle();
-  const Object& result =
-      Object::Handle(DartEntry::InvokeStatic(getter_func,
-                                             arguments,
-                                             kNoArgumentNames));
+  const Object& result = Object::Handle(
+      DartEntry::InvokeStatic(getter_func, Object::empty_array()));
   if (result.IsError() || result.IsNull()) {
     // TODO(turnidge): We could get better error messages by returning
     // the Error object directly to the parser.  This will involve
diff --git a/runtime/vm/ast.h b/runtime/vm/ast.h
index 1be3a90..c3af57c 100644
--- a/runtime/vm/ast.h
+++ b/runtime/vm/ast.h
@@ -345,6 +345,13 @@
 
   const AbstractType& type() const { return type_; }
 
+  virtual const Instance* EvalConstExpr() const {
+    if (!type_.IsInstantiated() || type_.IsMalformed()) {
+      return NULL;
+    }
+    return &type();
+  }
+
   virtual void VisitChildren(AstNodeVisitor* visitor) const { }
 
   DECLARE_COMMON_NODE_FUNCTIONS(TypeNode);
@@ -367,7 +374,7 @@
     ASSERT(type_.IsZoneHandle());
     ASSERT(!type_.IsNull());
     ASSERT(type_.IsFinalized());
-    ASSERT(dst_name_.IsZoneHandle());
+    ASSERT(dst_name_.IsNotTemporaryScopedHandle());
   }
 
   AstNode* expr() const { return expr_; }
@@ -418,6 +425,8 @@
     }
   }
 
+  virtual AstNode* MakeAssignmentNode(AstNode* rhs);
+
   virtual const Instance* EvalConstExpr() const;
 
   DECLARE_COMMON_NODE_FUNCTIONS(ClosureNode);
@@ -439,13 +448,13 @@
  public:
   PrimaryNode(intptr_t token_pos, const Object& primary)
       : AstNode(token_pos), primary_(primary) {
-    ASSERT(primary_.IsZoneHandle());
+    ASSERT(primary_.IsNotTemporaryScopedHandle());
   }
 
   const Object& primary() const { return primary_; }
 
   bool IsSuper() const {
-    return primary().IsString() && (primary().raw() == Symbols::Super());
+    return primary().IsString() && (primary().raw() == Symbols::Super().raw());
   }
 
   virtual void VisitChildren(AstNodeVisitor* visitor) const;
@@ -1192,7 +1201,7 @@
         function_name_(function_name),
         arguments_(arguments) {
     ASSERT(receiver_ != NULL);
-    ASSERT(function_name_.IsZoneHandle());
+    ASSERT(function_name_.IsNotTemporaryScopedHandle());
     ASSERT(function_name_.IsSymbol());
     ASSERT(arguments_ != NULL);
   }
@@ -1226,7 +1235,7 @@
         receiver_(receiver),
         field_name_(field_name) {
     ASSERT(receiver_ != NULL);
-    ASSERT(field_name_.IsZoneHandle());
+    ASSERT(field_name_.IsNotTemporaryScopedHandle());
     ASSERT(field_name_.IsSymbol());
   }
 
diff --git a/runtime/vm/bigint_operations.cc b/runtime/vm/bigint_operations.cc
index 4adec18..8120e58 100644
--- a/runtime/vm/bigint_operations.cc
+++ b/runtime/vm/bigint_operations.cc
@@ -207,9 +207,9 @@
   }
   DoubleInternals internals = DoubleInternals(d);
   if (internals.IsSpecial()) {
-    GrowableArray<const Object*> exception_arguments;
-    exception_arguments.Add(
-        &Object::ZoneHandle(String::New("BigintOperations::NewFromDouble")));
+    const Array& exception_arguments = Array::Handle(Array::New(1));
+    exception_arguments.SetAt(
+        0, Object::Handle(String::New("BigintOperations::NewFromDouble")));
     Exceptions::ThrowByType(Exceptions::kInternalError, exception_arguments);
   }
   uint64_t significand = internals.Significand();
diff --git a/runtime/vm/bit_vector.cc b/runtime/vm/bit_vector.cc
index c08eaf1d..80b640b 100644
--- a/runtime/vm/bit_vector.cc
+++ b/runtime/vm/bit_vector.cc
@@ -62,6 +62,18 @@
 }
 
 
+bool BitVector::RemoveAll(const BitVector* from) {
+  ASSERT(data_length_ == from->data_length_);
+  bool changed = false;
+  for (intptr_t i = 0; i < data_length_; i++) {
+    const uword before = data_[i];
+    const uword after = data_[i] & ~from->data_[i];
+    if (before != after) changed = true;
+    data_[i] = after;
+  }
+  return changed;
+}
+
 bool BitVector::KillAndAdd(BitVector* kill, BitVector* gen) {
   ASSERT(data_length_ == kill->data_length_);
   ASSERT(data_length_ == gen->data_length_);
diff --git a/runtime/vm/bit_vector.h b/runtime/vm/bit_vector.h
index 1b48280..3dcd118 100644
--- a/runtime/vm/bit_vector.h
+++ b/runtime/vm/bit_vector.h
@@ -76,6 +76,9 @@
   // Add all elements that are in the bitvector from.
   bool AddAll(const BitVector* from);
 
+  // Remove all elements that are in the bitvector from.
+  bool RemoveAll(const BitVector* from);
+
   // From the bitvector gen add those elements that are not in the
   // bitvector kill.
   bool KillAndAdd(BitVector* kill, BitVector* gen);
diff --git a/runtime/vm/bit_vector_test.cc b/runtime/vm/bit_vector_test.cc
index 208f964..de2fe4f 100644
--- a/runtime/vm/bit_vector_test.cc
+++ b/runtime/vm/bit_vector_test.cc
@@ -102,6 +102,19 @@
     a->Remove(1);
     EXPECT_EQ(true, a->Equals(*b));
   }
+
+  { BitVector* a = new BitVector(128);
+    BitVector* b = new BitVector(128);
+    b->Add(0);
+    b->Add(32);
+    b->Add(64);
+    a->Add(0);
+    a->Add(64);
+    b->RemoveAll(a);
+    EXPECT_EQ(false, b->Contains(0));
+    EXPECT_EQ(true, b->Contains(32));
+    EXPECT_EQ(false, b->Contains(64));
+  }
 }
 
 }  // namespace dart
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index a7bd996..fec7c9d 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -16,7 +16,11 @@
   V(Object_toString, 1)                                                        \
   V(Object_noSuchMethod, 5)                                                    \
   V(Object_runtimeType, 1)                                                     \
+  V(Object_instanceOf, 5)                                                      \
+  V(Function_apply, 2)                                                         \
+  V(InvocationMirror_invoke, 4)                                                \
   V(AbstractType_toString, 1)                                                  \
+  V(Identical_comparison, 2)                                                   \
   V(Integer_bitAndFromInteger, 2)                                              \
   V(Integer_bitOrFromInteger, 2)                                               \
   V(Integer_bitXorFromInteger, 2)                                              \
@@ -102,7 +106,6 @@
   V(TypeError_throwNew, 5)                                                     \
   V(FallThroughError_throwNew, 1)                                              \
   V(AbstractClassInstantiationError_throwNew, 2)                               \
-  V(NoSuchMethodError_throwNew, 2)                                             \
   V(Stopwatch_now, 0)                                                          \
   V(Stopwatch_frequency, 0)                                                    \
   V(ByteArray_getLength, 1)                                                    \
@@ -192,7 +195,7 @@
   V(ExternalFloat64Array_getIndexed, 2)                                        \
   V(ExternalFloat64Array_setIndexed, 3)                                        \
   V(isolate_getPortInternal, 0)                                                \
-  V(isolate_spawnFunction, 1)                                                  \
+  V(isolate_spawnFunction, 2)                                                  \
   V(isolate_spawnUri, 1)                                                       \
   V(Mirrors_isLocalPort, 1)                                                    \
   V(Mirrors_makeLocalInstanceMirror, 1)                                        \
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 69f033e..ddc789c 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -138,9 +138,8 @@
       if (FLAG_trace_class_finalization) {
         OS::Print("Resolving super and interfaces: %s\n", cls.ToCString());
       }
-      ResolveSuperType(cls);
       GrowableArray<intptr_t> visited_interfaces;
-      ResolveInterfaces(cls, &visited_interfaces);
+      ResolveSuperTypeAndInterfaces(cls, &visited_interfaces);
     }
     // Finalize all classes.
     for (intptr_t i = 0; i < class_array.Length(); i++) {
@@ -309,88 +308,6 @@
 }
 
 
-// Resolve unresolved supertype (String -> Class).
-void ClassFinalizer::ResolveSuperType(const Class& cls) {
-  if (cls.is_finalized()) {
-    return;
-  }
-  Type& super_type = Type::Handle(cls.super_type());
-  if (super_type.IsNull()) {
-    return;
-  }
-  // Resolve failures lead to a longjmp.
-  ResolveType(cls, super_type, kCanonicalizeWellFormed);
-  const Class& super_class = Class::Handle(super_type.type_class());
-  // If cls belongs to core lib or to core lib's implementation, restrictions
-  // about allowed interfaces are lifted.
-  if (cls.library() != Library::CoreLibrary()) {
-    // Prevent extending core implementation classes.
-    bool is_error = false;
-    switch (super_class.id()) {
-      case kNumberCid:
-      case kIntegerCid:
-      case kSmiCid:
-      case kMintCid:
-      case kBigintCid:
-      case kDoubleCid:
-      case kOneByteStringCid:
-      case kTwoByteStringCid:
-      case kExternalOneByteStringCid:
-      case kExternalTwoByteStringCid:
-      case kBoolCid:
-      case kArrayCid:
-      case kImmutableArrayCid:
-      case kGrowableObjectArrayCid:
-      case kInt8ArrayCid:
-      case kExternalInt8ArrayCid:
-      case kUint8ArrayCid:
-      case kUint8ClampedArrayCid:
-      case kExternalUint8ArrayCid:
-      case kExternalUint8ClampedArrayCid:
-      case kInt16ArrayCid:
-      case kExternalInt16ArrayCid:
-      case kUint16ArrayCid:
-      case kExternalUint16ArrayCid:
-      case kInt32ArrayCid:
-      case kExternalInt32ArrayCid:
-      case kUint32ArrayCid:
-      case kExternalUint32ArrayCid:
-      case kInt64ArrayCid:
-      case kExternalInt64ArrayCid:
-      case kUint64ArrayCid:
-      case kExternalUint64ArrayCid:
-      case kFloat32ArrayCid:
-      case kExternalFloat32ArrayCid:
-      case kFloat64ArrayCid:
-      case kExternalFloat64ArrayCid:
-      case kDartFunctionCid:
-      case kWeakPropertyCid:
-        is_error = true;
-        break;
-      default: {
-        // Special case: classes for which we don't have a known class id.
-        // TODO(regis): Why isn't comparing to kIntegerCid enough?
-        if (Type::Handle(Type::Double()).type_class() == super_class.raw() ||
-            Type::Handle(Type::IntType()).type_class() == super_class.raw() ||
-            Type::Handle(
-                Type::StringType()).type_class() == super_class.raw()) {
-          is_error = true;
-        }
-        break;
-      }
-    }
-    if (is_error) {
-      const Script& script = Script::Handle(cls.script());
-      ReportError(script, cls.token_pos(),
-                  "'%s' is not allowed to extend '%s'",
-                  String::Handle(cls.Name()).ToCString(),
-                  String::Handle(super_class.Name()).ToCString());
-    }
-  }
-  return;
-}
-
-
 void ClassFinalizer::ResolveRedirectingFactoryTarget(
     const Class& cls,
     const Function& factory,
@@ -437,7 +354,7 @@
   const Class& target_class = Class::Handle(type.type_class());
   String& target_class_name = String::Handle(target_class.Name());
   String& target_name = String::Handle(
-      String::Concat(target_class_name, Symbols::DotHandle()));
+      String::Concat(target_class_name, Symbols::Dot()));
   const String& identifier = String::Handle(factory.RedirectionIdentifier());
   if (!identifier.IsNull()) {
     target_name = String::Concat(target_name, identifier);
@@ -1326,31 +1243,33 @@
 }
 
 
-// Walks the graph of explicitly declared interfaces of classes and
-// interfaces recursively. Resolves unresolved interfaces.
-// Returns false if there is an interface reference that cannot be
+// 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
 // resolved, or if there is a cycle in the graph. We detect cycles by
 // remembering interfaces we've visited in each path through the
 // graph. If we visit an interface a second time on a given path,
 // we found a loop.
-void ClassFinalizer::ResolveInterfaces(const Class& cls,
-                                       GrowableArray<intptr_t>* visited) {
+void ClassFinalizer::ResolveSuperTypeAndInterfaces(
+    const Class& cls, GrowableArray<intptr_t>* visited) {
   ASSERT(visited != NULL);
   const intptr_t cls_index = cls.id();
   for (int i = 0; i < visited->length(); i++) {
     if ((*visited)[i] == cls_index) {
-      // We have already visited interface class 'cls'. We found a cycle.
-      const String& interface_name = String::Handle(cls.Name());
+      // We have already visited class 'cls'. We found a cycle.
+      const String& class_name = String::Handle(cls.Name());
       const Script& script = Script::Handle(cls.script());
       ReportError(script, cls.token_pos(),
-                  "cyclic reference found for interface '%s'",
-                  interface_name.ToCString());
+                  "cyclic reference found for class '%s'",
+                  class_name.ToCString());
     }
   }
 
-  // If the class/interface has no explicit interfaces, we are done.
+  // If the class/interface has no explicit super class/interfaces, we are done.
+  Type& super_type = Type::Handle(cls.super_type());
   Array& super_interfaces = Array::Handle(cls.interfaces());
-  if (super_interfaces.Length() == 0) {
+  if ((super_type.IsNull() || super_type.IsObjectType()) &&
+      (super_interfaces.Length() == 0)) {
     return;
   }
 
@@ -1358,10 +1277,84 @@
   // about allowed interfaces are lifted.
   const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary();
 
-  // Resolve and check the interfaces of cls.
+  // Resolve and check the super type and interfaces of cls.
   visited->Add(cls_index);
   AbstractType& interface = AbstractType::Handle();
   Class& interface_class = Class::Handle();
+
+  // Resolve super type. Failures lead to a longjmp.
+  ResolveType(cls, super_type, kCanonicalizeWellFormed);
+
+  // If cls belongs to core lib or to core lib's implementation, restrictions
+  interface_class = super_type.type_class();
+  // If cls belongs to core lib or to core lib's implementation, restrictions
+  // about allowed interfaces are lifted.
+  if (!cls_belongs_to_core_lib) {
+    // Prevent extending core implementation classes.
+    bool is_error = false;
+    switch (interface_class.id()) {
+      case kNumberCid:
+      case kIntegerCid:  // Class Integer, not int.
+      case kSmiCid:
+      case kMintCid:
+      case kBigintCid:
+      case kDoubleCid:  // Class Double, not double.
+      case kOneByteStringCid:
+      case kTwoByteStringCid:
+      case kExternalOneByteStringCid:
+      case kExternalTwoByteStringCid:
+      case kBoolCid:
+      case kArrayCid:
+      case kImmutableArrayCid:
+      case kGrowableObjectArrayCid:
+      case kInt8ArrayCid:
+      case kExternalInt8ArrayCid:
+      case kUint8ArrayCid:
+      case kUint8ClampedArrayCid:
+      case kExternalUint8ArrayCid:
+      case kExternalUint8ClampedArrayCid:
+      case kInt16ArrayCid:
+      case kExternalInt16ArrayCid:
+      case kUint16ArrayCid:
+      case kExternalUint16ArrayCid:
+      case kInt32ArrayCid:
+      case kExternalInt32ArrayCid:
+      case kUint32ArrayCid:
+      case kExternalUint32ArrayCid:
+      case kInt64ArrayCid:
+      case kExternalInt64ArrayCid:
+      case kUint64ArrayCid:
+      case kExternalUint64ArrayCid:
+      case kFloat32ArrayCid:
+      case kExternalFloat32ArrayCid:
+      case kFloat64ArrayCid:
+      case kExternalFloat64ArrayCid:
+      case kDartFunctionCid:
+      case kWeakPropertyCid:
+        is_error = true;
+        break;
+      default: {
+        // Special case: classes for which we don't have a known class id.
+        if (super_type.IsDoubleType() ||
+            super_type.IsIntType() ||
+            super_type.IsStringType()) {
+          is_error = true;
+        }
+        break;
+      }
+    }
+    if (is_error) {
+      const Script& script = Script::Handle(cls.script());
+      ReportError(script, cls.token_pos(),
+                  "'%s' is not allowed to extend '%s'",
+                  String::Handle(cls.Name()).ToCString(),
+                  String::Handle(interface_class.Name()).ToCString());
+    }
+  }
+  // Now resolve the super interfaces of the super type.
+  ResolveSuperTypeAndInterfaces(interface_class, visited);
+
+  // Resolve interfaces. Failures lead to a longjmp.
   for (intptr_t i = 0; i < super_interfaces.Length(); i++) {
     interface ^= super_interfaces.At(i);
     ResolveType(cls, interface, kCanonicalizeWellFormed);
@@ -1399,7 +1392,7 @@
     }
     interface_class.set_is_implemented();
     // Now resolve the super interfaces.
-    ResolveInterfaces(interface_class, visited);
+    ResolveSuperTypeAndInterfaces(interface_class, visited);
   }
   visited->RemoveLast();
 }
@@ -1537,9 +1530,10 @@
     const char* format, ...) {
   va_list args;
   va_start(args, format);
-  const String& no_name = String::Handle(Symbols::Empty());
   const UnresolvedClass& unresolved_class = UnresolvedClass::Handle(
-      UnresolvedClass::New(LibraryPrefix::Handle(), no_name, type_pos));
+      UnresolvedClass::New(LibraryPrefix::Handle(),
+                           Symbols::Empty(),
+                           type_pos));
   const Type& type = Type::Handle(
       Type::New(unresolved_class, TypeArguments::Handle(), type_pos));
   ReportMalformedType(prev_error, cls, type, finalization, format, args);
diff --git a/runtime/vm/class_finalizer.h b/runtime/vm/class_finalizer.h
index 6804b0c..c272379 100644
--- a/runtime/vm/class_finalizer.h
+++ b/runtime/vm/class_finalizer.h
@@ -95,13 +95,12 @@
   static void CheckForLegalConstClass(const Class& cls);
   static RawClass* ResolveClass(const Class& cls,
                                 const UnresolvedClass& unresolved_class);
-  static void ResolveSuperType(const Class& cls);
   static void ResolveRedirectingFactoryTarget(
       const Class& cls,
       const Function& factory,
       const GrowableObjectArray& visited_factories);
-  static void ResolveInterfaces(const Class& cls,
-                                GrowableArray<intptr_t>* visited);
+  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,
diff --git a/runtime/vm/class_finalizer_test.cc b/runtime/vm/class_finalizer_test.cc
index 63038a5..cba2728 100644
--- a/runtime/vm/class_finalizer_test.cc
+++ b/runtime/vm/class_finalizer_test.cc
@@ -11,14 +11,13 @@
 
 
 static RawClass* CreateTestClass(const char* name) {
-  const Array& empty_array = Array::Handle(Object::empty_array());
   const String& class_name = String::Handle(Symbols::New(name));
   const Script& script = Script::Handle();
   const Class& cls =
       Class::Handle(Class::New(class_name, script, Scanner::kDummyTokenIndex));
-  cls.set_interfaces(empty_array);
-  cls.SetFunctions(empty_array);
-  cls.SetFields(empty_array);
+  cls.set_interfaces(Object::empty_array());
+  cls.SetFunctions(Object::empty_array());
+  cls.SetFields(Object::empty_array());
   return cls.raw();
 }
 
diff --git a/runtime/vm/class_table.cc b/runtime/vm/class_table.cc
index 3b34490..2d14cec 100644
--- a/runtime/vm/class_table.cc
+++ b/runtime/vm/class_table.cc
@@ -5,6 +5,7 @@
 #include "vm/class_table.h"
 #include "vm/flags.h"
 #include "vm/freelist.h"
+#include "vm/heap_trace.h"
 #include "vm/object.h"
 #include "vm/raw_object.h"
 #include "vm/visitor.h"
@@ -49,6 +50,9 @@
     ASSERT(table_[index] == 0);
     ASSERT(index < capacity_);
     table_[index] = cls.raw();
+    if (HeapTrace::is_enabled()) {
+      Isolate::Current()->heap()->trace()->TraceRegisterClass(cls);
+    }
     // Add the vtable for this predefined class into the static vtable registry
     // if it has not been setup yet.
     cpp_vtable cls_vtable = cls.handle_vtable();
@@ -72,6 +76,9 @@
     ASSERT(top_ < capacity_);
     cls.set_id(top_);
     table_[top_] = cls.raw();
+    if (HeapTrace::is_enabled()) {
+      Isolate::Current()->heap()->trace()->TraceRegisterClass(cls);
+    }
     top_++;  // Increment next index.
   }
 }
diff --git a/runtime/vm/code_descriptors.cc b/runtime/vm/code_descriptors.cc
index 9613441..7ad06c1 100644
--- a/runtime/vm/code_descriptors.cc
+++ b/runtime/vm/code_descriptors.cc
@@ -65,7 +65,7 @@
   ASSERT(Verify());
   intptr_t num_entries = Length();
   if (num_entries == 0) {
-    return Object::empty_array();
+    return Object::empty_array().raw();
   }
   uword entry_point = code.EntryPoint();
   for (intptr_t i = 0; i < num_entries; i++) {
diff --git a/runtime/vm/code_descriptors_test.cc b/runtime/vm/code_descriptors_test.cc
index f255232..261b0dd 100644
--- a/runtime/vm/code_descriptors_test.cc
+++ b/runtime/vm/code_descriptors_test.cc
@@ -277,10 +277,8 @@
   // Now invoke 'A.moo' and it will trigger a GC when the native function
   // is called, this should then cause the stack map of function 'A.foo'
   // to be traversed and the appropriate objects visited.
-  GrowableArray<const Object*> arguments;
-  const Array& kNoArgumentNames = Array::Handle();
-  Object& result = Object::Handle();
-  result = DartEntry::InvokeStatic(function_foo, arguments, kNoArgumentNames);
+  const Object& result = Object::Handle(
+      DartEntry::InvokeStatic(function_foo, Object::empty_array()));
   EXPECT(!result.IsError());
 }
 
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 78f0625..eb37c81 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -30,7 +30,6 @@
 DEFINE_FLAG(bool, deoptimize_alot, false,
     "Deoptimizes all live frames when we are about to return to Dart code from"
     " native entries.");
-DEFINE_FLAG(bool, inline_cache, true, "Enable inline caches");
 DEFINE_FLAG(bool, trace_deoptimization, false, "Trace deoptimization");
 DEFINE_FLAG(bool, trace_deoptimization_verbose, false,
     "Trace deoptimization verbose");
@@ -39,7 +38,7 @@
     "Trace IC miss in optimized code");
 DEFINE_FLAG(bool, trace_patching, false, "Trace patching of code.");
 DEFINE_FLAG(bool, trace_runtime_calls, false, "Trace runtime calls");
-DEFINE_FLAG(int, optimization_counter_threshold, 2000,
+DEFINE_FLAG(int, optimization_counter_threshold, 3000,
     "Function's usage-counter value before it is optimized, -1 means never");
 DECLARE_FLAG(bool, enable_type_checks);
 DECLARE_FLAG(bool, trace_type_checks);
@@ -160,16 +159,7 @@
   DartFrameIterator iterator;
   StackFrame* caller_frame = iterator.NextFrame();
   ASSERT(caller_frame != NULL);
-  const Code& code = Code::Handle(caller_frame->LookupDartCode());
-  const PcDescriptors& descriptors =
-      PcDescriptors::Handle(code.pc_descriptors());
-  ASSERT(!descriptors.IsNull());
-  for (int i = 0; i < descriptors.Length(); i++) {
-    if (static_cast<uword>(descriptors.PC(i)) == caller_frame->pc()) {
-      return descriptors.TokenPos(i);
-    }
-  }
-  return -1;
+  return caller_frame->GetTokenPos();
 }
 
 
@@ -234,9 +224,9 @@
       const intptr_t location = GetCallerLocation();
       String& malformed_error_message =  String::Handle(
           String::New(malformed_error.ToErrorCString()));
-      const String& no_name = String::Handle(Symbols::Empty());
       Exceptions::CreateAndThrowTypeError(
-          location, no_name, no_name, no_name, malformed_error_message);
+          location, Symbols::Empty(), Symbols::Empty(),
+          Symbols::Empty(), malformed_error_message);
       UNREACHABLE();
     }
   }
@@ -377,7 +367,7 @@
               message,
               String::Handle(instance_type.Name()).ToCString(),
               Class::Handle(instance_type.type_class()).id(),
-              (result.raw() == Bool::True()) ? "is" : "is !",
+              (result.raw() == Bool::True().raw()) ? "is" : "is !",
               String::Handle(type.Name()).ToCString(),
               Class::Handle(type.type_class()).id(),
               caller_frame->pc());
@@ -388,7 +378,7 @@
     OS::Print("%s: '%s' %s '%s' instantiated from '%s' (pc: %#"Px").\n",
               message,
               String::Handle(instance_type.Name()).ToCString(),
-              (result.raw() == Bool::True()) ? "is" : "is !",
+              (result.raw() == Bool::True().raw()) ? "is" : "is !",
               String::Handle(instantiated_type.Name()).ToCString(),
               String::Handle(type.Name()).ToCString(),
               caller_frame->pc());
@@ -574,11 +564,10 @@
       SubtypeTestCache::CheckedHandle(arguments.ArgAt(4));
   ASSERT(type.IsFinalized());
   Error& malformed_error = Error::Handle();
-  const Bool& result = Bool::Handle(
+  const Bool& result =
       instance.IsInstanceOf(type,
                             instantiator_type_arguments,
-                            &malformed_error) ?
-      Bool::True() : Bool::False());
+                            &malformed_error) ? Bool::True() : Bool::False();
   if (FLAG_trace_type_checks) {
     PrintTypeCheck("InstanceOf",
         instance, type, instantiator_type_arguments, result);
@@ -588,9 +577,9 @@
     const intptr_t location = GetCallerLocation();
     String& malformed_error_message =  String::Handle(
         String::New(malformed_error.ToErrorCString()));
-    const String& no_name = String::Handle(Symbols::Empty());
     Exceptions::CreateAndThrowTypeError(
-        location, no_name, no_name, no_name, malformed_error_message);
+        location, Symbols::Empty(), Symbols::Empty(),
+        Symbols::Empty(), malformed_error_message);
     UNREACHABLE();
   }
   UpdateTypeTestCache(instance, type, instantiator,
@@ -630,8 +619,8 @@
 
   if (FLAG_trace_type_checks) {
     PrintTypeCheck("TypeCheck",
-        src_instance, dst_type, instantiator_type_arguments,
-        Bool::Handle(is_instance_of ? Bool::True() : Bool::False()));
+                   src_instance, dst_type, instantiator_type_arguments,
+                   is_instance_of ? Bool::True() : Bool::False());
   }
   if (!is_instance_of) {
     // Throw a dynamic type error.
@@ -658,7 +647,7 @@
   }
   UpdateTypeTestCache(src_instance, dst_type,
                       dst_instantiator, instantiator_type_arguments,
-                      Bool::ZoneHandle(Bool::True()), cache);
+                      Bool::True(), cache);
   arguments.SetReturn(src_instance);
 }
 
@@ -689,7 +678,7 @@
       }
     }
   }
-  arguments.SetReturn(Bool::Handle(Bool::Get(is_defined)));
+  arguments.SetReturn(is_defined ? Bool::True() : Bool::False());
 }
 
 
@@ -707,10 +696,10 @@
   const String& src_type_name = String::Handle(src_type.UserVisibleName());
   const String& bool_type_name =
       String::Handle(bool_interface.UserVisibleName());
-  const String& expr = String::Handle(Symbols::New("boolean expression"));
   const String& no_malformed_type_error = String::Handle();
   Exceptions::CreateAndThrowTypeError(location, src_type_name, bool_type_name,
-                                      expr, no_malformed_type_error);
+                                      Symbols::BooleanExpression(),
+                                      no_malformed_type_error);
   UNREACHABLE();
 }
 
@@ -727,11 +716,11 @@
   const Instance& src_value = Instance::CheckedHandle(arguments.ArgAt(0));
   const String& dst_name = String::CheckedHandle(arguments.ArgAt(1));
   const String& malformed_error = String::CheckedHandle(arguments.ArgAt(2));
-  const String& dst_type_name = String::Handle(Symbols::New("malformed"));
   const AbstractType& src_type = AbstractType::Handle(src_value.GetType());
   const String& src_type_name = String::Handle(src_type.UserVisibleName());
   Exceptions::CreateAndThrowTypeError(location, src_type_name,
-                                      dst_type_name, dst_name, malformed_error);
+                                      Symbols::Malformed(),
+                                      dst_name, malformed_error);
   UNREACHABLE();
 }
 
@@ -893,9 +882,6 @@
   const Function& target_function =
       Function::Handle(target_code.function());
   ASSERT(!target_function.IsNull());
-  DartFrameIterator iterator;
-  StackFrame* caller_frame = iterator.NextFrame();
-  ASSERT(caller_frame != NULL);
   if (args.length() == 1) {
     ic_data.AddReceiverCheck(Class::Handle(args[0]->clazz()).id(),
                              target_function);
@@ -907,23 +893,28 @@
     }
     ic_data.AddCheck(class_ids, target_function);
   }
-  if (FLAG_trace_ic_miss_in_optimized) {
-    const Code& caller = Code::Handle(Code::LookupCode(caller_frame->pc()));
-    if (caller.is_optimized()) {
-      OS::Print("IC miss in optimized code; call %s -> %s\n",
-          Function::Handle(caller.function()).ToCString(),
+  if (FLAG_trace_ic_miss_in_optimized || FLAG_trace_ic) {
+    DartFrameIterator iterator;
+    StackFrame* caller_frame = iterator.NextFrame();
+    ASSERT(caller_frame != NULL);
+    if (FLAG_trace_ic_miss_in_optimized) {
+      const Code& caller = Code::Handle(Code::LookupCode(caller_frame->pc()));
+      if (caller.is_optimized()) {
+        OS::Print("IC miss in optimized code; call %s -> %s\n",
+            Function::Handle(caller.function()).ToCString(),
+            target_function.ToCString());
+      }
+    }
+    if (FLAG_trace_ic) {
+      OS::Print("InlineCacheMissHandler %d call at %#"Px"' "
+                "adding <%s> id:%"Pd" -> <%s>\n",
+          args.length(),
+          caller_frame->pc(),
+          Class::Handle(receiver.clazz()).ToCString(),
+          Class::Handle(receiver.clazz()).id(),
           target_function.ToCString());
     }
   }
-  if (FLAG_trace_ic) {
-    OS::Print("InlineCacheMissHandler %d call at %#"Px"' "
-              "adding <%s> id:%"Pd" -> <%s>\n",
-        args.length(),
-        caller_frame->pc(),
-        Class::Handle(receiver.clazz()).ToCString(),
-        Class::Handle(receiver.clazz()).id(),
-        target_function.ToCString());
-  }
   return target_function.raw();
 }
 
@@ -1041,9 +1032,10 @@
   Instructions& instructions = Instructions::Handle();
   if (!target.IsNull()) {
     if (!target.HasCode()) {
-      const Error& error =
-          Error::Handle(Compiler::CompileFunction(target));
-      if (!error.IsNull()) Exceptions::PropagateError(error);
+      const Error& error = Error::Handle(Compiler::CompileFunction(target));
+      if (!error.IsNull()) {
+        Exceptions::PropagateError(error);
+      }
     }
     ASSERT(target.HasCode());
     instructions = Code::Handle(target.CurrentCode()).instructions();
@@ -1090,274 +1082,25 @@
 }
 
 
-static RawFunction* LookupDynamicFunction(Isolate* isolate,
-                                          const Class& in_cls,
-                                          const String& name) {
-  Class& cls = Class::Handle();
-  // For lookups treat null as an instance of class Object.
-  if (in_cls.IsNullClass()) {
-    cls = isolate->object_store()->object_class();
-  } else {
-    cls = in_cls.raw();
-  }
-
-  Function& function = Function::Handle();
-  while (!cls.IsNull()) {
-    // Check if function exists.
-    function = cls.LookupDynamicFunction(name);
-    if (!function.IsNull()) {
-      break;
-    }
-    cls = cls.SuperClass();
-  }
-  return function.raw();
-}
-
-
-// Resolve an implicit closure by checking if an instance function
-// of the same name exists and creating a closure object of the function.
-// Arg0: receiver object.
-// Arg1: ic-data.
-// Returns: Closure object or NULL (instance function not found).
-// This is called by the megamorphic stub when it is unable to resolve an
-// instance method. This is done just before the call to noSuchMethod.
-DEFINE_RUNTIME_ENTRY(ResolveImplicitClosureFunction, 2) {
-  ASSERT(arguments.ArgCount() ==
-         kResolveImplicitClosureFunctionRuntimeEntry.argument_count());
-  const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0));
-  const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1));
-  const String& original_function_name = String::Handle(ic_data.target_name());
-  Instance& closure = Instance::Handle();
-  if (!Field::IsGetterName(original_function_name)) {
-    // This is not a getter so can't be the case where we are trying to
-    // create an implicit closure of an instance function.
-    arguments.SetReturn(closure);
-    return;
-  }
-  const Class& receiver_class = Class::Handle(receiver.clazz());
-  ASSERT(!receiver_class.IsNull());
-  String& func_name = String::Handle();
-  func_name = Field::NameFromGetter(original_function_name);
-  func_name = Symbols::New(func_name);
-  const Function& function = Function::Handle(
-      LookupDynamicFunction(isolate, receiver_class, func_name));
-  if (function.IsNull()) {
-    // There is no function of the same name so can't be the case where
-    // we are trying to create an implicit closure of an instance function.
-    arguments.SetReturn(closure);
-    return;
-  }
-  Function& implicit_closure_function =
-      Function::Handle(function.ImplicitClosureFunction());
-  // Create a closure object for the implicit closure function.
-  const Context& context = Context::Handle(Context::New(1));
-  context.SetAt(0, receiver);
-  closure = Closure::New(implicit_closure_function, context);
-  if (receiver_class.HasTypeArguments()) {
-    const AbstractTypeArguments& type_arguments =
-        AbstractTypeArguments::Handle(receiver.GetTypeArguments());
-    closure.SetTypeArguments(type_arguments);
-  }
-  arguments.SetReturn(closure);
-}
-
-
-// Resolve an implicit closure by invoking getter and checking if the return
-// value from getter is a closure.
-// Arg0: receiver object.
-// Arg1: ic-data.
-// Returns: Closure object or NULL (closure not found).
-// This is called by the megamorphic stub when it is unable to resolve an
-// instance method. This is done just before the call to noSuchMethod.
-DEFINE_RUNTIME_ENTRY(ResolveImplicitClosureThroughGetter, 2) {
-  ASSERT(arguments.ArgCount() ==
-         kResolveImplicitClosureThroughGetterRuntimeEntry.argument_count());
-  const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0));
-  const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1));
-  const String& original_function_name = String::Handle(ic_data.target_name());
-  const int kNumArguments = 1;
-  const int kNumNamedArguments = 0;
-  const String& getter_function_name =
-      String::Handle(Field::GetterName(original_function_name));
-  Function& function = Function::ZoneHandle(
-      Resolver::ResolveDynamic(receiver,
-                               getter_function_name,
-                               kNumArguments,
-                               kNumNamedArguments));
-  const Object& null_object = Object::Handle();
-  if (function.IsNull()) {
-    arguments.SetReturn(null_object);
-    return;  // No getter function found so can't be an implicit closure.
-  }
-  GrowableArray<const Object*> invoke_arguments(0);
-  const Array& kNoArgumentNames = Array::Handle();
-  const Object& result =
-      Object::Handle(DartEntry::InvokeDynamic(receiver,
-                                              function,
-                                              invoke_arguments,
-                                              kNoArgumentNames));
-  if (result.IsError()) {
-    if (result.IsUnhandledException()) {
-      // If the getter throws an exception, treat as no such method.
-      arguments.SetReturn(null_object);
-      return;
-    } else {
-      Exceptions::PropagateError(Error::Cast(result));
-    }
-  }
-  if (!result.IsSmi()) {
-    const Class& cls = Class::Handle(result.clazz());
-    ASSERT(!cls.IsNull());
-    function = cls.signature_function();
-    if (!function.IsNull()) {
-      arguments.SetReturn(result);
-      return;  // Return closure object.
-    }
-  }
-  // The result instance is not a closure, try to invoke method "call" before
-  // throwing a NoSuchMethodError.
-
-  // TODO(regis): Factorize the following code.
-
-  // TODO(regis): Args should be passed.
-  const Array& function_args = Array::Handle();
-  const String& function_name = String::Handle(Symbols::Call());
-  GrowableArray<const Object*> dart_arguments(5);
-
-  // TODO(regis): Resolve and invoke "call" method, if existing.
-
-  dart_arguments.Add(&result);
-  dart_arguments.Add(&function_name);
-  dart_arguments.Add(&function_args);
-  dart_arguments.Add(&null_object);
-
-  // Report if a function "call" with different arguments has been found.
-  {
-    Class& instance_class = Class::Handle(result.clazz());
-    Function& function =
-        Function::Handle(instance_class.LookupDynamicFunction(function_name));
-    while (function.IsNull()) {
-      instance_class = instance_class.SuperClass();
-      if (instance_class.IsNull()) break;
-      function = instance_class.LookupDynamicFunction(function_name);
-    }
-    if (!function.IsNull()) {
-      const int total_num_parameters = function.NumParameters();
-      const Array& array = Array::Handle(Array::New(total_num_parameters - 1));
-      // Skip receiver.
-      for (int i = 1; i < total_num_parameters; i++) {
-        array.SetAt(i - 1, String::Handle(function.ParameterNameAt(i)));
-      }
-      dart_arguments.Add(&array);
-    }
-  }
-  Exceptions::ThrowByType(Exceptions::kNoSuchMethod, dart_arguments);
-  UNREACHABLE();
-}
-
-
-// Invoke Implicit Closure function.
-// Arg0: closure object.
-// Arg1: arguments descriptor (originally passed as dart instance invocation).
-// Arg2: arguments array (originally passed to dart instance invocation).
-DEFINE_RUNTIME_ENTRY(InvokeImplicitClosureFunction, 3) {
-  ASSERT(arguments.ArgCount() ==
-         kInvokeImplicitClosureFunctionRuntimeEntry.argument_count());
-  const Instance& closure = Instance::CheckedHandle(arguments.ArgAt(0));
-  const Array& args_descriptor = Array::CheckedHandle(arguments.ArgAt(1));
-  const Array& func_arguments = Array::CheckedHandle(arguments.ArgAt(2));
-  const Function& function = Function::Handle(Closure::function(closure));
-  ASSERT(!function.IsNull());
-  if (!function.HasCode()) {
-    const Error& error = Error::Handle(Compiler::CompileFunction(function));
-    if (!error.IsNull()) {
-      Exceptions::PropagateError(error);
-    }
-  }
-  const Context& context = Context::Handle(Closure::context(closure));
-  const Code& code = Code::Handle(function.CurrentCode());
-  ASSERT(!code.IsNull());
-  const Instructions& instrs = Instructions::Handle(code.instructions());
-  ASSERT(!instrs.IsNull());
-
-  // The closure object is passed as implicit first argument to closure
-  // functions, since it may be needed to throw a NoSuchMethodError, in case
-  // the wrong number of arguments is passed.
-  // Replace the original receiver in the arguments array by the closure.
-  GrowableArray<const Object*> invoke_arguments(func_arguments.Length());
-  invoke_arguments.Add(&closure);
-  for (intptr_t i = 1; i < func_arguments.Length(); i++) {
-    const Object& value = Object::Handle(func_arguments.At(i));
-    invoke_arguments.Add(&value);
-  }
-
-  // Now call the invoke stub which will invoke the closure.
-  DartEntry::invokestub entrypoint = reinterpret_cast<DartEntry::invokestub>(
-      StubCode::InvokeDartCodeEntryPoint());
-  ASSERT(context.isolate() == Isolate::Current());
-  const Object& result = Object::Handle(
-      entrypoint(instrs.EntryPoint(),
-                 args_descriptor,
-                 invoke_arguments.data(),
-                 context));
-  CheckResultError(result);
-  arguments.SetReturn(result);
-}
-
-
 // Invoke appropriate noSuchMethod function.
 // Arg0: receiver.
 // Arg1: ic-data.
-// Arg2: original arguments descriptor array.
-// Arg3: original arguments array.
+// Arg2: arguments descriptor array.
+// Arg3: arguments array.
 DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodFunction, 4) {
   ASSERT(arguments.ArgCount() ==
          kInvokeNoSuchMethodFunctionRuntimeEntry.argument_count());
   const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0));
   const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1));
-  const String& original_function_name = String::Handle(ic_data.target_name());
   const Array& orig_arguments_desc = Array::CheckedHandle(arguments.ArgAt(2));
   const Array& orig_arguments = Array::CheckedHandle(arguments.ArgAt(3));
-  // Allocate an InvocationMirror object.
-  const Library& core_lib = Library::Handle(Library::CoreLibrary());
-  const String& invocation_mirror_name = String::Handle(
-      Symbols::InvocationMirror());
-  Class& invocation_mirror_class = Class::Handle(
-      core_lib.LookupClassAllowPrivate(invocation_mirror_name));
-  ASSERT(!invocation_mirror_class.IsNull());
-  const String& allocation_function_name = String::Handle(
-      Symbols::AllocateInvocationMirror());
-  const Function& allocation_function = Function::ZoneHandle(
-      Resolver::ResolveStaticByName(invocation_mirror_class,
-                                    allocation_function_name,
-                                    Resolver::kIsQualified));
-  ASSERT(!allocation_function.IsNull());
-  GrowableArray<const Object*> allocation_arguments(3);
-  allocation_arguments.Add(&original_function_name);
-  allocation_arguments.Add(&orig_arguments_desc);
-  allocation_arguments.Add(&orig_arguments);
-  const Array& kNoArgumentNames = Array::Handle();
-  const Object& invocation_mirror = Object::Handle(
-      DartEntry::InvokeStatic(allocation_function,
-                              allocation_arguments,
-                              kNoArgumentNames));
 
-  const int kNumArguments = 2;
-  const int kNumNamedArguments = 0;
-  const String& function_name = String::Handle(Symbols::NoSuchMethod());
-  const Function& function = Function::ZoneHandle(
-      Resolver::ResolveDynamic(receiver,
-                               function_name,
-                               kNumArguments,
-                               kNumNamedArguments));
-  ASSERT(!function.IsNull());
-  GrowableArray<const Object*> invoke_arguments(1);
-  invoke_arguments.Add(&invocation_mirror);
+  const String& original_function_name = String::Handle(ic_data.target_name());
   const Object& result = Object::Handle(
-      DartEntry::InvokeDynamic(receiver,
-                               function,
-                               invoke_arguments,
-                               kNoArgumentNames));
+      DartEntry::InvokeNoSuchMethod(receiver,
+                                    original_function_name,
+                                    orig_arguments,
+                                    orig_arguments_desc));
   CheckResultError(result);
   arguments.SetReturn(result);
 }
@@ -1375,60 +1118,141 @@
   const Array& args_descriptor = Array::CheckedHandle(arguments.ArgAt(1));
   const Array& function_args = Array::CheckedHandle(arguments.ArgAt(2));
 
-  // Resolve and invoke "call" method, if existing.
-  const String& function_name = String::Handle(Symbols::Call());
-  Class& instance_class = Class::Handle(instance.clazz());
-  Function& function =
-      Function::Handle(instance_class.LookupDynamicFunction(function_name));
-  while (function.IsNull()) {
-    instance_class = instance_class.SuperClass();
-    if (instance_class.IsNull()) break;
-    function = instance_class.LookupDynamicFunction(function_name);
+  const Object& result = Object::Handle(
+      DartEntry::InvokeClosure(instance,
+                               function_args,
+                               args_descriptor));
+  CheckResultError(result);
+  arguments.SetReturn(result);
+}
+
+
+// An instance call could not be resolved by an IC miss handler.  Check if
+// it was a getter call and if there is an instance function with the same
+// name.  If so, create and return an implicit closure from the function.
+// Otherwise return null.
+static RawInstance* ResolveImplicitClosure(const Instance& receiver,
+                                           const Class& receiver_class,
+                                           const String& target_name) {
+  // 1. Check if was a getter call.
+  if (!Field::IsGetterName(target_name)) return Instance::null();
+
+  // 2. Check if there is an instance function with the same name.
+  String& function_name = String::Handle(Field::NameFromGetter(target_name));
+  function_name = Symbols::New(function_name);
+  const Function& function = Function::Handle(
+      Resolver::ResolveDynamicAnyArgs(receiver_class, function_name));
+  if (function.IsNull()) return Instance::null();
+
+  // Create a closure object for the implicit closure function.
+  const Function& closure_function =
+      Function::Handle(function.ImplicitClosureFunction());
+  const Context& context = Context::Handle(Context::New(1));
+  context.SetAt(0, receiver);
+  const Instance& closure =
+      Instance::Handle(Closure::New(closure_function, context));
+  if (receiver_class.HasTypeArguments()) {
+    const AbstractTypeArguments& type_arguments =
+        AbstractTypeArguments::Handle(receiver.GetTypeArguments());
+    closure.SetTypeArguments(type_arguments);
   }
-  if (!function.IsNull()) {
-    if (!function.HasCode()) {
-      const Error& error = Error::Handle(Compiler::CompileFunction(function));
-      if (!error.IsNull()) {
-        Exceptions::PropagateError(error);
-      }
-    }
-    const Code& code = Code::Handle(function.CurrentCode());
-    ASSERT(!code.IsNull());
-    const Instructions& instrs = Instructions::Handle(code.instructions());
-    ASSERT(!instrs.IsNull());
+  return closure.raw();
+}
 
-    // The non-closure object is passed as implicit first argument (receiver).
-    // It is already included in the arguments array.
-    GrowableArray<const Object*> invoke_arguments(function_args.Length());
-    for (intptr_t i = 0; i < function_args.Length(); i++) {
-      const Object& value = Object::Handle(function_args.At(i));
-      invoke_arguments.Add(&value);
-    }
 
-    // Now call the invoke stub which will invoke the call method.
-    DartEntry::invokestub entrypoint = reinterpret_cast<DartEntry::invokestub>(
-        StubCode::InvokeDartCodeEntryPoint());
-    const Context& context = Context::ZoneHandle(
-        Isolate::Current()->object_store()->empty_context());
-    const Object& result = Object::Handle(
-        entrypoint(instrs.EntryPoint(),
-                   args_descriptor,
-                   invoke_arguments.data(),
-                   context));
-    CheckResultError(result);
-    arguments.SetReturn(result);
+// An instance call of the form o.f(...) could not be resolved.  Check if
+// there is a getter with the same name.  If so, invoke it.  If the value is
+// a closure, invoke it with the given arguments.  If the value is a
+// non-closure, attempt to invoke "call" on it.
+static bool ResolveCallThroughGetter(const Instance& receiver,
+                                     const Class& receiver_class,
+                                     const String& target_name,
+                                     const Array& arguments_descriptor,
+                                     const Array& arguments,
+                                     Object* result) {
+  // 1. Check if there is a getter with the same name.
+  const String& getter_name = String::Handle(Field::GetterName(target_name));
+  const int kNumArguments = 1;
+  const int kNumNamedArguments = 0;
+  const Function& getter = Function::Handle(
+      Resolver::ResolveDynamicForReceiverClass(receiver_class,
+                                               getter_name,
+                                               kNumArguments,
+                                               kNumNamedArguments));
+  if (getter.IsNull()) return false;
+
+  // 2. Invoke the getter.
+  const Array& args = Array::Handle(Array::New(kNumArguments));
+  args.SetAt(0, receiver);
+  const Object& value = Object::Handle(DartEntry::InvokeDynamic(getter, args));
+
+  // 3. If the getter threw an exception, treat it as no such method.
+  if (value.IsUnhandledException()) return false;
+
+  // 4. If there was some other error, propagate it.
+  CheckResultError(value);
+
+  // 5. Invoke the value as a closure.
+  Instance& instance = Instance::Handle();
+  instance ^= value.raw();
+  arguments.SetAt(0, instance);
+  *result = DartEntry::InvokeClosure(instance,
+                                     arguments,
+                                     arguments_descriptor);
+  CheckResultError(*result);
+  return true;
+}
+
+
+// The IC miss handler has failed to find a (cacheable) instance function to
+// invoke.  Handle three possibilities:
+//
+// 1. If the call was a getter o.f, there may be an instance function with
+//    the same name.  If so, create an implicit closure and return it.
+//
+// 2. If the call was an instance call o.f(...), there may be a getter with
+//    the same name.  If so, invoke it.  If the value is a closure, invoke
+//    it with the given arguments.  If the value is a non-closure, attempt
+//    to invoke "call" on it.
+//
+// 3. There is no such method.
+DEFINE_RUNTIME_ENTRY(InstanceFunctionLookup, 4) {
+  ASSERT(arguments.ArgCount() ==
+         kInstanceFunctionLookupRuntimeEntry.argument_count());
+  const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0));
+  const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1));
+  const Array& args_descriptor = Array::CheckedHandle(arguments.ArgAt(2));
+  const Array& args = Array::CheckedHandle(arguments.ArgAt(3));
+
+  Class& receiver_class = Class::Handle(receiver.clazz());
+  // For lookups treat null as an instance of class Object.
+  if (receiver_class.IsNullClass()) {
+    receiver_class = isolate->object_store()->object_class();
+  }
+  const String& target_name = String::Handle(ic_data.target_name());
+
+  Instance& closure = Instance::Handle(ResolveImplicitClosure(receiver,
+                                                              receiver_class,
+                                                              target_name));
+  if (!closure.IsNull()) {
+    arguments.SetReturn(closure);
     return;
   }
-  const Object& null_object = Object::Handle();
-  GrowableArray<const Object*> dart_arguments(5);
-  dart_arguments.Add(&instance);
-  dart_arguments.Add(&function_name);
-  dart_arguments.Add(&function_args);
-  dart_arguments.Add(&null_object);
-  // If a function "call" with different arguments exists, it will have been
-  // invoked above, so no need to handle this case here.
-  Exceptions::ThrowByType(Exceptions::kNoSuchMethod, dart_arguments);
-  UNREACHABLE();
+
+  Object& result = Object::Handle();
+  if (!ResolveCallThroughGetter(receiver,
+                                receiver_class,
+                                target_name,
+                                args_descriptor,
+                                args,
+                                &result)) {
+    result = DartEntry::InvokeNoSuchMethod(receiver,
+                                           target_name,
+                                           args,
+                                           args_descriptor);
+  }
+  CheckResultError(result);
+  arguments.SetReturn(result);
 }
 
 
@@ -1954,4 +1778,20 @@
 }
 END_LEAF_RUNTIME_ENTRY
 
+
+DEFINE_LEAF_RUNTIME_ENTRY(void,
+                          HeapTraceStore,
+                          RawObject* object,
+                          uword field_addr,
+                          RawObject* value) {
+  if (!(object->IsHeapObject() && value->IsHeapObject())) {
+    return;
+  }
+  HeapTrace* heap_trace = Isolate::Current()->heap()->trace();
+  heap_trace->TraceStoreIntoObject(RawObject::ToAddr(object),
+                                   field_addr,
+                                   RawObject::ToAddr(value));
+}
+END_LEAF_RUNTIME_ENTRY
+
 }  // namespace dart
diff --git a/runtime/vm/code_generator.h b/runtime/vm/code_generator.h
index 87011a9..7bf4e99 100644
--- a/runtime/vm/code_generator.h
+++ b/runtime/vm/code_generator.h
@@ -30,20 +30,19 @@
 DECLARE_RUNTIME_ENTRY(CloneContext);
 DECLARE_RUNTIME_ENTRY(Deoptimize);
 DECLARE_RUNTIME_ENTRY(FixCallersTarget);
+DECLARE_LEAF_RUNTIME_ENTRY(void, HeapTraceStore, RawObject*, uword, RawObject*);
 DECLARE_RUNTIME_ENTRY(InlineCacheMissHandlerOneArg);
 DECLARE_RUNTIME_ENTRY(InlineCacheMissHandlerTwoArgs);
 DECLARE_RUNTIME_ENTRY(InlineCacheMissHandlerThreeArgs);
+DECLARE_RUNTIME_ENTRY(InstanceFunctionLookup);
 DECLARE_RUNTIME_ENTRY(Instanceof);
 DECLARE_RUNTIME_ENTRY(InstantiateTypeArguments);
-DECLARE_RUNTIME_ENTRY(InvokeImplicitClosureFunction);
 DECLARE_RUNTIME_ENTRY(InvokeNoSuchMethodFunction);
 DECLARE_RUNTIME_ENTRY(MegamorphicCacheMissHandler);
 DECLARE_RUNTIME_ENTRY(OptimizeInvokedFunction);
 DECLARE_RUNTIME_ENTRY(TraceICCall);
 DECLARE_RUNTIME_ENTRY(PatchStaticCall);
 DECLARE_RUNTIME_ENTRY(InvokeNonClosure);
-DECLARE_RUNTIME_ENTRY(ResolveImplicitClosureFunction);
-DECLARE_RUNTIME_ENTRY(ResolveImplicitClosureThroughGetter);
 DECLARE_RUNTIME_ENTRY(ReThrow);
 DECLARE_RUNTIME_ENTRY(StackOverflow);
 DECLARE_RUNTIME_ENTRY(Throw);
@@ -73,6 +72,7 @@
   V(CheckSmi)                                                                  \
   V(CheckArrayBound)                                                           \
   V(AtCall)                                                                    \
+  V(DoubleToSmi)                                                               \
   V(NumReasons)                                                                \
 
 enum DeoptReasonId {
diff --git a/runtime/vm/code_generator_test.cc b/runtime/vm/code_generator_test.cc
index 4b18bdf..f2b4c62 100644
--- a/runtime/vm/code_generator_test.cc
+++ b/runtime/vm/code_generator_test.cc
@@ -160,24 +160,21 @@
 
 CODEGEN_TEST_GENERATE(BoolNotCodegen, test) {
   SequenceNode* node_seq = test->node_sequence();
-  const Bool& bool_false = Bool::ZoneHandle(Bool::False());
-  LiteralNode* b = new LiteralNode(kPos, bool_false);
+  LiteralNode* b = new LiteralNode(kPos, Bool::False());
   UnaryOpNode* not_node = new UnaryOpNode(kPos, Token::kNOT, b);
   node_seq->Add(new ReturnNode(kPos, not_node));
 }
-CODEGEN_TEST_RUN(BoolNotCodegen, Bool::True())
+CODEGEN_TEST_RUN(BoolNotCodegen, Bool::True().raw())
 
 
 CODEGEN_TEST_GENERATE(BoolAndCodegen, test) {
   SequenceNode* node_seq = test->node_sequence();
-  const Bool& bool_true = Bool::ZoneHandle(Bool::True());
-  const Bool& bool_false = Bool::ZoneHandle(Bool::False());
-  LiteralNode* a = new LiteralNode(kPos, bool_true);
-  LiteralNode* b = new LiteralNode(kPos, bool_false);
+  LiteralNode* a = new LiteralNode(kPos, Bool::True());
+  LiteralNode* b = new LiteralNode(kPos, Bool::False());
   BinaryOpNode* and_node = new BinaryOpNode(kPos, Token::kAND, a, b);
   node_seq->Add(new ReturnNode(kPos, and_node));
 }
-CODEGEN_TEST_RUN(BoolAndCodegen, Bool::False())
+CODEGEN_TEST_RUN(BoolAndCodegen, Bool::False().raw())
 
 
 CODEGEN_TEST_GENERATE(BinaryOpCodegen, test) {
@@ -547,10 +544,8 @@
 
 
 CODEGEN_TEST_RAW_RUN(AllocateNewObjectCodegen, function) {
-  GrowableArray<const Object*> arguments;
-  const Array& kNoArgumentNames = Array::Handle();
-  Object& result = Object::Handle();
-  result = DartEntry::InvokeStatic(function, arguments, kNoArgumentNames);
+  const Object& result = Object::Handle(
+      DartEntry::InvokeStatic(function, Object::empty_array()));
   EXPECT(!result.IsError());
   const GrowableObjectArray& libs =  GrowableObjectArray::Handle(
       Isolate::Current()->object_store()->libraries());
diff --git a/runtime/vm/code_observers.cc b/runtime/vm/code_observers.cc
index c537feb..ef84ceb 100644
--- a/runtime/vm/code_observers.cc
+++ b/runtime/vm/code_observers.cc
@@ -4,19 +4,10 @@
 
 #include "vm/code_observers.h"
 
-#include "vm/dart.h"
-#include "vm/debuginfo.h"
-#include "vm/flags.h"
-#include "vm/isolate.h"
 #include "vm/os.h"
-#include "vm/vtune.h"
-#include "vm/zone.h"
 
 namespace dart {
 
-DEFINE_FLAG(bool, generate_gdb_symbols, false,
-    "Generate symbols of generated dart functions for debugging with GDB");
-
 intptr_t CodeObservers::observers_length_ = 0;
 CodeObserver** CodeObservers::observers_ = NULL;
 
@@ -54,89 +45,16 @@
 }
 
 
-class PerfCodeObserver : public CodeObserver {
- public:
-  virtual bool IsActive() const {
-    return Dart::perf_events_file() != NULL;
+void CodeObservers::DeleteAll() {
+  for (intptr_t i = 0; i < observers_length_; i++) {
+    delete observers_[i];
   }
-
-  virtual void Notify(const char* name,
-                      uword base,
-                      uword prologue_offset,
-                      uword size,
-                      bool optimized) {
-    const char* format = "%"Px" %"Px" %s%s\n";
-    const char* marker = optimized ? "*" : "";
-    intptr_t len = OS::SNPrint(NULL, 0, format, base, size, marker, name);
-    char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
-    OS::SNPrint(buffer, len + 1, format, base, size, marker, name);
-    Dart_FileWriteCallback file_write = Isolate::file_write_callback();
-    ASSERT(file_write != NULL);
-    void* file = Dart::perf_events_file();
-    ASSERT(file != NULL);
-    (*file_write)(buffer, len, file);
-  }
-};
-
-
-class PprofCodeObserver : public CodeObserver {
- public:
-  virtual bool IsActive() const {
-    return Dart::pprof_symbol_generator() != NULL;
-  }
-
-  virtual void Notify(const char* name,
-                      uword base,
-                      uword prologue_offset,
-                      uword size,
-                      bool optimized) {
-    DebugInfo* pprof_symbol_generator = Dart::pprof_symbol_generator();
-    ASSERT(pprof_symbol_generator != NULL);
-    pprof_symbol_generator->AddCode(base, size);
-    pprof_symbol_generator->AddCodeRegion(name, base, size);
-  }
-};
-
-
-class GdbCodeObserver : public CodeObserver {
- public:
-  virtual bool IsActive() const {
-    return FLAG_generate_gdb_symbols;
-  }
-
-  virtual void Notify(const char* name,
-                      uword base,
-                      uword prologue_offset,
-                      uword size,
-                      bool optimized) {
-    if (prologue_offset > 0) {
-      // In order to ensure that gdb sees the first instruction of a function
-      // as the prologue sequence we register two symbols for the cases when
-      // the prologue sequence is not the first instruction:
-      // <name>_entry is used for code preceding the prologue sequence.
-      // <name> for rest of the code (first instruction is prologue sequence).
-      const char* kFormat = "%s_%s";
-      intptr_t len = OS::SNPrint(NULL, 0, kFormat, name, "entry");
-      char* pname = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
-      OS::SNPrint(pname, (len + 1), kFormat, name, "entry");
-      DebugInfo::RegisterSection(pname, base, size);
-      DebugInfo::RegisterSection(name,
-                                 (base + prologue_offset),
-                                 (size - prologue_offset));
-    } else {
-      DebugInfo::RegisterSection(name, base, size);
-    }
-  }
-};
+  delete[] observers_;
+}
 
 
 void CodeObservers::InitOnce() {
-  Register(new PerfCodeObserver);
-  Register(new PprofCodeObserver);
-  Register(new GdbCodeObserver);
-#if defined(DART_VTUNE_SUPPORT)
-  Register(new VTuneCodeObserver);
-#endif
+  OS::RegisterCodeObservers();
 }
 
 
diff --git a/runtime/vm/code_observers.h b/runtime/vm/code_observers.h
index 1891f3d..8281815 100644
--- a/runtime/vm/code_observers.h
+++ b/runtime/vm/code_observers.h
@@ -6,6 +6,7 @@
 #define VM_CODE_OBSERVERS_H_
 
 #include "vm/globals.h"
+#include "vm/allocation.h"
 
 namespace dart {
 
@@ -13,6 +14,8 @@
 // debuggers to map address ranges to function names.
 class CodeObserver {
  public:
+  CodeObserver() { }
+
   virtual ~CodeObserver() { }
 
   // Returns true if this observer is active and should be notified
@@ -26,10 +29,13 @@
                       uword prologue_offset,
                       uword size,
                       bool optimized) = 0;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(CodeObserver);
 };
 
 
-class CodeObservers {
+class CodeObservers : public AllStatic {
  public:
   static void InitOnce();
 
@@ -45,6 +51,8 @@
   // Returns true if there is at least one active code observer.
   static bool AreActive();
 
+  static void DeleteAll();
+
  private:
   static intptr_t observers_length_;
   static CodeObserver** observers_;
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 6e4fb44..b30cd0f 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -52,6 +52,7 @@
 DEFINE_FLAG(bool, verify_compiler, false,
     "Enable compiler verification assertions");
 DECLARE_FLAG(bool, print_flow_graph);
+DECLARE_FLAG(bool, print_flow_graph_optimized);
 
 
 // Compile a function. Should call only if the function has not been compiled.
@@ -160,7 +161,8 @@
       flow_graph->ComputeSSA(0, NULL);
     }
 
-    if (FLAG_print_flow_graph) {
+    if (FLAG_print_flow_graph ||
+        (optimized && FLAG_print_flow_graph_optimized)) {
       OS::Print("Before Optimizations\n");
       FlowGraphPrinter printer(*flow_graph);
       printer.PrintBlocks();
@@ -246,7 +248,7 @@
       FlowGraphAllocator allocator(*flow_graph);
       allocator.AllocateRegisters();
 
-      if (FLAG_print_flow_graph) {
+      if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) {
         OS::Print("After Optimizations:\n");
         FlowGraphPrinter printer(*flow_graph);
         printer.PrintBlocks();
@@ -623,17 +625,13 @@
     // Non-optimized code generator.
     CompileParsedFunctionHelper(*parsed_function, false);
 
-    GrowableArray<const Object*> arguments;  // no arguments.
-    const Array& kNoArgumentNames = Array::Handle();
-    Object& result = Object::Handle();
-    result = DartEntry::InvokeStatic(func,
-                                     arguments,
-                                     kNoArgumentNames);
+    const Object& result = Object::Handle(
+        DartEntry::InvokeStatic(func, Object::empty_array()));
     isolate->set_long_jump_base(base);
     return result.raw();
   } else {
-    Object& result = Object::Handle();
-    result = isolate->object_store()->sticky_error();
+    const Object& result =
+      Object::Handle(isolate->object_store()->sticky_error());
     isolate->object_store()->clear_sticky_error();
     isolate->set_long_jump_base(base);
     return result.raw();
diff --git a/runtime/vm/custom_isolate_test.cc b/runtime/vm/custom_isolate_test.cc
index d8e2444..81aa607 100644
--- a/runtime/vm/custom_isolate_test.cc
+++ b/runtime/vm/custom_isolate_test.cc
@@ -48,8 +48,8 @@
     "  String _entry;\n"
     "}\n"
     "\n"
-    "interface CustomIsolate default CustomIsolateImpl {\n"
-    "  CustomIsolate(String entry);\n"
+    "abstract class CustomIsolate {\n"
+    "  factory CustomIsolate(String entry) = CustomIsolateImpl;\n"
     "\n"
     "  Future<SendPort> spawn();\n"
     "}\n"
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index d6ca37e..af8c650 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -25,14 +25,15 @@
 
 DEFINE_FLAG(bool, heap_profile_initialize, false,
             "Writes a heap profile on isolate initialization.");
+DECLARE_FLAG(bool, heap_trace);
 DECLARE_FLAG(bool, print_bootstrap);
 DECLARE_FLAG(bool, print_class_table);
 DECLARE_FLAG(bool, trace_isolates);
 
 Isolate* Dart::vm_isolate_ = NULL;
 ThreadPool* Dart::thread_pool_ = NULL;
-void* Dart::perf_events_file_ = NULL;
 DebugInfo* Dart::pprof_symbol_generator_ = NULL;
+ReadOnlyHandles* Dart::predefined_handles_ = NULL;
 
 // An object visitor which will mark all visited objects. This is used to
 // premark all objects in the vm_isolate_ heap.
@@ -49,6 +50,29 @@
 };
 
 
+// Structure for managing read-only global handles allocation used for
+// creating global read-only handles that are pre created and initialized
+// for use across all isolates. Having these global pre created handles
+// stored in the vm isolate ensures that we don't constantly create and
+// destroy handles for read-only objects referred in the VM code
+// (e.g: symbols, null object, empty array etc.)
+// The ReadOnlyHandles C++ Wrapper around VMHandles which is a ValueObject is
+// to ensure that the handles area is not trashed by automatic running of C++
+// static destructors when 'exit()" is called by any isolate. There might be
+// other isolates running at the same time and trashing the handles area will
+// have unintended consequences.
+class ReadOnlyHandles {
+ public:
+  ReadOnlyHandles() { }
+
+ private:
+  VMHandles handles_;
+
+  friend class Dart;
+  DISALLOW_COPY_AND_ASSIGN(ReadOnlyHandles);
+};
+
+
 // TODO(turnidge): We should add a corresponding Dart::Cleanup.
 const char* Dart::InitOnce(Dart_IsolateCreateCallback create,
                            Dart_IsolateInterruptCallback interrupt,
@@ -69,6 +93,9 @@
   FreeListElement::InitOnce();
   Api::InitOnce();
   CodeObservers::InitOnce();
+  // Create the read-only handles area.
+  ASSERT(predefined_handles_ == NULL);
+  predefined_handles_ = new ReadOnlyHandles();
   // Create the VM isolate and finish the VM initialization.
   ASSERT(thread_pool_ == NULL);
   thread_pool_ = new ThreadPool();
@@ -100,6 +127,9 @@
   Isolate::SetInterruptCallback(interrupt);
   Isolate::SetUnhandledExceptionCallback(unhandled);
   Isolate::SetShutdownCallback(shutdown);
+  if (FLAG_heap_trace) {
+    HeapTrace::InitOnce(file_open, file_write, file_close);
+  }
   return NULL;
 }
 
@@ -182,6 +212,9 @@
 
   StubCode::Init(isolate);
   isolate->megamorphic_cache_table()->InitMissHandler();
+  if (FLAG_heap_trace) {
+    isolate->heap()->trace()->Init(isolate);
+  }
   isolate->heap()->EnableGrowthControl();
   isolate->set_init_callback_data(data);
   if (FLAG_print_class_table) {
@@ -204,4 +237,15 @@
 }
 
 
+uword Dart::AllocateReadOnlyHandle() {
+  ASSERT(predefined_handles_ != NULL);
+  return predefined_handles_->handles_.AllocateScopedHandle();
+}
+
+
+bool Dart::IsReadOnlyHandle(uword address) {
+  ASSERT(predefined_handles_ != NULL);
+  return predefined_handles_->handles_.IsValidScopedHandle(address);
+}
+
 }  // namespace dart
diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h
index 80a0857..090c4a1 100644
--- a/runtime/vm/dart.h
+++ b/runtime/vm/dart.h
@@ -14,6 +14,7 @@
 class DebugInfo;
 class Isolate;
 class RawError;
+class ReadOnlyHandles;
 class ThreadPool;
 
 class Dart : public AllStatic {
@@ -34,23 +35,19 @@
   static Isolate* vm_isolate() { return vm_isolate_; }
   static ThreadPool* thread_pool() { return thread_pool_; }
 
-  static void set_perf_events_file(void* file) {
-    perf_events_file_ = file;
-  }
-  static void* perf_events_file() {
-    return perf_events_file_;
-  }
-
   static void set_pprof_symbol_generator(DebugInfo* value) {
     pprof_symbol_generator_ = value;
   }
   static DebugInfo* pprof_symbol_generator() { return pprof_symbol_generator_; }
 
+  static uword AllocateReadOnlyHandle();
+  static bool IsReadOnlyHandle(uword address);
+
  private:
   static Isolate* vm_isolate_;
   static ThreadPool* thread_pool_;
-  static void* perf_events_file_;
   static DebugInfo* pprof_symbol_generator_;
+  static ReadOnlyHandles* predefined_handles_;
 };
 
 }  // namespace dart
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 80938c0..52b8a04 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1102,26 +1102,20 @@
   DARTSCOPE(isolate);
   Library& isolate_lib = Library::Handle(isolate, Library::IsolateLibrary());
   ASSERT(!isolate_lib.IsNull());
-  const String& public_class_name =
-      String::Handle(isolate, String::New("_ReceivePortImpl"));
-  const String& class_name =
-      String::Handle(isolate, isolate_lib.PrivateName(public_class_name));
-  const String& function_name =
-      String::Handle(isolate, Symbols::New("_get_or_create"));
+  const String& class_name = String::Handle(
+      isolate, isolate_lib.PrivateName(Symbols::_ReceivePortImpl()));
   const int kNumArguments = 1;
-  const Array& kNoArgumentNames = Array::Handle(isolate);
   const Function& function = Function::Handle(
       isolate,
       Resolver::ResolveStatic(isolate_lib,
                               class_name,
-                              function_name,
+                              Symbols::_get_or_create(),
                               kNumArguments,
-                              kNoArgumentNames,
+                              Object::empty_array(),
                               Resolver::kIsQualified));
-  GrowableArray<const Object*> arguments(kNumArguments);
-  arguments.Add(&Integer::Handle(isolate, Integer::New(port_id)));
-  return Api::NewHandle(
-      isolate, DartEntry::InvokeStatic(function, arguments, kNoArgumentNames));
+  const Array& args = Array::Handle(isolate, Array::New(kNumArguments));
+  args.SetAt(0, Integer::Handle(isolate, Integer::New(port_id)));
+  return Api::NewHandle(isolate, DartEntry::InvokeStatic(function, args));
 }
 
 
@@ -1702,6 +1696,34 @@
 }
 
 
+DART_EXPORT Dart_Handle Dart_StringToLatin1(Dart_Handle str,
+                                            uint8_t* latin1_array,
+                                            intptr_t* length) {
+  Isolate* isolate = Isolate::Current();
+  DARTSCOPE(isolate);
+  if (latin1_array == NULL) {
+    RETURN_NULL_ERROR(latin1_array);
+  }
+  if (length == NULL) {
+    RETURN_NULL_ERROR(length);
+  }
+  const String& str_obj = Api::UnwrapStringHandle(isolate, str);
+  if (str_obj.IsNull() || !str_obj.IsOneByteString()) {
+    RETURN_TYPE_ERROR(isolate, str, String);
+  }
+  intptr_t str_len = str_obj.Length();
+  intptr_t copy_len = (str_len > *length) ? *length : str_len;
+
+  // We have already asserted that the string object is a Latin-1 string
+  // so we can copy the characters over using a simple loop.
+  for (intptr_t i = 0; i < copy_len; i++) {
+    latin1_array[i] = str_obj.CharAt(i);
+  }
+  *length = copy_len;
+  return Api::Success(isolate);
+}
+
+
 DART_EXPORT Dart_Handle Dart_StringToUTF16(Dart_Handle str,
                                            uint16_t* utf16_array,
                                            intptr_t* length) {
@@ -1754,10 +1776,6 @@
   if (array == NULL) {
     RETURN_NULL_ERROR(array);
   }
-  if (str_obj.IsCanonical()) {
-    return Api::NewError("Dart_MakeExternalString "
-                         "cannot externalize a read-only string.");
-  }
   intptr_t str_size = (str_obj.Length() * str_obj.CharSize());
   if ((length < str_size) || (length > String::kMaxElements)) {
     return Api::NewError("Dart_MakeExternalString "
@@ -1765,6 +1783,29 @@
                          "[%"Pd"..%"Pd"].",
                          str_size, String::kMaxElements);
   }
+  if (str_obj.IsCanonical()) {
+    // Since the string object is read only we do not externalize
+    // the string but instead copy the contents of the string into the
+    // specified buffer and return a Null object.
+    // This ensures that the embedder does not have to call again
+    // to get at the contents.
+    intptr_t copy_len = str_obj.Length();
+    if (str_obj.IsOneByteString()) {
+      ASSERT(length >= copy_len);
+      uint8_t* latin1_array = reinterpret_cast<uint8_t*>(array);
+      for (intptr_t i = 0; i < copy_len; i++) {
+        latin1_array[i] = static_cast<uint8_t>(str_obj.CharAt(i));
+      }
+    } else {
+      ASSERT(str_obj.IsTwoByteString());
+      ASSERT(length >= (copy_len * str_obj.CharSize()));
+      uint16_t* utf16_array = reinterpret_cast<uint16_t*>(array);
+      for (intptr_t i = 0; i < copy_len; i++) {
+        utf16_array[i] = static_cast<uint16_t>(str_obj.CharAt(i));
+      }
+    }
+    return Api::Null(isolate);
+  }
   return Api::NewHandle(isolate,
                         str_obj.MakeExternal(array, length, peer, cback));
 }
@@ -1842,19 +1883,18 @@
   if (instance.IsNull()) {
     return Api::NewError("Object does not implement the List interface");
   }
-  String& name = String::Handle(isolate, Symbols::Length());
-  name = Field::GetterName(name);
+  const String& name = String::Handle(Field::GetterName(Symbols::Length()));
   const Function& function =
       Function::Handle(isolate, Resolver::ResolveDynamic(instance, name, 1, 0));
   if (function.IsNull()) {
     return Api::NewError("List object does not have a 'length' field.");
   }
 
-  GrowableArray<const Object*> args(0);
-  const Array& kNoArgumentNames = Array::Handle(isolate);
-  const Object& retval = Object::Handle(
-      isolate,
-      DartEntry::InvokeDynamic(instance, function, args, kNoArgumentNames));
+  const int kNumArgs = 1;
+  const Array& args = Array::Handle(isolate, Array::New(kNumArgs));
+  args.SetAt(0, instance);  // Set up the receiver as the first argument.
+  const Object& retval =
+    Object::Handle(isolate, DartEntry::InvokeDynamic(function, args));
   if (retval.IsSmi()) {
     *len = Smi::Cast(retval).Value();
     return Api::Success(isolate);
@@ -1910,18 +1950,15 @@
     if (!instance.IsNull()) {
       const Function& function = Function::Handle(
           isolate,
-          Resolver::ResolveDynamic(instance,
-                                   Symbols::IndexTokenHandle(),
-                                   2,
-                                   0));
+          Resolver::ResolveDynamic(instance, Symbols::IndexToken(), 2, 0));
       if (!function.IsNull()) {
-        GrowableArray<const Object*> args(1);
-        Integer& indexobj = Integer::Handle(isolate);
-        indexobj = Integer::New(index);
-        args.Add(&indexobj);
-        const Array& kNoArgumentNames = Array::Handle(isolate);
-        return Api::NewHandle(isolate, DartEntry::InvokeDynamic(
-            instance, function, args, kNoArgumentNames));
+        const int kNumArgs = 2;
+        const Array& args = Array::Handle(isolate, Array::New(kNumArgs));
+        const Integer& indexobj = Integer::Handle(isolate, Integer::New(index));
+        args.SetAt(0, instance);
+        args.SetAt(1, indexobj);
+        return Api::NewHandle(isolate, DartEntry::InvokeDynamic(function,
+                                                                args));
       }
     }
     return Api::NewError("Object does not implement the 'List' interface");
@@ -1965,7 +2002,7 @@
       const Function& function = Function::Handle(
           isolate,
           Resolver::ResolveDynamic(instance,
-                                   Symbols::AssignIndexTokenHandle(),
+                                   Symbols::AssignIndexToken(),
                                    3,
                                    0));
       if (!function.IsNull()) {
@@ -1976,12 +2013,13 @@
         if (!value_obj.IsNull() && !value_obj.IsInstance()) {
           RETURN_TYPE_ERROR(isolate, value, Instance);
         }
-        GrowableArray<const Object*> args(2);
-        args.Add(&index_obj);
-        args.Add(&value_obj);
-        const Array& kNoArgumentNames = Array::Handle(isolate);
-        return Api::NewHandle(isolate, DartEntry::InvokeDynamic(
-            instance, function, args, kNoArgumentNames));
+        const intptr_t kNumArgs = 3;
+        const Array& args = Array::Handle(isolate, Array::New(kNumArgs));
+        args.SetAt(0, instance);
+        args.SetAt(1, index_obj);
+        args.SetAt(2, value_obj);
+        return Api::NewHandle(isolate, DartEntry::InvokeDynamic(function,
+                                                                args));
       }
     }
     return Api::NewError("Object does not implement the 'List' interface");
@@ -2049,20 +2087,17 @@
     if (!instance.IsNull()) {
       const Function& function = Function::Handle(
           isolate,
-          Resolver::ResolveDynamic(instance,
-                                   Symbols::IndexTokenHandle(),
-                                   2,
-                                   0));
+          Resolver::ResolveDynamic(instance, Symbols::IndexToken(), 2, 0));
       if (!function.IsNull()) {
         Object& result = Object::Handle(isolate);
         Integer& intobj = Integer::Handle(isolate);
+        const int kNumArgs = 2;
+        const Array& args = Array::Handle(isolate, Array::New(kNumArgs));
+        args.SetAt(0, instance);  // Set up the receiver as the first argument.
         for (int i = 0; i < length; i++) {
           intobj = Integer::New(offset + i);
-          GrowableArray<const Object*> args(1);
-          args.Add(&intobj);
-          const Array& kNoArgumentNames = Array::Handle(isolate);
-          result = DartEntry::InvokeDynamic(
-              instance, function, args, kNoArgumentNames);
+          args.SetAt(1, intobj);
+          result = DartEntry::InvokeDynamic(function, args);
           if (result.IsError()) {
             return Api::NewHandle(isolate, result.raw());
           }
@@ -2141,23 +2176,22 @@
       const Function& function = Function::Handle(
           isolate,
           Resolver::ResolveDynamic(instance,
-                                   Symbols::AssignIndexTokenHandle(),
+                                   Symbols::AssignIndexToken(),
                                    3,
                                    0));
       if (!function.IsNull()) {
         Integer& indexobj = Integer::Handle(isolate);
         Integer& valueobj = Integer::Handle(isolate);
+        const int kNumArgs = 3;
+        const Array& args = Array::Handle(isolate, Array::New(kNumArgs));
+        args.SetAt(0, instance);  // Set up the receiver as the first argument.
         for (int i = 0; i < length; i++) {
           indexobj = Integer::New(offset + i);
           valueobj = Integer::New(native_array[i]);
-          GrowableArray<const Object*> args(2);
-          args.Add(&indexobj);
-          args.Add(&valueobj);
-          const Array& kNoArgumentNames = Array::Handle(isolate);
+          args.SetAt(1, indexobj);
+          args.SetAt(2, valueobj);
           const Object& result = Object::Handle(
-              isolate,
-              DartEntry::InvokeDynamic(
-                  instance, function, args, kNoArgumentNames));
+              isolate, DartEntry::InvokeDynamic(function, args));
           if (result.IsError()) {
             return Api::NewHandle(isolate, result.raw());
           }
@@ -2450,7 +2484,7 @@
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
   const Instance& closure_obj = Api::UnwrapInstanceHandle(isolate, closure);
-  if (closure_obj.IsNull() || !closure_obj.IsClosure()) {
+  if (closure_obj.IsNull() || !closure_obj.IsCallable(NULL, NULL)) {
     RETURN_TYPE_ERROR(isolate, closure, Instance);
   }
   if (number_of_arguments < 0) {
@@ -2460,20 +2494,20 @@
   }
   ASSERT(ClassFinalizer::AllClassesFinalized());
 
-  // Now try to invoke the closure.
-  GrowableArray<const Object*> dart_arguments(number_of_arguments);
+  // Set up arguments to include the closure as the first argument.
+  const Array& args = Array::Handle(isolate,
+                                    Array::New(number_of_arguments + 1));
+  Object& obj = Object::Handle(isolate);
+  args.SetAt(0, closure_obj);
   for (int i = 0; i < number_of_arguments; i++) {
-    const Object& arg =
-        Object::Handle(isolate, Api::UnwrapHandle(arguments[i]));
-    if (!arg.IsNull() && !arg.IsInstance()) {
+    obj = Api::UnwrapHandle(arguments[i]);
+    if (!obj.IsNull() && !obj.IsInstance()) {
       RETURN_TYPE_ERROR(isolate, arguments[i], Instance);
     }
-    dart_arguments.Add(&arg);
+    args.SetAt(i + 1, obj);
   }
-  const Array& kNoArgumentNames = Array::Handle(isolate);
-  return Api::NewHandle(
-      isolate,
-      DartEntry::InvokeClosure(closure_obj, dart_arguments, kNoArgumentNames));
+  // Now try to invoke the closure.
+  return Api::NewHandle(isolate, DartEntry::InvokeClosure(closure_obj, args));
 }
 
 
@@ -2753,7 +2787,7 @@
     // Case 4.  Lookup the function with a . appended to find the
     // unnamed constructor.
     if (func.IsNull()) {
-      tmp_name = String::Concat(func_name, Symbols::DotHandle());
+      tmp_name = String::Concat(func_name, Symbols::Dot());
       func = cls.LookupFunction(tmp_name);
     }
   } else if (obj.IsLibrary()) {
@@ -3318,9 +3352,9 @@
   const Object& name_obj =
       Object::Handle(isolate, Api::UnwrapHandle(constructor_name));
   if (name_obj.IsNull()) {
-    dot_name = Symbols::Dot();
+    dot_name = Symbols::Dot().raw();
   } else if (name_obj.IsString()) {
-    dot_name = String::Concat(Symbols::DotHandle(), String::Cast(name_obj));
+    dot_name = String::Concat(Symbols::Dot(), String::Cast(name_obj));
   } else {
     RETURN_TYPE_ERROR(isolate, constructor_name, String);
   }
@@ -3347,34 +3381,36 @@
   }
 
   // Create the argument list.
+  intptr_t arg_index = 0;
   int extra_args = (constructor.IsConstructor() ? 2 : 1);
-  GrowableArray<const Object*> args(number_of_arguments + extra_args);
+  const Array& args =
+      Array::Handle(isolate, Array::New(number_of_arguments + extra_args));
   if (constructor.IsConstructor()) {
     // Constructors get the uninitialized object and a constructor phase.
-    args.Add(&new_object);
-    args.Add(&Smi::Handle(isolate, Smi::New(Function::kCtorPhaseAll)));
+    args.SetAt(arg_index++, new_object);
+    args.SetAt(arg_index++,
+               Smi::Handle(isolate, Smi::New(Function::kCtorPhaseAll)));
   } else {
     // Factories get type arguments.
-    args.Add(&TypeArguments::Handle(isolate));
+    args.SetAt(arg_index++, TypeArguments::Handle(isolate));
   }
+  Object& argument = Object::Handle(isolate);
   for (int i = 0; i < number_of_arguments; i++) {
-    const Object& arg =
-        Object::Handle(isolate, Api::UnwrapHandle(arguments[i]));
-    if (!arg.IsNull() && !arg.IsInstance()) {
-      if (arg.IsError()) {
-        return Api::NewHandle(isolate, arg.raw());
+    argument = Api::UnwrapHandle(arguments[i]);
+    if (!argument.IsNull() && !argument.IsInstance()) {
+      if (argument.IsError()) {
+        return Api::NewHandle(isolate, argument.raw());
       } else {
         return Api::NewError(
             "%s expects arguments[%d] to be an Instance handle.",
             CURRENT_FUNC, i);
       }
     }
-    args.Add(&arg);
+    args.SetAt(arg_index++, argument);
   }
 
   // Invoke the constructor and return the new object.
-  const Array& kNoArgNames = Array::Handle(isolate);
-  result = DartEntry::InvokeStatic(constructor, args, kNoArgNames);
+  result = DartEntry::InvokeStatic(constructor, args);
   if (result.IsError()) {
     return Api::NewHandle(isolate, result.raw());
   }
@@ -3404,12 +3440,18 @@
         "%s expects argument 'number_of_arguments' to be non-negative.",
         CURRENT_FUNC);
   }
+  const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target));
+  if (obj.IsError()) {
+    return target;
+  }
 
   // Check for malformed arguments in the arguments list.
-  GrowableArray<const Object*> args(number_of_arguments);
+  intptr_t num_receiver = (obj.IsNull() || obj.IsInstance()) ? 1 : 0;
+  const Array& args =
+      Array::Handle(isolate, Array::New(number_of_arguments + num_receiver));
+  Object& arg = Object::Handle(isolate);
   for (int i = 0; i < number_of_arguments; i++) {
-    const Object& arg =
-        Object::Handle(isolate, Api::UnwrapHandle(arguments[i]));
+    arg = Api::UnwrapHandle(arguments[i]);
     if (!arg.IsNull() && !arg.IsInstance()) {
       if (arg.IsError()) {
         return Api::NewHandle(isolate, arg.raw());
@@ -3419,13 +3461,7 @@
             CURRENT_FUNC, i);
       }
     }
-    args.Add(&arg);
-  }
-
-  const Array& kNoArgNames = Array::Handle(isolate);
-  const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target));
-  if (obj.IsError()) {
-    return target;
+    args.SetAt((i + num_receiver), arg);
   }
 
   if (obj.IsNull() || obj.IsInstance()) {
@@ -3446,9 +3482,8 @@
                            cls_name.ToCString(),
                            function_name.ToCString());
     }
-    return Api::NewHandle(
-        isolate,
-        DartEntry::InvokeDynamic(instance, function, args, kNoArgNames));
+    args.SetAt(0, instance);
+    return Api::NewHandle(isolate, DartEntry::InvokeDynamic(function, args));
 
   } else if (obj.IsClass()) {
     // Finalize all classes.
@@ -3463,7 +3498,7 @@
         Resolver::ResolveStatic(cls,
                                 function_name,
                                 number_of_arguments,
-                                Array::Handle(isolate),
+                                Object::empty_array(),
                                 Resolver::kIsQualified));
     if (function.IsNull()) {
       const String& cls_name = String::Handle(isolate, cls.Name());
@@ -3472,9 +3507,7 @@
                            cls_name.ToCString(),
                            function_name.ToCString());
     }
-    return Api::NewHandle(
-        isolate,
-        DartEntry::InvokeStatic(function, args, kNoArgNames));
+    return Api::NewHandle(isolate, DartEntry::InvokeStatic(function, args));
 
   } else if (obj.IsLibrary()) {
     // Check whether class finalization is needed.
@@ -3515,8 +3548,7 @@
                            function_name.ToCString(),
                            error_message.ToCString());
     }
-    return Api::NewHandle(
-        isolate, DartEntry::InvokeStatic(function, args, kNoArgNames));
+    return Api::NewHandle(isolate, DartEntry::InvokeStatic(function, args));
 
   } else {
     return Api::NewError(
@@ -3533,8 +3565,8 @@
   // field object, since the value in the field object will not be
   // initialized until the first time the getter is invoked.
   const Instance& value = Instance::Handle(isolate, fld.value());
-  ASSERT(value.raw() != Object::transition_sentinel());
-  return value.raw() == Object::sentinel();
+  ASSERT(value.raw() != Object::transition_sentinel().raw());
+  return value.raw() == Object::sentinel().raw();
 }
 
 
@@ -3576,11 +3608,10 @@
     }
 
     // Invoke the getter and return the result.
-    GrowableArray<const Object*> args;
-    const Array& kNoArgNames = Array::Handle(isolate);
-    return Api::NewHandle(
-        isolate,
-        DartEntry::InvokeDynamic(instance, getter, args, kNoArgNames));
+    const int kNumArgs = 1;
+    const Array& args = Array::Handle(isolate, Array::New(kNumArgs));
+    args.SetAt(0, instance);
+    return Api::NewHandle(isolate, DartEntry::InvokeDynamic(getter, args));
 
   } else if (obj.IsClass()) {
     // Finalize all classes.
@@ -3600,10 +3631,8 @@
 
     if (!getter.IsNull()) {
       // Invoke the getter and return the result.
-      GrowableArray<const Object*> args;
-      const Array& kNoArgNames = Array::Handle(isolate);
       return Api::NewHandle(
-          isolate, DartEntry::InvokeStatic(getter, args, kNoArgNames));
+          isolate, DartEntry::InvokeStatic(getter, Object::empty_array()));
     } else if (!field.IsNull()) {
       return Api::NewHandle(isolate, field.value());
     } else {
@@ -3634,10 +3663,8 @@
 
     if (!getter.IsNull()) {
       // Invoke the getter and return the result.
-      GrowableArray<const Object*> args;
-      const Array& kNoArgNames = Array::Handle(isolate);
       return Api::NewHandle(
-          isolate, DartEntry::InvokeStatic(getter, args, kNoArgNames));
+          isolate, DartEntry::InvokeStatic(getter, Object::empty_array()));
     } else if (!field.IsNull()) {
       return Api::NewHandle(isolate, field.value());
     } else {
@@ -3707,12 +3734,11 @@
     }
 
     // Invoke the setter and return the result.
-    GrowableArray<const Object*> args(1);
-    args.Add(&value_instance);
-    const Array& kNoArgNames = Array::Handle(isolate);
-    return Api::NewHandle(
-        isolate,
-        DartEntry::InvokeDynamic(instance, setter, args, kNoArgNames));
+    const int kNumArgs = 2;
+    const Array& args = Array::Handle(isolate, Array::New(kNumArgs));
+    args.SetAt(0, instance);
+    args.SetAt(1, value_instance);
+    return Api::NewHandle(isolate, DartEntry::InvokeDynamic(setter, args));
 
   } else if (obj.IsClass()) {
     // To access a static field we may need to use the Field or the
@@ -3727,12 +3753,11 @@
 
     if (!setter.IsNull()) {
       // Invoke the setter and return the result.
-      GrowableArray<const Object*> args(1);
-      args.Add(&value_instance);
-      const Array& kNoArgNames = Array::Handle(isolate);
-      const Object& result = Object::Handle(
-          isolate,
-          DartEntry::InvokeStatic(setter, args, kNoArgNames));
+      const int kNumArgs = 1;
+      const Array& args = Array::Handle(isolate, Array::New(kNumArgs));
+      args.SetAt(0, value_instance);
+      const Object& result =
+          Object::Handle(isolate, DartEntry::InvokeStatic(setter, args));
       if (result.IsError()) {
         return Api::NewHandle(isolate, result.raw());
       } else {
@@ -3765,11 +3790,11 @@
 
     if (!setter.IsNull()) {
       // Invoke the setter and return the result.
-      GrowableArray<const Object*> args(1);
-      args.Add(&value_instance);
-      const Array& kNoArgNames = Array::Handle(isolate);
-      const Object& result = Object::Handle(
-          isolate, DartEntry::InvokeStatic(setter, args, kNoArgNames));
+      const int kNumArgs = 1;
+      const Array& args = Array::Handle(isolate, Array::New(kNumArgs));
+      args.SetAt(0, value_instance);
+      const Object& result =
+          Object::Handle(isolate, DartEntry::InvokeStatic(setter, args));
       if (result.IsError()) {
         return Api::NewHandle(isolate, result.raw());
       } else {
@@ -4303,7 +4328,7 @@
   const Object& prefix_object =
       Object::Handle(isolate, Api::UnwrapHandle(prefix));
   const String& prefix_vm = prefix_object.IsNull()
-      ? String::Handle(isolate, Symbols::New(""))
+      ? Symbols::Empty()
       : String::Cast(prefix_object);
   if (prefix_vm.IsNull()) {
     RETURN_TYPE_ERROR(isolate, prefix, String);
@@ -4392,41 +4417,16 @@
 }
 
 
-// --- Profiling support ----
+// --- Profiling support ---
 
+// TODO(7565): Dartium should use the new VM flag "generate_pprof_symbols" for
+// pprof profiling. Then these symbols should be removed.
 
-DART_EXPORT void Dart_InitPprofSupport() {
-  DebugInfo* pprof_symbol_generator = DebugInfo::NewGenerator();
-  ASSERT(pprof_symbol_generator != NULL);
-  Dart::set_pprof_symbol_generator(pprof_symbol_generator);
-}
-
+DART_EXPORT void Dart_InitPprofSupport() { }
 
 DART_EXPORT void Dart_GetPprofSymbolInfo(void** buffer, int* buffer_size) {
-  Isolate* isolate = Isolate::Current();
-  DebugInfo* pprof_symbol_generator = Dart::pprof_symbol_generator();
-  if (pprof_symbol_generator != NULL) {
-    DebugInfo::ByteBuffer* debug_region = new DebugInfo::ByteBuffer();
-    ASSERT(debug_region != NULL);
-    pprof_symbol_generator->WriteToMemory(debug_region);
-    *buffer_size = debug_region->size();
-    if (*buffer_size != 0) {
-      Zone* zone = Api::TopScope(isolate)->zone();
-      *buffer = reinterpret_cast<void*>(zone->AllocUnsafe(*buffer_size));
-      memmove(*buffer, debug_region->data(), *buffer_size);
-    } else {
-      *buffer = NULL;
-    }
-    delete debug_region;
-  } else {
-    *buffer = NULL;
-    *buffer_size = 0;
-  }
-}
-
-
-DART_EXPORT void Dart_InitPerfEventsSupport(void* perf_events_file) {
-  Dart::set_perf_events_file(perf_events_file);
+  *buffer = NULL;
+  *buffer_size = 0;
 }
 
 
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 3a27a14..e189325 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -532,6 +532,16 @@
   EXPECT(Dart_IsStringLatin1(str8));
   EXPECT(!Dart_IsExternalString(str8));
 
+  uint8_t latin1_array[] = {0, 0, 0, 0, 0};
+  len = 5;
+  Dart_Handle result = Dart_StringToLatin1(str8, latin1_array, &len);
+  EXPECT_VALID(result);
+  EXPECT_EQ(4, len);
+  EXPECT(latin1_array != NULL);
+  for (intptr_t i = 0; i < len; i++) {
+    EXPECT_EQ(data8[i], latin1_array[i]);
+  }
+
   Dart_Handle ext8 = Dart_NewExternalLatin1String(data8, ARRAY_SIZE(data8),
                                                   NULL, NULL);
   EXPECT_VALID(ext8);
@@ -1295,8 +1305,7 @@
  public:
   static void CollectNewSpace(Heap::ApiCallbacks api_callbacks) {
     bool invoke_api_callbacks = (api_callbacks == Heap::kInvokeApiCallbacks);
-    Isolate::Current()->heap()->new_space_->Scavenge(invoke_api_callbacks,
-                                                     "test case");
+    Isolate::Current()->heap()->new_space_->Scavenge(invoke_api_callbacks);
   }
 };
 
@@ -5771,7 +5780,7 @@
   EXPECT_VALID(result);
 
   result = Dart_Invoke(test_script, NewString("e1"), 0, NULL);
-  EXPECT_ERROR(result, "No such method: 'unpatched'");
+  EXPECT_ERROR(result, "method not found: 'unpatched'");
 
   int64_t value = 0;
   result = Dart_Invoke(test_script, NewString("m1"), 0, NULL);
@@ -7315,6 +7324,34 @@
 }
 
 
+TEST_CASE(ExternalizeConstantStrings) {
+  const char* kScriptChars =
+      "String testMain() {\n"
+      "  return 'constant string';\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
+  Dart_Handle result = Dart_Invoke(lib,
+                                      NewString("testMain"),
+                                      0,
+                                      NULL);
+  const char* expected_str = "constant string";
+  const intptr_t kExpectedLen = 15;
+  int peer = 40;
+  uint8_t ext_str[kExpectedLen];
+  Dart_Handle str = Dart_MakeExternalString(result,
+                                            ext_str,
+                                            kExpectedLen,
+                                            &peer,
+                                            MakeExternalCback);
+
+  EXPECT(Dart_IsNull(str));
+  for (intptr_t i = 0; i < kExpectedLen; i++) {
+    EXPECT_EQ(expected_str[i], ext_str[i]);
+  }
+}
+
+
 TEST_CASE(LazyLoadDeoptimizes) {
   const char* kLoadFirst =
       "start(a) {\n"
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc
index 78486db..b306b96 100644
--- a/runtime/vm/dart_api_message.cc
+++ b/runtime/vm/dart_api_message.cc
@@ -215,34 +215,32 @@
 
 
 Dart_CObject* ApiMessageReader::ReadVMSymbol(intptr_t object_id) {
-  if (Symbols::IsVMSymbolId(object_id)) {
-    intptr_t symbol_id = object_id - kMaxPredefinedObjectIds;
-    Dart_CObject* object;
-    if (vm_symbol_references_ != NULL &&
-        (object = vm_symbol_references_[symbol_id]) != NULL) {
-      return object;
-    }
-
-    if (vm_symbol_references_ == NULL) {
-      intptr_t size = sizeof(*vm_symbol_references_) * Symbols::kMaxId;
-      vm_symbol_references_ =
-          reinterpret_cast<Dart_CObject**>(alloc_(NULL, 0, size));
-      memset(vm_symbol_references_, 0, size);
-    }
-
-    RawOneByteString* str =
-        reinterpret_cast<RawOneByteString*>(Symbols::GetVMSymbol(object_id));
-    intptr_t len = Smi::Value(str->ptr()->length_);
-    object = AllocateDartCObjectString(len);
-    char* p = object->value.as_string;
-    memmove(p, str->ptr()->data_, len);
-    p[len] = '\0';
-    ASSERT(vm_symbol_references_[symbol_id] == NULL);
-    vm_symbol_references_[symbol_id] = object;
+  ASSERT(Symbols::IsVMSymbolId(object_id));
+  intptr_t symbol_id = object_id - kMaxPredefinedObjectIds;
+  Dart_CObject* object;
+  if (vm_symbol_references_ != NULL &&
+      (object = vm_symbol_references_[symbol_id]) != NULL) {
     return object;
   }
-  // No other VM isolate objects are supported.
-  return AllocateDartCObjectNull();
+
+  if (vm_symbol_references_ == NULL) {
+    intptr_t size =
+        (sizeof(*vm_symbol_references_) * Symbols::kMaxPredefinedId);
+    vm_symbol_references_ =
+        reinterpret_cast<Dart_CObject**>(alloc_(NULL, 0, size));
+    memset(vm_symbol_references_, 0, size);
+  }
+
+  RawOneByteString* str =
+      reinterpret_cast<RawOneByteString*>(Symbols::GetVMSymbol(object_id));
+  intptr_t len = Smi::Value(str->ptr()->length_);
+  object = AllocateDartCObjectString(len);
+  char* p = object->value.as_string;
+  memmove(p, str->ptr()->data_, len);
+  p[len] = '\0';
+  ASSERT(vm_symbol_references_[symbol_id] == NULL);
+  vm_symbol_references_[symbol_id] = object;
+  return object;
 }
 
 
@@ -258,11 +256,7 @@
   }
   ASSERT((value <= kIntptrMax) && (value >= kIntptrMin));
   if (IsVMIsolateObject(value)) {
-    intptr_t object_id = GetVMIsolateObjectId(value);
-    if (object_id == kNullObject) {
-      return AllocateDartCObjectNull();
-    }
-    return ReadVMSymbol(object_id);
+    return ReadVMIsolateObject(value);
   }
   if (SerializedHeaderTag::decode(value) == kObjectId) {
     return ReadIndexedObject(SerializedHeaderData::decode(value));
@@ -293,6 +287,25 @@
 }
 
 
+Dart_CObject* ApiMessageReader::ReadVMIsolateObject(intptr_t value) {
+  intptr_t object_id = GetVMIsolateObjectId(value);
+  if (object_id == kNullObject) {
+    return AllocateDartCObjectNull();
+  }
+  if (object_id == kTrueValue) {
+    return AllocateDartCObjectBool(true);
+  }
+  if (object_id == kFalseValue) {
+    return AllocateDartCObjectBool(false);
+  }
+  if (Symbols::IsVMSymbolId(object_id)) {
+    return ReadVMSymbol(object_id);
+  }
+  // No other VM isolate objects are supported.
+  return AllocateDartCObjectNull();
+}
+
+
 Dart_CObject* ApiMessageReader::ReadInternalVMObject(intptr_t class_id,
                                                      intptr_t object_id) {
   switch (class_id) {
@@ -459,12 +472,6 @@
 
 
 Dart_CObject* ApiMessageReader::ReadIndexedObject(intptr_t object_id) {
-  if (object_id == kTrueValue) {
-    return AllocateDartCObjectBool(true);
-  }
-  if (object_id == kFalseValue) {
-    return AllocateDartCObjectBool(false);
-  }
   if (object_id == kDynamicType ||
       object_id == kDoubleType ||
       object_id == kIntType ||
@@ -504,11 +511,7 @@
   }
   ASSERT((value <= kIntptrMax) && (value >= kIntptrMin));
   if (IsVMIsolateObject(value)) {
-    intptr_t object_id = GetVMIsolateObjectId(value);
-    if (object_id == kNullObject) {
-      return AllocateDartCObjectNull();
-    }
-    return ReadVMSymbol(object_id);
+    return ReadVMIsolateObject(value);
   }
   if (SerializedHeaderTag::decode(value) == kObjectId) {
     return ReadIndexedObject(SerializedHeaderData::decode(value));
@@ -760,9 +763,9 @@
       break;
     case Dart_CObject::kBool:
       if (object->value.as_bool) {
-        WriteIndexedObject(kTrueValue);
+        WriteVMIsolateObject(kTrueValue);
       } else {
-        WriteIndexedObject(kFalseValue);
+        WriteVMIsolateObject(kFalseValue);
       }
       break;
     case Dart_CObject::kInt32:
diff --git a/runtime/vm/dart_api_message.h b/runtime/vm/dart_api_message.h
index dbd7278..7103fa1 100644
--- a/runtime/vm/dart_api_message.h
+++ b/runtime/vm/dart_api_message.h
@@ -85,6 +85,7 @@
   void Init();
 
   intptr_t LookupInternalClass(intptr_t class_header);
+  Dart_CObject* ReadVMIsolateObject(intptr_t value);
   Dart_CObject* ReadInternalVMObject(intptr_t class_id, intptr_t object_id);
   Dart_CObject* ReadInlinedObject(intptr_t object_id);
   Dart_CObject* ReadObjectImpl();
diff --git a/runtime/vm/dart_api_state.h b/runtime/vm/dart_api_state.h
index 55b5ad0..0d615fe 100644
--- a/runtime/vm/dart_api_state.h
+++ b/runtime/vm/dart_api_state.h
@@ -610,9 +610,8 @@
     if (true_ == NULL) {
       DARTSCOPE(Isolate::Current());
 
-      const Object& true_object = Object::Handle(Bool::True());
       true_ = persistent_handles().AllocateHandle();
-      true_->set_raw(true_object);
+      true_->set_raw(Bool::True());
     }
     return true_;
   }
@@ -620,9 +619,8 @@
     if (false_ == NULL) {
       DARTSCOPE(Isolate::Current());
 
-      const Object& false_object = Object::Handle(Bool::False());
       false_ = persistent_handles().AllocateHandle();
-      false_->set_raw(false_object);
+      false_->set_raw(Bool::False());
     }
     return false_;
   }
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 493af6c..c1eb53b 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -13,58 +13,27 @@
 
 namespace dart {
 
-RawObject* DartEntry::InvokeDynamic(
-    const Instance& receiver,
-    const Function& function,
-    const GrowableArray<const Object*>& arguments,
-    const Array& optional_arguments_names) {
-  // Get the entrypoint corresponding to the function specified, this
-  // will result in a compilation of the function if it is not already
-  // compiled.
-  if (!function.HasCode()) {
-    const Error& error = Error::Handle(Compiler::CompileFunction(function));
-    if (!error.IsNull()) {
-      return error.raw();
-    }
-  }
-
-  // Set up arguments to include the receiver as the first argument.
-  const int num_arguments = arguments.length() + 1;
-  GrowableArray<const Object*> args(num_arguments);
-  const Object& arg0 = Object::ZoneHandle(receiver.raw());
-  args.Add(&arg0);
-  for (int i = 1; i < num_arguments; i++) {
-    args.Add(arguments[i - 1]);
-  }
-  // Now Call the invoke stub which will invoke the dart function.
-  invokestub entrypoint = reinterpret_cast<invokestub>(
-      StubCode::InvokeDartCodeEntryPoint());
-  const Context& context =
-      Context::ZoneHandle(Isolate::Current()->object_store()->empty_context());
-  ASSERT(context.isolate() == Isolate::Current());
-  const Code& code = Code::Handle(function.CurrentCode());
-  ASSERT(!code.IsNull());
-  const Array& arg_descriptor =
-      Array::Handle(ArgumentsDescriptor::New(num_arguments,
-                                             optional_arguments_names));
-  return entrypoint(code.EntryPoint(), arg_descriptor, args.data(), context);
+RawObject* DartEntry::InvokeDynamic(const Function& function,
+                                    const Array& arguments) {
+  const Array& arg_desc =
+      Array::Handle(ArgumentsDescriptor::New(arguments.Length()));
+  return InvokeDynamic(function, arguments, arg_desc);
 }
 
 
-RawObject* DartEntry::InvokeStatic(
-    const Function& function,
-    const GrowableArray<const Object*>& arguments,
-    const Array& optional_arguments_names) {
+RawObject* DartEntry::InvokeDynamic(const Function& function,
+                                    const Array& arguments,
+                                    const Array& arguments_descriptor) {
   // Get the entrypoint corresponding to the function specified, this
   // will result in a compilation of the function if it is not already
   // compiled.
-  ASSERT(!function.IsNull());
   if (!function.HasCode()) {
     const Error& error = Error::Handle(Compiler::CompileFunction(function));
     if (!error.IsNull()) {
       return error.raw();
     }
   }
+
   // Now Call the invoke stub which will invoke the dart function.
   invokestub entrypoint = reinterpret_cast<invokestub>(
       StubCode::InvokeDartCodeEntryPoint());
@@ -73,24 +42,27 @@
   ASSERT(context.isolate() == Isolate::Current());
   const Code& code = Code::Handle(function.CurrentCode());
   ASSERT(!code.IsNull());
-  const Array& arg_descriptor =
-      Array::Handle(ArgumentsDescriptor::New(arguments.length(),
-                                             optional_arguments_names));
-  return entrypoint(code.EntryPoint(), arg_descriptor, arguments.data(),
+  return entrypoint(code.EntryPoint(),
+                    arguments_descriptor,
+                    arguments,
                     context);
 }
 
 
-RawObject* DartEntry::InvokeClosure(
-    const Instance& closure,
-    const GrowableArray<const Object*>& arguments,
-    const Array& optional_arguments_names) {
-  // Get the entrypoint corresponding to the closure specified, this
-  // will result in a compilation of the closure if it is not already
+RawObject* DartEntry::InvokeStatic(const Function& function,
+                                   const Array& arguments) {
+  const Array& arguments_descriptor =
+      Array::Handle(ArgumentsDescriptor::New(arguments.Length()));
+  return InvokeStatic(function, arguments, arguments_descriptor);
+}
+
+
+RawObject* DartEntry::InvokeStatic(const Function& function,
+                                   const Array& arguments,
+                                   const Array& arguments_descriptor) {
+  // Get the entrypoint corresponding to the function specified, this
+  // will result in a compilation of the function if it is not already
   // compiled.
-  ASSERT(Class::Handle(closure.clazz()).signature_function() != Object::null());
-  const Function& function = Function::Handle(Closure::function(closure));
-  const Context& context = Context::Handle(Closure::context(closure));
   ASSERT(!function.IsNull());
   if (!function.HasCode()) {
     const Error& error = Error::Handle(Compiler::CompileFunction(function));
@@ -98,24 +70,109 @@
       return error.raw();
     }
   }
-  // Set up arguments to include the closure as the first argument.
-  const int num_arguments = arguments.length() + 1;
-  GrowableArray<const Object*> args(num_arguments);
-  const Object& arg0 = Object::ZoneHandle(closure.raw());
-  args.Add(&arg0);
-  for (int i = 1; i < num_arguments; i++) {
-    args.Add(arguments[i - 1]);
-  }
-  // Now call the invoke stub which will invoke the closure.
+  // Now Call the invoke stub which will invoke the dart function.
   invokestub entrypoint = reinterpret_cast<invokestub>(
       StubCode::InvokeDartCodeEntryPoint());
+  const Context& context =
+      Context::ZoneHandle(Isolate::Current()->object_store()->empty_context());
   ASSERT(context.isolate() == Isolate::Current());
   const Code& code = Code::Handle(function.CurrentCode());
   ASSERT(!code.IsNull());
-  const Array& arg_descriptor =
-      Array::Handle(ArgumentsDescriptor::New(num_arguments,
-                                             optional_arguments_names));
-  return entrypoint(code.EntryPoint(), arg_descriptor, args.data(), context);
+  return entrypoint(code.EntryPoint(),
+                    arguments_descriptor,
+                    arguments,
+                    context);
+}
+
+
+RawObject* DartEntry::InvokeClosure(const Instance& closure,
+                                    const Array& arguments) {
+  const Array& arguments_descriptor =
+      Array::Handle(ArgumentsDescriptor::New(arguments.Length()));
+  return InvokeClosure(closure, arguments, arguments_descriptor);
+}
+
+
+RawObject* DartEntry::InvokeClosure(const Instance& instance,
+                                    const Array& arguments,
+                                    const Array& arguments_descriptor) {
+  ASSERT(instance.raw() == arguments.At(0));
+  // Get the entrypoint corresponding to the closure function or to the call
+  // method of the instance. This will result in a compilation of the function
+  // if it is not already compiled.
+  Function& function = Function::Handle();
+  Context& context = Context::Handle();
+  if (instance.IsCallable(&function, &context)) {
+    // Only invoke the function if its arguments are compatible.
+    const ArgumentsDescriptor args_desc(arguments_descriptor);
+    if (function.AreValidArgumentCounts(args_desc.Count(),
+                                        args_desc.NamedCount(),
+                                        NULL)) {
+      if (!function.HasCode()) {
+        const Error& error = Error::Handle(Compiler::CompileFunction(function));
+        if (!error.IsNull()) {
+          return error.raw();
+        }
+      }
+      // Now call the invoke stub which will invoke the closure function or
+      // 'call' function.
+      // The closure or non-closure object (receiver) is passed as implicit
+      // first argument. It is already included in the arguments array.
+      invokestub entrypoint = reinterpret_cast<invokestub>(
+          StubCode::InvokeDartCodeEntryPoint());
+      ASSERT(context.isolate() == Isolate::Current());
+      const Code& code = Code::Handle(function.CurrentCode());
+      ASSERT(!code.IsNull());
+      return entrypoint(code.EntryPoint(),
+                        arguments_descriptor,
+                        arguments,
+                        context);
+    }
+  }
+  // There is no compatible 'call' method, so invoke noSuchMethod.
+  return InvokeNoSuchMethod(instance,
+                            Symbols::Call(),
+                            arguments,
+                            arguments_descriptor);
+}
+
+
+RawObject* DartEntry::InvokeNoSuchMethod(const Instance& receiver,
+                                         const String& target_name,
+                                         const Array& arguments,
+                                         const Array& arguments_descriptor) {
+  ASSERT(receiver.raw() == arguments.At(0));
+  // Allocate an InvocationMirror object.
+  const Library& core_lib = Library::Handle(Library::CoreLibrary());
+  Class& invocation_mirror_class = Class::Handle(
+      core_lib.LookupClassAllowPrivate(Symbols::InvocationMirror()));
+  ASSERT(!invocation_mirror_class.IsNull());
+  const Function& allocation_function = Function::Handle(
+      Resolver::ResolveStaticByName(invocation_mirror_class,
+                                    Symbols::AllocateInvocationMirror(),
+                                    Resolver::kIsQualified));
+  ASSERT(!allocation_function.IsNull());
+  const int kNumAllocationArgs = 3;
+  const Array& allocation_args = Array::Handle(Array::New(kNumAllocationArgs));
+  allocation_args.SetAt(0, target_name);
+  allocation_args.SetAt(1, arguments_descriptor);
+  allocation_args.SetAt(2, arguments);
+  const Object& invocation_mirror = Object::Handle(
+      InvokeStatic(allocation_function, allocation_args));
+
+  // Now use the invocation mirror object and invoke NoSuchMethod.
+  const int kNumArguments = 2;
+  const int kNumNamedArguments = 0;
+  const Function& function = Function::Handle(
+      Resolver::ResolveDynamic(receiver,
+                               Symbols::NoSuchMethod(),
+                               kNumArguments,
+                               kNumNamedArguments));
+  ASSERT(!function.IsNull());
+  const Array& args = Array::Handle(Array::New(kNumArguments));
+  args.SetAt(0, receiver);
+  args.SetAt(1, invocation_mirror);
+  return InvokeDynamic(function, args);
 }
 
 
@@ -210,28 +267,56 @@
 }
 
 
-RawObject* DartLibraryCalls::ExceptionCreate(
-    const Library& lib,
-    const String& class_name,
-    const GrowableArray<const Object*>& arguments) {
+RawArray* ArgumentsDescriptor::New(intptr_t num_arguments) {
+  // Build the arguments descriptor array, which consists of the total
+  // argument count; the positional argument count; and
+  // a terminating null to simplify iterating in generated code.
+  const intptr_t descriptor_len = LengthFor(0);
+  Array& descriptor = Array::Handle(Array::New(descriptor_len, Heap::kOld));
+  const Smi& arg_count = Smi::Handle(Smi::New(num_arguments));
+
+  // Set total number of passed arguments.
+  descriptor.SetAt(kCountIndex, arg_count);
+
+  // Set number of positional arguments.
+  descriptor.SetAt(kPositionalCountIndex, arg_count);
+
+  // Set terminating null.
+  descriptor.SetAt((descriptor_len - 1), Object::Handle());
+
+  // Share the immutable descriptor when possible by canonicalizing it.
+  descriptor.MakeImmutable();
+  descriptor ^= descriptor.Canonicalize();
+  return descriptor.raw();
+}
+
+
+RawObject* DartLibraryCalls::ExceptionCreate(const Library& lib,
+                                             const String& class_name,
+                                             const Array& arguments) {
   const Class& cls = Class::Handle(lib.LookupClassAllowPrivate(class_name));
   ASSERT(!cls.IsNull());
   // For now, we only support a non-parameterized or raw type.
+  const int kNumExtraArgs = 2;  // implicit rcvr and construction phase args.
   const Instance& exception_object = Instance::Handle(Instance::New(cls));
-  GrowableArray<const Object*> constructor_arguments(arguments.length() + 2);
-  constructor_arguments.Add(&exception_object);
-  constructor_arguments.Add(&Smi::Handle(Smi::New(Function::kCtorPhaseAll)));
-  constructor_arguments.AddArray(arguments);
+  const Array& constructor_arguments =
+    Array::Handle(Array::New(arguments.Length() + kNumExtraArgs));
+  constructor_arguments.SetAt(0, exception_object);
+  constructor_arguments.SetAt(
+      1, Smi::Handle(Smi::New(Function::kCtorPhaseAll)));
+  Object& obj = Object::Handle();
+  for (intptr_t i = 0; i < arguments.Length(); i++) {
+    obj = arguments.At(i);
+    constructor_arguments.SetAt((i + kNumExtraArgs), obj);
+  }
 
   String& constructor_name = String::Handle(
-      String::Concat(class_name, Symbols::DotHandle()));
+      String::Concat(class_name, Symbols::Dot()));
   Function& constructor =
       Function::Handle(cls.LookupConstructor(constructor_name));
   ASSERT(!constructor.IsNull());
-  const Array& kNoArgumentNames = Array::Handle();
-  const Object& retval = Object::Handle(
-      DartEntry::InvokeStatic(constructor, constructor_arguments,
-                              kNoArgumentNames));
+  const Object& retval =
+    Object::Handle(DartEntry::InvokeStatic(constructor, constructor_arguments));
   ASSERT(retval.IsNull() || retval.IsError());
   if (retval.IsError()) {
     return retval.raw();
@@ -241,23 +326,18 @@
 
 
 RawObject* DartLibraryCalls::ToString(const Instance& receiver) {
-  const String& function_name =
-      String::Handle(Symbols::New("toString"));
-  GrowableArray<const Object*> arguments;
   const int kNumArguments = 1;  // Receiver.
   const int kNumNamedArguments = 0;  // None.
-  const Array& kNoArgumentNames = Array::Handle();
   const Function& function = Function::Handle(
       Resolver::ResolveDynamic(receiver,
-                               function_name,
+                               Symbols::toString(),
                                kNumArguments,
                                kNumNamedArguments));
   ASSERT(!function.IsNull());
-  const Object& result = Object::Handle(
-      DartEntry::InvokeDynamic(receiver,
-                               function,
-                               arguments,
-                               kNoArgumentNames));
+  const Array& args = Array::Handle(Array::New(kNumArguments));
+  args.SetAt(0, receiver);
+  const Object& result = Object::Handle(DartEntry::InvokeDynamic(function,
+                                                                 args));
   ASSERT(result.IsInstance() || result.IsError());
   return result.raw();
 }
@@ -265,50 +345,79 @@
 
 RawObject* DartLibraryCalls::Equals(const Instance& left,
                                     const Instance& right) {
-  GrowableArray<const Object*> arguments;
-  arguments.Add(&right);
   const int kNumArguments = 2;
   const int kNumNamedArguments = 0;
-  const Array& kNoArgumentNames = Array::Handle();
   const Function& function = Function::Handle(
       Resolver::ResolveDynamic(left,
-                               Symbols::EqualOperatorHandle(),
+                               Symbols::EqualOperator(),
                                kNumArguments,
                                kNumNamedArguments));
   ASSERT(!function.IsNull());
-  const Object& result = Object::Handle(
-      DartEntry::InvokeDynamic(left, function, arguments, kNoArgumentNames));
+
+  const Array& args = Array::Handle(Array::New(kNumArguments));
+  args.SetAt(0, left);
+  args.SetAt(1, right);
+  const Object& result = Object::Handle(DartEntry::InvokeDynamic(function,
+                                                                 args));
   ASSERT(result.IsInstance() || result.IsError());
   return result.raw();
 }
 
 
-RawObject* DartLibraryCalls::HandleMessage(Dart_Port dest_port_id,
+RawObject* DartLibraryCalls::LookupReceivePort(Dart_Port port_id) {
+  Isolate* isolate = Isolate::Current();
+  Function& function =
+      Function::Handle(isolate,
+                       isolate->object_store()->lookup_receive_port_function());
+  const int kNumArguments = 1;
+  if (function.IsNull()) {
+    Library& isolate_lib = Library::Handle(Library::IsolateLibrary());
+    ASSERT(!isolate_lib.IsNull());
+    const String& class_name =
+        String::Handle(isolate_lib.PrivateName(Symbols::_ReceivePortImpl()));
+    function = Resolver::ResolveStatic(isolate_lib,
+                                       class_name,
+                                       Symbols::_lookupReceivePort(),
+                                       kNumArguments,
+                                       Object::empty_array(),
+                                       Resolver::kIsQualified);
+    isolate->object_store()->set_lookup_receive_port_function(function);
+  }
+  const Array& args = Array::Handle(Array::New(kNumArguments));
+  args.SetAt(0, Integer::Handle(Integer::New(port_id)));
+  const Object& result =
+      Object::Handle(DartEntry::InvokeStatic(function, args));
+  return result.raw();
+}
+
+
+RawObject* DartLibraryCalls::HandleMessage(const Object& receive_port,
                                            Dart_Port reply_port_id,
                                            const Instance& message) {
-  Library& isolate_lib = Library::Handle(Library::IsolateLibrary());
-  ASSERT(!isolate_lib.IsNull());
-  const String& public_class_name =
-      String::Handle(Symbols::New("_ReceivePortImpl"));
-  const String& class_name =
-      String::Handle(isolate_lib.PrivateName(public_class_name));
-  const String& function_name =
-      String::Handle(Symbols::New("_handleMessage"));
+  Isolate* isolate = Isolate::Current();
+  Function& function =
+      Function::Handle(isolate,
+                       isolate->object_store()->handle_message_function());
   const int kNumArguments = 3;
-  const Array& kNoArgumentNames = Array::Handle();
-  const Function& function = Function::Handle(
-      Resolver::ResolveStatic(isolate_lib,
-                              class_name,
-                              function_name,
-                              kNumArguments,
-                              kNoArgumentNames,
-                              Resolver::kIsQualified));
-  GrowableArray<const Object*> arguments(kNumArguments);
-  arguments.Add(&Integer::Handle(Integer::New(dest_port_id)));
-  arguments.Add(&Integer::Handle(Integer::New(reply_port_id)));
-  arguments.Add(&message);
-  const Object& result = Object::Handle(
-      DartEntry::InvokeStatic(function, arguments, kNoArgumentNames));
+  if (function.IsNull()) {
+    Library& isolate_lib = Library::Handle(Library::IsolateLibrary());
+    ASSERT(!isolate_lib.IsNull());
+    const String& class_name =
+        String::Handle(isolate_lib.PrivateName(Symbols::_ReceivePortImpl()));
+    function = Resolver::ResolveStatic(isolate_lib,
+                                       class_name,
+                                       Symbols::_handleMessage(),
+                                       kNumArguments,
+                                       Object::empty_array(),
+                                       Resolver::kIsQualified);
+    isolate->object_store()->set_handle_message_function(function);
+  }
+  const Array& args = Array::Handle(isolate, Array::New(kNumArguments));
+  args.SetAt(0, receive_port);
+  args.SetAt(1, Integer::Handle(isolate, Integer::New(reply_port_id)));
+  args.SetAt(2, message);
+  const Object& result =
+      Object::Handle(isolate, DartEntry::InvokeStatic(function, args));
   ASSERT(result.IsNull() || result.IsError());
   return result.raw();
 }
@@ -317,52 +426,50 @@
 RawObject* DartLibraryCalls::NewSendPort(intptr_t port_id) {
   Library& isolate_lib = Library::Handle(Library::IsolateLibrary());
   ASSERT(!isolate_lib.IsNull());
-  const String& public_class_name =
-      String::Handle(String::New("_SendPortImpl"));
   const String& class_name =
-      String::Handle(isolate_lib.PrivateName(public_class_name));
-  const String& function_name = String::Handle(Symbols::New("_create"));
+      String::Handle(isolate_lib.PrivateName(Symbols::_SendPortImpl()));
   const int kNumArguments = 1;
-  const Array& kNoArgumentNames = Array::Handle();
   const Function& function = Function::Handle(
       Resolver::ResolveStatic(isolate_lib,
                               class_name,
-                              function_name,
+                              Symbols::_create(),
                               kNumArguments,
-                              kNoArgumentNames,
+                              Object::empty_array(),
                               Resolver::kIsQualified));
-  GrowableArray<const Object*> arguments(kNumArguments);
-  arguments.Add(&Integer::Handle(Integer::New(port_id)));
-  return DartEntry::InvokeStatic(function, arguments, kNoArgumentNames);
+  const Array& args = Array::Handle(Array::New(kNumArguments));
+  args.SetAt(0, Integer::Handle(Integer::New(port_id)));
+  return DartEntry::InvokeStatic(function, args);
 }
 
 
 RawObject* DartLibraryCalls::MapSetAt(const Instance& map,
                                       const Instance& key,
                                       const Instance& value) {
-  String& name = String::Handle(Symbols::AssignIndexToken());
+  const int kNumArguments = 3;
   const Function& function = Function::Handle(
-      Resolver::ResolveDynamic(map, name, 3, 0));
+      Resolver::ResolveDynamic(map,
+                               Symbols::AssignIndexToken(),
+                               kNumArguments,
+                               0));
   ASSERT(!function.IsNull());
-  GrowableArray<const Object*> args(2);
-  args.Add(&key);
-  args.Add(&value);
-  const Array& kNoArgumentNames = Array::Handle();
-  const Object& result = Object::Handle(
-      DartEntry::InvokeDynamic(map, function, args, kNoArgumentNames));
+  const Array& args = Array::Handle(Array::New(kNumArguments));
+  args.SetAt(0, map);
+  args.SetAt(1, key);
+  args.SetAt(2, value);
+  const Object& result = Object::Handle(DartEntry::InvokeDynamic(function,
+                                                                 args));
   return result.raw();
 }
 
 
 RawObject* DartLibraryCalls::PortGetId(const Instance& port) {
-  const String& field_name = String::Handle(Symbols::New("_id"));
   const Class& cls = Class::Handle(port.clazz());
-  const String& func_name = String::Handle(Field::GetterName(field_name));
+  const String& func_name = String::Handle(Field::GetterName(Symbols::_id()));
   const Function& func = Function::Handle(cls.LookupDynamicFunction(func_name));
   ASSERT(!func.IsNull());
-  GrowableArray<const Object*> arguments;
-  const Array& kNoArgumentNames = Array::Handle();
-  return DartEntry::InvokeDynamic(port, func, arguments, kNoArgumentNames);
+  const Array& args = Array::Handle(Array::New(1));
+  args.SetAt(0, port);
+  return DartEntry::InvokeDynamic(func, args);
 }
 
 
diff --git a/runtime/vm/dart_entry.h b/runtime/vm/dart_entry.h
index d0d2d6c..dcf3a34 100644
--- a/runtime/vm/dart_entry.h
+++ b/runtime/vm/dart_entry.h
@@ -53,6 +53,10 @@
   static RawArray* New(intptr_t count,
                        const Array& optional_arguments_names);
 
+  // Allocate and return an arguments descriptor that has no optional
+  // arguments. All arguments are positional.
+  static RawArray* New(intptr_t count);
+
  private:
   // Absolute indexes into the array.
   enum {
@@ -86,30 +90,51 @@
   // On success, returns a RawInstance.  On failure, a RawError.
   typedef RawObject* (*invokestub)(uword entry_point,
                                    const Array& arguments_descriptor,
-                                   const Object** arguments,
+                                   const Array& arguments,
                                    const Context& context);
 
   // Invokes the specified instance function on the receiver.
   // On success, returns a RawInstance.  On failure, a RawError.
-  static RawObject* InvokeDynamic(
-      const Instance& receiver,
-      const Function& function,
-      const GrowableArray<const Object*>& arguments,
-      const Array& optional_arguments_names);
+  // This is used when there are no named arguments in the call.
+  static RawObject* InvokeDynamic(const Function& function,
+                                  const Array& arguments);
+
+  // Invokes the specified instance function on the receiver.
+  // On success, returns a RawInstance.  On failure, a RawError.
+  static RawObject* InvokeDynamic(const Function& function,
+                                  const Array& arguments,
+                                  const Array& arguments_descriptor);
 
   // Invoke the specified static function.
   // On success, returns a RawInstance.  On failure, a RawError.
-  static RawObject* InvokeStatic(
-      const Function& function,
-      const GrowableArray<const Object*>& arguments,
-      const Array& optional_arguments_names);
+  // This is used when there are no named arguments in the call.
+  static RawObject* InvokeStatic(const Function& function,
+                                 const Array& arguments);
+
+  // Invoke the specified static function.
+  // On success, returns a RawInstance.  On failure, a RawError.
+  static RawObject* InvokeStatic(const Function& function,
+                                 const Array& arguments,
+                                 const Array& arguments_descriptor);
 
   // Invoke the specified closure object.
   // On success, returns a RawInstance.  On failure, a RawError.
-  static RawObject* InvokeClosure(
-      const Instance& closure,
-      const GrowableArray<const Object*>& arguments,
-      const Array& optional_arguments_names);
+  // This is used when there are no named arguments in the call.
+  static RawObject* InvokeClosure(const Instance& closure,
+                                  const Array& arguments);
+
+  // Invoke the specified closure object.
+  // On success, returns a RawInstance.  On failure, a RawError.
+  static RawObject* InvokeClosure(const Instance& closure,
+                                  const Array& arguments,
+                                  const Array& arguments_descriptor);
+
+  // Invoke the noSuchMethod instance function on the receiver.
+  // On success, returns a RawInstance.  On failure, a RawError.
+  static RawObject* InvokeNoSuchMethod(const Instance& receiver,
+                                       const String& target_name,
+                                       const Array& arguments,
+                                       const Array& arguments_descriptor);
 };
 
 
@@ -118,10 +143,9 @@
 class DartLibraryCalls : public AllStatic {
  public:
   // On success, returns a RawInstance.  On failure, a RawError.
-  static RawObject* ExceptionCreate(
-      const Library& library,
-      const String& exception_name,
-      const GrowableArray<const Object*>& arguments);
+  static RawObject* ExceptionCreate(const Library& library,
+                                    const String& exception_name,
+                                    const Array& arguments);
 
   // On success, returns a RawInstance.  On failure, a RawError.
   static RawObject* ToString(const Instance& receiver);
@@ -129,8 +153,12 @@
   // On success, returns a RawInstance.  On failure, a RawError.
   static RawObject* Equals(const Instance& left, const Instance& right);
 
+  // Returns the receive port if it is in the port map and null otherwise.
+  // On failure, a RawError.
+  static RawObject* LookupReceivePort(Dart_Port port_id);
+
   // Returns null on success, a RawError on failure.
-  static RawObject* HandleMessage(Dart_Port dest_port_id,
+  static RawObject* HandleMessage(const Object& receive_port,
                                   Dart_Port reply_port_id,
                                   const Instance& dart_message);
 
diff --git a/runtime/vm/dart_entry_test.cc b/runtime/vm/dart_entry_test.cc
index 1e3322d..65a629f 100644
--- a/runtime/vm/dart_entry_test.cc
+++ b/runtime/vm/dart_entry_test.cc
@@ -39,12 +39,8 @@
 
   EXPECT(CompilerTest::TestCompileFunction(function));
   EXPECT(function.HasCode());
-  GrowableArray<const Object*> arguments;
-  const Array& kNoArgumentNames = Array::Handle();
-  const Smi& retval = Smi::Handle(
-      reinterpret_cast<RawSmi*>(DartEntry::InvokeStatic(function,
-                                                        arguments,
-                                                        kNoArgumentNames)));
+  const Smi& retval = Smi::Handle(reinterpret_cast<RawSmi*>(
+      DartEntry::InvokeStatic(function, Object::empty_array())));
   EXPECT_EQ(Smi::New(42), retval.raw());
 }
 
@@ -69,9 +65,8 @@
   Function& function = Function::Handle(cls.LookupStaticFunction(name));
   EXPECT(!function.IsNull());
   GrowableArray<const Object*> arguments;
-  const Array& kNoArgumentNames = Array::Handle();
   const Object& retval = Object::Handle(
-      DartEntry::InvokeStatic(function, arguments, kNoArgumentNames));
+      DartEntry::InvokeStatic(function, Object::empty_array()));
   EXPECT(retval.IsError());
   EXPECT_SUBSTRING("++++", Error::Cast(retval).ToErrorCString());
 }
@@ -96,24 +91,24 @@
 
   // Invoke the constructor.
   const Instance& instance = Instance::Handle(Instance::New(cls));
-  GrowableArray<const Object*> constructor_arguments(2);
-  constructor_arguments.Add(&instance);
-  constructor_arguments.Add(&Smi::Handle(Smi::New(Function::kCtorPhaseAll)));
+  const Array& constructor_arguments = Array::Handle(Array::New(2));
+  constructor_arguments.SetAt(0, instance);
+  constructor_arguments.SetAt(
+      1, Smi::Handle(Smi::New(Function::kCtorPhaseAll)));
   String& constructor_name = String::Handle(Symbols::New("A."));
   Function& constructor =
-      Function::Handle(cls.LookupConstructor(constructor_name));
+    Function::Handle(cls.LookupConstructor(constructor_name));
   ASSERT(!constructor.IsNull());
-  const Array& kNoArgumentNames = Array::Handle();
-  DartEntry::InvokeStatic(constructor, constructor_arguments, kNoArgumentNames);
+  DartEntry::InvokeStatic(constructor, constructor_arguments);
 
   // Call foo.
   String& name = String::Handle(String::New("foo"));
   Function& function = Function::Handle(cls.LookupDynamicFunction(name));
   EXPECT(!function.IsNull());
-  GrowableArray<const Object*> arguments;
-  const Object& retval = Object::Handle(
-      DartEntry::InvokeDynamic(
-          instance, function, arguments, kNoArgumentNames));
+  const Array& args = Array::Handle(Array::New(1));
+  args.SetAt(0, instance);
+  const Object& retval = Object::Handle(DartEntry::InvokeDynamic(function,
+                                                                 args));
   EXPECT(retval.IsError());
   EXPECT_SUBSTRING("++++", Error::Cast(retval).ToErrorCString());
 }
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index d34593c..708d77a 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -852,7 +852,12 @@
 
 
 void Debugger::SignalExceptionThrown(const Object& exc) {
+  // We ignore this exception event when the VM is executing code invoked
+  // by the debugger to evaluate variables values, when we see a nested
+  // breakpoint or exception event, or if the debugger is not
+  // interested in exception events.
   if (ignore_breakpoints_ ||
+      (stack_trace_ != NULL) ||
       (event_handler_ == NULL) ||
       (exc_pause_info_ == kNoPauseOnExceptions)) {
     return;
@@ -932,10 +937,11 @@
     bpt = new CodeBreakpoint(func, best_fit_index);
     if (FLAG_verbose_debug) {
       OS::Print("Setting breakpoint in function '%s' "
-                "(%s:%"Pd") (PC %#"Px")\n",
+                "(%s:%"Pd") (Token %"Pd") (PC %#"Px")\n",
                 String::Handle(func.name()).ToCString(),
                 String::Handle(bpt->SourceUrl()).ToCString(),
                 bpt->LineNumber(),
+                bpt->token_pos(),
                 bpt->pc());
     }
     RegisterCodeBreakpoint(bpt);
@@ -1008,6 +1014,7 @@
     const Function& closure =
         Function::Handle(target_function.ImplicitClosureFunction());
     if (closure.HasCode()) {
+      EnsureFunctionIsDeoptimized(closure);
       CodeBreakpoint* closure_bpt =
           MakeCodeBreakpoint(closure, first_token_pos, last_token_pos);
       if ((closure_bpt != NULL) && (closure_bpt->src_bpt() == NULL)) {
@@ -1127,10 +1134,9 @@
   bool saved_ignore_flag = ignore_breakpoints_;
   ignore_breakpoints_ = true;
   if (setjmp(*jump.Set()) == 0) {
-    GrowableArray<const Object*> noArguments;
-    const Array& noArgumentNames = Array::Handle();
-    result = DartEntry::InvokeDynamic(object, getter_func,
-                                      noArguments, noArgumentNames);
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, object);
+    result = DartEntry::InvokeDynamic(getter_func, args);
   } else {
     result = isolate_->object_store()->sticky_error();
   }
@@ -1146,8 +1152,8 @@
   if (!fld.IsNull()) {
     // Return the value in the field if it has been initialized already.
     const Instance& value = Instance::Handle(fld.value());
-    ASSERT(value.raw() != Object::transition_sentinel());
-    if (value.raw() != Object::sentinel()) {
+    ASSERT(value.raw() != Object::transition_sentinel().raw());
+    if (value.raw() != Object::sentinel().raw()) {
       return value.raw();
     }
   }
@@ -1167,9 +1173,7 @@
   bool saved_ignore_flag = ignore_breakpoints_;
   ignore_breakpoints_ = true;
   if (setjmp(*jump.Set()) == 0) {
-    GrowableArray<const Object*> noArguments;
-    const Array& noArgumentNames = Array::Handle();
-    result = DartEntry::InvokeStatic(getter_func, noArguments, noArgumentNames);
+    result = DartEntry::InvokeStatic(getter_func, Object::empty_array());
   } else {
     result = isolate_->object_store()->sticky_error();
   }
@@ -1283,8 +1287,7 @@
     prefix = it.GetNext();
     prefix_name = prefix.name();
     ASSERT(!prefix_name.IsNull());
-    prefix_name = String::Concat(prefix_name,
-                                 String::Handle(isolate_, Symbols::Dot()));
+    prefix_name = String::Concat(prefix_name, Symbols::Dot());
     for (int i = 0; i < prefix.num_imports(); i++) {
       imported = prefix.GetLibrary(i);
       CollectLibraryFields(field_list, imported, prefix_name, false);
@@ -1335,7 +1338,10 @@
 
 
 void Debugger::SignalBpReached() {
-  if (ignore_breakpoints_) {
+  // We ignore this breakpoint when the VM is executing code invoked
+  // by the debugger to evaluate variables values, or when we see a nested
+  // breakpoint or exception event.
+  if (ignore_breakpoints_ || (stack_trace_ != NULL)) {
     return;
   }
   DebuggerStackTrace* stack_trace = CollectStackTrace();
@@ -1345,10 +1351,12 @@
   CodeBreakpoint* bpt = GetCodeBreakpoint(top_frame->pc());
   ASSERT(bpt != NULL);
   if (FLAG_verbose_debug) {
-    OS::Print(">>> hit %s breakpoint at %s:%"Pd" (Address %#"Px")\n",
+    OS::Print(">>> hit %s breakpoint at %s:%"Pd" "
+              "(token %"Pd") (address %#"Px")\n",
               bpt->IsInternal() ? "internal" : "user",
               String::Handle(bpt->SourceUrl()).ToCString(),
               bpt->LineNumber(),
+              bpt->token_pos(),
               top_frame->pc());
   }
 
diff --git a/runtime/vm/debugger_api_impl.cc b/runtime/vm/debugger_api_impl.cc
index fdd3072..d4687d1 100644
--- a/runtime/vm/debugger_api_impl.cc
+++ b/runtime/vm/debugger_api_impl.cc
@@ -632,8 +632,7 @@
     prefix = it.GetNext();
     prefix_name = prefix.name();
     ASSERT(!prefix_name.IsNull());
-    prefix_name = String::Concat(prefix_name,
-                                 String::Handle(isolate, Symbols::Dot()));
+    prefix_name = String::Concat(prefix_name, Symbols::Dot());
     for (int i = 0; i < prefix.num_imports(); i++) {
       imported = prefix.GetLibrary(i);
       import_list.Add(prefix_name);
diff --git a/runtime/vm/debugger_api_impl_test.cc b/runtime/vm/debugger_api_impl_test.cc
index 8056372..20f0e3f 100644
--- a/runtime/vm/debugger_api_impl_test.cc
+++ b/runtime/vm/debugger_api_impl_test.cc
@@ -971,20 +971,24 @@
   const String& script_url = String::Handle(String::New(TestCase::url()));
   Function& func = Function::Handle();
 
-  // TODO(hausner): Looking up functions from source and line number
-  // needs to be refined. We currently dont find "main" on line 7.
-  for (int line = 8; line <= 9; line++) {
+  for (int line = 7; line <= 9; line++) {
     func = test_lib.LookupFunctionInSource(script_url, line);
     EXPECT(!func.IsNull());
     EXPECT_STREQ("main", String::Handle(func.name()).ToCString());
   }
 
-  func = test_lib.LookupFunctionInSource(script_url, 3);
-  EXPECT(!func.IsNull());
-  EXPECT_STREQ("foo", String::Handle(func.name()).ToCString());
+  for (int line = 2; line <= 4; line++) {
+    func = test_lib.LookupFunctionInSource(script_url, 3);
+    EXPECT(!func.IsNull());
+    EXPECT_STREQ("foo", String::Handle(func.name()).ToCString());
+  }
 
+  // The VM generates an implicit constructor for class A and
+  // locates it at the token position of the keyword 'class'.
   func = test_lib.LookupFunctionInSource(script_url, 1);
-  EXPECT(func.IsNull());
+  EXPECT(!func.IsNull());
+  EXPECT_STREQ("A.", String::Handle(func.name()).ToCString());
+
   func = test_lib.LookupFunctionInSource(script_url, 6);
   EXPECT(func.IsNull());
   func = test_lib.LookupFunctionInSource(script_url, 10);
diff --git a/runtime/vm/debuginfo_macos.cc b/runtime/vm/debuginfo_macos.cc
deleted file mode 100644
index d86ffe0..0000000
--- a/runtime/vm/debuginfo_macos.cc
+++ /dev/null
@@ -1,50 +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/debuginfo.h"
-
-namespace dart {
-
-DebugInfo::DebugInfo() {
-  handle_ = NULL;
-}
-
-
-DebugInfo::~DebugInfo() {
-}
-
-
-void DebugInfo::AddCode(uword pc, intptr_t size) {
-  // Nothing to do as there is no support for this on macos.
-}
-
-
-void DebugInfo::AddCodeRegion(const char* name, uword pc, intptr_t size) {
-  // Nothing to do as there is no support for this on macos.
-}
-
-
-bool DebugInfo::WriteToMemory(ByteBuffer* region) {
-  // Nothing to do as there is no support for this on macos.
-  return false;
-}
-
-
-DebugInfo* DebugInfo::NewGenerator() {
-  return new DebugInfo();
-}
-
-
-void DebugInfo::RegisterSection(const char* name,
-                                uword entry_point,
-                                intptr_t size) {
-  // Nothing to do as there is no support for this on macos.
-}
-
-
-void DebugInfo::UnregisterAllSections() {
-  // Nothing to do as there is no support for this on macos.
-}
-
-}  // namespace dart
diff --git a/runtime/vm/debuginfo_win.cc b/runtime/vm/debuginfo_win.cc
deleted file mode 100644
index d86ffe0..0000000
--- a/runtime/vm/debuginfo_win.cc
+++ /dev/null
@@ -1,50 +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/debuginfo.h"
-
-namespace dart {
-
-DebugInfo::DebugInfo() {
-  handle_ = NULL;
-}
-
-
-DebugInfo::~DebugInfo() {
-}
-
-
-void DebugInfo::AddCode(uword pc, intptr_t size) {
-  // Nothing to do as there is no support for this on macos.
-}
-
-
-void DebugInfo::AddCodeRegion(const char* name, uword pc, intptr_t size) {
-  // Nothing to do as there is no support for this on macos.
-}
-
-
-bool DebugInfo::WriteToMemory(ByteBuffer* region) {
-  // Nothing to do as there is no support for this on macos.
-  return false;
-}
-
-
-DebugInfo* DebugInfo::NewGenerator() {
-  return new DebugInfo();
-}
-
-
-void DebugInfo::RegisterSection(const char* name,
-                                uword entry_point,
-                                intptr_t size) {
-  // Nothing to do as there is no support for this on macos.
-}
-
-
-void DebugInfo::UnregisterAllSections() {
-  // Nothing to do as there is no support for this on macos.
-}
-
-}  // namespace dart
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index 432a376..85f5885 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -20,7 +20,6 @@
             "Prints a stack trace everytime a throw occurs.");
 DEFINE_FLAG(bool, heap_profile_out_of_memory, false,
             "Writes a heap profile on unhandled out-of-memory exceptions.");
-DECLARE_FLAG(bool, heap_profile_out_of_memory);
 
 
 const char* Exceptions::kCastErrorDstName = "type cast";
@@ -144,8 +143,8 @@
                                  const Instance& existing_stacktrace) {
   Instance& exception = Instance::Handle(incoming_exception.raw());
   if (exception.IsNull()) {
-    GrowableArray<const Object*> arguments;
-    exception ^= Exceptions::Create(Exceptions::kNullThrown, arguments);
+    exception ^= Exceptions::Create(Exceptions::kNullThrown,
+                                    Object::empty_array());
   }
   uword handler_pc = 0;
   uword handler_sp = 0;
@@ -379,8 +378,7 @@
 }
 
 
-void Exceptions::ThrowByType(
-    ExceptionType type, const GrowableArray<const Object*>& arguments) {
+void Exceptions::ThrowByType(ExceptionType type, const Array& arguments) {
   const Object& result = Object::Handle(Create(type, arguments));
   if (result.IsError()) {
     // We got an error while constructing the exception object.
@@ -393,57 +391,60 @@
 }
 
 
-RawObject* Exceptions::Create(
-    ExceptionType type, const GrowableArray<const Object*>& arguments) {
+RawObject* Exceptions::Create(ExceptionType type, const Array& arguments) {
   Library& library = Library::Handle();
-  String& class_name = String::Handle();
+  const String* class_name = NULL;
   switch (type) {
     case kNone:
       UNREACHABLE();
       break;
     case kRange:
       library = Library::CoreLibrary();
-      class_name = Symbols::New("RangeError");
+      class_name = &Symbols::RangeError();
       break;
     case kArgument:
       library = Library::CoreLibrary();
-      class_name = Symbols::New("ArgumentError");
+      class_name = &Symbols::ArgumentError();
       break;
     case kNoSuchMethod:
       library = Library::CoreLibrary();
-      class_name = Symbols::New("NoSuchMethodError");
+      class_name = &Symbols::NoSuchMethodError();
       break;
     case kFormat:
       library = Library::CoreLibrary();
-      class_name = Symbols::New("FormatException");
+      class_name = &Symbols::FormatException();
       break;
     case kStackOverflow:
       library = Library::CoreLibrary();
-      class_name = Symbols::New("StackOverflowError");
+      class_name = &Symbols::StackOverflowError();
       break;
     case kOutOfMemory:
       library = Library::CoreLibrary();
-      class_name = Symbols::New("OutOfMemoryError");
+      class_name = &Symbols::OutOfMemoryError();
       break;
     case kInternalError:
       library = Library::CoreLibrary();
-      class_name = Symbols::New("InternalError");
+      class_name = &Symbols::InternalError();
       break;
     case kNullThrown:
       library = Library::CoreLibrary();
-      class_name = Symbols::New("NullThrownError");
+      class_name = &Symbols::NullThrownError();
       break;
     case kIllegalJSRegExp:
       library = Library::CoreLibrary();
-      class_name = Symbols::New("IllegalJSRegExpException");
+      class_name = &Symbols::IllegalJSRegExpException();
       break;
     case kIsolateSpawn:
       library = Library::IsolateLibrary();
-      class_name = Symbols::New("IsolateSpawnException");
+      class_name = &Symbols::IsolateSpawnException();
+      break;
+    case kIsolateUnhandledException:
+      library = Library::IsolateLibrary();
+      class_name = &Symbols::IsolateUnhandledException();
       break;
   }
 
-  return DartLibraryCalls::ExceptionCreate(library, class_name, arguments);
+  return DartLibraryCalls::ExceptionCreate(library, *class_name, arguments);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/exceptions.h b/runtime/vm/exceptions.h
index 0cc048f..794801b 100644
--- a/runtime/vm/exceptions.h
+++ b/runtime/vm/exceptions.h
@@ -58,15 +58,14 @@
     kInternalError,
     kNullThrown,
     kIllegalJSRegExp,
-    kIsolateSpawn
+    kIsolateSpawn,
+    kIsolateUnhandledException
   };
 
-  static void ThrowByType(ExceptionType type,
-                          const GrowableArray<const Object*>& arguments);
+  static void ThrowByType(ExceptionType type, const Array& arguments);
   // Returns a RawInstance if the exception is successfully created,
   // otherwise returns a RawError.
-  static RawObject* Create(ExceptionType type,
-                           const GrowableArray<const Object*>& arguments);
+  static RawObject* Create(ExceptionType type, const Array& arguments);
 
  private:
   DISALLOW_COPY_AND_ASSIGN(Exceptions);
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index f2aafe0..3b6a97d 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -24,6 +24,8 @@
             "Eliminate type checks when allowed by static type analysis.");
 DEFINE_FLAG(bool, print_ast, false, "Print abstract syntax tree.");
 DEFINE_FLAG(bool, print_flow_graph, false, "Print the IR flow graph.");
+DEFINE_FLAG(bool, print_flow_graph_optimized, false,
+            "Print the IR flow graph when optimizing.");
 DEFINE_FLAG(bool, trace_type_check_elimination, false,
             "Trace type check elimination at compile time.");
 DECLARE_FLAG(bool, enable_type_checks);
@@ -362,8 +364,7 @@
   if (FLAG_enable_type_checks) {
     value = Bind(new AssertBooleanInstr(condition_token_pos(), value));
   }
-  const Bool& bool_true = Bool::ZoneHandle(Bool::True());
-  Value* constant_true = Bind(new ConstantInstr(bool_true));
+  Value* constant_true = Bind(new ConstantInstr(Bool::True()));
   StrictCompareInstr* comp =
       new StrictCompareInstr(Token::kEQ_STRICT, value, constant_true);
   BranchInstr* branch = new BranchInstr(comp);
@@ -400,8 +401,7 @@
 
 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) {
   ASSERT(!FLAG_enable_type_checks);
-  const Bool& bool_true = Bool::ZoneHandle(Bool::True());
-  Value* constant_true = Bind(new ConstantInstr(bool_true));
+  Value* constant_true = Bind(new ConstantInstr(Bool::True()));
   BranchInstr* branch = new BranchInstr(
       new StrictCompareInstr(Token::kNE_STRICT, neg->value(), constant_true));
   AddInstruction(branch);
@@ -508,11 +508,10 @@
       const AbstractType& dst_type =
           AbstractType::ZoneHandle(
               owner()->parsed_function().function().result_type());
-      const String& dst_name = String::ZoneHandle(Symbols::FunctionResult());
       return_value = BuildAssignableValue(node->value()->token_pos(),
                                           return_value,
                                           dst_type,
-                                          dst_name);
+                                          Symbols::FunctionResult());
     }
   }
 
@@ -545,9 +544,17 @@
 }
 
 
-// Type nodes only occur as the right-hand side of instanceof comparisons,
-// and they are handled specially in that context.
-void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); }
+// Type nodes are used when a type is referenced as a literal. Type nodes
+// can also be used for the right-hand side of instanceof comparisons,
+// but they are handled specially in that context, not here.
+void EffectGraphVisitor::VisitTypeNode(TypeNode* node) {
+  return;
+}
+
+
+void ValueGraphVisitor::VisitTypeNode(TypeNode* node) {
+  ReturnDefinition(new ConstantInstr(node->type()));
+}
 
 
 // Returns true if the type check can be skipped, for example, if the
@@ -692,8 +699,6 @@
     // of left is sufficient.
     // AND:  left ? right === true : false;
     // OR:   left ? true : right === true;
-    const Bool& bool_true = Bool::ZoneHandle(Bool::True());
-    const Bool& bool_false = Bool::ZoneHandle(Bool::False());
 
     TestGraphVisitor for_test(owner(),
                               temp_index(),
@@ -709,7 +714,7 @@
           for_right.Bind(new AssertBooleanInstr(node->right()->token_pos(),
                                                 right_value));
     }
-    Value* constant_true = for_right.Bind(new ConstantInstr(bool_true));
+    Value* constant_true = for_right.Bind(new ConstantInstr(Bool::True()));
     Value* compare =
         for_right.Bind(new StrictCompareInstr(Token::kEQ_STRICT,
                                               right_value,
@@ -718,13 +723,13 @@
 
     if (node->kind() == Token::kAND) {
       ValueGraphVisitor for_false(owner(), temp_index(), loop_depth());
-      Value* constant_false = for_false.Bind(new ConstantInstr(bool_false));
+      Value* constant_false = for_false.Bind(new ConstantInstr(Bool::False()));
       for_false.Do(BuildStoreExprTemp(constant_false));
       Join(for_test, for_right, for_false);
     } else {
       ASSERT(node->kind() == Token::kOR);
       ValueGraphVisitor for_true(owner(), temp_index(), loop_depth());
-      Value* constant_true = for_true.Bind(new ConstantInstr(bool_true));
+      Value* constant_true = for_true.Bind(new ConstantInstr(Bool::True()));
       for_true.Do(BuildStoreExprTemp(constant_true));
       Join(for_test, for_true, for_right);
     }
@@ -735,6 +740,34 @@
 }
 
 
+void EffectGraphVisitor::BuildTypecheckPushArguments(
+    intptr_t token_pos,
+    PushArgumentInstr** push_instantiator_result,
+    PushArgumentInstr** push_instantiator_type_arguments_result) {
+  const Class& instantiator_class = Class::Handle(
+      owner()->parsed_function().function().Owner());
+  // Since called only when type tested against is not instantiated.
+  ASSERT(instantiator_class.NumTypeParameters() > 0);
+  Value* instantiator_type_arguments = NULL;
+  Value* instantiator = BuildInstantiator();
+  if (instantiator == NULL) {
+    // No instantiator when inside factory.
+    *push_instantiator_result = PushArgument(BuildNullValue());
+    instantiator_type_arguments =
+        BuildInstantiatorTypeArguments(token_pos, NULL);
+  } else {
+    instantiator = Bind(BuildStoreExprTemp(instantiator));
+    *push_instantiator_result = PushArgument(instantiator);
+    Value* loaded = Bind(BuildLoadExprTemp());
+    instantiator_type_arguments =
+        BuildInstantiatorTypeArguments(token_pos, loaded);
+  }
+  *push_instantiator_type_arguments_result =
+      PushArgument(instantiator_type_arguments);
+}
+
+
+
 void EffectGraphVisitor::BuildTypecheckArguments(
     intptr_t token_pos,
     Value** instantiator_result,
@@ -832,8 +865,6 @@
 
 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) {
   ASSERT(Token::IsTypeTestOperator(node->kind()));
-  const Bool& bool_true = Bool::ZoneHandle(Bool::True());
-  const Bool& bool_false = Bool::ZoneHandle(Bool::False());
   const AbstractType& type = node->right()->AsTypeNode()->type();
   ASSERT(type.IsFinalized() && !type.IsMalformed());
   const bool negate_result = (node->kind() == Token::kISNOT);
@@ -844,7 +875,8 @@
     EffectGraphVisitor for_left_value(owner(), temp_index(), loop_depth());
     node->left()->Visit(&for_left_value);
     Append(for_left_value);
-    ReturnDefinition(new ConstantInstr(negate_result ? bool_false : bool_true));
+    ReturnDefinition(new ConstantInstr(negate_result ?
+                                       Bool::False() : Bool::True()));
     return;
   }
 
@@ -860,12 +892,14 @@
       // already been checked above (if the type is instantiated). So we can
       // return false here if the instance is null (and if the type is
       // instantiated).
-      result = new ConstantInstr(negate_result ? bool_true : bool_false);
+      result = new ConstantInstr(negate_result ? Bool::True() : Bool::False());
     } else {
       if (literal_value.IsInstanceOf(type, TypeArguments::Handle(), NULL)) {
-        result = new ConstantInstr(negate_result ? bool_false : bool_true);
+        result = new ConstantInstr(negate_result ?
+                                   Bool::False() : Bool::True());
       } else {
-        result = new ConstantInstr(negate_result ? bool_true : bool_false);
+        result = new ConstantInstr(negate_result ?
+                                   Bool::True() : Bool::False());
       }
     }
     ReturnDefinition(result);
@@ -875,24 +909,39 @@
   ValueGraphVisitor for_left_value(owner(), temp_index(), loop_depth());
   node->left()->Visit(&for_left_value);
   Append(for_left_value);
-  Value* instantiator = NULL;
-  Value* instantiator_type_arguments = NULL;
+  PushArgumentInstr* push_left = PushArgument(for_left_value.value());
+  PushArgumentInstr* push_instantiator = NULL;
+  PushArgumentInstr* push_type_args = NULL;
   if (type.IsInstantiated()) {
-    instantiator = BuildNullValue();
-    instantiator_type_arguments = BuildNullValue();
+    push_instantiator = PushArgument(BuildNullValue());
+    push_type_args = PushArgument(BuildNullValue());
   } else {
-    BuildTypecheckArguments(node->token_pos(),
-                            &instantiator,
-                            &instantiator_type_arguments);
+    BuildTypecheckPushArguments(node->token_pos(),
+                                &push_instantiator,
+                                &push_type_args);
   }
-  InstanceOfInstr* instance_of =
-      new InstanceOfInstr(node->token_pos(),
-                          for_left_value.value(),
-                          instantiator,
-                          instantiator_type_arguments,
-                          node->right()->AsTypeNode()->type(),
-                          (node->kind() == Token::kISNOT));
-  ReturnDefinition(instance_of);
+  const String& name = String::ZoneHandle(Symbols::New("_instanceOf"));
+  ZoneGrowableArray<PushArgumentInstr*>* arguments =
+      new ZoneGrowableArray<PushArgumentInstr*>(5);
+  arguments->Add(push_left);
+  arguments->Add(push_instantiator);
+  arguments->Add(push_type_args);
+  ASSERT(!node->right()->AsTypeNode()->type().IsNull());
+  Value* type_arg = Bind(
+      new ConstantInstr(node->right()->AsTypeNode()->type()));
+  arguments->Add(PushArgument(type_arg));
+  const Bool& negate = (node->kind() == Token::kISNOT) ? Bool::True() :
+                                                         Bool::False();
+  Value* negate_arg = Bind(new ConstantInstr(negate));
+  arguments->Add(PushArgument(negate_arg));
+  const intptr_t kNumArgsChecked = 1;
+  InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(),
+                                                  name,
+                                                  node->kind(),
+                                                  arguments,
+                                                  Array::ZoneHandle(),
+                                                  kNumArgsChecked);
+  ReturnDefinition(call);
 }
 
 
@@ -1598,7 +1647,7 @@
 // <Expression> ::= StaticCall { function: Function
 //                               arguments: <ArgumentList> }
 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) {
-  if (node->function().name() == Symbols::Identical()) {
+  if (node->function().name() == Symbols::Identical().raw()) {
     // Attempt to replace top level defined 'identical' from the core
     // library with strict equal early on.
     // TODO(hausner): Evaluate if this can happen at AST building time.
@@ -1749,7 +1798,7 @@
 
   const String& function_name = String::Handle(function.name());
   const String& expected_function_name = String::Handle(
-      String::Concat(expected_class_name, Symbols::DotHandle()));
+      String::Concat(expected_class_name, Symbols::Dot()));
   return function_name.Equals(expected_function_name);
 }
 
@@ -1764,8 +1813,8 @@
   }
 
   if (node->constructor().IsFactory()) {
-    if ((function_class.Name() == Symbols::List()) &&
-        (function.name() == Symbols::ListFactory())) {
+    if ((function_class.Name() == Symbols::List().raw()) &&
+        (function.name() == Symbols::ListFactory().raw())) {
       // If there are no arguments then the result is guaranteed to be a
       // GrowableObjectArray. However if there is an argument the result
       // is not guaranteed to be a fixed size array because the argument
@@ -1774,12 +1823,11 @@
         return kGrowableObjectArrayCid;
       }
     } else {
-      if (IsRecognizedConstructor(function,
-                                  String::Handle(Symbols::ObjectArray())) &&
+      if (IsRecognizedConstructor(function, Symbols::ObjectArray()) &&
           (node->arguments()->length() == 1)) {
         return kArrayCid;
       } else if (IsRecognizedConstructor(function,
-                     String::Handle(Symbols::GrowableObjectArray())) &&
+                                         Symbols::GrowableObjectArray()) &&
                  (node->arguments()->length() == 0)) {
         return kGrowableObjectArrayCid;
       }
@@ -2095,20 +2143,30 @@
 
 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) {
   const String& getter_name =
-      String::Handle(Field::GetterName(node->field_name()));
+      String::ZoneHandle(Field::GetterSymbol(node->field_name()));
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
       new ZoneGrowableArray<PushArgumentInstr*>();
   Function& getter_function = Function::ZoneHandle();
   if (node->is_super_getter()) {
     // Statically resolved instance getter, i.e. "super getter".
-    getter_function =
-        Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name);
-    ASSERT(!getter_function.IsNull());
     ASSERT(node->receiver() != NULL);
-    ValueGraphVisitor receiver_value(owner(), temp_index(), loop_depth());
-    node->receiver()->Visit(&receiver_value);
-    Append(receiver_value);
-    arguments->Add(PushArgument(receiver_value.value()));
+    getter_function = Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name);
+    if (getter_function.IsNull()) {
+      // Resolve and call noSuchMethod.
+      ArgumentListNode* arguments = new ArgumentListNode(node->token_pos());
+      arguments->Add(node->receiver());
+      StaticCallInstr* call = BuildStaticNoSuchMethodCall(node->cls(),
+                                                          node->receiver(),
+                                                          getter_name,
+                                                          arguments);
+      ReturnDefinition(call);
+      return;
+    } else {
+      ValueGraphVisitor receiver_value(owner(), temp_index(), loop_depth());
+      node->receiver()->Visit(&receiver_value);
+      Append(receiver_value);
+      arguments->Add(PushArgument(receiver_value.value()));
+    }
   } else {
     getter_function = node->cls().LookupStaticFunction(getter_name);
     if (getter_function.IsNull()) {
@@ -2126,27 +2184,15 @@
       // StaticGetterNode missing a getter function, so we throw a
       // NoSuchMethodError.
 
-      // Location argument.
-      Value* call_pos = Bind(
-          new ConstantInstr(Smi::ZoneHandle(Smi::New(node->token_pos()))));
-      arguments->Add(PushArgument(call_pos));
-      // Function name argument.
-      const String& method_name = String::ZoneHandle(Symbols::New(getter_name));
-      Value* method_name_value = Bind(new ConstantInstr(method_name));
-      arguments->Add(PushArgument(method_name_value));
-      const String& cls_name = String::Handle(Symbols::NoSuchMethodError());
-      const String& func_name = String::Handle(Symbols::ThrowNew());
-      const Class& cls = Class::Handle(
-          Library::Handle(Library::CoreLibrary()).LookupClass(cls_name));
-      ASSERT(!cls.IsNull());
-      getter_function = Resolver::ResolveStatic(cls,
-                                                func_name,
-                                                arguments->length(),
-                                                Array::ZoneHandle(),
-                                                Resolver::kIsQualified);
-      ASSERT(!getter_function.IsNull());
+      // Throw a NoSuchMethodError.
+      StaticCallInstr* call = BuildThrowNoSuchMethodError(node->token_pos(),
+                                                          node->cls(),
+                                                          getter_name);
+      ReturnDefinition(call);
+      return;
     }
   }
+  ASSERT(!getter_function.IsNull());
   StaticCallInstr* call = new StaticCallInstr(node->token_pos(),
                                               getter_function,
                                               Array::ZoneHandle(),  // No names.
@@ -2158,41 +2204,59 @@
 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node,
                                            bool result_is_needed) {
   const String& setter_name =
-      String::Handle(Field::SetterName(node->field_name()));
+      String::ZoneHandle(Field::SetterSymbol(node->field_name()));
+  ZoneGrowableArray<PushArgumentInstr*>* arguments =
+      new ZoneGrowableArray<PushArgumentInstr*>(1);
   // A super setter is an instance setter whose setter function is
   // resolved at compile time (in the caller instance getter's super class).
   // Unlike a static getter, a super getter has a receiver parameter.
   const bool is_super_setter = (node->receiver() != NULL);
-  const Function& setter_function =
+  Function& setter_function =
       Function::ZoneHandle(is_super_setter
           ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name)
           : node->cls().LookupStaticFunction(setter_name));
-  ASSERT(!setter_function.IsNull());
-
-  ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new ZoneGrowableArray<PushArgumentInstr*>(1);
-  if (is_super_setter) {
-    // Add receiver of instance getter.
-    ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth());
-    node->receiver()->Visit(&for_receiver);
-    Append(for_receiver);
-    arguments->Add(PushArgument(for_receiver.value()));
-  }
-  ValueGraphVisitor for_value(owner(), temp_index(), loop_depth());
-  node->value()->Visit(&for_value);
-  Append(for_value);
-  Value* value = NULL;
-  if (result_is_needed) {
-    value = Bind(BuildStoreExprTemp(for_value.value()));
+  StaticCallInstr* call;
+  if (setter_function.IsNull()) {
+    if (is_super_setter) {
+      ASSERT(node->receiver() != NULL);
+      // Resolve and call noSuchMethod.
+      ArgumentListNode* arguments = new ArgumentListNode(node->token_pos());
+      arguments->Add(node->receiver());
+      arguments->Add(node->value());
+      call = BuildStaticNoSuchMethodCall(node->cls(),
+                                         node->receiver(),
+                                         setter_name,
+                                         arguments);
+    } else {
+      // Throw a NoSuchMethodError.
+      call = BuildThrowNoSuchMethodError(node->token_pos(),
+                                         node->cls(),
+                                         setter_name);
+    }
   } else {
-    value = for_value.value();
-  }
-  arguments->Add(PushArgument(value));
+    if (is_super_setter) {
+      // Add receiver of instance getter.
+      ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth());
+      node->receiver()->Visit(&for_receiver);
+      Append(for_receiver);
+      arguments->Add(PushArgument(for_receiver.value()));
+    }
+    ValueGraphVisitor for_value(owner(), temp_index(), loop_depth());
+    node->value()->Visit(&for_value);
+    Append(for_value);
+    Value* value = NULL;
+    if (result_is_needed) {
+      value = Bind(BuildStoreExprTemp(for_value.value()));
+    } else {
+      value = for_value.value();
+    }
+    arguments->Add(PushArgument(value));
 
-  StaticCallInstr* call = new StaticCallInstr(node->token_pos(),
-                                              setter_function,
-                                              Array::ZoneHandle(),  // No names.
-                                              arguments);
+    call = new StaticCallInstr(node->token_pos(),
+                               setter_function,
+                               Array::ZoneHandle(),  // No names.
+                               arguments);
+  }
   if (result_is_needed) {
     Do(call);
     ReturnDefinition(BuildLoadExprTemp());
@@ -2370,16 +2434,17 @@
     // Resolve the load indexed operator in the super class.
     super_function = &Function::ZoneHandle(
           Resolver::ResolveDynamicAnyArgs(node->super_class(),
-                                          Symbols::IndexTokenHandle()));
+                                          Symbols::IndexToken()));
     if (super_function->IsNull()) {
       // Could not resolve super operator. Generate call noSuchMethod() of the
       // super class instead.
       ArgumentListNode* arguments = new ArgumentListNode(node->token_pos());
+      arguments->Add(node->array());
       arguments->Add(node->index_expr());
       StaticCallInstr* call =
           BuildStaticNoSuchMethodCall(node->super_class(),
                                       node->array(),
-                                      Symbols::IndexTokenHandle(),
+                                      Symbols::IndexToken(),
                                       arguments);
       ReturnDefinition(call);
       return;
@@ -2408,7 +2473,7 @@
     // Generate dynamic call to index operator.
     const intptr_t checked_argument_count = 1;
     InstanceCallInstr* load = new InstanceCallInstr(node->token_pos(),
-                                                    Symbols::IndexTokenHandle(),
+                                                    Symbols::IndexToken(),
                                                     Token::kINDEX,
                                                     arguments,
                                                     Array::ZoneHandle(),
@@ -2426,7 +2491,7 @@
     // Resolve the store indexed operator in the super class.
     super_function = &Function::ZoneHandle(
         Resolver::ResolveDynamicAnyArgs(node->super_class(),
-                                        Symbols::AssignIndexTokenHandle()));
+                                        Symbols::AssignIndexToken()));
     if (super_function->IsNull()) {
       // Could not resolve super operator. Generate call noSuchMethod() of the
       // super class instead.
@@ -2439,12 +2504,13 @@
         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());
       StaticCallInstr* call =
           BuildStaticNoSuchMethodCall(node->super_class(),
                                       node->array(),
-                                      Symbols::AssignIndexTokenHandle(),
+                                      Symbols::AssignIndexToken(),
                                       arguments);
       if (result_is_needed) {
         Do(call);
@@ -2778,16 +2844,13 @@
     ArgumentListNode* method_arguments) {
   // Build the graph to allocate an InvocationMirror object by calling
   // the static allocation method.
-  const String& mirror_name = String::Handle(Symbols::InvocationMirror());
   const Library& corelib = Library::Handle(Library::CoreLibrary());
   const Class& mirror_class = Class::Handle(
-      corelib.LookupClassAllowPrivate(mirror_name));
+      corelib.LookupClassAllowPrivate(Symbols::InvocationMirror()));
   ASSERT(!mirror_class.IsNull());
-  const String& function_name = String::Handle(
-      Symbols::AllocateInvocationMirror());
   const Function& allocation_function = Function::ZoneHandle(
       Resolver::ResolveStaticByName(mirror_class,
-                                    function_name,
+                                    Symbols::AllocateInvocationMirror(),
                                     Resolver::kIsQualified));
   ASSERT(!allocation_function.IsNull());
 
@@ -2827,10 +2890,8 @@
   Value* invocation_mirror = Bind(allocation);
   PushArgumentInstr* push_invocation_mirror = PushArgument(invocation_mirror);
   // Lookup noSuchMethod and call it with the receiver and the InvocationMirror.
-  const String& no_such_method_name =
-      String::ZoneHandle(Symbols::NoSuchMethod());
   const Function& no_such_method_func = Function::ZoneHandle(
-      Resolver::ResolveDynamicAnyArgs(target_class, no_such_method_name));
+      Resolver::ResolveDynamicAnyArgs(target_class, Symbols::NoSuchMethod()));
   // We are guaranteed to find noSuchMethod of class Object.
   ASSERT(!no_such_method_func.IsNull());
   ZoneGrowableArray<PushArgumentInstr*>* args =
@@ -2844,6 +2905,58 @@
 }
 
 
+StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError(
+    intptr_t token_pos,
+    const Class& function_class,
+    const String& function_name) {
+  ZoneGrowableArray<PushArgumentInstr*>* arguments =
+      new ZoneGrowableArray<PushArgumentInstr*>();
+  // Object receiver.
+  // TODO(regis): For now, we pass a class literal of the unresolved
+  // method's owner, but this is not specified and will probably change.
+  Type& type = Type::ZoneHandle(
+      Type::New(function_class,
+                TypeArguments::Handle(),
+                token_pos,
+                Heap::kOld));
+  type ^= ClassFinalizer::FinalizeType(
+      function_class, type, ClassFinalizer::kCanonicalize);
+  Value* receiver_value = Bind(new ConstantInstr(type));
+  arguments->Add(PushArgument(receiver_value));
+  // String memberName.
+  const String& member_name = String::ZoneHandle(Symbols::New(function_name));
+  Value* member_name_value = Bind(new ConstantInstr(member_name));
+  arguments->Add(PushArgument(member_name_value));
+  // List arguments.
+  Value* arguments_value = Bind(new ConstantInstr(Array::ZoneHandle()));
+  arguments->Add(PushArgument(arguments_value));
+  // List argumentNames.
+  Value* argument_names_value =
+      Bind(new ConstantInstr(Array::ZoneHandle()));
+  arguments->Add(PushArgument(argument_names_value));
+  // List existingArgumentNames.
+  Value* existing_argument_names_value =
+      Bind(new ConstantInstr(Array::ZoneHandle()));
+  arguments->Add(PushArgument(existing_argument_names_value));
+  // Resolve and call NoSuchMethodError._throwNew.
+  const Library& core_lib = Library::Handle(Library::CoreLibrary());
+  const Class& cls = Class::Handle(
+      core_lib.LookupClass(Symbols::NoSuchMethodError()));
+  ASSERT(!cls.IsNull());
+  const Function& func = Function::ZoneHandle(
+      Resolver::ResolveStatic(cls,
+                              Symbols::ThrowNew(),
+                              arguments->length(),
+                              Array::ZoneHandle(),
+                              Resolver::kIsQualified));
+  ASSERT(!func.IsNull());
+  return new StaticCallInstr(token_pos,
+                             func,
+                             Array::ZoneHandle(),  // No names.
+                             arguments);
+}
+
+
 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) {
   // TODO(kmillikin) non-local control flow is not handled correctly
   // by the inliner.
diff --git a/runtime/vm/flow_graph_builder.h b/runtime/vm/flow_graph_builder.h
index 64139bd..7fcdb0f 100644
--- a/runtime/vm/flow_graph_builder.h
+++ b/runtime/vm/flow_graph_builder.h
@@ -202,6 +202,10 @@
       Value** instantiator,
       ZoneGrowableArray<PushArgumentInstr*>* call_arguments);
 
+  void BuildTypecheckPushArguments(
+      intptr_t token_pos,
+      PushArgumentInstr** push_instantiator,
+      PushArgumentInstr** push_instantiator_type_arguments);
   void BuildTypecheckArguments(intptr_t token_pos,
                                Value** instantiator,
                                Value** instantiator_type_arguments);
@@ -262,6 +266,10 @@
       const String& method_name,
       ArgumentListNode* method_arguments);
 
+  StaticCallInstr* BuildThrowNoSuchMethodError(intptr_t token_pos,
+                                               const Class& function_class,
+                                               const String& function_name);
+
   void BuildStaticSetter(StaticSetterNode* node, bool result_is_needed);
   Definition* BuildStoreStaticField(StoreStaticFieldNode* node,
                                     bool result_is_needed);
@@ -325,6 +333,7 @@
   virtual void VisitClosureCallNode(ClosureCallNode* node);
   virtual void VisitStaticSetterNode(StaticSetterNode* node);
   virtual void VisitStoreStaticFieldNode(StoreStaticFieldNode* node);
+  virtual void VisitTypeNode(TypeNode* node);
 
   Value* value() const { return value_; }
 
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index da86242..b8dbef8 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -150,8 +150,6 @@
           GrowableObjectArray::New())),
       is_optimizing_(is_optimizing),
       may_reoptimize_(false),
-      bool_true_(Bool::ZoneHandle(Bool::True())),
-      bool_false_(Bool::ZoneHandle(Bool::False())),
       double_class_(Class::ZoneHandle(
           Isolate::Current()->object_store()->double_class())),
       parallel_move_resolver_(this) {
@@ -628,6 +626,47 @@
 }
 
 
+struct CidTarget {
+  intptr_t cid;
+  Function* target;
+  intptr_t count;
+  CidTarget(intptr_t cid_arg,
+            Function* target_arg,
+            intptr_t count_arg)
+      : cid(cid_arg), target(target_arg), count(count_arg) {}
+};
+
+
+// Returns 'sorted' array in decreasing count order.
+// The expected number of elements to sort is less than 10.
+static void SortICDataByCount(const ICData& ic_data,
+                              GrowableArray<CidTarget>* sorted) {
+  ASSERT(ic_data.num_args_tested() == 1);
+  const intptr_t len = ic_data.NumberOfChecks();
+  sorted->Clear();
+
+  for (int i = 0; i < len; i++) {
+    sorted->Add(CidTarget(ic_data.GetReceiverClassIdAt(i),
+                          &Function::ZoneHandle(ic_data.GetTargetAt(i)),
+                          ic_data.GetCountAt(i)));
+  }
+  for (int i = 0; i < len; i++) {
+    intptr_t largest_ix = i;
+    for (int k = i + 1; k < len; k++) {
+      if ((*sorted)[largest_ix].count < (*sorted)[k].count) {
+        largest_ix = k;
+      }
+    }
+    if (i != largest_ix) {
+      // Swap.
+      CidTarget temp = (*sorted)[i];
+      (*sorted)[i] = (*sorted)[largest_ix];
+      (*sorted)[largest_ix] = temp;
+    }
+  }
+}
+
+
 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
                                         Register class_id_reg,
                                         intptr_t arg_count,
@@ -639,19 +678,20 @@
   ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
   Label match_found;
   const intptr_t len = ic_data.NumberOfChecks();
+  GrowableArray<CidTarget> sorted(len);
+  SortICDataByCount(ic_data, &sorted);
   for (intptr_t i = 0; i < len; i++) {
     const bool is_last_check = (i == (len - 1));
     Label next_test;
-    assembler()->cmpl(class_id_reg, Immediate(ic_data.GetReceiverClassIdAt(i)));
+    assembler()->cmpl(class_id_reg, Immediate(sorted[i].cid));
     if (is_last_check) {
       assembler()->j(NOT_EQUAL, deopt);
     } else {
       assembler()->j(NOT_EQUAL, &next_test);
     }
-    const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i));
     GenerateStaticCall(deopt_id,
                        token_index,
-                       target,
+                       *sorted[i].target,
                        arg_count,
                        arg_names,
                        locs);
@@ -687,10 +727,10 @@
   assembler()->j(PARITY_EVEN, &is_false, Assembler::kNearJump);  // NaN false;
   assembler()->j(true_condition, &is_true, Assembler::kNearJump);
   assembler()->Bind(&is_false);
-  assembler()->LoadObject(result, bool_false());
+  assembler()->LoadObject(result, Bool::False());
   assembler()->jmp(&done);
   assembler()->Bind(&is_true);
-  assembler()->LoadObject(result, bool_true());
+  assembler()->LoadObject(result, Bool::True());
   assembler()->Bind(&done);
 }
 
@@ -1020,6 +1060,8 @@
   if (!FLAG_use_cha || !is_optimizing()) return false;
   if (!type.IsInstantiated()) return false;
   const Class& type_class = Class::Handle(type.type_class());
+  // Signature classes have different type checking rules.
+  if (type_class.IsSignatureClass()) return false;
   // Could be an interface check?
   if (type_class.is_implemented()) return false;
   const intptr_t type_cid = type_class.id();
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 9f4b9b3..deeec69 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -61,7 +61,7 @@
   Label fall_through;
   __ cmpl(bool_register, raw_null);
   __ j(EQUAL, &fall_through, Assembler::kNearJump);
-  __ CompareObject(bool_register, bool_true());
+  __ CompareObject(bool_register, Bool::True());
   __ j(EQUAL, is_true);
   __ jmp(is_false);
   __ Bind(&fall_through);
@@ -200,21 +200,18 @@
   ASSERT(!type_class.HasTypeArguments());
 
   const Register kInstanceReg = EAX;
-  Label compare_classes;
   __ testl(kInstanceReg, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &compare_classes, Assembler::kNearJump);
-  // Instance is Smi, check directly.
+  // If instance is Smi, check directly.
   const Class& smi_class = Class::Handle(Smi::Class());
   if (smi_class.IsSubtypeOf(TypeArguments::Handle(),
                             type_class,
                             TypeArguments::Handle(),
                             NULL)) {
-    __ jmp(is_instance_lbl);
+    __ j(ZERO, is_instance_lbl);
   } else {
-    __ jmp(is_not_instance_lbl);
+    __ j(ZERO, is_not_instance_lbl);
   }
   // Compare if the classes are equal.
-  __ Bind(&compare_classes);
   const Register kClassIdReg = ECX;
   __ LoadClassId(kClassIdReg, kInstanceReg);
   __ cmpl(kClassIdReg, Immediate(type_class.id()));
@@ -235,8 +232,6 @@
     __ movl(EDI, FieldAddress(EDI, Class::signature_function_offset()));
     __ cmpl(EDI, raw_null);
     __ j(NOT_EQUAL, is_instance_lbl);
-    __ jmp(is_not_instance_lbl);
-    return false;
   }
   // Custom checking for numbers (Smi, Mint, Bigint and Double).
   // Note that instance is not Smi (checked above).
@@ -501,21 +496,21 @@
     __ Drop(5);
     if (negate_result) {
       __ popl(EDX);
-      __ LoadObject(EAX, bool_true());
+      __ LoadObject(EAX, Bool::True());
       __ cmpl(EDX, EAX);
       __ j(NOT_EQUAL, &done, Assembler::kNearJump);
-      __ LoadObject(EAX, bool_false());
+      __ LoadObject(EAX, Bool::False());
     } else {
       __ popl(EAX);
     }
     __ jmp(&done, Assembler::kNearJump);
   }
   __ Bind(&is_not_instance);
-  __ LoadObject(EAX, negate_result ? bool_true() : bool_false());
+  __ LoadObject(EAX, negate_result ? Bool::True() : Bool::False());
   __ jmp(&done, Assembler::kNearJump);
 
   __ Bind(&is_instance);
-  __ LoadObject(EAX, negate_result ? bool_false() : bool_true());
+  __ LoadObject(EAX, negate_result ? Bool::False() : Bool::True());
   __ Bind(&done);
   __ popl(EDX);  // Remove pushed instantiator type arguments.
   __ popl(ECX);  // Remove pushed instantiator.
@@ -800,7 +795,7 @@
   // Invoke noSuchMethod function passing the original name of the function.
   // If the function is a closure function, use "call" as the original name.
   const String& name = String::Handle(
-      function.IsClosureFunction() ? Symbols::Call() : function.name());
+      function.IsClosureFunction() ? Symbols::Call().raw() : function.name());
   const int kNumArgsChecked = 1;
   const ICData& ic_data = ICData::ZoneHandle(
       ICData::New(function, name, Isolate::kNoDeoptId, kNumArgsChecked));
@@ -899,7 +894,7 @@
   // We check the number of passed arguments when we have to copy them due to
   // the presence of optional parameters.
   // No such checking code is generated if only fixed parameters are declared,
-  // unless we are debug mode or unless we are compiling a closure.
+  // unless we are in debug mode or unless we are compiling a closure.
   LocalVariable* saved_args_desc_var =
       parsed_function().GetSavedArgumentsDescriptorVar();
   if (num_copied_params == 0) {
@@ -911,11 +906,17 @@
 #endif
     if (check_arguments) {
       __ Comment("Check argument count");
-      // Check that num_fixed <= argc <= num_params.
-      Label argc_in_range;
+      // Check that exactly num_fixed arguments are passed in.
+      Label correct_num_arguments, wrong_num_arguments;
       __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
       __ cmpl(EAX, Immediate(Smi::RawValue(num_fixed_params)));
-      __ j(EQUAL, &argc_in_range, Assembler::kNearJump);
+      __ j(NOT_EQUAL, &wrong_num_arguments, Assembler::kNearJump);
+      __ cmpl(EAX,
+              FieldAddress(EDX,
+                           ArgumentsDescriptor::positional_count_offset()));
+      __ j(EQUAL, &correct_num_arguments, Assembler::kNearJump);
+
+      __ Bind(&wrong_num_arguments);
       if (function.IsClosureFunction()) {
         if (StackSize() != 0) {
           // We need to unwind the space we reserved for locals and copied
@@ -928,10 +929,10 @@
         BitmapBuilder* empty_stack_bitmap = new BitmapBuilder();
 
         // Invoke noSuchMethod function passing "call" as the function name.
-        const String& name = String::Handle(Symbols::Call());
         const int kNumArgsChecked = 1;
         const ICData& ic_data = ICData::ZoneHandle(
-            ICData::New(function, name, Isolate::kNoDeoptId, kNumArgsChecked));
+            ICData::New(function, Symbols::Call(),
+                        Isolate::kNoDeoptId, kNumArgsChecked));
         __ LoadObject(ECX, ic_data);
         // EBP - 4 : PC marker, for easy identification of RawInstruction obj.
         // EBP : points to previous frame pointer.
@@ -952,7 +953,7 @@
       } else {
         __ Stop("Wrong number of arguments");
       }
-      __ Bind(&argc_in_range);
+      __ Bind(&correct_num_arguments);
     }
     // The arguments descriptor is never saved in the absence of optional
     // parameters, since any argument definition test would always yield true.
@@ -1245,11 +1246,11 @@
   __ cmpl(result, Address(ESP, 0 * kWordSize));
   Label is_false;
   __ j(NOT_EQUAL, &is_false, Assembler::kNearJump);
-  __ LoadObject(result, bool_true());
+  __ LoadObject(result, Bool::True());
   __ Drop(1);
   __ jmp(skip_call);
   __ Bind(&is_false);
-  __ LoadObject(result, bool_false());
+  __ LoadObject(result, Bool::False());
   __ Drop(1);
   __ jmp(skip_call);
   __ Bind(&fall_through);
diff --git a/runtime/vm/flow_graph_compiler_ia32.h b/runtime/vm/flow_graph_compiler_ia32.h
index f29351c..9897b7b 100644
--- a/runtime/vm/flow_graph_compiler_ia32.h
+++ b/runtime/vm/flow_graph_compiler_ia32.h
@@ -206,8 +206,6 @@
   void FinalizeComments(const Code& code);
   void FinalizeStaticCallTargetsTable(const Code& code);
 
-  const Bool& bool_true() const { return bool_true_; }
-  const Bool& bool_false() const { return bool_false_; }
   const Class& double_class() const { return double_class_; }
 
   void SaveLiveRegisters(LocationSummary* locs);
@@ -344,8 +342,6 @@
   // Set to true if optimized code has IC calls.
   bool may_reoptimize_;
 
-  const Bool& bool_true_;
-  const Bool& bool_false_;
   const Class& double_class_;
 
   ParallelMoveResolver parallel_move_resolver_;
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index a998490..17298b6 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -61,7 +61,7 @@
   Label fall_through;
   __ cmpq(bool_register, raw_null);
   __ j(EQUAL, &fall_through, Assembler::kNearJump);
-  __ CompareObject(bool_register, bool_true());
+  __ CompareObject(bool_register, Bool::True());
   __ j(EQUAL, is_true);
   __ jmp(is_false);
   __ Bind(&fall_through);
@@ -200,21 +200,18 @@
   ASSERT(!type_class.HasTypeArguments());
 
   const Register kInstanceReg = RAX;
-  Label compare_classes;
   __ testq(kInstanceReg, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &compare_classes, Assembler::kNearJump);
-  // Instance is Smi, check directly.
+  // If instance is Smi, check directly.
   const Class& smi_class = Class::Handle(Smi::Class());
   if (smi_class.IsSubtypeOf(TypeArguments::Handle(),
                             type_class,
                             TypeArguments::Handle(),
                             NULL)) {
-    __ jmp(is_instance_lbl);
+    __ j(ZERO, is_instance_lbl);
   } else {
-    __ jmp(is_not_instance_lbl);
+    __ j(ZERO, is_not_instance_lbl);
   }
   // Compare if the classes are equal.
-  __ Bind(&compare_classes);
   const Register kClassIdReg = R10;
   __ LoadClassId(kClassIdReg, kInstanceReg);
   __ cmpl(kClassIdReg, Immediate(type_class.id()));
@@ -235,8 +232,6 @@
     __ movq(R13, FieldAddress(R13, Class::signature_function_offset()));
     __ cmpq(R13, raw_null);
     __ j(NOT_EQUAL, is_instance_lbl);
-    __ jmp(is_not_instance_lbl);
-    return false;
   }
   // Custom checking for numbers (Smi, Mint, Bigint and Double).
   // Note that instance is not Smi (checked above).
@@ -501,21 +496,21 @@
     __ Drop(5);
     if (negate_result) {
       __ popq(RDX);
-      __ LoadObject(RAX, bool_true());
+      __ LoadObject(RAX, Bool::True());
       __ cmpq(RDX, RAX);
       __ j(NOT_EQUAL, &done, Assembler::kNearJump);
-      __ LoadObject(RAX, bool_false());
+      __ LoadObject(RAX, Bool::False());
     } else {
       __ popq(RAX);
     }
     __ jmp(&done, Assembler::kNearJump);
   }
   __ Bind(&is_not_instance);
-  __ LoadObject(RAX, negate_result ? bool_true() : bool_false());
+  __ LoadObject(RAX, negate_result ? Bool::True() : Bool::False());
   __ jmp(&done, Assembler::kNearJump);
 
   __ Bind(&is_instance);
-  __ LoadObject(RAX, negate_result ? bool_false() : bool_true());
+  __ LoadObject(RAX, negate_result ? Bool::False() : Bool::True());
   __ Bind(&done);
   __ popq(RDX);  // Remove pushed instantiator type arguments.
   __ popq(RCX);  // Remove pushed instantiator.
@@ -802,7 +797,7 @@
   // Invoke noSuchMethod function passing the original name of the function.
   // If the function is a closure function, use "call" as the original name.
   const String& name = String::Handle(
-      function.IsClosureFunction() ? Symbols::Call() : function.name());
+      function.IsClosureFunction() ? Symbols::Call().raw() : function.name());
   const int kNumArgsChecked = 1;
   const ICData& ic_data = ICData::ZoneHandle(
       ICData::New(function, name, Isolate::kNoDeoptId, kNumArgsChecked));
@@ -902,7 +897,7 @@
   // We check the number of passed arguments when we have to copy them due to
   // the presence of optional parameters.
   // No such checking code is generated if only fixed parameters are declared,
-  // unless we are debug mode or unless we are compiling a closure.
+  // unless we are in debug mode or unless we are compiling a closure.
   LocalVariable* saved_args_desc_var =
       parsed_function().GetSavedArgumentsDescriptorVar();
   if (num_copied_params == 0) {
@@ -914,11 +909,17 @@
 #endif
     if (check_arguments) {
       __ Comment("Check argument count");
-      // Check that num_fixed <= argc <= num_params.
-      Label argc_in_range;
+      // Check that exactly num_fixed arguments are passed in.
+      Label correct_num_arguments, wrong_num_arguments;
       __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
       __ cmpq(RAX, Immediate(Smi::RawValue(num_fixed_params)));
-      __ j(EQUAL, &argc_in_range, Assembler::kNearJump);
+      __ j(NOT_EQUAL, &wrong_num_arguments, Assembler::kNearJump);
+      __ cmpq(RAX,
+              FieldAddress(R10,
+                           ArgumentsDescriptor::positional_count_offset()));
+      __ j(EQUAL, &correct_num_arguments, Assembler::kNearJump);
+
+      __ Bind(&wrong_num_arguments);
       if (function.IsClosureFunction()) {
         if (StackSize() != 0) {
           // We need to unwind the space we reserved for locals and copied
@@ -931,10 +932,10 @@
         BitmapBuilder* empty_stack_bitmap = new BitmapBuilder();
 
         // Invoke noSuchMethod function passing "call" as the function name.
-        const String& name = String::Handle(Symbols::Call());
         const int kNumArgsChecked = 1;
         const ICData& ic_data = ICData::ZoneHandle(
-            ICData::New(function, name, Isolate::kNoDeoptId, kNumArgsChecked));
+            ICData::New(function, Symbols::Call(),
+                        Isolate::kNoDeoptId, kNumArgsChecked));
         __ LoadObject(RBX, ic_data);
         // RBP - 8 : PC marker, for easy identification of RawInstruction obj.
         // RBP : points to previous frame pointer.
@@ -955,7 +956,7 @@
       } else {
         __ Stop("Wrong number of arguments");
       }
-      __ Bind(&argc_in_range);
+      __ Bind(&correct_num_arguments);
     }
     // The arguments descriptor is never saved in the absence of optional
     // parameters, since any argument definition test would always yield true.
@@ -1249,11 +1250,11 @@
   __ cmpq(result, Address(RSP, 0 * kWordSize));
   Label is_false;
   __ j(NOT_EQUAL, &is_false, Assembler::kNearJump);
-  __ LoadObject(result, bool_true());
+  __ LoadObject(result, Bool::True());
   __ Drop(1);
   __ jmp(skip_call);
   __ Bind(&is_false);
-  __ LoadObject(result, bool_false());
+  __ LoadObject(result, Bool::False());
   __ Drop(1);
   __ jmp(skip_call);
   __ Bind(&fall_through);
diff --git a/runtime/vm/flow_graph_compiler_x64.h b/runtime/vm/flow_graph_compiler_x64.h
index f62868b..a63317a 100644
--- a/runtime/vm/flow_graph_compiler_x64.h
+++ b/runtime/vm/flow_graph_compiler_x64.h
@@ -207,8 +207,6 @@
   void FinalizeComments(const Code& code);
   void FinalizeStaticCallTargetsTable(const Code& code);
 
-  const Bool& bool_true() const { return bool_true_; }
-  const Bool& bool_false() const { return bool_false_; }
   const Class& double_class() const { return double_class_; }
 
   // Returns true if the compiled function has a finally clause.
@@ -345,8 +343,6 @@
   // Set to true if optimized code has IC calls.
   bool may_reoptimize_;
 
-  const Bool& bool_true_;
-  const Bool& bool_false_;
   const Class& double_class_;
 
   ParallelMoveResolver parallel_move_resolver_;
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index 2b3bfe2..644d88d 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -36,6 +36,9 @@
 DEFINE_FLAG(int, inlining_constant_arguments_size_threshold, 60,
     "Inline function calls with sufficient constant arguments "
     "and up to the increased threshold on instructions");
+DEFINE_FLAG(int, inlining_hotness, 10,
+    "Inline only hotter calls, in percents (0 .. 100); "
+    "default 10%: calls above-equal 10% of max-count are inlined.");
 
 DECLARE_FLAG(bool, print_flow_graph);
 DECLARE_FLAG(int, deoptimization_counter_threshold);
@@ -185,16 +188,23 @@
         instance_calls_(),
         skip_static_call_deopt_ids_() { }
 
-  GrowableArray<StaticCallInstr*>* static_calls() {
-    return &static_calls_;
+  const GrowableArray<StaticCallInstr*>& static_calls() const {
+    return static_calls_;
   }
 
-  GrowableArray<ClosureCallInstr*>* closure_calls() {
-    return &closure_calls_;
+  const GrowableArray<ClosureCallInstr*>& closure_calls() const {
+    return closure_calls_;
   }
 
-  GrowableArray<PolymorphicInstanceCallInstr*>* instance_calls() {
-    return &instance_calls_;
+  struct InstanceCallInfo {
+    PolymorphicInstanceCallInstr* call;
+    double ratio;
+    explicit InstanceCallInfo(PolymorphicInstanceCallInstr* call_arg)
+        : call(call_arg), ratio(0.0) {}
+  };
+
+  const GrowableArray<InstanceCallInfo>& instance_calls() const {
+    return instance_calls_;
   }
 
   bool HasCalls() const {
@@ -215,8 +225,11 @@
     const Function& function = graph->parsed_function().function();
     ASSERT(function.HasCode());
     const Code& code = Code::Handle(function.unoptimized_code());
+
     skip_static_call_deopt_ids_.Clear();
     code.ExtractUncalledStaticCallDeoptIds(&skip_static_call_deopt_ids_);
+
+    const intptr_t instance_call_start_ix = instance_calls_.length();
     for (BlockIterator block_it = graph->postorder_iterator();
          !block_it.Done();
          block_it.Advance()) {
@@ -226,6 +239,24 @@
         it.Current()->Accept(this);
       }
     }
+    // Compute instance call site ratio.
+    const intptr_t num_instance_calls =
+        instance_calls_.length() - instance_call_start_ix;
+    intptr_t max_count = 0;
+    GrowableArray<intptr_t> call_counts(num_instance_calls);
+    for (intptr_t i = 0; i < num_instance_calls; ++i) {
+      const intptr_t aggregate_count =
+          instance_calls_[i + instance_call_start_ix].
+              call->ic_data().AggregateCount();
+      call_counts.Add(aggregate_count);
+      if (aggregate_count > max_count) max_count = aggregate_count;
+    }
+
+
+    for (intptr_t i = 0; i < num_instance_calls; ++i) {
+      const double ratio = static_cast<double>(call_counts[i]) / max_count;
+      instance_calls_[i + instance_call_start_ix].ratio = ratio;
+    }
   }
 
   void VisitClosureCall(ClosureCallInstr* call) {
@@ -233,7 +264,7 @@
   }
 
   void VisitPolymorphicInstanceCall(PolymorphicInstanceCallInstr* call) {
-    instance_calls_.Add(call);
+    instance_calls_.Add(InstanceCallInfo(call));
   }
 
   void VisitStaticCall(StaticCallInstr* call) {
@@ -251,7 +282,7 @@
  private:
   GrowableArray<StaticCallInstr*> static_calls_;
   GrowableArray<ClosureCallInstr*> closure_calls_;
-  GrowableArray<PolymorphicInstanceCallInstr*> instance_calls_;
+  GrowableArray<InstanceCallInfo> instance_calls_;
   GrowableArray<intptr_t> skip_static_call_deopt_ids_;
 
   DISALLOW_COPY_AND_ASSIGN(CallSites);
@@ -353,6 +384,24 @@
       return false;
     }
 
+    const intptr_t loop_depth = call->GetBlock()->loop_depth();
+    const intptr_t constant_arguments = CountConstants(*arguments);
+    if (!ShouldWeInline(loop_depth,
+                        function.optimized_instruction_count(),
+                        function.optimized_call_site_count(),
+                        constant_arguments)) {
+      TRACE_INLINING(OS::Print("     Bailout: early heuristics with "
+                               "loop depth: %"Pd", "
+                               "code size:  %"Pd", "
+                               "call sites: %"Pd", "
+                               "const args: %"Pd"\n",
+                               loop_depth,
+                               function.optimized_instruction_count(),
+                               function.optimized_call_site_count(),
+                               constant_arguments));
+      return false;
+    }
+
     // Abort if this is a recursive occurrence.
     if (IsCallRecursive(function, call)) {
       function.set_is_inlinable(false);
@@ -397,7 +446,6 @@
       }
 
       // Build the callee graph.
-      const intptr_t loop_depth = call->GetBlock()->loop_depth();
       FlowGraphBuilder builder(*parsed_function);
       builder.SetInitialBlockId(caller_graph_->max_block_id());
       FlowGraph* callee_graph;
@@ -482,6 +530,10 @@
       GraphInfoCollector info;
       info.Collect(*callee_graph);
       const intptr_t size = info.instruction_count();
+
+      function.set_optimized_instruction_count(size);
+      function.set_optimized_call_site_count(info.call_site_count());
+
       // Use heuristics do decide if this call should be inlined.
       if (!ShouldWeInline(loop_depth,
                           size,
@@ -580,6 +632,14 @@
     }
   }
 
+  static intptr_t CountConstants(const GrowableArray<Value*>& arguments) {
+    intptr_t count = 0;
+    for (intptr_t i = 0; i < arguments.length(); i++) {
+      if (arguments[i]->BindsToConstant()) count++;
+    }
+    return count;
+  }
+
   // Parse a function reusing the cache if possible.
   ParsedFunction* GetParsedFunction(const Function& function, bool* in_cache) {
     // TODO(zerny): Use a hash map for the cache.
@@ -601,7 +661,7 @@
 
   void InlineStaticCalls() {
     const GrowableArray<StaticCallInstr*>& calls =
-        *inlining_call_sites_->static_calls();
+        inlining_call_sites_->static_calls();
     TRACE_INLINING(OS::Print("  Static Calls (%d)\n", calls.length()));
     for (intptr_t i = 0; i < calls.length(); ++i) {
       StaticCallInstr* call = calls[i];
@@ -615,7 +675,7 @@
 
   void InlineClosureCalls() {
     const GrowableArray<ClosureCallInstr*>& calls =
-        *inlining_call_sites_->closure_calls();
+        inlining_call_sites_->closure_calls();
     TRACE_INLINING(OS::Print("  Closure Calls (%d)\n", calls.length()));
     for (intptr_t i = 0; i < calls.length(); ++i) {
       ClosureCallInstr* call = calls[i];
@@ -639,25 +699,33 @@
   }
 
   void InlineInstanceCalls() {
-    const GrowableArray<PolymorphicInstanceCallInstr*>& calls =
-        *inlining_call_sites_->instance_calls();
+    const GrowableArray<CallSites::InstanceCallInfo>& call_info =
+        inlining_call_sites_->instance_calls();
     TRACE_INLINING(OS::Print("  Polymorphic Instance Calls (%d)\n",
-                             calls.length()));
-    for (intptr_t i = 0; i < calls.length(); ++i) {
-      PolymorphicInstanceCallInstr* instr = calls[i];
+                             call_info.length()));
+    for (intptr_t i = 0; i < call_info.length(); ++i) {
+      PolymorphicInstanceCallInstr* instr = call_info[i].call;
       const ICData& ic_data = instr->ic_data();
       const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0));
       if (instr->with_checks()) {
         TRACE_INLINING(OS::Print(
-          "  => %s (deopt count %d)\n     Bailout: %"Pd" checks\n",
-          target.ToCString(),
-          target.deoptimization_counter(),
-          ic_data.NumberOfChecks()));
+            "  => %s (deopt count %d)\n     Bailout: %"Pd" checks\n",
+            target.ToCString(),
+            target.deoptimization_counter(),
+            ic_data.NumberOfChecks()));
+        continue;
+      }
+      if ((call_info[i].ratio * 100) < FLAG_inlining_hotness) {
+        TRACE_INLINING(OS::Print(
+            "  => %s (deopt count %d)\n     Bailout: cold %f\n",
+            target.ToCString(),
+            target.deoptimization_counter(),
+            call_info[i].ratio));
         continue;
       }
       GrowableArray<Value*> arguments(instr->ArgumentCount());
-      for (int i = 0; i < instr->ArgumentCount(); ++i) {
-        arguments.Add(instr->ArgumentAt(i)->value());
+      for (int arg_i = 0; arg_i < instr->ArgumentCount(); ++arg_i) {
+        arguments.Add(instr->ArgumentAt(arg_i)->value());
       }
       TryInlining(target,
                   instr->instance_call()->argument_names(),
@@ -769,7 +837,22 @@
 };
 
 
+void FlowGraphInliner::CollectGraphInfo(FlowGraph* flow_graph) {
+  GraphInfoCollector info;
+  info.Collect(*flow_graph);
+  const Function& function = flow_graph->parsed_function().function();
+  function.set_optimized_instruction_count(
+    static_cast<uint16_t>(info.instruction_count()));
+  function.set_optimized_call_site_count(
+    static_cast<uint16_t>(info.call_site_count()));
+}
+
+
 void FlowGraphInliner::Inline() {
+  // Collect graph info and store it on the function.
+  // We might later use it for an early bailout from the inlining.
+  CollectGraphInfo(flow_graph_);
+
   if ((FLAG_inlining_filter != NULL) &&
       (strstr(flow_graph_->
               parsed_function().function().ToFullyQualifiedCString(),
diff --git a/runtime/vm/flow_graph_inliner.h b/runtime/vm/flow_graph_inliner.h
index 7f37ac6..f95f8de 100644
--- a/runtime/vm/flow_graph_inliner.h
+++ b/runtime/vm/flow_graph_inliner.h
@@ -20,6 +20,8 @@
   // The flow graph is destructively updated upon inlining.
   void Inline();
 
+  static void CollectGraphInfo(FlowGraph* flow_graph);
+
  private:
   FlowGraph* flow_graph_;
   DISALLOW_COPY_AND_ASSIGN(FlowGraphInliner);
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index facc555..18dc942 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -117,14 +117,26 @@
 }
 
 
+static void EnsureSSATempIndex(FlowGraph* graph,
+                               Definition* defn,
+                               Definition* replacement) {
+  if ((replacement->ssa_temp_index() == -1) &&
+      (defn->ssa_temp_index() != -1)) {
+    replacement->set_ssa_temp_index(graph->alloc_ssa_temp_index());
+  }
+}
+
+
 static void ReplaceCurrentInstruction(ForwardInstructionIterator* it,
                                       Instruction* current,
-                                      Instruction* replacement) {
+                                      Instruction* replacement,
+                                      FlowGraph* graph) {
   if ((replacement != NULL) && current->IsDefinition()) {
     Definition* current_defn = current->AsDefinition();
     Definition* replacement_defn = replacement->AsDefinition();
     ASSERT(replacement_defn != NULL);
     current_defn->ReplaceUsesWith(replacement_defn);
+    EnsureSSATempIndex(graph, current_defn, replacement_defn);
 
     if (FLAG_trace_optimization) {
       OS::Print("Replacing v%"Pd" with v%"Pd"\n",
@@ -157,7 +169,7 @@
         // For non-definitions Canonicalize should return either NULL or
         // this.
         ASSERT((replacement == NULL) || current->IsDefinition());
-        ReplaceCurrentInstruction(&it, current, replacement);
+        ReplaceCurrentInstruction(&it, current, replacement, flow_graph_);
       }
     }
   }
@@ -192,7 +204,17 @@
     const intptr_t deopt_id = (deopt_target != NULL) ?
         deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
     ASSERT((deopt_target != NULL) || (def->GetPropagatedCid() == kDoubleCid));
-    converted = new UnboxDoubleInstr(new Value(def), deopt_id);
+    if (def->IsConstant() && def->AsConstant()->value().IsSmi()) {
+      const double dbl_val =
+          Smi::Cast(def->AsConstant()->value()).AsDoubleValue();
+      const Double& dbl_obj =
+          Double::ZoneHandle(Double::New(dbl_val, Heap::kOld));
+      ConstantInstr* double_const = new ConstantInstr(dbl_obj);
+      InsertBefore(instr, double_const, NULL, Definition::kValue);
+      converted = new UnboxDoubleInstr(new Value(double_const), deopt_id);
+    } else {
+      converted = new UnboxDoubleInstr(new Value(def), deopt_id);
+    }
   }
   ASSERT(converted != NULL);
   InsertBefore(instr, converted, use->instruction()->env(),
@@ -590,7 +612,7 @@
                                   instantiator,
                                   type_args,
                                   value_type,
-                                  String::ZoneHandle(Symbols::New("value")));
+                                  Symbols::Value());
     InsertBefore(call, assert_value, NULL, Definition::kValue);
   }
 
@@ -949,7 +971,8 @@
   LoadFieldInstr* load = new LoadFieldInstr(
       call->ArgumentAt(0)->value(),
       field.Offset(),
-      AbstractType::ZoneHandle(field.type()));
+      AbstractType::ZoneHandle(field.type()),
+      field.is_final());
   call->ReplaceWith(load, current_iterator());
   RemovePushArguments(call);
 }
@@ -974,7 +997,8 @@
 }
 
 
-void FlowGraphOptimizer::InlineGArrayCapacityGetter(InstanceCallInstr* call) {
+void FlowGraphOptimizer::InlineGrowableArrayCapacityGetter(
+    InstanceCallInstr* call) {
   // Check receiver class.
   AddCheckClass(call, call->ArgumentAt(0)->value()->Copy());
 
@@ -1040,6 +1064,22 @@
 }
 
 
+static intptr_t OffsetForLengthGetter(MethodRecognizer::Kind kind) {
+  switch (kind) {
+    case MethodRecognizer::kObjectArrayLength:
+    case MethodRecognizer::kImmutableArrayLength:
+      return Array::length_offset();
+    case MethodRecognizer::kByteArrayBaseLength:
+      return ByteArray::length_offset();
+    case MethodRecognizer::kGrowableArrayLength:
+      return GrowableObjectArray::length_offset();
+    default:
+      UNREACHABLE();
+      return 0;
+  }
+}
+
+
 // Only unique implicit instance getters can be currently handled.
 bool FlowGraphOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call) {
   ASSERT(call->HasICData());
@@ -1063,56 +1103,43 @@
       MethodRecognizer::RecognizeKind(target);
 
   // VM objects length getter.
-  if ((recognized_kind == MethodRecognizer::kObjectArrayLength) ||
-      (recognized_kind == MethodRecognizer::kImmutableArrayLength) ||
-      (recognized_kind == MethodRecognizer::kGrowableArrayLength)) {
-    if (!ic_data.HasOneTarget()) {
-      // TODO(srdjan): Implement for mutiple targets.
-      return false;
+  switch (recognized_kind) {
+    case MethodRecognizer::kObjectArrayLength:
+    case MethodRecognizer::kImmutableArrayLength:
+    case MethodRecognizer::kByteArrayBaseLength:
+    case MethodRecognizer::kGrowableArrayLength: {
+      if (!ic_data.HasOneTarget()) {
+        // TODO(srdjan): Implement for mutiple targets.
+        return false;
+      }
+      const bool is_immutable =
+          (recognized_kind != MethodRecognizer::kGrowableArrayLength);
+      InlineArrayLengthGetter(call,
+                              OffsetForLengthGetter(recognized_kind),
+                              is_immutable,
+                              recognized_kind);
+      return true;
     }
-    switch (recognized_kind) {
-      case MethodRecognizer::kObjectArrayLength:
-      case MethodRecognizer::kImmutableArrayLength:
-        InlineArrayLengthGetter(call,
-                                Array::length_offset(),
-                                true,
-                                recognized_kind);
-        break;
-      case MethodRecognizer::kGrowableArrayLength:
-        InlineArrayLengthGetter(call,
-                                GrowableObjectArray::length_offset(),
-                                false,
-                                recognized_kind);
-        break;
-      default:
-        UNREACHABLE();
-    }
-    return true;
+    case MethodRecognizer::kGrowableArrayCapacity:
+      InlineGrowableArrayCapacityGetter(call);
+      return true;
+    case MethodRecognizer::kStringBaseLength:
+      if (!ic_data.HasOneTarget()) {
+        // Target is not only StringBase_get_length.
+        return false;
+      }
+      InlineStringLengthGetter(call);
+      return true;
+    case MethodRecognizer::kStringBaseIsEmpty:
+      if (!ic_data.HasOneTarget()) {
+        // Target is not only StringBase_get_isEmpty.
+        return false;
+      }
+      InlineStringIsEmptyGetter(call);
+      return true;
+    default:
+      ASSERT(recognized_kind == MethodRecognizer::kUnknown);
   }
-
-  if (recognized_kind == MethodRecognizer::kGrowableArrayCapacity) {
-    InlineGArrayCapacityGetter(call);
-    return true;
-  }
-
-  if (recognized_kind == MethodRecognizer::kStringBaseLength) {
-    if (!ic_data.HasOneTarget()) {
-      // Target is not only StringBase_get_length.
-      return false;
-    }
-    InlineStringLengthGetter(call);
-    return true;
-  }
-
-  if (recognized_kind == MethodRecognizer::kStringBaseIsEmpty) {
-    if (!ic_data.HasOneTarget()) {
-      // Target is not only StringBase_get_isEmpty.
-      return false;
-    }
-    InlineStringIsEmptyGetter(call);
-    return true;
-  }
-
   return false;
 }
 
@@ -1203,9 +1230,17 @@
   if ((recognized_kind == MethodRecognizer::kDoubleToInteger) &&
       (class_ids[0] == kDoubleCid)) {
     AddCheckClass(call, call->ArgumentAt(0)->value()->Copy());
-    DoubleToIntegerInstr* d2int_instr =
-        new DoubleToIntegerInstr(call->ArgumentAt(0)->value(), call);
-    call->ReplaceWith(d2int_instr, current_iterator());
+    ASSERT(call->HasICData());
+    const ICData& ic_data = *call->ic_data();
+    Definition* d2i_instr = NULL;
+    if (ic_data.deopt_reason() == kDeoptDoubleToSmi) {
+      // Do not repeatedly deoptimize because result didn't fit into Smi.
+      d2i_instr = new DoubleToIntegerInstr(call->ArgumentAt(0)->value(), call);
+    } else {
+      // Optimistically assume result fits into Smi.
+      d2i_instr = new DoubleToSmiInstr(call->ArgumentAt(0)->value(), call);
+    }
+    call->ReplaceWith(d2i_instr, current_iterator());
     RemovePushArguments(call);
     return true;
   }
@@ -1214,6 +1249,77 @@
 }
 
 
+// Returns a Boolean constant if all classes in ic_data yield the same type-test
+// result and the type tests do not depend on type arguments. Otherwise return
+// Bool::null().
+RawBool* FlowGraphOptimizer::InstanceOfAsBool(const ICData& ic_data,
+                                              const AbstractType& type) const {
+  ASSERT(ic_data.num_args_tested() == 1);  // Unary checks only.
+  if (!type.IsInstantiated() || type.IsMalformed()) return Bool::null();
+  const Class& type_class = Class::Handle(type.type_class());
+  if (type_class.HasTypeArguments()) return Bool::null();
+  const ClassTable& class_table = *Isolate::Current()->class_table();
+  Bool& prev = Bool::Handle();
+  Class& cls = Class::Handle();
+  for (int i = 0; i < ic_data.NumberOfChecks(); i++) {
+    cls = class_table.At(ic_data.GetReceiverClassIdAt(i));
+    if (cls.HasTypeArguments()) return Bool::null();
+    bool is_subtype = false;
+    if (cls.IsNullClass()) {
+      is_subtype = type_class.IsDynamicClass() || type_class.IsObjectClass();
+    } else {
+      is_subtype = cls.IsSubtypeOf(TypeArguments::Handle(),
+                                   type_class,
+                                   TypeArguments::Handle(),
+                                   NULL);
+    }
+    if (prev.IsNull()) {
+      prev = is_subtype ? Bool::True().raw() : Bool::False().raw();
+    } else {
+      if (is_subtype != prev.value()) return Bool::null();
+    }
+  }
+  return prev.raw();
+}
+
+
+// TODO(srdjan): Use ICData to check if always true or false.
+void FlowGraphOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) {
+  ASSERT(Token::IsTypeTestOperator(call->token_kind()));
+  Value* left_val = call->ArgumentAt(0)->value();
+  Value* instantiator_val = call->ArgumentAt(1)->value();
+  Value* type_args_val = call->ArgumentAt(2)->value();
+  const AbstractType& type =
+      AbstractType::Cast(call->ArgumentAt(3)->value()->BoundConstant());
+  const bool negate =
+      Bool::Cast(call->ArgumentAt(4)->value()->BoundConstant()).value();
+  const ICData& unary_checks =
+      ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecks());
+  if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) {
+    Bool& as_bool = Bool::ZoneHandle(InstanceOfAsBool(unary_checks, type));
+    if (!as_bool.IsNull()) {
+      AddCheckClass(call, left_val->Copy());
+      if (negate) {
+        as_bool = as_bool.value() ? Bool::False().raw() : Bool::True().raw();
+      }
+      ConstantInstr* bool_const = new ConstantInstr(as_bool);
+      call->ReplaceWith(bool_const, current_iterator());
+      RemovePushArguments(call);
+      return;
+    }
+  }
+  InstanceOfInstr* instance_of =
+      new InstanceOfInstr(call->token_pos(),
+                          left_val,
+                          instantiator_val,
+                          type_args_val,
+                          type,
+                          negate);
+  call->ReplaceWith(instance_of, current_iterator());
+  RemovePushArguments(call);
+}
+
+
 // Tries to optimize instance call by replacing it with a faster instruction
 // (e.g, binary op, field load, ..).
 void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) {
@@ -1222,6 +1328,13 @@
     return;
   }
 
+  const Token::Kind op_kind = instr->token_kind();
+  // Type test is special as it always gets converted into inlined code.
+  if (Token::IsTypeTestOperator(op_kind)) {
+    ReplaceWithInstanceOf(instr);
+    return;
+  }
+
   const ICData& unary_checks =
       ICData::ZoneHandle(instr->ic_data()->AsUnaryClassChecks());
   if ((unary_checks.NumberOfChecks() > FLAG_max_polymorphic_checks) &&
@@ -1231,7 +1344,6 @@
     return;
   }
 
-  const Token::Kind op_kind = instr->token_kind();
   if ((op_kind == Token::kASSIGN_INDEX) &&
       TryReplaceWithStoreIndexed(instr)) {
     return;
@@ -2485,12 +2597,11 @@
     }
 
     if (FLAG_trace_type_check_elimination) {
-      const String& name = String::Handle(Symbols::New("boolean expression"));
       FlowGraphPrinter::PrintTypeCheck(parsed_function(),
                                        instr->token_pos(),
                                        instr->value(),
                                        Type::Handle(Type::BoolType()),
-                                       name,
+                                       Symbols::BooleanExpression(),
                                        instr->is_eliminated());
     }
   }
@@ -2504,8 +2615,8 @@
       instr->value()->CanComputeIsNull(&is_null) &&
       (is_null ||
        instr->value()->CanComputeIsInstanceOf(instr->type(), &is_instance))) {
-    Definition* result = new ConstantInstr(Bool::ZoneHandle(Bool::Get(
-        instr->negate_result() ? !is_instance : is_instance)));
+    bool val = instr->negate_result() ? !is_instance : is_instance;
+    Definition* result = new ConstantInstr(val ? Bool::True() : Bool::False());
     result->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
     result->InsertBefore(instr);
     // Replace uses and remove the current instruction via the iterator.
@@ -2519,12 +2630,11 @@
     }
 
     if (FLAG_trace_type_check_elimination) {
-      const String& name = String::Handle(Symbols::New("InstanceOf"));
       FlowGraphPrinter::PrintTypeCheck(parsed_function(),
                                        instr->token_pos(),
                                        instr->value(),
                                        instr->type(),
-                                       name,
+                                       Symbols::InstanceOf(),
                                        /* eliminated = */ true);
     }
   }
@@ -2829,10 +2939,105 @@
 }
 
 
+static Definition* GetStoredValue(Instruction* instr) {
+  if (instr->IsStoreIndexed()) {
+    return instr->AsStoreIndexed()->value()->definition();
+  }
+
+  StoreInstanceFieldInstr* store_instance_field = instr->AsStoreInstanceField();
+  if (store_instance_field != NULL) {
+    return store_instance_field->value()->definition();
+  }
+
+  StoreVMFieldInstr* store_vm_field = instr->AsStoreVMField();
+  if (store_vm_field != NULL) {
+    return store_vm_field->value()->definition();
+  }
+
+  UNREACHABLE();  // Should only be called for supported store instructions.
+  return NULL;
+}
+
+
+// KeyValueTrait used for numbering of loads. Allows to lookup loads
+// corresponding to stores.
+class LoadKeyValueTrait {
+ public:
+  typedef Definition* Value;
+  typedef Definition* Key;
+  typedef Definition* Pair;
+
+  static Key KeyOf(Pair kv) {
+    return kv;
+  }
+
+  static Value ValueOf(Pair kv) {
+    return kv;
+  }
+
+  static inline intptr_t Hashcode(Key key) {
+    intptr_t object = 0;
+    intptr_t location = 0;
+
+    if (key->IsLoadIndexed()) {
+      LoadIndexedInstr* load_indexed = key->AsLoadIndexed();
+      object = load_indexed->array()->definition()->ssa_temp_index();
+      location = load_indexed->index()->definition()->ssa_temp_index();
+    } else if (key->IsStoreIndexed()) {
+      StoreIndexedInstr* store_indexed = key->AsStoreIndexed();
+      object = store_indexed->array()->definition()->ssa_temp_index();
+      location = store_indexed->index()->definition()->ssa_temp_index();
+    } else if (key->IsLoadField()) {
+      LoadFieldInstr* load_field = key->AsLoadField();
+      object = load_field->value()->definition()->ssa_temp_index();
+      location = load_field->offset_in_bytes();
+    } else if (key->IsStoreInstanceField()) {
+      StoreInstanceFieldInstr* store_field = key->AsStoreInstanceField();
+      object = store_field->instance()->definition()->ssa_temp_index();
+      location = store_field->field().Offset();
+    } else if (key->IsStoreVMField()) {
+      StoreVMFieldInstr* store_field = key->AsStoreVMField();
+      object = store_field->dest()->definition()->ssa_temp_index();
+      location = store_field->offset_in_bytes();
+    }
+
+    return object * 31 + location;
+  }
+
+  static inline bool IsKeyEqual(Pair kv, Key key) {
+    if (kv->Equals(key)) return true;
+
+    if (kv->IsLoadIndexed()) {
+      if (key->IsStoreIndexed()) {
+        LoadIndexedInstr* load_indexed = kv->AsLoadIndexed();
+        StoreIndexedInstr* store_indexed = key->AsStoreIndexed();
+        return load_indexed->array()->Equals(store_indexed->array()) &&
+               load_indexed->index()->Equals(store_indexed->index());
+      }
+      return false;
+    }
+
+    ASSERT(kv->IsLoadField());
+    LoadFieldInstr* load_field = kv->AsLoadField();
+    if (key->IsStoreVMField()) {
+      StoreVMFieldInstr* store_field = key->AsStoreVMField();
+      return load_field->value()->Equals(store_field->dest()) &&
+             (load_field->offset_in_bytes() == store_field->offset_in_bytes());
+    } else if (key->IsStoreInstanceField()) {
+      StoreInstanceFieldInstr* store_field = key->AsStoreInstanceField();
+      return load_field->value()->Equals(store_field->instance()) &&
+             (load_field->offset_in_bytes() == store_field->field().Offset());
+    }
+
+    return false;
+  }
+};
+
+
 static intptr_t NumberLoadExpressions(
     FlowGraph* graph,
+    DirectChainedHashMap<LoadKeyValueTrait>* map,
     GrowableArray<BitVector*>* kill_by_offs) {
-  DirectChainedHashMap<PointerKeyValueTrait<Definition> > map;
   intptr_t expr_id = 0;
 
   // Loads representing different expression ids will be collected and
@@ -2850,9 +3055,9 @@
       if ((defn == NULL) || !IsLoadEliminationCandidate(defn)) {
         continue;
       }
-      Definition* result = map.Lookup(defn);
+      Definition* result = map->Lookup(defn);
       if (result == NULL) {
-        map.Insert(defn);
+        map->Insert(defn);
         defn->set_expr_id(expr_id++);
         loads.Add(defn);
       } else {
@@ -2876,217 +3081,474 @@
     (*kill_by_offs)[offset_in_words]->Add(defn->expr_id());
   }
 
-
   return expr_id;
 }
 
 
-static void ComputeAvailableLoads(
-    FlowGraph* graph,
-    intptr_t max_expr_id,
-    const GrowableArray<BitVector*>& avail_in,
-    const GrowableArray<BitVector*>& kill_by_offs) {
-  // Initialize gen-, kill-, out-sets.
-  intptr_t num_blocks = graph->preorder().length();
-  GrowableArray<BitVector*> avail_out(num_blocks);
-  GrowableArray<BitVector*> avail_gen(num_blocks);
-  GrowableArray<BitVector*> avail_kill(num_blocks);
-  for (intptr_t i = 0; i < num_blocks; i++) {
-    avail_out.Add(new BitVector(max_expr_id));
-    avail_gen.Add(new BitVector(max_expr_id));
-    avail_kill.Add(new BitVector(max_expr_id));
-  }
+class LoadOptimizer : public ValueObject {
+ public:
+  LoadOptimizer(FlowGraph* graph,
+                intptr_t max_expr_id,
+                DirectChainedHashMap<LoadKeyValueTrait>* map,
+                const GrowableArray<BitVector*>& kill_by_offset)
+      : graph_(graph),
+        map_(map),
+        max_expr_id_(max_expr_id),
+        kill_by_offset_(kill_by_offset),
+        in_(graph_->preorder().length()),
+        out_(graph_->preorder().length()),
+        gen_(graph_->preorder().length()),
+        kill_(graph_->preorder().length()),
+        exposed_values_(graph_->preorder().length()),
+        out_values_(graph_->preorder().length()),
+        phis_(5),
+        worklist_(5),
+        in_worklist_(NULL) {
+    const intptr_t num_blocks = graph_->preorder().length();
+    for (intptr_t i = 0; i < num_blocks; i++) {
+      out_.Add(new BitVector(max_expr_id_));
+      gen_.Add(new BitVector(max_expr_id_));
+      kill_.Add(new BitVector(max_expr_id_));
+      in_.Add(new BitVector(max_expr_id_));
 
-  for (BlockIterator block_it = graph->reverse_postorder_iterator();
-       !block_it.Done();
-       block_it.Advance()) {
-    BlockEntryInstr* block = block_it.Current();
-    intptr_t preorder_number = block->preorder_number();
-    for (BackwardInstructionIterator instr_it(block);
-         !instr_it.Done();
-         instr_it.Advance()) {
-      Instruction* instr = instr_it.Current();
-
-      intptr_t offset_in_words = 0;
-      if (IsInterferingStore(instr, &offset_in_words)) {
-        if ((offset_in_words < kill_by_offs.length()) &&
-            (kill_by_offs[offset_in_words] != NULL)) {
-          avail_kill[preorder_number]->AddAll(kill_by_offs[offset_in_words]);
-        }
-        ASSERT(instr->IsDefinition() &&
-               !IsLoadEliminationCandidate(instr->AsDefinition()));
-        continue;
-      } else if (instr->HasSideEffect()) {
-        avail_kill[preorder_number]->SetAll();
-        break;
-      }
-      Definition* defn = instr->AsDefinition();
-      if ((defn == NULL) || !IsLoadEliminationCandidate(defn)) {
-        continue;
-      }
-
-      const intptr_t expr_id = defn->expr_id();
-      if (!avail_kill[preorder_number]->Contains(expr_id)) {
-        avail_gen[preorder_number]->Add(expr_id);
-      }
+      exposed_values_.Add(NULL);
+      out_values_.Add(NULL);
     }
-    avail_out[preorder_number]->CopyFrom(avail_gen[preorder_number]);
   }
 
-  BitVector* temp = new BitVector(avail_in[0]->length());
+  void Optimize() {
+    ComputeInitialSets();
+    ComputeOutValues();
+    ForwardLoads();
+    EmitPhis();
+  }
 
-  bool changed = true;
-  while (changed) {
-    changed = false;
-
-    for (BlockIterator block_it = graph->reverse_postorder_iterator();
+ private:
+  // Compute sets of loads generated and killed by each block.
+  // Additionally compute upwards exposed and generated loads for each block.
+  // Exposed loads are those that can be replaced if a corresponding
+  // reaching load will be found.
+  // Loads that are locally redundant will be replaced as we go through
+  // instructions.
+  void ComputeInitialSets() {
+    for (BlockIterator block_it = graph_->reverse_postorder_iterator();
          !block_it.Done();
          block_it.Advance()) {
       BlockEntryInstr* block = block_it.Current();
-      BitVector* block_in = avail_in[block->preorder_number()];
-      BitVector* block_out = avail_out[block->preorder_number()];
-      BitVector* block_kill = avail_kill[block->preorder_number()];
-      BitVector* block_gen = avail_gen[block->preorder_number()];
+      const intptr_t preorder_number = block->preorder_number();
 
-      if (FLAG_trace_optimization) {
-        OS::Print("B%"Pd"", block->block_id());
-        block_in->Print();
-        block_out->Print();
-        OS::Print("\n");
+      BitVector* kill = kill_[preorder_number];
+      BitVector* gen = gen_[preorder_number];
+
+      ZoneGrowableArray<Definition*>* exposed_values = NULL;
+      ZoneGrowableArray<Definition*>* out_values = NULL;
+
+      for (ForwardInstructionIterator instr_it(block);
+           !instr_it.Done();
+           instr_it.Advance()) {
+        Instruction* instr = instr_it.Current();
+
+        intptr_t offset_in_words = 0;
+        if (IsInterferingStore(instr, &offset_in_words)) {
+          // Interfering stores kill only loads from the same offset.
+          if ((offset_in_words < kill_by_offset_.length()) &&
+              (kill_by_offset_[offset_in_words] != NULL)) {
+            kill->AddAll(kill_by_offset_[offset_in_words]);
+            // There is no need to clear out_values when clearing GEN set
+            // because only those values that are in the GEN set
+            // will ever be used.
+            gen->RemoveAll(kill_by_offset_[offset_in_words]);
+
+            Definition* load = map_->Lookup(instr->AsDefinition());
+            if (load != NULL) {
+              // Store has a corresponding numbered load. Try forwarding
+              // stored value to it.
+              gen->Add(load->expr_id());
+              if (out_values == NULL) out_values = CreateBlockOutValues();
+              (*out_values)[load->expr_id()] = GetStoredValue(instr);
+            }
+          }
+          ASSERT(instr->IsDefinition() &&
+                 !IsLoadEliminationCandidate(instr->AsDefinition()));
+          continue;
+        }
+
+        // Other instructions with side effects kill all loads.
+        if (instr->HasSideEffect()) {
+          kill->SetAll();
+          // There is no need to clear out_values when clearing GEN set
+          // because only those values that are in the GEN set
+          // will ever be used.
+          gen->Clear();
+          continue;
+        }
+
+        Definition* defn = instr->AsDefinition();
+        if ((defn == NULL) || !IsLoadEliminationCandidate(defn)) {
+          continue;
+        }
+
+        const intptr_t expr_id = defn->expr_id();
+        if (gen->Contains(expr_id)) {
+          // This is a locally redundant load.
+          ASSERT((out_values != NULL) && ((*out_values)[expr_id] != NULL));
+
+          Definition* replacement = (*out_values)[expr_id];
+          EnsureSSATempIndex(graph_, defn, replacement);
+          if (FLAG_trace_optimization) {
+            OS::Print("Replacing load v%"Pd" with v%"Pd"\n",
+                      defn->ssa_temp_index(),
+                      replacement->ssa_temp_index());
+          }
+
+          defn->ReplaceUsesWith(replacement);
+          instr_it.RemoveCurrentFromGraph();
+          continue;
+        } else if (!kill->Contains(expr_id)) {
+          // This is an exposed load: it is the first representative of a
+          // given expression id and it is not killed on the path from
+          // the block entry.
+          if (exposed_values == NULL) {
+            static const intptr_t kMaxExposedValuesInitialSize = 5;
+            exposed_values = new ZoneGrowableArray<Definition*>(
+                Utils::Minimum(kMaxExposedValuesInitialSize, max_expr_id_));
+          }
+
+          exposed_values->Add(defn);
+        }
+
+        gen->Add(expr_id);
+
+        if (out_values == NULL) out_values = CreateBlockOutValues();
+        (*out_values)[expr_id] = defn;
       }
 
-      // Compute block_in as the intersection of all out(p) where p
-      // is a predecessor of the current block.
-      if (block->IsGraphEntry()) {
-        temp->Clear();
-      } else {
-        temp->SetAll();
-        ASSERT(block->PredecessorCount() > 0);
-        for (intptr_t i = 0; i < block->PredecessorCount(); i++) {
-          BlockEntryInstr* pred = block->PredecessorAt(i);
-          BitVector* pred_out = avail_out[pred->preorder_number()];
-          temp->Intersect(*pred_out);
+      out_[preorder_number]->CopyFrom(gen);
+      exposed_values_[preorder_number] = exposed_values;
+      out_values_[preorder_number] = out_values;
+    }
+  }
+
+  // Compute OUT sets and corresponding out_values mappings by propagating them
+  // iteratively until fix point is reached.
+  // No replacement is done at this point and thus any out_value[expr_id] is
+  // changed at most once: from NULL to an actual value.
+  // When merging incoming loads we might need to create a phi.
+  // These phis are not inserted at the graph immediately because some of them
+  // might become redundant after load forwarding is done.
+  void ComputeOutValues() {
+    BitVector* temp = new BitVector(max_expr_id_);
+
+    bool changed = true;
+    while (changed) {
+      changed = false;
+
+      for (BlockIterator block_it = graph_->reverse_postorder_iterator();
+           !block_it.Done();
+           block_it.Advance()) {
+        BlockEntryInstr* block = block_it.Current();
+
+        const intptr_t preorder_number = block->preorder_number();
+
+        BitVector* block_in = in_[preorder_number];
+        BitVector* block_out = out_[preorder_number];
+        BitVector* block_kill = kill_[preorder_number];
+        BitVector* block_gen = gen_[preorder_number];
+
+        if (FLAG_trace_optimization) {
+          OS::Print("B%"Pd"", block->block_id());
+          block_in->Print();
+          block_out->Print();
+          block_kill->Print();
+          block_gen->Print();
+          OS::Print("\n");
+        }
+
+        ZoneGrowableArray<Definition*>* block_out_values =
+            out_values_[preorder_number];
+
+        // Compute block_in as the intersection of all out(p) where p
+        // is a predecessor of the current block.
+        if (block->IsGraphEntry()) {
+          temp->Clear();
+        } else {
+          // TODO(vegorov): this can be optimized for the case of a single
+          // predecessor.
+          // TODO(vegorov): this can be reordered to reduce amount of operations
+          // temp->CopyFrom(first_predecessor)
+          temp->SetAll();
+          ASSERT(block->PredecessorCount() > 0);
+          for (intptr_t i = 0; i < block->PredecessorCount(); i++) {
+            BlockEntryInstr* pred = block->PredecessorAt(i);
+            BitVector* pred_out = out_[pred->preorder_number()];
+            temp->Intersect(*pred_out);
+          }
+        }
+
+        if (!temp->Equals(*block_in)) {
+          // If IN set has changed propagate the change to OUT set.
+          block_in->CopyFrom(temp);
+          if (block_out->KillAndAdd(block_kill, block_in)) {
+            // If OUT set has changed then we have new values available out of
+            // the block. Compute these values creating phi where necessary.
+            for (BitVector::Iterator it(block_out);
+                 !it.Done();
+                 it.Advance()) {
+              const intptr_t expr_id = it.Current();
+
+              if (block_out_values == NULL) {
+                out_values_[preorder_number] = block_out_values =
+                    CreateBlockOutValues();
+              }
+
+              if ((*block_out_values)[expr_id] == NULL) {
+                ASSERT(block->PredecessorCount() > 0);
+                (*block_out_values)[expr_id] =
+                    MergeIncomingValues(block, expr_id);
+              }
+            }
+            changed = true;
+          }
+        }
+
+        if (FLAG_trace_optimization) {
+          OS::Print("after B%"Pd"", block->block_id());
+          block_in->Print();
+          block_out->Print();
+          block_kill->Print();
+          block_gen->Print();
+          OS::Print("\n");
         }
       }
-      if (!temp->Equals(*block_in)) {
-        block_in->CopyFrom(temp);
-        if (block_out->KillAndAdd(block_kill, block_gen)) changed = true;
+    }
+  }
+
+  // Compute incoming value for the given expression id.
+  // Will create a phi if different values are incoming from multiple
+  // predecessors.
+  Definition* MergeIncomingValues(BlockEntryInstr* block, intptr_t expr_id) {
+    // First check if the same value is coming in from all predecessors.
+    Definition* incoming = NULL;
+    for (intptr_t i = 0; i < block->PredecessorCount(); i++) {
+      BlockEntryInstr* pred = block->PredecessorAt(i);
+      ZoneGrowableArray<Definition*>* pred_out_values =
+          out_values_[pred->preorder_number()];
+      if (incoming == NULL) {
+        incoming = (*pred_out_values)[expr_id];
+      } else if (incoming != (*pred_out_values)[expr_id]) {
+        incoming = NULL;
+        break;
       }
     }
-  }
-}
 
-
-static bool OptimizeLoads(
-    BlockEntryInstr* block,
-    GrowableArray<Definition*>* definitions,
-    const GrowableArray<BitVector*>& avail_in,
-    const GrowableArray<BitVector*>& kill_by_offs) {
-  // TODO(fschneider): Factor out code shared with the existing CSE pass.
-
-  // Delete loads that are killed (not available) at the entry.
-  intptr_t pre_num = block->preorder_number();
-  ASSERT(avail_in[pre_num]->length() == definitions->length());
-  for (intptr_t i = 0; i < avail_in[pre_num]->length(); i++) {
-    if (!avail_in[pre_num]->Contains(i)) {
-      (*definitions)[i] = NULL;
+    if (incoming != NULL) {
+      return incoming;
     }
+
+    // Incoming values are different. Phi is required to merge.
+    PhiInstr* phi = new PhiInstr(
+        block->AsJoinEntry(), block->PredecessorCount());
+
+    for (intptr_t i = 0; i < block->PredecessorCount(); i++) {
+      BlockEntryInstr* pred = block->PredecessorAt(i);
+      ZoneGrowableArray<Definition*>* pred_out_values =
+          out_values_[pred->preorder_number()];
+      ASSERT((*pred_out_values)[expr_id] != NULL);
+
+      // Sets of outgoing values are not linked into use lists so
+      // they might contain values that were replaced and removed
+      // from the graph by this iteration.
+      // To prevent using them we additionally mark definitions themselves
+      // as replaced and store a pointer to the replacement.
+      Value* input = new Value((*pred_out_values)[expr_id]->Replacement());
+      phi->SetInputAt(i, input);
+
+      // TODO(vegorov): add a helper function to handle input insertion.
+      input->set_instruction(phi);
+      input->set_use_index(i);
+      input->AddToInputUseList();
+    }
+
+    phi->set_ssa_temp_index(graph_->alloc_ssa_temp_index());
+    phis_.Add(phi);  // Postpone phi insertion until after load forwarding.
+
+    return phi;
   }
 
-  bool changed = false;
-  for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
-    Instruction* instr = it.Current();
+  // Iterate over basic blocks and replace exposed loads with incoming
+  // values.
+  void ForwardLoads() {
+    for (BlockIterator block_it = graph_->reverse_postorder_iterator();
+         !block_it.Done();
+         block_it.Advance()) {
+      BlockEntryInstr* block = block_it.Current();
 
-    intptr_t offset_in_words = 0;
-    if (IsInterferingStore(instr, &offset_in_words)) {
-      if ((offset_in_words < kill_by_offs.length()) &&
-          (kill_by_offs[offset_in_words] != NULL)) {
-        for (BitVector::Iterator it(kill_by_offs[offset_in_words]);
-             !it.Done();
-             it.Advance()) {
-          (*definitions)[it.Current()] = NULL;
+      ZoneGrowableArray<Definition*>* loads =
+          exposed_values_[block->preorder_number()];
+      if (loads == NULL) continue;  // No exposed loads.
+
+      BitVector* in = in_[block->preorder_number()];
+
+      for (intptr_t i = 0; i < loads->length(); i++) {
+        Definition* load = (*loads)[i];
+        if (!in->Contains(load->expr_id())) continue;  // No incoming value.
+
+        Definition* replacement = MergeIncomingValues(block, load->expr_id());
+
+        // Sets of outgoing values are not linked into use lists so
+        // they might contain values that were replace and removed
+        // from the graph by this iteration.
+        // To prevent using them we additionally mark definitions themselves
+        // as replaced and store a pointer to the replacement.
+        replacement = replacement->Replacement();
+
+        if (load != replacement) {
+          EnsureSSATempIndex(graph_, load, replacement);
+
+          if (FLAG_trace_optimization) {
+            OS::Print("Replacing load v%"Pd" with v%"Pd"\n",
+                      load->ssa_temp_index(),
+                      replacement->ssa_temp_index());
+          }
+
+          load->ReplaceUsesWith(replacement);
+          load->RemoveFromGraph();
+          load->SetReplacement(replacement);
         }
       }
-      ASSERT(instr->IsDefinition() &&
-             !IsLoadEliminationCandidate(instr->AsDefinition()));
-      continue;
-    } else if (instr->HasSideEffect()) {
-      // Handle local side effects by clearing current definitions.
-      for (intptr_t i = 0; i < definitions->length(); i++) {
-        (*definitions)[i] = NULL;
-      }
-      continue;
-    }
-    Definition* defn = instr->AsDefinition();
-    if ((defn == NULL) || !IsLoadEliminationCandidate(defn)) {
-      continue;
-    }
-    Definition* result = (*definitions)[defn->expr_id()];
-    if (result == NULL) {
-      (*definitions)[defn->expr_id()] = defn;
-      continue;
-    }
-
-    // Replace current with lookup result.
-    defn->ReplaceUsesWith(result);
-    it.RemoveCurrentFromGraph();
-    changed = true;
-    if (FLAG_trace_optimization) {
-      OS::Print("Replacing load v%"Pd" with v%"Pd"\n",
-                defn->ssa_temp_index(),
-                result->ssa_temp_index());
     }
   }
 
-  // Process children in the dominator tree recursively.
-  intptr_t num_children = block->dominated_blocks().length();
-  for (intptr_t i = 0; i < num_children; ++i) {
-    BlockEntryInstr* child = block->dominated_blocks()[i];
-    if (i  < num_children - 1) {
-      GrowableArray<Definition*> child_defs(definitions->length());
-      child_defs.AddArray(*definitions);
-      changed = OptimizeLoads(child, &child_defs, avail_in, kill_by_offs) ||
-                changed;
+  // Check if the given phi take the same value on all code paths.
+  // Eliminate it as redundant if this is the case.
+  // When analyzing phi operands assumes that only generated during
+  // this load phase can be redundant. They can be distinguished because
+  // they are not marked alive.
+  // TODO(vegorov): move this into a separate phase over all phis.
+  bool EliminateRedundantPhi(PhiInstr* phi) {
+    Definition* value = NULL;  // Possible value of this phi.
+
+    worklist_.Clear();
+    if (in_worklist_ == NULL) {
+      in_worklist_ = new BitVector(graph_->current_ssa_temp_index());
     } else {
-      changed = OptimizeLoads(child, definitions, avail_in, kill_by_offs) ||
-                changed;
+      in_worklist_->Clear();
+    }
+
+    worklist_.Add(phi);
+    in_worklist_->Add(phi->ssa_temp_index());
+
+    for (intptr_t i = 0; i < worklist_.length(); i++) {
+      PhiInstr* phi = worklist_[i];
+
+      for (intptr_t i = 0; i < phi->InputCount(); i++) {
+        Definition* input = phi->InputAt(i)->definition();
+        if (input == phi) continue;
+
+        PhiInstr* phi_input = input->AsPhi();
+        if ((phi_input != NULL) && !phi_input->is_alive()) {
+          if (!in_worklist_->Contains(phi_input->ssa_temp_index())) {
+            worklist_.Add(phi_input);
+            in_worklist_->Add(phi_input->ssa_temp_index());
+          }
+          continue;
+        }
+
+        if (value == NULL) {
+          value = input;
+        } else if (value != input) {
+          return false;  // This phi is not redundant.
+        }
+      }
+    }
+
+    // All phis in the worklist are redundant and have the same computed
+    // value on all code paths.
+    ASSERT(value != NULL);
+    for (intptr_t i = 0; i < worklist_.length(); i++) {
+      worklist_[i]->ReplaceUsesWith(value);
+    }
+
+    return true;
+  }
+
+  // Emit non-redundant phis created during ComputeOutValues and ForwardLoads.
+  void EmitPhis() {
+    for (intptr_t i = 0; i < phis_.length(); i++) {
+      PhiInstr* phi = phis_[i];
+      if ((phi->input_use_list() != NULL) && !EliminateRedundantPhi(phi)) {
+        phi->mark_alive();
+        phi->block()->InsertPhi(phi);
+      }
     }
   }
-  return changed;
-}
+
+  ZoneGrowableArray<Definition*>* CreateBlockOutValues() {
+    ZoneGrowableArray<Definition*>* out =
+        new ZoneGrowableArray<Definition*>(max_expr_id_);
+    for (intptr_t i = 0; i < max_expr_id_; i++) {
+      out->Add(NULL);
+    }
+    return out;
+  }
+
+  FlowGraph* graph_;
+  DirectChainedHashMap<LoadKeyValueTrait>* map_;
+  const intptr_t max_expr_id_;
+
+  // Mapping between field offsets in words and expression ids of loads from
+  // that offset.
+  const GrowableArray<BitVector*>& kill_by_offset_;
+
+  // Per block sets of expression ids for loads that are: incoming (available
+  // on the entry), outgoing (available on the exit), generated and killed.
+  GrowableArray<BitVector*> in_;
+  GrowableArray<BitVector*> out_;
+  GrowableArray<BitVector*> gen_;
+  GrowableArray<BitVector*> kill_;
+
+  // Per block list of upwards exposed loads.
+  GrowableArray<ZoneGrowableArray<Definition*>*> exposed_values_;
+
+  // Per block mappings between expression ids and outgoing definitions that
+  // represent those ids.
+  GrowableArray<ZoneGrowableArray<Definition*>*> out_values_;
+
+  // List of phis generated during ComputeOutValues and ForwardLoads.
+  // Some of these phis might be redundant and thus a separate pass is
+  // needed to emit only non-redundant ones.
+  GrowableArray<PhiInstr*> phis_;
+
+  // Auxiliary worklist used by redundant phi elimination.
+  GrowableArray<PhiInstr*> worklist_;
+  BitVector* in_worklist_;
+
+  DISALLOW_COPY_AND_ASSIGN(LoadOptimizer);
+};
 
 
 bool DominatorBasedCSE::Optimize(FlowGraph* graph) {
   bool changed = false;
   if (FLAG_load_cse) {
     GrowableArray<BitVector*> kill_by_offs(10);
-    intptr_t max_expr_id = NumberLoadExpressions(graph, &kill_by_offs);
+    DirectChainedHashMap<LoadKeyValueTrait> map;
+    const intptr_t max_expr_id =
+        NumberLoadExpressions(graph, &map, &kill_by_offs);
     if (max_expr_id > 0) {
-      intptr_t num_blocks = graph->preorder().length();
-      GrowableArray<BitVector*> avail_in(num_blocks);
-      for (intptr_t i = 0; i < num_blocks; i++) {
-        avail_in.Add(new BitVector(max_expr_id));
-      }
-
-      ComputeAvailableLoads(graph, max_expr_id, avail_in, kill_by_offs);
-
-      GrowableArray<Definition*> definitions(max_expr_id);
-      for (intptr_t j = 0; j < max_expr_id ; j++) {
-        definitions.Add(NULL);
-      }
-      changed = OptimizeLoads(
-          graph->graph_entry(), &definitions, avail_in, kill_by_offs);
+      LoadOptimizer load_optimizer(graph, max_expr_id, &map, kill_by_offs);
+      load_optimizer.Optimize();
     }
   }
 
   DirectChainedHashMap<PointerKeyValueTrait<Instruction> > map;
-  changed = OptimizeRecursive(graph->graph_entry(), &map) || changed;
+  changed = OptimizeRecursive(graph, graph->graph_entry(), &map) || changed;
 
   return changed;
 }
 
 
 bool DominatorBasedCSE::OptimizeRecursive(
+    FlowGraph* graph,
     BlockEntryInstr* block,
     DirectChainedHashMap<PointerKeyValueTrait<Instruction> >* map) {
   bool changed = false;
@@ -3099,7 +3561,7 @@
       continue;
     }
     // Replace current with lookup result.
-    ReplaceCurrentInstruction(&it, current, replacement);
+    ReplaceCurrentInstruction(&it, current, replacement, graph);
     changed = true;
   }
 
@@ -3110,10 +3572,10 @@
     if (i  < num_children - 1) {
       // Copy map.
       DirectChainedHashMap<PointerKeyValueTrait<Instruction> > child_map(*map);
-      changed = OptimizeRecursive(child, &child_map) || changed;
+      changed = OptimizeRecursive(graph, child, &child_map) || changed;
     } else {
       // Reuse map for the last child.
-      changed = OptimizeRecursive(child, map) || changed;
+      changed = OptimizeRecursive(graph, child, map) || changed;
     }
   }
   return changed;
@@ -3125,8 +3587,8 @@
     const GrowableArray<BlockEntryInstr*>& ignored)
     : FlowGraphVisitor(ignored),
       graph_(graph),
-      unknown_(Object::ZoneHandle(Object::transition_sentinel())),
-      non_constant_(Object::ZoneHandle(Object::sentinel())),
+      unknown_(Object::transition_sentinel()),
+      non_constant_(Object::sentinel()),
       reachable_(new BitVector(graph->preorder().length())),
       definition_marks_(new BitVector(graph->max_virtual_register_number())),
       block_worklist_(),
@@ -3271,7 +3733,7 @@
     if (IsNonConstant(value)) {
       SetReachable(instr->true_successor());
       SetReachable(instr->false_successor());
-    } else if (value.raw() == Bool::True()) {
+    } else if (value.raw() == Bool::True().raw()) {
       SetReachable(instr->true_successor());
     } else if (!IsUnknown(value)) {  // Any other constant.
       SetReachable(instr->false_successor());
@@ -3417,14 +3879,32 @@
       bool result = left.IsNull() ? (instr->right()->ResultCid() == kNullCid)
                                   : (instr->left()->ResultCid() == kNullCid);
       if (instr->kind() == Token::kNE_STRICT) result = !result;
-      SetValue(instr, Bool::ZoneHandle(Bool::Get(result)));
+      SetValue(instr, result ? Bool::True() : Bool::False());
     } else {
       SetValue(instr, non_constant_);
     }
   } else if (IsConstant(left) && IsConstant(right)) {
     bool result = (left.raw() == right.raw());
     if (instr->kind() == Token::kNE_STRICT) result = !result;
-    SetValue(instr, Bool::ZoneHandle(Bool::Get(result)));
+    SetValue(instr, result ? Bool::True() : Bool::False());
+  }
+}
+
+
+static bool CompareIntegers(Token::Kind kind,
+                            const Integer& left,
+                            const Integer& right) {
+  const int result = left.CompareWith(right);
+  switch (kind) {
+    case Token::kEQ: return (result == 0);
+    case Token::kNE: return (result != 0);
+    case Token::kLT: return (result < 0);
+    case Token::kGT: return (result > 0);
+    case Token::kLTE: return (result <= 0);
+    case Token::kGTE: return (result >= 0);
+    default:
+      UNREACHABLE();
+      return false;
   }
 }
 
@@ -3435,8 +3915,14 @@
   if (IsNonConstant(left) || IsNonConstant(right)) {
     SetValue(instr, non_constant_);
   } else if (IsConstant(left) && IsConstant(right)) {
-    // TODO(kmillikin): Handle equality comparison of constants.
-    SetValue(instr, non_constant_);
+    if (left.IsInteger() && right.IsInteger()) {
+      const bool result = CompareIntegers(instr->kind(),
+                                          Integer::Cast(left),
+                                          Integer::Cast(right));
+      SetValue(instr, result ? Bool::True() : Bool::False());
+    } else {
+      SetValue(instr, non_constant_);
+    }
   }
 }
 
@@ -3447,8 +3933,14 @@
   if (IsNonConstant(left) || IsNonConstant(right)) {
     SetValue(instr, non_constant_);
   } else if (IsConstant(left) && IsConstant(right)) {
-    // TODO(kmillikin): Handle relational comparison of constants.
-    SetValue(instr, non_constant_);
+    if (left.IsInteger() && right.IsInteger()) {
+      const bool result = CompareIntegers(instr->kind(),
+                                          Integer::Cast(left),
+                                          Integer::Cast(right));
+      SetValue(instr, result ? Bool::True() : Bool::False());
+    } else {
+      SetValue(instr, non_constant_);
+    }
   }
 }
 
@@ -3500,7 +3992,8 @@
   if (IsNonConstant(value)) {
     SetValue(instr, non_constant_);
   } else if (IsConstant(value)) {
-    SetValue(instr, Bool::ZoneHandle(Bool::Get(value.raw() != Bool::True())));
+    bool val = value.raw() != Bool::True().raw();
+    SetValue(instr, val ? Bool::True() : Bool::False());
   }
 }
 
@@ -3539,7 +4032,15 @@
 
 
 void ConstantPropagator::VisitLoadField(LoadFieldInstr* instr) {
-  SetValue(instr, non_constant_);
+  if ((instr->recognized_kind() == MethodRecognizer::kObjectArrayLength) &&
+      (instr->value()->definition()->IsCreateArray())) {
+    const intptr_t length =
+        instr->value()->definition()->AsCreateArray()->ArgumentCount();
+    const Object& result = Smi::ZoneHandle(Smi::New(length));
+    SetValue(instr, result);
+  } else {
+    SetValue(instr, non_constant_);
+  }
 }
 
 
@@ -3700,6 +4201,12 @@
 }
 
 
+void ConstantPropagator::VisitDoubleToSmi(DoubleToSmiInstr* instr) {
+  // TODO(kmillikin): Handle conversion.
+  SetValue(instr, non_constant_);
+}
+
+
 void ConstantPropagator::VisitConstant(ConstantInstr* instr) {
   SetValue(instr, instr->value());
 }
@@ -3874,7 +4381,6 @@
 
       if (!reachable_->Contains(if_true->preorder_number())) {
         ASSERT(reachable_->Contains(if_false->preorder_number()));
-        ASSERT(branch->comparison()->IsStrictCompare());
         ASSERT(if_false->parallel_move() == NULL);
         ASSERT(if_false->loop_info() == NULL);
         join = new JoinEntryInstr(if_false->block_id(),
@@ -3882,7 +4388,6 @@
                                   if_false->loop_depth());
         next = if_false->next();
       } else if (!reachable_->Contains(if_false->preorder_number())) {
-        ASSERT(branch->comparison()->IsStrictCompare());
         ASSERT(if_true->parallel_move() == NULL);
         ASSERT(if_true->loop_info() == NULL);
         join = new JoinEntryInstr(if_true->block_id(),
diff --git a/runtime/vm/flow_graph_optimizer.h b/runtime/vm/flow_graph_optimizer.h
index e2c9cd1..f85d9e1 100644
--- a/runtime/vm/flow_graph_optimizer.h
+++ b/runtime/vm/flow_graph_optimizer.h
@@ -68,6 +68,7 @@
                                const ICData& unary_ic_data);
 
   bool TryInlineInstanceMethod(InstanceCallInstr* call);
+  void ReplaceWithInstanceOf(InstanceCallInstr* instr);
 
   StringCharCodeAtInstr* BuildStringCharCodeAt(InstanceCallInstr* call,
                                                intptr_t cid);
@@ -95,10 +96,14 @@
                                intptr_t length_offset,
                                bool is_immutable,
                                MethodRecognizer::Kind kind);
-  void InlineGArrayCapacityGetter(InstanceCallInstr* call);
+  void InlineGrowableArrayCapacityGetter(InstanceCallInstr* call);
   void InlineStringLengthGetter(InstanceCallInstr* call);
   void InlineStringIsEmptyGetter(InstanceCallInstr* call);
 
+  RawBool* InstanceOfAsBool(const ICData& ic_data,
+                            const AbstractType& type) const;
+
+
   FlowGraph* flow_graph_;
 
   DISALLOW_COPY_AND_ASSIGN(FlowGraphOptimizer);
@@ -168,6 +173,7 @@
 
  private:
   static bool OptimizeRecursive(
+      FlowGraph* graph,
       BlockEntryInstr* entry,
       DirectChainedHashMap<PointerKeyValueTrait<Instruction> >* map);
 };
@@ -183,7 +189,7 @@
   static void Optimize(FlowGraph* graph);
 
   // Used to initialize the abstract value of definitions.
-  static RawObject* Unknown() { return Object::transition_sentinel(); }
+  static RawObject* Unknown() { return Object::transition_sentinel().raw(); }
 
  private:
   void Analyze();
diff --git a/runtime/vm/freelist.cc b/runtime/vm/freelist.cc
index dc71f0e..ee3d9f9 100644
--- a/runtime/vm/freelist.cc
+++ b/runtime/vm/freelist.cc
@@ -4,6 +4,9 @@
 
 #include "vm/freelist.h"
 
+#include <map>
+#include <utility>
+
 #include "vm/bit_set.h"
 #include "vm/object.h"
 #include "vm/raw_object.h"
@@ -147,26 +150,66 @@
 }
 
 
-void FreeList::Print() const {
-  OS::Print("%*s %*s %*s\n", 10, "Class", 10, "Length", 10, "Size");
-  OS::Print("--------------------------------\n");
-  int total_index = 0;
-  int total_length = 0;
-  int total_size = 0;
+void FreeList::PrintSmall() const {
+  int small_sizes = 0;
+  int small_objects = 0;
+  intptr_t small_bytes = 0;
   for (int i = 0; i < kNumLists; ++i) {
     if (free_lists_[i] == NULL) {
       continue;
     }
-    total_index += 1;
-    intptr_t length = Length(i);
-    total_length += length;
-    intptr_t size = length * i * kObjectAlignment;
-    total_size += size;
-    OS::Print("%*d %*"Pd" %*"Pd"\n",
-              10, i * kObjectAlignment, 10, length, 10, size);
+    small_sizes += 1;
+    intptr_t list_length = Length(i);
+    small_objects += list_length;
+    intptr_t list_bytes = list_length * i * kObjectAlignment;
+    small_bytes += list_bytes;
+    OS::Print("small %3d [%8d bytes] : "
+              "%8"Pd" objs; %8.1f KB; %8.1f cum KB\n",
+              i,
+              i * kObjectAlignment,
+              list_length,
+              list_bytes / static_cast<double>(KB),
+              small_bytes / static_cast<double>(KB));
   }
-  OS::Print("--------------------------------\n");
-  OS::Print("%*d %*d %*d\n", 10, total_index, 10, total_length, 10, total_size);
+}
+
+
+void FreeList::PrintLarge() const {
+  int large_sizes = 0;
+  int large_objects = 0;
+  intptr_t large_bytes = 0;
+  std::map<intptr_t, intptr_t> sorted;
+  std::map<intptr_t, intptr_t>::iterator it;
+  FreeListElement* node;
+  for (node = free_lists_[kNumLists]; node != NULL; node = node->next()) {
+    it = sorted.find(node->Size());
+    if (it != sorted.end()) {
+      it->second += 1;
+    } else {
+      large_sizes += 1;
+      sorted.insert(std::make_pair(node->Size(), 1));
+    }
+    large_objects += 1;
+  }
+  for (it = sorted.begin(); it != sorted.end(); ++it) {
+    intptr_t size = it->first;
+    intptr_t list_length = it->second;
+    intptr_t list_bytes = list_length * size;
+    large_bytes += list_bytes;
+    OS::Print("large %3"Pd" [%8"Pd" bytes] : "
+              "%8"Pd" objs; %8.1f KB; %8.1f cum KB\n",
+              size / kObjectAlignment,
+              size,
+              list_length,
+              list_bytes / static_cast<double>(KB),
+              large_bytes / static_cast<double>(KB));
+  }
+}
+
+
+void FreeList::Print() const {
+  PrintSmall();
+  PrintLarge();
 }
 
 
diff --git a/runtime/vm/freelist.h b/runtime/vm/freelist.h
index 648a7f6..072348a 100644
--- a/runtime/vm/freelist.h
+++ b/runtime/vm/freelist.h
@@ -93,6 +93,9 @@
 
   void SplitElementAfterAndEnqueue(FreeListElement* element, intptr_t size);
 
+  void PrintSmall() const;
+  void PrintLarge() const;
+
   BitSet<kNumLists> free_map_;
 
   FreeListElement* free_lists_[kNumLists + 1];
diff --git a/runtime/vm/gc_sweeper.cc b/runtime/vm/gc_sweeper.cc
index 7f1cf8b..d87ea64 100644
--- a/runtime/vm/gc_sweeper.cc
+++ b/runtime/vm/gc_sweeper.cc
@@ -6,6 +6,8 @@
 
 #include "vm/freelist.h"
 #include "vm/globals.h"
+#include "vm/heap.h"
+#include "vm/heap_trace.h"
 #include "vm/pages.h"
 
 namespace dart {
@@ -28,7 +30,7 @@
 
   while (current < end) {
     intptr_t obj_size;
-    if (in_use_swept == in_use) {
+    if (in_use_swept == in_use && !HeapTrace::is_enabled()) {
       // No more marked objects will be found on this page.
       obj_size = end - current;
       freelist->Free(current, obj_size);
@@ -42,12 +44,18 @@
       in_use_swept += obj_size;
     } else {
       uword free_end = current + raw_obj->Size();
+      if (HeapTrace::is_enabled()) {
+        heap_->trace()->TraceSweep(current);
+      }
       while (free_end < end) {
         RawObject* next_obj = RawObject::FromAddr(free_end);
         if (next_obj->IsMarked()) {
           // Reached the end of the free block.
           break;
         }
+        if (HeapTrace::is_enabled()) {
+          heap_->trace()->TraceSweep(free_end);
+        }
         // Expand the free block by the size of this object.
         free_end += next_obj->Size();
       }
@@ -67,6 +75,9 @@
 intptr_t GCSweeper::SweepLargePage(HeapPage* page) {
   RawObject* raw_obj = RawObject::FromAddr(page->object_start());
   if (!raw_obj->IsMarked()) {
+    if (HeapTrace::is_enabled()) {
+      heap_->trace()->TraceSweep(page->object_start());
+    }
     // The large object was not marked. Used size is zero, which also tells the
     // calling code that the large object page can be recycled.
     return 0;
diff --git a/runtime/vm/handles.h b/runtime/vm/handles.h
index a4fe592..a658cdb 100644
--- a/runtime/vm/handles.h
+++ b/runtime/vm/handles.h
@@ -75,7 +75,8 @@
   Handles()
       : zone_blocks_(NULL),
         first_scoped_block_(NULL),
-        scoped_blocks_(&first_scoped_block_) {
+        scoped_blocks_(&first_scoped_block_),
+        last_visited_block_(NULL) {
   }
   ~Handles() {
     DeleteAll();
@@ -84,6 +85,16 @@
   // Visit all object pointers stored in the various handles.
   void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
+  // Visit all the scoped handles.
+  void VisitScopedHandles(ObjectPointerVisitor* visitor);
+
+  // Visit all blocks that have been added since the last time
+  // this method was called.
+  // Be careful with this, since multiple users of this method could
+  // interfere with eachother.
+  // Currently only used by GC trace facility.
+  void VisitUnvisitedScopedHandles(ObjectPointerVisitor* visitor);
+
   // Visit all of the various handles.
   void Visit(HandleVisitor* visitor);
 
@@ -126,7 +137,8 @@
   class HandlesBlock {
    public:
     explicit HandlesBlock(HandlesBlock* next)
-        : next_handle_slot_(0),
+        : last_visited_handle_(0),
+          next_handle_slot_(0),
           next_block_(next) { }
     ~HandlesBlock();
 
@@ -156,6 +168,10 @@
     // Visit all object pointers in the handle block.
     void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
+    // Visit all the object pointers in the block since the last time this
+    // method was called.
+    void VisitUnvisitedObjectPointers(ObjectPointerVisitor* visitor);
+
     // Visit all of the handles in the handle block.
     void Visit(HandleVisitor* visitor);
 
@@ -176,6 +192,10 @@
     void set_next_block(HandlesBlock* next) { next_block_ = next; }
 
    private:
+    // Last handle visited by VisitUnvisitedObjectPointers.  Handles
+    // at, or beyond this index are new.
+    intptr_t last_visited_handle_;
+
     uword data_[kHandleSizeInWords * kHandlesPerChunk];  // Handles area.
     intptr_t next_handle_slot_;  // Next slot for allocation in current block.
     HandlesBlock* next_block_;  // Link to next block of handles.
@@ -212,9 +232,12 @@
   HandlesBlock* zone_blocks_;  // List of zone handles.
   HandlesBlock first_scoped_block_;  // First block of scoped handles.
   HandlesBlock* scoped_blocks_;  // List of scoped handles.
+  // Last block visited by VisitUnvisitedHandles.
+  HandlesBlock* last_visited_block_;
 
   friend class HandleScope;
-  friend class Symbols;
+  friend class Dart;
+  friend class ObjectStore;
   DISALLOW_ALLOCATION();
   DISALLOW_COPY_AND_ASSIGN(Handles);
 };
diff --git a/runtime/vm/handles_impl.h b/runtime/vm/handles_impl.h
index 327c28b..06e3aca 100644
--- a/runtime/vm/handles_impl.h
+++ b/runtime/vm/handles_impl.h
@@ -5,6 +5,8 @@
 #ifndef VM_HANDLES_IMPL_H_
 #define VM_HANDLES_IMPL_H_
 
+#include "vm/heap.h"
+#include "vm/heap_trace.h"
 #include "vm/visitor.h"
 
 namespace dart {
@@ -24,7 +26,16 @@
   }
 
   // Visit all scoped handles.
-  block = &first_scoped_block_;
+  VisitScopedHandles(visitor);
+}
+
+
+template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
+void Handles<kHandleSizeInWords,
+             kHandlesPerChunk,
+             kOffsetOfRawPtr>::VisitScopedHandles(
+    ObjectPointerVisitor* visitor) {
+  HandlesBlock* block = &first_scoped_block_;
   do {
     block->VisitObjectPointers(visitor);
     block = block->next_block();
@@ -35,6 +46,23 @@
 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
 void Handles<kHandleSizeInWords,
              kHandlesPerChunk,
+             kOffsetOfRawPtr>::VisitUnvisitedScopedHandles(
+    ObjectPointerVisitor* visitor) {
+  HandlesBlock* block = &first_scoped_block_;
+  while (block != NULL && block != last_visited_block_) {
+    block->VisitUnvisitedObjectPointers(visitor);
+    block = block->next_block();
+  }
+  // We want this to point to first_scoped_block.next,
+  // Because pointers are still being added to first_scoped_block
+  // So it may be "partially new", and require a partial scan.
+  last_visited_block_ = first_scoped_block_.next_block();
+}
+
+
+template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
+void Handles<kHandleSizeInWords,
+             kHandlesPerChunk,
              kOffsetOfRawPtr>::Visit(HandleVisitor* visitor) {
   // Visit all zone handles.
   HandlesBlock* block = zone_blocks_;
@@ -83,7 +111,12 @@
   ASSERT(isolate->no_handle_scope_depth() == 0);
   Handles* handles = isolate->current_zone()->handles();
   ASSERT(handles != NULL);
-  return handles->AllocateHandleInZone();
+  uword address = handles->AllocateHandleInZone();
+  if (HeapTrace::is_enabled()) {
+    uword zone_addr = reinterpret_cast<uword>(isolate->current_zone());
+    isolate->heap()->trace()->TraceAllocateZoneHandle(address, zone_addr);
+  }
+  return address;
 }
 
 
@@ -109,10 +142,20 @@
              kHandlesPerChunk,
              kOffsetOfRawPtr>::DeleteAll() {
   // Delete all the zone allocated handle blocks.
+  // GCTrace does not need to trace this call to DeleteHandleBlocks,
+  // since the individual zone deletions will be caught
+  // by instrumentation in the BaseZone destructor.
   DeleteHandleBlocks(zone_blocks_);
   zone_blocks_ = NULL;
 
   // Delete all the scoped handle blocks.
+  // Do not trace if there is no  current isolate. This can happen during
+  // isolate shutdown.
+  if (HeapTrace::is_enabled() && Isolate::Current() != NULL) {
+    Isolate::Current()->heap()->trace()->TraceDeleteScopedHandles();
+  }
+
+
   scoped_blocks_ = first_scoped_block_.next_block();
   DeleteHandleBlocks(scoped_blocks_);
   first_scoped_block_.ReInit();
@@ -302,6 +345,24 @@
 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
 void Handles<kHandleSizeInWords,
              kHandlesPerChunk,
+             kOffsetOfRawPtr>::HandlesBlock::VisitUnvisitedObjectPointers(
+                 ObjectPointerVisitor* visitor) {
+  ASSERT(visitor != NULL);
+
+  // last_visited_handle_ picks up where we were last time,
+  // so there is nothing in the intialization position of this for loop.
+
+  while (last_visited_handle_ < next_handle_slot_) {
+    last_visited_handle_ += kHandleSizeInWords;
+    uword* addr = &data_[last_visited_handle_ + kOffsetOfRawPtr / kWordSize];
+    visitor->VisitPointer(reinterpret_cast<RawObject**>(addr));
+  }
+}
+
+
+template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
+void Handles<kHandleSizeInWords,
+             kHandlesPerChunk,
              kOffsetOfRawPtr>::HandlesBlock::Visit(HandleVisitor* visitor) {
   ASSERT(visitor != NULL);
   for (intptr_t i = 0; i < next_handle_slot_; i += kHandleSizeInWords) {
diff --git a/runtime/vm/hash_set.h b/runtime/vm/hash_set.h
index cd00306..4c32c84 100644
--- a/runtime/vm/hash_set.h
+++ b/runtime/vm/hash_set.h
@@ -84,7 +84,7 @@
     return value & size_mask_;
   }
 
-  // Returns true if the given slot contains a value.
+  // Returns true if the given slot does not contain a value.
   bool SlotIsEmpty(intptr_t index) const {
     return keys_[index] == 0;
   }
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index 79c335d..07696d0 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -8,11 +8,13 @@
 #include "platform/utils.h"
 #include "vm/flags.h"
 #include "vm/heap_profiler.h"
+#include "vm/heap_trace.h"
 #include "vm/isolate.h"
 #include "vm/object.h"
 #include "vm/object_set.h"
 #include "vm/os.h"
 #include "vm/pages.h"
+#include "vm/raw_object.h"
 #include "vm/scavenger.h"
 #include "vm/stack_frame.h"
 #include "vm/verifier.h"
@@ -21,6 +23,7 @@
 namespace dart {
 
 DEFINE_FLAG(bool, verbose_gc, false, "Enables verbose GC.");
+DEFINE_FLAG(int, verbose_gc_hdr, 40, "Print verbose GC header interval.");
 DEFINE_FLAG(bool, verify_before_gc, false,
             "Enables heap verification before GC.");
 DEFINE_FLAG(bool, verify_after_gc, false,
@@ -32,11 +35,13 @@
             "old gen heap size in MB,"
             "e.g: --old_gen_heap_size=1024 allocates a 1024MB old gen heap");
 
-Heap::Heap() : read_only_(false) {
+Heap::Heap() : read_only_(false), gc_in_progress_(false) {
   new_space_ = new Scavenger(this,
                              (FLAG_new_gen_heap_size * MB),
                              kNewObjectAlignmentOffset);
   old_space_ = new PageSpace(this, (FLAG_old_gen_heap_size * MB));
+  stats_.num_ = 0;
+  heap_trace_ = new HeapTrace;
 }
 
 
@@ -49,15 +54,17 @@
 uword Heap::AllocateNew(intptr_t size) {
   ASSERT(Isolate::Current()->no_gc_scope_depth() == 0);
   uword addr = new_space_->TryAllocate(size);
-  if (addr != 0) {
-    return addr;
+  if (addr == 0) {
+    CollectGarbage(kNew);
+    addr = new_space_->TryAllocate(size);
+    if (addr == 0) {
+      return AllocateOld(size, HeapPage::kData);
+    }
   }
-  CollectGarbage(kNew);
-  addr = new_space_->TryAllocate(size);
-  if (addr != 0) {
-    return addr;
+  if (HeapTrace::is_enabled()) {
+    heap_trace_->TraceAllocation(addr, size);
   }
-  return AllocateOld(size, HeapPage::kData);
+  return addr;
 }
 
 
@@ -70,8 +77,12 @@
     if (addr == 0) {
       OS::PrintErr("Exhausted heap space, trying to allocate %"Pd" bytes.\n",
                    size);
+      return 0;
     }
   }
+  if (HeapTrace::is_enabled()) {
+    heap_trace_->TraceAllocation(addr, size);
+  }
   return addr;
 }
 
@@ -142,25 +153,27 @@
   bool invoke_api_callbacks = (api_callbacks == kInvokeApiCallbacks);
   switch (space) {
     case kNew: {
-      new_space_->Scavenge(invoke_api_callbacks,
-                           GCReasonToString(kNewSpace));
+      RecordBeforeGC(kNew, kNewSpace);
+      new_space_->Scavenge(invoke_api_callbacks);
+      RecordAfterGC();
+      PrintStats();
       if (new_space_->HadPromotionFailure()) {
-        old_space_->MarkSweep(true,
-                              GCReasonToString(kPromotionFailure));
+        CollectGarbage(kOld, api_callbacks);
       }
       break;
     }
     case kOld:
-    case kCode:
-      old_space_->MarkSweep(invoke_api_callbacks,
-                            GCReasonToString(kOldSpace));
+    case kCode: {
+      bool promotion_failure = new_space_->HadPromotionFailure();
+      RecordBeforeGC(kOld, promotion_failure ? kPromotionFailure : kOldSpace);
+      old_space_->MarkSweep(invoke_api_callbacks);
+      RecordAfterGC();
+      PrintStats();
       break;
+    }
     default:
       UNREACHABLE();
   }
-  if (FLAG_verbose_gc) {
-    PrintSizes();
-  }
 }
 
 
@@ -176,12 +189,14 @@
 
 
 void Heap::CollectAllGarbage() {
-  const char* gc_reason = GCReasonToString(kFull);
-  new_space_->Scavenge(kInvokeApiCallbacks, gc_reason);
-  old_space_->MarkSweep(kInvokeApiCallbacks, gc_reason);
-  if (FLAG_verbose_gc) {
-    PrintSizes();
-  }
+  RecordBeforeGC(kNew, kFull);
+  new_space_->Scavenge(kInvokeApiCallbacks);
+  RecordAfterGC();
+  PrintStats();
+  RecordBeforeGC(kOld, kFull);
+  old_space_->MarkSweep(kInvokeApiCallbacks);
+  RecordAfterGC();
+  PrintStats();
 }
 
 
@@ -314,8 +329,6 @@
       return "promotion failure";
     case kOldSpace:
       return "old space";
-    case kCodeSpace:
-      return "code space";
     case kFull:
       return "full";
     case kGCAtAlloc:
@@ -353,6 +366,100 @@
 }
 
 
+void Heap::RecordBeforeGC(Space space, GCReason reason) {
+  ASSERT(!gc_in_progress_);
+  gc_in_progress_ = true;
+  stats_.num_++;
+  stats_.space_ = space;
+  stats_.reason_ = reason;
+  stats_.before_.micros_ = OS::GetCurrentTimeMicros();
+  stats_.before_.new_used_ = new_space_->in_use();
+  stats_.before_.new_capacity_ = new_space_->capacity();
+  stats_.before_.old_used_ = old_space_->in_use();
+  stats_.before_.old_capacity_ = old_space_->capacity();
+  stats_.times_[0] = 0;
+  stats_.times_[1] = 0;
+  stats_.times_[2] = 0;
+  stats_.times_[3] = 0;
+  stats_.data_[0] = 0;
+  stats_.data_[1] = 0;
+  stats_.data_[2] = 0;
+  stats_.data_[3] = 0;
+}
+
+
+void Heap::RecordAfterGC() {
+  stats_.after_.micros_ = OS::GetCurrentTimeMicros();
+  stats_.after_.new_used_ = new_space_->in_use();
+  stats_.after_.new_capacity_ = new_space_->capacity();
+  stats_.after_.old_used_ = old_space_->in_use();
+  stats_.after_.old_capacity_ = old_space_->capacity();
+  ASSERT(gc_in_progress_);
+  gc_in_progress_ = false;
+}
+
+
+static intptr_t RoundToKB(intptr_t memory_size) {
+  return (memory_size + (KB >> 1)) >> KBLog2;
+}
+
+
+static double RoundToSecs(int64_t micros) {
+  const int k1M = 1000000;  // Converting us to secs.
+  return static_cast<double>(micros + (k1M / 2)) / k1M;
+}
+
+
+static double RoundToMillis(int64_t micros) {
+  const int k1K = 1000;  // Conversting us to ms.
+  return static_cast<double>(micros + (k1K / 2)) / k1K;
+}
+
+
+void Heap::PrintStats() {
+  if (!FLAG_verbose_gc) return;
+  Isolate* isolate = Isolate::Current();
+
+  if ((FLAG_verbose_gc_hdr != 0) &&
+      (((stats_.num_ - 1) % FLAG_verbose_gc_hdr) == 0)) {
+    OS::PrintErr("[    GC    |  space  | count | start | gc time | "
+                 "new gen (KB) | old gen (KB) | timers | data ]\n"
+                 "[ (isolate)| (reason)|       |  (s)  |   (ms)  | "
+                 " used , cap  |  used , cap  |  (ms)  |      ]\n");
+  }
+
+  const char* space_str = stats_.space_ == kNew ? "Scavenge" : "Mark-Sweep";
+  OS::PrintErr(
+    "[ GC(%"Pd64"): %s(%s), "  // GC(isolate), space(reason)
+    "%"Pd", "  // count
+    "%.3f, "  // start time
+    "%.3f, "  // total time
+    "%"Pd", %"Pd", %"Pd", %"Pd", "  // new gen: in use, capacity before/after
+    "%"Pd", %"Pd", %"Pd", %"Pd", "  // old gen: in use, capacity before/after
+    "%.3f, %.3f, %.3f, %.3f, "  // times
+    "%"Pd", %"Pd", %"Pd", %"Pd", "  // data
+    "]\n",  // End with a comma to make it easier to import in spreadsheets.
+    isolate->main_port(), space_str, GCReasonToString(stats_.reason_),
+    stats_.num_,
+    RoundToSecs(stats_.before_.micros_ - isolate->start_time()),
+    RoundToMillis(stats_.after_.micros_ - stats_.before_.micros_),
+    RoundToKB(stats_.before_.new_used_), RoundToKB(stats_.after_.new_used_),
+    RoundToKB(stats_.before_.new_capacity_),
+    RoundToKB(stats_.after_.new_capacity_),
+    RoundToKB(stats_.before_.old_used_), RoundToKB(stats_.after_.old_used_),
+    RoundToKB(stats_.before_.old_capacity_),
+    RoundToKB(stats_.after_.old_capacity_),
+    RoundToMillis(stats_.times_[0]),
+    RoundToMillis(stats_.times_[1]),
+    RoundToMillis(stats_.times_[2]),
+    RoundToMillis(stats_.times_[3]),
+    stats_.data_[0],
+    stats_.data_[1],
+    stats_.data_[2],
+    stats_.data_[3]);
+}
+
+
 #if defined(DEBUG)
 NoGCScope::NoGCScope() : StackResource(Isolate::Current()) {
   isolate()->IncrementNoGCScopeDepth();
diff --git a/runtime/vm/heap.h b/runtime/vm/heap.h
index c466642..00c21a8 100644
--- a/runtime/vm/heap.h
+++ b/runtime/vm/heap.h
@@ -15,6 +15,7 @@
 namespace dart {
 
 // Forward declarations.
+class HeapTrace;
 class Isolate;
 class ObjectPointerVisitor;
 class ObjectSet;
@@ -42,7 +43,6 @@
     kNewSpace,
     kPromotionFailure,
     kOldSpace,
-    kCodeSpace,
     kFull,
     kGCAtAlloc,
     kGCTestCase,
@@ -148,6 +148,10 @@
   // Verify that all pointers in the heap point to the heap.
   bool Verify() const;
 
+  // Accessor function to get the HeapTrace used for tracing.  There
+  // should only ever be one of these per isolate
+  HeapTrace* trace() const { return heap_trace_; }
+
   // Print heap sizes.
   void PrintSizes() const;
 
@@ -173,19 +177,77 @@
   // Returns the number of objects with a peer.
   int64_t PeerCount() const;
 
+  // Stats collection.
+  void RecordTime(int id, int64_t micros) {
+    ASSERT((id >= 0) && (id < GCStats::kDataEntries));
+    stats_.times_[id] = micros;
+  }
+
+  void RecordData(int id, intptr_t value) {
+    ASSERT((id >= 0) && (id < GCStats::kDataEntries));
+    stats_.data_[id] = value;
+  }
+
+  bool gc_in_progress() const { return gc_in_progress_; }
+
  private:
+  class GCStats : public ValueObject {
+   public:
+    GCStats() {}
+    intptr_t num_;
+    Heap::Space space_;
+    Heap::GCReason reason_;
+
+    class Data : public ValueObject {
+    public:
+      Data() {}
+      int64_t micros_;
+      intptr_t new_used_;
+      intptr_t new_capacity_;
+      intptr_t old_used_;
+      intptr_t old_capacity_;
+
+      DISALLOW_COPY_AND_ASSIGN(Data);
+    };
+
+    enum {
+      kDataEntries = 4
+    };
+
+    Data before_;
+    Data after_;
+    int64_t times_[kDataEntries];
+    intptr_t data_[kDataEntries];
+
+    DISALLOW_COPY_AND_ASSIGN(GCStats);
+  };
+
   Heap();
 
   uword AllocateNew(intptr_t size);
   uword AllocateOld(intptr_t size, HeapPage::PageType type);
 
+  // GC stats collection.
+  void RecordBeforeGC(Space space, GCReason reason);
+  void RecordAfterGC();
+  void PrintStats();
+
   // The different spaces used for allocation.
   Scavenger* new_space_;
   PageSpace* old_space_;
 
+  // GC stats collection.
+  GCStats stats_;
+
+  // The active heap trace.
+  HeapTrace* heap_trace_;
+
   // This heap is in read-only mode: No allocation is allowed.
   bool read_only_;
 
+  // GC on the heap is in progress.
+  bool gc_in_progress_;
+
   friend class GCTestHelper;
   DISALLOW_COPY_AND_ASSIGN(Heap);
 };
diff --git a/runtime/vm/heap_trace.cc b/runtime/vm/heap_trace.cc
new file mode 100644
index 0000000..56282c2
--- /dev/null
+++ b/runtime/vm/heap_trace.cc
@@ -0,0 +1,488 @@
+// 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.
+
+#include "vm/heap_trace.h"
+
+#include "include/dart_api.h"
+#include "vm/dart_api_state.h"
+#include "vm/debugger.h"
+#include "vm/isolate.h"
+#include "vm/object.h"
+#include "vm/object_set.h"
+#include "vm/object_store.h"
+#include "vm/os.h"
+#include "vm/stack_frame.h"
+#include "vm/unicode.h"
+
+namespace dart {
+
+DEFINE_FLAG(bool, heap_trace, false, "Enable heap tracing.");
+
+Dart_FileOpenCallback HeapTrace::open_callback_ = NULL;
+Dart_FileWriteCallback HeapTrace::write_callback_ = NULL;
+Dart_FileCloseCallback HeapTrace::close_callback_ = NULL;
+bool HeapTrace::is_enabled_ = false;
+
+class HeapTraceVisitor : public ObjectPointerVisitor {
+ public:
+  HeapTraceVisitor(Isolate* isolate,
+                   HeapTrace* heap_trace,
+                   ObjectSet* object_set)
+      : ObjectPointerVisitor(isolate),
+        heap_trace_(heap_trace),
+        vm_isolate_(Dart::vm_isolate()),
+        object_set_(object_set) {
+  }
+
+  void VisitPointers(RawObject** first, RawObject** last) {
+    for (RawObject** current = first; current <= last; current++) {
+      RawObject* raw_obj = *current;
+
+      // We only care about objects in the heap
+      // Also, since this visitor will frequently be encountering redudant
+      // roots, we use an object_set to skip the duplicates.
+      if (raw_obj->IsHeapObject() &&
+          raw_obj != reinterpret_cast<RawObject*>(0x1) &&
+          raw_obj != reinterpret_cast<RawObject*>(0xabababab) &&
+          !object_set_->Contains(raw_obj) &&
+          !vm_isolate_->heap()->Contains(RawObject::ToAddr(raw_obj))) {
+        object_set_->Add(raw_obj);
+        uword addr = RawObject::ToAddr(raw_obj);
+        heap_trace_->TraceSingleRoot(addr);
+      }
+    }
+  }
+
+ private:
+  HeapTrace* heap_trace_;
+  Isolate* vm_isolate_;
+  // TODO(cshapiro): replace with a sparse data structure.
+  ObjectSet* object_set_;
+  DISALLOW_COPY_AND_ASSIGN(HeapTraceVisitor);
+};
+
+
+class HeapTraceScopedHandleVisitor : public ObjectPointerVisitor {
+ public:
+  HeapTraceScopedHandleVisitor(Isolate* isolate, HeapTrace* heap_trace)
+       : ObjectPointerVisitor(isolate), heap_trace_(heap_trace) {
+  }
+
+  void VisitPointers(RawObject**  first, RawObject** last) {
+    for (RawObject** current = first; current <= last; current++) {
+      RawObject* raw_obj = *current;
+      Heap* heap = isolate()->heap();
+
+      // We only care about objects in the heap
+      if (raw_obj->IsHeapObject() &&
+          raw_obj != reinterpret_cast<RawObject*>(0x1) &&
+          raw_obj != reinterpret_cast<RawObject*>(0xabababab) &&
+          heap->Contains(RawObject::ToAddr(raw_obj))) {
+        uword addr = RawObject::ToAddr(raw_obj);
+        heap_trace_->TraceScopedHandle(addr);
+     }
+    }
+  }
+
+ private:
+  HeapTrace* heap_trace_;
+  DISALLOW_COPY_AND_ASSIGN(HeapTraceScopedHandleVisitor);
+};
+
+
+class HeapTraceObjectStoreVisitor : public ObjectPointerVisitor {
+ public:
+  HeapTraceObjectStoreVisitor(Isolate* isolate, HeapTrace* heap_trace)
+        : ObjectPointerVisitor(isolate), heap_trace_(heap_trace) {
+  }
+
+  void VisitPointers(RawObject** first, RawObject** last) {
+    for (RawObject** current = first; current <= last; current++) {
+      RawObject* raw_obj = *current;
+
+      // We only care about obects in the heap.
+      if (raw_obj->IsHeapObject() &&
+          raw_obj != reinterpret_cast<RawObject*>(0x1) &&
+          raw_obj != reinterpret_cast<RawObject*>(0xabababab)) {
+        uword addr = RawObject::ToAddr(raw_obj);
+        heap_trace_->TraceObjectStorePointer(addr);
+      }
+    }
+  }
+
+ private:
+  HeapTrace* heap_trace_;
+  DISALLOW_COPY_AND_ASSIGN(HeapTraceObjectStoreVisitor);
+};
+
+
+class HeapTraceInitialHeapVisitor : public ObjectVisitor {
+ public:
+  HeapTraceInitialHeapVisitor(Isolate* isolate, HeapTrace* heap_trace)
+    : ObjectVisitor(isolate), heap_trace_(heap_trace) {}
+
+  void VisitObject(RawObject* raw_obj) {
+    heap_trace_->TraceSnapshotAlloc(raw_obj, raw_obj->Size());
+  }
+
+ private:
+  HeapTrace* heap_trace_;
+  DISALLOW_COPY_AND_ASSIGN(HeapTraceInitialHeapVisitor);
+};
+
+
+HeapTrace::HeapTrace() : isolate_initialized_(false), output_stream_(NULL) {
+}
+
+
+HeapTrace::~HeapTrace() {
+  if (isolate_initialized_) {
+    (*close_callback_)(output_stream_);
+  }
+}
+
+
+void HeapTrace::InitOnce(Dart_FileOpenCallback open_callback,
+                         Dart_FileWriteCallback write_callback,
+                         Dart_FileCloseCallback close_callback) {
+  ASSERT(open_callback != NULL);
+  ASSERT(write_callback != NULL);
+  ASSERT(close_callback != NULL);
+  HeapTrace::open_callback_ = open_callback;
+  HeapTrace::write_callback_ = write_callback;
+  HeapTrace::close_callback_ = close_callback;
+  HeapTrace::is_enabled_ = true;
+}
+
+
+ObjectSet* HeapTrace::CreateEmptyObjectSet() const {
+  Isolate* isolate = Isolate::Current();
+  uword start, end;
+  isolate->heap()->StartEndAddress(&start, &end);
+
+  Isolate* vm_isolate = Dart::vm_isolate();
+  uword vm_start, vm_end;
+  vm_isolate->heap()->StartEndAddress(&vm_start, &vm_end);
+
+  ObjectSet* allocated_set = new ObjectSet(Utils::Minimum(start, vm_start),
+                                           Utils::Maximum(end, vm_end));
+
+  return allocated_set;
+}
+
+
+void HeapTrace::ResizeObjectSet() {
+  Isolate* isolate = Isolate::Current();
+  uword start, end;
+  isolate->heap()->StartEndAddress(&start, &end);
+  Isolate* vm_isolate = Dart::vm_isolate();
+  uword vm_start, vm_end;
+  vm_isolate->heap()->StartEndAddress(&vm_start, &vm_end);
+  object_set_.Resize(Utils::Minimum(start, vm_start),
+                     Utils::Maximum(end, vm_end));
+}
+
+
+void HeapTrace::Init(Isolate* isolate) {
+  // Do not trace the VM isolate
+  if (isolate == Dart::vm_isolate()) {
+    return;
+  }
+  ASSERT(isolate_initialized_ == false);
+  const char* format = "%s.htrace";
+  intptr_t len = OS::SNPrint(NULL, 0, format, isolate->name());
+  char* filename = new char[len + 1];
+  OS::SNPrint(filename, len + 1, format, isolate->name());
+  output_stream_ = (*open_callback_)(filename);
+  ASSERT(output_stream_ != NULL);
+  delete[] filename;
+  isolate_initialized_ = true;
+
+  HeapTraceObjectStoreVisitor object_store_visitor(isolate, this);
+  isolate->object_store()->VisitObjectPointers(&object_store_visitor);
+
+  // Visit any objects that may have been allocated during startup,
+  // before we started tracing.
+  HeapTraceInitialHeapVisitor heap_visitor(isolate, this);
+  isolate->heap()->IterateObjects(&heap_visitor);
+  TraceRoots(isolate);
+}
+
+
+// Allocation Record - 'A' (0x41)
+//
+// Format:
+// 'A'
+//  uword - address of allocated object
+//  uword - size of allocated object
+void HeapTrace::TraceAllocation(uword addr, intptr_t size) {
+  if (isolate_initialized_) {
+    {
+      AllocationRecord rec(this);
+      rec.Write(addr);
+      rec.Write(size);
+    }
+    TraceRoots(Isolate::Current());
+  }
+}
+
+
+// Snapshot Allocation Record - 'B' (0x41)
+//
+// Format:
+// 'B'
+//  uword - address of allocated object
+//  uword - size of allocated object
+void HeapTrace::TraceSnapshotAlloc(RawObject* obj, intptr_t size) {
+  if (isolate_initialized_) {
+    SnapshotAllocationRecord rec(this);
+    rec.Write(RawObject::ToAddr(obj));
+    rec.Write(static_cast<uword>(size));
+  }
+}
+
+
+// Allocate Zone Handle Record - 'Z' (0x5a)
+//
+// Format:
+//  'Z'
+//  uword - handle address (where the handle is pointing)
+//  uword - zone address (address of the zone the handle is in)
+void HeapTrace::TraceAllocateZoneHandle(uword handle, uword zone_addr) {
+  if (isolate_initialized_) {
+    AllocZoneHandleRecord rec(this);
+    rec.Write(handle);
+    rec.Write(zone_addr);
+  }
+}
+
+
+// Delete Zone Record - 'z' (0x7a)
+//
+// Format:
+//  'z'
+//  uword - zone address (all the handles in that zone are now gone)
+void HeapTrace::TraceDeleteZone(Zone* zone) {
+  if (isolate_initialized_) {
+    DeleteZoneRecord rec(this);
+    rec.Write(reinterpret_cast<uword>(zone));
+  }
+}
+
+
+// Delete Scoped Hanldes Record - 's' (0x73)
+//
+// Format:
+//  's'
+void HeapTrace::TraceDeleteScopedHandles() {
+  if (isolate_initialized_) {
+    DeleteScopedHandlesRecord rec(this);
+  }
+}
+
+
+//  Copy Record - 'C' (0x43)
+//
+//  Format:
+//   'C'
+//   uword - old address
+//   uword - new address
+void HeapTrace::TraceCopy(uword from_addr, uword to_addr) {
+    if (isolate_initialized_) {
+      CopyRecord rec(this);
+      rec.Write(from_addr);
+      rec.Write(to_addr);
+  }
+}
+
+
+// Object Store Recorda - 'O'(0x4f)
+//
+// Format:
+//  'O'
+//  uword - address
+void HeapTrace::TraceObjectStorePointer(uword addr) {
+  if (isolate_initialized_) {
+    ObjectStoreRecord rec(this);
+    rec.Write(addr);
+  }
+}
+
+
+// Promotion Records - 'P' (0x50)
+//
+// Format:
+//  'P'
+//  uword - old address
+//  uword - new address
+void HeapTrace::TracePromotion(uword old_addr, uword promoted_addr) {
+  if (isolate_initialized_) {
+    PromotionRecord rec(this);
+    rec.Write(old_addr);
+    rec.Write(promoted_addr);
+  }
+}
+
+
+// Death Range Record - 'L' (0x4c)
+//
+// Format:
+//  'L'
+//  uword - inclusive start address of the space being left
+//  uword - exclusive end address of the space being left
+void HeapTrace::TraceDeathRange(uword inclusive_start, uword exclusive_end) {
+  if (isolate_initialized_) {
+    DeathRangeRecord rec(this);
+    rec.Write(inclusive_start);
+    rec.Write(exclusive_end);
+  }
+}
+
+
+// Register Class Record - 'K' (0x4b)
+//
+// Format:
+//  'K'
+//  uword - address ( the address of the class)
+void HeapTrace::TraceRegisterClass(const Class& cls) {
+  if (isolate_initialized_) {
+    RegisterClassRecord rec(this);
+    rec.Write(RawObject::ToAddr(cls.raw()));
+  }
+}
+
+
+// Scoped Handle Record - 'H' (0x48)
+//
+// Format:
+//  'H'
+//  uword - adress of the scoped handle (where it is pointing)
+void HeapTrace::TraceScopedHandle(uword handle) {
+  if (isolate_initialized_) {
+    AllocScopedHandleRecord rec(this);
+    rec.Write(handle);
+  }
+}
+
+
+// Root Record - 'R' (0x52)
+//
+// Format:
+// 'R'
+// uword - address
+void HeapTrace::TraceSingleRoot(uword root_addr) {
+  if (isolate_initialized_) {
+    RootRecord rec(this);
+    rec.Write(root_addr);
+  }
+}
+
+
+// Sweep Record - 'S'
+//
+// Format:
+// 'S'
+// uword - address
+void HeapTrace::TraceSweep(uword sweept_addr) {
+  if (isolate_initialized_) {
+    SweepRecord rec(this);
+    rec.Write(sweept_addr);
+  }
+}
+
+
+// Does not output any records directly,
+// but does call TraceSingleRoot
+void HeapTrace::TraceRoots(Isolate* isolate) {
+  if (isolate_initialized_) {
+    ResizeObjectSet();
+    HeapTraceVisitor visitor(isolate, this, &object_set_);
+    HeapTraceScopedHandleVisitor handle_visitor(isolate, this);
+
+    bool visit_prologue_weak_handles = true;
+    bool validate_frames = false;
+
+    // Visit objects in per isolate stubs.
+    StubCode::VisitObjectPointers(&visitor);
+
+    // stack
+    StackFrameIterator frames_iterator(validate_frames);
+    StackFrame* frame = frames_iterator.NextFrame();
+    while (frame != NULL) {
+      frame->VisitObjectPointers(&visitor);
+      frame = frames_iterator.NextFrame();
+    }
+
+    if (isolate->api_state() != NULL) {
+      isolate->api_state()->VisitObjectPointers(&visitor,
+                                                visit_prologue_weak_handles);
+    }
+
+    // Visit the top context which is stored in the isolate.
+    RawContext* top_context = isolate->top_context();
+    visitor.VisitPointer(reinterpret_cast<RawObject**>(&top_context));
+
+    // Visit the currently active IC data array.
+    RawArray* ic_data_array = isolate->ic_data_array();
+    visitor.VisitPointer(reinterpret_cast<RawObject**>(&ic_data_array));
+
+    // Visit objects in the debugger.
+    isolate->debugger()->VisitObjectPointers(&visitor);
+
+    isolate->current_zone()->handles()->
+        VisitUnvisitedScopedHandles(&handle_visitor);
+
+    object_set_.FastClear();
+  }
+}
+
+
+// Store Record - 'U' (0x55)
+//
+// Format:
+//  'U'
+//  uword - originating object address (where a pointer is being stored)
+//  uword - byte offset into origin where the pointer is being stored
+//  uword - value of the pointer being stored
+void HeapTrace::TraceStoreIntoObject(uword object,
+                                     uword field_addr,
+                                     uword value) {
+  if (isolate_initialized_) {
+    // We don't care about pointers into the VM_Islate heap, so skip them.
+    // There should not be any pointers /out/ of the VM isolate; so we
+    // do not check object.
+    if (Isolate::Current()->heap()->Contains(value)) {
+      StoreRecord rec(this);
+      uword slot_offset =  field_addr - object;
+
+      rec.Write(object);
+      rec.Write(slot_offset);
+      rec.Write(value);
+    }
+  }
+}
+
+
+// Mark Sweep Start Record - '{' (0x7b)
+//
+// Format:
+//  '{'
+void HeapTrace::TraceMarkSweepStart() {
+  if (isolate_initialized_) {
+    MarkSweepStartRecord rec(this);
+  }
+}
+
+
+// Mark Sweep Finish Record - '}' (0x7d)
+//
+// Format:
+//  '}'
+void HeapTrace::TraceMarkSweepFinish() {
+  if (isolate_initialized_) {
+    MarkSweepFinishRecord rec(this);
+  }
+}
+
+}  // namespace dart
diff --git a/runtime/vm/heap_trace.h b/runtime/vm/heap_trace.h
new file mode 100644
index 0000000..983f7df
--- /dev/null
+++ b/runtime/vm/heap_trace.h
@@ -0,0 +1,213 @@
+// 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.
+
+#ifndef VM_HEAP_TRACE_H_
+#define VM_HEAP_TRACE_H_
+
+#include "include/dart_api.h"
+#include "vm/globals.h"
+#include "vm/object_set.h"
+
+namespace dart {
+
+// Forward declarations.
+class HeapTraceVisitor;
+class Isolate;
+class RawClass;
+class RawObject;
+class RawString;
+class BaseZone;
+
+class HeapTrace {
+ public:
+  enum RecordSize {
+    kRootSize = 5,
+    kAllocSize = 9,
+    kSnapshotAllocSize = 9,
+    kCopySize = 9,
+    kStoreSize = 13,
+    kSweepSize = 5,
+    kDeathRangeSize = 9,
+    kPromotionSize = 9,
+    kAllocZoneHandleSize = 9,
+    kDeleteZoneSize = 5,
+    kRegisterClassSize = 5,
+    kAllocScopedHandleSize = 5,
+    kDeleteScopedHandlesSize = 1,
+    kMarkSweepStartSize = 1,
+    kMarkSweepFinishSize = 1,
+    kObjectStoreSize = 5
+  };
+
+  enum RecordType {
+    kRootType = 'R',
+    kAllocType = 'A',
+    kSnapshotAllocType = 'B',
+    kCopyType = 'C',
+    kStoreType = 'U',
+    kSweepType = 'S',
+    kDeathRangeType = 'L',
+    kPromotionType = 'P',
+    kAllocZoneHandleType = 'Z',
+    kDeleteZoneType = 'z',
+    kRegisterClassType = 'K',
+    kAllocScopedHandleType = 'H',
+    kDeleteScopedHandlesType = 'h',
+    kMarkSweepStartType = '{',
+    kMarkSweepFinishType = '}',
+    kObjectStoreType = 'O'
+  };
+
+  template <RecordType T, RecordSize N>
+  class Record {
+   public:
+    explicit Record(HeapTrace* trace): cursor_(0), trace_(trace) {
+      ASSERT(N >= 1);
+      buffer_[0] = T;
+      ++cursor_;
+    }
+    ~Record() {
+      (*trace_->write_callback_)(Buffer(), Length(), trace_->output_stream_);
+    }
+
+    void Write(uword word) {
+      ASSERT(cursor_ + sizeof(word) <= N);
+      memmove(&buffer_[cursor_], &word, sizeof(word));
+      cursor_ += sizeof(word);
+    }
+
+    intptr_t Length() const { return cursor_; }
+
+    const uint8_t* Buffer() const {
+      ASSERT(cursor_ == N);
+      return buffer_;
+    }
+
+   private:
+    uint8_t buffer_[N];
+    intptr_t cursor_;
+    HeapTrace* trace_;
+    DISALLOW_COPY_AND_ASSIGN(Record);
+  };
+
+  typedef Record<kRootType, kRootSize> RootRecord;
+  typedef Record<kAllocType, kAllocSize> AllocationRecord;
+  typedef Record<kSnapshotAllocType, kSnapshotAllocSize>
+  SnapshotAllocationRecord;
+  typedef Record<kCopyType, kCopySize> CopyRecord;
+  typedef Record<kStoreType, kStoreSize> StoreRecord;
+  typedef Record<kSweepType, kSweepSize> SweepRecord;
+  typedef Record<kDeathRangeType, kDeathRangeSize> DeathRangeRecord;
+  typedef Record<kPromotionType, kPromotionSize> PromotionRecord;
+  typedef Record<kAllocZoneHandleType, kAllocZoneHandleSize>
+  AllocZoneHandleRecord;
+  typedef Record<kDeleteZoneType, kDeleteZoneSize>
+  DeleteZoneRecord;
+  typedef Record<kRegisterClassType, kRegisterClassSize> RegisterClassRecord;
+  typedef Record<kAllocScopedHandleType, kAllocScopedHandleSize>
+  AllocScopedHandleRecord;
+  typedef Record<kDeleteScopedHandlesType, kDeleteScopedHandlesSize>
+  DeleteScopedHandlesRecord;
+  typedef Record<kMarkSweepStartType, kMarkSweepStartSize> MarkSweepStartRecord;
+  typedef Record<kMarkSweepFinishType, kMarkSweepFinishSize>
+  MarkSweepFinishRecord;
+  typedef Record<kObjectStoreType, kObjectStoreSize> ObjectStoreRecord;
+
+  HeapTrace();
+  ~HeapTrace();
+
+  // Called by the isolate just before EnableGrowthControl.  Indicates
+  // the Isolate is initialized and enables tracing.
+  void Init(Isolate* isolate);
+
+  // Called when an object is allocated in the heap.
+  void TraceAllocation(uword addr, intptr_t size);
+
+  // Invoked after the snapshot is loaded at Isolate startup time.
+  void TraceSnapshotAlloc(RawObject* obj, intptr_t size);
+
+  // Rename to something like TraceAllocateZoneHandle (or whatever)
+  void TraceAllocateZoneHandle(uword handle, uword zone_addr);
+
+  // Invoked when a Zone block is deleted.
+  void TraceDeleteZone(Zone* zone);
+
+  // Invoked whenever the scoped handles are delelted.
+  void TraceDeleteScopedHandles();
+
+  // Invoked when objects are coped from the from space to the to space
+  // by the scavenger.
+  void TraceCopy(uword from_addr, uword to_addr);
+
+  // Invoked on each pointer in the object store.
+  void TraceObjectStorePointer(uword addr);
+
+  // Invoked when an object is promoted from the new space to the old space.
+  void TracePromotion(uword old_addr, uword promoted_addr);
+
+  // Invoked after a scavenge with the addressed range of from-space
+  void TraceDeathRange(uword inclusive_start, uword exclusive_end);
+
+  // Invoked whenever a class is registered in the class table.
+  void TraceRegisterClass(const Class& cls);
+
+  // Invoked when an address is swept.
+  void TraceSweep(uword sweept_addr);
+
+  // Invoked when storing value into origin, and value is an object.
+  void TraceStoreIntoObject(uword origin_object_addr,
+                            uword slot_addr,
+                            uword value);
+
+  // Invoked when starting a mark-sweep collection on old space
+  void TraceMarkSweepStart();
+
+  // Invoked after finishing a mark sweep collection on old space.
+  void TraceMarkSweepFinish();
+
+  // Initialize tracing globablly across the VM. Invidual isolates
+  // will still have to initialized themselves when they are started.
+  static void InitOnce(Dart_FileOpenCallback open_callback,
+                       Dart_FileWriteCallback write_callback,
+                       Dart_FileCloseCallback close_callback);
+
+  // Returns true if tracign is enabled for the VM.
+  static bool is_enabled() { return is_enabled_; }
+
+ private:
+  ObjectSet* CreateEmptyObjectSet() const;
+  void ResizeObjectSet();
+
+  void TraceScopedHandle(uword handle);
+
+  // A helper for PutRoots, called by HeapTraceVisitor.
+  void TraceSingleRoot(uword root);
+
+  // Invoked while tracing an allocation.
+  void TraceRoots(Isolate* isolate);
+
+  // Is the isolate we are tracing initialized?
+  bool isolate_initialized_;
+
+  void* output_stream_;
+
+  ObjectSet object_set_;
+
+  static Dart_FileOpenCallback open_callback_;
+  static Dart_FileWriteCallback write_callback_;
+  static Dart_FileCloseCallback close_callback_;
+
+  static bool is_enabled_;
+
+  friend class HeapTraceVisitor;
+  friend class HeapTraceScopedHandleVisitor;
+  friend class HeapTraceObjectStoreVisitor;
+  friend class HeapTraceDebugObjectVisitor;
+
+  DISALLOW_COPY_AND_ASSIGN(HeapTrace);
+};
+
+}  // namespace dart
+
+#endif  // VM_HEAP_TRACE_H_
diff --git a/runtime/vm/heap_trace_test.cc b/runtime/vm/heap_trace_test.cc
new file mode 100644
index 0000000..eb0ca6b
--- /dev/null
+++ b/runtime/vm/heap_trace_test.cc
@@ -0,0 +1,104 @@
+// 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.
+
+#include <iostream>
+#include <sstream>
+#include <string>
+#include "vm/dart_api_impl.h"
+#include "vm/growable_array.h"
+#include "vm/heap.h"
+#include "vm/heap_trace.h"
+#include "vm/unit_test.h"
+
+namespace dart {
+
+// only ia32 can run heap trace tests.
+#if defined(TARGET_ARCH_IA32)
+static std::stringstream* global_stream;
+
+static void* OpenTraceFile(const char* name) {
+  ASSERT(global_stream == NULL);
+  global_stream = new std::stringstream;
+  return reinterpret_cast<void*>(global_stream);
+}
+
+
+static void WriteToTraceFile(const void* data, intptr_t length, void* stream) {
+  ASSERT(stream == global_stream);
+  std::stringstream* sstream = reinterpret_cast<std::stringstream*>(stream);
+  sstream->write(reinterpret_cast<const char*>(data), length);
+}
+
+
+static void CloseTraceFile(void *stream) {
+  ASSERT(stream == global_stream);
+  global_stream = NULL;
+  delete reinterpret_cast<std::stringstream*>(stream);
+}
+
+
+bool DoesAllocationRecordExist(uword addr, const std::string& trace_string) {
+  const char* raw_trace = trace_string.c_str();
+  for (size_t i = 0; i < trace_string.length(); ++i) {
+    if ((raw_trace[i] == 'A') && (i + 4 < trace_string.length())) {
+      const uword candidate_address =
+          *(reinterpret_cast<const uword*>(raw_trace + i + 1));
+      if (candidate_address == addr) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+
+bool DoesSweepRecordExist(uword addr, const std::string& trace_string) {
+  const char* raw_trace = trace_string.c_str();
+  for (size_t i = 0; i < trace_string.length(); ++i) {
+    if ((raw_trace[i] == 'S') && (i + 4 < trace_string.length())) {
+      const uword candidate_address =
+          *(reinterpret_cast<const uword*>(raw_trace + i + 1));
+      if (candidate_address == addr) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+
+TEST_CASE(GCTraceAllocate) {
+  HeapTrace::InitOnce(OpenTraceFile,
+                      WriteToTraceFile,
+                      CloseTraceFile);
+
+  Isolate* isolate = Isolate::Current();
+  isolate->heap()->trace()->Init(isolate);
+
+  const int kArrayLen = 5;
+  RawArray* raw_arr = Array::New(kArrayLen);
+  uword addr = RawObject::ToAddr(raw_arr);
+
+  ASSERT(DoesAllocationRecordExist(addr, global_stream->str()));
+}
+
+
+TEST_CASE(GCTraceSweep) {
+  HeapTrace::InitOnce(OpenTraceFile,
+                      WriteToTraceFile,
+                      CloseTraceFile);
+
+  Isolate* isolate = Isolate::Current();
+  isolate->heap()->trace()->Init(isolate);
+
+  const int kArrayLen = 5;
+  RawArray* raw_arr = Array::New(kArrayLen, Heap::kOld);
+  uword addr = RawObject::ToAddr(raw_arr);
+
+  Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+  DoesSweepRecordExist(addr, global_stream->str());
+}
+#endif
+
+}  // namespace dart
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 3fd0394..022b446 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -149,8 +149,8 @@
   LoadStaticFieldInstr* other_load = other->AsLoadStaticField();
   ASSERT(other_load != NULL);
   // Assert that the field is initialized.
-  ASSERT(field().value() != Object::sentinel());
-  ASSERT(field().value() != Object::transition_sentinel());
+  ASSERT(field().value() != Object::sentinel().raw());
+  ASSERT(field().value() != Object::transition_sentinel().raw());
   return field().raw() == other_load->field().raw();
 }
 
@@ -229,17 +229,21 @@
 }
 
 
+static bool IsRecognizedLibrary(const Library& library) {
+  // List of libraries where methods can be recognized.
+  return (library.raw() == Library::CoreLibrary())
+      || (library.raw() == Library::MathLibrary())
+      || (library.raw() == Library::ScalarlistLibrary());
+}
+
 MethodRecognizer::Kind MethodRecognizer::RecognizeKind(
     const Function& function) {
-  // Only core and math library methods can be recognized.
-  const Library& core_lib = Library::Handle(Library::CoreLibrary());
-  const Library& math_lib = Library::Handle(Library::MathLibrary());
   const Class& function_class = Class::Handle(function.Owner());
-  if ((function_class.library() != core_lib.raw()) &&
-      (function_class.library() != math_lib.raw())) {
+  const Library& lib = Library::Handle(function_class.library());
+  if (!IsRecognizedLibrary(lib)) {
     return kUnknown;
   }
-  const Library& lib = Library::Handle(function_class.library());
+
   const String& function_name = String::Handle(function.name());
   const String& class_name = String::Handle(function_class.Name());
 
@@ -698,84 +702,41 @@
 }
 
 
-void GraphEntryInstr::DiscoverBlocks(
-    BlockEntryInstr* current_block,
-    GrowableArray<BlockEntryInstr*>* preorder,
-    GrowableArray<BlockEntryInstr*>* postorder,
-    GrowableArray<intptr_t>* parent,
-    GrowableArray<BitVector*>* assigned_vars,
-    intptr_t variable_count,
-    intptr_t fixed_parameter_count) {
-  // We only visit this block once, first of all blocks.
-  ASSERT(!IsMarked(this, preorder));
-  ASSERT(current_block == NULL);
-  ASSERT(preorder->is_empty());
-  ASSERT(postorder->is_empty());
-  ASSERT(parent->is_empty());
-
-  // This node has no parent, indicated by -1.  The preorder number is 0.
-  parent->Add(-1);
-  set_preorder_number(0);
-  preorder->Add(this);
-  BitVector* vars =
-      (variable_count == 0) ? NULL : new BitVector(variable_count);
-  assigned_vars->Add(vars);
-
-  // The graph entry consists of only one instruction.
-  set_last_instruction(this);
-
-  // Iteratively traverse all successors.  In the unoptimized code, we will
-  // enter the function at the first successor in reverse postorder, so we
-  // must visit the normal entry last.
-  for (intptr_t i = catch_entries_.length() - 1; i >= 0; --i) {
-    catch_entries_[i]->DiscoverBlocks(this, preorder, postorder,
-                                      parent, assigned_vars,
-                                      variable_count, fixed_parameter_count);
-  }
-  normal_entry_->DiscoverBlocks(this, preorder, postorder,
-                                parent, assigned_vars,
-                                variable_count, fixed_parameter_count);
-
-  // Assign postorder number.
-  set_postorder_number(postorder->length());
-  postorder->Add(this);
-}
-
-
 // Base class implementation used for JoinEntry and TargetEntry.
 void BlockEntryInstr::DiscoverBlocks(
-    BlockEntryInstr* current_block,
+    BlockEntryInstr* predecessor,
     GrowableArray<BlockEntryInstr*>* preorder,
     GrowableArray<BlockEntryInstr*>* postorder,
     GrowableArray<intptr_t>* parent,
     GrowableArray<BitVector*>* assigned_vars,
     intptr_t variable_count,
     intptr_t fixed_parameter_count) {
-  // We have already visited the graph entry, so we can assume current_block
-  // is non-null and preorder array is non-empty.
-  ASSERT(current_block != NULL);
-  ASSERT(!preorder->is_empty());
+  // If this block has a predecessor (i.e., is not the graph entry) we can
+  // assume the preorder array is non-empty.
+  ASSERT((predecessor == NULL) || !preorder->is_empty());
   // Blocks with a single predecessor cannot have been reached before.
-  ASSERT(!IsTargetEntry() || !IsMarked(this, preorder));
+  ASSERT(IsJoinEntry() || !IsMarked(this, preorder));
 
   // 1. If the block has already been reached, add current_block as a
   // basic-block predecessor and we are done.
   if (IsMarked(this, preorder)) {
-    AddPredecessor(current_block);
+    ASSERT(predecessor != NULL);
+    AddPredecessor(predecessor);
     return;
   }
 
   // 2. Otherwise, clear the predecessors which might have been computed on
-  // some earlier call to DiscoverBlocks and record this predecessor.  For
-  // joins save the original predecessors, if any, so we can garbage collect
-  // phi inputs from unreachable predecessors without recomputing SSA.
+  // some earlier call to DiscoverBlocks and record this predecessor.
   ClearPredecessors();
-  AddPredecessor(current_block);
+  if (predecessor != NULL) AddPredecessor(predecessor);
 
-  // 3. The current block is the spanning-tree parent.
-  parent->Add(current_block->preorder_number());
+  // 3. The predecessor is the spanning-tree parent.  The graph entry has no
+  // parent, indicated by -1.
+  intptr_t parent_number =
+      (predecessor == NULL) ? -1 : predecessor->preorder_number();
+  parent->Add(parent_number);
 
-  // 4. Assign preorder number and add the block entry to the list.
+  // 4. Assign the preorder number and add the block entry to the list.
   // Allocate an empty set of assigned variables for the block.
   set_preorder_number(preorder->length());
   preorder->Add(this);
@@ -787,26 +748,25 @@
   ASSERT(preorder->length() == parent->length());
   ASSERT(preorder->length() == assigned_vars->length());
 
-  // 5. Iterate straight-line successors until a branch instruction or
-  // another basic block entry instruction, and visit that instruction.
-  ASSERT(next() != NULL);
-  ASSERT(!next()->IsBlockEntry());
-  Instruction* next_instr = next();
-  while ((next_instr != NULL) &&
-         !next_instr->IsBlockEntry() &&
-         !next_instr->IsControl()) {
+  // 5. Iterate straight-line successors to record assigned variables and
+  // find the last instruction in the block.  The graph entry block consists
+  // of only the entry instruction, so that is the last instruction in the
+  // block.
+  Instruction* last = this;
+  for (ForwardInstructionIterator it(this); !it.Done(); it.Advance()) {
+    last = it.Current();
     if (vars != NULL) {
-      next_instr->RecordAssignedVars(vars, fixed_parameter_count);
+      last->RecordAssignedVars(vars, fixed_parameter_count);
     }
-    set_last_instruction(next_instr);
-    GotoInstr* goto_instr = next_instr->AsGoto();
-    next_instr =
-        (goto_instr != NULL) ? goto_instr->successor() : next_instr->next();
   }
-  if (next_instr != NULL) {
-    next_instr->DiscoverBlocks(this, preorder, postorder,
-                               parent, assigned_vars,
-                               variable_count, fixed_parameter_count);
+  set_last_instruction(last);
+
+  // Visit the block's successors in reverse so that they appear forwards
+  // the reverse postorder block ordering.
+  for (intptr_t i = last->SuccessorCount() - 1; i >= 0; --i) {
+    last->SuccessorAt(i)->DiscoverBlocks(this, preorder, postorder,
+                                         parent, assigned_vars,
+                                         variable_count, fixed_parameter_count);
   }
 
   // 6. Assign postorder number and add the block entry to the list.
@@ -827,29 +787,6 @@
 }
 
 
-void ControlInstruction::DiscoverBlocks(
-    BlockEntryInstr* current_block,
-    GrowableArray<BlockEntryInstr*>* preorder,
-    GrowableArray<BlockEntryInstr*>* postorder,
-    GrowableArray<intptr_t>* parent,
-    GrowableArray<BitVector*>* assigned_vars,
-    intptr_t variable_count,
-    intptr_t fixed_parameter_count) {
-  current_block->set_last_instruction(this);
-  // Visit the false successor before the true successor so they appear in
-  // true/false order in reverse postorder used as the block ordering in the
-  // nonoptimizing compiler.
-  ASSERT(true_successor_ != NULL);
-  ASSERT(false_successor_ != NULL);
-  false_successor_->DiscoverBlocks(current_block, preorder, postorder,
-                                   parent, assigned_vars,
-                                   variable_count, fixed_parameter_count);
-  true_successor_->DiscoverBlocks(current_block, preorder, postorder,
-                                  parent, assigned_vars,
-                                  variable_count, fixed_parameter_count);
-}
-
-
 void JoinEntryInstr::InsertPhi(intptr_t var_index, intptr_t var_count) {
   // Lazily initialize the array of phis.
   // Currently, phis are stored in a sparse array that holds the phi
@@ -867,6 +804,16 @@
 }
 
 
+void JoinEntryInstr::InsertPhi(PhiInstr* phi) {
+  // Lazily initialize the array of phis.
+  if (phis_ == NULL) {
+    phis_ = new ZoneGrowableArray<PhiInstr*>(1);
+  }
+  phis_->Add(phi);
+  phi_count_++;
+}
+
+
 void JoinEntryInstr::RemoveDeadPhis() {
   if (phis_ == NULL) return;
 
@@ -1446,6 +1393,11 @@
 }
 
 
+RawAbstractType* DoubleToSmiInstr::CompileType() const {
+  return Type::SmiType();
+}
+
+
 RawAbstractType* CheckClassInstr::CompileType() const {
   return AbstractType::null();
 }
@@ -1539,7 +1491,7 @@
   // TODO(fschneider): Handle other cases: e === false and e !== true/false.
   // Handles e === true.
   if ((kind() == Token::kEQ_STRICT) &&
-      (right_constant.raw() == Bool::True()) &&
+      (right_constant.raw() == Bool::True().raw()) &&
       (left()->ResultCid() == kBoolCid)) {
     // Return left subexpression as the replacement for this instruction.
     return left_defn;
@@ -1839,8 +1791,7 @@
     const bool result = (kind() == Token::kEQ_STRICT) ?
         left.constant().raw() == right.constant().raw() :
         left.constant().raw() != right.constant().raw();
-    __ LoadObject(locs()->out().reg(), result ? compiler->bool_true() :
-                                                compiler->bool_false());
+    __ LoadObject(locs()->out().reg(), result ? Bool::True() : Bool::False());
     return;
   }
   if (left.IsConstant()) {
@@ -1861,10 +1812,10 @@
   Label load_true, done;
   Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
   __ j(true_condition, &load_true, Assembler::kNearJump);
-  __ LoadObject(result, compiler->bool_false());
+  __ LoadObject(result, Bool::False());
   __ jmp(&done, Assembler::kNearJump);
   __ Bind(&load_true);
-  __ LoadObject(result, compiler->bool_true());
+  __ LoadObject(result, Bool::True());
   __ Bind(&done);
 }
 
@@ -1975,7 +1926,7 @@
 
 void StaticCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   Label skip_call;
-  if (function().name() == Symbols::EqualOperator()) {
+  if (function().name() == Symbols::EqualOperator().raw()) {
     compiler->EmitSuperEqualityCallPrologue(locs()->out().reg(), &skip_call);
   }
   compiler->GenerateStaticCall(deopt_id(),
@@ -2011,10 +1962,10 @@
   Register result = locs()->out().reg();
 
   Label done;
-  __ LoadObject(result, compiler->bool_true());
+  __ LoadObject(result, Bool::True());
   __ CompareRegisters(result, value);
   __ j(NOT_EQUAL, &done, Assembler::kNearJump);
-  __ LoadObject(result, compiler->bool_false());
+  __ LoadObject(result, Bool::False());
   __ Bind(&done);
 }
 
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index ccfa829..d743e0f 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -29,22 +29,22 @@
 class FlowGraphOptimizer;
 
 
-// TODO(srdjan): Add _ByteArrayBase, get:length.
 // TODO(srdjan): Unify with INTRINSIC_LIST.
 // (class-name, function-name, recognized enum, fingerprint).
 // See intrinsifier for fingerprint computation.
 #define RECOGNIZED_LIST(V)                                                     \
   V(_ObjectArray, get:length, ObjectArrayLength, 405297088)                    \
   V(_ImmutableArray, get:length, ImmutableArrayLength, 433698233)              \
+  V(_ByteArrayBase, get:length, ByteArrayBaseLength, 1098081765)               \
   V(_GrowableObjectArray, get:length, GrowableArrayLength, 725548050)          \
-  V(_GrowableObjectArray, get:capacity, GrowableArrayCapacity, 725548050)      \
+  V(_GrowableObjectArray, get:_capacity, GrowableArrayCapacity, 725548050)     \
   V(_StringBase, get:length, StringBaseLength, 320803993)                      \
-  V(_StringBase, get:isEmpty, StringBaseIsEmpty, 583130725)                    \
+  V(_StringBase, get:isEmpty, StringBaseIsEmpty, 711547329)                    \
   V(_StringBase, charCodeAt, StringBaseCharCodeAt, 984449525)                  \
   V(_StringBase, [], StringBaseCharAt, 1062366987)                             \
-  V(_IntegerImplementation, toDouble, IntegerToDouble, 1252792570)             \
+  V(_IntegerImplementation, toDouble, IntegerToDouble, 733149324)              \
   V(_Double, toInt, DoubleToInteger, 362666636)                                \
-  V(::, sqrt, MathSqrt, 2232519)                                               \
+  V(::, sqrt, MathSqrt, 1662640002)                                            \
 
 // Class that recognizes the name and owner of a function and returns the
 // corresponding enum. See RECOGNIZED_LIST above for list of recognizable
@@ -253,6 +253,7 @@
   M(CheckStackOverflow)                                                        \
   M(SmiToDouble)                                                               \
   M(DoubleToInteger)                                                           \
+  M(DoubleToSmi)                                                               \
   M(CheckClass)                                                                \
   M(CheckSmi)                                                                  \
   M(Constant)                                                                  \
@@ -378,31 +379,6 @@
 
   void Goto(JoinEntryInstr* entry);
 
-  // Discover basic-block structure by performing a recursive depth first
-  // traversal of the instruction graph reachable from this instruction.  As
-  // a side effect, the block entry instructions in the graph are assigned
-  // numbers in both preorder and postorder.  The array 'preorder' maps
-  // preorder block numbers to the block entry instruction with that number
-  // and analogously for the array 'postorder'.  The depth first spanning
-  // tree is recorded in the array 'parent', which maps preorder block
-  // numbers to the preorder number of the block's spanning-tree parent.
-  // The array 'assigned_vars' maps preorder block numbers to the set of
-  // assigned frame-allocated local variables in the block.  As a side
-  // effect of this function, the set of basic block predecessors (e.g.,
-  // block entry instructions of predecessor blocks) and also the last
-  // instruction in the block is recorded in each entry instruction.
-  virtual void DiscoverBlocks(
-      BlockEntryInstr* current_block,
-      GrowableArray<BlockEntryInstr*>* preorder,
-      GrowableArray<BlockEntryInstr*>* postorder,
-      GrowableArray<intptr_t>* parent,
-      GrowableArray<BitVector*>* assigned_vars,
-      intptr_t variable_count,
-      intptr_t fixed_parameter_count) {
-    // Never called for instructions except block entries and branches.
-    UNREACHABLE();
-  }
-
   // Mutate assigned_vars to add the local variable index for all
   // frame-allocated locals assigned to by the instruction.
   virtual void RecordAssignedVars(BitVector* assigned_vars,
@@ -534,6 +510,7 @@
   friend class CheckEitherNonSmiInstr;
   friend class StringCharCodeAtInstr;
   friend class LICM;
+  friend class DoubleToSmiInstr;
 
   intptr_t deopt_id_;
   intptr_t lifetime_position_;  // Position used by register allocator.
@@ -725,8 +702,21 @@
     return parallel_move_;
   }
 
-  virtual void DiscoverBlocks(
-      BlockEntryInstr* current_block,
+  // Discover basic-block structure by performing a recursive depth first
+  // traversal of the instruction graph reachable from this instruction.  As
+  // a side effect, the block entry instructions in the graph are assigned
+  // numbers in both preorder and postorder.  The array 'preorder' maps
+  // preorder block numbers to the block entry instruction with that number
+  // and analogously for the array 'postorder'.  The depth first spanning
+  // tree is recorded in the array 'parent', which maps preorder block
+  // numbers to the preorder number of the block's spanning-tree parent.
+  // The array 'assigned_vars' maps preorder block numbers to the set of
+  // assigned frame-allocated local variables in the block.  As a side
+  // effect of this function, the set of basic block predecessors (e.g.,
+  // block entry instructions of predecessor blocks) and also the last
+  // instruction in the block is recorded in each entry instruction.
+  void DiscoverBlocks(
+      BlockEntryInstr* predecessor,
       GrowableArray<BlockEntryInstr*>* preorder,
       GrowableArray<BlockEntryInstr*>* postorder,
       GrowableArray<intptr_t>* parent,
@@ -814,7 +804,6 @@
  public:
   explicit ForwardInstructionIterator(BlockEntryInstr* block_entry)
       : block_entry_(block_entry), current_(block_entry) {
-    ASSERT(block_entry_->last_instruction()->next() == NULL);
     Advance();
   }
 
@@ -876,15 +865,6 @@
   virtual intptr_t SuccessorCount() const;
   virtual BlockEntryInstr* SuccessorAt(intptr_t index) const;
 
-  virtual void DiscoverBlocks(
-      BlockEntryInstr* current_block,
-      GrowableArray<BlockEntryInstr*>* preorder,
-      GrowableArray<BlockEntryInstr*>* postorder,
-      GrowableArray<intptr_t>* parent,
-      GrowableArray<BitVector*>* assigned_vars,
-      intptr_t variable_count,
-      intptr_t fixed_parameter_count);
-
   void AddCatchEntry(TargetEntryInstr* entry) { catch_entries_.Add(entry); }
 
   virtual void PrepareEntry(FlowGraphCompiler* compiler);
@@ -905,7 +885,7 @@
   virtual void PrintTo(BufferFormatter* f) const;
 
  private:
-  virtual void ClearPredecessors() { UNREACHABLE(); }
+  virtual void ClearPredecessors() {}
   virtual void AddPredecessor(BlockEntryInstr* predecessor) { UNREACHABLE(); }
 
   TargetEntryInstr* normal_entry_;
@@ -942,6 +922,8 @@
   void InsertPhi(intptr_t var_index, intptr_t var_count);
   void RemoveDeadPhis();
 
+  void InsertPhi(PhiInstr* phi);
+
   intptr_t phi_count() const { return phi_count_; }
 
   virtual void PrintTo(BufferFormatter* f) const;
@@ -1139,6 +1121,22 @@
   // returning Definition (return type is covariant).
   virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer);
 
+  static const intptr_t kReplacementMarker = -2;
+
+  Definition* Replacement() {
+    if (ssa_temp_index_ == kReplacementMarker) {
+      return reinterpret_cast<Definition*>(temp_index_);
+    }
+    return this;
+  }
+
+  void SetReplacement(Definition* other) {
+    ASSERT(ssa_temp_index_ >= 0);
+    ASSERT(WasEliminated());
+    ssa_temp_index_ = kReplacementMarker;
+    temp_index_ = reinterpret_cast<intptr_t>(other);
+  }
+
  protected:
   friend class RangeAnalysis;
 
@@ -1486,16 +1484,6 @@
   virtual intptr_t SuccessorCount() const;
   virtual BlockEntryInstr* SuccessorAt(intptr_t index) const;
 
-  virtual void DiscoverBlocks(
-      BlockEntryInstr* current_block,
-      GrowableArray<BlockEntryInstr*>* preorder,
-      GrowableArray<BlockEntryInstr*>* postorder,
-      GrowableArray<intptr_t>* parent,
-      GrowableArray<BitVector*>* assigned_vars,
-      intptr_t variable_count,
-      intptr_t fixed_parameter_count);
-
-
   void EmitBranchOnCondition(FlowGraphCompiler* compiler,
                              Condition true_condition);
 
@@ -2064,6 +2052,7 @@
     ASSERT(Token::IsBinaryOperator(token_kind) ||
            Token::IsPrefixOperator(token_kind) ||
            Token::IsIndexOperator(token_kind) ||
+           Token::IsTypeTestOperator(token_kind) ||
            token_kind == Token::kGET ||
            token_kind == Token::kSET ||
            token_kind == Token::kILLEGAL);
@@ -3013,7 +3002,7 @@
 
   virtual bool HasSideEffect() const { return true; }
 
-  virtual intptr_t ResultCid() const { return kDynamicCid; }
+  virtual intptr_t ResultCid() const { return kArrayCid; }
 
  private:
   const intptr_t token_pos_;
@@ -3957,7 +3946,7 @@
 
 class DoubleToIntegerInstr : public TemplateDefinition<1> {
  public:
-  explicit DoubleToIntegerInstr(Value* value, InstanceCallInstr* instance_call)
+  DoubleToIntegerInstr(Value* value, InstanceCallInstr* instance_call)
       : instance_call_(instance_call) {
     ASSERT(value != NULL);
     inputs_[0] = value;
@@ -3985,6 +3974,39 @@
 };
 
 
+// Similar to 'DoubleToIntegerInstr' but expects unboxed double as input
+// and creates a Smi.
+class DoubleToSmiInstr : public TemplateDefinition<1> {
+ public:
+  DoubleToSmiInstr(Value* value, InstanceCallInstr* instance_call) {
+    ASSERT(value != NULL);
+    inputs_[0] = value;
+    deopt_id_ = instance_call->deopt_id();
+  }
+
+  Value* value() const { return inputs_[0]; }
+
+  DECLARE_INSTRUCTION(DoubleToSmi)
+  virtual RawAbstractType* CompileType() const;
+
+  virtual bool CanDeoptimize() const { return true; }
+
+  virtual bool HasSideEffect() const { return false; }
+
+  virtual intptr_t ResultCid() const { return kSmiCid; }
+
+  virtual Representation RequiredInputRepresentation(intptr_t idx) const {
+    ASSERT(idx == 0);
+    return kUnboxedDouble;
+  }
+
+  virtual intptr_t DeoptimizationTarget() const { return deopt_id_; }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(DoubleToSmiInstr);
+};
+
+
 class CheckClassInstr : public TemplateInstruction<1> {
  public:
   CheckClassInstr(Value* value,
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index a7b2ac5..927e552 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -206,9 +206,9 @@
   // Call the runtime if the object is not bool::true or bool::false.
   ASSERT(locs->always_calls());
   Label done;
-  __ CompareObject(reg, compiler->bool_true());
+  __ CompareObject(reg, Bool::True());
   __ j(EQUAL, &done, Assembler::kNearJump);
-  __ CompareObject(reg, compiler->bool_false());
+  __ CompareObject(reg, Bool::False());
   __ j(EQUAL, &done, Assembler::kNearJump);
 
   __ pushl(reg);  // Push the source object.
@@ -377,7 +377,7 @@
     }
   } else {
     equality_ic_data = ICData::New(compiler->parsed_function().function(),
-                                   Symbols::EqualOperatorHandle(),
+                                   Symbols::EqualOperator(),
                                    deopt_id,
                                    kNumArgumentsChecked);
   }
@@ -399,12 +399,10 @@
     __ popl(EDX);
     __ cmpl(EAX, EDX);
     __ j(EQUAL, &is_true);
-    __ LoadObject(EAX, (kind == Token::kEQ) ? compiler->bool_false()
-                                            : compiler->bool_true());
+    __ LoadObject(EAX, (kind == Token::kEQ) ? Bool::False() : Bool::True());
     __ jmp(&equality_done);
     __ Bind(&is_true);
-    __ LoadObject(EAX, (kind == Token::kEQ) ? compiler->bool_true()
-                                            : compiler->bool_false());
+    __ LoadObject(EAX, (kind == Token::kEQ) ? Bool::True() : Bool::False());
     if (kind == Token::kNE) {
       // Skip not-equal result conversion.
       __ jmp(&equality_done);
@@ -425,13 +423,13 @@
   if (kind == Token::kNE) {
     Label false_label, true_label, done;
     // Negate the condition: true label returns false and vice versa.
-    __ CompareObject(EAX, compiler->bool_true());
+    __ CompareObject(EAX, Bool::True());
     __ j(EQUAL, &true_label, Assembler::kNearJump);
     __ Bind(&false_label);
-    __ LoadObject(EAX, compiler->bool_true());
+    __ LoadObject(EAX, Bool::True());
     __ jmp(&done, Assembler::kNearJump);
     __ Bind(&true_label);
-    __ LoadObject(EAX, compiler->bool_false());
+    __ LoadObject(EAX, Bool::False());
     __ Bind(&done);
   }
   __ Bind(&equality_done);
@@ -488,10 +486,10 @@
         Register result = locs->out().reg();
         Label load_true;
         __ j(cond, &load_true, Assembler::kNearJump);
-        __ LoadObject(result, compiler->bool_false());
+        __ LoadObject(result, Bool::False());
         __ jmp(&done);
         __ Bind(&load_true);
-        __ LoadObject(result, compiler->bool_true());
+        __ LoadObject(result, Bool::True());
       }
     } else {
       const int kNumberOfArguments = 2;
@@ -505,19 +503,19 @@
       if (branch == NULL) {
         if (kind == Token::kNE) {
           Label false_label;
-          __ CompareObject(EAX, compiler->bool_true());
+          __ CompareObject(EAX, Bool::True());
           __ j(EQUAL, &false_label, Assembler::kNearJump);
-          __ LoadObject(EAX, compiler->bool_true());
+          __ LoadObject(EAX, Bool::True());
           __ jmp(&done);
           __ Bind(&false_label);
-          __ LoadObject(EAX, compiler->bool_false());
+          __ LoadObject(EAX, Bool::False());
           __ jmp(&done);
         }
       } else {
         if (branch->is_checked()) {
           EmitAssertBoolean(EAX, token_pos, locs, compiler);
         }
-        __ CompareObject(EAX, compiler->bool_true());
+        __ CompareObject(EAX, Bool::True());
         branch->EmitBranchOnCondition(compiler, cond);
       }
     }
@@ -570,12 +568,10 @@
     Register result = locs.out().reg();
     __ j(EQUAL, &is_equal, Assembler::kNearJump);
     // Not equal.
-    __ LoadObject(result, (kind == Token::kEQ) ? compiler->bool_false()
-                                               : compiler->bool_true());
+    __ LoadObject(result, (kind == Token::kEQ) ? Bool::False() : Bool::True());
     __ jmp(&done, Assembler::kNearJump);
     __ Bind(&is_equal);
-    __ LoadObject(result, (kind == Token::kEQ) ? compiler->bool_true()
-                                               : compiler->bool_false());
+    __ LoadObject(result, (kind == Token::kEQ) ? Bool::True() : Bool::False());
     __ Bind(&done);
   } else {
     Condition cond = TokenKindToSmiCondition(kind);
@@ -615,10 +611,10 @@
     Register result = locs->out().reg();
     Label load_true;
     __ j(cond, &load_true, Assembler::kNearJump);
-    __ LoadObject(result, compiler->bool_false());
+    __ LoadObject(result, Bool::False());
     __ jmp(&done);
     __ Bind(&load_true);
-    __ LoadObject(result, compiler->bool_true());
+    __ LoadObject(result, Bool::True());
   }
   __ jmp(&done);
   __ Bind(&non_null_compare);  // Receiver is not null.
@@ -655,10 +651,10 @@
     Register result = locs.out().reg();
     Label done, is_true;
     __ j(true_condition, &is_true);
-    __ LoadObject(result, compiler->bool_false());
+    __ LoadObject(result, Bool::False());
     __ jmp(&done);
     __ Bind(&is_true);
-    __ LoadObject(result, compiler->bool_true());
+    __ LoadObject(result, Bool::True());
     __ Bind(&done);
   }
 }
@@ -700,10 +696,10 @@
     Register result = locs.out().reg();
     Label done, is_true;
     __ j(true_condition, &is_true);
-    __ LoadObject(result, compiler->bool_false());
+    __ LoadObject(result, Bool::False());
     __ jmp(&done);
     __ Bind(&is_true);
-    __ LoadObject(result, compiler->bool_true());
+    __ LoadObject(result, Bool::True());
     __ Bind(&done);
   }
 }
@@ -765,10 +761,10 @@
     Label done;
     __ j(lo_cond, &is_true);
     __ Bind(&is_false);
-    __ LoadObject(result, compiler->bool_false());
+    __ LoadObject(result, Bool::False());
     __ jmp(&done);
     __ Bind(&is_true);
-    __ LoadObject(result, compiler->bool_true());
+    __ LoadObject(result, Bool::True());
     __ Bind(&done);
   }
 }
@@ -891,7 +887,7 @@
     EmitAssertBoolean(EAX, token_pos(), locs(), compiler);
   }
   Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
-  __ CompareObject(EAX, compiler->bool_true());
+  __ CompareObject(EAX, Bool::True());
   branch->EmitBranchOnCondition(compiler, branch_condition);
 }
 
@@ -1031,7 +1027,7 @@
     return;
   }
   EmitNativeCode(compiler);
-  __ CompareObject(EAX, compiler->bool_true());
+  __ CompareObject(EAX, Bool::True());
   branch->EmitBranchOnCondition(compiler, EQUAL);
 }
 
@@ -1143,7 +1139,7 @@
   __ movl(result, Address(result,
                           char_code,
                           TIMES_HALF_WORD_SIZE,  // Char code is a smi.
-                          Symbols::kNullCharId * kWordSize));
+                          Symbols::kNullCharCodeSymbolOffset * kWordSize));
 }
 
 
@@ -2315,6 +2311,31 @@
 }
 
 
+LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* result = new LocationSummary(
+      kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  result->set_in(0, Location::RequiresXmmRegister());
+  result->set_out(Location::RequiresRegister());
+  return result;
+}
+
+
+void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi);
+  Register result = locs()->out().reg();
+  XmmRegister value = locs()->in(0).xmm_reg();
+  __ cvttsd2si(result, value);
+  // Overflow is signalled with minint.
+  Label do_call, done;
+  // Check for overflow and that it fits into Smi.
+  __ cmpl(result, Immediate(0xC0000000));
+  __ j(NEGATIVE, deopt);
+  __ SmiTag(result);
+}
+
+
 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const {
   return MakeCallSummary();
 }
diff --git a/runtime/vm/intermediate_language_test.cc b/runtime/vm/intermediate_language_test.cc
index 26e9de9..7286ce5 100644
--- a/runtime/vm/intermediate_language_test.cc
+++ b/runtime/vm/intermediate_language_test.cc
@@ -30,8 +30,8 @@
   Value* use2 = new Value(def2);
   EXPECT(!use2->Equals(use1a));
 
-  ConstantInstr* c1 = new ConstantInstr(Bool::ZoneHandle(Bool::True()));
-  ConstantInstr* c2 = new ConstantInstr(Bool::ZoneHandle(Bool::True()));
+  ConstantInstr* c1 = new ConstantInstr(Bool::True());
+  ConstantInstr* c2 = new ConstantInstr(Bool::True());
   EXPECT(c1->Equals(c2));
   ConstantInstr* c3 = new ConstantInstr(Object::ZoneHandle());
   ConstantInstr* c4 = new ConstantInstr(Object::ZoneHandle());
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index d18c97d..c9b2fe9 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -217,9 +217,9 @@
   // Call the runtime if the object is not bool::true or bool::false.
   ASSERT(locs->always_calls());
   Label done;
-  __ CompareObject(reg, compiler->bool_true());
+  __ CompareObject(reg, Bool::True());
   __ j(EQUAL, &done, Assembler::kNearJump);
-  __ CompareObject(reg, compiler->bool_false());
+  __ CompareObject(reg, Bool::False());
   __ j(EQUAL, &done, Assembler::kNearJump);
 
   __ pushq(reg);  // Push the source object.
@@ -378,7 +378,7 @@
     }
   } else {
     equality_ic_data = ICData::New(compiler->parsed_function().function(),
-                                   Symbols::EqualOperatorHandle(),
+                                   Symbols::EqualOperator(),
                                    deopt_id,
                                    kNumArgumentsChecked);
   }
@@ -400,12 +400,10 @@
     __ popq(RDX);
     __ cmpq(RAX, RDX);
     __ j(EQUAL, &is_true);
-    __ LoadObject(RAX, (kind == Token::kEQ) ? compiler->bool_false()
-                                            : compiler->bool_true());
+    __ LoadObject(RAX, (kind == Token::kEQ) ? Bool::False() : Bool::True());
     __ jmp(&equality_done);
     __ Bind(&is_true);
-    __ LoadObject(RAX, (kind == Token::kEQ) ? compiler->bool_true()
-                                            : compiler->bool_false());
+    __ LoadObject(RAX, (kind == Token::kEQ) ? Bool::True() : Bool::False());
     if (kind == Token::kNE) {
       // Skip not-equal result conversion.
       __ jmp(&equality_done);
@@ -426,13 +424,13 @@
   if (kind == Token::kNE) {
     Label false_label, true_label, done;
     // Negate the condition: true label returns false and vice versa.
-    __ CompareObject(RAX, compiler->bool_true());
+    __ CompareObject(RAX, Bool::True());
     __ j(EQUAL, &true_label, Assembler::kNearJump);
     __ Bind(&false_label);
-    __ LoadObject(RAX, compiler->bool_true());
+    __ LoadObject(RAX, Bool::True());
     __ jmp(&done, Assembler::kNearJump);
     __ Bind(&true_label);
-    __ LoadObject(RAX, compiler->bool_false());
+    __ LoadObject(RAX, Bool::False());
     __ Bind(&done);
   }
   __ Bind(&equality_done);
@@ -490,10 +488,10 @@
         Register result = locs->out().reg();
         Label load_true;
         __ j(cond, &load_true, Assembler::kNearJump);
-        __ LoadObject(result, compiler->bool_false());
+        __ LoadObject(result, Bool::False());
         __ jmp(&done);
         __ Bind(&load_true);
-        __ LoadObject(result, compiler->bool_true());
+        __ LoadObject(result, Bool::True());
       }
     } else {
       const int kNumberOfArguments = 2;
@@ -507,19 +505,19 @@
       if (branch == NULL) {
         if (kind == Token::kNE) {
           Label false_label;
-          __ CompareObject(RAX, compiler->bool_true());
+          __ CompareObject(RAX, Bool::True());
           __ j(EQUAL, &false_label, Assembler::kNearJump);
-          __ LoadObject(RAX, compiler->bool_true());
+          __ LoadObject(RAX, Bool::True());
           __ jmp(&done);
           __ Bind(&false_label);
-          __ LoadObject(RAX, compiler->bool_false());
+          __ LoadObject(RAX, Bool::False());
           __ jmp(&done);
         }
       } else {
         if (branch->is_checked()) {
           EmitAssertBoolean(RAX, token_pos, locs, compiler);
         }
-        __ CompareObject(RAX, compiler->bool_true());
+        __ CompareObject(RAX, Bool::True());
         branch->EmitBranchOnCondition(compiler, cond);
       }
     }
@@ -572,12 +570,10 @@
     Register result = locs.out().reg();
     __ j(EQUAL, &is_equal, Assembler::kNearJump);
     // Not equal.
-    __ LoadObject(result, (kind == Token::kEQ) ? compiler->bool_false()
-                                               : compiler->bool_true());
+    __ LoadObject(result, (kind == Token::kEQ) ? Bool::False() : Bool::True());
     __ jmp(&done, Assembler::kNearJump);
     __ Bind(&is_equal);
-    __ LoadObject(result, (kind == Token::kEQ) ? compiler->bool_true()
-                                               : compiler->bool_false());
+    __ LoadObject(result, (kind == Token::kEQ) ? Bool::True() : Bool::False());
     __ Bind(&done);
   } else {
     Condition cond = TokenKindToSmiCondition(kind);
@@ -617,10 +613,10 @@
     Register result = locs->out().reg();
     Label load_true;
     __ j(cond, &load_true, Assembler::kNearJump);
-    __ LoadObject(result, compiler->bool_false());
+    __ LoadObject(result, Bool::False());
     __ jmp(&done);
     __ Bind(&load_true);
-    __ LoadObject(result, compiler->bool_true());
+    __ LoadObject(result, Bool::True());
   }
   __ jmp(&done);
   __ Bind(&non_null_compare);  // Receiver is not null.
@@ -657,10 +653,10 @@
     Register result = locs.out().reg();
     Label done, is_true;
     __ j(true_condition, &is_true);
-    __ LoadObject(result, compiler->bool_false());
+    __ LoadObject(result, Bool::False());
     __ jmp(&done);
     __ Bind(&is_true);
-    __ LoadObject(result, compiler->bool_true());
+    __ LoadObject(result, Bool::True());
     __ Bind(&done);
   }
 }
@@ -777,7 +773,7 @@
     EmitAssertBoolean(RAX, token_pos(), locs(), compiler);
   }
   Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
-  __ CompareObject(RAX, compiler->bool_true());
+  __ CompareObject(RAX, Bool::True());
   branch->EmitBranchOnCondition(compiler, branch_condition);
 }
 
@@ -899,7 +895,7 @@
     return;
   }
   EmitNativeCode(compiler);
-  __ CompareObject(RAX, compiler->bool_true());
+  __ CompareObject(RAX, Bool::True());
   branch->EmitBranchOnCondition(compiler, EQUAL);
 }
 
@@ -1011,7 +1007,7 @@
   __ movq(result, Address(result,
                           char_code,
                           TIMES_HALF_WORD_SIZE,  // Char code is a smi.
-                          Symbols::kNullCharId * kWordSize));
+                          Symbols::kNullCharCodeSymbolOffset * kWordSize));
 }
 
 
@@ -2204,6 +2200,35 @@
 }
 
 
+LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 1;
+  LocationSummary* result = new LocationSummary(
+      kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  result->set_in(0, Location::RequiresXmmRegister());
+  result->set_out(Location:: Location::RequiresRegister());
+  result->set_temp(0, Location::RequiresRegister());
+  return result;
+}
+
+
+void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi);
+  Register result = locs()->out().reg();
+  XmmRegister value = locs()->in(0).xmm_reg();
+  Register temp = locs()->temp(0).reg();
+
+  __ cvttsd2siq(result, value);
+  // Overflow is signalled with minint.
+  Label do_call, done;
+  // Check for overflow and that it fits into Smi.
+  __ movq(temp, result);
+  __ shlq(temp, Immediate(1));
+  __ j(OVERFLOW, deopt);
+  __ SmiTag(result);
+}
+
+
 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const {
   return MakeCallSummary();
 }
diff --git a/runtime/vm/intrinsifier.h b/runtime/vm/intrinsifier.h
index ff07cc1..bc20acc 100644
--- a/runtime/vm/intrinsifier.h
+++ b/runtime/vm/intrinsifier.h
@@ -17,47 +17,47 @@
 // build and run to get the correct fingerprint from the mismatch error.
 #define INTRINSIC_LIST(V)                                                      \
   V(_IntegerImplementation, _addFromInteger, Integer_addFromInteger, 726019207)\
-  V(_IntegerImplementation, +, Integer_add, 1821133110)                        \
+  V(_IntegerImplementation, +, Integer_add, 959303888)                         \
   V(_IntegerImplementation, _subFromInteger, Integer_subFromInteger, 726019207)\
-  V(_IntegerImplementation, -, Integer_sub, 2091907336)                        \
+  V(_IntegerImplementation, -, Integer_sub, 483122878)                         \
   V(_IntegerImplementation, _mulFromInteger, Integer_mulFromInteger, 726019207)\
-  V(_IntegerImplementation, *, Integer_mul, 146702919)                         \
-  V(_IntegerImplementation, %, Integer_modulo, 578878541)                      \
-  V(_IntegerImplementation, ~/, Integer_truncDivide, 1806780482)               \
-  V(_IntegerImplementation, unary-, Integer_negate, 1705538272)                \
+  V(_IntegerImplementation, *, Integer_mul, 1043837343)                        \
+  V(_IntegerImplementation, %, Integer_modulo, 2027609817)                     \
+  V(_IntegerImplementation, ~/, Integer_truncDivide, 958840900)                \
+  V(_IntegerImplementation, unary-, Integer_negate, 678480358)                 \
   V(_IntegerImplementation, _bitAndFromInteger,                                \
     Integer_bitAndFromInteger, 726019207)                                      \
-  V(_IntegerImplementation, &, Integer_bitAnd, 927461461)                      \
+  V(_IntegerImplementation, &, Integer_bitAnd, 1692486097)                     \
   V(_IntegerImplementation, _bitOrFromInteger,                                 \
     Integer_bitOrFromInteger, 726019207)                                       \
-  V(_IntegerImplementation, |, Integer_bitOr, 2056857508)                      \
+  V(_IntegerImplementation, |, Integer_bitOr, 66350242)                        \
   V(_IntegerImplementation, _bitXorFromInteger,                                \
     Integer_bitXorFromInteger, 726019207)                                      \
-  V(_IntegerImplementation, ^, Integer_bitXor, 837002595)                      \
+  V(_IntegerImplementation, ^, Integer_bitXor, 1620294403)                     \
   V(_IntegerImplementation,                                                    \
     _greaterThanFromInteger,                                                   \
     Integer_greaterThanFromInt, 79222670)                                      \
-  V(_IntegerImplementation, >, Integer_greaterThan, 2126978373)                \
-  V(_IntegerImplementation, ==, Integer_equal, 507939054)                      \
+  V(_IntegerImplementation, >, Integer_greaterThan, 1800453857)                \
+  V(_IntegerImplementation, ==, Integer_equal, 1540405784)                     \
   V(_IntegerImplementation, _equalToInteger, Integer_equalToInteger, 79222670) \
-  V(_IntegerImplementation, <, Integer_lessThan, 1277579871)                   \
-  V(_IntegerImplementation, <=, Integer_lessEqualThan, 806519877)              \
-  V(_IntegerImplementation, >=, Integer_greaterEqualThan, 807443398)           \
-  V(_IntegerImplementation, <<, Integer_shl, 1246348641)                       \
-  V(_IntegerImplementation, >>, Integer_sar, 1937635847)                       \
+  V(_IntegerImplementation, <, Integer_lessThan, 1426685575)                   \
+  V(_IntegerImplementation, <=, Integer_lessEqualThan, 1065121761)             \
+  V(_IntegerImplementation, >=, Integer_greaterEqualThan, 1065151552)          \
+  V(_IntegerImplementation, <<, Integer_shl, 386573125)                        \
+  V(_IntegerImplementation, >>, Integer_sar, 1170883039)                       \
   V(_Smi, ~, Smi_bitNegate, 882629793)                                         \
-  V(_Double, >, Double_greaterThan, 1471126121)                                \
-  V(_Double, >=, Double_greaterEqualThan, 1664965640)                          \
-  V(_Double, <, Double_lessThan, 148927649)                                    \
-  V(_Double, <=, Double_lessEqualThan, 1664042119)                             \
-  V(_Double, ==, Double_equal, 900686217)                                      \
-  V(_Double, +, Double_add, 786489945)                                         \
-  V(_Double, -, Double_sub, 1074937651)                                        \
-  V(_Double, *, Double_mul, 1515140403)                                        \
-  V(_Double, /, Double_div, 1481616340)                                        \
+  V(_Double, >, Double_greaterThan, 2056391997)                                \
+  V(_Double, >=, Double_greaterEqualThan, 1300634558)                          \
+  V(_Double, <, Double_lessThan, 1598098437)                                   \
+  V(_Double, <=, Double_lessEqualThan, 1300604767)                             \
+  V(_Double, ==, Double_equal, 1206706717)                                     \
+  V(_Double, +, Double_add, 1965033293)                                        \
+  V(_Double, -, Double_sub, 1212327731)                                        \
+  V(_Double, *, Double_mul, 395243827)                                         \
+  V(_Double, /, Double_div, 809804402)                                         \
   V(_Double, get:isNaN, Double_getIsNaN, 54462366)                             \
   V(_Double, get:isNegative, Double_getIsNegative, 54462366)                   \
-  V(_Double, _mulFromInteger, Double_mulFromInteger, 1668662807)               \
+  V(_Double, _mulFromInteger, Double_mulFromInteger, 815838159)                \
   V(_Double, .fromInteger, Double_fromInteger, 842078193)                      \
   V(_Double, toInt, Double_toInt, 362666636)                                   \
   V(_ObjectArray, ., ObjectArray_Allocate, 577949617)                          \
@@ -66,41 +66,41 @@
   V(_ObjectArray, []=, Array_setIndexed, 255863719)                            \
   V(_GrowableObjectArray, .fromObjectArray, GArray_Allocate, 989879928)        \
   V(_GrowableObjectArray, get:length, GrowableArray_getLength, 725548050)      \
-  V(_GrowableObjectArray, get:capacity, GrowableArray_getCapacity, 725548050)  \
+  V(_GrowableObjectArray, get:_capacity, GrowableArray_getCapacity, 725548050) \
   V(_GrowableObjectArray, [], GrowableArray_getIndexed, 581838973)             \
   V(_GrowableObjectArray, []=, GrowableArray_setIndexed, 1048007636)           \
   V(_GrowableObjectArray, _setLength, GrowableArray_setLength, 796709584)      \
   V(_GrowableObjectArray, _setData, GrowableArray_setData, 477312179)          \
-  V(_GrowableObjectArray, add, GrowableArray_add, 455936651)                   \
+  V(_GrowableObjectArray, add, GrowableArray_add, 1367698386)                  \
   V(_ImmutableArray, [], ImmutableArray_getIndexed, 486821199)                 \
   V(_ImmutableArray, get:length, ImmutableArray_getLength, 433698233)          \
-  V(::, sqrt, Math_sqrt, 2232519)                                              \
-  V(::, sin, Math_sin, 837187616)                                              \
-  V(::, cos, Math_cos, 548880317)                                              \
-  V(Object, ==, Object_equal, 1511145014)                                      \
+  V(::, sqrt, Math_sqrt, 1662640002)                                           \
+  V(::, sin, Math_sin, 1273932041)                                             \
+  V(::, cos, Math_cos, 1749547468)                                             \
+  V(Object, ==, Object_equal, 2126956595)                                      \
   V(_FixedSizeArrayIterator, get:hasNext,                                      \
-    FixedSizeArrayIterator_getHasNext, 1819226215)                             \
-  V(_FixedSizeArrayIterator, next, FixedSizeArrayIterator_next, 1147008464)    \
+    FixedSizeArrayIterator_getHasNext, 682147711)                              \
+  V(_FixedSizeArrayIterator, next, FixedSizeArrayIterator_next, 1283926262)    \
   V(_StringBase, get:hashCode, String_getHashCode, 320803993)                  \
-  V(_StringBase, get:isEmpty, String_getIsEmpty, 583130725)                    \
+  V(_StringBase, get:isEmpty, String_getIsEmpty, 711547329)                    \
   V(_StringBase, get:length, String_getLength, 320803993)                      \
   V(_StringBase, charCodeAt, String_charCodeAt, 984449525)                     \
-  V(_ByteArrayBase, get:length, ByteArrayBase_getLength, 1828280001)           \
-  V(_Int8Array, [], Int8Array_getIndexed, 1499790324)                          \
-  V(_Int8Array, []=, Int8Array_setIndexed, 1469038436)                         \
-  V(_Uint8Array, [], Uint8Array_getIndexed, 748420218)                         \
-  V(_Uint8Array, []=, Uint8Array_setIndexed, 1619321522)                       \
-  V(_Int16Array, [], Int16Array_getIndexed, 1203257976)                        \
-  V(_Uint16Array, [], Uint16Array_getIndexed, 1549909675)                      \
-  V(_Int32Array, [], Int32Array_getIndexed, 1849422378)                        \
-  V(_Uint32Array, [], Uint32Array_getIndexed, 586613266)                       \
-  V(_Int64Array, [], Int64Array_getIndexed, 619332438)                         \
-  V(_Uint64Array, [], Uint64Array_getIndexed, 969448467)                       \
-  V(_Float32Array, [], Float32Array_getIndexed, 280103602)                     \
-  V(_Float32Array, []=, Float32Array_setIndexed, 1270729544)                   \
-  V(_Float64Array, [], Float64Array_getIndexed, 476393480)                     \
-  V(_Float64Array, []=, Float64Array_setIndexed, 283625119)                    \
-  V(_ExternalUint8Array, [], ExternalUint8Array_getIndexed, 1892679907)        \
+  V(_ByteArrayBase, get:length, ByteArrayBase_getLength, 1098081765)           \
+  V(_Int8Array, [], Int8Array_getIndexed, 1295306322)                          \
+  V(_Int8Array, []=, Int8Array_setIndexed, 1709956322)                         \
+  V(_Uint8Array, [], Uint8Array_getIndexed, 578331916)                         \
+  V(_Uint8Array, []=, Uint8Array_setIndexed, 121509844)                        \
+  V(_Int16Array, [], Int16Array_getIndexed, 870098766)                         \
+  V(_Uint16Array, [], Uint16Array_getIndexed, 1019828411)                      \
+  V(_Int32Array, [], Int32Array_getIndexed, 1999321436)                        \
+  V(_Uint32Array, [], Uint32Array_getIndexed, 1750764660)                      \
+  V(_Int64Array, [], Int64Array_getIndexed, 504894128)                         \
+  V(_Uint64Array, [], Uint64Array_getIndexed, 31272531)                        \
+  V(_Float32Array, [], Float32Array_getIndexed, 147582932)                     \
+  V(_Float32Array, []=, Float32Array_setIndexed, 664454270)                    \
+  V(_Float64Array, [], Float64Array_getIndexed, 638830526)                     \
+  V(_Float64Array, []=, Float64Array_setIndexed, 1948811847)                   \
+  V(_ExternalUint8Array, [], ExternalUint8Array_getIndexed, 753790851)         \
 
 // Forward declarations.
 class Assembler;
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index ba42141..87ae668 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -174,10 +174,9 @@
 
 
 static intptr_t ComputeObjectArrayTypeArgumentsOffset() {
-  const String& class_name = String::Handle(Symbols::New("_ObjectArray"));
   const Library& core_lib = Library::Handle(Library::CoreLibrary());
   const Class& cls =
-      Class::Handle(core_lib.LookupClassAllowPrivate(class_name));
+      Class::Handle(core_lib.LookupClassAllowPrivate(Symbols::ObjectArray()));
   ASSERT(!cls.IsNull());
   ASSERT(cls.HasTypeArguments());
   ASSERT(cls.NumTypeArguments() == 1);
@@ -1076,17 +1075,15 @@
 
 static bool CompareIntegers(Assembler* assembler, Condition true_condition) {
   Label try_mint_smi, is_true, is_false, drop_two_fall_through, fall_through;
-  const Bool& bool_true = Bool::ZoneHandle(Bool::True());
-  const Bool& bool_false = Bool::ZoneHandle(Bool::False());
   TestBothArgumentsSmis(assembler, &try_mint_smi);
   // EAX contains the right argument.
   __ cmpl(Address(ESP, + 2 * kWordSize), EAX);
   __ j(true_condition, &is_true, Assembler::kNearJump);
   __ Bind(&is_false);
-  __ LoadObject(EAX, bool_false);
+  __ LoadObject(EAX, Bool::False());
   __ ret();
   __ Bind(&is_true);
-  __ LoadObject(EAX, bool_true);
+  __ LoadObject(EAX, Bool::True());
   __ ret();
 
   // 64-bit comparison
@@ -1166,8 +1163,6 @@
 // can be Smi, Mint, Bigint or double.
 bool Intrinsifier::Integer_equalToInteger(Assembler* assembler) {
   Label fall_through, true_label, check_for_mint;
-  const Bool& bool_true = Bool::ZoneHandle(Bool::True());
-  const Bool& bool_false = Bool::ZoneHandle(Bool::False());
   // For integer receiver '===' check first.
   __ movl(EAX, Address(ESP, + 1 * kWordSize));
   __ cmpl(EAX, Address(ESP, + 2 * kWordSize));
@@ -1177,10 +1172,10 @@
   __ testl(EAX, Immediate(kSmiTagMask));
   __ j(NOT_ZERO, &check_for_mint, Assembler::kNearJump);
   // Both arguments are smi, '===' is good enough.
-  __ LoadObject(EAX, bool_false);
+  __ LoadObject(EAX, Bool::False());
   __ ret();
   __ Bind(&true_label);
-  __ LoadObject(EAX, bool_true);
+  __ LoadObject(EAX, Bool::True());
   __ ret();
 
   // At least one of the arguments was not Smi.
@@ -1196,7 +1191,7 @@
   __ movl(EAX, Address(ESP, + 1 * kWordSize));  // Right argument.
   __ CompareClassId(EAX, kDoubleCid, EDI);
   __ j(EQUAL, &fall_through);
-  __ LoadObject(EAX, bool_false);  // Smi == Mint -> false.
+  __ LoadObject(EAX, Bool::False());  // Smi == Mint -> false.
   __ ret();
 
   __ Bind(&receiver_not_smi);
@@ -1207,7 +1202,7 @@
   __ movl(EAX, Address(ESP, + 1 * kWordSize));  // Right argument.
   __ testl(EAX, Immediate(kSmiTagMask));
   __ j(NOT_ZERO, &fall_through);
-  __ LoadObject(EAX, bool_false);
+  __ LoadObject(EAX, Bool::False());
   __ ret();
   // TODO(srdjan): Implement Mint == Mint comparison.
 
@@ -1278,8 +1273,6 @@
 // returns false. Any non-double arg1 causes control flow to fall through to the
 // slow case (compiled method body).
 static bool CompareDoubles(Assembler* assembler, Condition true_condition) {
-  const Bool& bool_true = Bool::ZoneHandle(Bool::True());
-  const Bool& bool_false = Bool::ZoneHandle(Bool::False());
   Label fall_through, is_false, is_true, is_smi, double_op;
   TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
   // Both arguments are double, right operand is in EAX.
@@ -1292,10 +1285,10 @@
   __ j(true_condition, &is_true, Assembler::kNearJump);
   // Fall through false.
   __ Bind(&is_false);
-  __ LoadObject(EAX, bool_false);
+  __ LoadObject(EAX, Bool::False());
   __ ret();
   __ Bind(&is_true);
-  __ LoadObject(EAX, bool_true);
+  __ LoadObject(EAX, Bool::True());
   __ ret();
   __ Bind(&is_smi);
   __ SmiUntag(EAX);
@@ -1436,25 +1429,21 @@
 
 
 bool Intrinsifier::Double_getIsNaN(Assembler* assembler) {
-  const Bool& bool_true = Bool::ZoneHandle(Bool::True());
-  const Bool& bool_false = Bool::ZoneHandle(Bool::False());
   Label is_true;
   __ movl(EAX, Address(ESP, +1 * kWordSize));
   __ movsd(XMM0, FieldAddress(EAX, Double::value_offset()));
   __ comisd(XMM0, XMM0);
   __ j(PARITY_EVEN, &is_true, Assembler::kNearJump);  // NaN -> true;
-  __ LoadObject(EAX, bool_false);
+  __ LoadObject(EAX, Bool::False());
   __ ret();
   __ Bind(&is_true);
-  __ LoadObject(EAX, bool_true);
+  __ LoadObject(EAX, Bool::True());
   __ ret();
   return true;  // Method is complete, no slow case.
 }
 
 
 bool Intrinsifier::Double_getIsNegative(Assembler* assembler) {
-  const Bool& bool_true = Bool::ZoneHandle(Bool::True());
-  const Bool& bool_false = Bool::ZoneHandle(Bool::False());
   Label is_false, is_true, is_zero;
   __ movl(EAX, Address(ESP, +1 * kWordSize));
   __ movsd(XMM0, FieldAddress(EAX, Double::value_offset()));
@@ -1464,10 +1453,10 @@
   __ j(EQUAL, &is_zero, Assembler::kNearJump);  // Check for negative zero.
   __ j(ABOVE_EQUAL, &is_false, Assembler::kNearJump);  // >= 0 -> false.
   __ Bind(&is_true);
-  __ LoadObject(EAX, bool_true);
+  __ LoadObject(EAX, Bool::True());
   __ ret();
   __ Bind(&is_false);
-  __ LoadObject(EAX, bool_false);
+  __ LoadObject(EAX, Bool::False());
   __ ret();
   __ Bind(&is_zero);
   // Check for negative zero (get the sign bit).
@@ -1581,15 +1570,13 @@
 // Identity comparison.
 bool Intrinsifier::Object_equal(Assembler* assembler) {
   Label is_true;
-  const Bool& bool_true = Bool::ZoneHandle(Bool::True());
-  const Bool& bool_false = Bool::ZoneHandle(Bool::False());
   __ movl(EAX, Address(ESP, + 1 * kWordSize));
   __ cmpl(EAX, Address(ESP, + 2 * kWordSize));
   __ j(EQUAL, &is_true, Assembler::kNearJump);
-  __ LoadObject(EAX, bool_false);
+  __ LoadObject(EAX, Bool::False());
   __ ret();
   __ Bind(&is_true);
-  __ LoadObject(EAX, bool_true);
+  __ LoadObject(EAX, Bool::True());
   __ ret();
   return true;
 }
@@ -1651,8 +1638,6 @@
 //   }
 bool Intrinsifier::FixedSizeArrayIterator_getHasNext(Assembler* assembler) {
   Label fall_through, is_true;
-  const Bool& bool_true = Bool::ZoneHandle(Bool::True());
-  const Bool& bool_false = Bool::ZoneHandle(Bool::False());
   intptr_t length_offset =
       GetOffsetForField(kFixedSizeArrayIteratorClassName, "_length");
   intptr_t pos_offset =
@@ -1666,10 +1651,10 @@
   __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);  // Non-smi _length.
   __ cmpl(EBX, EAX);     // _length > _pos.
   __ j(GREATER, &is_true, Assembler::kNearJump);
-  __ LoadObject(EAX, bool_false);
+  __ LoadObject(EAX, Bool::False());
   __ ret();
   __ Bind(&is_true);
-  __ LoadObject(EAX, bool_true);
+  __ LoadObject(EAX, Bool::True());
   __ ret();
   __ Bind(&fall_through);
   return false;
@@ -1721,17 +1706,15 @@
 
 bool Intrinsifier::String_getIsEmpty(Assembler* assembler) {
   Label is_true;
-  const Bool& bool_true = Bool::ZoneHandle(Bool::True());
-  const Bool& bool_false = Bool::ZoneHandle(Bool::False());
   // Get length.
   __ movl(EAX, Address(ESP, + 1 * kWordSize));  // String object.
   __ movl(EAX, FieldAddress(EAX, String::length_offset()));
   __ cmpl(EAX, Immediate(Smi::RawValue(0)));
   __ j(EQUAL, &is_true, Assembler::kNearJump);
-  __ LoadObject(EAX, bool_false);
+  __ LoadObject(EAX, Bool::False());
   __ ret();
   __ Bind(&is_true);
-  __ LoadObject(EAX, bool_true);
+  __ LoadObject(EAX, Bool::True());
   __ ret();
   return true;
 }
diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc
index 8d52b6a..e7ded2c 100644
--- a/runtime/vm/intrinsifier_x64.cc
+++ b/runtime/vm/intrinsifier_x64.cc
@@ -987,16 +987,14 @@
 
 static bool CompareIntegers(Assembler* assembler, Condition true_condition) {
   Label fall_through, true_label;
-  const Bool& bool_true = Bool::ZoneHandle(Bool::True());
-  const Bool& bool_false = Bool::ZoneHandle(Bool::False());
   TestBothArgumentsSmis(assembler, &fall_through);
   // RAX contains the right argument.
   __ cmpq(Address(RSP, + 2 * kWordSize), RAX);
   __ j(true_condition, &true_label, Assembler::kNearJump);
-  __ LoadObject(RAX, bool_false);
+  __ LoadObject(RAX, Bool::False());
   __ ret();
   __ Bind(&true_label);
-  __ LoadObject(RAX, bool_true);
+  __ LoadObject(RAX, Bool::True());
   __ ret();
   __ Bind(&fall_through);
   return false;
@@ -1033,8 +1031,6 @@
 // can be Smi, Mint, Bigint or double.
 bool Intrinsifier::Integer_equalToInteger(Assembler* assembler) {
   Label fall_through, true_label, check_for_mint;
-  const Bool& bool_true = Bool::ZoneHandle(Bool::True());
-  const Bool& bool_false = Bool::ZoneHandle(Bool::False());
   // For integer receiver '===' check first.
   __ movq(RAX, Address(RSP, + 1 * kWordSize));
   __ movq(RCX, Address(RSP, + 2 * kWordSize));
@@ -1044,10 +1040,10 @@
   __ testq(RAX, Immediate(kSmiTagMask));
   __ j(NOT_ZERO, &check_for_mint, Assembler::kNearJump);
   // Both arguments are smi, '===' is good enough.
-  __ LoadObject(RAX, bool_false);
+  __ LoadObject(RAX, Bool::False());
   __ ret();
   __ Bind(&true_label);
-  __ LoadObject(RAX, bool_true);
+  __ LoadObject(RAX, Bool::True());
   __ ret();
 
   // At least one of the arguments was not Smi.
@@ -1063,7 +1059,7 @@
   __ movq(RAX, Address(RSP, + 1 * kWordSize));
   __ CompareClassId(RAX, kDoubleCid);
   __ j(EQUAL, &fall_through);
-  __ LoadObject(RAX, bool_false);
+  __ LoadObject(RAX, Bool::False());
   __ ret();
 
   __ Bind(&receiver_not_smi);
@@ -1074,7 +1070,7 @@
   __ movq(RAX, Address(RSP, + 1 * kWordSize));  // Right argument.
   __ testq(RAX, Immediate(kSmiTagMask));
   __ j(NOT_ZERO, &fall_through);
-  __ LoadObject(RAX, bool_false);  // Smi == Mint -> false.
+  __ LoadObject(RAX, Bool::False());  // Smi == Mint -> false.
   __ ret();
   // TODO(srdjan): Implement Mint == Mint comparison.
 
@@ -1144,8 +1140,6 @@
 // returns false. Any non-double argument causes control flow to fall through
 // to the slow case (compiled method body).
 static bool CompareDoubles(Assembler* assembler, Condition true_condition) {
-  const Bool& bool_true = Bool::ZoneHandle(Bool::True());
-  const Bool& bool_false = Bool::ZoneHandle(Bool::False());
   Label fall_through, is_false, is_true, is_smi, double_op;
   TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
   // Both arguments are double, right operand is in RAX.
@@ -1158,10 +1152,10 @@
   __ j(true_condition, &is_true, Assembler::kNearJump);
   // Fall through false.
   __ Bind(&is_false);
-  __ LoadObject(RAX, bool_false);
+  __ LoadObject(RAX, Bool::False());
   __ ret();
   __ Bind(&is_true);
-  __ LoadObject(RAX, bool_true);
+  __ LoadObject(RAX, Bool::True());
   __ ret();
   __ Bind(&is_smi);
   __ SmiUntag(RAX);
@@ -1297,25 +1291,21 @@
 
 
 bool Intrinsifier::Double_getIsNaN(Assembler* assembler) {
-  const Bool& bool_true = Bool::ZoneHandle(Bool::True());
-  const Bool& bool_false = Bool::ZoneHandle(Bool::False());
   Label is_true;
   __ movq(RAX, Address(RSP, +1 * kWordSize));
   __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
   __ comisd(XMM0, XMM0);
   __ j(PARITY_EVEN, &is_true, Assembler::kNearJump);  // NaN -> true;
-  __ LoadObject(RAX, bool_false);
+  __ LoadObject(RAX, Bool::False());
   __ ret();
   __ Bind(&is_true);
-  __ LoadObject(RAX, bool_true);
+  __ LoadObject(RAX, Bool::True());
   __ ret();
   return true;  // Method is complete, no slow case.
 }
 
 
 bool Intrinsifier::Double_getIsNegative(Assembler* assembler) {
-  const Bool& bool_true = Bool::ZoneHandle(Bool::True());
-  const Bool& bool_false = Bool::ZoneHandle(Bool::False());
   Label is_false, is_true, is_zero;
   __ movq(RAX, Address(RSP, +1 * kWordSize));
   __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
@@ -1325,10 +1315,10 @@
   __ j(EQUAL, &is_zero, Assembler::kNearJump);  // Check for negative zero.
   __ j(ABOVE_EQUAL, &is_false, Assembler::kNearJump);  // >= 0 -> false.
   __ Bind(&is_true);
-  __ LoadObject(RAX, bool_true);
+  __ LoadObject(RAX, Bool::True());
   __ ret();
   __ Bind(&is_false);
-  __ LoadObject(RAX, bool_false);
+  __ LoadObject(RAX, Bool::False());
   __ ret();
   __ Bind(&is_zero);
   // Check for negative zero (get the sign bit).
@@ -1392,8 +1382,9 @@
   // Overflow is signalled with minint.
   Label fall_through;
   // Check for overflow and that it fits into Smi.
-  __ cmpq(RAX, Immediate(0xC000000000000000));
-  __ j(NEGATIVE, &fall_through, Assembler::kNearJump);
+  __ movq(RCX, RAX);
+  __ shlq(RCX, Immediate(1));
+  __ j(OVERFLOW, &fall_through, Assembler::kNearJump);
   __ SmiTag(RAX);
   __ ret();
   __ Bind(&fall_through);
@@ -1441,15 +1432,13 @@
 // Identity comparison.
 bool Intrinsifier::Object_equal(Assembler* assembler) {
   Label is_true;
-  const Bool& bool_true = Bool::ZoneHandle(Bool::True());
-  const Bool& bool_false = Bool::ZoneHandle(Bool::False());
   __ movq(RAX, Address(RSP, + 1 * kWordSize));
   __ cmpq(RAX, Address(RSP, + 2 * kWordSize));
   __ j(EQUAL, &is_true, Assembler::kNearJump);
-  __ LoadObject(RAX, bool_false);
+  __ LoadObject(RAX, Bool::False());
   __ ret();
   __ Bind(&is_true);
-  __ LoadObject(RAX, bool_true);
+  __ LoadObject(RAX, Bool::True());
   __ ret();
   return true;
 }
@@ -1524,8 +1513,6 @@
 //   }
 bool Intrinsifier::FixedSizeArrayIterator_getHasNext(Assembler* assembler) {
   Label fall_through, is_true;
-  const Bool& bool_true = Bool::ZoneHandle(Bool::True());
-  const Bool& bool_false = Bool::ZoneHandle(Bool::False());
   const intptr_t length_offset =
       GetOffsetForField(kFixedSizeArrayIteratorClassName, "_length");
   const intptr_t pos_offset =
@@ -1539,10 +1526,10 @@
   __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);  // Non-smi _length/_pos.
   __ cmpq(RCX, RAX);     // _length > _pos.
   __ j(GREATER, &is_true, Assembler::kNearJump);
-  __ LoadObject(RAX, bool_false);
+  __ LoadObject(RAX, Bool::False());
   __ ret();
   __ Bind(&is_true);
-  __ LoadObject(RAX, bool_true);
+  __ LoadObject(RAX, Bool::True());
   __ ret();
   __ Bind(&fall_through);
   return false;
@@ -1594,17 +1581,15 @@
 
 bool Intrinsifier::String_getIsEmpty(Assembler* assembler) {
   Label is_true;
-  const Bool& bool_true = Bool::ZoneHandle(Bool::True());
-  const Bool& bool_false = Bool::ZoneHandle(Bool::False());
   // Get length.
   __ movq(RAX, Address(RSP, + 1 * kWordSize));  // String object.
   __ movq(RAX, FieldAddress(RAX, String::length_offset()));
   __ cmpq(RAX, Immediate(Smi::RawValue(0)));
   __ j(EQUAL, &is_true, Assembler::kNearJump);
-  __ LoadObject(RAX, bool_false);
+  __ LoadObject(RAX, Bool::False());
   __ ret();
   __ Bind(&is_true);
-  __ LoadObject(RAX, bool_true);
+  __ LoadObject(RAX, Bool::True());
   __ ret();
   return true;
 }
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 5ac23bc..f76e292 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -7,11 +7,11 @@
 #include "include/dart_api.h"
 #include "platform/assert.h"
 #include "lib/mirrors.h"
+#include "vm/code_observers.h"
 #include "vm/compiler_stats.h"
 #include "vm/dart_api_state.h"
 #include "vm/dart_entry.h"
 #include "vm/debugger.h"
-#include "vm/debuginfo.h"
 #include "vm/heap.h"
 #include "vm/message_handler.h"
 #include "vm/object_store.h"
@@ -30,7 +30,6 @@
             "Track function usage and report.");
 DEFINE_FLAG(bool, trace_isolates, false,
             "Trace isolate creation and shut down.");
-DECLARE_FLAG(bool, generate_gdb_symbols);
 
 
 class IsolateMessageHandler : public MessageHandler {
@@ -48,10 +47,12 @@
 #endif
   bool IsCurrentIsolate() const;
   virtual Isolate* GetIsolate() const { return isolate_; }
+  bool UnhandledExceptionCallbackHandler(const Object& message,
+                                         const UnhandledException& error);
 
  private:
-  bool ProcessUnhandledException(const Object& result);
-
+  bool ProcessUnhandledException(const Object& message, const Error& result);
+  RawFunction* ResolveCallbackFunction();
   Isolate* isolate_;
 };
 
@@ -87,13 +88,28 @@
   StackZone zone(isolate_);
   HandleScope handle_scope(isolate_);
 
+  // If the message is in band we lookup the receive port to dispatch to.  If
+  // the receive port is closed, we drop the message without deserializing it.
+  Object& receive_port = Object::Handle();
+  if (!message->IsOOB()) {
+    receive_port = DartLibraryCalls::LookupReceivePort(message->dest_port());
+    if (receive_port.IsError()) {
+      return ProcessUnhandledException(Instance::Handle(),
+                                       Error::Cast(receive_port));
+    }
+    if (receive_port.IsNull()) {
+      delete message;
+      return true;
+    }
+  }
+
   // Parse the message.
   SnapshotReader reader(message->data(), message->len(),
                         Snapshot::kMessage, Isolate::Current());
   const Object& msg_obj = Object::Handle(reader.ReadObject());
   if (msg_obj.IsError()) {
     // An error occurred while reading the message.
-    return ProcessUnhandledException(msg_obj);
+    return ProcessUnhandledException(Instance::Handle(), Error::Cast(msg_obj));
   }
   if (!msg_obj.IsNull() && !msg_obj.IsInstance()) {
     // TODO(turnidge): We need to decide what an isolate does with
@@ -107,23 +123,89 @@
   Instance& msg = Instance::Handle();
   msg ^= msg_obj.raw();  // Can't use Instance::Cast because may be null.
 
+  bool success = true;
   if (message->IsOOB()) {
     // For now the only OOB messages are Mirrors messages.
     HandleMirrorsMessage(isolate_, message->reply_port(), msg);
-    delete message;
   } else {
     const Object& result = Object::Handle(
         DartLibraryCalls::HandleMessage(
-            message->dest_port(), message->reply_port(), msg));
-    delete message;
+            receive_port, message->reply_port(), msg));
     if (result.IsError()) {
-      return ProcessUnhandledException(result);
+      success = ProcessUnhandledException(msg, Error::Cast(result));
+    } else {
+      ASSERT(result.IsNull());
     }
-    ASSERT(result.IsNull());
   }
-  return true;
+  delete message;
+  return success;
 }
 
+RawFunction* IsolateMessageHandler::ResolveCallbackFunction() {
+  ASSERT(isolate_->object_store()->unhandled_exception_handler() != NULL);
+  String& callback_name = String::Handle(isolate_);
+  if (isolate_->object_store()->unhandled_exception_handler() !=
+      String::null()) {
+    callback_name = isolate_->object_store()->unhandled_exception_handler();
+  } else {
+    callback_name = String::New("_unhandledExceptionCallback");
+  }
+  Library& lib =
+      Library::Handle(isolate_, isolate_->object_store()->isolate_library());
+  Function& func =
+      Function::Handle(isolate_, lib.LookupLocalFunction(callback_name));
+  if (func.IsNull()) {
+    lib = isolate_->object_store()->root_library();
+    func = lib.LookupLocalFunction(callback_name);
+  }
+  return func.raw();
+}
+
+
+bool IsolateMessageHandler::UnhandledExceptionCallbackHandler(
+    const Object& message, const UnhandledException& error) {
+  const Instance& cause = Instance::Handle(isolate_, error.exception());
+  const Instance& stacktrace =
+      Instance::Handle(isolate_, error.stacktrace());
+
+  // Wrap these args into an IsolateUncaughtException object.
+  const Array& exception_args = Array::Handle(Array::New(3));
+  exception_args.SetAt(0, message);
+  exception_args.SetAt(1, cause);
+  exception_args.SetAt(2, stacktrace);
+  const Object& exception =
+      Object::Handle(isolate_,
+                     Exceptions::Create(Exceptions::kIsolateUnhandledException,
+                                        exception_args));
+  if (exception.IsError()) {
+    return false;
+  }
+  ASSERT(exception.IsInstance());
+
+  // Invoke script's callback function.
+  Object& function = Object::Handle(isolate_, ResolveCallbackFunction());
+  if (function.IsNull() || function.IsError()) {
+    return false;
+  }
+  const Array& callback_args = Array::Handle(Array::New(1));
+  callback_args.SetAt(0, exception);
+  const Object& result =
+      Object::Handle(DartEntry::InvokeStatic(Function::Cast(function),
+                                             callback_args));
+  if (result.IsError()) {
+    const Error& err = Error::Cast(result);
+    OS::PrintErr("failed calling unhandled exception callback: %s\n",
+                 err.ToErrorCString());
+    return false;
+  }
+
+  ASSERT(result.IsBool());
+  bool continue_from_exception = Bool::Cast(result).value();
+  if (continue_from_exception) {
+    isolate_->object_store()->clear_sticky_error();
+  }
+  return continue_from_exception;
+}
 
 #if defined(DEBUG)
 void IsolateMessageHandler::CheckAccess() {
@@ -137,15 +219,29 @@
 }
 
 
-bool IsolateMessageHandler::ProcessUnhandledException(const Object& result) {
-  isolate_->object_store()->set_sticky_error(Error::Cast(result));
-  // Invoke the dart unhandled exception callback if there is one.
+bool IsolateMessageHandler::ProcessUnhandledException(
+    const Object& message, const Error& result) {
+  if (result.IsUnhandledException()) {
+    // Invoke the isolate's uncaught exception handler, if it exists.
+    const UnhandledException& error = UnhandledException::Cast(result);
+    RawInstance* exception = error.exception();
+    if ((exception != isolate_->object_store()->out_of_memory()) &&
+        (exception != isolate_->object_store()->stack_overflow())) {
+      if (UnhandledExceptionCallbackHandler(message, error)) {
+        return true;
+      }
+    }
+  }
+
+  // Invoke the isolate's unhandled exception callback if there is one.
   if (Isolate::UnhandledExceptionCallback() != NULL) {
     Dart_EnterScope();
     Dart_Handle error = Api::NewHandle(isolate_, result.raw());
     (Isolate::UnhandledExceptionCallback())(error);
     Dart_ExitScope();
   }
+
+  isolate_->object_store()->set_sticky_error(result);
   return false;
 }
 
@@ -163,6 +259,7 @@
       store_buffer_(),
       message_notify_callback_(NULL),
       name_(NULL),
+      start_time_(OS::GetCurrentTimeMicros()),
       main_port_(0),
       heap_(NULL),
       object_store_(NULL),
@@ -446,9 +543,9 @@
     PrintInvokedFunctions();
   }
   CompilerStats::Print();
-  if (FLAG_generate_gdb_symbols) {
-    DebugInfo::UnregisterAllSections();
-  }
+  // TODO(asiva): Move this code to Dart::Cleanup when we have that method
+  // as the cleanup for Dart::InitOnce.
+  CodeObservers::DeleteAll();
   if (FLAG_trace_isolates) {
     StackZone zone(this);
     HandleScope handle_scope(this);
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index bfbbaa8..597ecea 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -128,6 +128,8 @@
 
   const char* name() const { return name_; }
 
+  int64_t start_time() const { return start_time_; }
+
   Dart_Port main_port() { return main_port_; }
   void set_main_port(Dart_Port port) {
     ASSERT(main_port_ == 0);  // Only set main port once.
@@ -351,6 +353,7 @@
   MegamorphicCacheTable megamorphic_cache_table_;
   Dart_MessageNotifyCallback message_notify_callback_;
   char* name_;
+  int64_t start_time_;
   Dart_Port main_port_;
   Heap* heap_;
   ObjectStore* object_store_;
@@ -372,6 +375,7 @@
   uword spawn_data_;
   GcPrologueCallbacks gc_prologue_callbacks_;
   GcEpilogueCallbacks gc_epilogue_callbacks_;
+
   // Deoptimization support.
   intptr_t* deopt_cpu_registers_copy_;
   double* deopt_xmm_registers_copy_;
diff --git a/runtime/vm/megamorphic_cache_table.cc b/runtime/vm/megamorphic_cache_table.cc
index bec06e3..6e6ed43 100644
--- a/runtime/vm/megamorphic_cache_table.cc
+++ b/runtime/vm/megamorphic_cache_table.cc
@@ -54,11 +54,10 @@
   const Code& code =
       Code::Handle(StubCode::Generate("_stub_MegamorphicMiss",
                                       StubCode::GenerateMegamorphicMissStub));
-  const String& name = String::Handle(Symbols::New("megamorphic_miss"));
   const Class& cls =
       Class::Handle(Type::Handle(Type::Function()).type_class());
   const Function& function =
-      Function::Handle(Function::New(name,
+      Function::Handle(Function::New(Symbols::MegamorphicMiss(),
                                      RawFunction::kRegularFunction,
                                      false,  // Not static.
                                      false,  // Not const.
diff --git a/runtime/vm/message.cc b/runtime/vm/message.cc
index 807de7e..73f5da3 100644
--- a/runtime/vm/message.cc
+++ b/runtime/vm/message.cc
@@ -14,9 +14,8 @@
 
 MessageQueue::~MessageQueue() {
   // Ensure that all pending messages have been released.
-#if defined(DEBUG)
+  Clear();
   ASSERT(head_ == NULL);
-#endif
 }
 
 
@@ -54,31 +53,7 @@
 }
 
 
-void MessageQueue::Flush(Dart_Port port) {
-  Message* cur = head_;
-  Message* prev = NULL;
-  while (cur != NULL) {
-    Message* next = cur->next_;
-    // If the message matches, then remove it from the queue and delete it.
-    if (cur->dest_port() == port) {
-      if (prev != NULL) {
-        prev->next_ = next;
-      } else {
-        head_ = next;
-      }
-      delete cur;
-    } else {
-      // Move prev forward.
-      prev = cur;
-    }
-    // Advance to the next message in the queue.
-    cur = next;
-  }
-  tail_ = prev;
-}
-
-
-void MessageQueue::FlushAll() {
+void MessageQueue::Clear() {
   Message* cur = head_;
   head_ = NULL;
   tail_ = NULL;
diff --git a/runtime/vm/message.h b/runtime/vm/message.h
index 9e99cfc..80d1df5 100644
--- a/runtime/vm/message.h
+++ b/runtime/vm/message.h
@@ -76,8 +76,8 @@
   // message is available.  This function will not block.
   Message* Dequeue();
 
-  void Flush(Dart_Port port);
-  void FlushAll();
+  // Clear all messages from the message queue.
+  void Clear();
 
  private:
   friend class MessageQueueTestPeer;
diff --git a/runtime/vm/message_handler.cc b/runtime/vm/message_handler.cc
index 2727eac..a3e2170 100644
--- a/runtime/vm/message_handler.cc
+++ b/runtime/vm/message_handler.cc
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/message_handler.h"
+#include "vm/port.h"
 #include "vm/dart.h"
 
 namespace dart {
@@ -150,9 +151,7 @@
     monitor_.Exit();
     Message::Priority saved_priority = message->priority();
     result = HandleMessage(message);
-    // ASSERT(Isolate::Current() == NULL);
     monitor_.Enter();
-
     if (!result) {
       // If we hit an error, we're done processing messages.
       break;
@@ -238,8 +237,6 @@
               "\tport:       %"Pd64"\n",
               name(), port);
   }
-  queue_->Flush(port);
-  oob_queue_->Flush(port);
 }
 
 
@@ -250,8 +247,8 @@
               "\thandler:    %s\n",
               name());
   }
-  queue_->FlushAll();
-  oob_queue_->FlushAll();
+  queue_->Clear();
+  oob_queue_->Clear();
 }
 
 
diff --git a/runtime/vm/message_handler_test.cc b/runtime/vm/message_handler_test.cc
index 57eeb34..7fcf7dd 100644
--- a/runtime/vm/message_handler_test.cc
+++ b/runtime/vm/message_handler_test.cc
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/message_handler.h"
+#include "vm/port.h"
 #include "vm/unit_test.h"
 
 namespace dart {
@@ -32,14 +33,17 @@
 class TestMessageHandler : public MessageHandler {
  public:
   TestMessageHandler()
-      : port_buffer_(strdup("")),
+      : port_buffer_(NULL),
+        port_buffer_size_(0),
         notify_count_(0),
         message_count_(0),
+        start_called_(false),
+        end_called_(false),
         result_(true) {
   }
 
   ~TestMessageHandler() {
-    free(port_buffer_);
+    delete[] port_buffer_;
   }
 
   void MessageNotify(Message::Priority priority) {
@@ -47,55 +51,56 @@
   }
 
   bool HandleMessage(Message* message) {
-    // For testing purposes, keep a string with a list of the ports
+    // For testing purposes, keep a list of the ports
     // for all messages we receive.
-    intptr_t len =
-        OS::SNPrint(NULL, 0, "%s %"Pd64"",
-                    port_buffer_,
-                    message->dest_port()) + 1;
-    char* buffer = reinterpret_cast<char*>(malloc(len));
-    OS::SNPrint(buffer, len, "%s %"Pd64"",
-                port_buffer_,
-                message->dest_port());
-    free(port_buffer_);
-    port_buffer_ = buffer;
+    AddPortToBuffer(message->dest_port());
     delete message;
     message_count_++;
     return result_;
   }
 
-
   bool Start() {
-    intptr_t len =
-        OS::SNPrint(NULL, 0, "%s start", port_buffer_) + 1;
-    char* buffer = reinterpret_cast<char*>(malloc(len));
-    OS::SNPrint(buffer, len, "%s start", port_buffer_);
-    free(port_buffer_);
-    port_buffer_ = buffer;
+    start_called_ = true;
     return true;
   }
 
-
   void End() {
-    intptr_t len =
-        OS::SNPrint(NULL, 0, "%s end", port_buffer_) + 1;
-    char* buffer = reinterpret_cast<char*>(malloc(len));
-    OS::SNPrint(buffer, len, "%s end", port_buffer_);
-    free(port_buffer_);
-    port_buffer_ = buffer;
+    end_called_ = true;
+    AddPortToBuffer(-2);
   }
 
-
-  const char* port_buffer() const { return port_buffer_; }
+  Dart_Port* port_buffer() const { return port_buffer_; }
   int notify_count() const { return notify_count_; }
   int message_count() const { return message_count_; }
+  bool start_called() const { return start_called_; }
+  bool end_called() const { return end_called_; }
 
   void set_result(bool result) { result_ = result; }
 
  private:
-  char* port_buffer_;
+  void AddPortToBuffer(Dart_Port port) {
+    if (port_buffer_ == NULL) {
+      port_buffer_ = new Dart_Port[10];
+      port_buffer_size_ = 10;
+    } else if (message_count_ == port_buffer_size_) {
+      int new_port_buffer_size_ = 2 * port_buffer_size_;
+      Dart_Port* new_port_buffer_ = new Dart_Port[new_port_buffer_size_];
+      for (int i = 0; i < port_buffer_size_; i++) {
+        new_port_buffer_[i] = port_buffer_[i];
+      }
+      delete[] port_buffer_;
+      port_buffer_ = new_port_buffer_;
+      port_buffer_size_ = new_port_buffer_size_;
+    }
+    port_buffer_[message_count_] = port;
+  }
+
+  Dart_Port* port_buffer_;
+  int port_buffer_size_;
   int notify_count_;
   int message_count_;
+  bool start_called_;
+  bool end_called_;
   bool result_;
 
   DISALLOW_COPY_AND_ASSIGN(TestMessageHandler);
@@ -153,9 +158,10 @@
 
   handler_peer.ClosePort(1);
 
-  // The message on port 1 is dropped from the queue.
+  // Closing the port does not drop the messages from the queue.
+  EXPECT(message1 == handler_peer.queue()->Dequeue());
   EXPECT(message2 == handler_peer.queue()->Dequeue());
-  EXPECT(NULL == handler_peer.queue()->Dequeue());
+  delete message1;
   delete message2;
 }
 
@@ -178,43 +184,58 @@
 UNIT_TEST_CASE(MessageHandler_HandleNextMessage) {
   TestMessageHandler handler;
   MessageHandlerTestPeer handler_peer(&handler);
-  Message* message1 = new Message(1, 0, NULL, 0, Message::kNormalPriority);
+  Dart_Port port1 = PortMap::CreatePort(&handler);
+  Dart_Port port2 = PortMap::CreatePort(&handler);
+  Dart_Port port3 = PortMap::CreatePort(&handler);
+  Message* message1 = new Message(port1, 0, NULL, 0, Message::kNormalPriority);
   handler_peer.PostMessage(message1);
-  Message* oob_message1 = new Message(3, 0, NULL, 0, Message::kOOBPriority);
+  Message* oob_message1 = new Message(port2, 0, NULL, 0, Message::kOOBPriority);
   handler_peer.PostMessage(oob_message1);
-  Message* message2 = new Message(2, 0, NULL, 0, Message::kNormalPriority);
+  Message* message2 = new Message(port2, 0, NULL, 0, Message::kNormalPriority);
   handler_peer.PostMessage(message2);
-  Message* oob_message2 = new Message(4, 0, NULL, 0, Message::kOOBPriority);
+  Message* oob_message2 = new Message(port3, 0, NULL, 0, Message::kOOBPriority);
   handler_peer.PostMessage(oob_message2);
 
   // We handle both oob messages and a single normal message.
   EXPECT(handler.HandleNextMessage());
-  EXPECT_STREQ(" 3 4 1", handler.port_buffer());
-  handler_peer.CloseAllPorts();
+  EXPECT_EQ(3, handler.message_count());
+  Dart_Port* ports = handler.port_buffer();
+  EXPECT_EQ(port2, ports[0]);
+  EXPECT_EQ(port3, ports[1]);
+  EXPECT_EQ(port1, ports[2]);
+  PortMap::ClosePorts(&handler);
 }
 
 
 UNIT_TEST_CASE(MessageHandler_HandleOOBMessages) {
   TestMessageHandler handler;
   MessageHandlerTestPeer handler_peer(&handler);
-  Message* message1 = new Message(1, 0, NULL, 0, Message::kNormalPriority);
+  Dart_Port port1 = PortMap::CreatePort(&handler);
+  Dart_Port port2 = PortMap::CreatePort(&handler);
+  Dart_Port port3 = PortMap::CreatePort(&handler);
+  Dart_Port port4 = PortMap::CreatePort(&handler);
+  Message* message1 = new Message(port1, 0, NULL, 0, Message::kNormalPriority);
   handler_peer.PostMessage(message1);
-  Message* message2 = new Message(2, 0, NULL, 0, Message::kNormalPriority);
+  Message* message2 = new Message(port2, 0, NULL, 0, Message::kNormalPriority);
   handler_peer.PostMessage(message2);
-  Message* oob_message1 = new Message(3, 0, NULL, 0, Message::kOOBPriority);
+  Message* oob_message1 = new Message(port3, 0, NULL, 0, Message::kOOBPriority);
   handler_peer.PostMessage(oob_message1);
-  Message* oob_message2 = new Message(4, 0, NULL, 0, Message::kOOBPriority);
+  Message* oob_message2 = new Message(port4, 0, NULL, 0, Message::kOOBPriority);
   handler_peer.PostMessage(oob_message2);
 
   // We handle both oob messages but no normal messages.
   EXPECT(handler.HandleOOBMessages());
-  EXPECT_STREQ(" 3 4", handler.port_buffer());
+  EXPECT_EQ(2, handler.message_count());
+  Dart_Port* ports = handler.port_buffer();
+  EXPECT_EQ(port3, ports[0]);
+  EXPECT_EQ(port4, ports[1]);
   handler_peer.CloseAllPorts();
 }
 
 
 struct ThreadStartInfo {
   MessageHandler* handler;
+  Dart_Port* ports;
   int count;
 };
 
@@ -224,7 +245,8 @@
   MessageHandler* handler = info->handler;
   MessageHandlerTestPeer handler_peer(handler);
   for (int i = 0; i < info->count; i++) {
-    Message* message = new Message(i + 1, 0, NULL, 0, Message::kNormalPriority);
+    Message* message =
+        new Message(info->ports[i], 0, NULL, 0, Message::kNormalPriority);
     handler_peer.PostMessage(message);
   }
 }
@@ -244,7 +266,8 @@
               TestStartFunction,
               TestEndFunction,
               reinterpret_cast<uword>(&handler));
-  Message* message = new Message(100, 0, NULL, 0, Message::kNormalPriority);
+  Dart_Port port = PortMap::CreatePort(&handler);
+  Message* message = new Message(port, 0, NULL, 0, Message::kNormalPriority);
   handler_peer.PostMessage(message);
 
   // Wait for the first message to be handled.
@@ -252,21 +275,37 @@
     OS::Sleep(10);
     sleep += 10;
   }
-  EXPECT_STREQ(" start 100", handler.port_buffer());
+  EXPECT_EQ(1, handler.message_count());
+  EXPECT(handler.start_called());
+  EXPECT(!handler.end_called());
+  Dart_Port* handler_ports = handler.port_buffer();
+  EXPECT_EQ(port, handler_ports[0]);
 
   // Start a thread which sends more messages.
+  Dart_Port* ports = new Dart_Port[10];
+  for (int i = 0; i < 10; i++) {
+    ports[i] = PortMap::CreatePort(&handler);
+  }
   ThreadStartInfo info;
   info.handler = &handler;
+  info.ports = ports;
   info.count = 10;
   Thread::Start(SendMessages, reinterpret_cast<uword>(&info));
   while (sleep < kMaxSleep && handler.message_count() < 11) {
     OS::Sleep(10);
     sleep += 10;
   }
-  EXPECT_STREQ(" start 100 1 2 3 4 5 6 7 8 9 10", handler.port_buffer());
-
+  handler_ports = handler.port_buffer();
+  EXPECT_EQ(11, handler.message_count());
+  EXPECT(handler.start_called());
+  EXPECT(!handler.end_called());
+  EXPECT_EQ(port, handler_ports[0]);
+  for (int i = 1; i < 11; i++) {
+    EXPECT_EQ(ports[i - 1], handler_ports[i]);
+  }
   handler_peer.decrement_live_ports();
   EXPECT(!handler.HasLivePorts());
+  PortMap::ClosePorts(&handler);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/message_test.cc b/runtime/vm/message_test.cc
index f302a7b..e2bb672 100644
--- a/runtime/vm/message_test.cc
+++ b/runtime/vm/message_test.cc
@@ -73,7 +73,7 @@
 }
 
 
-TEST_CASE(MessageQueue_FlushAll) {
+TEST_CASE(MessageQueue_Clear) {
   MessageQueue queue;
   MessageQueueTestPeer queue_peer(&queue);
   Dart_Port port1 = 1;
@@ -93,84 +93,10 @@
   queue.Enqueue(msg2);
 
   EXPECT(queue_peer.HasMessage());
-  queue.FlushAll();
+  queue.Clear();
   EXPECT(!queue_peer.HasMessage());
 
   // msg1 and msg2 already delete by FlushAll.
 }
 
-
-TEST_CASE(MessageQueue_Flush) {
-  MessageQueue queue;
-  MessageQueueTestPeer queue_peer(&queue);
-  Dart_Port port1 = 1;
-  Dart_Port port2 = 2;
-
-  const char* str1 = "msg1";
-  const char* str2 = "msg2";
-
-  // Add two messages on different ports.
-  Message* msg1 =
-      new Message(port1, 0, AllocMsg(str1), strlen(str1) + 1,
-                  Message::kNormalPriority);
-  queue.Enqueue(msg1);
-  Message* msg2 =
-      new Message(port2, 0, AllocMsg(str2), strlen(str2) + 1,
-                  Message::kNormalPriority);
-  queue.Enqueue(msg2);
-  EXPECT(queue_peer.HasMessage());
-
-  queue.Flush(port1);
-
-  // One message is left in the queue.
-  EXPECT(queue_peer.HasMessage());
-  Message* msg = queue.Dequeue();
-  EXPECT(msg != NULL);
-  EXPECT_STREQ(str2, reinterpret_cast<char*>(msg->data()));
-
-  EXPECT(!queue_peer.HasMessage());
-
-  // msg1 is already deleted by Flush.
-  delete msg2;
-}
-
-
-TEST_CASE(MessageQueue_Flush_MultipleMessages) {
-  MessageQueue queue;
-  MessageQueueTestPeer queue_peer(&queue);
-  Dart_Port port1 = 1;
-
-  const char* str1 = "msg1";
-  const char* str2 = "msg2";
-
-  Message* msg1 =
-      new Message(port1, 0, AllocMsg(str1), strlen(str1) + 1,
-                  Message::kNormalPriority);
-  queue.Enqueue(msg1);
-  Message* msg2 =
-      new Message(port1, 0, AllocMsg(str2), strlen(str2) + 1,
-                  Message::kNormalPriority);
-  queue.Enqueue(msg2);
-  EXPECT(queue_peer.HasMessage());
-
-  queue.Flush(port1);
-
-  // Queue is empty.
-  EXPECT(!queue_peer.HasMessage());
-  // msg1 and msg2 are already deleted by Flush.
-}
-
-
-TEST_CASE(MessageQueue_Flush_EmptyQueue) {
-  MessageQueue queue;
-  MessageQueueTestPeer queue_peer(&queue);
-  Dart_Port port1 = 1;
-
-  EXPECT(!queue_peer.HasMessage());
-  queue.Flush(port1);
-
-  // Queue is still empty.
-  EXPECT(!queue_peer.HasMessage());
-}
-
 }  // namespace dart
diff --git a/runtime/vm/native_entry.h b/runtime/vm/native_entry.h
index 6a29b50..6058c11 100644
--- a/runtime/vm/native_entry.h
+++ b/runtime/vm/native_entry.h
@@ -57,8 +57,8 @@
   const Instance& __##name##_instance__ =                                      \
       Instance::CheckedHandle(isolate, value);                                 \
   if (!__##name##_instance__.Is##type()) {                                     \
-    GrowableArray<const Object*> __args__;                                     \
-    __args__.Add(&__##name##_instance__);                                      \
+    const Array& __args__ = Array::Handle(Array::New(1));                      \
+    __args__.SetAt(0, __##name##_instance__);                                  \
     Exceptions::ThrowByType(Exceptions::kArgument, __args__);                  \
   }                                                                            \
   const type& name = type::Cast(__##name##_instance__);
@@ -72,8 +72,8 @@
   type& name = type::Handle(isolate);                                          \
   if (!__##name##_instance__.IsNull()) {                                       \
     if (!__##name##_instance__.Is##type()) {                                   \
-      GrowableArray<const Object*> __args__;                                   \
-      __args__.Add(&__##name##_instance__);                                    \
+      const Array& __args__ = Array::Handle(Array::New(1));                    \
+      __args__.SetAt(0, __##name##_instance__);                                \
       Exceptions::ThrowByType(Exceptions::kArgument, __args__);                \
     }                                                                          \
   }                                                                            \
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 5277d97..bdfc7ee 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -40,6 +40,8 @@
     "instead of showing the corresponding interface names (e.g. \"String\")");
 DEFINE_FLAG(bool, trace_disabling_optimized_code, false,
     "Trace disabling optimized code.");
+DEFINE_FLAG(int, huge_method_cutoff, 20000,
+            "Huge method cutoff: Disables optimizations for huge methods.");
 DECLARE_FLAG(bool, trace_compiler);
 DECLARE_FLAG(bool, eliminate_type_checks);
 DECLARE_FLAG(bool, enable_type_checks);
@@ -59,11 +61,13 @@
 #error RAW_NULL should not be defined.
 #endif
 #define RAW_NULL kHeapObjectTag
-RawObject* Object::null_ = reinterpret_cast<RawInstance*>(RAW_NULL);
-RawArray* Object::empty_array_ = reinterpret_cast<RawArray*>(RAW_NULL);
-RawInstance* Object::sentinel_ = reinterpret_cast<RawInstance*>(RAW_NULL);
-RawInstance* Object::transition_sentinel_ =
-    reinterpret_cast<RawInstance*>(RAW_NULL);
+Array* Object::empty_array_ = NULL;
+Instance* Object::sentinel_ = NULL;
+Instance* Object::transition_sentinel_ = NULL;
+Bool* Object::bool_true_ = NULL;
+Bool* Object::bool_false_ = NULL;
+
+RawObject* Object::null_ = reinterpret_cast<RawObject*>(RAW_NULL);
 RawClass* Object::class_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
 RawClass* Object::null_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
 RawClass* Object::dynamic_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
@@ -187,8 +191,7 @@
 
   if (is_setter) {
     // Setters need to end with '='.
-    const String& suffix = String::Handle(Symbols::Equals());
-    return String::Concat(result, suffix);
+    return String::Concat(result, Symbols::Equals());
   }
 
   return result.raw();
@@ -240,6 +243,14 @@
     Smi::handle_vtable_ = fake_smi.vtable();
   }
 
+  // Allocate the read only object handles here.
+  empty_array_ = reinterpret_cast<Array*>(Dart::AllocateReadOnlyHandle());
+  sentinel_ = reinterpret_cast<Instance*>(Dart::AllocateReadOnlyHandle());
+  transition_sentinel_ =
+      reinterpret_cast<Instance*>(Dart::AllocateReadOnlyHandle());
+  bool_true_ = reinterpret_cast<Bool*>(Dart::AllocateReadOnlyHandle());
+  bool_false_ = reinterpret_cast<Bool*>(Dart::AllocateReadOnlyHandle());
+
   Isolate* isolate = Isolate::Current();
   Heap* heap = isolate->heap();
   // Allocate and initialize the null instance.
@@ -252,9 +263,9 @@
     InitializeObject(address, kNullCid, Instance::InstanceSize());
   }
 
-  // Initialize object_store empty array to null_ in order to be able to check
+  // Initialize the empty array handle to null_ in order to be able to check
   // if the empty array was allocated (RAW_NULL is not available).
-  empty_array_ = Array::null();
+  *empty_array_ = Array::null();
 
   Class& cls = Class::Handle();
 
@@ -294,15 +305,11 @@
 
   // Allocate and initialize the sentinel values of Null class.
   {
-    Instance& sentinel = Instance::Handle();
-    sentinel ^=
+    *sentinel_ ^=
         Object::Allocate(kNullCid, Instance::InstanceSize(), Heap::kOld);
-    sentinel_ = sentinel.raw();
 
-    Instance& transition_sentinel = Instance::Handle();
-    transition_sentinel ^=
+    *transition_sentinel_ ^=
         Object::Allocate(kNullCid, Instance::InstanceSize(), Heap::kOld);
-    transition_sentinel_ = transition_sentinel.raw();
   }
 
   cls = Class::New<Instance>(kDynamicCid);
@@ -420,21 +427,25 @@
   // Allocate and initialize the empty_array instance.
   {
     uword address = heap->Allocate(Array::InstanceSize(0), Heap::kOld);
-    empty_array_ = reinterpret_cast<RawArray*>(address + kHeapObjectTag);
+    *empty_array_ = reinterpret_cast<RawArray*>(address + kHeapObjectTag);
     InitializeObject(address, kArrayCid, Array::InstanceSize(0));
-    empty_array_->ptr()->length_ = Smi::New(0);
+    empty_array_->raw()->ptr()->length_ = Smi::New(0);
   }
+
+  // Allocate and initialize singleton true and false boolean objects.
+  cls = Class::New<Bool>();
+  isolate->object_store()->set_bool_class(cls);
+  *bool_true_ = Bool::New(true);
+  *bool_false_ = Bool::New(false);
 }
 
 
 #define SET_CLASS_NAME(class_name, name)                                       \
   cls = class_name##_class();                                                  \
-  str = Symbols::name();                                                       \
-  cls.set_name(str);                                                           \
+  cls.set_name(Symbols::name());                                               \
 
 void Object::RegisterSingletonClassNames() {
   Class& cls = Class::Handle();
-  String& str = String::Handle();
 
   // Set up names for all VM singleton classes.
   SET_CLASS_NAME(class, Class);
@@ -475,11 +486,9 @@
   // Set up names for object array and one byte string class which are
   // pre-allocated in the vm isolate also.
   cls = Dart::vm_isolate()->object_store()->array_class();
-  str = Symbols::ObjectArray();
-  cls.set_name(str);
+  cls.set_name(Symbols::ObjectArray());
   cls = Dart::vm_isolate()->object_store()->one_byte_string_class();
-  str = Symbols::OneByteString();
-  cls.set_name(str);
+  cls.set_name(Symbols::OneByteString());
 }
 
 
@@ -573,8 +582,11 @@
   cls.set_type_arguments_field_offset(
       GrowableObjectArray::type_arguments_offset());
 
-  // canonical_type_arguments_ are NULL terminated.
-  array = Array::New(4);
+  // canonical_type_arguments_ are Smi terminated.
+  // Last element contains the count of used slots.
+  const intptr_t kInitialCanonicalTypeArgumentsSize = 4;
+  array = Array::New(kInitialCanonicalTypeArgumentsSize + 1);
+  array.SetAt(kInitialCanonicalTypeArgumentsSize, Smi::Handle(Smi::New(0)));
   object_store->set_canonical_type_arguments(array);
 
   // Setup type class early in the process.
@@ -618,13 +630,11 @@
   String& name = String::Handle();
   cls = Class::New<Bool>();
   object_store->set_bool_class(cls);
-  name = Symbols::Bool();
-  RegisterClass(cls, name, core_lib);
+  RegisterClass(cls, Symbols::Bool(), core_lib);
   pending_classes.Add(cls, Heap::kOld);
 
   cls = object_store->array_class();  // Was allocated above.
-  name = Symbols::ObjectArray();
-  RegisterPrivateClass(cls, name, core_lib);
+  RegisterPrivateClass(cls, Symbols::ObjectArray(), core_lib);
   pending_classes.Add(cls, Heap::kOld);
   // We cannot use NewNonParameterizedType(cls), because Array is parameterized.
   type ^= Type::New(Object::Handle(cls.raw()),
@@ -635,51 +645,43 @@
   object_store->set_array_type(type);
 
   cls = object_store->growable_object_array_class();  // Was allocated above.
-  name = Symbols::GrowableObjectArray();
-  RegisterPrivateClass(cls, name, core_lib);
+  RegisterPrivateClass(cls, Symbols::GrowableObjectArray(), core_lib);
   pending_classes.Add(cls, Heap::kOld);
 
   cls = Class::New<ImmutableArray>();
   object_store->set_immutable_array_class(cls);
   cls.set_type_arguments_field_offset(Array::type_arguments_offset());
   ASSERT(object_store->immutable_array_class() != object_store->array_class());
-  name = Symbols::ImmutableArray();
-  RegisterPrivateClass(cls, name, core_lib);
+  RegisterPrivateClass(cls, Symbols::ImmutableArray(), core_lib);
   pending_classes.Add(cls, Heap::kOld);
 
   cls = object_store->one_byte_string_class();  // Was allocated above.
-  name = Symbols::OneByteString();
-  RegisterPrivateClass(cls, name, core_lib);
+  RegisterPrivateClass(cls, Symbols::OneByteString(), core_lib);
   pending_classes.Add(cls, Heap::kOld);
 
   cls = object_store->two_byte_string_class();  // Was allocated above.
-  name = Symbols::TwoByteString();
-  RegisterPrivateClass(cls, name, core_lib);
+  RegisterPrivateClass(cls, Symbols::TwoByteString(), core_lib);
   pending_classes.Add(cls, Heap::kOld);
 
   cls = Class::NewStringClass(kExternalOneByteStringCid);
   object_store->set_external_one_byte_string_class(cls);
-  name = Symbols::ExternalOneByteString();
-  RegisterPrivateClass(cls, name, core_lib);
+  RegisterPrivateClass(cls, Symbols::ExternalOneByteString(), core_lib);
   pending_classes.Add(cls, Heap::kOld);
 
   cls = Class::NewStringClass(kExternalTwoByteStringCid);
   object_store->set_external_two_byte_string_class(cls);
-  name = Symbols::ExternalTwoByteString();
-  RegisterPrivateClass(cls, name, core_lib);
+  RegisterPrivateClass(cls, Symbols::ExternalTwoByteString(), core_lib);
   pending_classes.Add(cls, Heap::kOld);
 
   cls = Class::New<Stacktrace>();
   object_store->set_stacktrace_class(cls);
-  name = Symbols::Stacktrace();
-  RegisterClass(cls, name, core_lib);
+  RegisterClass(cls, Symbols::Stacktrace(), core_lib);
   pending_classes.Add(cls, Heap::kOld);
   // Super type set below, after Object is allocated.
 
   cls = Class::New<JSRegExp>();
   object_store->set_jsregexp_class(cls);
-  name = Symbols::JSSyntaxRegExp();
-  RegisterPrivateClass(cls, name, core_lib);
+  RegisterPrivateClass(cls, Symbols::JSSyntaxRegExp(), core_lib);
   pending_classes.Add(cls, Heap::kOld);
 
   // Initialize the base interfaces used by the core VM classes.
@@ -688,8 +690,7 @@
   // Allocate and initialize the pre-allocated classes in the core library.
   cls = Class::New<Instance>(kInstanceCid);
   object_store->set_object_class(cls);
-  name = Symbols::Object();
-  cls.set_name(name);
+  cls.set_name(Symbols::Object());
   cls.set_script(script);
   cls.set_is_prefinalized();
   core_lib.AddClass(cls);
@@ -698,162 +699,134 @@
   object_store->set_object_type(type);
 
   cls = object_store->type_class();
-  name = Symbols::Type();
-  RegisterPrivateClass(cls, name, core_lib);
+  RegisterPrivateClass(cls, Symbols::Type(), core_lib);
   pending_classes.Add(cls, Heap::kOld);
 
   cls = object_store->type_parameter_class();
-  name = Symbols::TypeParameter();
-  RegisterPrivateClass(cls, name, core_lib);
+  RegisterPrivateClass(cls, Symbols::TypeParameter(), core_lib);
   pending_classes.Add(cls, Heap::kOld);
 
   cls = Class::New<Integer>();
   object_store->set_integer_implementation_class(cls);
-  name = Symbols::IntegerImplementation();
-  RegisterPrivateClass(cls, name, core_lib);
+  RegisterPrivateClass(cls, Symbols::IntegerImplementation(), core_lib);
   pending_classes.Add(cls, Heap::kOld);
 
   cls = Class::New<Smi>();
   object_store->set_smi_class(cls);
-  name = Symbols::Smi();
-  RegisterPrivateClass(cls, name, core_lib);
+  RegisterPrivateClass(cls, Symbols::_Smi(), core_lib);
   pending_classes.Add(cls, Heap::kOld);
 
   cls = Class::New<Mint>();
   object_store->set_mint_class(cls);
-  name = Symbols::Mint();
-  RegisterPrivateClass(cls, name, core_lib);
+  RegisterPrivateClass(cls, Symbols::_Mint(), core_lib);
   pending_classes.Add(cls, Heap::kOld);
 
   cls = Class::New<Bigint>();
   object_store->set_bigint_class(cls);
-  name = Symbols::Bigint();
-  RegisterPrivateClass(cls, name, core_lib);
+  RegisterPrivateClass(cls, Symbols::_Bigint(), core_lib);
   pending_classes.Add(cls, Heap::kOld);
 
   cls = Class::New<Double>();
   object_store->set_double_class(cls);
-  name = Symbols::Double();
-  RegisterPrivateClass(cls, name, core_lib);
+  RegisterPrivateClass(cls, Symbols::_Double(), core_lib);
   pending_classes.Add(cls, Heap::kOld);
 
   cls = Class::New<WeakProperty>();
   object_store->set_weak_property_class(cls);
-  name = Symbols::_WeakProperty();
-  RegisterPrivateClass(cls, name, core_lib);
+  RegisterPrivateClass(cls, Symbols::_WeakProperty(), core_lib);
 
   Library::InitScalarlistLibrary(isolate);
   Library& scalarlist_lib = Library::Handle(Library::ScalarlistLibrary());
 
   cls = Class::New<Int8Array>();
   object_store->set_int8_array_class(cls);
-  name = Symbols::_Int8Array();
-  RegisterPrivateClass(cls, name, scalarlist_lib);
+  RegisterPrivateClass(cls, Symbols::_Int8Array(), scalarlist_lib);
 
   cls = Class::New<Uint8Array>();
   object_store->set_uint8_array_class(cls);
-  name = Symbols::_Uint8Array();
-  RegisterPrivateClass(cls, name, scalarlist_lib);
+  RegisterPrivateClass(cls, Symbols::_Uint8Array(), scalarlist_lib);
 
   cls = Class::New<Uint8ClampedArray>();
   object_store->set_uint8_clamped_array_class(cls);
-  name = Symbols::_Uint8ClampedArray();
-  RegisterPrivateClass(cls, name, scalarlist_lib);
+  RegisterPrivateClass(cls, Symbols::_Uint8ClampedArray(), scalarlist_lib);
 
   cls = Class::New<Int16Array>();
   object_store->set_int16_array_class(cls);
-  name = Symbols::_Int16Array();
-  RegisterPrivateClass(cls, name, scalarlist_lib);
+  RegisterPrivateClass(cls, Symbols::_Int16Array(), scalarlist_lib);
 
   cls = Class::New<Uint16Array>();
   object_store->set_uint16_array_class(cls);
-  name = Symbols::_Uint16Array();
-  RegisterPrivateClass(cls, name, scalarlist_lib);
+  RegisterPrivateClass(cls, Symbols::_Uint16Array(), scalarlist_lib);
 
   cls = Class::New<Int32Array>();
   object_store->set_int32_array_class(cls);
-  name = Symbols::_Int32Array();
-  RegisterPrivateClass(cls, name, scalarlist_lib);
+  RegisterPrivateClass(cls, Symbols::_Int32Array(), scalarlist_lib);
 
   cls = Class::New<Uint32Array>();
   object_store->set_uint32_array_class(cls);
-  name = Symbols::_Uint32Array();
-  RegisterPrivateClass(cls, name, scalarlist_lib);
+  RegisterPrivateClass(cls, Symbols::_Uint32Array(), scalarlist_lib);
 
   cls = Class::New<Int64Array>();
   object_store->set_int64_array_class(cls);
-  name = Symbols::_Int64Array();
-  RegisterPrivateClass(cls, name, scalarlist_lib);
+  RegisterPrivateClass(cls, Symbols::_Int64Array(), scalarlist_lib);
 
   cls = Class::New<Uint64Array>();
   object_store->set_uint64_array_class(cls);
-  name = Symbols::_Uint64Array();
-  RegisterPrivateClass(cls, name, scalarlist_lib);
+  RegisterPrivateClass(cls, Symbols::_Uint64Array(), scalarlist_lib);
 
   cls = Class::New<Float32Array>();
   object_store->set_float32_array_class(cls);
-  name = Symbols::_Float32Array();
-  RegisterPrivateClass(cls, name, scalarlist_lib);
+  RegisterPrivateClass(cls, Symbols::_Float32Array(), scalarlist_lib);
 
   cls = Class::New<Float64Array>();
   object_store->set_float64_array_class(cls);
-  name = Symbols::_Float64Array();
-  RegisterPrivateClass(cls, name, scalarlist_lib);
+  RegisterPrivateClass(cls, Symbols::_Float64Array(), scalarlist_lib);
 
   cls = Class::New<ExternalInt8Array>();
   object_store->set_external_int8_array_class(cls);
-  name = Symbols::_ExternalInt8Array();
-  RegisterPrivateClass(cls, name, scalarlist_lib);
+  RegisterPrivateClass(cls, Symbols::_ExternalInt8Array(), scalarlist_lib);
 
   cls = Class::New<ExternalUint8Array>();
   object_store->set_external_uint8_array_class(cls);
-  name = Symbols::_ExternalUint8Array();
-  RegisterPrivateClass(cls, name, scalarlist_lib);
+  RegisterPrivateClass(cls, Symbols::_ExternalUint8Array(), scalarlist_lib);
 
   cls = Class::New<ExternalUint8ClampedArray>();
   object_store->set_external_uint8_clamped_array_class(cls);
-  name = Symbols::_ExternalUint8ClampedArray();
-  RegisterPrivateClass(cls, name, scalarlist_lib);
+  RegisterPrivateClass(cls,
+                       Symbols::_ExternalUint8ClampedArray(),
+                       scalarlist_lib);
 
   cls = Class::New<ExternalInt16Array>();
   object_store->set_external_int16_array_class(cls);
-  name = Symbols::_ExternalInt16Array();
-  RegisterPrivateClass(cls, name, scalarlist_lib);
+  RegisterPrivateClass(cls, Symbols::_ExternalInt16Array(), scalarlist_lib);
 
   cls = Class::New<ExternalUint16Array>();
   object_store->set_external_uint16_array_class(cls);
-  name = Symbols::_ExternalUint16Array();
-  RegisterPrivateClass(cls, name, scalarlist_lib);
+  RegisterPrivateClass(cls, Symbols::_ExternalUint16Array(), scalarlist_lib);
 
   cls = Class::New<ExternalInt32Array>();
   object_store->set_external_int32_array_class(cls);
-  name = Symbols::_ExternalInt32Array();
-  RegisterPrivateClass(cls, name, scalarlist_lib);
+  RegisterPrivateClass(cls, Symbols::_ExternalInt32Array(), scalarlist_lib);
 
   cls = Class::New<ExternalUint32Array>();
   object_store->set_external_uint32_array_class(cls);
-  name = Symbols::_ExternalUint32Array();
-  RegisterPrivateClass(cls, name, scalarlist_lib);
+  RegisterPrivateClass(cls, Symbols::_ExternalUint32Array(), scalarlist_lib);
 
   cls = Class::New<ExternalInt64Array>();
   object_store->set_external_int64_array_class(cls);
-  name = Symbols::_ExternalInt64Array();
-  RegisterPrivateClass(cls, name, scalarlist_lib);
+  RegisterPrivateClass(cls, Symbols::_ExternalInt64Array(), scalarlist_lib);
 
   cls = Class::New<ExternalUint64Array>();
   object_store->set_external_uint64_array_class(cls);
-  name = Symbols::_ExternalUint64Array();
-  RegisterPrivateClass(cls, name, scalarlist_lib);
+  RegisterPrivateClass(cls, Symbols::_ExternalUint64Array(), scalarlist_lib);
 
   cls = Class::New<ExternalFloat32Array>();
   object_store->set_external_float32_array_class(cls);
-  name = Symbols::_ExternalFloat32Array();
-  RegisterPrivateClass(cls, name, scalarlist_lib);
+  RegisterPrivateClass(cls, Symbols::_ExternalFloat32Array(), scalarlist_lib);
 
   cls = Class::New<ExternalFloat64Array>();
   object_store->set_external_float64_array_class(cls);
-  name = Symbols::_ExternalFloat64Array();
-  RegisterPrivateClass(cls, name, scalarlist_lib);
+  RegisterPrivateClass(cls, Symbols::_ExternalFloat64Array(), scalarlist_lib);
 
   // Set the super type of class Stacktrace to Object type so that the
   // 'toString' method is implemented.
@@ -862,30 +835,28 @@
 
   // Note: The abstract class Function is represented by VM class
   // DartFunction, not VM class Function.
-  name = Symbols::Function();
   cls = Class::New<DartFunction>();
-  RegisterClass(cls, name, core_lib);
+  RegisterClass(cls, Symbols::Function(), core_lib);
   pending_classes.Add(cls, Heap::kOld);
   type = Type::NewNonParameterizedType(cls);
   object_store->set_function_type(type);
 
   cls = Class::New<Number>();
-  name = Symbols::Number();
-  RegisterClass(cls, name, core_lib);
+  RegisterClass(cls, Symbols::Number(), core_lib);
   pending_classes.Add(cls, Heap::kOld);
   type = Type::NewNonParameterizedType(cls);
   object_store->set_number_type(type);
 
-  name = Symbols::New("int");
-  cls = Class::New<Instance>(name, script, Scanner::kDummyTokenIndex);
-  RegisterClass(cls, name, core_lib);
+  cls = Class::New<Instance>(Symbols::Int(), script, Scanner::kDummyTokenIndex);
+  RegisterClass(cls, Symbols::Int(), core_lib);
   pending_classes.Add(cls, Heap::kOld);
   type = Type::NewNonParameterizedType(cls);
   object_store->set_int_type(type);
 
-  name = Symbols::New("double");
-  cls = Class::New<Instance>(name, script, Scanner::kDummyTokenIndex);
-  RegisterClass(cls, name, core_lib);
+  cls = Class::New<Instance>(Symbols::Double(),
+                             script,
+                             Scanner::kDummyTokenIndex);
+  RegisterClass(cls, Symbols::Double(), core_lib);
   pending_classes.Add(cls, Heap::kOld);
   type = Type::NewNonParameterizedType(cls);
   object_store->set_double_type(type);
@@ -897,9 +868,10 @@
   type = Type::NewNonParameterizedType(cls);
   object_store->set_string_type(type);
 
-  name = Symbols::New("List");
-  cls = Class::New<Instance>(name, script, Scanner::kDummyTokenIndex);
-  RegisterClass(cls, name, core_lib);
+  cls = Class::New<Instance>(Symbols::List(),
+                             script,
+                             Scanner::kDummyTokenIndex);
+  RegisterClass(cls, Symbols::List(), core_lib);
   pending_classes.Add(cls, Heap::kOld);
   object_store->set_list_class(cls);
 
@@ -935,13 +907,6 @@
   type = Type::NewNonParameterizedType(cls);
   object_store->set_dynamic_type(type);
 
-  // Allocate pre-initialized values.
-  Bool& bool_value = Bool::Handle();
-  bool_value = Bool::New(true);
-  object_store->set_true_value(bool_value);
-  bool_value = Bool::New(false);
-  object_store->set_false_value(bool_value);
-
   // Setup some default native field classes which can be extended for
   // specifying native fields in dart classes.
   Library::InitNativeWrappersLibrary(isolate);
@@ -1169,13 +1134,6 @@
 
   cls = Class::New<WeakProperty>();
   object_store->set_weak_property_class(cls);
-
-  // Allocate pre-initialized values.
-  Bool& bool_value = Bool::Handle();
-  bool_value = Bool::New(true);
-  object_store->set_true_value(bool_value);
-  bool_value = Bool::New(false);
-  object_store->set_false_value(bool_value);
 }
 
 
@@ -1250,9 +1208,13 @@
 };
 
 
+bool Object::IsReadOnlyHandle() const {
+  return Dart::IsReadOnlyHandle(reinterpret_cast<uword>(this));
+}
+
+
 bool Object::IsNotTemporaryScopedHandle() const {
-  return (IsZoneHandle() ||
-          Symbols::IsPredefinedHandle(reinterpret_cast<uword>(this)));
+  return (IsZoneHandle() || IsReadOnlyHandle());
 }
 
 
@@ -1286,9 +1248,9 @@
     case kSmiCid:
     case kMintCid:
     case kBigintCid:
-      return Symbols::New("int");
+      return Symbols::Int().raw();
     case kDoubleCid:
-      return Symbols::New("double");
+      return Symbols::Double().raw();
     case kOneByteStringCid:
     case kTwoByteStringCid:
     case kExternalOneByteStringCid:
@@ -1297,40 +1259,40 @@
     case kArrayCid:
     case kImmutableArrayCid:
     case kGrowableObjectArrayCid:
-      return Symbols::New("List");
+      return Symbols::List().raw();
     case kInt8ArrayCid:
     case kExternalInt8ArrayCid:
-      return Symbols::New("Int8List");
+      return Symbols::Int8List().raw();
     case kUint8ArrayCid:
     case kExternalUint8ArrayCid:
-      return Symbols::New("Uint8List");
+      return Symbols::Uint8List().raw();
     case kUint8ClampedArrayCid:
     case kExternalUint8ClampedArrayCid:
-      return Symbols::New("Uint8ClampedList");
+      return Symbols::Uint8ClampedList().raw();
     case kInt16ArrayCid:
     case kExternalInt16ArrayCid:
-      return Symbols::New("Int16List");
+      return Symbols::Int16List().raw();
     case kUint16ArrayCid:
     case kExternalUint16ArrayCid:
-      return Symbols::New("Uint16List");
+      return Symbols::Uint16List().raw();
     case kInt32ArrayCid:
     case kExternalInt32ArrayCid:
-      return Symbols::New("Int32List");
+      return Symbols::Int32List().raw();
     case kUint32ArrayCid:
     case kExternalUint32ArrayCid:
-      return Symbols::New("Uint32List");
+      return Symbols::Uint32List().raw();
     case kInt64ArrayCid:
     case kExternalInt64ArrayCid:
-      return Symbols::New("Int64List");
+      return Symbols::Int64List().raw();
     case kUint64ArrayCid:
     case kExternalUint64ArrayCid:
-      return Symbols::New("Uint64List");
+      return Symbols::Uint64List().raw();
     case kFloat32ArrayCid:
     case kExternalFloat32ArrayCid:
-      return Symbols::New("Float32List");
+      return Symbols::Float32List().raw();
     case kFloat64ArrayCid:
     case kExternalFloat64ArrayCid:
-      return Symbols::New("Float64List");
+      return Symbols::Float64List().raw();
     default:
       if (!IsSignatureClass()) {
         const String& name = String::Handle(Name());
@@ -1415,15 +1377,15 @@
 
 // Initialize class fields of type Array with empty array.
 void Class::InitEmptyFields() {
-  if (Object::empty_array() == Array::null()) {
+  if (Object::empty_array().raw() == Array::null()) {
     // The empty array has not been initialized yet.
     return;
   }
-  StorePointer(&raw_ptr()->interfaces_, Object::empty_array());
-  StorePointer(&raw_ptr()->constants_, Object::empty_array());
-  StorePointer(&raw_ptr()->canonical_types_, Object::empty_array());
-  StorePointer(&raw_ptr()->functions_, Object::empty_array());
-  StorePointer(&raw_ptr()->fields_, Object::empty_array());
+  StorePointer(&raw_ptr()->interfaces_, Object::empty_array().raw());
+  StorePointer(&raw_ptr()->constants_, Object::empty_array().raw());
+  StorePointer(&raw_ptr()->canonical_types_, Object::empty_array().raw());
+  StorePointer(&raw_ptr()->functions_, Object::empty_array().raw());
+  StorePointer(&raw_ptr()->fields_, Object::empty_array().raw());
 }
 
 
@@ -1837,15 +1799,14 @@
   const intptr_t token_pos = signature_function.token_pos();
   Class& result = Class::Handle(New<Instance>(name, script, token_pos));
   const Type& super_type = Type::Handle(Type::ObjectType());
-  const Array& empty_array = Array::Handle(Object::empty_array());
   ASSERT(!super_type.IsNull());
   result.set_instance_size(Closure::InstanceSize());
   result.set_next_field_offset(Closure::InstanceSize());
   result.set_super_type(super_type);
   result.set_signature_function(signature_function);
   result.set_type_parameters(type_parameters);
-  result.SetFields(empty_array);
-  result.SetFunctions(empty_array);
+  result.SetFields(Object::empty_array());
+  result.SetFunctions(Object::empty_array());
   result.set_type_arguments_field_offset(
       Closure::type_arguments_offset());
   // Implements interface "Function".
@@ -1883,10 +1844,9 @@
                                   int field_count) {
   Class& cls = Class::Handle(library.LookupClass(name));
   if (cls.IsNull()) {
-    const Array& empty_array = Array::Handle(Object::empty_array());
     cls = New<Instance>(name, Script::Handle(), Scanner::kDummyTokenIndex);
-    cls.SetFields(empty_array);
-    cls.SetFunctions(empty_array);
+    cls.SetFields(Object::empty_array());
+    cls.SetFunctions(Object::empty_array());
     // Set super class to Object.
     cls.set_super_type(Type::Handle(Type::ObjectType()));
     // Compute instance size. First word contains a pointer to a properly
@@ -2119,13 +2079,13 @@
                           malformed_error);
     }
     // Check if type S has a call() method of function type T.
-    const String& function_name = String::Handle(Symbols::Call());
-    Function& function = Function::Handle(LookupDynamicFunction(function_name));
+    Function& function =
+        Function::Handle(LookupDynamicFunction(Symbols::Call()));
     if (function.IsNull()) {
       // Walk up the super_class chain.
       Class& cls = Class::Handle(SuperClass());
       while (!cls.IsNull() && function.IsNull()) {
-        function = cls.LookupDynamicFunction(function_name);
+        function = cls.LookupDynamicFunction(Symbols::Call());
         cls = cls.SuperClass();
       }
     }
@@ -2333,7 +2293,7 @@
   for (intptr_t i = 0; i < len; i++) {
     func ^= funcs.At(i);
     if ((func.token_pos() <= token_pos) &&
-        (token_pos < func.end_token_pos())) {
+        (token_pos <= func.end_token_pos())) {
       return func.raw();
     }
   }
@@ -2473,11 +2433,9 @@
   if (library_prefix() != LibraryPrefix::null()) {
     const LibraryPrefix& lib_prefix = LibraryPrefix::Handle(library_prefix());
     String& name = String::Handle();
-    String& str = String::Handle();
     name = lib_prefix.name();  // Qualifier.
-    str = Symbols::Dot();
-    name = String::Concat(name, str);
-    str = ident();
+    name = String::Concat(name, Symbols::Dot());
+    const String& str = String::Handle(ident());
     name = String::Concat(name, str);
     return name.raw();
   } else {
@@ -2538,6 +2496,29 @@
 }
 
 
+static intptr_t FinalizeHash(uword hash) {
+  hash += hash << 3;
+  hash ^= hash >> 11;
+  hash += hash << 15;
+  return hash;
+}
+
+
+intptr_t AbstractTypeArguments::Hash() const {
+  if (IsNull()) return 0;
+  uword result = 0;
+  intptr_t num_types = Length();
+  AbstractType& type = AbstractType::Handle();
+  for (intptr_t i = 0; i < num_types; i++) {
+    type = TypeAt(i);
+    result += type.Hash();
+    result += result << 10;
+    result ^= result >> 6;
+  }
+  return FinalizeHash(result);
+}
+
+
 RawString* AbstractTypeArguments::SubvectorName(
     intptr_t from_index,
     intptr_t len,
@@ -2547,18 +2528,17 @@
   const intptr_t num_strings = 2*len + 1;  // "<""T"", ""T"">".
   const Array& strings = Array::Handle(Array::New(num_strings));
   intptr_t s = 0;
-  strings.SetAt(s++, String::Handle(Symbols::New("<")));
-  const String& kCommaSpace = String::Handle(Symbols::New(", "));
+  strings.SetAt(s++, Symbols::LAngleBracket());
   AbstractType& type = AbstractType::Handle();
   for (intptr_t i = 0; i < len; i++) {
     type = TypeAt(from_index + i);
     name = type.BuildName(name_visibility);
     strings.SetAt(s++, name);
     if (i < len - 1) {
-      strings.SetAt(s++, kCommaSpace);
+      strings.SetAt(s++, Symbols::CommaSpace());
     }
   }
-  strings.SetAt(s++, String::Handle(Symbols::New(">")));
+  strings.SetAt(s++, Symbols::RAngleBracket());
   ASSERT(s == num_strings);
   name = String::ConcatAll(strings);
   return Symbols::New(name);
@@ -2871,36 +2851,108 @@
 }
 
 
+static void GrowCanonicalTypeArguments(Isolate* isolate, const Array& table) {
+  // Last element of the array is the number of used elements.
+  intptr_t table_size = table.Length() - 1;
+  intptr_t new_table_size = table_size * 2;
+  Array& new_table = Array::Handle(isolate, Array::New(new_table_size + 1));
+  // Copy all elements from the original table to the newly allocated
+  // array.
+  TypeArguments& element = TypeArguments::Handle(isolate);
+  Object& new_element = Object::Handle(isolate);
+  for (intptr_t i = 0; i < table_size; i++) {
+    element ^= table.At(i);
+    if (!element.IsNull()) {
+      intptr_t hash = element.Hash();
+      ASSERT(Utils::IsPowerOfTwo(new_table_size));
+      intptr_t index = hash & (new_table_size - 1);
+      new_element = new_table.At(index);
+      while (!new_element.IsNull()) {
+        index = (index + 1) & (new_table_size - 1);  // Move to next element.
+        new_element = new_table.At(index);
+      }
+      new_table.SetAt(index, element);
+    }
+  }
+  // Copy used count.
+  new_element = table.At(table_size);
+  new_table.SetAt(new_table_size, new_element);
+  // Remember the new table now.
+  isolate->object_store()->set_canonical_type_arguments(new_table);
+}
+
+
+static void InsertIntoCanonicalTypeArguments(Isolate* isolate,
+                                             const Array& table,
+                                             const TypeArguments& arguments,
+                                             intptr_t index) {
+  arguments.SetCanonical();  // Mark object as being canonical.
+  table.SetAt(index, arguments);  // Remember the new element.
+  // Update used count.
+  // Last element of the array is the number of used elements.
+  intptr_t table_size = table.Length() - 1;
+  Smi& used = Smi::Handle(isolate);
+  used ^= table.At(table_size);
+  intptr_t used_elements = used.Value() + 1;
+  used = Smi::New(used_elements);
+  table.SetAt(table_size, used);
+
+  // Rehash if table is 75% full.
+  if (used_elements > ((table_size / 4) * 3)) {
+    GrowCanonicalTypeArguments(isolate, table);
+  }
+}
+
+
+static intptr_t FindIndexInCanonicalTypeArguments(
+    Isolate* isolate,
+    const Array& table,
+    const TypeArguments& arguments,
+    intptr_t hash) {
+  // Last element of the array is the number of used elements.
+  intptr_t table_size = table.Length() - 1;
+  ASSERT(Utils::IsPowerOfTwo(table_size));
+  intptr_t index = hash & (table_size - 1);
+
+  TypeArguments& current = TypeArguments::Handle(isolate);
+  current ^= table.At(index);
+  while (!current.IsNull() && !current.Equals(arguments)) {
+    index = (index + 1) & (table_size - 1);  // Move to next element.
+    current ^= table.At(index);
+  }
+  return index;  // Index of element if found or slot into which to add it.
+}
+
+
 RawAbstractTypeArguments* TypeArguments::Canonicalize() const {
   if (IsNull() || IsCanonical()) {
     ASSERT(IsOld());
     return this->raw();
   }
-  ObjectStore* object_store = Isolate::Current()->object_store();
-  // 'table' must be null terminated.
-  Array& table = Array::Handle(object_store->canonical_type_arguments());
+  Isolate* isolate = Isolate::Current();
+  ObjectStore* object_store = isolate->object_store();
+  const Array& table = Array::Handle(isolate,
+                                     object_store->canonical_type_arguments());
   ASSERT(table.Length() > 0);
-  intptr_t index = 0;
-  TypeArguments& result = TypeArguments::Handle();
+  intptr_t index = FindIndexInCanonicalTypeArguments(isolate,
+                                                     table,
+                                                     *this,
+                                                     Hash());
+  TypeArguments& result = TypeArguments::Handle(isolate);
   result ^= table.At(index);
-  while (!result.IsNull()) {
-    if (this->Equals(result)) {
-      return result.raw();
+  if (result.IsNull()) {
+    // Make sure we have an old space object and add it to the table.
+    if (this->IsNew()) {
+      result ^= Object::Clone(*this, Heap::kOld);
+    } else {
+      result ^= this->raw();
     }
-    result ^= table.At(++index);
+    ASSERT(result.IsOld());
+    InsertIntoCanonicalTypeArguments(isolate, table, result, index);
   }
-  // Not found. Add 'this' to table.
-  result ^= this->raw();
-  if (result.IsNew()) {
-    result ^= Object::Clone(result, Heap::kOld);
-  }
-  ASSERT(result.IsOld());
-  if (index == table.Length() - 1) {
-    table = Array::Grow(table, table.Length() + 4, Heap::kOld);
-    object_store->set_canonical_type_arguments(table);
-  }
-  table.SetAt(index, result);
-  result.SetCanonical();
+  ASSERT(result.Equals(*this));
+  ASSERT(!result.IsNull());
+  ASSERT(result.IsTypeArguments());
   return result.raw();
 }
 
@@ -3402,7 +3454,8 @@
 bool Function::is_optimizable() const {
   return OptimizableBit::decode(raw_ptr()->kind_tag_) &&
          (script() != Script::null()) &&
-         !is_native();
+         !is_native() &&
+         ((end_token_pos() - token_pos()) < FLAG_huge_method_cutoff);
 }
 
 
@@ -3435,7 +3488,7 @@
   // '==' call is handled specially.
   return InlinableBit::decode(raw_ptr()->kind_tag_) &&
          HasCode() &&
-         name() != Symbols::EqualOperator();
+         name() != Symbols::EqualOperator().raw();
 }
 
 
@@ -3841,9 +3894,8 @@
   ASSERT(name.IsOneByteString());
   ASSERT(!owner.IsNull());
   const Function& result = Function::Handle(Function::New());
-  const Array& empty_array = Array::Handle(Object::empty_array());
-  result.set_parameter_types(empty_array);
-  result.set_parameter_names(empty_array);
+  result.set_parameter_types(Object::empty_array());
+  result.set_parameter_names(Object::empty_array());
   result.set_name(name);
   result.set_kind(kind);
   result.set_is_static(is_static);
@@ -3858,6 +3910,8 @@
   result.set_num_optional_parameters(0);
   result.set_usage_counter(0);
   result.set_deoptimization_counter(0);
+  result.set_optimized_instruction_count(0);
+  result.set_optimized_call_site_count(0);
   result.set_is_optimizable(true);
   result.set_has_finally(false);
   result.set_is_native(false);
@@ -3935,8 +3989,7 @@
   // Add implicit closure object parameter.
   param_type = Type::DynamicType();
   closure_function.SetParameterTypeAt(0, param_type);
-  param_name = Symbols::ClosureParameter();
-  closure_function.SetParameterNameAt(0, param_name);
+  closure_function.SetParameterNameAt(0, Symbols::ClosureParameter());
   for (int i = kClosure; i < num_params; i++) {
     param_type = ParameterTypeAt(has_receiver - kClosure + i);
     closure_function.SetParameterTypeAt(i, param_type);
@@ -3980,23 +4033,11 @@
     const AbstractTypeArguments& instantiator) const {
   const GrowableObjectArray& pieces =
       GrowableObjectArray::Handle(GrowableObjectArray::New());
-  const String& kCommaSpace = String::Handle(Symbols::New(", "));
-  const String& kColonSpace = String::Handle(Symbols::New(": "));
-  const String& kLParen = String::Handle(Symbols::New("("));
-  const String& kRParenArrow = String::Handle(Symbols::New(") => "));
-  const String& kLBracket = String::Handle(Symbols::New("["));
-  const String& kRBracket = String::Handle(Symbols::New("]"));
-  const String& kLBrace = String::Handle(Symbols::New("{"));
-  const String& kRBrace = String::Handle(Symbols::New("}"));
   String& name = String::Handle();
   if (!instantiate && !is_static() && (name_visibility == kInternalName)) {
     // Prefix the signature with its class and type parameters, if any (e.g.
     // "Map<K, V>(K) => bool").
     // The signature of static functions cannot be type parameterized.
-    const String& kSpaceExtendsSpace =
-        String::Handle(Symbols::New(" extends "));
-    const String& kLAngleBracket = String::Handle(Symbols::New("<"));
-    const String& kRAngleBracket = String::Handle(Symbols::New(">"));
     const Class& function_class = Class::Handle(Owner());
     ASSERT(!function_class.IsNull());
     const TypeArguments& type_parameters = TypeArguments::Handle(
@@ -4005,7 +4046,7 @@
       const String& function_class_name = String::Handle(function_class.Name());
       pieces.Add(function_class_name);
       intptr_t num_type_parameters = type_parameters.Length();
-      pieces.Add(kLAngleBracket);
+      pieces.Add(Symbols::LAngleBracket());
       TypeParameter& type_parameter = TypeParameter::Handle();
       AbstractType& bound = AbstractType::Handle();
       for (intptr_t i = 0; i < num_type_parameters; i++) {
@@ -4014,15 +4055,15 @@
         pieces.Add(name);
         bound = type_parameter.bound();
         if (!bound.IsNull() && !bound.IsObjectType()) {
-          pieces.Add(kSpaceExtendsSpace);
+          pieces.Add(Symbols::SpaceExtendsSpace());
           name = bound.BuildName(name_visibility);
           pieces.Add(name);
         }
         if (i < num_type_parameters - 1) {
-          pieces.Add(kCommaSpace);
+          pieces.Add(Symbols::CommaSpace());
         }
       }
-      pieces.Add(kRAngleBracket);
+      pieces.Add(Symbols::RAngleBracket());
     }
   }
   AbstractType& param_type = AbstractType::Handle();
@@ -4032,7 +4073,7 @@
   const intptr_t num_opt_named_params = NumOptionalNamedParameters();
   const intptr_t num_opt_params = num_opt_pos_params + num_opt_named_params;
   ASSERT((num_fixed_params + num_opt_params) == num_params);
-  pieces.Add(kLParen);
+  pieces.Add(Symbols::LParen());
   intptr_t i = 0;
   if (name_visibility == kUserVisibleName) {
     // Hide implicit parameters.
@@ -4047,15 +4088,15 @@
     name = param_type.BuildName(name_visibility);
     pieces.Add(name);
     if (i != (num_params - 1)) {
-      pieces.Add(kCommaSpace);
+      pieces.Add(Symbols::CommaSpace());
     }
     i++;
   }
   if (num_opt_params > 0) {
     if (num_opt_pos_params > 0) {
-      pieces.Add(kLBracket);
+      pieces.Add(Symbols::LBracket());
     } else {
-      pieces.Add(kLBrace);
+      pieces.Add(Symbols::LBrace());
     }
     for (intptr_t i = num_fixed_params; i < num_params; i++) {
       // The parameter name of an optional positional parameter does not need
@@ -4063,7 +4104,7 @@
       if (num_opt_named_params > 0) {
         name = ParameterNameAt(i);
         pieces.Add(name);
-        pieces.Add(kColonSpace);
+        pieces.Add(Symbols::ColonSpace());
       }
       param_type = ParameterTypeAt(i);
       if (instantiate && !param_type.IsInstantiated()) {
@@ -4073,16 +4114,16 @@
       name = param_type.BuildName(name_visibility);
       pieces.Add(name);
       if (i != (num_params - 1)) {
-        pieces.Add(kCommaSpace);
+        pieces.Add(Symbols::CommaSpace());
       }
     }
     if (num_opt_pos_params > 0) {
-      pieces.Add(kRBracket);
+      pieces.Add(Symbols::RBracket());
     } else {
-      pieces.Add(kRBrace);
+      pieces.Add(Symbols::RBrace());
     }
   }
-  pieces.Add(kRParenArrow);
+  pieces.Add(Symbols::RParenArrow());
   AbstractType& res_type = AbstractType::Handle(result_type());
   if (instantiate && !res_type.IsInstantiated()) {
     res_type = res_type.InstantiateFrom(instantiator);
@@ -4143,7 +4184,6 @@
 
 RawString* Function::QualifiedUserVisibleName() const {
   String& tmp = String::Handle();
-  String& suffix = String::Handle();
   const Class& cls = Class::Handle(Owner());
 
   if (IsClosureFunction()) {
@@ -4160,9 +4200,8 @@
       tmp = cls.UserVisibleName();
     }
   }
-  suffix = Symbols::Dot();
-  tmp = String::Concat(tmp, suffix);
-  suffix = UserVisibleName();
+  tmp = String::Concat(tmp, Symbols::Dot());
+  const String& suffix = String::Handle(UserVisibleName());
   return String::Concat(tmp, suffix);
 }
 
@@ -4329,8 +4368,7 @@
 
 
 RawString* Field::GetterSymbol(const String& field_name) {
-  String& str = String::Handle();
-  str = Field::GetterName(field_name);
+  const String& str = String::Handle(Field::GetterName(field_name));
   return Symbols::New(str);
 }
 
@@ -4344,8 +4382,7 @@
 
 
 RawString* Field::SetterSymbol(const String& field_name) {
-  String& str = String::Handle();
-  str = Field::SetterName(field_name);
+  const String& str = String::Handle(Field::SetterName(field_name));
   return Symbols::New(str);
 }
 
@@ -4542,14 +4579,6 @@
   const String& private_key = String::Handle(PrivateKey());
   intptr_t private_len = private_key.Length();
 
-  String& blank = String::Handle(String::New(" "));
-  String& newline = String::Handle(String::New("\n"));
-  String& two_newlines = String::Handle(String::New("\n\n"));
-  String& double_quotes = String::Handle(String::New("\""));
-  String& dollar = String::Handle(String::New("$"));
-  String& two_spaces = String::Handle(String::New("  "));
-  String& raw_string = String::Handle(String::New("r"));
-
   Token::Kind curr = iterator.CurrentTokenKind();
   Token::Kind prev = Token::kILLEGAL;
   // Handles used in the loop.
@@ -4590,9 +4619,9 @@
       }
       if ((prev != Token::kINTERPOL_VAR) && (prev != Token::kINTERPOL_END)) {
         if (is_raw_string) {
-          literals.Add(raw_string);
+          literals.Add(Symbols::LowercaseR());
         }
-        literals.Add(double_quotes);
+        literals.Add(Symbols::DoubleQuotes());
       }
       if (escape_characters) {
         literal = String::EscapeSpecialCharacters(literal, is_raw_string);
@@ -4601,10 +4630,10 @@
         literals.Add(literal);
       }
       if ((next != Token::kINTERPOL_VAR) && (next != Token::kINTERPOL_START)) {
-        literals.Add(double_quotes);
+        literals.Add(Symbols::DoubleQuotes());
       }
     } else if (curr == Token::kINTERPOL_VAR) {
-      literals.Add(dollar);
+      literals.Add(Symbols::Dollar());
       if (literal.CharAt(0) == Scanner::kPrivateIdentifierStart) {
         literal = String::SubString(literal, 0, literal.Length() - private_len);
       }
@@ -4622,17 +4651,17 @@
     switch (curr) {
       case Token::kLBRACE:
         indent++;
-        separator = &newline;
+        separator = &Symbols::NewLine();
         break;
       case Token::kRBRACE:
         if (indent == 0) {
-          separator = &two_newlines;
+          separator = &Symbols::TwoNewlines();
         } else {
-          separator = &newline;
+          separator = &Symbols::NewLine();
         }
         break;
       case Token::kSEMICOLON:
-        separator = &newline;
+        separator = &Symbols::NewLine();
         break;
       case Token::kPERIOD:
       case Token::kLPAREN:
@@ -4643,7 +4672,7 @@
       case Token::kINTERPOL_END:
         break;
       default:
-        separator = &blank;
+        separator = &Symbols::Blank();
         break;
     }
     // Determine whether the separation text needs to be updated based on the
@@ -4665,7 +4694,7 @@
         separator = NULL;
         break;
       case Token::kELSE:
-        separator = &blank;
+        separator = &Symbols::Blank();
       default:
         // Do nothing.
         break;
@@ -4673,17 +4702,17 @@
     // Update the few cases where both tokens need to be taken into account.
     if (((curr == Token::kIF) || (curr == Token::kFOR)) &&
         (next == Token::kLPAREN)) {
-      separator = &blank;
+      separator = &Symbols::Blank();
     } else if ((curr == Token::kASSIGN) && (next == Token::kLPAREN)) {
-      separator = & blank;
+      separator = &Symbols::Blank();
     } else if ((curr == Token::kLBRACE) && (next == Token::kRBRACE)) {
       separator = NULL;
     }
     if (separator != NULL) {
       literals.Add(*separator);
-      if (separator == &newline) {
+      if (separator == &Symbols::NewLine()) {
         for (int i = 0; i < indent; i++) {
-          literals.Add(two_spaces);
+          literals.Add(Symbols::TwoSpaces());
         }
       }
     }
@@ -5116,10 +5145,9 @@
                               intptr_t* line,
                               intptr_t* column) const {
   const String& src = String::Handle(Source());
-  const String& dummy_key = String::Handle(Symbols::Empty());
   const TokenStream& tkns = TokenStream::Handle(tokens());
   intptr_t src_pos = tkns.ComputeSourcePosition(token_pos);
-  Scanner scanner(src, dummy_key);
+  Scanner scanner(src, Symbols::Empty());
   scanner.ScanTo(src_pos);
   *line = scanner.CurrentPosition().line;
   *column = scanner.CurrentPosition().column;
@@ -5130,9 +5158,8 @@
                               intptr_t* first_token_index,
                               intptr_t* last_token_index) const {
   const String& src = String::Handle(Source());
-  const String& dummy_key = String::Handle(Symbols::Empty());
   const TokenStream& tkns = TokenStream::Handle(tokens());
-  Scanner scanner(src, dummy_key);
+  Scanner scanner(src, Symbols::Empty());
   scanner.TokenRangeAtLine(line_number, first_token_index, last_token_index);
   if (*first_token_index >= 0) {
     *first_token_index = tkns.ComputeTokenPosition(*first_token_index);
@@ -5165,11 +5192,13 @@
     }
   }
   // Guarantee that returned string is never NULL.
-  String& line = String::Handle(Symbols::Empty());
   if (line_start >= 0) {
-    line = String::SubString(src, line_start, last_char - line_start + 1);
+    const String& line = String::Handle(
+        String::SubString(src, line_start, last_char - line_start + 1));
+    return line.raw();
+  } else {
+    return Symbols::Empty().raw();
   }
-  return line.raw();
 }
 
 
@@ -5564,7 +5593,14 @@
     // Script does not contain the given line number.
     return Function::null();
   }
-  return LookupFunctionInScript(script, first_token_pos);
+  Function& func = Function::Handle();
+  for (intptr_t pos = first_token_pos; pos <= last_token_pos; pos++) {
+    func = LookupFunctionInScript(script, pos);
+    if (!func.IsNull()) {
+      return func.raw();
+    }
+  }
+  return Function::null();
 }
 
 
@@ -5859,7 +5895,7 @@
 // Convenience function to determine whether the export list is
 // non-empty.
 bool Library::HasExports() const {
-  return exports() != Object::empty_array();
+  return exports() != Object::empty_array().raw();
 }
 
 
@@ -5910,11 +5946,11 @@
   result.StorePointer(&result.raw_ptr()->name_, url.raw());
   result.StorePointer(&result.raw_ptr()->url_, url.raw());
   result.raw_ptr()->private_key_ = Scanner::AllocatePrivateKey(result);
-  result.raw_ptr()->dictionary_ = Object::empty_array();
-  result.raw_ptr()->anonymous_classes_ = Object::empty_array();
+  result.raw_ptr()->dictionary_ = Object::empty_array().raw();
+  result.raw_ptr()->anonymous_classes_ = Object::empty_array().raw();
   result.raw_ptr()->num_anonymous_ = 0;
-  result.raw_ptr()->imports_ = Object::empty_array();
-  result.raw_ptr()->exports_ = Object::empty_array();
+  result.raw_ptr()->imports_ = Object::empty_array().raw();
+  result.raw_ptr()->exports_ = Object::empty_array().raw();
   result.raw_ptr()->loaded_scripts_ = Array::null();
   result.set_native_entry_resolver(NULL);
   result.raw_ptr()->corelib_imported_ = true;
@@ -6968,7 +7004,8 @@
   if (count == 0) {
     comments = new Comments(Object::empty_array());
   } else {
-    comments = new Comments(Array::New(count * kNumberOfEntries));
+    const Array& data = Array::Handle(Array::New(count * kNumberOfEntries));
+    comments = new Comments(data);
   }
   return *comments;
 }
@@ -7005,8 +7042,8 @@
 }
 
 
-Code::Comments::Comments(RawArray* comments)
-    : comments_(Array::Handle(comments)) {
+Code::Comments::Comments(const Array& comments)
+    : comments_(comments) {
 }
 
 
@@ -7064,7 +7101,7 @@
 
 
 const Code::Comments& Code::comments() const  {
-  Comments* comments = new Code::Comments(raw_ptr()->comments_);
+  Comments* comments = new Code::Comments(Array::Handle(raw_ptr()->comments_));
   return *comments;
 }
 
@@ -7696,6 +7733,16 @@
 }
 
 
+intptr_t ICData::AggregateCount() const {
+  const intptr_t len = NumberOfChecks();
+  intptr_t count = 0;
+  for (intptr_t i = 0; i < len; i++) {
+    count += GetCountAt(i);
+  }
+  return count;
+}
+
+
 RawFunction* ICData::GetTargetForReceiverClassId(intptr_t class_id) const {
   const intptr_t len = NumberOfChecks();
   for (intptr_t i = 0; i < len; i++) {
@@ -8308,8 +8355,8 @@
       // Object::transition_sentinel() if type checks were not eliminated at
       // compile time. Both sentinels are instances of the Null class, but they
       // are not the Object::null() instance.
-      ASSERT((raw() == Object::transition_sentinel()) ||
-             (raw() == Object::sentinel()));
+      ASSERT((raw() == Object::transition_sentinel().raw()) ||
+             (raw() == Object::sentinel().raw()));
       ASSERT(!FLAG_eliminate_type_checks);
       return true;  // We are doing an instance of test as part of a type check.
     }
@@ -8409,6 +8456,36 @@
 }
 
 
+bool Instance::IsCallable(Function* function, Context* context) const {
+  Class& cls = Class::Handle(clazz());
+  if (cls.IsSignatureClass()) {
+    if (function != NULL) {
+      *function = Closure::function(*this);
+    }
+    if (context != NULL) {
+      *context = Closure::context(*this);
+    }
+    return true;
+  }
+  // Try to resolve a "call" method.
+  Function& call_function = Function::Handle();
+  do {
+    call_function = cls.LookupDynamicFunction(Symbols::Call());
+    if (!call_function.IsNull()) {
+      if (function != NULL) {
+        *function = call_function.raw();
+      }
+      if (context != NULL) {
+        *context = Isolate::Current()->object_store()->empty_context();
+      }
+      return true;
+    }
+    cls = cls.SuperClass();
+  } while (!cls.IsNull());
+  return false;
+}
+
+
 RawInstance* Instance::New(const Class& cls, Heap::Space space) {
   Instance& result = Instance::Handle();
   {
@@ -8431,9 +8508,9 @@
 const char* Instance::ToCString() const {
   if (IsNull()) {
     return "null";
-  } else if (raw() == Object::sentinel()) {
+  } else if (raw() == Object::sentinel().raw()) {
     return "sentinel";
-  } else if (raw() == Object::transition_sentinel()) {
+  } else if (raw() == Object::transition_sentinel().raw()) {
     return "transition_sentinel";
   } else if (Isolate::Current()->no_gc_scope_depth() > 0) {
     // Can occur when running disassembler.
@@ -8751,6 +8828,13 @@
 }
 
 
+intptr_t AbstractType::Hash() const {
+  // AbstractType is an abstract class.
+  UNREACHABLE();
+  return 0;
+}
+
+
 const char* AbstractType::ToCString() const {
   // AbstractType is an abstract class.
   UNREACHABLE();
@@ -9025,6 +9109,16 @@
 }
 
 
+intptr_t Type::Hash() const {
+  ASSERT(IsFinalized());
+  uword result = 1;
+  if (IsMalformed()) return result;
+  result += Class::Handle(type_class()).id();
+  result += AbstractTypeArguments::Handle(arguments()).Hash();
+  return FinalizeHash(result);
+}
+
+
 void Type::set_type_class(const Object& value) const {
   ASSERT(!value.IsNull() && (value.IsClass() || value.IsUnresolvedClass()));
   StorePointer(&raw_ptr()->type_class_, value.raw());
@@ -9128,9 +9222,7 @@
   if (index() != other_type_param.index()) {
     return false;
   }
-  const String& type_param_name = String::Handle(name());
-  const String& other_type_param_name = String::Handle(other_type_param.name());
-  return type_param_name.Equals(other_type_param_name);
+  return true;
 }
 
 
@@ -9166,6 +9258,15 @@
 }
 
 
+intptr_t TypeParameter::Hash() const {
+  ASSERT(IsFinalized());
+  uword result = 0;
+  result += Class::Handle(parameterized_class()).id();
+  result <<= index();
+  return FinalizeHash(result);
+}
+
+
 RawTypeParameter* TypeParameter::New() {
   ASSERT(Isolate::Current()->object_store()->type_parameter_class() !=
          Class::null());
@@ -10514,7 +10615,7 @@
   ASSERT(begin_index >= 0);
   ASSERT(length >= 0);
   if (begin_index <= str.Length() && length == 0) {
-    return Symbols::Empty();
+    return Symbols::Empty().raw();
   }
   if (begin_index > str.Length()) {
     return String::null();
@@ -10927,7 +11028,7 @@
   ASSERT(begin_index >= 0);
   ASSERT(length >= 0);
   if (begin_index <= str.Length() && length == 0) {
-    return OneByteString::raw(String::Handle(Symbols::Empty()));
+    return OneByteString::raw(Symbols::Empty());
   }
   ASSERT(begin_index < str.Length());
   RawOneByteString* result = OneByteString::New(length, space);
@@ -11182,16 +11283,6 @@
 }
 
 
-RawBool* Bool::True() {
-  return Isolate::Current()->object_store()->true_value();
-}
-
-
-RawBool* Bool::False() {
-  return Isolate::Current()->object_store()->false_value();
-}
-
-
 RawBool* Bool::New(bool value) {
   ASSERT(Isolate::Current()->object_store()->bool_class() != Class::null());
   Bool& result = Bool::Handle();
@@ -11205,6 +11296,7 @@
     result ^= raw;
   }
   result.set_value(value);
+  result.SetCanonical();
   return result.raw();
 }
 
@@ -11308,7 +11400,6 @@
   intptr_t capacity_len = growable_array.Capacity();
   Isolate* isolate = Isolate::Current();
   const Array& array = Array::Handle(isolate, growable_array.data());
-  const Array& new_array = Array::Handle(isolate, Object::empty_array());
   intptr_t capacity_size = Array::InstanceSize(capacity_len);
   intptr_t used_size = Array::InstanceSize(used_len);
   NoGCScope no_gc;
@@ -11322,7 +11413,7 @@
 
   // Null the GrowableObjectArray, we are removing it's backing array.
   growable_array.SetLength(0);
-  growable_array.SetData(new_array);
+  growable_array.SetData(Object::empty_array());
 
   // If there is any left over space fill it with either an Array object or
   // just a plain object (depending on the amount of left over space) so
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 5864410..973109f 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -202,6 +202,15 @@
 
   bool IsNew() const { return raw()->IsNewObject(); }
   bool IsOld() const { return raw()->IsOldObject(); }
+  bool InVMHeap() const {
+#if defined(DEBUG)
+    if (raw()->IsVMHeapObject()) {
+      Heap* vm_isolate_heap = Dart::vm_isolate()->heap();
+      ASSERT(vm_isolate_heap->Contains(RawObject::ToAddr(raw())));
+    }
+#endif
+    return raw()->IsVMHeapObject();
+  }
 
   // Print the object on stdout for debugging.
   void Print() const;
@@ -210,6 +219,8 @@
     return VMHandles::IsZoneHandle(reinterpret_cast<uword>(this));
   }
 
+  bool IsReadOnlyHandle() const;
+
   bool IsNotTemporaryScopedHandle() const;
 
   static RawObject* Clone(const Object& src, Heap::Space space = Heap::kNew);
@@ -248,15 +259,33 @@
   }
 
   static RawObject* null() { return null_; }
-  static RawArray* empty_array() { return empty_array_; }
+  static const Array& empty_array() {
+    ASSERT(empty_array_ != NULL);
+    return *empty_array_;
+  }
 
   // The sentinel is a value that cannot be produced by Dart code.
   // It can be used to mark special values, for example to distinguish
   // "uninitialized" fields.
-  static RawInstance* sentinel() { return sentinel_; }
+  static const Instance& sentinel() {
+    ASSERT(sentinel_ != NULL);
+    return *sentinel_;
+  }
   // Value marking that we are transitioning from sentinel, e.g., computing
   // a field value. Used to detect circular initialization.
-  static RawInstance* transition_sentinel() { return transition_sentinel_; }
+  static const Instance& transition_sentinel() {
+    ASSERT(transition_sentinel_ != NULL);
+    return *transition_sentinel_;
+  }
+
+  static const Bool& bool_true() {
+    ASSERT(bool_true_ != NULL);
+    return *bool_true_;
+  }
+  static const Bool& bool_false() {
+    ASSERT(bool_false_ != NULL);
+    return *bool_false_;
+  }
 
   static RawClass* class_class() { return class_class_; }
   static RawClass* null_class() { return null_class_; }
@@ -400,9 +429,6 @@
   // The static values below are singletons shared between the different
   // isolates. They are all allocated in the non-GC'd Dart::vm_isolate_.
   static RawObject* null_;
-  static RawArray* empty_array_;
-  static RawInstance* sentinel_;
-  static RawInstance* transition_sentinel_;
 
   static RawClass* class_class_;  // Class of the Class vm object.
   static RawClass* null_class_;  // Class of the null object.
@@ -440,6 +466,14 @@
   static RawClass* unhandled_exception_class_;  // Class of UnhandledException.
   static RawClass* unwind_error_class_;  // Class of UnwindError.
 
+  // The static values below are read-only handle pointers for singleton
+  // objects that are shared between the different isolates.
+  static Array* empty_array_;
+  static Instance* sentinel_;
+  static Instance* transition_sentinel_;
+  static Bool* bool_true_;
+  static Bool* bool_false_;
+
   friend void ClassTable::Register(const Class& cls);
   friend void RawObject::Validate(Isolate* isolate) const;
   friend class Closure;
@@ -924,6 +958,8 @@
   virtual bool IsInstantiated() const;
   virtual bool IsUninstantiatedIdentity() const;
 
+  virtual intptr_t Hash() const;
+
  private:
   // Check if this type argument vector consists solely of DynamicType,
   // considering only a prefix of length 'len'.
@@ -1286,6 +1322,29 @@
     raw_ptr()->deoptimization_counter_ = value;
   }
 
+  static const intptr_t kMaxInstructionCount = (1 << 16) - 1;
+  intptr_t optimized_instruction_count() const {
+    return raw_ptr()->optimized_instruction_count_;
+  }
+  void set_optimized_instruction_count(intptr_t value) const {
+    ASSERT(value >= 0);
+    if (value > kMaxInstructionCount) {
+      value = kMaxInstructionCount;
+    }
+    raw_ptr()->optimized_instruction_count_ = static_cast<uint16_t>(value);
+  }
+
+  intptr_t optimized_call_site_count() const {
+    return raw_ptr()->optimized_call_site_count_;
+  }
+  void set_optimized_call_site_count(intptr_t value) const {
+    ASSERT(value >= 0);
+    if (value > kMaxInstructionCount) {
+      value = kMaxInstructionCount;
+    }
+    raw_ptr()->optimized_call_site_count_ = static_cast<uint16_t>(value);
+  }
+
   bool is_optimizable() const;
   void set_is_optimizable(bool value) const;
 
@@ -2527,7 +2586,7 @@
     const String& CommentAt(intptr_t idx) const;
 
    private:
-    explicit Comments(RawArray* comments);
+    explicit Comments(const Array& comments);
 
     // Layout of entries describing comments.
     enum {
@@ -2890,6 +2949,7 @@
   RawFunction* GetTargetForReceiverClassId(intptr_t class_id) const;
 
   intptr_t GetCountAt(intptr_t index) const;
+  intptr_t AggregateCount() const;
 
   // Returns this->raw() if num_args_tested == 1 and arg_nr == 1, otherwise
   // returns a new ICData object containing only unique arg_nr checks.
@@ -3188,6 +3248,12 @@
   // Returns true if the instance is a closure object.
   bool IsClosure() const;
 
+  // If the instance is a callable object, i.e. a closure or the instance of a
+  // class implementing a 'call' method, return true and set the function
+  // (if not NULL) to call and the context (if not NULL) to pass to the
+  // function.
+  bool IsCallable(Function* function, Context* context) const;
+
   static intptr_t InstanceSize() {
     return RoundedAllocationSize(sizeof(RawInstance));
   }
@@ -3254,6 +3320,8 @@
     return BuildName(kUserVisibleName);
   }
 
+  virtual intptr_t Hash() const;
+
   // The name of this type's class, i.e. without the type argument names of this
   // type.
   RawString* ClassName() const;
@@ -3366,6 +3434,8 @@
       const AbstractTypeArguments& instantiator_type_arguments) const;
   virtual RawAbstractType* Canonicalize() const;
 
+  virtual intptr_t Hash() const;
+
   static intptr_t InstanceSize() {
     return RoundedAllocationSize(sizeof(RawType));
   }
@@ -3464,6 +3534,8 @@
       const AbstractTypeArguments& instantiator_type_arguments) const;
   virtual RawAbstractType* Canonicalize() const { return raw(); }
 
+  virtual intptr_t Hash() const;
+
   static intptr_t InstanceSize() {
     return RoundedAllocationSize(sizeof(RawTypeParameter));
   }
@@ -4342,11 +4414,16 @@
     return RoundedAllocationSize(sizeof(RawBool));
   }
 
-  static RawBool* True();
-  static RawBool* False();
+  static const Bool& True() {
+    return Object::bool_true();
+  }
+
+  static const Bool& False() {
+    return Object::bool_false();
+  }
 
   static RawBool* Get(bool value) {
-    return value ? Bool::True() : Bool::False();
+    return value ? Bool::True().raw() : Bool::False().raw();
   }
 
  private:
@@ -6070,8 +6147,8 @@
   if (FLAG_verify_handles) {
     Heap* isolate_heap = isolate->heap();
     Heap* vm_isolate_heap = Dart::vm_isolate()->heap();
-    ASSERT(isolate_heap->Contains(reinterpret_cast<uword>(raw_->ptr())) ||
-           vm_isolate_heap->Contains(reinterpret_cast<uword>(raw_->ptr())));
+    ASSERT(isolate_heap->Contains(RawObject::ToAddr(raw_)) ||
+           vm_isolate_heap->Contains(RawObject::ToAddr(raw_)));
   }
   ASSERT(builtin_vtables_[cid] ==
          isolate->class_table()->At(cid)->ptr()->handle_vtable_);
diff --git a/runtime/vm/object_set.h b/runtime/vm/object_set.h
index 159a092..6f687a9 100644
--- a/runtime/vm/object_set.h
+++ b/runtime/vm/object_set.h
@@ -5,13 +5,29 @@
 #ifndef VM_OBJECT_SET_H_
 #define VM_OBJECT_SET_H_
 
+#include "platform/utils.h"
 #include "vm/globals.h"
+#include "vm/raw_object.h"
 
 namespace dart {
 
 class ObjectSet {
  public:
-  ObjectSet(uword start, uword end) : start_(start), end_(end) {
+  ObjectSet() {
+    Init(0, 0);
+  }
+
+  ObjectSet(uword start, uword end) {
+    Init(start, end);
+  }
+
+  ~ObjectSet() {
+    delete[] allocation_;
+  }
+
+  void Init(uword start, uword end) {
+    start_ = start;
+    end_ = end;
     ASSERT(start_ <= end_);
     size_ = SizeFor((end_ - start_) >> kWordSizeLog2);
     allocation_ = new uword[size_];
@@ -20,10 +36,6 @@
     Clear();
   }
 
-  ~ObjectSet() {
-    delete[] allocation_;
-  }
-
   bool Contains(RawObject* raw_obj) const {
     uword raw_addr = RawObject::ToAddr(raw_obj);
     ASSERT(raw_addr >= start_);
@@ -39,10 +51,30 @@
     ASSERT(raw_addr < end_);
     uword i = raw_addr >> kWordSizeLog2;
     data_[i / kBitsPerWord] |= (static_cast<uword>(1) << (i % kBitsPerWord));
+    min_ = Utils::Minimum(raw_addr, min_);
+    max_ = Utils::Maximum(raw_addr, max_);
+  }
+
+  void Resize(uword start, uword end) {
+    if (start_ != start || end_ != end) {
+      delete[] allocation_;
+      Init(start, end);
+    }
   }
 
   void Clear() {
     memset(allocation_, 0, (size_ * sizeof(allocation_[0])));
+    min_ = end_;
+    max_ = start_;
+  }
+
+  void FastClear() {
+    uword i = min_ >> kWordSizeLog2;
+    memset(&data_[i / kBitsPerWord],
+           0,
+           sizeof(uword) * SizeFor((max_ + 1  - min_) >> kWordSizeLog2));
+    min_ = end_;
+    max_ = start_;
   }
 
  private:
@@ -66,7 +98,15 @@
   // Highest possible heap address, exclusive.
   uword end_;
 
-  DISALLOW_IMPLICIT_CONSTRUCTORS(ObjectSet);
+  // The inclusive minimum address set in this ObjectMap.
+  // Used by FastClear
+  uword min_;
+
+  // The inclusive maximum address in this ObjectMap.
+  // Used by FastClear
+  uword max_;
+
+  DISALLOW_COPY_AND_ASSIGN(ObjectSet);
 };
 
 }  // namespace dart
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index 925079a..c44d966 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -64,8 +64,6 @@
     stacktrace_class_(Class::null()),
     jsregexp_class_(Class::null()),
     weak_property_class_(Class::null()),
-    true_value_(Bool::null()),
-    false_value_(Bool::null()),
     symbol_table_(Array::null()),
     canonical_type_arguments_(Array::null()),
     core_library_(Library::null()),
@@ -80,10 +78,14 @@
     libraries_(GrowableObjectArray::null()),
     pending_classes_(GrowableObjectArray::null()),
     sticky_error_(Error::null()),
+    unhandled_exception_handler_(String::null()),
     empty_context_(Context::null()),
     stack_overflow_(Instance::null()),
     out_of_memory_(Instance::null()),
-    keyword_symbols_(Array::null()) {
+    keyword_symbols_(Array::null()),
+    receive_port_create_function_(Function::null()),
+    lookup_receive_port_function_(Function::null()),
+    handle_message_function_(Function::null()) {
 }
 
 
@@ -113,16 +115,16 @@
   }
   ASSERT(this->stack_overflow() == Instance::null());
   ASSERT(this->out_of_memory() == Instance::null());
-  GrowableArray<const Object*> args;
   Object& result = Object::Handle();
 
-  result = Exceptions::Create(Exceptions::kStackOverflow, args);
+  result = Exceptions::Create(Exceptions::kStackOverflow,
+                              Object::empty_array());
   if (result.IsError()) {
     return false;
   }
   set_stack_overflow(Instance::Cast(result));
 
-  result = Exceptions::Create(Exceptions::kOutOfMemory, args);
+  result = Exceptions::Create(Exceptions::kOutOfMemory, Object::empty_array());
   if (result.IsError()) {
     return false;
   }
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index fbe6d80..d798ff0 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -435,11 +435,12 @@
   }
   void clear_sticky_error() { sticky_error_ = Error::null(); }
 
-  RawBool* true_value() const { return true_value_; }
-  void set_true_value(const Bool& value) { true_value_ = value.raw(); }
-
-  RawBool* false_value() const { return false_value_; }
-  void set_false_value(const Bool& value) { false_value_ = value.raw(); }
+  RawString* unhandled_exception_handler() const {
+    return unhandled_exception_handler_;
+  }
+  void set_unhandled_exception_handler(const String& value) {
+    unhandled_exception_handler_ = value.raw();
+  }
 
   RawContext* empty_context() const { return empty_context_; }
   void set_empty_context(const Context& value) {
@@ -462,6 +463,27 @@
   }
   void InitKeywordTable();
 
+  RawFunction* receive_port_create_function() const {
+    return receive_port_create_function_;
+  }
+  void set_receive_port_create_function(const Function& function) {
+    receive_port_create_function_ = function.raw();
+  }
+
+  RawFunction* lookup_receive_port_function() const {
+    return lookup_receive_port_function_;
+  }
+  void set_lookup_receive_port_function(const Function& function) {
+    lookup_receive_port_function_ = function.raw();
+  }
+
+  RawFunction* handle_message_function() const {
+    return handle_message_function_;
+  }
+  void set_handle_message_function(const Function& function) {
+    handle_message_function_ = function.raw();
+  }
+
   // Visit all object pointers.
   void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
@@ -531,8 +553,6 @@
   RawClass* stacktrace_class_;
   RawClass* jsregexp_class_;
   RawClass* weak_property_class_;
-  RawBool* true_value_;
-  RawBool* false_value_;
   RawArray* symbol_table_;
   RawArray* canonical_type_arguments_;
   RawLibrary* core_library_;
@@ -548,10 +568,14 @@
   RawGrowableObjectArray* libraries_;
   RawGrowableObjectArray* pending_classes_;
   RawError* sticky_error_;
+  RawString* unhandled_exception_handler_;
   RawContext* empty_context_;
   RawInstance* stack_overflow_;
   RawInstance* out_of_memory_;
   RawArray* keyword_symbols_;
+  RawFunction* receive_port_create_function_;
+  RawFunction* lookup_receive_port_function_;
+  RawFunction* handle_message_function_;
   RawObject** to() { return reinterpret_cast<RawObject**>(&keyword_symbols_); }
 
   friend class SnapshotReader;
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index bfda577..e578f7f 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -22,8 +22,7 @@
       Class::New(class_name, script, Scanner::kDummyTokenIndex));
 
   // Class has no fields.
-  const Array& no_fields = Array::Handle(Object::empty_array());
-  cls.SetFields(no_fields);
+  cls.SetFields(Object::empty_array());
 
   // Create and populate the function arrays.
   const Array& functions = Array::Handle(Array::New(6));
@@ -168,8 +167,7 @@
       Class::Handle(Class::New(class_name, script, Scanner::kDummyTokenIndex));
 
   // No functions and no super class for the EmptyClass.
-  const Array& no_fields = Array::Handle(Object::empty_array());
-  empty_class.SetFields(no_fields);
+  empty_class.SetFields(Object::empty_array());
   empty_class.Finalize();
   EXPECT_EQ(kObjectAlignment, empty_class.instance_size());
   Instance& instance = Instance::Handle(Instance::New(empty_class));
@@ -1615,10 +1613,8 @@
 
 
 TEST_CASE(Bool) {
-  const Bool& true_value = Bool::Handle(Bool::True());
-  EXPECT(true_value.value());
-  const Bool& false_value = Bool::Handle(Bool::False());
-  EXPECT(!false_value.value());
+  EXPECT(Bool::True().value());
+  EXPECT(!Bool::False().value());
 }
 
 
@@ -1654,7 +1650,7 @@
   other_array.SetAt(2, array);
   EXPECT(!array.Equals(other_array));
 
-  EXPECT_EQ(0, Array::Handle(Object::empty_array()).Length());
+  EXPECT_EQ(0, Object::empty_array().Length());
 }
 
 
@@ -2545,8 +2541,8 @@
   const Class& bool_class = Class::Handle(object_store->bool_class());
   EXPECT_STREQ("Library:'dart:core' Class: bool",
                bool_class.ToCString());
-  EXPECT_STREQ("true", Bool::Handle(Bool::True()).ToCString());
-  EXPECT_STREQ("false", Bool::Handle(Bool::False()).ToCString());
+  EXPECT_STREQ("true", Bool::True().ToCString());
+  EXPECT_STREQ("false", Bool::False().ToCString());
 
   // Strings.
   EXPECT_STREQ("Sugarbowl",
@@ -2848,7 +2844,7 @@
   EXPECT_EQ(0, cache.NumberOfChecks());
   const TypeArguments& targ_0 = TypeArguments::Handle(TypeArguments::New(2));
   const TypeArguments& targ_1 = TypeArguments::Handle(TypeArguments::New(3));
-  cache.AddCheck(empty_class.id(), targ_0, targ_1, Bool::Handle(Bool::True()));
+  cache.AddCheck(empty_class.id(), targ_0, targ_1, Bool::True());
   EXPECT_EQ(1, cache.NumberOfChecks());
   intptr_t test_class_id = -1;
   AbstractTypeArguments& test_targ_0 = AbstractTypeArguments::Handle();
@@ -2858,7 +2854,7 @@
   EXPECT_EQ(empty_class.id(), test_class_id);
   EXPECT_EQ(targ_0.raw(), test_targ_0.raw());
   EXPECT_EQ(targ_1.raw(), test_targ_1.raw());
-  EXPECT_EQ(Bool::True(), test_result.raw());
+  EXPECT_EQ(Bool::True().raw(), test_result.raw());
 }
 
 
@@ -3127,13 +3123,12 @@
   {
     // Weak property and value in new. Key in VM isolate.
     HANDLESCOPE(isolate);
-    String& key = String::Handle();
-    key ^= Symbols::Dot();
     String& value = String::Handle();
     value ^= OneByteString::New("value", Heap::kNew);
     weak ^= WeakProperty::New(Heap::kNew);
-    weak.set_key(key);
+    weak.set_key(Symbols::Dot());
     weak.set_value(value);
+    String& key = String::Handle();
     key ^= OneByteString::null();
     value ^= OneByteString::null();
   }
@@ -3145,13 +3140,12 @@
   {
     // Weak property and value in old. Key in VM isolate.
     HANDLESCOPE(isolate);
-    String& key = String::Handle();
-    key ^= Symbols::Dot();
     String& value = String::Handle();
     value ^= OneByteString::New("value", Heap::kOld);
     weak ^= WeakProperty::New(Heap::kOld);
-    weak.set_key(key);
+    weak.set_key(Symbols::Dot());
     weak.set_value(value);
+    String& key = String::Handle();
     key ^= OneByteString::null();
     value ^= OneByteString::null();
   }
diff --git a/runtime/vm/os.h b/runtime/vm/os.h
index d7d293a..874f3a6 100644
--- a/runtime/vm/os.h
+++ b/runtime/vm/os.h
@@ -111,6 +111,9 @@
   // value.
   static bool StringToInt64(const char* str, int64_t* value);
 
+  // Register code observers relevant to this OS.
+  static void RegisterCodeObservers();
+
   // Initialize the OS class.
   static void InitOnce();
 
diff --git a/runtime/vm/os_android.cc b/runtime/vm/os_android.cc
index 38c67cd..ac1a640 100644
--- a/runtime/vm/os_android.cc
+++ b/runtime/vm/os_android.cc
@@ -15,10 +15,170 @@
 #include <unistd.h>
 
 #include "platform/utils.h"
+#include "vm/code_observers.h"
+#include "vm/dart.h"
+#include "vm/debuginfo.h"
 #include "vm/isolate.h"
+#include "vm/zone.h"
+
 
 namespace dart {
 
+// Android CodeObservers.
+
+DEFINE_FLAG(bool, generate_gdb_symbols, false,
+    "Generate symbols of generated dart functions for debugging with GDB");
+DEFINE_FLAG(bool, generate_perf_events_symbols, false,
+    "Generate events symbols for profiling with perf");
+DEFINE_FLAG(charp, generate_pprof_symbols, false,
+    "Generate events symbols for profiling with pprof");
+
+class PerfCodeObserver : public CodeObserver {
+ public:
+  PerfCodeObserver() {
+    Dart_FileOpenCallback file_open = Isolate::file_open_callback();
+    if (file_open == NULL) {
+      return;
+    }
+    const char* format = "/tmp/perf-%ld.map";
+    intptr_t pid = getpid();
+    intptr_t len = OS::SNPrint(NULL, 0, format, pid);
+    char* filename = new char[len + 1];
+    OS::SNPrint(filename, len + 1, format, pid);
+    out_file_ = (*file_open)(filename);
+  }
+
+  ~PerfCodeObserver() {
+    Dart_FileCloseCallback file_close = Isolate::file_close_callback();
+    if (file_close == NULL) {
+      return;
+    }
+    ASSERT(out_file_ != NULL);
+    (*file_close)(out_file_);
+  }
+
+  virtual bool IsActive() const {
+    return FLAG_generate_perf_events_symbols;
+  }
+
+  virtual void Notify(const char* name,
+                      uword base,
+                      uword prologue_offset,
+                      uword size,
+                      bool optimized) {
+    Dart_FileWriteCallback file_write = Isolate::file_write_callback();
+    ASSERT(file_write != NULL);
+    const char* format = "%"Px" %"Px" %s%s\n";
+    const char* marker = optimized ? "*" : "";
+    intptr_t len = OS::SNPrint(NULL, 0, format, base, size, marker, name);
+    char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
+    OS::SNPrint(buffer, len + 1, format, base, size, marker, name);
+    ASSERT(out_file_ != NULL);
+    (*file_write)(buffer, len, out_file_);
+  }
+
+ private:
+  void* out_file_;
+
+  DISALLOW_COPY_AND_ASSIGN(PerfCodeObserver);
+};
+
+class PprofCodeObserver : public CodeObserver {
+ public:
+  PprofCodeObserver() {
+    pprof_symbol_generator_ = DebugInfo::NewGenerator();
+  }
+
+  ~PprofCodeObserver() {
+    Dart_FileOpenCallback file_open = Isolate::file_open_callback();
+    if (file_open == NULL) {
+      return;
+    }
+    Dart_FileCloseCallback file_close = Isolate::file_close_callback();
+    if (file_close == NULL) {
+      return;
+    }
+    Dart_FileWriteCallback file_write = Isolate::file_write_callback();
+    if (file_write == NULL) {
+      return;
+    }
+    if (FLAG_generate_pprof_symbols == NULL) {
+      return;
+    }
+    const char* filename = FLAG_generate_pprof_symbols;
+    void* out_file = (*file_open)(filename);
+    ASSERT(out_file != NULL);
+    DebugInfo::ByteBuffer* debug_region = new DebugInfo::ByteBuffer();
+    ASSERT(debug_region != NULL);
+    pprof_symbol_generator_->WriteToMemory(debug_region);
+    int buffer_size = debug_region->size();
+    void* buffer = debug_region->data();
+    delete debug_region;
+    if (buffer_size > 0) {
+      ASSERT(buffer != NULL);
+      (*file_write)(buffer, buffer_size, out_file);
+    }
+    (*file_close)(out_file);
+    DebugInfo::UnregisterAllSections();
+  }
+
+  virtual bool IsActive() const {
+    return FLAG_generate_pprof_symbols != NULL;
+  }
+
+  virtual void Notify(const char* name,
+                      uword base,
+                      uword prologue_offset,
+                      uword size,
+                      bool optimized) {
+    ASSERT(pprof_symbol_generator_ != NULL);
+    pprof_symbol_generator_->AddCode(base, size);
+    pprof_symbol_generator_->AddCodeRegion(name, base, size);
+  }
+
+ private:
+  DebugInfo* pprof_symbol_generator_;
+
+  DISALLOW_COPY_AND_ASSIGN(PprofCodeObserver);
+};
+
+class GdbCodeObserver : public CodeObserver {
+ public:
+  GdbCodeObserver() { }
+
+  virtual bool IsActive() const {
+    return FLAG_generate_gdb_symbols;
+  }
+
+  virtual void Notify(const char* name,
+                      uword base,
+                      uword prologue_offset,
+                      uword size,
+                      bool optimized) {
+    if (prologue_offset > 0) {
+      // In order to ensure that gdb sees the first instruction of a function
+      // as the prologue sequence we register two symbols for the cases when
+      // the prologue sequence is not the first instruction:
+      // <name>_entry is used for code preceding the prologue sequence.
+      // <name> for rest of the code (first instruction is prologue sequence).
+      const char* kFormat = "%s_%s";
+      intptr_t len = OS::SNPrint(NULL, 0, kFormat, name, "entry");
+      char* pname = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
+      OS::SNPrint(pname, (len + 1), kFormat, name, "entry");
+      DebugInfo::RegisterSection(pname, base, size);
+      DebugInfo::RegisterSection(name,
+                                 (base + prologue_offset),
+                                 (size - prologue_offset));
+    } else {
+      DebugInfo::RegisterSection(name, base, size);
+    }
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(GdbCodeObserver);
+};
+
+
 static bool LocalTime(int64_t seconds_since_epoch, tm* tm_result) {
   time_t seconds = static_cast<time_t>(seconds_since_epoch);
   if (seconds != seconds_since_epoch) return false;
@@ -202,6 +362,22 @@
 }
 
 
+void OS::RegisterCodeObservers() {
+  if (FLAG_generate_perf_events_symbols) {
+    CodeObservers::Register(new PerfCodeObserver);
+  }
+  if (FLAG_generate_gdb_symbols) {
+    CodeObservers::Register(new GdbCodeObserver);
+  }
+  if (FLAG_generate_pprof_symbols != NULL) {
+    CodeObservers::Register(new PprofCodeObserver);
+  }
+#if defined(DART_VTUNE_SUPPORT)
+  Register(new VTuneCodeObserver);
+#endif
+}
+
+
 void OS::PrintErr(const char* format, ...) {
   va_list args;
   va_start(args, format);
diff --git a/runtime/vm/os_linux.cc b/runtime/vm/os_linux.cc
index c7bfcbc..3c7495b 100644
--- a/runtime/vm/os_linux.cc
+++ b/runtime/vm/os_linux.cc
@@ -14,10 +14,170 @@
 #include <unistd.h>
 
 #include "platform/utils.h"
+#include "vm/code_observers.h"
+#include "vm/dart.h"
+#include "vm/debuginfo.h"
 #include "vm/isolate.h"
+#include "vm/zone.h"
+
 
 namespace dart {
 
+// Linux CodeObservers.
+
+DEFINE_FLAG(bool, generate_gdb_symbols, false,
+    "Generate symbols of generated dart functions for debugging with GDB");
+DEFINE_FLAG(bool, generate_perf_events_symbols, false,
+    "Generate events symbols for profiling with perf");
+DEFINE_FLAG(charp, generate_pprof_symbols, NULL,
+    "Writes pprof events symbols to the provided file");
+
+class PerfCodeObserver : public CodeObserver {
+ public:
+  PerfCodeObserver() {
+    Dart_FileOpenCallback file_open = Isolate::file_open_callback();
+    if (file_open == NULL) {
+      return;
+    }
+    const char* format = "/tmp/perf-%ld.map";
+    intptr_t pid = getpid();
+    intptr_t len = OS::SNPrint(NULL, 0, format, pid);
+    char* filename = new char[len + 1];
+    OS::SNPrint(filename, len + 1, format, pid);
+    out_file_ = (*file_open)(filename);
+  }
+
+  ~PerfCodeObserver() {
+    Dart_FileCloseCallback file_close = Isolate::file_close_callback();
+    if (file_close == NULL) {
+      return;
+    }
+    ASSERT(out_file_ != NULL);
+    (*file_close)(out_file_);
+  }
+
+  virtual bool IsActive() const {
+    return FLAG_generate_perf_events_symbols;
+  }
+
+  virtual void Notify(const char* name,
+                      uword base,
+                      uword prologue_offset,
+                      uword size,
+                      bool optimized) {
+    Dart_FileWriteCallback file_write = Isolate::file_write_callback();
+    ASSERT(file_write != NULL);
+    const char* format = "%"Px" %"Px" %s%s\n";
+    const char* marker = optimized ? "*" : "";
+    intptr_t len = OS::SNPrint(NULL, 0, format, base, size, marker, name);
+    char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
+    OS::SNPrint(buffer, len + 1, format, base, size, marker, name);
+    ASSERT(out_file_ != NULL);
+    (*file_write)(buffer, len, out_file_);
+  }
+
+ private:
+  void* out_file_;
+
+  DISALLOW_COPY_AND_ASSIGN(PerfCodeObserver);
+};
+
+class PprofCodeObserver : public CodeObserver {
+ public:
+  PprofCodeObserver() {
+    pprof_symbol_generator_ = DebugInfo::NewGenerator();
+  }
+
+  ~PprofCodeObserver() {
+    Dart_FileOpenCallback file_open = Isolate::file_open_callback();
+    if (file_open == NULL) {
+      return;
+    }
+    Dart_FileCloseCallback file_close = Isolate::file_close_callback();
+    if (file_close == NULL) {
+      return;
+    }
+    Dart_FileWriteCallback file_write = Isolate::file_write_callback();
+    if (file_write == NULL) {
+      return;
+    }
+    if (FLAG_generate_pprof_symbols == NULL) {
+      return;
+    }
+    const char* filename = FLAG_generate_pprof_symbols;
+    void* out_file = (*file_open)(filename);
+    ASSERT(out_file != NULL);
+    DebugInfo::ByteBuffer* debug_region = new DebugInfo::ByteBuffer();
+    ASSERT(debug_region != NULL);
+    pprof_symbol_generator_->WriteToMemory(debug_region);
+    int buffer_size = debug_region->size();
+    void* buffer = debug_region->data();
+    delete debug_region;
+    if (buffer_size > 0) {
+      ASSERT(buffer != NULL);
+      (*file_write)(buffer, buffer_size, out_file);
+    }
+    (*file_close)(out_file);
+    DebugInfo::UnregisterAllSections();
+  }
+
+  virtual bool IsActive() const {
+    return FLAG_generate_pprof_symbols != NULL;
+  }
+
+  virtual void Notify(const char* name,
+                      uword base,
+                      uword prologue_offset,
+                      uword size,
+                      bool optimized) {
+    ASSERT(pprof_symbol_generator_ != NULL);
+    pprof_symbol_generator_->AddCode(base, size);
+    pprof_symbol_generator_->AddCodeRegion(name, base, size);
+  }
+
+ private:
+  DebugInfo* pprof_symbol_generator_;
+
+  DISALLOW_COPY_AND_ASSIGN(PprofCodeObserver);
+};
+
+class GdbCodeObserver : public CodeObserver {
+ public:
+  GdbCodeObserver() { }
+
+  virtual bool IsActive() const {
+    return FLAG_generate_gdb_symbols;
+  }
+
+  virtual void Notify(const char* name,
+                      uword base,
+                      uword prologue_offset,
+                      uword size,
+                      bool optimized) {
+    if (prologue_offset > 0) {
+      // In order to ensure that gdb sees the first instruction of a function
+      // as the prologue sequence we register two symbols for the cases when
+      // the prologue sequence is not the first instruction:
+      // <name>_entry is used for code preceding the prologue sequence.
+      // <name> for rest of the code (first instruction is prologue sequence).
+      const char* kFormat = "%s_%s";
+      intptr_t len = OS::SNPrint(NULL, 0, kFormat, name, "entry");
+      char* pname = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
+      OS::SNPrint(pname, (len + 1), kFormat, name, "entry");
+      DebugInfo::RegisterSection(pname, base, size);
+      DebugInfo::RegisterSection(name,
+                                 (base + prologue_offset),
+                                 (size - prologue_offset));
+    } else {
+      DebugInfo::RegisterSection(name, base, size);
+    }
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(GdbCodeObserver);
+};
+
+
 static bool LocalTime(int64_t seconds_since_epoch, tm* tm_result) {
   time_t seconds = static_cast<time_t>(seconds_since_epoch);
   if (seconds != seconds_since_epoch) return false;
@@ -199,6 +359,22 @@
 }
 
 
+void OS::RegisterCodeObservers() {
+  if (FLAG_generate_perf_events_symbols) {
+    CodeObservers::Register(new PerfCodeObserver);
+  }
+  if (FLAG_generate_gdb_symbols) {
+    CodeObservers::Register(new GdbCodeObserver);
+  }
+  if (FLAG_generate_pprof_symbols != NULL) {
+    CodeObservers::Register(new PprofCodeObserver);
+  }
+#if defined(DART_VTUNE_SUPPORT)
+  Register(new VTuneCodeObserver);
+#endif
+}
+
+
 void OS::PrintErr(const char* format, ...) {
   va_list args;
   va_start(args, format);
diff --git a/runtime/vm/os_macos.cc b/runtime/vm/os_macos.cc
index 9af9907..56c4842 100644
--- a/runtime/vm/os_macos.cc
+++ b/runtime/vm/os_macos.cc
@@ -174,6 +174,10 @@
 }
 
 
+void OS::RegisterCodeObservers() {
+}
+
+
 void OS::PrintErr(const char* format, ...) {
   va_list args;
   va_start(args, format);
diff --git a/runtime/vm/os_win.cc b/runtime/vm/os_win.cc
index 1203c1e..75bd8f8 100644
--- a/runtime/vm/os_win.cc
+++ b/runtime/vm/os_win.cc
@@ -233,6 +233,13 @@
 }
 
 
+void OS::RegisterCodeObservers() {
+#if defined(DART_VTUNE_SUPPORT)
+  Register(new VTuneCodeObserver);
+#endif
+}
+
+
 void OS::PrintErr(const char* format, ...) {
   va_list args;
   va_start(args, format);
diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc
index 7e41881..fdca884 100644
--- a/runtime/vm/pages.cc
+++ b/runtime/vm/pages.cc
@@ -8,6 +8,7 @@
 #include "vm/compiler_stats.h"
 #include "vm/gc_marker.h"
 #include "vm/gc_sweeper.h"
+#include "vm/heap_trace.h"
 #include "vm/object.h"
 #include "vm/virtual_memory.h"
 
@@ -117,7 +118,6 @@
       max_capacity_(max_capacity),
       capacity_(0),
       in_use_(0),
-      count_(0),
       sweeping_(false),
       page_space_controller_(FLAG_heap_growth_space_ratio,
                              FLAG_heap_growth_rate,
@@ -232,7 +232,9 @@
       // On overflow we fail to allocate.
       return 0;
     }
-    if (CanIncreaseCapacity(page_size)) {
+    if ((page_space_controller_.CanGrowPageSpace(size) ||
+         growth_policy == kForceGrowth) &&
+        CanIncreaseCapacity(page_size)) {
       HeapPage* page = AllocateLargePage(size, type);
       if (page != NULL) {
         result = page->object_start();
@@ -399,17 +401,21 @@
 }
 
 
-void PageSpace::MarkSweep(bool invoke_api_callbacks, const char* gc_reason) {
+void PageSpace::MarkSweep(bool invoke_api_callbacks) {
   // MarkSweep is not reentrant. Make sure that is the case.
   ASSERT(!sweeping_);
   sweeping_ = true;
   Isolate* isolate = Isolate::Current();
   NoHandleScope no_handles(isolate);
 
+  if (HeapTrace::is_enabled()) {
+    isolate->heap()->trace()->TraceMarkSweepStart();
+  }
+
   if (FLAG_print_free_list_before_gc) {
-    OS::Print("Data Freelist:\n");
+    OS::Print("Data Freelist (before GC):\n");
     freelist_[HeapPage::kData].Print();
-    OS::Print("Executable Freelist:\n");
+    OS::Print("Executable Freelist (before GC):\n");
     freelist_[HeapPage::kExecutable].Print();
   }
 
@@ -419,21 +425,21 @@
     OS::PrintErr(" done.\n");
   }
 
-  if (FLAG_verbose_gc) {
-    OS::PrintErr("Start mark sweep for %s collection\n", gc_reason);
-  }
-  Timer timer(true, "MarkSweep");
-  timer.Start();
-  int64_t start = OS::GetCurrentTimeMillis();
+  int64_t start = OS::GetCurrentTimeMicros();
 
   // Mark all reachable old-gen objects.
   GCMarker marker(heap_);
   marker.MarkObjects(isolate, this, invoke_api_callbacks);
 
+  int64_t mid1 = OS::GetCurrentTimeMicros();
+
   // Reset the bump allocation page to unused.
   // Reset the freelists and setup sweeping.
   freelist_[HeapPage::kData].Reset();
   freelist_[HeapPage::kExecutable].Reset();
+
+  int64_t mid2 = OS::GetCurrentTimeMicros();
+
   GCSweeper sweeper(heap_);
   intptr_t in_use = 0;
 
@@ -452,6 +458,8 @@
     page = next_page;
   }
 
+  int64_t mid3 = OS::GetCurrentTimeMicros();
+
   prev_page = NULL;
   page = large_pages_;
   while (page != NULL) {
@@ -471,27 +479,21 @@
   intptr_t in_use_before = in_use_;
   in_use_ = in_use;
 
-  int64_t end = OS::GetCurrentTimeMillis();
-  timer.Stop();
+  int64_t end = OS::GetCurrentTimeMicros();
 
   // Record signals for growth control.
   page_space_controller_.EvaluateGarbageCollection(in_use_before, in_use,
                                                    start, end);
 
-  if (FLAG_verbose_gc) {
-    const intptr_t KB2 = KB / 2;
-    OS::PrintErr("Mark-Sweep[%d]: %"Pd64"us (%"Pd"K -> %"Pd"K, %"Pd"K)\n",
-                 count_,
-                 timer.TotalElapsedTime(),
-                 (in_use_before + (KB2)) / KB,
-                 (in_use + (KB2)) / KB,
-                 (capacity_ + KB2) / KB);
-  }
+  heap_->RecordTime(kMarkObjects, mid1 - start);
+  heap_->RecordTime(kResetFreeLists, mid2 - mid1);
+  heap_->RecordTime(kSweepPages, mid3 - mid2);
+  heap_->RecordTime(kSweepLargePages, end - mid3);
 
   if (FLAG_print_free_list_after_gc) {
-    OS::Print("Data Freelist:\n");
+    OS::Print("Data Freelist (after GC):\n");
     freelist_[HeapPage::kData].Print();
-    OS::Print("Executable Freelist:\n");
+    OS::Print("Executable Freelist (after GC):\n");
     freelist_[HeapPage::kExecutable].Print();
   }
 
@@ -501,7 +503,10 @@
     OS::PrintErr(" done.\n");
   }
 
-  count_++;
+  if (HeapTrace::is_enabled()) {
+    isolate->heap()->trace()->TraceMarkSweepFinish();
+  }
+
   // Done, reset the marker.
   ASSERT(sweeping_);
   sweeping_ = false;
@@ -555,37 +560,23 @@
       history_.GarbageCollectionTimeFraction();
   bool enough_free_time =
       (garbage_collection_time_fraction <= garbage_collection_time_ratio_);
+
+  Heap* heap = Isolate::Current()->heap();
   if (enough_free_space && enough_free_time) {
     grow_heap_ = 0;
   } else {
-    if (FLAG_verbose_gc) {
-      OS::PrintErr("PageSpaceController: ");
-      if (!enough_free_space) {
-        OS::PrintErr("free space %d%% < %d%%",
-                     collected_garbage_ratio,
-                     heap_growth_ratio_);
-      }
-      if (!enough_free_space && !enough_free_time) {
-        OS::PrintErr(", ");
-      }
-      if (!enough_free_time) {
-        OS::PrintErr("garbage collection time %d%% > %d%%",
-                     garbage_collection_time_fraction,
-                     garbage_collection_time_ratio_);
-      }
-      OS::PrintErr("\n");
-    }
-    if (!enough_free_space) {
-      intptr_t growth_target = static_cast<intptr_t>(in_use_after /
-                                                     desired_utilization_);
-      intptr_t growth_in_bytes = Utils::RoundUp(growth_target - in_use_after,
-                                                PageSpace::kPageSize);
-      int growth_in_pages = growth_in_bytes / PageSpace::kPageSize;
-      grow_heap_ = Utils::Maximum(growth_in_pages, heap_growth_rate_);
-    } else {
-      grow_heap_ = heap_growth_rate_;
-    }
+    intptr_t growth_target = static_cast<intptr_t>(in_use_after /
+                                                   desired_utilization_);
+    intptr_t growth_in_bytes = Utils::RoundUp(growth_target - in_use_after,
+                                              PageSpace::kPageSize);
+    int growth_in_pages = growth_in_bytes / PageSpace::kPageSize;
+    grow_heap_ = Utils::Maximum(growth_in_pages, heap_growth_rate_);
+    heap->RecordData(PageSpace::kPageGrowth, growth_in_pages);
   }
+  heap->RecordData(PageSpace::kGarbageRatio, collected_garbage_ratio);
+  heap->RecordData(PageSpace::kGCTimeFraction,
+                   garbage_collection_time_fraction);
+  heap->RecordData(PageSpace::kAllowedGrowth, grow_heap_);
 }
 
 
diff --git a/runtime/vm/pages.h b/runtime/vm/pages.h
index 4f51658..69632b6 100644
--- a/runtime/vm/pages.h
+++ b/runtime/vm/pages.h
@@ -135,7 +135,7 @@
   bool is_enabled_;
 
   // Heap growth control variable.
-  uword grow_heap_;
+  intptr_t grow_heap_;
 
   // If the garbage collector was not able to free more than heap_growth_ratio_
   // memory, then the heap is grown. Otherwise garbage collection is performed.
@@ -195,7 +195,7 @@
                         HeapPage::PageType type) const;
 
   // Collect the garbage in the page space using mark-sweep.
-  void MarkSweep(bool invoke_api_callbacks, const char* gc_reason);
+  void MarkSweep(bool invoke_api_callbacks);
 
   static HeapPage* PageFor(RawObject* raw_obj) {
     return reinterpret_cast<HeapPage*>(
@@ -221,6 +221,20 @@
   PeerTable* GetPeerTable() { return &peer_table_; }
 
  private:
+  // Ids for time and data records in Heap::GCStats.
+  enum {
+    // Time
+    kMarkObjects = 0,
+    kResetFreeLists = 1,
+    kSweepPages = 2,
+    kSweepLargePages = 3,
+    // Data
+    kGarbageRatio = 0,
+    kGCTimeFraction = 1,
+    kPageGrowth = 2,
+    kAllowedGrowth = 3
+  };
+
   static const intptr_t kAllocatablePageSize = kPageSize - sizeof(HeapPage);
 
   HeapPage* AllocatePage(HeapPage::PageType type);
@@ -251,14 +265,13 @@
   intptr_t capacity_;
   intptr_t in_use_;
 
-  // Old-gen GC cycle count.
-  int count_;
-
   // Keep track whether a MarkSweep is currently running.
   bool sweeping_;
 
   PageSpaceController page_space_controller_;
 
+  friend class PageSpaceController;
+
   DISALLOW_IMPLICIT_CONSTRUCTORS(PageSpace);
 };
 
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 397ccc1..179d96d 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -115,7 +115,7 @@
 
 LocalVariable* ParsedFunction::CreateExpressionTempVar(intptr_t token_pos) {
   return new LocalVariable(token_pos,
-                           String::ZoneHandle(Symbols::ExprTemp()),
+                           Symbols::ExprTemp(),
                            Type::ZoneHandle(Type::DynamicType()));
 }
 
@@ -140,7 +140,7 @@
     // name).
     if ((saved_args_desc_var->owner() == scope) &&
         saved_args_desc_var->name().StartsWith(
-            String::Handle(Symbols::SavedArgDescVarPrefix()))) {
+            Symbols::SavedArgDescVarPrefix())) {
       return saved_args_desc_var;
     }
   }
@@ -190,11 +190,9 @@
   // variables, the context needs to be saved on entry and restored on exit.
   // Add and allocate a local variable to this purpose.
   if ((context_owner != NULL) && !function().IsClosureFunction()) {
-    const String& context_var_name =
-        String::ZoneHandle(Symbols::SavedEntryContextVar());
     LocalVariable* context_var =
         new LocalVariable(function().token_pos(),
-                          context_var_name,
+                          Symbols::SavedEntryContextVar(),
                           Type::ZoneHandle(Type::DynamicType()));
     context_var->set_index(next_free_frame_index--);
     scope->AddVariable(context_var);
@@ -449,7 +447,7 @@
   void AddReceiver(const Type* receiver_type) {
     ASSERT(this->parameters->is_empty());
     AddFinalParameter(receiver_type->token_pos(),
-                      &Symbols::ThisHandle(),
+                      &Symbols::This(),
                       receiver_type);
   }
 
@@ -759,7 +757,7 @@
 
   if (!HasReturnNode(node_sequence)) {
     // Add implicit return node.
-    node_sequence->Add(new ReturnNode(parser.TokenPos()));
+    node_sequence->Add(new ReturnNode(func.end_token_pos()));
   }
   if (parser.expression_temp_ != NULL) {
     parsed_function->set_expression_temp_var(parser.expression_temp_);
@@ -807,6 +805,7 @@
   OpenFunctionBlock(func);
   AddFormalParamsToScope(&params, current_block_->scope);
 
+  intptr_t ident_pos = TokenPos();
   const String& field_name = *ExpectIdentifier("field name expected");
   const Class& field_class = Class::Handle(func.Owner());
   const Field& field =
@@ -828,7 +827,7 @@
     if (expr->EvalConstExpr() == NULL) {
       ErrorMsg(expr_pos, "initializer must be a compile-time constant");
     }
-    ReturnNode* return_node = new ReturnNode(TokenPos(), expr);
+    ReturnNode* return_node = new ReturnNode(ident_pos, expr);
     current_block_->statements->Add(return_node);
   } else {
     // This getter may be called each time the static field is accessed.
@@ -845,59 +844,55 @@
 
     // Generate code checking for circular dependency in field initialization.
     AstNode* compare_circular = new ComparisonNode(
-        TokenPos(),
+        ident_pos,
         Token::kEQ_STRICT,
-        new LoadStaticFieldNode(TokenPos(), field),
-        new LiteralNode(TokenPos(),
-                        Instance::ZoneHandle(Object::transition_sentinel())));
+        new LoadStaticFieldNode(ident_pos, field),
+        new LiteralNode(ident_pos, Object::transition_sentinel()));
     // Set field to null prior to throwing exception, so that subsequent
     // accesses to the field do not throw again, since initializers should only
     // be executed once.
-    SequenceNode* report_circular = new SequenceNode(TokenPos(), NULL);
+    SequenceNode* report_circular = new SequenceNode(ident_pos, NULL);
     report_circular->Add(
         new StoreStaticFieldNode(
-            TokenPos(),
+            ident_pos,
             field,
-            new LiteralNode(TokenPos(), Instance::ZoneHandle())));
+            new LiteralNode(ident_pos, Instance::ZoneHandle())));
     // TODO(regis): Exception to throw is not specified by spec.
     const String& circular_error = String::ZoneHandle(
         Symbols::New("circular dependency in field initialization"));
     report_circular->Add(
-        new ThrowNode(TokenPos(),
-                      new LiteralNode(TokenPos(), circular_error),
+        new ThrowNode(ident_pos,
+                      new LiteralNode(ident_pos, circular_error),
                       NULL));
     AstNode* circular_check =
-        new IfNode(TokenPos(), compare_circular, report_circular, NULL);
+        new IfNode(ident_pos, compare_circular, report_circular, NULL);
     current_block_->statements->Add(circular_check);
 
     // Generate code checking for uninitialized field.
     AstNode* compare_uninitialized = new ComparisonNode(
-        TokenPos(),
+        ident_pos,
         Token::kEQ_STRICT,
-        new LoadStaticFieldNode(TokenPos(), field),
-        new LiteralNode(TokenPos(),
-                        Instance::ZoneHandle(Object::sentinel())));
-    SequenceNode* initialize_field = new SequenceNode(TokenPos(), NULL);
+        new LoadStaticFieldNode(ident_pos, field),
+        new LiteralNode(ident_pos, Object::sentinel()));
+    SequenceNode* initialize_field = new SequenceNode(ident_pos, NULL);
     initialize_field->Add(
         new StoreStaticFieldNode(
-            TokenPos(),
+            ident_pos,
             field,
-            new LiteralNode(
-                TokenPos(),
-                Instance::ZoneHandle(Object::transition_sentinel()))));
+            new LiteralNode(ident_pos, Object::transition_sentinel())));
     // TODO(hausner): If evaluation of the field value throws an exception,
     // we leave the field value as 'transition_sentinel', which is wrong.
     // A second reference to the field later throws a circular dependency
     // exception. The field should instead be set to null after an exception.
-    initialize_field->Add(new StoreStaticFieldNode(TokenPos(), field, expr));
+    initialize_field->Add(new StoreStaticFieldNode(ident_pos, field, expr));
     AstNode* uninitialized_check =
-        new IfNode(TokenPos(), compare_uninitialized, initialize_field, NULL);
+        new IfNode(ident_pos, compare_uninitialized, initialize_field, NULL);
     current_block_->statements->Add(uninitialized_check);
 
     // Generate code returning the field value.
     ReturnNode* return_node =
-        new ReturnNode(TokenPos(),
-                       new LoadStaticFieldNode(TokenPos(), field));
+        new ReturnNode(ident_pos,
+                       new LoadStaticFieldNode(ident_pos, field));
     current_block_->statements->Add(return_node);
   }
   return CloseBlock();
@@ -911,8 +906,10 @@
 SequenceNode* Parser::ParseInstanceGetter(const Function& func) {
   TRACE_PARSER("ParseInstanceGetter");
   ParamList params;
+  // func.token_pos() points to the name of the field.
+  intptr_t ident_pos = func.token_pos();
   ASSERT(current_class().raw() == func.Owner());
-  params.AddReceiver(ReceiverType(TokenPos()));
+  params.AddReceiver(ReceiverType(ident_pos));
   ASSERT(func.num_fixed_parameters() == 1);  // receiver.
   ASSERT(!func.HasOptionalParameters());
   ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
@@ -923,9 +920,7 @@
 
   // Receiver is local 0.
   LocalVariable* receiver = current_block_->scope->VariableAt(0);
-  LoadLocalNode* load_receiver = new LoadLocalNode(TokenPos(), receiver);
-  // TokenPos() returns the function's token position which points to the
-  // name of the field;
+  LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver);
   ASSERT(IsIdentifier());
   const String& field_name = *CurrentLiteral();
   const Class& field_class = Class::Handle(func.Owner());
@@ -933,9 +928,9 @@
       Field::ZoneHandle(field_class.LookupInstanceField(field_name));
 
   LoadInstanceFieldNode* load_field =
-      new LoadInstanceFieldNode(TokenPos(), load_receiver, field);
+      new LoadInstanceFieldNode(ident_pos, load_receiver, field);
 
-  ReturnNode* return_node = new ReturnNode(TokenPos(), load_field);
+  ReturnNode* return_node = new ReturnNode(ident_pos, load_field);
   current_block_->statements->Add(return_node);
   return CloseBlock();
 }
@@ -948,8 +943,8 @@
 //   ReturnNode (void);
 SequenceNode* Parser::ParseInstanceSetter(const Function& func) {
   TRACE_PARSER("ParseInstanceSetter");
-  // TokenPos() returns the function's token position which points to
-  // the name of the field; we can use it to form the field_name.
+  // func.token_pos() points to the name of the field.
+  intptr_t ident_pos = func.token_pos();
   const String& field_name = *CurrentLiteral();
   const Class& field_class = Class::ZoneHandle(func.Owner());
   const Field& field =
@@ -958,9 +953,9 @@
 
   ParamList params;
   ASSERT(current_class().raw() == func.Owner());
-  params.AddReceiver(ReceiverType(TokenPos()));
-  params.AddFinalParameter(TokenPos(),
-                           &String::ZoneHandle(Symbols::Value()),
+  params.AddReceiver(ReceiverType(ident_pos));
+  params.AddFinalParameter(ident_pos,
+                           &Symbols::Value(),
                            &field_type);
   ASSERT(func.num_fixed_parameters() == 2);  // receiver, value.
   ASSERT(!func.HasOptionalParameters());
@@ -971,15 +966,15 @@
   AddFormalParamsToScope(&params, current_block_->scope);
 
   LoadLocalNode* receiver =
-      new LoadLocalNode(TokenPos(), current_block_->scope->VariableAt(0));
+      new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(0));
   LoadLocalNode* value =
-      new LoadLocalNode(TokenPos(), current_block_->scope->VariableAt(1));
+      new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(1));
 
   StoreInstanceFieldNode* store_field =
-      new StoreInstanceFieldNode(TokenPos(), receiver, field, value);
+      new StoreInstanceFieldNode(ident_pos, receiver, field, value);
 
   current_block_->statements->Add(store_field);
-  current_block_->statements->Add(new ReturnNode(TokenPos()));
+  current_block_->statements->Add(new ReturnNode(ident_pos));
   return CloseBlock();
 }
 
@@ -1125,7 +1120,7 @@
       // Add implicit closure object parameter.
       func_params.AddFinalParameter(
           TokenPos(),
-          &String::ZoneHandle(Symbols::ClosureParameter()),
+          &Symbols::ClosureParameter(),
           &Type::ZoneHandle(Type::DynamicType()));
 
       const bool no_explicit_default_values = false;
@@ -1286,6 +1281,7 @@
 // set is_no_such_method to true..
 RawFunction* Parser::GetSuperFunction(intptr_t token_pos,
                                       const String& name,
+                                      ArgumentListNode* arguments,
                                       bool resolve_getter,
                                       bool* is_no_such_method) {
   const Class& super_class = Class::Handle(current_class().SuperClass());
@@ -1293,18 +1289,22 @@
     ErrorMsg(token_pos, "class '%s' does not have a superclass",
              String::Handle(current_class().Name()).ToCString());
   }
-  Function& super_func =
-      Function::Handle(Resolver::ResolveDynamicAnyArgs(super_class, name));
-  if (super_func.IsNull() && resolve_getter) {
+  Function& super_func = Function::Handle(
+      Resolver::ResolveDynamicAnyArgs(super_class, name));
+  if (!super_func.IsNull() &&
+      !super_func.AreValidArguments(arguments->length(),
+                                    arguments->names(),
+                                    NULL)) {
+    super_func = Function::null();
+  } else if (super_func.IsNull() && resolve_getter) {
     const String& getter_name = String::ZoneHandle(Field::GetterName(name));
     super_func = Resolver::ResolveDynamicAnyArgs(super_class, getter_name);
     ASSERT(super_func.IsNull() ||
            (super_func.kind() != RawFunction::kConstImplicitGetter));
   }
   if (super_func.IsNull()) {
-    const String& no_such_method_name = String::Handle(Symbols::NoSuchMethod());
     super_func =
-        Resolver::ResolveDynamicAnyArgs(super_class, no_such_method_name);
+        Resolver::ResolveDynamicAnyArgs(super_class, Symbols::NoSuchMethod());
     ASSERT(!super_func.IsNull());
     *is_no_such_method = true;
   } else {
@@ -1352,13 +1352,11 @@
   }
   arguments->Add(args_array);
   // Lookup the static InvocationMirror._allocateInvocationMirror method.
-  const Class& mirror_class = Class::Handle(
-      LookupCoreClass(String::Handle(Symbols::InvocationMirror())));
+  const Class& mirror_class =
+      Class::Handle(LookupCoreClass(Symbols::InvocationMirror()));
   ASSERT(!mirror_class.IsNull());
-  const String& allocation_function_name =
-      String::Handle(Symbols::AllocateInvocationMirror());
   const Function& allocation_function = Function::ZoneHandle(
-      mirror_class.LookupStaticFunction(allocation_function_name));
+      mirror_class.LookupStaticFunction(Symbols::AllocateInvocationMirror()));
   ASSERT(!allocation_function.IsNull());
   return new StaticCallNode(call_pos, allocation_function, arguments);
 }
@@ -1384,18 +1382,22 @@
   ASSERT(CurrentToken() == Token::kLPAREN);
   const intptr_t supercall_pos = TokenPos();
 
+  // 'this' parameter is the first argument to super call.
+  ArgumentListNode* arguments = new ArgumentListNode(supercall_pos);
+  AstNode* receiver = LoadReceiver(supercall_pos);
+  arguments->Add(receiver);
+  ParseActualParameters(arguments, kAllowConst);
+
   const bool kResolveGetter = true;
   bool is_no_such_method = false;
   const Function& super_function = Function::ZoneHandle(
       GetSuperFunction(supercall_pos,
                        function_name,
+                       arguments,
                        kResolveGetter,
                        &is_no_such_method));
-  ArgumentListNode* arguments = new ArgumentListNode(supercall_pos);
   if (super_function.IsGetterFunction() ||
       super_function.IsImplicitGetterFunction()) {
-    // 'this' is not passed as parameter to the closure.
-    ParseActualParameters(arguments, kAllowConst);
     const Class& super_class = Class::ZoneHandle(current_class().SuperClass());
     AstNode* closure = new StaticGetterNode(supercall_pos,
                                             LoadReceiver(supercall_pos),
@@ -1403,12 +1405,13 @@
                                             super_class,
                                             function_name);
     EnsureExpressionTemp();
-    return new ClosureCallNode(supercall_pos, closure, arguments);
+    // 'this' is not passed as parameter to the closure.
+    ArgumentListNode* closure_arguments = new ArgumentListNode(supercall_pos);
+    for (int i = 1; i < arguments->length(); i++) {
+      closure_arguments->Add(arguments->NodeAt(i));
+    }
+    return new ClosureCallNode(supercall_pos, closure, closure_arguments);
   }
-  // 'this' parameter is the first argument to super call.
-  AstNode* receiver = LoadReceiver(supercall_pos);
-  arguments->Add(receiver);
-  ParseActualParameters(arguments, kAllowConst);
   if (is_no_such_method) {
     arguments = BuildNoSuchMethodArguments(
         supercall_pos, function_name, *arguments);
@@ -1438,16 +1441,17 @@
     // Resolve the operator function in the superclass.
     const String& operator_function_name =
         String::ZoneHandle(Symbols::New(Token::Str(op)));
+    ArgumentListNode* op_arguments = new ArgumentListNode(super_pos);
+    AstNode* receiver = LoadReceiver(super_pos);
+    op_arguments->Add(receiver);
     const bool kResolveGetter = false;
     bool is_no_such_method = false;
     const Function& super_operator = Function::ZoneHandle(
         GetSuperFunction(super_pos,
                          operator_function_name,
+                         op_arguments,
                          kResolveGetter,
                          &is_no_such_method));
-    ArgumentListNode* op_arguments = new ArgumentListNode(super_pos);
-    AstNode* receiver = LoadReceiver(super_pos);
-    op_arguments->Add(receiver);
     if (is_no_such_method) {
       op_arguments = BuildNoSuchMethodArguments(
           super_pos, operator_function_name, *op_arguments);
@@ -1485,17 +1489,6 @@
       negate_result = true;
     }
 
-    // Resolve the operator function in the superclass.
-    const String& operator_function_name =
-        String::Handle(Symbols::New(Token::Str(op)));
-    const bool kResolveGetter = false;
-    bool is_no_such_method = false;
-    const Function& super_operator = Function::ZoneHandle(
-        GetSuperFunction(operator_pos,
-                         operator_function_name,
-                         kResolveGetter,
-                         &is_no_such_method));
-
     ASSERT(Token::Precedence(op) >= Token::Precedence(Token::kBIT_OR));
     AstNode* other_operand = ParseBinaryExpr(Token::Precedence(op) + 1);
 
@@ -1504,6 +1497,17 @@
     op_arguments->Add(receiver);
     op_arguments->Add(other_operand);
 
+    // Resolve the operator function in the superclass.
+    const String& operator_function_name =
+        String::ZoneHandle(Symbols::New(Token::Str(op)));
+    const bool kResolveGetter = false;
+    bool is_no_such_method = false;
+    const Function& super_operator = Function::ZoneHandle(
+        GetSuperFunction(operator_pos,
+                         operator_function_name,
+                         op_arguments,
+                         kResolveGetter,
+                         &is_no_such_method));
     if (is_no_such_method) {
       op_arguments = BuildNoSuchMethodArguments(
           operator_pos, operator_function_name, *op_arguments);
@@ -1527,7 +1531,8 @@
     // parameterized class, make sure that the receiver is captured as
     // instantiator.
     if (current_block_->scope->function_level() > 0) {
-      const Class& signature_class = Class::Handle(func.signature_class());
+      const Class& signature_class = Class::Handle(
+          implicit_closure_function.signature_class());
       if (signature_class.NumTypeParameters() > 0) {
         CaptureInstantiator();
       }
@@ -1568,15 +1573,16 @@
     // creating an implicit closure of the function and returning it.
     const Function& super_function = Function::ZoneHandle(
         Resolver::ResolveDynamicAnyArgs(super_class, field_name));
-    if (super_function.IsNull()) {
-      ErrorMsg(field_pos, "field or getter '%s' not found in superclass",
-               field_name.ToCString());
+    if (!super_function.IsNull()) {
+      // In case CreateAssignmentNode is called later on this
+      // CreateImplicitClosureNode, it will be replaced by a StaticSetterNode.
+      return CreateImplicitClosureNode(super_function,
+                                       field_pos,
+                                       implicit_argument);
     }
-    return CreateImplicitClosureNode(super_function,
-                                     field_pos,
-                                     implicit_argument);
+    // No function or field exists of the specified field_name.
+    // Emit a StaticGetterNode anyway, so that noSuchMethod gets called.
   }
-
   return new StaticGetterNode(
       field_pos, implicit_argument, true, super_class, field_name);
 }
@@ -1595,7 +1601,7 @@
     return;
   }
   String& ctor_name = String::Handle(super_class.Name());
-  ctor_name = String::Concat(ctor_name, Symbols::DotHandle());
+  ctor_name = String::Concat(ctor_name, Symbols::Dot());
   ArgumentListNode* arguments = new ArgumentListNode(supercall_pos);
   // Implicit 'this' parameter is the first argument.
   AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver);
@@ -1635,7 +1641,7 @@
   const Class& super_class = Class::Handle(cls.SuperClass());
   ASSERT(!super_class.IsNull());
   String& ctor_name = String::Handle(super_class.Name());
-  ctor_name = String::Concat(ctor_name, Symbols::DotHandle());
+  ctor_name = String::Concat(ctor_name, Symbols::Dot());
   if (CurrentToken() == Token::kPERIOD) {
     ConsumeToken();
     ctor_name = String::Concat(ctor_name,
@@ -1854,7 +1860,7 @@
   ConsumeToken();
   String& ctor_name = String::Handle(cls.Name());
 
-  ctor_name = String::Concat(ctor_name, Symbols::DotHandle());
+  ctor_name = String::Concat(ctor_name, Symbols::Dot());
   if (CurrentToken() == Token::kPERIOD) {
     ConsumeToken();
     ctor_name = String::Concat(ctor_name,
@@ -1903,13 +1909,13 @@
   const Class& cls = Class::Handle(func.Owner());
   LocalVariable* receiver = new LocalVariable(
       ctor_pos,
-      Symbols::ThisHandle(),
+      Symbols::This(),
       Type::ZoneHandle(Type::DynamicType()));
   current_block_->scope->AddVariable(receiver);
 
   LocalVariable* phase_parameter = new LocalVariable(
        ctor_pos,
-       String::ZoneHandle(Symbols::PhaseParameter()),
+       Symbols::PhaseParameter(),
        Type::ZoneHandle(Type::SmiType()));
   current_block_->scope->AddVariable(phase_parameter);
 
@@ -1977,7 +1983,7 @@
   // Add implicit parameter for construction phase.
   params.AddFinalParameter(
       TokenPos(),
-      &String::ZoneHandle(Symbols::PhaseParameter()),
+      &Symbols::PhaseParameter(),
       &Type::ZoneHandle(Type::SmiType()));
 
   if (func.is_const()) {
@@ -2225,7 +2231,7 @@
     ASSERT(!func.is_const());  // Closure functions cannot be const.
     params.AddFinalParameter(
         TokenPos(),
-        &String::ZoneHandle(Symbols::ClosureParameter()),
+        &Symbols::ClosureParameter(),
         &Type::ZoneHandle(Type::DynamicType()));
   } else if (!func.is_static()) {
     // Static functions do not have a receiver.
@@ -2236,7 +2242,7 @@
     // the type of the instance to be allocated.
     params.AddFinalParameter(
         TokenPos(),
-        &String::ZoneHandle(Symbols::TypeArgumentsParameter()),
+        &Symbols::TypeArgumentsParameter(),
         &Type::ZoneHandle(Type::DynamicType()));
   }
   ASSERT((CurrentToken() == Token::kLPAREN) || func.IsGetterFunction());
@@ -2304,8 +2310,10 @@
   } else if (func.is_external()) {
     // Body of an external method contains a single throw.
     const String& function_name = String::ZoneHandle(func.name());
+    // TODO(regis): For an instance function, pass the receiver to
+    // NoSuchMethodError.
     current_block_->statements->Add(
-        ThrowNoSuchMethodError(TokenPos(), function_name));
+        ThrowNoSuchMethodError(TokenPos(), current_class(), function_name));
   } else {
     UnexpectedToken();
   }
@@ -2443,14 +2451,14 @@
   } else if (method->IsFactory()) {
     method->params.AddFinalParameter(
         formal_param_pos,
-        &String::ZoneHandle(Symbols::TypeArgumentsParameter()),
+        &Symbols::TypeArgumentsParameter(),
         &Type::ZoneHandle(Type::DynamicType()));
   }
   // Constructors have an implicit parameter for the construction phase.
   if (method->IsConstructor()) {
     method->params.AddFinalParameter(
         TokenPos(),
-        &String::ZoneHandle(Symbols::PhaseParameter()),
+        &Symbols::PhaseParameter(),
         &Type::ZoneHandle(Type::SmiType()));
   }
   if (are_implicitly_final) {
@@ -2544,7 +2552,7 @@
       ConsumeToken();  // Colon.
       ExpectToken(Token::kTHIS);
       String& redir_name = String::ZoneHandle(
-          String::Concat(members->class_name(), Symbols::DotHandle()));
+          String::Concat(members->class_name(), Symbols::Dot()));
       if (CurrentToken() == Token::kPERIOD) {
         ConsumeToken();
         redir_name = String::Concat(redir_name,
@@ -2590,7 +2598,7 @@
       SkipExpr();
       ExpectSemicolon();
     }
-    method_end_pos = TokenPos();
+    method_end_pos = TokenPos() - 1;
   } else if (IsLiteral("native")) {
     if (method->has_abstract) {
       ErrorMsg(method->name_pos,
@@ -2717,7 +2725,7 @@
     bool has_simple_literal = false;
     if (has_initializer) {
       ConsumeToken();
-      init_value = Object::sentinel();
+      init_value = Object::sentinel().raw();
       // For static const fields, the initialization expression
       // will be parsed through the kConstImplicitGetter method
       // invocation/compilation.
@@ -2802,7 +2810,7 @@
         ASSERT(current_class().raw() == setter.Owner());
         params.AddReceiver(ReceiverType(TokenPos()));
         params.AddFinalParameter(TokenPos(),
-                                 &String::ZoneHandle(Symbols::Value()),
+                                 &Symbols::Value(),
                                  field->type);
         setter.set_result_type(Type::Handle(Type::VoidType()));
         AddFormalParamsToFunction(&params, setter);
@@ -2950,7 +2958,7 @@
     }
     // We must be dealing with a constructor or named constructor.
     member.kind = RawFunction::kConstructor;
-    *member.name = String::Concat(*member.name, Symbols::DotHandle());
+    *member.name = String::Concat(*member.name, Symbols::Dot());
     if (CurrentToken() == Token::kPERIOD) {
       // Named constructor.
       ConsumeToken();
@@ -3097,15 +3105,15 @@
     }
     cls ^= obj.raw();
     if (is_patch) {
-      String& patch = String::Handle(Symbols::New("patch "));
-      patch = String::Concat(patch, class_name);
+      String& patch = String::Handle(
+          String::Concat(Symbols::PatchSpace(), class_name));
       patch = Symbols::New(patch);
       cls = Class::New(patch, script_, classname_pos);
       cls.set_library(library_);
     } else {
       // Not patching a class, but it has been found. This must be one of the
       // pre-registered classes from object.cc or a duplicate definition.
-      if (cls.functions() != Object::empty_array()) {
+      if (cls.functions() != Object::empty_array().raw()) {
         ErrorMsg(classname_pos, "class '%s' is already defined",
                  class_name.ToCString());
       }
@@ -3114,7 +3122,7 @@
     }
   }
   ASSERT(!cls.IsNull());
-  ASSERT(cls.functions() == Object::empty_array());
+  ASSERT(cls.functions() == Object::empty_array().raw());
   set_current_class(cls);
   ParseTypeParameters(cls);
   Type& super_type = Type::Handle();
@@ -3140,7 +3148,7 @@
   if (CurrentToken() == Token::kIMPLEMENTS) {
     Array& interfaces = Array::Handle();
     const intptr_t interfaces_pos = TokenPos();
-    interfaces = ParseInterfaceList();
+    interfaces = ParseInterfaceList(super_type);
     AddInterfaces(interfaces_pos, cls, interfaces);
   }
 
@@ -3189,7 +3197,7 @@
   // The implicit constructor is unnamed, has no explicit parameter,
   // and contains a supercall in the initializer list.
   String& ctor_name = String::ZoneHandle(
-    String::Concat(class_desc->class_name(), Symbols::DotHandle()));
+    String::Concat(class_desc->class_name(), Symbols::Dot()));
   ctor_name = Symbols::New(ctor_name);
   // The token position for the implicit constructor is the 'class'
   // keyword of the constructor's class.
@@ -3208,7 +3216,7 @@
   params.AddReceiver(ReceiverType(TokenPos()));
   // Add implicit parameter for construction phase.
   params.AddFinalParameter(TokenPos(),
-                           &String::ZoneHandle(Symbols::PhaseParameter()),
+                           &Symbols::PhaseParameter(),
                            &Type::ZoneHandle(Type::SmiType()));
 
   AddFormalParamsToFunction(&params, ctor);
@@ -3289,9 +3297,7 @@
   // Allocate an abstract class to hold the type parameters and their bounds.
   // Make it the owner of the function type descriptor.
   const Class& alias_owner = Class::Handle(
-      Class::New(String::Handle(Symbols::New(":alias_owner")),
-                 Script::Handle(),
-                 TokenPos()));
+      Class::New(Symbols::AliasOwner(), Script::Handle(), TokenPos()));
 
   alias_owner.set_is_abstract();
   alias_owner.set_library(library_);
@@ -3330,7 +3336,7 @@
   // Add implicit closure object parameter.
   func_params.AddFinalParameter(
       TokenPos(),
-      &String::ZoneHandle(Symbols::ClosureParameter()),
+      &Symbols::ClosureParameter(),
       &Type::ZoneHandle(Type::DynamicType()));
 
   const bool no_explicit_default_values = false;
@@ -3566,7 +3572,7 @@
 
 
 // Parse and return an array of interface types.
-RawArray* Parser::ParseInterfaceList() {
+RawArray* Parser::ParseInterfaceList(const Type& super_type) {
   TRACE_PARSER("ParseInterfaceList");
   ASSERT((CurrentToken() == Token::kIMPLEMENTS) ||
          (CurrentToken() == Token::kEXTENDS));
@@ -3576,14 +3582,19 @@
   AbstractType& interface = AbstractType::Handle();
   String& other_name = String::Handle();
   AbstractType& other_interface = AbstractType::Handle();
+  const String& super_type_name = String::Handle(super_type.Name());
   do {
     ConsumeToken();
     intptr_t interface_pos = TokenPos();
     interface = ParseType(ClassFinalizer::kTryResolve);
     interface_name = interface.UserVisibleName();
+    if (interface_name.Equals(super_type_name)) {
+      ErrorMsg(interface_pos, "class may not extend and implement '%s'",
+               interface_name.ToCString());
+    }
     for (int i = 0; i < interfaces.Length(); i++) {
       other_interface ^= interfaces.At(i);
-      other_name = other_interface.UserVisibleName();
+      other_name = other_interface.Name();
       if (interface_name.Equals(other_name)) {
         ErrorMsg(interface_pos, "duplicate interface '%s'",
                  interface_name.ToCString());
@@ -3597,30 +3608,18 @@
 
 // Add 'interface' to 'interface_list' if it is not already in the list.
 // An error is reported if the interface conflicts with an interface already in
-// the list with the same class, but different type arguments.
-// Non-conflicting duplicates are ignored without error.
+// the list with the same class and same type arguments.
 void Parser::AddInterfaceIfUnique(intptr_t interfaces_pos,
                                   const GrowableObjectArray& interface_list,
                                   const AbstractType& interface) {
-  String& interface_class_name = String::Handle(interface.ClassName());
-  String& existing_interface_class_name = String::Handle();
-  String& interface_name = String::Handle();
+  String& interface_name = String::Handle(interface.Name());
   String& existing_interface_name = String::Handle();
   AbstractType& other_interface = AbstractType::Handle();
   for (intptr_t i = 0; i < interface_list.Length(); i++) {
     other_interface ^= interface_list.At(i);
-    existing_interface_class_name = other_interface.ClassName();
-    if (interface_class_name.Equals(existing_interface_class_name)) {
-      // Same interface class name, now check names of type arguments.
-      interface_name = interface.Name();
-      existing_interface_name = other_interface.Name();
-      // TODO(regis): Revisit depending on the outcome of issue 4905685.
-      if (!interface_name.Equals(existing_interface_name)) {
-        ErrorMsg(interfaces_pos,
-                 "interface '%s' conflicts with interface '%s'",
-                 String::Handle(interface.UserVisibleName()).ToCString(),
-                 String::Handle(other_interface.UserVisibleName()).ToCString());
-      }
+    existing_interface_name = other_interface.Name();
+    if (interface_name.Equals(existing_interface_name)) {
+      return;
     }
   }
   interface_list.Add(interface);
@@ -3698,7 +3697,7 @@
     library_.AddObject(field, var_name);
     if (CurrentToken() == Token::kASSIGN) {
       ConsumeToken();
-      Instance& field_value = Instance::Handle(Object::sentinel());
+      Instance& field_value = Instance::Handle(Object::sentinel().raw());
       bool has_simple_literal = false;
       if (is_final && (LookaheadToken(1) == Token::kSEMICOLON)) {
         has_simple_literal = IsSimpleLiteral(type, &field_value);
@@ -3791,12 +3790,12 @@
     ExpectSemicolon();
   } else if (CurrentToken() == Token::kLBRACE) {
     SkipBlock();
-    function_end_pos = TokenPos();
+    function_end_pos = TokenPos() - 1;
   } else if (CurrentToken() == Token::kARROW) {
     ConsumeToken();
     SkipExpr();
     ExpectSemicolon();
-    function_end_pos = TokenPos();
+    function_end_pos = TokenPos() - 1;
   } else if (IsLiteral("native")) {
     ParseNativeDeclaration();
   } else {
@@ -4078,7 +4077,7 @@
   if (CurrentToken() == Token::kPERIOD) {
     while (CurrentToken() == Token::kPERIOD) {
       ConsumeToken();
-      lib_name = String::Concat(lib_name, Symbols::DotHandle());
+      lib_name = String::Concat(lib_name, Symbols::Dot());
       lib_name = String::Concat(lib_name,
           *ExpectIdentifier("malformed library name"));
     }
@@ -4317,7 +4316,7 @@
   is_top_level_ = true;
   TopLevel top_level;
   Class& toplevel_class = Class::Handle(
-      Class::New(String::Handle(Symbols::TopLevel()), script_, TokenPos()));
+      Class::New(Symbols::TopLevel(), script_, TokenPos()));
   toplevel_class.set_library(library_);
 
   if (is_library_source()) {
@@ -4538,21 +4537,20 @@
 
 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, bool test_only) {
   ASSERT(!current_function().is_static());
-  return from_scope->LookupVariable(Symbols::ThisHandle(), test_only);
+  return from_scope->LookupVariable(Symbols::This(), test_only);
 }
 
 
 LocalVariable* Parser::LookupTypeArgumentsParameter(LocalScope* from_scope,
                                                     bool test_only) {
   ASSERT(current_function().IsInFactoryScope());
-  const String& param_name = String::Handle(Symbols::TypeArgumentsParameter());
-  return from_scope->LookupVariable(param_name, test_only);
+  return from_scope->LookupVariable(Symbols::TypeArgumentsParameter(),
+                                    test_only);
 }
 LocalVariable* Parser::LookupPhaseParameter() {
-  const String& phase_name =
-      String::Handle(Symbols::PhaseParameter());
   const bool kTestOnly = false;
-  return current_block_->scope->LookupVariable(phase_name, kTestOnly);
+  return current_block_->scope->LookupVariable(Symbols::PhaseParameter(),
+                                               kTestOnly);
 }
 
 
@@ -4730,7 +4728,7 @@
   if (FLAG_strict_function_literals) {
     if (is_literal) {
       ASSERT(CurrentToken() == Token::kLPAREN);
-      function_name = &String::ZoneHandle(Symbols::AnonymousClosure());
+      function_name = &Symbols::AnonymousClosure();
     } else {
       if (CurrentToken() == Token::kVOID) {
         ConsumeToken();
@@ -4762,7 +4760,7 @@
       if (!is_literal) {
         ErrorMsg("function name expected");
       }
-      function_name = &String::ZoneHandle(Symbols::AnonymousClosure());
+      function_name = &Symbols::AnonymousClosure();
     }
   }
 
@@ -4828,8 +4826,8 @@
   Array& default_parameter_values = Array::Handle();
   SequenceNode* statements = Parser::ParseFunc(function,
                                                default_parameter_values);
-  ASSERT(is_new_closure || (function.end_token_pos() == TokenPos()));
-  function.set_end_token_pos(TokenPos());
+  ASSERT(is_new_closure || (function.end_token_pos() == (TokenPos() - 1)));
+  function.set_end_token_pos(TokenPos() - 1);
 
   // Now that the local function has formal parameters, lookup the signature
   // class in the current library (but not in its imports) and only create a new
@@ -4989,11 +4987,11 @@
     return true;
   } else if ((CurrentToken() == Token::kTRUE) &&
       (no_check || type.IsBoolType())) {
-    *value = Bool::True();
+    *value = Bool::True().raw();
     return true;
   } else if ((CurrentToken() == Token::kFALSE) &&
       (no_check || type.IsBoolType())) {
-    *value = Bool::False();
+    *value = Bool::False().raw();
     return true;
   } else if (CurrentToken() == Token::kNULL) {
     *value = Instance::null();
@@ -5403,10 +5401,10 @@
         ArgumentListNode* arguments = new ArgumentListNode(TokenPos());
         arguments->Add(new LiteralNode(
             TokenPos(), Integer::ZoneHandle(Integer::New(TokenPos()))));
-        const String& cls_name = String::Handle(Symbols::FallThroughError());
-        const String& func_name = String::Handle(Symbols::ThrowNew());
         current_block_->statements->Add(
-            MakeStaticCall(cls_name, func_name, arguments));
+            MakeStaticCall(Symbols::FallThroughError(),
+                           Symbols::ThrowNew(),
+                           arguments));
       }
       break;
     }
@@ -5450,7 +5448,7 @@
   // Store switch expression in temporary local variable.
   LocalVariable* temp_variable =
       new LocalVariable(expr_pos,
-                        String::ZoneHandle(Symbols::New(":switch_expr")),
+                        Symbols::SwitchExpr(),
                         Type::ZoneHandle(Type::DynamicType()));
   current_block_->scope->AddVariable(temp_variable);
   AstNode* save_switch_expr =
@@ -5581,7 +5579,6 @@
   OpenBlock();  // Implicit block around while loop.
 
   // Generate implicit iterator variable and add to scope.
-  const String& iterator_name = String::ZoneHandle(Symbols::ForInIter());
   // We could set the type of the implicit iterator variable to Iterator<T>
   // where T is the type of the for loop variable. However, the type error
   // would refer to the compiler generated iterator and could confuse the user.
@@ -5589,15 +5586,13 @@
   // until the loop variable is assigned to.
   const AbstractType& iterator_type = Type::ZoneHandle(Type::DynamicType());
   LocalVariable* iterator_var =
-      new LocalVariable(collection_pos, iterator_name, iterator_type);
+      new LocalVariable(collection_pos, Symbols::ForInIter(), iterator_type);
   current_block_->scope->AddVariable(iterator_var);
 
   // Generate initialization of iterator variable.
-  const String& iterator_method_name =
-      String::ZoneHandle(Symbols::GetIterator());
   ArgumentListNode* no_args = new ArgumentListNode(collection_pos);
   AstNode* get_iterator = new InstanceCallNode(
-      collection_pos, collection_expr, iterator_method_name, no_args);
+      collection_pos, collection_expr, Symbols::GetIterator(), no_args);
   AstNode* iterator_init =
       new StoreLocalNode(collection_pos, iterator_var, get_iterator);
   current_block_->statements->Add(iterator_init);
@@ -5606,7 +5601,7 @@
   AstNode* iterator_has_next = new InstanceGetterNode(
       collection_pos,
       new LoadLocalNode(collection_pos, iterator_var),
-      String::ZoneHandle(Symbols::HasNext()));
+      Symbols::HasNext());
 
   // Parse the for loop body. Ideally, we would use ParseNestedStatement()
   // here, but that does not work well because we have to insert an implicit
@@ -5618,7 +5613,7 @@
   AstNode* iterator_next = new InstanceCallNode(
       collection_pos,
       new LoadLocalNode(collection_pos, iterator_var),
-      String::ZoneHandle(Symbols::Next()),
+      Symbols::Next(),
       no_args);
 
   // Generate assignment of next iterator value to loop variable.
@@ -5751,9 +5746,9 @@
       Integer::ZoneHandle(Integer::New(begin))));
   arguments->Add(new LiteralNode(end,
       Integer::ZoneHandle(Integer::New(end))));
-  const String& cls_name = String::Handle(Symbols::AssertionError());
-  const String& func_name = String::Handle(Symbols::ThrowNew());
-  return MakeStaticCall(cls_name, func_name, arguments);
+  return MakeStaticCall(Symbols::AssertionError(),
+                        Symbols::ThrowNew(),
+                        arguments);
 }
 
 
@@ -5911,33 +5906,27 @@
   // :exception_var and :stacktrace_var get set with the exception object
   // and the stacktrace object when an exception is thrown.
   // These three implicit variables can never be captured variables.
-  const String& context_var_name =
-      String::ZoneHandle(Symbols::SavedContextVar());
   LocalVariable* context_var =
-      current_block_->scope->LocalLookupVariable(context_var_name);
+      current_block_->scope->LocalLookupVariable(Symbols::SavedContextVar());
   if (context_var == NULL) {
     context_var = new LocalVariable(TokenPos(),
-                                    context_var_name,
+                                    Symbols::SavedContextVar(),
                                     Type::ZoneHandle(Type::DynamicType()));
     current_block_->scope->AddVariable(context_var);
   }
-  const String& catch_excp_var_name =
-      String::ZoneHandle(Symbols::ExceptionVar());
   LocalVariable* catch_excp_var =
-      current_block_->scope->LocalLookupVariable(catch_excp_var_name);
+      current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar());
   if (catch_excp_var == NULL) {
     catch_excp_var = new LocalVariable(TokenPos(),
-                                       catch_excp_var_name,
+                                       Symbols::ExceptionVar(),
                                        Type::ZoneHandle(Type::DynamicType()));
     current_block_->scope->AddVariable(catch_excp_var);
   }
-  const String& catch_trace_var_name =
-      String::ZoneHandle(Symbols::StacktraceVar());
   LocalVariable* catch_trace_var =
-      current_block_->scope->LocalLookupVariable(catch_trace_var_name);
+      current_block_->scope->LocalLookupVariable(Symbols::StacktraceVar());
   if (catch_trace_var == NULL) {
     catch_trace_var = new LocalVariable(TokenPos(),
-                                        catch_trace_var_name,
+                                        Symbols::StacktraceVar(),
                                         Type::ZoneHandle(Type::DynamicType()));
     current_block_->scope->AddVariable(catch_trace_var);
   }
@@ -6302,11 +6291,11 @@
     ASSERT(label->owner() != NULL);
     LocalScope* scope = label->owner()->parent();
     ASSERT(scope != NULL);
-    LocalVariable* excp_var = scope->LocalLookupVariable(
-        String::ZoneHandle(Symbols::ExceptionVar()));
+    LocalVariable* excp_var =
+        scope->LocalLookupVariable(Symbols::ExceptionVar());
     ASSERT(excp_var != NULL);
-    LocalVariable* trace_var = scope->LocalLookupVariable(
-        String::ZoneHandle(Symbols::StacktraceVar()));
+    LocalVariable* trace_var =
+        scope->LocalLookupVariable(Symbols::StacktraceVar());
     ASSERT(trace_var != NULL);
     statement = new ThrowNode(statement_pos,
                               new LoadLocalNode(statement_pos, excp_var),
@@ -6579,32 +6568,45 @@
   // Src value argument.
   arguments->Add(new LiteralNode(type_pos, Instance::ZoneHandle()));
   // Dst type name argument.
-  arguments->Add(new LiteralNode(type_pos, String::ZoneHandle(
-      Symbols::New("malformed"))));
+  arguments->Add(new LiteralNode(type_pos, Symbols::Malformed()));
   // Dst name argument.
-  arguments->Add(new LiteralNode(type_pos,
-                                 String::ZoneHandle(Symbols::Empty())));
+  arguments->Add(new LiteralNode(type_pos, Symbols::Empty()));
   // Malformed type error.
   const Error& error = Error::Handle(type.malformed_error());
   arguments->Add(new LiteralNode(type_pos, String::ZoneHandle(
       Symbols::New(error.ToErrorCString()))));
-  const String& cls_name = String::Handle(Symbols::TypeError());
-  const String& func_name = String::Handle(Symbols::ThrowNew());
-  return MakeStaticCall(cls_name, func_name, arguments);
+  return MakeStaticCall(Symbols::TypeError(), Symbols::ThrowNew(), arguments);
 }
 
 
-AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos, const String& name) {
+// TODO(regis): Providing the argument values is not always feasible, since
+// evaluating them could throw an error.
+// Should NoSuchMethodError reflect the argument count and names instead of
+// argument values? Or should the spec specify a different evaluation order?
+AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos,
+                                        const Class& cls,
+                                        const String& function_name) {
   ArgumentListNode* arguments = new ArgumentListNode(call_pos);
-  // Location argument.
+  // Object receiver.
+  // TODO(regis): For now, we pass a class literal of the unresolved
+  // method's owner, but this is not specified and will probably change.
+  Type& type = Type::ZoneHandle(
+      Type::New(cls, TypeArguments::Handle(), call_pos, Heap::kOld));
+  type ^= ClassFinalizer::FinalizeType(
+      current_class(), type, ClassFinalizer::kCanonicalize);
+  arguments->Add(new LiteralNode(call_pos, type));
+  // String memberName.
   arguments->Add(new LiteralNode(
-      call_pos, Integer::ZoneHandle(Integer::New(call_pos))));
-  // Function name argument.
-  arguments->Add(new LiteralNode(
-      call_pos, String::ZoneHandle(Symbols::New(name))));
-  const String& cls_name = String::Handle(Symbols::NoSuchMethodError());
-  const String& func_name = String::Handle(Symbols::ThrowNew());
-  return MakeStaticCall(cls_name, func_name, arguments);
+      call_pos, String::ZoneHandle(Symbols::New(function_name))));
+  // List arguments.
+  arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle()));
+  // List argumentNames.
+  arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle()));
+  // List existingArgumentNames.
+  arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle()));
+  return MakeStaticCall(Symbols::NoSuchMethodError(),
+                        Symbols::ThrowNew(),
+                        arguments);
 }
 
 
@@ -6886,14 +6888,14 @@
 // Ensure that the expression temp is allocated for nodes that may need it.
 AstNode* Parser::CreateAssignmentNode(AstNode* original, AstNode* rhs) {
   AstNode* result = original->MakeAssignmentNode(rhs);
-  if ((result == NULL) && original->IsStaticGetterNode()) {
-    const String& setter_name = String::ZoneHandle(
-        Field::SetterSymbol(original->AsStaticGetterNode()->field_name()));
-    result = ThrowNoSuchMethodError(original->token_pos(), setter_name);
+  if ((result == NULL) && original->IsTypeNode()) {
+    const String& type_name = String::ZoneHandle(
+        original->AsTypeNode()->type().ClassName());
+    // TODO(tball): determine whether NoSuchMethod should be called instead.
+    result = ThrowNoSuchMethodError(original->token_pos(),
+                                    current_class(),
+                                    type_name);
   }
-  // TODO(hausner): if we decide to throw a no such method error on
-  // assignment to a final variable, we need to do the same as in the
-  // StaticGetterNode above.
   if ((result != NULL) &&
       (result->IsStoreIndexedNode() ||
        result->IsInstanceSetterNode() ||
@@ -7154,11 +7156,10 @@
       const String& getter_name =
           String::ZoneHandle(Field::GetterName(func_name));
       const int kNumArguments = 0;  // no arguments.
-      const Array& kNoArgumentNames = Array::Handle();
       func = Resolver::ResolveStatic(cls,
                                      getter_name,
                                      kNumArguments,
-                                     kNoArgumentNames,
+                                     Object::empty_array(),
                                      Resolver::kIsQualified);
       if (!func.IsNull()) {
         ASSERT(func.kind() != RawFunction::kConstImplicitGetter);
@@ -7176,7 +7177,7 @@
       return new ClosureCallNode(call_pos, closure, arguments);
     }
     // Could not resolve static method: throw a NoSuchMethodError.
-    return ThrowNoSuchMethodError(ident_pos, func_name);
+    return ThrowNoSuchMethodError(ident_pos, cls, func_name);
   }
   return new StaticCallNode(call_pos, func, arguments);
 }
@@ -7215,8 +7216,8 @@
   }
   // The field is initialized.
   if (field.is_const()) {
-    ASSERT(field.value() != Object::sentinel());
-    ASSERT(field.value() != Object::transition_sentinel());
+    ASSERT(field.value() != Object::sentinel().raw());
+    ASSERT(field.value() != Object::transition_sentinel().raw());
     return new LiteralNode(ident_pos, Instance::ZoneHandle(field.value()));
   }
   // Access the field directly.
@@ -7240,15 +7241,14 @@
       const String& setter_name =
           String::ZoneHandle(Field::SetterName(field_name));
       const int kNumArguments = 1;  // value.
-      const Array& kNoArgumentNames = Array::Handle();
       func = Resolver::ResolveStatic(cls,
                                      setter_name,
                                      kNumArguments,
-                                     kNoArgumentNames,
+                                     Object::empty_array(),
                                      Resolver::kIsQualified);
       if (func.IsNull()) {
         // No field or explicit setter function, throw a NoSuchMethodError.
-        return ThrowNoSuchMethodError(ident_pos, field_name);
+        return ThrowNoSuchMethodError(ident_pos, cls, field_name);
       }
 
       // Explicit setter function for the field found, field does not exist.
@@ -7277,11 +7277,10 @@
       const String& getter_name =
           String::ZoneHandle(Field::GetterName(field_name));
       const int kNumArguments = 0;  // no arguments.
-      const Array& kNoArgumentNames = Array::Handle();
       func = Resolver::ResolveStatic(cls,
                                      getter_name,
                                      kNumArguments,
-                                     kNoArgumentNames,
+                                     Object::empty_array(),
                                      Resolver::kIsQualified);
       if (func.IsNull()) {
         // We might be referring to an implicit closure, check to see if
@@ -7289,7 +7288,7 @@
         func = cls.LookupStaticFunction(field_name);
         if (func.IsNull()) {
           // No field or explicit getter function, throw a NoSuchMethodError.
-          return ThrowNoSuchMethodError(ident_pos, field_name);
+          return ThrowNoSuchMethodError(ident_pos, cls, field_name);
         }
         access = CreateImplicitClosureNode(func, call_pos, NULL);
       } else {
@@ -7324,7 +7323,9 @@
     String& name = String::CheckedZoneHandle(primary->primary().raw());
     if (current_function().is_static() ||
         current_function().IsInFactoryScope()) {
-      return ThrowNoSuchMethodError(primary->token_pos(), name);
+      return ThrowNoSuchMethodError(primary->token_pos(),
+                                    current_class(),
+                                    name);
     } else {
       AstNode* receiver = LoadReceiver(primary->token_pos());
       return CallGetter(node->token_pos(), receiver, name);
@@ -7461,7 +7462,9 @@
           }
           String& name = String::CheckedZoneHandle(primary->primary().raw());
           if (current_function().is_static()) {
-            selector = ThrowNoSuchMethodError(primary->token_pos(), name);
+            selector = ThrowNoSuchMethodError(primary->token_pos(),
+                                              current_class(),
+                                              name);
           } else {
             // Treat as call to unresolved (instance) method.
             AstNode* receiver = LoadReceiver(primary->token_pos());
@@ -7486,13 +7489,14 @@
         if (primary->primary().IsFunction()) {
           // Treat as implicit closure.
           left = LoadClosure(primary);
-        } else if (left->AsPrimaryNode()->primary().IsClass()) {
-          Class& cls = Class::CheckedHandle(
-              left->AsPrimaryNode()->primary().raw());
-          String& cls_name = String::Handle(cls.Name());
-          ErrorMsg(left->token_pos(),
-                   "illegal use of class name '%s'",
-                   cls_name.ToCString());
+        } else if (primary->primary().IsClass()) {
+          const Class& type_class = Class::Cast(primary->primary());
+          Type& type = Type::ZoneHandle(
+              Type::New(type_class, TypeArguments::Handle(),
+                        primary->token_pos(), Heap::kOld));
+          type ^= ClassFinalizer::FinalizeType(
+              current_class(), type, ClassFinalizer::kCanonicalize);
+          left = new TypeNode(primary->token_pos(), type);
         } else if (primary->IsSuper()) {
           // Return "super" to handle unary super operator calls,
           // or to report illegal use of "super" otherwise.
@@ -7696,7 +7700,7 @@
   if (current_block_ == NULL) {
     return false;
   }
-  if (ident.Equals(Symbols::ThisHandle())) {
+  if (ident.Equals(Symbols::This())) {
     // 'this' is not a formal parameter.
     return false;
   }
@@ -7829,7 +7833,7 @@
 AstNode* Parser::RunStaticFieldInitializer(const Field& field) {
   ASSERT(field.is_static());
   const Instance& value = Instance::Handle(field.value());
-  if (value.raw() == Object::transition_sentinel()) {
+  if (value.raw() == Object::transition_sentinel().raw()) {
     if (field.is_const()) {
       ErrorMsg("circular dependency while initializing static field '%s'",
                String::Handle(field.name()).ToCString());
@@ -7841,29 +7845,27 @@
                                   Class::ZoneHandle(field.owner()),
                                   String::ZoneHandle(field.name()));
     }
-  } else if (value.raw() == Object::sentinel()) {
+  } else if (value.raw() == Object::sentinel().raw()) {
     // This field has not been referenced yet and thus the value has
     // not been evaluated. If the field is const, call the static getter method
     // to evaluate the expression and canonicalize the value.
     if (field.is_const()) {
-      field.set_value(Instance::Handle(Object::transition_sentinel()));
+      field.set_value(Object::transition_sentinel());
       const String& field_name = String::Handle(field.name());
       const String& getter_name =
           String::Handle(Field::GetterName(field_name));
       const Class& cls = Class::Handle(field.owner());
-      GrowableArray<const Object*> arguments;  // no arguments.
       const int kNumArguments = 0;  // no arguments.
-      const Array& kNoArgumentNames = Array::Handle();
       const Function& func =
           Function::Handle(Resolver::ResolveStatic(cls,
                                                    getter_name,
                                                    kNumArguments,
-                                                   kNoArgumentNames,
+                                                   Object::empty_array(),
                                                    Resolver::kIsQualified));
       ASSERT(!func.IsNull());
       ASSERT(func.kind() == RawFunction::kConstImplicitGetter);
       Object& const_value = Object::Handle(
-          DartEntry::InvokeStatic(func, arguments, kNoArgumentNames));
+          DartEntry::InvokeStatic(func, Object::empty_array()));
       if (const_value.IsError()) {
         const Error& error = Error::Cast(const_value);
         if (error.IsUnhandledException()) {
@@ -7901,8 +7903,9 @@
     const AbstractTypeArguments& type_arguments,
     const Function& constructor,
     ArgumentListNode* arguments) {
-  // +2 for implicit receiver and construction phase arguments.
-  GrowableArray<const Object*> arg_values(arguments->length() + 2);
+  const int kNumExtraArgs = 2;  // implicit rcvr and construction phase args.
+  const int num_arguments = arguments->length() + kNumExtraArgs;
+  const Array& arg_values = Array::Handle(Array::New(num_arguments));
   Instance& instance = Instance::Handle();
   ASSERT(!constructor.IsFactory());
   instance = Instance::New(type_class, Heap::kOld);
@@ -7913,17 +7916,21 @@
     instance.SetTypeArguments(
         AbstractTypeArguments::Handle(type_arguments.Canonicalize()));
   }
-  arg_values.Add(&instance);
-  arg_values.Add(&Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)));
+  arg_values.SetAt(0, instance);
+  arg_values.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll)));
   for (int i = 0; i < arguments->length(); i++) {
     AstNode* arg = arguments->NodeAt(i);
     // Arguments have been evaluated to a literal value already.
     ASSERT(arg->IsLiteralNode());
-    arg_values.Add(&arg->AsLiteralNode()->literal());
+    arg_values.SetAt((i + kNumExtraArgs), arg->AsLiteralNode()->literal());
   }
-  const Array& opt_arg_names = arguments->names();
-  const Object& result = Object::Handle(
-      DartEntry::InvokeStatic(constructor, arg_values, opt_arg_names));
+  const Array& arg_descriptor =
+      Array::Handle(ArgumentsDescriptor::New(num_arguments,
+                                             arguments->names()));
+  const Object& result =
+      Object::Handle(DartEntry::InvokeStatic(constructor,
+                                             arg_values,
+                                             arg_descriptor));
   if (result.IsError()) {
       if (result.IsUnhandledException()) {
         return result.raw();
@@ -8361,7 +8368,7 @@
       // the unresolved name to an instance field access, since a
       // subclass might define a field with this name.
       if (current_function().is_static()) {
-        resolved = ThrowNoSuchMethodError(ident_pos, ident);
+        resolved = ThrowNoSuchMethodError(ident_pos, current_class(), ident);
       } else {
         // Treat as call to unresolved instance field.
         resolved = CallGetter(ident_pos, LoadReceiver(ident_pos), ident);
@@ -8504,7 +8511,6 @@
   // comma after the last element.
   if (!is_empty_literal) {
     const bool saved_mode = SetAllowFunctionLiterals(true);
-    const String& dst_name = String::ZoneHandle(Symbols::ListLiteralElement());
     while (CurrentToken() != Token::kRBRACK) {
       const intptr_t element_pos = TokenPos();
       AstNode* element = ParseExpr(is_const, kConsumeCascades);
@@ -8514,7 +8520,7 @@
         element = new AssignableNode(element_pos,
                                      element,
                                      element_type,
-                                     dst_name);
+                                     Symbols::ListLiteralElement());
       }
       list->AddElement(element);
       if (CurrentToken() == Token::kCOMMA) {
@@ -8561,14 +8567,11 @@
     return new LiteralNode(literal_pos, const_list);
   } else {
     // Factory call at runtime.
-    String& factory_class_name = String::Handle(Symbols::List());
     const Class& factory_class =
-        Class::Handle(LookupCoreClass(factory_class_name));
+        Class::Handle(LookupCoreClass(Symbols::List()));
     ASSERT(!factory_class.IsNull());
-    const String& factory_method_name =
-        String::Handle(Symbols::ListLiteralFactory());
     const Function& factory_method = Function::ZoneHandle(
-        factory_class.LookupFactory(factory_method_name));
+        factory_class.LookupFactory(Symbols::ListLiteralFactory()));
     ASSERT(!factory_method.IsNull());
     if (!type_arguments.IsNull() &&
         !type_arguments.IsInstantiated() &&
@@ -8700,7 +8703,6 @@
 
   // Parse the map entries. Note: there may be an optional extra
   // comma after the last entry.
-  const String& dst_name = String::ZoneHandle(Symbols::ListLiteralElement());
   while (CurrentToken() != Token::kRBRACE) {
     AstNode* key = NULL;
     if (CurrentToken() == Token::kSTRING) {
@@ -8722,7 +8724,7 @@
       value = new AssignableNode(value_pos,
                                  value,
                                  value_type,
-                                 dst_name);
+                                 Symbols::ListLiteralElement());
     }
     AddKeyValuePair(kv_pairs, is_const, key, value);
 
@@ -8771,20 +8773,17 @@
     key_value_array.MakeImmutable();
 
     // Construct the map object.
-    const String& immutable_map_class_name =
-        String::Handle(Symbols::ImmutableMap());
     const Class& immutable_map_class =
-        Class::Handle(LookupCoreClass(immutable_map_class_name));
+        Class::Handle(LookupCoreClass(Symbols::ImmutableMap()));
     ASSERT(!immutable_map_class.IsNull());
     // If the immutable map class extends other parameterized classes, we need
     // to adjust the type argument vector. This is currently not the case.
     ASSERT(immutable_map_class.NumTypeArguments() == 2);
     ArgumentListNode* constr_args = new ArgumentListNode(TokenPos());
     constr_args->Add(new LiteralNode(literal_pos, key_value_array));
-    const String& constr_name =
-        String::Handle(Symbols::ImmutableMapConstructor());
-    const Function& map_constr = Function::ZoneHandle(
-        immutable_map_class.LookupConstructor(constr_name));
+    const Function& map_constr =
+        Function::ZoneHandle(immutable_map_class.LookupConstructor(
+            Symbols::ImmutableMapConstructor()));
     ASSERT(!map_constr.IsNull());
     const Object& constructor_result = Object::Handle(
         EvaluateConstConstructorCall(immutable_map_class,
@@ -8800,14 +8799,11 @@
     }
   } else {
     // Factory call at runtime.
-    String& factory_class_name = String::Handle(Symbols::Map());
     const Class& factory_class =
-        Class::Handle(LookupCoreClass(factory_class_name));
+        Class::Handle(LookupCoreClass(Symbols::Map()));
     ASSERT(!factory_class.IsNull());
-    const String& factory_method_name =
-        String::Handle(Symbols::MapLiteralFactory());
     const Function& factory_method = Function::ZoneHandle(
-        factory_class.LookupFactory(factory_method_name));
+        factory_class.LookupFactory(Symbols::MapLiteralFactory()));
     ASSERT(!factory_method.IsNull());
     if (!map_type_arguments.IsNull() &&
         !map_type_arguments.IsInstantiated() &&
@@ -8876,7 +8872,7 @@
   // unnamed constructor for class 'A' is labeled 'A.'.
   // This convention prevents users from explicitly calling constructors.
   String& constructor_name =
-      String::Handle(String::Concat(type_class_name, Symbols::DotHandle()));
+      String::Handle(String::Concat(type_class_name, Symbols::Dot()));
   if (named_constructor != NULL) {
     constructor_name = String::Concat(constructor_name, *named_constructor);
   }
@@ -8965,19 +8961,21 @@
           (named_constructor ? constructor_name : type_class_name);
       // Replace the type with a malformed type and compile a throw or report a
       // compile-time error if the constructor is const.
-      type = ClassFinalizer::NewFinalizedMalformedType(
-          Error::Handle(),  // No previous error.
-          current_class(),
-          call_pos,
-          ClassFinalizer::kTryResolve,  // No compile-time error.
-          "class '%s' has no constructor or factory named '%s'",
-          String::Handle(type_class.Name()).ToCString(),
-          external_constructor_name.ToCString());
       if (is_const) {
+        type = ClassFinalizer::NewFinalizedMalformedType(
+            Error::Handle(),  // No previous error.
+            current_class(),
+            call_pos,
+            ClassFinalizer::kTryResolve,  // No compile-time error.
+            "class '%s' has no constructor or factory named '%s'",
+            String::Handle(type_class.Name()).ToCString(),
+            external_constructor_name.ToCString());
         const Error& error = Error::Handle(type.malformed_error());
         ErrorMsg(error);
       }
-      return ThrowNoSuchMethodError(call_pos, external_constructor_name);
+      return ThrowNoSuchMethodError(call_pos,
+                                    type_class,
+                                    external_constructor_name);
     } else if (constructor.IsRedirectingFactory()) {
       Type& redirect_type = Type::Handle(constructor.RedirectionType());
       if (!redirect_type.IsMalformed() && !redirect_type.IsInstantiated()) {
@@ -9017,10 +9015,9 @@
         TokenPos(), Integer::ZoneHandle(Integer::New(type_pos))));
     arguments->Add(new LiteralNode(
         TokenPos(), String::ZoneHandle(type_class_name.raw())));
-    const String& cls_name =
-        String::Handle(Symbols::AbstractClassInstantiationError());
-    const String& func_name = String::Handle(Symbols::ThrowNew());
-    return MakeStaticCall(cls_name, func_name, arguments);
+    return MakeStaticCall(Symbols::AbstractClassInstantiationError(),
+                          Symbols::ThrowNew(),
+                          arguments);
   }
   String& error_message = String::Handle();
   if (!constructor.AreValidArguments(arguments_length,
@@ -9036,7 +9033,9 @@
                String::Handle(type_class.Name()).ToCString(),
                error_message.ToCString());
     }
-    return ThrowNoSuchMethodError(call_pos, external_constructor_name);
+    return ThrowNoSuchMethodError(call_pos,
+                                  type_class,
+                                  external_constructor_name);
   }
 
   // Return a throw in case of a malformed type or report a compile-time error
@@ -9099,20 +9098,20 @@
         new_pos, type_arguments, constructor, arguments);
   }
   if (!type_bound.IsNull()) {
-    const String& dst_name = String::ZoneHandle(Symbols::FactoryResult());
-    new_object = new AssignableNode(new_pos, new_object, type_bound, dst_name);
+    new_object = new AssignableNode(new_pos,
+                                    new_object,
+                                    type_bound,
+                                    Symbols::FactoryResult());
   }
   return new_object;
 }
 
 
 String& Parser::Interpolate(ArrayNode* values) {
-  const String& class_name = String::Handle(Symbols::StringBase());
-  const Class& cls = Class::Handle(LookupCoreClass(class_name));
+  const Class& cls = Class::Handle(LookupCoreClass(Symbols::StringBase()));
   ASSERT(!cls.IsNull());
-  const String& func_name = String::Handle(Symbols::Interpolate());
   const Function& func =
-      Function::Handle(cls.LookupStaticFunction(func_name));
+      Function::Handle(cls.LookupStaticFunction(Symbols::Interpolate()));
   ASSERT(!func.IsNull());
 
   // Build the array of literal values to interpolate.
@@ -9123,15 +9122,12 @@
   }
 
   // Build argument array to pass to the interpolation function.
-  GrowableArray<const Object*> interpolate_arg;
-  interpolate_arg.Add(&value_arr);
-  const Array& kNoArgumentNames = Array::Handle();
+  const Array& interpolate_arg = Array::Handle(Array::New(1));
+  interpolate_arg.SetAt(0, value_arr);
 
   // Call interpolation function.
   String& concatenated = String::ZoneHandle();
-  concatenated ^= DartEntry::InvokeStatic(func,
-                                          interpolate_arg,
-                                          kNoArgumentNames);
+  concatenated ^= DartEntry::InvokeStatic(func, interpolate_arg);
   if (concatenated.IsUnhandledException()) {
     ErrorMsg("Exception thrown in Parser::Interpolate");
   }
@@ -9206,9 +9202,9 @@
     ArgumentListNode* interpolate_arg =
         new ArgumentListNode(values->token_pos());
     interpolate_arg->Add(values);
-    const String& cls_name = String::Handle(Symbols::StringBase());
-    const String& func_name = String::Handle(Symbols::Interpolate());
-    primary = MakeStaticCall(cls_name, func_name, interpolate_arg);
+    primary = MakeStaticCall(Symbols::StringBase(),
+                             Symbols::Interpolate(),
+                             interpolate_arg);
   }
   return primary;
 }
@@ -9228,11 +9224,11 @@
   if (param_index < owner_function.num_fixed_parameters()) {
     // The formal parameter is not optional, therefore the corresponding
     // argument is always passed and defined.
-    return new LiteralNode(test_pos, Bool::ZoneHandle(Bool::True()));
+    return new LiteralNode(test_pos, Bool::True());
   }
   char name[64];
   OS::SNPrint(name, 64, "%s_%"Pd"",
-              Symbols::Name(Symbols::kSavedArgDescVarPrefix),
+              Symbols::Name(Symbols::kSavedArgDescVarPrefixId),
               owner_function.token_pos());
   const String& saved_args_desc_name = String::ZoneHandle(Symbols::New(name));
   LocalVariable* saved_args_desc_var = LookupLocalScope(saved_args_desc_name);
@@ -9311,7 +9307,7 @@
     }
     ASSERT(primary != NULL);
   } else if (CurrentToken() == Token::kTHIS) {
-    LocalVariable* local = LookupLocalScope(Symbols::ThisHandle());
+    LocalVariable* local = LookupLocalScope(Symbols::This());
     if (local == NULL) {
       ErrorMsg("receiver 'this' is not in scope");
     }
@@ -9322,10 +9318,10 @@
     primary = new LiteralNode(TokenPos(), literal);
     ConsumeToken();
   } else if (CurrentToken() == Token::kTRUE) {
-    primary = new LiteralNode(TokenPos(), Bool::ZoneHandle(Bool::True()));
+    primary = new LiteralNode(TokenPos(), Bool::True());
     ConsumeToken();
   } else if (CurrentToken() == Token::kFALSE) {
-    primary = new LiteralNode(TokenPos(), Bool::ZoneHandle(Bool::False()));
+    primary = new LiteralNode(TokenPos(), Bool::False());
     ConsumeToken();
   } else if (CurrentToken() == Token::kNULL) {
     primary = new LiteralNode(TokenPos(), Instance::ZoneHandle());
@@ -9383,8 +9379,7 @@
         (CurrentToken() == Token::kNE)) {
       primary = ParseSuperOperator();
     } else {
-      primary = new PrimaryNode(TokenPos(),
-                                String::ZoneHandle(Symbols::Super()));
+      primary = new PrimaryNode(TokenPos(), Symbols::Super());
     }
   } else if (CurrentToken() == Token::kCONDITIONAL) {
     primary = ParseArgumentDefinitionTest();
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 5af3352..1b117b4 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -351,7 +351,7 @@
                          LocalVariable* receiver,
                          GrowableArray<Field*>* initialized_fields);
   String& ParseNativeDeclaration();
-  RawArray* ParseInterfaceList();
+  RawArray* ParseInterfaceList(const Type& super_type);
   void AddInterfaceIfUnique(intptr_t interfaces_pos,
                             const GrowableObjectArray& interface_list,
                             const AbstractType& interface);
@@ -368,6 +368,7 @@
       const ArgumentListNode& function_args);
   RawFunction* GetSuperFunction(intptr_t token_pos,
                                 const String& name,
+                                ArgumentListNode* arguments,
                                 bool resolve_getter,
                                 bool* is_no_such_method);
   AstNode* ParseSuperCall(const String& function_name);
@@ -572,7 +573,9 @@
   String& Interpolate(ArrayNode* values);
   AstNode* MakeAssertCall(intptr_t begin, intptr_t end);
   AstNode* ThrowTypeError(intptr_t type_pos, const AbstractType& type);
-  AstNode* ThrowNoSuchMethodError(intptr_t call_pos, const String& name);
+  AstNode* ThrowNoSuchMethodError(intptr_t call_pos,
+                                  const Class& cls,
+                                  const String& function_name);
 
   void CheckOperatorArity(const MemberDesc& member);
 
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 06362bb..534c38c 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -13,6 +13,16 @@
 
 namespace dart {
 
+bool RawObject::IsVMHeapObject() const {
+  // TODO(asiva): Need a better way to represent VM heap objects, for
+  // now we use the premarked property for identifying objects in the
+  // VM heap.
+  ASSERT(IsHeapObject());
+  ASSERT(!Isolate::Current()->heap()->gc_in_progress());
+  return IsMarked();
+}
+
+
 void RawObject::Validate(Isolate* isolate) const {
   if (Object::null_class_ == reinterpret_cast<RawClass*>(kHeapObjectTag)) {
     // Validation relies on properly initialized class classes. Skip if the
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index bf5164e..2af50ea 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -260,6 +260,7 @@
     uword addr = reinterpret_cast<uword>(this);
     return (addr & kNewObjectAlignmentOffset) == kOldObjectAlignmentOffset;
   }
+  bool IsVMHeapObject() const;
 
   // Support for GC marking bit.
   bool IsMarked() const {
@@ -390,6 +391,10 @@
   friend class Heap;
   friend class HeapProfiler;
   friend class HeapProfilerRootVisitor;
+  friend class HeapTrace;
+  friend class HeapTraceDebugObjectVisitor;
+  friend class HeapTraceHandleVisitor;
+  friend class HeapTraceVisitor;
   friend class MarkingVisitor;
   friend class Object;
   friend class RawInstructions;
@@ -443,6 +448,7 @@
   intptr_t token_pos_;
   uint8_t state_bits_;  // state, is_const, is_implemented.
 
+  friend class HeapTrace;
   friend class Instance;
   friend class Object;
   friend class RawInstance;
@@ -559,6 +565,8 @@
   int16_t num_optional_parameters_;  // > 0: positional; < 0: named.
   uint16_t deoptimization_counter_;
   uint16_t kind_tag_;
+  uint16_t optimized_instruction_count_;
+  uint16_t optimized_call_site_count_;
 };
 
 
@@ -1135,6 +1143,8 @@
   RawSmi* length_;
   RawSmi* hash_;
   RawObject** to() { return reinterpret_cast<RawObject**>(&ptr()->hash_); }
+
+  friend class HeapTrace;
 };
 
 
@@ -1144,8 +1154,9 @@
   // Variable length data follows here.
   uint8_t data_[0];
 
-  friend class SnapshotReader;
   friend class ApiMessageReader;
+  friend class HeapTrace;
+  friend class SnapshotReader;
 };
 
 
@@ -1155,6 +1166,7 @@
   // Variable length data follows here.
   uint16_t data_[0];
 
+  friend class HeapTrace;
   friend class SnapshotReader;
 };
 
@@ -1234,6 +1246,7 @@
 class RawImmutableArray : public RawArray {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ImmutableArray);
 
+  friend class HeapTrace;
   friend class SnapshotReader;
 };
 
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index fd891d4..326fe8d 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -593,6 +593,8 @@
   func.set_num_optional_parameters(reader->ReadIntptrValue());
   func.set_deoptimization_counter(reader->ReadIntptrValue());
   func.set_kind_tag(reader->Read<uint16_t>());
+  func.set_optimized_instruction_count(reader->Read<uint16_t>());
+  func.set_optimized_call_site_count(reader->Read<uint16_t>());
 
   // Set all the object fields.
   // TODO(5411462): Need to assert No GC can happen here, even though
@@ -628,6 +630,8 @@
   writer->WriteIntptrValue(ptr()->num_optional_parameters_);
   writer->WriteIntptrValue(ptr()->deoptimization_counter_);
   writer->Write<uint16_t>(ptr()->kind_tag_);
+  writer->Write<uint16_t>(ptr()->optimized_instruction_count_);
+  writer->Write<uint16_t>(ptr()->optimized_call_site_count_);
 
   // Write out all the object pointer fields.
   SnapshotWriterVisitor visitor(writer);
diff --git a/runtime/vm/resolver_test.cc b/runtime/vm/resolver_test.cc
index ee28480..6e97d71 100644
--- a/runtime/vm/resolver_test.cc
+++ b/runtime/vm/resolver_test.cc
@@ -99,36 +99,33 @@
   // Now try to resolve and invoke the static function in this class.
   {
     const int kNumArguments = 2;
-    const Array& kNoArgumentNames = Array::Handle();
     const Function& function = Function::Handle(
         Resolver::ResolveStatic(library,
                                 class_name,
                                 static_function_name,
                                 kNumArguments,
-                                kNoArgumentNames,
+                                Object::empty_array(),
                                 kResolveType));
     EXPECT(!function.IsNull());
-    GrowableArray<const Object*> arguments(2);
+    const Array& args = Array::Handle(Array::New(kNumArguments));
     const String& arg0 = String::Handle(String::New("junk"));
-    arguments.Add(&arg0);
+    args.SetAt(0, arg0);
     const Smi& arg1 = Smi::Handle(Smi::New(kTestValue));
-    arguments.Add(&arg1);
+    args.SetAt(1, arg1);
     const Smi& retval = Smi::Handle(
-        reinterpret_cast<RawSmi*>(
-            DartEntry::InvokeStatic(function, arguments, kNoArgumentNames)));
+        reinterpret_cast<RawSmi*>(DartEntry::InvokeStatic(function, args)));
     EXPECT_EQ(kTestValue, retval.Value());
   }
 
   // Now try to resolve a static function with invalid argument count.
   {
     const int kNumArguments = 1;
-    const Array& kNoArgumentNames = Array::Handle();
     const Function& bad_function = Function::Handle(
         Resolver::ResolveStatic(library,
                                 class_name,
                                 static_function_name,
                                 kNumArguments,
-                                kNoArgumentNames,
+                                Object::empty_array(),
                                 kResolveType));
     EXPECT(bad_function.IsNull());
   }
@@ -139,13 +136,12 @@
         String::Handle(String::New("statCall"));
     const String& super_class_name = String::Handle(String::New("Base"));
     const int kNumArguments = 0;
-    const Array& kNoArgumentNames = Array::Handle();
     const Function& super_function = Function::Handle(
         Resolver::ResolveStatic(library,
                                 super_class_name,
                                 super_static_function_name,
                                 kNumArguments,
-                                kNoArgumentNames,
+                                Object::empty_array(),
                                 kResolveType));
     EXPECT(!super_function.IsNull());
   }
@@ -185,17 +181,14 @@
                                  kNumPositionalArguments,
                                  kNumNamedArguments));
     EXPECT(!function.IsNull());
-    GrowableArray<const Object*> arguments;
+    const Array& args = Array::Handle(Array::New(kNumPositionalArguments));
+    args.SetAt(0, receiver);
     const String& arg0 = String::Handle(String::New("junk"));
-    arguments.Add(&arg0);
+    args.SetAt(1, arg0);
     const Smi& arg1 = Smi::Handle(Smi::New(kTestValue));
-    arguments.Add(&arg1);
-    const Array& kNoArgumentNames = Array::Handle();
+    args.SetAt(2, arg1);
     const Smi& retval = Smi::Handle(
-        reinterpret_cast<RawSmi*>(DartEntry::InvokeDynamic(receiver,
-                                                           function,
-                                                           arguments,
-                                                           kNoArgumentNames)));
+        reinterpret_cast<RawSmi*>(DartEntry::InvokeDynamic(function, args)));
     EXPECT_EQ(kTestValue, retval.Value());
   }
 
diff --git a/runtime/vm/scanner.cc b/runtime/vm/scanner.cc
index f814b43..716dae7 100644
--- a/runtime/vm/scanner.cc
+++ b/runtime/vm/scanner.cc
@@ -426,19 +426,16 @@
     SkipLine();
     return;
   }
-  const String& kLibrary = String::Handle(Symbols::Library());
-  const String& kImport = String::Handle(Symbols::Import());
-  const String& kSource = String::Handle(Symbols::Source());
   const String& ident = String::Handle(ConsumeIdentChars(false));
-  if (ident.Equals(kLibrary)) {
+  if (ident.Equals(Symbols::Library())) {
     current_token_.kind = Token::kLEGACY_LIBRARY;
     return;
   }
-  if (ident.Equals(kImport)) {
+  if (ident.Equals(Symbols::Import())) {
     current_token_.kind = Token::kLEGACY_IMPORT;
     return;
   }
-  if (ident.Equals(kSource)) {
+  if (ident.Equals(Symbols::Source())) {
     current_token_.kind = Token::kLEGACY_SOURCE;
     return;
   }
diff --git a/runtime/vm/scavenger.cc b/runtime/vm/scavenger.cc
index 44a5c7b..f627345 100644
--- a/runtime/vm/scavenger.cc
+++ b/runtime/vm/scavenger.cc
@@ -74,7 +74,6 @@
         vm_heap_(Dart::vm_isolate()->heap()),
         delayed_weak_stack_(),
         growth_policy_(PageSpace::kControlGrowth),
-        bytes_promoted_(0),
         visiting_old_pointers_(false),
         in_scavenge_pointer_(false) {}
 
@@ -109,8 +108,6 @@
     }
   }
 
-  intptr_t bytes_promoted() { return bytes_promoted_; }
-
  private:
   void UpdateStoreBuffer(RawObject** p, RawObject* obj) {
     uword ptr = reinterpret_cast<uword>(p);
@@ -172,6 +169,9 @@
         // Not a survivor of a previous scavenge. Just copy the object into the
         // to space.
         new_addr = scavenger_->TryAllocate(size);
+        if (HeapTrace::is_enabled()) {
+          heap_->trace()->TraceCopy(raw_addr, new_addr);
+        }
       } else {
         // TODO(iposva): Experiment with less aggressive promotion. For example
         // a coin toss determines if an object is promoted or whether it should
@@ -184,7 +184,9 @@
           // If promotion succeeded then we need to remember it so that it can
           // be traversed later.
           scavenger_->PushToPromotedStack(new_addr);
-          bytes_promoted_ += size;
+          if (HeapTrace::is_enabled()) {
+            heap_->trace()->TracePromotion(raw_addr, new_addr);
+          }
         } else if (!scavenger_->had_promotion_failure_) {
           // Signal a promotion failure and set the growth policy for
           // this, and all subsequent promotion allocations, to force
@@ -194,16 +196,24 @@
           new_addr = heap_->TryAllocate(size, Heap::kOld, growth_policy_);
           if (new_addr != 0) {
             scavenger_->PushToPromotedStack(new_addr);
-            bytes_promoted_ += size;
+            if (HeapTrace::is_enabled()) {
+              heap_->trace()->TracePromotion(raw_addr, new_addr);
+            }
           } else {
             // Promotion did not succeed. Copy into the to space
             // instead.
             new_addr = scavenger_->TryAllocate(size);
+            if (HeapTrace::is_enabled()) {
+              heap_->trace()->TraceCopy(raw_addr, new_addr);
+            }
           }
         } else {
           ASSERT(growth_policy_ == PageSpace::kForceGrowth);
           // Promotion did not succeed. Copy into the to space instead.
           new_addr = scavenger_->TryAllocate(size);
+          if (HeapTrace::is_enabled()) {
+            heap_->trace()->TraceCopy(raw_addr, new_addr);
+          }
         }
       }
       // During a scavenge we always succeed to at least copy all of the
@@ -232,7 +242,6 @@
   DelaySet delay_set_;
   GrowableArray<RawObject*> delayed_weak_stack_;
   PageSpace::GrowthPolicy growth_policy_;
-  intptr_t bytes_promoted_;
 
   bool visiting_old_pointers_;
   bool in_scavenge_pointer_;
@@ -288,7 +297,6 @@
 Scavenger::Scavenger(Heap* heap, intptr_t max_capacity, uword object_alignment)
     : heap_(heap),
       object_alignment_(object_alignment),
-      count_(0),
       scavenging_(false) {
   // Verify assumptions about the first word in objects which the scavenger is
   // going to use for forwarding pointers.
@@ -402,10 +410,8 @@
     delete pending;
     pending = next;
   }
-  if (FLAG_verbose_gc) {
-    OS::PrintErr("StoreBuffer: %"Pd", %"Pd" (entries, dups)\n",
-                 entries, duplicates);
-  }
+  heap_->RecordData(kStoreBufferEntries, entries);
+  heap_->RecordData(kStoreBufferDuplicates, duplicates);
   StoreBufferBlock* block = isolate->store_buffer_block();
   entries = block->Count();
   duplicates = 0;
@@ -421,20 +427,23 @@
     }
   }
   block->Reset();
-  if (FLAG_verbose_gc) {
-    OS::PrintErr("StoreBufferBlock: %"Pd", %"Pd" (entries, dups)\n",
-                 entries, duplicates);
-  }
+  heap_->RecordData(kStoreBufferBlockEntries, entries);
+  heap_->RecordData(kStoreBufferBlockDuplicates, duplicates);
 }
 
 
 void Scavenger::IterateRoots(Isolate* isolate,
                              ScavengerVisitor* visitor,
                              bool visit_prologue_weak_persistent_handles) {
-  IterateStoreBuffers(isolate, visitor);
+  int64_t start = OS::GetCurrentTimeMicros();
   isolate->VisitObjectPointers(visitor,
                                visit_prologue_weak_persistent_handles,
                                StackFrameIterator::kDontValidateFrames);
+  int64_t middle = OS::GetCurrentTimeMicros();
+  IterateStoreBuffers(isolate, visitor);
+  int64_t end = OS::GetCurrentTimeMicros();
+  heap_->RecordTime(kVisitIsolateRoots, middle - start);
+  heap_->RecordTime(kIterateStoreBuffers, end - middle);
 }
 
 
@@ -611,14 +620,14 @@
 }
 
 
-void Scavenger::Scavenge(const char* gc_reason) {
+void Scavenger::Scavenge() {
   // TODO(cshapiro): Add a decision procedure for determining when the
   // the API callbacks should be invoked.
-  Scavenge(false, gc_reason);
+  Scavenge(false);
 }
 
 
-void Scavenger::Scavenge(bool invoke_api_callbacks, const char* gc_reason) {
+void Scavenger::Scavenge(bool invoke_api_callbacks) {
   // Scavenging is not reentrant. Make sure that is the case.
   ASSERT(!scavenging_);
   scavenging_ = true;
@@ -632,38 +641,25 @@
     OS::PrintErr(" done.\n");
   }
 
-  if (FLAG_verbose_gc) {
-    OS::PrintErr("Start scavenge for %s collection\n", gc_reason);
-  }
-  Timer timer(FLAG_verbose_gc, "Scavenge");
-  timer.Start();
-
-  intptr_t in_use_before = in_use();
+  uword prev_first_obj_start = FirstObjectStart();
+  uword prev_top_addr = *(TopAddress());
 
   // Setup the visitor and run a scavenge.
   ScavengerVisitor visitor(isolate, this);
   Prologue(isolate, invoke_api_callbacks);
   IterateRoots(isolate, &visitor, !invoke_api_callbacks);
+  int64_t start = OS::GetCurrentTimeMicros();
   ProcessToSpace(&visitor);
+  int64_t middle = OS::GetCurrentTimeMicros();
   IterateWeakReferences(isolate, &visitor);
   ScavengerWeakVisitor weak_visitor(this);
   IterateWeakRoots(isolate, &weak_visitor, invoke_api_callbacks);
   visitor.Finalize();
   ProcessPeerReferents();
+  int64_t end = OS::GetCurrentTimeMicros();
+  heap_->RecordTime(kProcessToSpace, middle - start);
+  heap_->RecordTime(kIterateWeaks, end - middle);
   Epilogue(isolate, invoke_api_callbacks);
-  timer.Stop();
-
-  if (FLAG_verbose_gc) {
-    const intptr_t KB2 = KB / 2;
-    OS::PrintErr("Scavenge[%d]: %"Pd64"us (%"Pd"K -> %"Pd"K, %"Pd"K)\n"
-                 "Promoted %"Pd"K\n",
-                 count_,
-                 timer.TotalElapsedTime(),
-                 (in_use_before + KB2) / KB,
-                 (in_use() + KB2) / KB,
-                 (capacity() + KB2) / KB,
-                 (visitor.bytes_promoted() + KB2) / KB);
-  }
 
   if (FLAG_verify_after_gc) {
     OS::PrintErr("Verifying after Scavenge...");
@@ -671,7 +667,10 @@
     OS::PrintErr(" done.\n");
   }
 
-  count_++;
+  if (HeapTrace::is_enabled()) {
+    heap_->trace()->TraceDeathRange(prev_first_obj_start, prev_top_addr);
+  }
+
   // Done scavenging. Reset the marker.
   ASSERT(scavenging_);
   scavenging_ = false;
diff --git a/runtime/vm/scavenger.h b/runtime/vm/scavenger.h
index feff90d..81f4c3b 100644
--- a/runtime/vm/scavenger.h
+++ b/runtime/vm/scavenger.h
@@ -62,8 +62,8 @@
   }
 
   // Collect the garbage in this scavenger.
-  void Scavenge(const char* gc_reason);
-  void Scavenge(bool invoke_api_callbacks, const char* gc_reason);
+  void Scavenge();
+  void Scavenge(bool invoke_api_callbacks);
 
   // Accessors to generate code for inlined allocation.
   uword* TopAddress() { return &top_; }
@@ -96,6 +96,20 @@
   int64_t PeerCount() const;
 
  private:
+  // Ids for time and data records in Heap::GCStats.
+  enum {
+    // Time
+    kVisitIsolateRoots = 0,
+    kIterateStoreBuffers = 1,
+    kProcessToSpace = 2,
+    kIterateWeaks = 3,
+    // Data
+    kStoreBufferEntries = 0,
+    kStoreBufferDuplicates = 1,
+    kStoreBufferBlockEntries = 2,
+    kStoreBufferBlockDuplicates = 3
+  };
+
   uword FirstObjectStart() const { return to_->start() | object_alignment_; }
   void Prologue(Isolate* isolate, bool invoke_api_callbacks);
   void IterateStoreBuffers(Isolate* isolate, ScavengerVisitor* visitor);
@@ -159,8 +173,6 @@
   // All object are aligned to this value.
   uword object_alignment_;
 
-  // Scavenge cycle count.
-  int count_;
   // Keep track whether a scavenge is currently running.
   bool scavenging_;
   // Keep track whether the scavenge had a promotion failure.
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index ccc6a3b..42614f0 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -259,7 +259,7 @@
         desc.info.index = var->index();
         vars->Add(desc);
       } else if (var->name().Equals(
-            Symbols::Name(Symbols::kSavedEntryContextVar))) {
+            Symbols::Name(Symbols::kSavedEntryContextVarId))) {
         // This is the local variable in which the function saves the
         // caller's chain of closure contexts (caller's CTX register).
         VarDesc desc;
@@ -526,7 +526,7 @@
 
   // Create a descriptor for 'this' variable.
   context_scope.SetTokenIndexAt(0, func.token_pos());
-  context_scope.SetNameAt(0, Symbols::ThisHandle());
+  context_scope.SetNameAt(0, Symbols::This());
   context_scope.SetIsFinalAt(0, true);
   context_scope.SetIsConstAt(0, false);
   const AbstractType& type = AbstractType::Handle(func.ParameterTypeAt(0));
diff --git a/runtime/vm/scopes.h b/runtime/vm/scopes.h
index 65f0132..4b0fd2a 100644
--- a/runtime/vm/scopes.h
+++ b/runtime/vm/scopes.h
@@ -77,7 +77,7 @@
   }
 
   void SetConstValue(const Instance& value) {
-    ASSERT(value.IsZoneHandle());
+    ASSERT(value.IsZoneHandle() || value.IsReadOnlyHandle());
     const_value_ = &value;
   }
 
@@ -148,7 +148,7 @@
       return new SourceLabel(token_pos, *name, kind);
     } else {
       return new SourceLabel(token_pos,
-                             String::ZoneHandle(Symbols::DefaultLabel()),
+                             Symbols::DefaultLabel(),
                              kind);
     }
   }
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index fad97c7..d6a50ba 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -656,10 +656,16 @@
     return Object::null();
   }
   if (object_id == kSentinelObject) {
-    return Object::sentinel();
+    return Object::sentinel().raw();
   }
   if (object_id == kEmptyArrayObject) {
-    return Object::empty_array();
+    return Object::empty_array().raw();
+  }
+  if (object_id == kTrueValue) {
+    return Bool::True().raw();
+  }
+  if (object_id == kFalseValue) {
+    return Bool::False().raw();
   }
   intptr_t class_id = ClassIdFromObjectId(object_id);
   if (IsSingletonClassId(class_id)) {
@@ -674,12 +680,6 @@
 
 
 RawObject* SnapshotReader::ReadIndexedObject(intptr_t object_id) {
-  if (object_id == kTrueValue) {
-    return object_store()->true_value();
-  }
-  if (object_id == kFalseValue) {
-    return object_store()->false_value();
-  }
   intptr_t class_id = ClassIdFromObjectId(object_id);
   if (IsObjectStoreClassId(class_id)) {
     return isolate()->class_table()->At(class_id);  // get singleton class.
@@ -801,17 +801,29 @@
   }
 
   // Check if it is a singleton sentinel object.
-  if (rawobj == Object::sentinel()) {
+  if (rawobj == Object::sentinel().raw()) {
     WriteVMIsolateObject(kSentinelObject);
     return;
   }
 
   // Check if it is a singleton empty array object.
-  if (rawobj == Object::empty_array()) {
+  if (rawobj == Object::empty_array().raw()) {
     WriteVMIsolateObject(kEmptyArrayObject);
     return;
   }
 
+  // Check if it is a singleton boolean true object.
+  if (rawobj == Bool::True().raw()) {
+    WriteVMIsolateObject(kTrueValue);
+    return;
+  }
+
+  // Check if it is a singleton boolean false object.
+  if (rawobj == Bool::False().raw()) {
+    WriteVMIsolateObject(kFalseValue);
+    return;
+  }
+
   // Check if it is a singleton class object which is shared by
   // all isolates.
   intptr_t id = rawobj->GetClassId();
@@ -1034,23 +1046,11 @@
   // Now check if it is an object from the VM isolate (NOTE: premarked objects
   // are considered to be objects in the VM isolate). These objects are shared
   // by all isolates.
-  if (rawobj->IsMarked()) {
+  if (rawobj->IsVMHeapObject()) {
     HandleVMIsolateObject(rawobj);
     return true;
   }
 
-  // Check if it is a singleton boolean true value.
-  if (rawobj == object_store()->true_value()) {
-    WriteIndexedObject(kTrueValue);
-    return true;
-  }
-
-  // Check if it is a singleton boolean false value.
-  if (rawobj == object_store()->false_value()) {
-    WriteIndexedObject(kFalseValue);
-    return true;
-  }
-
   // Check if the object is a Mint and could potentially be a Smi
   // on other architectures (64 bit), if so write it out as int64_t value.
   if (rawobj->GetClassId() == kMintCid) {
@@ -1251,8 +1251,8 @@
   Isolate::Current()->object_store()->clear_sticky_error();
   UnmarkAll();
   const String& msg_obj = String::Handle(String::New(msg));
-  GrowableArray<const Object*> args(1);
-  args.Add(&msg_obj);
+  const Array& args = Array::Handle(Array::New(1));
+  args.SetAt(0, msg_obj);
   Exceptions::ThrowByType(type, args);
   UNREACHABLE();
 }
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index bdadf78..594ab31 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -39,11 +39,7 @@
   }
   if (expected.IsBool()) {
     if (actual.IsBool()) {
-      Bool& bl1 = Bool::Handle();
-      Bool& bl2 = Bool::Handle();
-      bl1 ^= expected.raw();
-      bl2 ^= actual.raw();
-      return bl1.value() == bl2.value();
+      return expected.raw() == actual.raw();
     }
     return false;
   }
@@ -312,7 +308,7 @@
   // Write snapshot with true object.
   uint8_t* buffer;
   MessageWriter writer(&buffer, &zone_allocator);
-  const Bool& bl = Bool::Handle(Bool::True());
+  const Bool& bl = Bool::True();
   writer.WriteMessage(bl);
   intptr_t buffer_len = writer.BytesWritten();
 
@@ -341,7 +337,7 @@
   // Write snapshot with false object.
   uint8_t* buffer;
   MessageWriter writer(&buffer, &zone_allocator);
-  const Bool& bl = Bool::Handle(Bool::False());
+  const Bool& bl = Bool::False();
   writer.WriteMessage(bl);
   intptr_t buffer_len = writer.BytesWritten();
 
@@ -1260,12 +1256,12 @@
 }
 
 
-static void CheckString(Dart_Handle string, const char* expected) {
+static void CheckString(Dart_Handle dart_string, const char* expected) {
   StackZone zone(Isolate::Current());
   uint8_t* buffer;
   MessageWriter writer(&buffer, &zone_allocator);
   String& str = String::Handle();
-  str ^= Api::UnwrapHandle(string);
+  str ^= Api::UnwrapHandle(dart_string);
   writer.WriteMessage(str);
   intptr_t buffer_len = writer.BytesWritten();
 
@@ -1280,12 +1276,12 @@
 }
 
 
-static void CheckStringInvalid(Dart_Handle string) {
+static void CheckStringInvalid(Dart_Handle dart_string) {
   StackZone zone(Isolate::Current());
   uint8_t* buffer;
   MessageWriter writer(&buffer, &zone_allocator);
   String& str = String::Handle();
-  str ^= Api::UnwrapHandle(string);
+  str ^= Api::UnwrapHandle(dart_string);
   writer.WriteMessage(str);
   intptr_t buffer_len = writer.BytesWritten();
 
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index 2fc4302..983aa84 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -178,6 +178,24 @@
 }
 
 
+intptr_t StackFrame::GetTokenPos() const {
+  const Code& code = Code::Handle(LookupDartCode());
+  if (code.IsNull()) {
+    return -1;  // Stub frames do not have token_pos.
+  }
+  const PcDescriptors& descriptors =
+      PcDescriptors::Handle(code.pc_descriptors());
+  ASSERT(!descriptors.IsNull());
+  for (int i = 0; i < descriptors.Length(); i++) {
+    if (static_cast<uword>(descriptors.PC(i)) == pc()) {
+      return descriptors.TokenPos(i);
+    }
+  }
+  return -1;
+}
+
+
+
 bool StackFrame::IsValid() const {
   if (IsEntryFrame() || IsExitFrame() || IsStubFrame()) {
     return true;
diff --git a/runtime/vm/stack_frame.h b/runtime/vm/stack_frame.h
index 3a6ec42..7d1192e 100644
--- a/runtime/vm/stack_frame.h
+++ b/runtime/vm/stack_frame.h
@@ -57,6 +57,9 @@
   RawFunction* LookupDartFunction() const;
   RawCode* LookupDartCode() const;
   bool FindExceptionHandler(uword* handler_pc) const;
+  // Returns token_pos of the pc(), or -1 if none exists.
+  intptr_t GetTokenPos() const;
+
 
  protected:
   StackFrame() : fp_(0), sp_(0) { }
diff --git a/runtime/vm/store_buffer.h b/runtime/vm/store_buffer.h
index 04eada4..bc52958 100644
--- a/runtime/vm/store_buffer.h
+++ b/runtime/vm/store_buffer.h
@@ -66,7 +66,7 @@
  public:
   // Simple linked list element containing a HashSet of old->new pointers.
   class DedupSet {
-  public:
+   public:
     enum {
       kSetSize = 1024,
       kFillRatio = 75
@@ -81,7 +81,7 @@
     DedupSet* next() const { return next_; }
     HashSet* set() const { return set_; }
 
-  private:
+   private:
     DedupSet* next_;
     HashSet* set_;
 
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index 5b3ae64..499b1b1 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -226,15 +226,13 @@
 
 
 // Input parameters:
-//   EDI: argument count, may be zero.
+//   EDX: smi-tagged argument count, may be zero.
 // Uses EAX, EBX, ECX, EDX.
 static void PushArgumentsArray(Assembler* assembler, intptr_t arg_offset) {
   const Immediate raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
 
   // Allocate array to store arguments of caller.
-  __ movl(EDX, EDI);  // Arguments array length.
-  __ SmiTag(EDX);  // Convert to Smi.
   __ movl(ECX, raw_null);  // Null element type for raw Array.
   __ call(&StubCode::AllocateArrayLabel());
   __ SmiUntag(EDX);
@@ -264,151 +262,44 @@
 //       when trying to resolve the call.
 // Uses EDI.
 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) {
-  const Immediate raw_null =
-      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);
 
-  // Preserve values across call to resolving.
-  // Stack at this point:
-  // TOS + 0: PC marker => RawInstruction object.
-  // TOS + 1: Saved EBP of previous frame. <== EBP
-  // TOS + 2: Dart code return address
-  // TOS + 3: Last argument of caller.
-  // ....
-  __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
-  __ movl(EAX, Address(EBP, EAX, TIMES_2, kWordSize));  // Get receiver.
-  // EAX: receiver.
-  // ECX: ic-data.
-  // EDX: arguments descriptor array.
-  // The target function was not found.
-  // First check to see if this is a getter function and we are
-  // trying to create a closure of an instance function.
-  // Push values that need to be preserved across runtime call.
-  __ pushl(EAX);  // Preserve receiver.
-  __ pushl(ECX);  // Preserve ic-data.
-  __ pushl(EDX);  // Preserve arguments descriptor array.
+  const Immediate raw_null =
+      Immediate(reinterpret_cast<intptr_t>(Object::null()));
+  __ pushl(raw_null);  // Space for the return value.
 
-  __ pushl(raw_null);  // Setup space on stack for return value.
-  __ pushl(EAX);  // Push receiver.
-  __ pushl(ECX);  // Ic-data.
-  __ CallRuntime(kResolveImplicitClosureFunctionRuntimeEntry);
-  __ popl(EAX);
-  __ popl(EAX);
-  __ popl(EBX);  // Get return value into EBX, might be Closure object.
-
-  // Pop preserved values.
-  __ popl(EDX);  // Restore arguments descriptor array.
-  __ popl(ECX);  // Restore ic-data.
-  __ popl(EAX);  // Restore receiver.
-
-  __ cmpl(EBX, raw_null);
-  Label check_implicit_closure_through_getter;
-  __ j(EQUAL, &check_implicit_closure_through_getter, Assembler::kNearJump);
-
-  __ movl(EAX, EBX);  // Return value is the closure object.
-  // Remove the stub frame as we are about return.
-  __ LeaveFrame();
-  __ ret();
-
-  __ Bind(&check_implicit_closure_through_getter);
-  // EAX: receiver.
-  // ECX: ic-data.
-  // EDX: arguments descriptor array.
-  // This is not the case of an instance so invoke the getter of the
-  // same name and see if we get a closure back which we are then
-  // supposed to invoke.
-  // Push values that need to be preserved across runtime call.
-  __ pushl(EAX);  // Preserve receiver.
-  __ pushl(ECX);  // Preserve ic-data.
-  __ pushl(EDX);  // Preserve arguments descriptor array.
-
-  __ pushl(raw_null);  // Setup space on stack for return value.
-  __ pushl(EAX);  // Push receiver.
-  __ pushl(ECX);  // Ic-data.
-  __ CallRuntime(kResolveImplicitClosureThroughGetterRuntimeEntry);
-  __ popl(EAX);  // Pop argument.
-  __ popl(EAX);  // Pop argument.
-  __ popl(EBX);  // get return value into EBX, might be Closure object.
-
-  // Pop preserved values.
-  __ popl(EDX);  // Restore arguments descriptor array.
-  __ popl(ECX);  // Restore ic-data.
-  __ popl(EAX);  // Restore receiver.
-
-  __ cmpl(EBX, raw_null);
-  Label function_not_found;
-  __ j(EQUAL, &function_not_found, Assembler::kNearJump);
-
-  // EBX: Closure object.
-  // EDX: Arguments descriptor array.
-  __ pushl(raw_null);  // Setup space on stack for result from invoking Closure.
-  __ pushl(EBX);  // Closure object.
-  __ pushl(EDX);  // Arguments descriptor.
+  // Push the receiver as an argument.  Load the smi-tagged argument
+  // count into EDI to index the receiver in the stack.  There are
+  // three words (null, stub's pc marker, saved fp) above the return
+  // address.
   __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
-  __ SmiUntag(EDI);  // Arguments array length, including the original receiver.
-  PushArgumentsArray(assembler, (kWordSize * 6));
-  // Stack layout explaining "(kWordSize * 6)" offset.
-  // TOS + 0: Argument array.
-  // TOS + 1: Arguments descriptor array.
-  // TOS + 2: Closure object.
-  // TOS + 3: Place for result from closure function.
-  // TOS + 4: PC marker => RawInstruction object.
-  // TOS + 5: Saved EBP of previous frame. <== EBP
-  // TOS + 6: Dart code return address
-  // TOS + 7: Last argument of caller.
-  // ....
+  __ pushl(Address(ESP, EDI, TIMES_2, (3 * kWordSize)));
 
-  __ CallRuntime(kInvokeImplicitClosureFunctionRuntimeEntry);
-  // Remove arguments.
-  __ popl(EAX);
-  __ popl(EAX);
-  __ popl(EAX);
-  __ popl(EAX);  // Get result into EAX.
+  __ pushl(ECX);  // Pass IC data object.
+  __ pushl(EDX);  // Pass arguments descriptor array.
 
-  // Remove the stub frame as we are about to return.
-  __ LeaveFrame();
-  __ ret();
-
-  __ Bind(&function_not_found);
-  // The target function was not found, so invoke method
-  // "dynamic noSuchMethod(InvocationMirror invocation)".
-  //   EAX: receiver.
-  //   ECX: ic-data.
-  //   EDX: arguments descriptor array.
-
-  __ pushl(raw_null);  // Setup space on stack for result from noSuchMethod.
-  __ pushl(EAX);  // Receiver.
-  __ pushl(ECX);  // IC-data.
-  __ pushl(EDX);  // Arguments descriptor array.
-  __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
-  __ SmiUntag(EDI);  // Arguments array length, including the original receiver.
-  // See stack layout below explaining "wordSize * 7" offset.
-  PushArgumentsArray(assembler, (kWordSize * 7));
-
-  // Stack:
+  // Pass the call's arguments array.
+  __ movl(EDX, EDI);  // Smi-tagged arguments array length.
+  PushArgumentsArray(assembler, (7 * kWordSize));
+  // Stack layout explaining "(7 * kWordSize)" offset.
   // TOS + 0: Arguments array.
   // TOS + 1: Arguments descriptor array.
-  // TOS + 2: IC-data.
-  // TOS + 3: Receiver
-  // TOS + 4: Place for result from noSuchMethod.
-  // TOS + 5: PC marker => RawInstruction object.
-  // TOS + 6: Saved EBP of previous frame. <== EBP
+  // TOS + 2: IC data object.
+  // TOS + 3: Receiver.
+  // TOS + 4: Space for the result of the runtime call.
+  // TOS + 5: Stub's PC marker (0)
+  // TOS + 6: Saved FP
   // TOS + 7: Dart code return address
   // TOS + 8: Last argument of caller.
   // ....
 
-  __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry);
+  __ CallRuntime(kInstanceFunctionLookupRuntimeEntry);
   // Remove arguments.
   __ popl(EAX);
   __ popl(EAX);
   __ popl(EAX);
   __ popl(EAX);
   __ popl(EAX);  // Get result into EAX.
-
-  // Remove the stub frame as we are about to return.
   __ LeaveFrame();
   __ ret();
 }
@@ -536,7 +427,8 @@
   // Load the receiver into EAX.  The argument count in the arguments
   // descriptor in EDX is a smi.
   __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
-  // Two words (return addres, saved fp) in the stack above the last argument.
+  // Two words (saved fp, stub's pc marker) in the stack above the return
+  // address.
   __ movl(EAX, Address(ESP, EAX, TIMES_2, 2 * kWordSize));
   // Preserve IC data and arguments descriptor.
   __ pushl(ECX);
@@ -789,9 +681,8 @@
   __ pushl(raw_null);  // Setup space on stack for result from error reporting.
   __ pushl(EDI);  // Non-closure object.
   __ pushl(EDX);  // Arguments descriptor.
-  // Load num_args.
-  __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
-  __ SmiUntag(EDI);  // Arguments array length, including the non-closure.
+  // Load smi-tagged arguments array length, including the non-closure.
+  __ movl(EDX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
   // See stack layout below explaining "wordSize * 6" offset.
   PushArgumentsArray(assembler, (kWordSize * 6));
 
@@ -823,7 +714,7 @@
 //   ESP : points to return address.
 //   ESP + 4 : entrypoint of the dart function to call.
 //   ESP + 8 : arguments descriptor array.
-//   ESP + 12 : pointer to the argument array.
+//   ESP + 12 : arguments array.
 //   ESP + 16 : new context containing the current isolate pointer.
 // Uses EAX, EDX, ECX, EDI as temporary registers.
 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
@@ -883,10 +774,14 @@
   __ testl(EBX, EBX);  // check if there are arguments.
   __ j(ZERO, &done_push_arguments, Assembler::kNearJump);
   __ movl(EAX, Immediate(0));
-  __ movl(EDI, Address(EBP, kArgumentsOffset));  // start of arguments.
+
+  // Compute address of 'arguments array' data area into EDI.
+  __ movl(EDI, Address(EBP, kArgumentsOffset));
+  __ movl(EDI, Address(EDI, VMHandles::kOffsetOfRawPtrInHandle));
+  __ leal(EDI, FieldAddress(EDI, Array::data_offset()));
+
   __ Bind(&push_arguments);
   __ movl(ECX, Address(EDI, EAX, TIMES_4, 0));
-  __ movl(ECX, Address(ECX, VMHandles::kOffsetOfRawPtrInHandle));
   __ pushl(ECX);
   __ incl(EAX);
   __ cmpl(EAX, EBX);
@@ -1458,8 +1353,7 @@
   const Immediate raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
   __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
-  __ SmiUntag(EDI);
-  __ movl(EAX, Address(EBP, EDI, TIMES_4, kWordSize));  // Get receiver.
+  __ movl(EAX, Address(EBP, EDI, TIMES_2, kWordSize));  // Get receiver.
 
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
@@ -1469,7 +1363,8 @@
   __ pushl(EAX);  // Receiver.
   __ pushl(ECX);  // IC data array.
   __ pushl(EDX);  // Arguments descriptor array.
-  // EDI: Arguments array length, including the receiver.
+
+  __ movl(EDX, EDI);
   // See stack layout below explaining "wordSize * 10" offset.
   PushArgumentsArray(assembler, (kWordSize * 10));
 
@@ -2087,10 +1982,10 @@
   __ movl(EAX, Address(ESP, 1 * kWordSize));
   __ cmpl(EAX, Address(ESP, 2 * kWordSize));
   __ j(EQUAL, &true_label, Assembler::kNearJump);
-  __ LoadObject(EAX, Bool::ZoneHandle(Bool::False()));
+  __ LoadObject(EAX, Bool::False());
   __ ret();
   __ Bind(&true_label);
-  __ LoadObject(EAX, Bool::ZoneHandle(Bool::True()));
+  __ LoadObject(EAX, Bool::True());
   __ ret();
 
   __ Bind(&get_class_id_as_smi);
@@ -2114,7 +2009,7 @@
   AssemblerMacros::EnterStubFrame(assembler);
   __ pushl(EDI);  // arg 0
   __ pushl(EAX);  // arg 1
-  __ PushObject(Symbols::EqualOperatorHandle());  // Target's name.
+  __ PushObject(Symbols::EqualOperator());  // Target's name.
   __ pushl(ECX);  // ICData
   __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry);
   __ Drop(4);
diff --git a/runtime/vm/stub_code_ia32_test.cc b/runtime/vm/stub_code_ia32_test.cc
index 902164d..222fd0f 100644
--- a/runtime/vm/stub_code_ia32_test.cc
+++ b/runtime/vm/stub_code_ia32_test.cc
@@ -70,10 +70,8 @@
   const Code& code = Code::Handle(Code::FinalizeCode(
       *CreateFunction("Test_CallRuntimeStubCode"), &_assembler_));
   const Function& function = RegisterFakeFunction(kName, code);
-  GrowableArray<const Object*>  arguments;
-  const Array& kNoArgumentNames = Array::Handle();
   Smi& result = Smi::Handle();
-  result ^= DartEntry::InvokeStatic(function, arguments, kNoArgumentNames);
+  result ^= DartEntry::InvokeStatic(function, Object::empty_array());
   EXPECT_EQ((value1 - value2), result.Value());
 }
 
@@ -107,10 +105,8 @@
   const Code& code = Code::Handle(Code::FinalizeCode(
       *CreateFunction("Test_CallLeafRuntimeStubCode"), &_assembler_));
   const Function& function = RegisterFakeFunction(kName, code);
-  GrowableArray<const Object*>  arguments;
-  const Array& kNoArgumentNames = Array::Handle();
   Smi& result = Smi::Handle();
-  result ^= DartEntry::InvokeStatic(function, arguments, kNoArgumentNames);
+  result ^= DartEntry::InvokeStatic(function, Object::empty_array());
   EXPECT_EQ((value1 + value2), result.Value());
 }
 
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 24116c8..4bd353b 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -223,14 +223,12 @@
 
 
 // Input parameters:
-//   R13: argument count, may be zero.
+//   R10: smi-tagged argument count, may be zero.
 static void PushArgumentsArray(Assembler* assembler, intptr_t arg_offset) {
   const Immediate raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
 
   // Allocate array to store arguments of caller.
-  __ movq(R10, R13);  // Arguments array length.
-  __ SmiTag(R10);  // Convert to Smi.
   __ movq(RBX, raw_null);  // Null element type for raw Array.
   __ call(&StubCode::AllocateArrayLabel());
   __ SmiUntag(R10);
@@ -259,151 +257,44 @@
 //       called, the stub accesses the receiver from this location directly
 //       when trying to resolve the call.
 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) {
-  const Immediate raw_null =
-      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);
 
-  // Preserve values across call to resolving.
-  // Stack at this point:
-  // TOS + 0: PC marker => RawInstruction object.
-  // TOS + 1: Saved RBP of previous frame. <== RBP
-  // TOS + 2: Dart code return address
-  // TOS + 3: Last argument of caller.
-  // ....
-  __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
-  __ movq(RAX, Address(RBP, RAX, TIMES_4, kWordSize));  // Get receiver.
-  // RAX: receiver.
-  // RBX: ic-data.
-  // R10: arguments descriptor array.
-  // The target function was not found.
-  // First check to see if this is a getter function and we are
-  // trying to create a closure of an instance function.
-  // Push values that need to be preserved across runtime call.
-  __ pushq(RAX);  // Preserve receiver.
-  __ pushq(RBX);  // Preserve ic-data.
-  __ pushq(R10);  // Preserve arguments descriptor array.
+  const Immediate raw_null =
+      Immediate(reinterpret_cast<intptr_t>(Object::null()));
+  __ pushq(raw_null);  // Space for the return value.
 
-  __ pushq(raw_null);  // Setup space on stack for return value.
-  __ pushq(RAX);  // Push receiver.
-  __ pushq(RBX);  // Ic-data array.
-  __ CallRuntime(kResolveImplicitClosureFunctionRuntimeEntry);
-  __ popq(RAX);
-  __ popq(RAX);
-  __ popq(RCX);  // Get return value into RCX, might be Closure object.
-
-  // Pop preserved values.
-  __ popq(R10);  // Restore arguments descriptor array.
-  __ popq(RBX);  // Restore ic-data.
-  __ popq(RAX);  // Restore receiver.
-
-  __ cmpq(RCX, raw_null);
-  Label check_implicit_closure_through_getter;
-  __ j(EQUAL, &check_implicit_closure_through_getter, Assembler::kNearJump);
-
-  __ movq(RAX, RCX);  // Return value is the closure object.
-  // Remove the stub frame as we are about return.
-  __ LeaveFrame();
-  __ ret();
-
-  __ Bind(&check_implicit_closure_through_getter);
-  // RAX: receiver.
-  // RBX: ic-data.
-  // R10: arguments descriptor array.
-  // This is not the case of an instance so invoke the getter of the
-  // same name and see if we get a closure back which we are then
-  // supposed to invoke.
-  // Push values that need to be preserved across runtime call.
-  __ pushq(RAX);  // Preserve receiver.
-  __ pushq(RBX);  // Preserve ic-data.
-  __ pushq(R10);  // Preserve arguments descriptor array.
-
-  __ pushq(raw_null);  // Setup space on stack for return value.
-  __ pushq(RAX);  // Push receiver.
-  __ pushq(RBX);  // Ic-data array.
-  __ CallRuntime(kResolveImplicitClosureThroughGetterRuntimeEntry);
-  __ popq(RAX);  // Pop argument.
-  __ popq(RAX);  // Pop argument.
-  __ popq(RCX);  // get return value into RCX, might be Closure object.
-
-  // Pop preserved values.
-  __ popq(R10);  // Restore arguments descriptor array.
-  __ popq(RBX);  // Restore ic-data.
-  __ popq(RAX);  // Restore receiver.
-
-  __ cmpq(RCX, raw_null);
-  Label function_not_found;
-  __ j(EQUAL, &function_not_found);
-
-  // RCX: Closure object.
-  // R10: Arguments descriptor array.
-  __ pushq(raw_null);  // Setup space on stack for result from invoking Closure.
-  __ pushq(RCX);  // Closure object.
-  __ pushq(R10);  // Arguments descriptor.
+  // Push the receiver as an argument.  Load the smi-tagged argument
+  // count into R13 to index the receiver in the stack.  There are
+  // three words (null, stub's pc marker, saved fp) above the return
+  // address.
   __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
-  __ SmiUntag(R13);  // Arguments array length, including the original receiver.
-  PushArgumentsArray(assembler, (kWordSize * 6));
-  // Stack layout explaining "(kWordSize * 6)" offset.
-  // TOS + 0: Argument array.
-  // TOS + 1: Arguments descriptor array.
-  // TOS + 2: Closure object.
-  // TOS + 3: Place for result from closure function.
-  // TOS + 4: PC marker => RawInstruction object.
-  // TOS + 5: Saved RBP of previous frame. <== RBP
-  // TOS + 6: Dart code return address
-  // TOS + 7: Last argument of caller.
-  // ....
+  __ pushq(Address(RSP, R13, TIMES_4, (3 * kWordSize)));
 
-  __ CallRuntime(kInvokeImplicitClosureFunctionRuntimeEntry);
-  // Remove arguments.
-  __ popq(RAX);
-  __ popq(RAX);
-  __ popq(RAX);
-  __ popq(RAX);  // Get result into RAX.
+  __ pushq(RBX);  // Pass IC data object.
+  __ pushq(R10);  // Pass arguments descriptor array.
 
-  // Remove the stub frame as we are about to return.
-  __ LeaveFrame();
-  __ ret();
-
-  __ Bind(&function_not_found);
-  // The target function was not found, so invoke method
-  // "dynamic noSuchMethod(InvocationMirror invocation)".
-  //   RAX: receiver.
-  //   RBX: ic-data.
-  //   R10: arguments descriptor array.
-
-  __ pushq(raw_null);  // Setup space on stack for result from noSuchMethod.
-  __ pushq(RAX);  // Receiver.
-  __ pushq(RBX);  // IC-data array.
-  __ pushq(R10);  // Arguments descriptor array.
-  __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
-  __ SmiUntag(R13);  // Arguments array length, including the original receiver.
-  // See stack layout below explaining "wordSize * 7" offset.
-  PushArgumentsArray(assembler, (kWordSize * 7));
-
-  // Stack:
+  // Pass the call's arguments array.
+  __ movq(R10, R13);  // Smi-tagged arguments array length.
+  PushArgumentsArray(assembler, (7 * kWordSize));
+  // Stack layout explaining "(7 * kWordSize)" offset.
   // TOS + 0: Arguments array.
   // TOS + 1: Arguments descriptor array.
-  // TOS + 2: IC-data array.
+  // TOS + 2: IC data object.
   // TOS + 3: Receiver.
-  // TOS + 4: Place for result from noSuchMethod.
-  // TOS + 5: PC marker => RawInstruction object.
-  // TOS + 6: Saved RBP of previous frame. <== RBP
+  // TOS + 4: Space for the result of the runtime call.
+  // TOS + 5: Stub's PC marker (0)
+  // TOS + 6: Saved FP
   // TOS + 7: Dart code return address
   // TOS + 8: Last argument of caller.
   // ....
 
-  __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry);
+  __ CallRuntime(kInstanceFunctionLookupRuntimeEntry);
   // Remove arguments.
   __ popq(RAX);
   __ popq(RAX);
   __ popq(RAX);
   __ popq(RAX);
   __ popq(RAX);  // Get result into RAX.
-
-  // Remove the stub frame as we are about to return.
   __ LeaveFrame();
   __ ret();
 }
@@ -532,7 +423,8 @@
   // Load the receiver into RAX.  The argument count in the arguments
   // descriptor in R10 is a smi.
   __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
-  // Two words (return addres, saved fp) in the stack above the last argument.
+  // Two words (saved fp, stub's pc marker) in the stack above the return
+  // address.
   __ movq(RAX, Address(RSP, RAX, TIMES_4, 2 * kWordSize));
   // Preserve IC data and arguments descriptor.
   __ pushq(RBX);
@@ -778,9 +670,8 @@
   __ pushq(raw_null);  // Setup space on stack for result from call.
   __ pushq(R13);  // Non-closure object.
   __ pushq(R10);  // Arguments descriptor.
-  // Load num_args.
-  __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
-  __ SmiUntag(R13);  // Arguments array length, including the non-closure.
+  // Load smi-tagged arguments array length, including the non-closure.
+  __ movq(R10, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
   // See stack layout below explaining "wordSize * 6" offset.
   PushArgumentsArray(assembler, (kWordSize * 6));
 
@@ -812,7 +703,7 @@
 //   RSP : points to return address.
 //   RDI : entrypoint of the Dart function to call.
 //   RSI : arguments descriptor array.
-//   RDX : pointer to the argument array.
+//   RDX : arguments array.
 //   RCX : new context containing the current isolate pointer.
 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
   // Save frame pointer coming in.
@@ -866,6 +757,10 @@
   __ movq(RBX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
   __ SmiUntag(RBX);
 
+  // Compute address of 'arguments array' data area into RDX.
+  __ movq(RDX, Address(RDX, VMHandles::kOffsetOfRawPtrInHandle));
+  __ leaq(RDX, FieldAddress(RDX, Array::data_offset()));
+
   // Set up arguments for the Dart call.
   Label push_arguments;
   Label done_push_arguments;
@@ -874,7 +769,6 @@
   __ movq(RAX, Immediate(0));
   __ Bind(&push_arguments);
   __ movq(RCX, Address(RDX, RAX, TIMES_8, 0));  // RDX is start of arguments.
-  __ movq(RCX, Address(RCX, VMHandles::kOffsetOfRawPtrInHandle));
   __ pushq(RCX);
   __ incq(RAX);
   __ cmpq(RAX, RBX);
@@ -1445,8 +1339,7 @@
   const Immediate raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
   __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
-  __ SmiUntag(R13);
-  __ movq(RAX, Address(RBP, R13, TIMES_8, kWordSize));  // Get receiver.
+  __ movq(RAX, Address(RBP, R13, TIMES_4, kWordSize));  // Get receiver.
 
   // Create a stub frame.
   AssemblerMacros::EnterStubFrame(assembler);
@@ -1455,7 +1348,8 @@
   __ pushq(RAX);  // Receiver.
   __ pushq(RBX);  // IC data array.
   __ pushq(R10);  // Arguments descriptor array.
-  // R13: Arguments array length, including the receiver.
+
+  __ movq(R10, R13);  // Smi-tagged arguments array length.
   // See stack layout below explaining "wordSize * 10" offset.
   PushArgumentsArray(assembler, (kWordSize * 10));
 
@@ -2053,10 +1947,10 @@
   __ movq(RAX, Address(RSP, 1 * kWordSize));
   __ cmpq(RAX, Address(RSP, 2 * kWordSize));
   __ j(EQUAL, &true_label, Assembler::kNearJump);
-  __ LoadObject(RAX, Bool::ZoneHandle(Bool::False()));
+  __ LoadObject(RAX, Bool::False());
   __ ret();
   __ Bind(&true_label);
-  __ LoadObject(RAX, Bool::ZoneHandle(Bool::True()));
+  __ LoadObject(RAX, Bool::True());
   __ ret();
 
   __ Bind(&get_class_id_as_smi);
@@ -2080,7 +1974,7 @@
   AssemblerMacros::EnterStubFrame(assembler);
   __ pushq(R13);  // arg 0
   __ pushq(RAX);  // arg 1
-  __ PushObject(Symbols::EqualOperatorHandle());  // Target's name.
+  __ PushObject(Symbols::EqualOperator());  // Target's name.
   __ pushq(RBX);  // ICData
   __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry);
   __ Drop(4);
diff --git a/runtime/vm/stub_code_x64_test.cc b/runtime/vm/stub_code_x64_test.cc
index f853ee2..20a7d7a 100644
--- a/runtime/vm/stub_code_x64_test.cc
+++ b/runtime/vm/stub_code_x64_test.cc
@@ -70,10 +70,8 @@
   const Code& code = Code::Handle(Code::FinalizeCode(
       *CreateFunction("Test_CallRuntimeStubCode"), &_assembler_));
   const Function& function = RegisterFakeFunction(kName, code);
-  GrowableArray<const Object*>  arguments;
-  const Array& kNoArgumentNames = Array::Handle();
   Smi& result = Smi::Handle();
-  result ^= DartEntry::InvokeStatic(function, arguments, kNoArgumentNames);
+  result ^= DartEntry::InvokeStatic(function, Object::empty_array());
   EXPECT_EQ((value1 - value2), result.Value());
 }
 
@@ -105,10 +103,8 @@
   const Code& code = Code::Handle(Code::FinalizeCode(
       *CreateFunction("Test_CallLeafRuntimeStubCode"), &_assembler_));
   const Function& function = RegisterFakeFunction(kName, code);
-  GrowableArray<const Object*>  arguments;
-  const Array& kNoArgumentNames = Array::Handle();
   Smi& result = Smi::Handle();
-  result ^= DartEntry::InvokeStatic(function, arguments, kNoArgumentNames);
+  result ^= DartEntry::InvokeStatic(function, Object::empty_array());
   EXPECT_EQ((value1 + value2), result.Value());
 }
 
diff --git a/runtime/vm/symbols.cc b/runtime/vm/symbols.cc
index 9813d88..b0e1480 100644
--- a/runtime/vm/symbols.cc
+++ b/runtime/vm/symbols.cc
@@ -16,14 +16,8 @@
 
 namespace dart {
 
-RawString* Symbols::predefined_[Symbols::kMaxId];
-
-Symbols::ReadOnlyHandles* Symbols::predefined_handles_ = NULL;
-
-#define DEFINE_SYMBOL_HANDLE(symbol)                                           \
-  String* Symbols::symbol##_handle_ = NULL;
-PREDEFINED_SYMBOL_HANDLES_LIST(DEFINE_SYMBOL_HANDLE)
-#undef DEFINE_SYMBOL_HANDLE
+RawString* Symbols::predefined_[Symbols::kNumberOfOneCharCodeSymbols];
+String* Symbols::symbol_handles_[Symbols::kMaxPredefinedId];
 
 static const char* names[] = {
   NULL,
@@ -41,7 +35,7 @@
 
 
 const char* Symbols::Name(SymbolId symbol) {
-  ASSERT((symbol > kIllegal) && (symbol < kMaxPredefinedId));
+  ASSERT((symbol > kIllegal) && (symbol < kNullCharId));
   return names[symbol];
 }
 
@@ -61,33 +55,38 @@
   SetupSymbolTable(isolate);
 
   // Create all predefined symbols.
-  ASSERT((sizeof(names) / sizeof(const char*)) == Symbols::kMaxPredefinedId);
+  ASSERT((sizeof(names) / sizeof(const char*)) == Symbols::kNullCharId);
   ObjectStore* object_store = isolate->object_store();
   Array& symbol_table = Array::Handle();
-  dart::String& str = String::Handle();
 
-  for (intptr_t i = 1; i < Symbols::kMaxPredefinedId; i++) {
+
+  // First set up all the predefined string symbols.
+  for (intptr_t i = 1; i < Symbols::kNullCharId; i++) {
     // The symbol_table needs to be reloaded as it might have grown in the
     // previous iteration.
     symbol_table = object_store->symbol_table();
-    str = OneByteString::New(names[i], Heap::kOld);
-    Add(symbol_table, str);
-    predefined_[i] = str.raw();
+    String* str = reinterpret_cast<String*>(Dart::AllocateReadOnlyHandle());
+    *str = OneByteString::New(names[i], Heap::kOld);
+    Add(symbol_table, *str);
+    symbol_handles_[i] = str;
   }
   Object::RegisterSingletonClassNames();
 
-  for (int32_t c = 0; c <= kMaxOneCharCodeSymbol; c++) {
-    ASSERT(kMaxPredefinedId + c < kMaxId);
-    predefined_[kMaxPredefinedId + c] = FromUTF32(&c, 1);
+  // Add Latin1 characters as Symbols, so that Symbols::FromCharCode is fast.
+  for (intptr_t c = 0; c < kNumberOfOneCharCodeSymbols; c++) {
+    // The symbol_table needs to be reloaded as it might have grown in the
+    // previous iteration.
+    symbol_table = object_store->symbol_table();
+    intptr_t idx = (kNullCharId + c);
+    ASSERT(idx < kMaxPredefinedId);
+    ASSERT(Utf::IsLatin1(c));
+    uint8_t ch = static_cast<uint8_t>(c);
+    String* str = reinterpret_cast<String*>(Dart::AllocateReadOnlyHandle());
+    *str = OneByteString::New(&ch, 1, Heap::kOld);
+    Add(symbol_table, *str);
+    predefined_[c] = str->raw();
+    symbol_handles_[idx] = str;
   }
-
-  predefined_handles_ = new ReadOnlyHandles();
-#define INITIALIZE_SYMBOL_HANDLE(symbol)                                       \
-  symbol##_handle_ = reinterpret_cast<String*>(                                \
-      predefined_handles_->AllocateHandle());                                  \
-  *symbol##_handle_ = symbol();
-PREDEFINED_SYMBOL_HANDLES_LIST(INITIALIZE_SYMBOL_HANDLE)
-#undef INITIALIZE_SYMBOL_HANDLE
 }
 
 
@@ -273,12 +272,7 @@
   if (char_code > kMaxOneCharCodeSymbol) {
     return FromUTF32(&char_code, 1);
   }
-  return predefined_[kNullCharId + char_code];
-}
-
-
-bool Symbols::IsPredefinedHandle(uword address) {
-  return predefined_handles_->IsValidHandle(address);
+  return predefined_[char_code];
 }
 
 
@@ -441,8 +435,8 @@
 
 
 intptr_t Symbols::LookupVMSymbol(RawObject* obj) {
-  for (intptr_t i = 1;  i < Symbols::kMaxId; i++) {
-    if (predefined_[i] == obj) {
+  for (intptr_t i = 1; i < Symbols::kMaxPredefinedId; i++) {
+    if (symbol_handles_[i]->raw() == obj) {
       return (i + kMaxPredefinedObjectIds);
     }
   }
@@ -453,7 +447,10 @@
 RawObject* Symbols::GetVMSymbol(intptr_t object_id) {
   ASSERT(IsVMSymbolId(object_id));
   intptr_t i = (object_id - kMaxPredefinedObjectIds);
-  return (i > 0 && i < Symbols::kMaxId) ? predefined_[i] : Object::null();
+  if ((i > kIllegal) && (i < Symbols::kMaxPredefinedId)) {
+    return symbol_handles_[i]->raw();
+  }
+  return Object::null();
 }
 
 }  // namespace dart
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 17d03fe..274f36e 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -16,8 +16,6 @@
 
 #define PREDEFINED_SYMBOLS_LIST(V)                                             \
   V(Empty, "")                                                                 \
-  V(Dot, ".")                                                                  \
-  V(Equals, "=")                                                               \
   V(EqualOperator, "==")                                                       \
   V(Identical, "identical")                                                    \
   V(Length, "length")                                                          \
@@ -41,7 +39,7 @@
   V(FallThroughError, "FallThroughErrorImplementation")                        \
   V(AbstractClassInstantiationError,                                           \
     "AbstractClassInstantiationErrorImplementation")                           \
-  V(NoSuchMethodError, "NoSuchMethodErrorImplementation")                      \
+  V(NoSuchMethodError, "NoSuchMethodError")                                    \
   V(ThrowNew, "_throwNew")                                                     \
   V(List, "List")                                                              \
   V(ListLiteralFactory, "List._fromLiteral")                                   \
@@ -104,10 +102,10 @@
   V(UnwindError, "UnwindError")                                                \
   V(IntegerImplementation, "_IntegerImplementation")                           \
   V(Number, "num")                                                             \
-  V(Smi, "_Smi")                                                               \
-  V(Mint, "_Mint")                                                             \
-  V(Bigint, "_Bigint")                                                         \
-  V(Double, "_Double")                                                         \
+  V(_Smi, "_Smi")                                                              \
+  V(_Mint, "_Mint")                                                            \
+  V(_Bigint, "_Bigint")                                                        \
+  V(_Double, "_Double")                                                        \
   V(Bool, "bool")                                                              \
   V(ObjectArray, "_ObjectArray")                                               \
   V(GrowableObjectArray, "_GrowableObjectArray")                               \
@@ -119,6 +117,19 @@
   V(Stacktrace, "Stacktrace")                                                  \
   V(JSSyntaxRegExp, "_JSSyntaxRegExp")                                         \
   V(Object, "Object")                                                          \
+  V(Int, "int")                                                                \
+  V(Double, "double")                                                          \
+  V(Int8List, "Int8List")                                                      \
+  V(Uint8List, "Uint8List")                                                    \
+  V(Uint8ClampedList, "Uint8ClampedList")                                      \
+  V(Int16List, "Int16List")                                                    \
+  V(Uint16List, "Uint16List")                                                  \
+  V(Int32List, "Int32List")                                                    \
+  V(Uint32List, "Uint32List")                                                  \
+  V(Int64List, "Int64List")                                                    \
+  V(Uint64List, "Uint64List")                                                  \
+  V(Float32List, "Float32List")                                                \
+  V(Float64List, "Float64List")                                                \
   V(_Int8Array, "_Int8Array")                                                  \
   V(_Uint8Array, "_Uint8Array")                                                \
   V(_Uint8ClampedArray, "_Uint8ClampedArray")                                  \
@@ -144,13 +155,37 @@
   V(_WeakProperty, "_WeakProperty")                                            \
   V(InvocationMirror, "_InvocationMirror")                                     \
   V(AllocateInvocationMirror, "_allocateInvocationMirror")                     \
-
-#define PREDEFINED_SYMBOL_HANDLES_LIST(V)                                      \
-  V(Dot)                                                                       \
-  V(EqualOperator)                                                             \
-  V(IndexToken)                                                                \
-  V(AssignIndexToken)                                                          \
-  V(This)                                                                      \
+  V(toString, "toString")                                                      \
+  V(_ReceivePortImpl, "_ReceivePortImpl")                                      \
+  V(_lookupReceivePort, "_lookupReceivePort")                                  \
+  V(_handleMessage, "_handleMessage")                                          \
+  V(_SendPortImpl, "_SendPortImpl")                                            \
+  V(_create, "_create")                                                        \
+  V(_id, "_id")                                                                \
+  V(_get_or_create, "_get_or_create")                                          \
+  V(RangeError, "RangeError")                                                  \
+  V(ArgumentError, "ArgumentError")                                            \
+  V(FormatException, "FormatException")                                        \
+  V(StackOverflowError, "StackOverflowError")                                  \
+  V(OutOfMemoryError, "OutOfMemoryError")                                      \
+  V(InternalError, "InternalError")                                            \
+  V(NullThrownError, "NullThrownError")                                        \
+  V(IllegalJSRegExpException, "IllegalJSRegExpException")                      \
+  V(IsolateSpawnException, "IsolateSpawnException")                            \
+  V(IsolateUnhandledException, "IsolateUnhandledException")                    \
+  V(BooleanExpression, "boolean expression")                                   \
+  V(Malformed, "malformed")                                                    \
+  V(InstanceOf, "InstanceOf")                                                  \
+  V(MegamorphicMiss, "megamorphic_miss")                                       \
+  V(CommaSpace, ", ")                                                          \
+  V(ColonSpace, ": ")                                                          \
+  V(RParenArrow, ") => ")                                                      \
+  V(SpaceExtendsSpace, " extends ")                                            \
+  V(PatchSpace, "patch ")                                                      \
+  V(AliasOwner, ":alias_owner")                                                \
+  V(SwitchExpr, ":switch_expr")                                                \
+  V(TwoNewlines, "\n\n")                                                       \
+  V(TwoSpaces, "  ")                                                           \
 
 // Contains a list of frequently used strings in a canonicalized form. This
 // list is kept in the vm_isolate in order to share the copy across isolates
@@ -164,24 +199,75 @@
     kIllegal = 0,
 
 #define DEFINE_SYMBOL_INDEX(symbol, literal)                                   \
-    k##symbol,
+    k##symbol##Id,
 PREDEFINED_SYMBOLS_LIST(DEFINE_SYMBOL_INDEX)
 #undef DEFINE_SYMBOL_INDEX
-    kMaxPredefinedId,
-    kNullCharId = kMaxPredefinedId,
-    kMaxId = kNullCharId + kMaxOneCharCodeSymbol + 1,
+
+    kNullCharId,  // One char code symbol starts here and takes up 256 entries.
+    kMaxPredefinedId = kNullCharId + kMaxOneCharCodeSymbol + 1,
   };
 
-  // Access methods for symbols stored in the vm isolate.
-#define DEFINE_SYMBOL_ACCESSOR(symbol, literal)                                \
-  static RawString* symbol() { return predefined_[k##symbol]; }
-PREDEFINED_SYMBOLS_LIST(DEFINE_SYMBOL_ACCESSOR)
-#undef DEFINE_SYMBOL_ACCESSOR
+  // Number of one character symbols being predefined in the predefined_ array.
+  static const int kNumberOfOneCharCodeSymbols =
+      (kMaxPredefinedId - kNullCharId);
+
+  // Offset of Null character which is the predefined character symbol.
+  static const int kNullCharCodeSymbolOffset = 0;
+
+  // Access methods for one byte character symbols stored in the vm isolate.
+  static const String& Dot() {
+    return *(symbol_handles_[kNullCharId + '.']);
+  }
+  static const String& Equals() {
+    return *(symbol_handles_[kNullCharId + '=']);
+  }
+  static const String& LAngleBracket() {
+    return *(symbol_handles_[kNullCharId + '<']);
+  }
+  static const String& RAngleBracket() {
+    return *(symbol_handles_[kNullCharId + '>']);
+  }
+  static const String& LParen() {
+    return *(symbol_handles_[kNullCharId + '(']);
+  }
+  static const String& RParen() {
+    return *(symbol_handles_[kNullCharId + ')']);
+  }
+  static const String& LBracket() {
+    return *(symbol_handles_[kNullCharId + '[']);
+  }
+  static const String& RBracket() {
+    return *(symbol_handles_[kNullCharId + ']']);
+  }
+  static const String& LBrace() {
+    return *(symbol_handles_[kNullCharId + '{']);
+  }
+  static const String& RBrace() {
+    return *(symbol_handles_[kNullCharId + '}']);
+  }
+  static const String& Blank() {
+    return *(symbol_handles_[kNullCharId + ' ']);
+  }
+  static const String& Dollar() {
+    return *(symbol_handles_[kNullCharId + '$']);
+  }
+  static const String& NewLine() {
+    return *(symbol_handles_[kNullCharId + '\n']);
+  }
+  static const String& DoubleQuotes() {
+    return *(symbol_handles_[kNullCharId + '"']);
+  }
+  static const String& LowercaseR() {
+    return *(symbol_handles_[kNullCharId + 'r']);
+  }
+  static const String& Dash() {
+    return *(symbol_handles_[kNullCharId + '-']);
+  }
 
   // Access methods for symbol handles stored in the vm isolate.
-#define DEFINE_SYMBOL_HANDLE_ACCESSOR(symbol)                                  \
-  static const String& symbol##Handle() { return *symbol##_handle_; }
-PREDEFINED_SYMBOL_HANDLES_LIST(DEFINE_SYMBOL_HANDLE_ACCESSOR)
+#define DEFINE_SYMBOL_HANDLE_ACCESSOR(symbol, literal)                         \
+  static const String& symbol() { return *(symbol_handles_[k##symbol##Id]); }
+PREDEFINED_SYMBOLS_LIST(DEFINE_SYMBOL_HANDLE_ACCESSOR)
 #undef DEFINE_SYMBOL_HANDLE_ACCESSOR
 
   // Initialize frequently used symbols in the vm isolate.
@@ -224,8 +310,6 @@
     return reinterpret_cast<RawString**>(&predefined_);
   }
 
-  static bool IsPredefinedHandle(uword address);
-
   static void DumpStats();
 
  private:
@@ -267,43 +351,22 @@
   static RawObject* GetVMSymbol(intptr_t object_id);
   static bool IsVMSymbolId(intptr_t object_id) {
     return (object_id >= kMaxPredefinedObjectIds &&
-            object_id < (kMaxPredefinedObjectIds + kMaxId));
+            object_id < (kMaxPredefinedObjectIds + kMaxPredefinedId));
   }
 
-  // List of symbols that are stored in the vm isolate for easy access.
-  static RawString* predefined_[kMaxId];
+  // List of Latin1 characters stored in the vm isolate as symbols
+  // in order to make Symbols::FromCharCode fast. This structure is
+  // used in generated dart code for direct access to these objects.
+  static RawString* predefined_[kNumberOfOneCharCodeSymbols];
+
+  // List of handles for predefined symbols.
+  static String* symbol_handles_[kMaxPredefinedId];
 
   // Statistics used to measure the efficiency of the symbol table.
   static const intptr_t kMaxCollisionBuckets = 10;
   static intptr_t num_of_grows_;
   static intptr_t collision_count_[kMaxCollisionBuckets];
 
-  // Structure for managing handles allocation for symbols that are
-  // stored in the vm isolate. We don't want these handles to be
-  // destroyed as part of the C++ static destructors and hence this
-  // object is dynamically allocated.
-  class ReadOnlyHandles {
-    public:
-      ReadOnlyHandles() { }
-      uword AllocateHandle() {
-        return handles_.AllocateScopedHandle();
-      }
-      bool IsValidHandle(uword address) {
-        return handles_.IsValidScopedHandle(address);
-      }
-
-    private:
-      VMHandles handles_;
-
-      DISALLOW_COPY_AND_ASSIGN(ReadOnlyHandles);
-  };
-  static ReadOnlyHandles* predefined_handles_;
-
-#define DECLARE_SYMBOL_HANDLE(symbol)                                          \
-  static String* symbol##_handle_;
-PREDEFINED_SYMBOL_HANDLES_LIST(DECLARE_SYMBOL_HANDLE)
-#undef DECLARE_SYMBOL_HANDLE
-
   friend class String;
   friend class SnapshotReader;
   friend class SnapshotWriter;
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h
index 713c272..7859a5e 100644
--- a/runtime/vm/unit_test.h
+++ b/runtime/vm/unit_test.h
@@ -81,10 +81,8 @@
     CodeGenTestRun##name(__test__.function());                                 \
   }                                                                            \
   static void CodeGenTestRun##name(const Function& function) {                 \
-    GrowableArray<const Object*>  arguments;                                   \
-    const Array& kNoArgumentNames = Array::Handle();                           \
     Object& result = Object::Handle();                                         \
-    result = DartEntry::InvokeStatic(function, arguments, kNoArgumentNames);   \
+    result = DartEntry::InvokeStatic(function, Object::empty_array());         \
     EXPECT(!result.IsError());                                                 \
     Instance& actual = Instance::Handle();                                     \
     actual ^= result.raw();                                                    \
@@ -121,10 +119,8 @@
     CodeGenTestRun##name1(__test1__.function());                               \
   }                                                                            \
   static void CodeGenTestRun##name1(const Function& function) {                \
-    GrowableArray<const Object*> arguments;                                    \
-    const Array& kNoArgumentNames = Array::Handle();                           \
     Object& result = Object::Handle();                                         \
-    result = DartEntry::InvokeStatic(function, arguments, kNoArgumentNames);   \
+    result = DartEntry::InvokeStatic(function, Object::empty_array());         \
     EXPECT(!result.IsError());                                                 \
     Instance& actual = Instance::Handle();                                     \
     actual ^= result.raw();                                                    \
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index 8cc57c1..a6370d6 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -113,8 +113,6 @@
     'debuginfo.h',
     'debuginfo_android.cc',
     'debuginfo_linux.cc',
-    'debuginfo_macos.cc',
-    'debuginfo_win.cc',
     'double_conversion.cc',
     'double_conversion.h',
     'exceptions.cc',
@@ -169,6 +167,9 @@
     'heap_profiler.h',
     'heap_profiler_test.cc',
     'heap_test.cc',
+    'heap_trace.cc',
+    'heap_trace.h',
+    'heap_trace_test.cc',
     'il_printer.cc',
     'il_printer.h',
     'instructions.h',
diff --git a/runtime/vm/zone.cc b/runtime/vm/zone.cc
index 5227b16..5a2629d 100644
--- a/runtime/vm/zone.cc
+++ b/runtime/vm/zone.cc
@@ -7,6 +7,8 @@
 #include "platform/assert.h"
 #include "platform/utils.h"
 #include "vm/flags.h"
+#include "vm/heap.h"
+#include "vm/heap_trace.h"
 #include "vm/isolate.h"
 #include "vm/os.h"
 
@@ -91,6 +93,10 @@
 
 Zone::~Zone() {
   DeleteAll();
+  if (HeapTrace::is_enabled()) {
+    Isolate* isolate = Isolate::Current();
+    isolate->heap()->trace()->TraceDeleteZone(this);
+  }
 #if defined(DEBUG)
   if (FLAG_trace_zone_sizes) {
     DumpZoneSizes();
diff --git a/sdk/lib/_internal/compiler/implementation/closure.dart b/sdk/lib/_internal/compiler/implementation/closure.dart
index 7f981dc..7f3df99 100644
--- a/sdk/lib/_internal/compiler/implementation/closure.dart
+++ b/sdk/lib/_internal/compiler/implementation/closure.dart
@@ -6,6 +6,7 @@
 
 import "elements/elements.dart";
 import "dart2jslib.dart";
+import "scanner/scannerlib.dart" show Token;
 import "tree/tree.dart";
 import "util/util.dart";
 
@@ -108,6 +109,20 @@
       : super(const SourceString('this'), ElementKind.PARAMETER, enclosing);
 
   bool isAssignable() => false;
+
+  // Since there is no declaration corresponding to 'this', use the position of
+  // the enclosing method.
+  Token position() => enclosingElement.position();
+}
+
+class CheckVariableElement extends Element {
+  Element parameter;
+  CheckVariableElement(SourceString name, this.parameter, Element enclosing)
+      : super(name, ElementKind.VARIABLE, enclosing);
+
+  // Since there is no declaration for the synthetic 'check' variable, use
+  // parameter.
+  Token position() => parameter.position();
 }
 
 // The box-element for a scope, and the captured variables that need to be
@@ -273,10 +288,12 @@
         freeVariableMapping[element] = fieldElement;
       }
       // Add the box elements first so we get the same ordering.
+      // TODO(sra): What is the canonical order of multiple boxes?
       for (Element capturedElement in boxes) {
         addElement(capturedElement, capturedElement.name);
       }
-      for (Element capturedElement in fieldCaptures) {
+      for (Element capturedElement in
+               Elements.sortedByPosition(fieldCaptures)) {
         int id = closureFieldCounter++;
         SourceString name =
             namer.getClosureVariableName(capturedElement.name, id);
@@ -364,9 +381,9 @@
       if (!cached.parametersWithSentinel.containsKey(parameter)) {
         SourceString parameterName = parameter.name;
         String name = '${parameterName.slowToString()}_check';
-        Element newElement = new Element(new SourceString(name),
-                                         ElementKind.VARIABLE,
-                                         enclosing);
+        Element newElement = new CheckVariableElement(new SourceString(name),
+                                                      parameter,
+                                                      enclosing);
         useLocal(newElement);
         cached.parametersWithSentinel[parameter] = newElement;
       }
@@ -597,8 +614,7 @@
     currentElement = oldFunctionElement;
 
     // Mark all free variables as captured and use them in the outer function.
-    List<Element> freeVariables =
-        savedClosureData.freeVariableMapping.keys;
+    List<Element> freeVariables = savedClosureData.freeVariableMapping.keys;
     assert(freeVariables.isEmpty || savedInsideClosure);
     for (Element freeElement in freeVariables) {
       if (capturedVariableMapping[freeElement] != null &&
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index 9470db5..636fcc5 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -115,6 +115,11 @@
   final bool enableTypeAssertions;
   final bool enableUserAssertions;
   final bool enableConcreteTypeInference;
+  /**
+   * The maximum size of a concrete type before it widens to dynamic during
+   * concrete type inference.
+   */
+  final int maxConcreteTypeSize;
   final bool analyzeAll;
   final bool enableNativeLiveTypeAnalysis;
   final bool rejectDeprecatedFeatures;
@@ -128,6 +133,7 @@
   Element _currentElement;
   LibraryElement coreLibrary;
   LibraryElement isolateLibrary;
+  LibraryElement isolateHelperLibrary;
   LibraryElement jsHelperLibrary;
   LibraryElement interceptorsLibrary;
   LibraryElement foreignLibrary;
@@ -232,6 +238,7 @@
             this.enableTypeAssertions: false,
             this.enableUserAssertions: false,
             this.enableConcreteTypeInference: false,
+            this.maxConcreteTypeSize: 5,
             this.enableMinification: false,
             this.enableNativeLiveTypeAnalysis: false,
             bool emitJavaScript: true,
@@ -270,7 +277,7 @@
       resolver = new ResolverTask(this),
       closureToClassMapper = new closureMapping.ClosureTask(this, closureNamer),
       checker = new TypeCheckerTask(this),
-      typesTask = new ti.TypesTask(this, enableConcreteTypeInference),
+      typesTask = new ti.TypesTask(this),
       constantHandler = new ConstantHandler(this, backend.constantSystem),
       enqueuer = new EnqueueTask(this)];
 
@@ -402,12 +409,14 @@
   void enableIsolateSupport(LibraryElement element) {
     // TODO(ahe): Move this method to Enqueuer.
     isolateLibrary = element.patch;
-    enqueuer.resolution.addToWorkList(isolateLibrary.find(START_ROOT_ISOLATE));
     enqueuer.resolution.addToWorkList(
-        isolateLibrary.find(const SourceString('_currentIsolate')));
+        isolateHelperLibrary.find(START_ROOT_ISOLATE));
     enqueuer.resolution.addToWorkList(
-        isolateLibrary.find(const SourceString('_callInIsolate')));
-    enqueuer.codegen.addToWorkList(isolateLibrary.find(START_ROOT_ISOLATE));
+        isolateHelperLibrary.find(const SourceString('_currentIsolate')));
+    enqueuer.resolution.addToWorkList(
+        isolateHelperLibrary.find(const SourceString('_callInIsolate')));
+    enqueuer.codegen.addToWorkList(
+        isolateHelperLibrary.find(START_ROOT_ISOLATE));
   }
 
   bool hasIsolateSupport() => isolateLibrary != null;
@@ -463,6 +472,13 @@
     jsHelperLibrary = scanBuiltinLibrary('_js_helper');
     interceptorsLibrary = scanBuiltinLibrary('_interceptors');
     foreignLibrary = scanBuiltinLibrary('_foreign_helper');
+    isolateHelperLibrary = scanBuiltinLibrary('_isolate_helper');
+    // The helper library does not use the native language extension,
+    // so we manually set the native classes this library defines.
+    // TODO(ngeoffray): Enable annotations on these classes.
+    ClassElement cls =
+        isolateHelperLibrary.find(const SourceString('_WorkerStub'));
+    cls.setNative('"*Worker"');
 
     // The core library was loaded and patched before jsHelperLibrary was
     // initialized, so it wasn't imported into those two libraries during
@@ -473,6 +489,9 @@
     importForeignLibrary(jsHelperLibrary);
     importForeignLibrary(interceptorsLibrary);
 
+    importForeignLibrary(isolateHelperLibrary);
+    importHelperLibrary(isolateHelperLibrary);
+
     assertMethod = jsHelperLibrary.find(const SourceString('assertHelper'));
     identicalFunction = coreLibrary.find(const SourceString('identical'));
 
@@ -500,11 +519,17 @@
 
   /** Define the JS helper functions in the given library. */
   void importForeignLibrary(LibraryElement library) {
-    if (jsHelperLibrary != null) {
+    if (foreignLibrary != null) {
       libraryLoader.importLibrary(library, foreignLibrary, null);
     }
   }
 
+  void importIsolateHelperLibrary(LibraryElement library) {
+    if (isolateHelperLibrary != null) {
+      libraryLoader.importLibrary(library, isolateHelperLibrary, null);
+    }
+  }
+
   // TODO(karlklose,floitsch): move this to the javascript backend.
   /** Enable the 'JS' helper for a library if needed. */
   void maybeEnableJSHelper(LibraryElement library) {
@@ -513,7 +538,6 @@
         'dart/tests/compiler/dart2js_native');
     if (nativeTest
         || libraryName == 'dart:mirrors'
-        || libraryName == 'dart:isolate'
         || libraryName == 'dart:math'
         || libraryName == 'dart:html'
         || libraryName == 'dart:html_common'
@@ -524,8 +548,7 @@
           || libraryName == 'dart:html'
           || libraryName == 'dart:html_common'
           || libraryName == 'dart:indexed_db'
-          || libraryName == 'dart:svg'
-          || libraryName == 'dart:mirrors') {
+          || libraryName == 'dart:svg') {
         // dart:html and dart:svg need access to convertDartClosureToJS and
         // annotation classes.
         // dart:mirrors needs access to the Primitives class.
@@ -541,12 +564,21 @@
     }
   }
 
+  void maybeEnableIsolateHelper(LibraryElement library) {
+    String libraryName = library.uri.toString();
+    if (libraryName == 'dart:isolate'
+        || libraryName == 'dart:html') {
+      importIsolateHelperLibrary(library);
+    }
+  }
+
   void runCompiler(Uri uri) {
     log('compiling $uri ($BUILD_ID)');
     scanBuiltinLibraries();
     mainApp = libraryLoader.loadLibrary(uri, null, uri);
     libraries.forEach((_, library) {
       maybeEnableJSHelper(library);
+      maybeEnableIsolateHelper(library);
     });
     final Element main = mainApp.find(MAIN);
     if (main == null) {
diff --git a/sdk/lib/_internal/compiler/implementation/elements/elements.dart b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
index 4bb1abb..360800b 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/elements.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
@@ -1489,6 +1489,15 @@
     return result;
   }
 
+  /// Lookup a synthetic element created by the backend.
+  Element lookupBackendMember(SourceString memberName) {
+    for (Element element in backendMembers) {
+      if (element.name == memberName) {
+        return element;
+      }
+    }
+  }
+
   /**
    * Lookup super members for the class. This will ignore constructors.
    */
@@ -1761,6 +1770,9 @@
 
   bool isInterface() => false;
   bool isNative() => nativeTagInfo != null;
+  void setNative(String name) {
+    nativeTagInfo = new SourceString(name);
+  }
   int get hashCode => id;
 
   Scope buildScope() => new ClassScope(enclosingElement.buildScope(), this);
@@ -2007,6 +2019,30 @@
     return (element == coreLibrary.find(const SourceString('Collection')))
         || (element == coreLibrary.find(const SourceString('Iterable')));
   }
+
+  /// A `compareTo` function that places [Element]s in a consistent order based
+  /// on the source code order.
+  static int compareByPosition(Element a, Element b) {
+    CompilationUnitElement unitA = a.getCompilationUnit();
+    CompilationUnitElement unitB = b.getCompilationUnit();
+    if (!identical(unitA, unitB)) {
+      int r = unitA.script.uri.path.compareTo(unitB.script.uri.path);
+      if (r != 0) return r;
+    }
+    Token positionA = a.position();
+    Token positionB = b.position();
+    int r = positionA.charOffset.compareTo(positionB.charOffset);
+    if (r != 0) return r;
+    r = a.name.slowToString().compareTo(b.name.slowToString());
+    if (r != 0) return r;
+    // Same file, position and name.  If this happens, we should find out why
+    // and make the order total and independent of hashCode.
+    return a.hashCode.compareTo(b.hashCode);
+  }
+
+  static List<Element> sortedByPosition(Collection<Element> elements) {
+    return new List<Element>.from(elements)..sort(compareByPosition);
+  }
 }
 
 class LabelElement extends Element {
@@ -2125,6 +2161,11 @@
   Element annotatedElement;
   int resolutionState;
 
+  /**
+   * The beginning token of this annotation, or [:null:] if it is synthetic.
+   */
+  Token get beginToken;
+
   MetadataAnnotation([this.resolutionState = STATE_NOT_STARTED]);
 
   MetadataAnnotation ensureResolved(Compiler compiler) {
diff --git a/sdk/lib/_internal/compiler/implementation/js/nodes.dart b/sdk/lib/_internal/compiler/implementation/js/nodes.dart
index f206c0e..d55b6a4 100644
--- a/sdk/lib/_internal/compiler/implementation/js/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/js/nodes.dart
@@ -857,3 +857,41 @@
 
   int get precedenceLevel => PRIMARY;
 }
+
+Prefix typeOf(Expression argument) => new Prefix('typeof', argument);
+
+Binary equals(Expression left, Expression right) {
+  return new Binary('==', left, right);
+}
+
+LiteralString string(String value) => new LiteralString("'$value'");
+
+If if_(Expression condition, Node then, [Node otherwise]) {
+  return (otherwise == null)
+      ? new If.noElse(condition, then)
+      : new If(condition, then, otherwise);
+}
+
+Return return_([Expression value]) => new Return(value);
+
+VariableUse use(String name) => new VariableUse(name);
+
+PropertyAccess fieldAccess(Expression receiver, String fieldName) {
+  return new PropertyAccess.field(receiver, fieldName);
+}
+
+Block emptyBlock() => new Block.empty();
+
+Call call(Expression target, List<Expression> arguments) {
+  return new Call(target, arguments);
+}
+
+Fun fun(List<String> parameterNames, Block body) {
+  return new Fun(parameterNames.map((n) => new Parameter(n)), body);
+}
+
+Assignment assign(Expression leftHandSide, Expression value) {
+  return new Assignment(leftHandSide, value);
+}
+
+Expression undefined() => new Prefix('void', new LiteralNumber('0'));
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
index 902414d..463d2a7 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
@@ -690,7 +690,7 @@
   /**
    * Set of classes whose instances are intercepted. Implemented as a
    * [LinkedHashMap] to preserve the insertion order.
-   * TODO(ngeoffray): Use a BitSet instead.
+   * TODO(ngeoffray): No need to preserve order anymore.
    */
   final Map<ClassElement, ClassElement> interceptedClasses;
 
@@ -849,6 +849,12 @@
       addInterceptors(jsStringClass, enqueuer);
     } else if (cls == compiler.listClass) {
       addInterceptors(jsArrayClass, enqueuer);
+      // The backend will try to optimize array access and use the
+      // `ioore` and `iae` helpers directly.
+      enqueuer.registerStaticUse(
+          compiler.findHelper(const SourceString('ioore')));
+      enqueuer.registerStaticUse(
+          compiler.findHelper(const SourceString('iae')));
     } else if (cls == compiler.intClass) {
       addInterceptors(jsIntClass, enqueuer);
       addInterceptors(jsNumberClass, enqueuer);
@@ -1095,7 +1101,7 @@
       return const SourceString('numTypeCheck');
     } else if (element == compiler.boolClass) {
       return const SourceString('boolTypeCheck');
-    } else if (element == compiler.functionClass || element.isTypedef()) {
+    } else if (element == compiler.functionClass) {
       return const SourceString('functionTypeCheck');
     } else if (element == compiler.intClass) {
       return const SourceString('intTypeCheck');
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
index 8a212a4..58debdb 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
@@ -44,6 +44,9 @@
       well as in the generated code. */
   String isolateProperties;
   String classesCollector;
+  Set<ClassElement> neededClasses;
+  // TODO(ngeoffray): remove this field.
+  Set<ClassElement> instantiatedClasses;
 
   String get _ => compiler.enableMinification ? "" : " ";
   String get n => compiler.enableMinification ? "" : "\n";
@@ -757,6 +760,49 @@
     }
   }
 
+  void emitRuntimeClassesAndTests(CodeBuffer buffer) {
+    JavaScriptBackend backend = compiler.backend;
+    RuntimeTypeInformation rti = backend.rti;
+
+    TypeChecks typeChecks = rti.computeRequiredChecks();
+
+    bool needsHolder(ClassElement cls) {
+      return !neededClasses.contains(cls) || cls.isNative() ||
+          rti.isJsNative(cls);
+    }
+
+    void maybeGenerateHolder(ClassElement cls) {
+      if (!needsHolder(cls)) return;
+
+      String holder = namer.isolateAccess(cls);
+      String name = namer.getName(cls);
+      buffer.add("$holder$_=$_{builtin\$cls:$_'$name'");
+      for (ClassElement check in typeChecks[cls]) {
+        buffer.add(',$_${namer.operatorIs(check)}:${_}true');
+      };
+      buffer.add('}$N');
+    }
+
+    // Create representation objects for classes that we do not have a class
+    // definition for (because they are uninstantiated or native).
+    for (ClassElement cls in rti.allArguments) {
+      maybeGenerateHolder(cls);
+    }
+
+    // Add checks to the constructors of instantiated classes.
+    for (ClassElement cls in typeChecks) {
+      if (needsHolder(cls)) {
+        // We already emitted the is-checks in the object definition for this
+        // class.
+        continue;
+      }
+      String holder = namer.isolateAccess(cls);
+      for (ClassElement check in typeChecks[cls]) {
+        buffer.add('$holder.${namer.operatorIs(check)}$_=${_}true$N');
+      };
+    }
+  }
+
   /**
    * Documentation wanted -- johnniwinther
    *
@@ -833,17 +879,17 @@
   }
 
   void generateGetter(Element member, String fieldName, String accessorName,
-                      CodeBuffer buffer) {      
+                      CodeBuffer buffer) {
     String getterName = namer.getterNameFromAccessorName(accessorName);
-    buffer.add("$getterName: function() { return this.$fieldName; }");    
-  }       
-  
+    buffer.add("$getterName: function() { return this.$fieldName; }");
+  }
+
   void generateSetter(Element member, String fieldName, String accessorName,
-                      CodeBuffer buffer) {      
+                      CodeBuffer buffer) {
     String setterName = namer.setterNameFromAccessorName(accessorName);
-    buffer.add("$setterName: function(v) { this.$fieldName = v; }");      
-  }       
-  
+    buffer.add("$setterName: function(v) { this.$fieldName = v; }");
+  }
+
   bool canGenerateCheckedSetter(Element member) {
     DartType type = member.computeType(compiler);
     if (type.element.isTypeVariable()
@@ -1043,7 +1089,6 @@
         parameters.add(new js.Parameter('value'));
         arguments.add(new js.VariableUse('value'));
       } else {
-        assert(selector.isCall() || selector.isOperator());
         name = backend.namer.instanceMethodInvocationName(
             selector.library, selector.name, selector);
         for (int i = 0; i < selector.argumentCount; i++) {
@@ -1067,6 +1112,14 @@
     }
   }
 
+  Collection<Element> getTypedefChecksOn(DartType type) {
+    return checkedTypedefs.filter((TypedefElement typedef) {
+      FunctionType typedefType =
+          typedef.computeType(compiler).unalias(compiler);
+      return compiler.types.isSubtype(type, typedefType);
+    });
+  }
+
   /**
    * Generate "is tests" for [cls]: itself, and the "is tests" for the
    * classes it implements. We don't need to add the "is tests" of the
@@ -1084,18 +1137,15 @@
     if (checkedClasses.contains(compiler.functionClass) ||
         !checkedTypedefs.isEmpty) {
       FunctionElement call = cls.lookupLocalMember(Compiler.CALL_OPERATOR_NAME);
+      if (call == null) {
+        // If [cls] is a closure, it has a synthetic call operator method.
+        call = cls.lookupBackendMember(Compiler.CALL_OPERATOR_NAME);
+      }
       if (call != null) {
         generateInterfacesIsTests(compiler.functionClass,
                                   emitIsTest,
                                   generated);
-        FunctionType callType = call.computeType(compiler);
-        for (TypedefElement typedef in checkedTypedefs) {
-          FunctionType typedefType =
-              typedef.computeType(compiler).unalias(compiler);
-          if (compiler.types.isSubtype(callType, typedefType)) {
-            emitIsTest(typedef);
-          }
-        }
+        getTypedefChecksOn(call.computeType(compiler)).forEach(emitIsTest);
       }
     }
     for (DartType interfaceType in cls.interfaces) {
@@ -1178,21 +1228,6 @@
     // Compute the required type checks to know which classes need a
     // 'is$' method.
     computeRequiredTypeChecks();
-
-    Set<ClassElement> instantiatedClasses =
-        compiler.codegenWorld.instantiatedClasses.filter(computeClassFilter());
-
-    Set<ClassElement> neededClasses =
-        new Set<ClassElement>.from(instantiatedClasses);
-
-    for (ClassElement element in instantiatedClasses) {
-      for (ClassElement superclass = element.superclass;
-           superclass != null;
-           superclass = superclass.superclass) {
-        if (neededClasses.contains(superclass)) break;
-        neededClasses.add(superclass);
-      }
-    }
     List<ClassElement> sortedClasses =
         new List<ClassElement>.from(neededClasses);
     sortedClasses.sort((ClassElement class1, ClassElement class2) {
@@ -1248,30 +1283,45 @@
     buffer.add(functionBuffer);
     buffer.add('$N$n');
   }
-  void emitStaticFunctionsWithNamer(CodeBuffer buffer,
-                                    Map<Element, CodeBuffer> generatedCode,
-                                    String functionNamer(Element element)) {
-    generatedCode.forEach((Element element, CodeBuffer functionBuffer) {
-      if (!element.isInstanceMember() && !element.isField()) {
-        emitStaticFunctionWithNamer(
-            buffer, element, functionBuffer,functionNamer);
-      }
-    });
-  }
 
   void emitStaticFunctions(CodeBuffer buffer) {
-    emitStaticFunctionsWithNamer(buffer,
-                                 compiler.codegenWorld.generatedCode,
-                                 namer.getName);
-    emitStaticFunctionsWithNamer(buffer,
-                                 compiler.codegenWorld.generatedBailoutCode,
-                                 namer.getBailoutName);
+    bool isStaticFunction(Element element) =>
+        !element.isInstanceMember() && !element.isField();
+
+    Collection<Element> elements =
+        compiler.codegenWorld.generatedCode.keys.filter(isStaticFunction);
+    Set<Element> pendingElementsWithBailouts =
+        new Set<Element>.from(
+            compiler.codegenWorld.generatedBailoutCode.keys.filter(
+                isStaticFunction));
+
+    for (Element element in Elements.sortedByPosition(elements)) {
+      CodeBuffer code = compiler.codegenWorld.generatedCode[element];
+      emitStaticFunctionWithNamer(buffer, element, code, namer.getName);
+      CodeBuffer bailoutCode =
+          compiler.codegenWorld.generatedBailoutCode[element];
+      if (bailoutCode != null) {
+        pendingElementsWithBailouts.remove(element);
+        emitStaticFunctionWithNamer(
+            buffer, element, bailoutCode, namer.getBailoutName);
+      }
+    }
+
+    // Is it possible the primary function was inlined but the bailout was not?
+    for (Element element in
+             Elements.sortedByPosition(pendingElementsWithBailouts)) {
+      CodeBuffer bailoutCode =
+          compiler.codegenWorld.generatedBailoutCode[element];
+      emitStaticFunctionWithNamer(
+          buffer, element, bailoutCode, namer.getBailoutName);
+    }
   }
 
   void emitStaticFunctionGetters(CodeBuffer buffer) {
     Set<FunctionElement> functionsNeedingGetter =
         compiler.codegenWorld.staticFunctionsNeedingGetter;
-    for (FunctionElement element in functionsNeedingGetter) {
+    for (FunctionElement element in
+             Elements.sortedByPosition(functionsNeedingGetter)) {
       // The static function does not have the correct name. Since
       // [addParameterStubs] use the name to create its stubs we simply
       // create a fake element with the correct name.
@@ -1290,6 +1340,12 @@
       // in case it is used in spawnFunction.
       String fieldName = namer.STATIC_CLOSURE_NAME_NAME;
       buffer.add('$fieldAccess.$fieldName$_=$_"$staticName"$N');
+      getTypedefChecksOn(element.computeType(compiler)).forEach(
+        (Element typedef) {
+          String operator = namer.operatorIs(typedef);
+          buffer.add('$fieldAccess.$operator$_=${_}true$N');
+        }
+      );
     }
   }
 
@@ -1351,7 +1407,13 @@
         : inInterceptor ? const ['self', 'target', 'receiver']
                         : const ['self', 'target'];
 
-    String closureClass = hasOptionalParameters ? null : cache[parameterCount];
+    Collection<Element> typedefChecks =
+        getTypedefChecksOn(member.computeType(compiler));
+    bool hasTypedefChecks = !typedefChecks.isEmpty;
+
+    bool canBeShared = !hasOptionalParameters && !hasTypedefChecks;
+
+    String closureClass = canBeShared ? cache[parameterCount] : null;
     if (closureClass == null) {
       // Either the class was not cached yet, or there are optional parameters.
       // Create a new closure class.
@@ -1403,12 +1465,18 @@
       addParameterStubs(callElement, (String stubName, CodeBuffer memberValue) {
         boundClosureBuffer.add(',\n$_$stubName:$_$memberValue');
       });
+
+      typedefChecks.forEach((Element typedef) {
+        String operator = namer.operatorIs(typedef);
+        boundClosureBuffer.add(',\n$_$operator$_:${_}true');
+      });
+
       boundClosureBuffer.add("$n}$N");
 
       closureClass = namer.isolateAccess(closureClassElement);
 
       // Cache it.
-      if (!hasOptionalParameters) {
+      if (canBeShared) {
         cache[parameterCount] = closureClass;
       }
     }
@@ -1672,8 +1740,7 @@
           selector.getOrderedNamedArguments().map((SourceString name) =>
               new js.LiteralString('"${name.slowToString()}"'));
 
-      String internalName = namer.instanceMethodInvocationName(
-          selector.library, new SourceString(methodName), selector);
+      String internalName = namer.invocationMirrorInternalName(selector);
 
       String createInvocationMirror = namer.getName(
           compiler.createInvocationMirrorElement);
@@ -1843,9 +1910,9 @@
     if (compiler.isMockCompilation) return;
     Element main = compiler.mainApp.find(Compiler.MAIN);
     String mainCall = null;
-    if (compiler.isolateLibrary != null) {
+    if (compiler.hasIsolateSupport()) {
       Element isolateMain =
-        compiler.isolateLibrary.find(Compiler.START_ROOT_ISOLATE);
+        compiler.isolateHelperLibrary.find(Compiler.START_ROOT_ISOLATE);
       mainCall = buildIsolateSetup(buffer, main, isolateMain);
     } else {
       mainCall = '${namer.isolateAccess(main)}()';
@@ -1887,32 +1954,129 @@
     }
   }
 
-  /**
-   * Emit the code for doing a type check on [cls]. [cls] must
-   * be an interceptor class.
-   */
-  void emitInterceptorCheck(ClassElement cls, CodeBuffer buffer) {
-    JavaScriptBackend backend = compiler.backend;
-    assert(backend.isInterceptorClass(cls));
-    if (cls == backend.jsBoolClass) {
-      buffer.add("if$_(typeof receiver$_==$_'boolean')");
-    } else if (cls == backend.jsIntClass) {
-      buffer.add("if$_(typeof receiver$_==$_'number'$_"
-                 "&&${_}Math.floor(receiver)$_==${_}receiver)");
-    } else if (cls == backend.jsDoubleClass || cls == backend.jsNumberClass) {
-      buffer.add("if$_(typeof receiver$_==$_'number')");
-    } else if (cls == backend.jsArrayClass) {
-      buffer.add("if$_(receiver$_!=${_}null$_&&$_"
-                 "receiver.constructor$_==${_}Array)");
-    } else if (cls == backend.jsStringClass) {
-      buffer.add("if$_(typeof receiver$_==$_'string')");
-    } else if (cls == backend.jsNullClass) {
-      buffer.add("if$_(receiver$_==${_}null)");
-    } else if (cls == backend.jsFunctionClass) {
-      buffer.add("if$_(typeof receiver$_==$_'function')");
+  void emitGetInterceptorMethod(CodeBuffer buffer,
+                                String objectName,
+                                String key,
+                                Collection<ClassElement> classes) {
+    js.Statement buildReturnInterceptor(ClassElement cls) {
+      return js.return_(js.fieldAccess(js.use(namer.isolateAccess(cls)),
+                                       'prototype'));
     }
-    buffer.add('${_}return ${namer.isolateAccess(cls)}.prototype');
-    if (!compiler.enableMinification) buffer.add(';');
+
+    js.VariableUse receiver = js.use('receiver');
+    JavaScriptBackend backend = compiler.backend;
+
+    /**
+     * Build a JavaScrit AST node for doing a type check on
+     * [cls]. [cls] must be an interceptor class.
+     */
+    js.Statement buildInterceptorCheck(ClassElement cls) {
+      js.Expression condition;
+      assert(backend.isInterceptorClass(cls));
+      if (cls == backend.jsBoolClass) {
+        condition = js.equals(js.typeOf(receiver), js.string('boolean'));
+      } else if (cls == backend.jsIntClass ||
+                 cls == backend.jsDoubleClass ||
+                 cls == backend.jsNumberClass) {
+        throw 'internal error';
+      } else if (cls == backend.jsArrayClass) {
+        condition = js.equals(js.fieldAccess(receiver, 'constructor'),
+                              js.use('Array'));
+      } else if (cls == backend.jsStringClass) {
+        condition = js.equals(js.typeOf(receiver), js.string('string'));
+      } else if (cls == backend.jsNullClass) {
+        condition = js.equals(receiver, new js.LiteralNull());
+      } else if (cls == backend.jsFunctionClass) {
+        condition = js.equals(js.typeOf(receiver), js.string('function'));
+      } else {
+        throw 'internal error';
+      }
+      return js.if_(condition, buildReturnInterceptor(cls));
+    }
+
+    bool hasArray = false;
+    bool hasBool = false;
+    bool hasDouble = false;
+    bool hasFunction = false;
+    bool hasInt = false;
+    bool hasNull = false;
+    bool hasNumber = false;
+    bool hasString = false;
+    for (ClassElement cls in classes) {
+      if (cls == backend.jsArrayClass) hasArray = true;
+      else if (cls == backend.jsBoolClass) hasBool = true;
+      else if (cls == backend.jsDoubleClass) hasDouble = true;
+      else if (cls == backend.jsFunctionClass) hasFunction = true;
+      else if (cls == backend.jsIntClass) hasInt = true;
+      else if (cls == backend.jsNullClass) hasNull = true;
+      else if (cls == backend.jsNumberClass) hasNumber = true;
+      else if (cls == backend.jsStringClass) hasString = true;
+      else throw 'Internal error: $cls';
+    }
+    if (hasDouble) {
+      assert(!hasNumber);
+      hasNumber = true;
+    }
+    if (hasInt) hasNumber = true;
+
+    js.Block block = new js.Block.empty();
+
+    if (hasNumber) {
+      js.Statement whenNumber;
+
+      /// Note: there are two number classes in play: Dart's [num],
+      /// and JavaScript's Number (typeof receiver == 'number').  This
+      /// is the fallback used when we have determined that receiver
+      /// is a JavaScript Number.
+      js.Return returnNumberClass = buildReturnInterceptor(
+          hasDouble ? backend.jsDoubleClass : backend.jsNumberClass);
+
+      if (hasInt) {
+        js.Expression isInt =
+            js.equals(js.call(js.fieldAccess(js.use('Math'), 'floor'),
+                              [receiver]),
+                      receiver);
+        (whenNumber = js.emptyBlock()).statements
+          ..add(js.if_(isInt, buildReturnInterceptor(backend.jsIntClass)))
+          ..add(returnNumberClass);
+      } else {
+        whenNumber = returnNumberClass;
+      }
+      block.statements.add(
+          js.if_(js.equals(js.typeOf(receiver), js.string('number')),
+                 whenNumber));
+    }
+
+    if (hasString) {
+      block.statements.add(buildInterceptorCheck(backend.jsStringClass));
+    }
+    if (hasNull) {
+      block.statements.add(buildInterceptorCheck(backend.jsNullClass));
+    } else {
+      // 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_(js.equals(receiver, new js.LiteralNull()),
+                                  js.return_(js.undefined())));
+    }
+    if (hasFunction) {
+      block.statements.add(buildInterceptorCheck(backend.jsFunctionClass));
+    }
+    if (hasBool) {
+      block.statements.add(buildInterceptorCheck(backend.jsBoolClass));
+    }
+    // TODO(ahe): It might be faster to check for Array before
+    // function and bool.
+    if (hasArray) {
+      block.statements.add(buildInterceptorCheck(backend.jsArrayClass));
+    }
+    block.statements.add(js.return_(js.fieldAccess(js.use(objectName),
+                                                   'prototype')));
+
+    js.PropertyAccess name = js.fieldAccess(js.use(isolateProperties), key);
+    buffer.add(js.prettyPrint(js.assign(name, js.fun(['receiver'], block)),
+                              compiler));
+    buffer.add(N);
   }
 
   /**
@@ -1925,19 +2089,28 @@
     String objectName = namer.isolateAccess(backend.objectInterceptorClass);
     backend.specializedGetInterceptors.forEach(
         (String key, Collection<ClassElement> classes) {
-          buffer.add('$isolateProperties.$key$_=${_}function(receiver)$_{');
-          for (ClassElement cls in classes) {
-            if (compiler.codegenWorld.instantiatedClasses.contains(cls)) {
-              buffer.add('\n$_$_');
-              emitInterceptorCheck(cls, buffer);
-            }
-          }
-          buffer.add('\n$_${_}return $objectName.prototype;$n}$N');
+          emitGetInterceptorMethod(buffer, objectName, key, classes);
         });
   }
 
+  void computeNeededClasses() {
+    instantiatedClasses =
+        compiler.codegenWorld.instantiatedClasses.filter(computeClassFilter());
+    neededClasses = new Set<ClassElement>.from(instantiatedClasses);
+    for (ClassElement element in instantiatedClasses) {
+      for (ClassElement superclass = element.superclass;
+          superclass != null;
+          superclass = superclass.superclass) {
+        if (neededClasses.contains(superclass)) break;
+        neededClasses.add(superclass);
+      }
+    }
+  }
+
   String assembleProgram() {
     measure(() {
+      computeNeededClasses();
+
       mainBuffer.add(GENERATED_BY);
       if (!compiler.enableMinification) mainBuffer.add(HOOKS_API_USAGE);
       mainBuffer.add('function ${namer.isolateName}()$_{}\n');
@@ -1958,6 +2131,7 @@
       // We need to finish the classes before we construct compile time
       // constants.
       emitFinishClassesInvocationIfNecessary(mainBuffer);
+      emitRuntimeClassesAndTests(mainBuffer);
       emitCompileTimeConstants(mainBuffer);
       // Static field initializations require the classes and compile-time
       // constants to be set up.
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 5d176c1..9a512d8 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/minify_namer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/minify_namer.dart
@@ -8,7 +8,9 @@
  * Assigns JavaScript identifiers to Dart variables, class-names and members.
  */
 class MinifyNamer extends Namer {
-  MinifyNamer(Compiler compiler) : super(compiler);
+  MinifyNamer(Compiler compiler) : super(compiler) {
+    reserveBackendNames();
+  }
 
   String get isolateName => 'I';
   String get isolatePropertiesName => 'p';
@@ -32,6 +34,15 @@
     return new SourceString("${getMappedInstanceName('closure')}_$id");
   }
 
+  void reserveBackendNames() {
+    for (var name in JsNames.reservedNativeProperties) {
+      if (name.length < 3) {
+        instanceNameMap[name] = name;
+      }
+      usedInstanceNames.add(name);
+    }
+  }
+
   // This gets a minified name based on a hash of the proposed name.  This
   // is slightly less efficient than just getting the next name in a series,
   // but it means that small changes in the input program will give smallish
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
index ba55f77..c55ed38 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
@@ -31,8 +31,8 @@
   final Map<String, LibraryElement> shortPrivateNameOwners;
   final Set<String> usedGlobalNames;
   final Set<String> usedInstanceNames;
-  final Map<String, String> instanceNameMap;
   final Map<String, String> globalNameMap;
+  final Map<String, String> instanceNameMap;
   final Map<String, int> popularNameCounters;
 
   /**
@@ -235,7 +235,7 @@
     // Check for following situation: Native field ${fieldElement.name} has
     // fixed JSName ${fieldElement.nativeName()}, but a subclass shadows this
     // name.  We normally handle that by renaming the superclass field, but we
-    // can't do that because native fields have fixed JSNames.  In practice
+    // can't do that because native fields have fixed JsNames.  In practice
     // this can't happen because we can't inherit from native classes.
     assert (!fieldElement.hasFixedBackendName());
 
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 1104974..84e57f1 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
@@ -110,30 +110,6 @@
 }""";
   }
 
-  void generateNativeLiteral(ClassElement classElement) {
-    String quotedNative = classElement.nativeTagInfo.slowToString();
-    String nativeCode = quotedNative.substring(2, quotedNative.length - 1);
-    String className = backend.namer.getName(classElement);
-    nativeBuffer.add(className);
-    nativeBuffer.add('$_=$_');
-    nativeBuffer.add(nativeCode);
-    nativeBuffer.add('$N');
-
-    void defineInstanceMember(String name, CodeBuffer value) {
-      nativeBuffer.add("$className.$name$_=$_$value$N");
-    }
-
-    classElement.implementation.forEachMember((_, Element member) {
-      if (member.isInstanceMember()) {
-        emitter.addInstanceMember(member, defineInstanceMember);
-      }
-    });
-  }
-
-  bool isNativeLiteral(String quotedName) {
-    return identical(quotedName[1], '=');
-  }
-
   bool isNativeGlobal(String quotedName) {
     return identical(quotedName[1], '@');
   }
@@ -153,12 +129,6 @@
 
     assert(classElement.backendMembers.isEmpty);
     String quotedName = classElement.nativeTagInfo.slowToString();
-    if (isNativeLiteral(quotedName)) {
-      generateNativeLiteral(classElement);
-      // The native literal kind needs to be dealt with specially when
-      // generating code for it.
-      return;
-    }
 
     CodeBuffer fieldBuffer = new CodeBuffer();
     CodeBuffer getterSetterBuffer = new CodeBuffer();
@@ -279,7 +249,7 @@
         new js.Return(
             new js.VariableUse('this').dot(target).callWith(arguments)));
 
-    if (isNativeLiteral(nativeTagInfo) || !overriddenMethods.contains(member)) {
+    if (!overriddenMethods.contains(member)) {
       // Call the method directly.
       return statements;
     } else {
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 564b457..2228998 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
@@ -4,11 +4,21 @@
 
 part of js_backend;
 
+/// For each class, stores the possible class subtype tests that could succeed.
+abstract class TypeChecks implements Iterable<ClassElement> {
+  /// Get the set of checks required for class [element].
+  Iterable<ClassElement> operator[](ClassElement element);
+}
+
 class RuntimeTypeInformation {
   final Compiler compiler;
 
   RuntimeTypeInformation(this.compiler);
 
+  /// Contains the classes of all arguments that have been used in
+  /// instantiations and checks.
+  Set<ClassElement> allArguments;
+
   bool isJsNative(Element element) {
     return (element == compiler.intClass ||
             element == compiler.boolClass ||
@@ -20,6 +30,60 @@
             element == compiler.dynamicClass);
   }
 
+  TypeChecks computeRequiredChecks() {
+    Set<ClassElement> instantiatedArguments = new Set<ClassElement>();
+    for (DartType type in compiler.codegenWorld.instantiatedTypes) {
+      addAllInterfaceTypeArguments(type, instantiatedArguments);
+    }
+
+    Set<ClassElement> checkedArguments = new Set<ClassElement>();
+    for (DartType type in compiler.enqueuer.codegen.universe.isChecks) {
+      addAllInterfaceTypeArguments(type, checkedArguments);
+    }
+
+    allArguments = new Set<ClassElement>.from(instantiatedArguments)
+        ..addAll(checkedArguments);
+
+    TypeCheckMapping requiredChecks = new TypeCheckMapping();
+    for (ClassElement element in instantiatedArguments) {
+      if (element == compiler.dynamicClass) continue;
+      if (checkedArguments.contains(element)) {
+        requiredChecks.add(element, element);
+      }
+      // Find all supertypes of [element] in [checkedArguments] and add checks.
+      for (DartType supertype in element.allSupertypes) {
+        ClassElement superelement = supertype.element;
+        if (checkedArguments.contains(superelement)) {
+          requiredChecks.add(element, superelement);
+        }
+      }
+    }
+
+    return requiredChecks;
+  }
+
+  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 && cls != compiler.objectClass) {
+          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;
@@ -31,20 +95,7 @@
   String getJsName(Element element) {
     JavaScriptBackend backend = compiler.backend;
     Namer namer = backend.namer;
-    if (element.isClass()) {
-      ClassElement cls = element;
-      // If the class is not instantiated, we will not generate code for it and
-      // thus cannot refer to its constructor. For now, use a string instead of
-      // a reference to the constructor.
-      // TODO(karlklose): remove this and record classes that we need only
-      // for runtime types and emit structures for them.
-      Universe universe = compiler.enqueuer.resolution.universe;
-      if (!universe.instantiatedClasses.contains(cls)) {
-        return "'${namer.isolateAccess(element)}'";
-      }
-    }
-   return isJsNative(element) ? "'${element.name.slowToString()}'"
-                               : namer.isolateAccess(element);
+    return namer.isolateAccess(element);
   }
 
   String getRawTypeRepresentation(DartType type) {
@@ -101,3 +152,20 @@
     }
   }
 }
+
+class TypeCheckMapping implements TypeChecks {
+  final Map<ClassElement, Set<ClassElement>> map =
+      new Map<ClassElement, Set<ClassElement>>();
+
+  Iterable<ClassElement> operator[](ClassElement element) {
+    Set<ClassElement> result = map[element];
+    return result != null ? result : const <ClassElement>[];
+  }
+
+  void add(ClassElement cls, ClassElement check) {
+    map.putIfAbsent(cls, () => new Set<ClassElement>());
+    map[cls].add(check);
+  }
+
+  Iterator<ClassElement> iterator() => map.keys.iterator();
+}
diff --git a/sdk/lib/_internal/compiler/implementation/lib/foreign_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/foreign_helper.dart
index 8e7db52..517fc86 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/foreign_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/foreign_helper.dart
@@ -4,7 +4,90 @@
 
 library _foreign_helper;
 
-dynamic JS(String typeDescription, String code,
+/**
+ * Emits a JavaScript code fragment parameterized by arguments.
+ *
+ * Hash characters `#` in the [codeTemplate] are replaced in left-to-right order
+ * with expressions that contain the values of, or evaluate to, the arguments.
+ * The number of hash marks must match the number or arguments.  Although
+ * declared with arguments [arg0] through [arg2], the form actually has no limit
+ * on the number of arguments.
+ *
+ * The [typeDescription] argument is interpreted as a description of the
+ * behavior of the JavaScript code.  Currently it describes the types that may
+ * be returned by the expression, with the additional behavior that the returned
+ * values may be fresh instances of the types.  The type information must be
+ * correct as it is trusted by the compiler in optimizations, and it must be
+ * precise as possible since it is used for native live type analysis to
+ * tree-shake large parts of the DOM libraries.  If poorly written, the
+ * [typeDescription] will cause unnecessarily bloated programs.  (You can check
+ * for this by compiling with `--verbose`; there is an info message describing
+ * the number of native (DOM) types that can be removed, which usually should be
+ * greater than zero.)
+ *
+ * The [typeDescription] is a [String] which contains a union of types separated
+ * by vertical bar `|` symbols, e.g.  `"num|String"` describes the union of
+ * numbers and Strings.  There is no type in Dart that is this precise.  The
+ * Dart alternative would be `Object` or `dynamic`, but these types imply that
+ * the JS-code might also be creating instances of all the DOM types.  The
+ * [typeDescription] has several extensions to help describe the behavior more
+ * accurately.  In addition to the union type already described:
+ *
+ *  + `=List` is the JavaScript array type.  This is more precise than `List`,
+ *     which includes about fifty DOM types that also implement the List
+ *     interface.
+ *
+ *  + `=Object` is a plain JavaScript object.  Some DOM methods return instances
+ *     that have no corresponing Dart type (e.g. cross-frame documents),
+ *     `=Object` can be used to describe these untyped' values.
+ *
+ *  + `var`.  If the entire [typeDescription] is `var` then the type is
+ *    `dynamic` but the code is known to not create any instances.
+ *
+ * Examples:
+ *
+ *     // Create a JavaScript Array.
+ *     List a = JS('=List', 'new Array(#)', length);
+ *
+ *     // Parent window might be an opaque cross-frame window.
+ *     var thing = JS('=Object|Window', '#.parent', myWindow);
+ *
+ * Guidelines:
+ *
+ *  + Do not use any parameter, local, method or field names in the
+ *    [codeTemplate].  These names are all subject to arbitrary renaming by the
+ *    compiler.  Pass the values in via `#` substition, and test with the
+ *    `--minify` dart2js command-line option.
+ *
+ *  + The substituted expressions are values, not locations.
+ *
+ *        JS('void', '# += "x"', this.field);
+ *
+ *    `this.field` might not be a substituted as a reference to the field.  The
+ *    generated code might accidentally work as intended, but it also might be
+ *
+ *        var t1 = this.field;
+ *        t1 += "x";
+ *
+ *    or
+ *
+ *        this.get$field() += "x";
+ *
+ *    The remedy in this case is to expand the `+=` operator, leaving all
+ *    references to the Dart field as Dart code:
+ *
+ *        this.field = JS('String', '# + "x"', this.field);
+ *
+ *
+ * Additional notes.
+ *
+ * In the future we may extend [typeDescription] to include other aspects of the
+ * behavior, for example, separating the returned types from the instantiated
+ * types, or including effects to allow the compiler to perform more
+ * optimizations around the code.  This might be an extension of [JS] or a new
+ * function similar to [JS] with additional arguments for the new information.
+ */
+dynamic JS(String typeDescription, String codeTemplate,
     [var arg0, var arg1, var arg2]) {}
 
 /**
diff --git a/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart
index dd17e1b..6710c02 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart
@@ -27,6 +27,9 @@
   patch static _rename(String path, String newPath) {
     throw new UnsupportedError("Directory._rename");
   }
+  patch static List _list(String path, bool recursive) {
+    throw new UnsupportedError("Directory._list");
+  }
   patch static SendPort _newServicePort() {
     throw new UnsupportedError("Directory._newServicePort");
   }
@@ -144,6 +147,9 @@
   patch static _exit(int status) {
     throw new UnsupportedError("ProcessUtils._exit");
   }
+  patch static _setExitCode(int status) {
+    throw new UnsupportedError("ProcessUtils._setExitCode");
+  }
 }
 
 patch class Process {
diff --git a/sdk/lib/_internal/compiler/implementation/lib/isolate_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/isolate_helper.dart
new file mode 100644
index 0000000..21f71d1
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/lib/isolate_helper.dart
@@ -0,0 +1,1248 @@
+// 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 _isolate_helper;
+
+import 'dart:isolate';
+
+/**
+ * Called by the compiler to support switching
+ * between isolates when we get a callback from the DOM.
+ */
+void _callInIsolate(_IsolateContext isolate, Function function) {
+  isolate.eval(function);
+  _globalState.topEventLoop.run();
+}
+
+/**
+ * Called by the compiler to fetch the current isolate context.
+ */
+_IsolateContext _currentIsolate() => _globalState.currentContext;
+
+/********************************************************
+  Inserted from lib/isolate/dart2js/compiler_hooks.dart
+ ********************************************************/
+
+/**
+ * Wrapper that takes the dart entry point and runs it within an isolate. The
+ * dart2js compiler will inject a call of the form
+ * [: startRootIsolate(main); :] when it determines that this wrapping
+ * is needed. For single-isolate applications (e.g. hello world), this
+ * call is not emitted.
+ */
+void startRootIsolate(entry) {
+  _globalState = new _Manager();
+
+  // Don't start the main loop again, if we are in a worker.
+  if (_globalState.isWorker) return;
+  final rootContext = new _IsolateContext();
+  _globalState.rootContext = rootContext;
+  _fillStatics(rootContext);
+
+  // BUG(5151491): Setting currentContext should not be necessary, but
+  // because closures passed to the DOM as event handlers do not bind their
+  // isolate automatically we try to give them a reasonable context to live in
+  // by having a "default" isolate (the first one created).
+  _globalState.currentContext = rootContext;
+
+  rootContext.eval(entry);
+  _globalState.topEventLoop.run();
+}
+
+/********************************************************
+  Inserted from lib/isolate/dart2js/isolateimpl.dart
+ ********************************************************/
+
+/**
+ * Concepts used here:
+ *
+ * "manager" - A manager contains one or more isolates, schedules their
+ * execution, and performs other plumbing on their behalf.  The isolate
+ * present at the creation of the manager is designated as its "root isolate".
+ * A manager may, for example, be implemented on a web Worker.
+ *
+ * [_Manager] - State present within a manager (exactly once, as a global).
+ *
+ * [_ManagerStub] - A handle held within one manager that allows interaction
+ * with another manager.  A target manager may be addressed by zero or more
+ * [_ManagerStub]s.
+ *
+ */
+
+/**
+ * A native object that is shared across isolates. This object is visible to all
+ * isolates running under the same manager (either UI or background web worker).
+ *
+ * This is code that is intended to 'escape' the isolate boundaries in order to
+ * implement the semantics of isolates in JavaScript. Without this we would have
+ * been forced to implement more code (including the top-level event loop) in
+ * JavaScript itself.
+ */
+// TODO(eub, sigmund): move the "manager" to be entirely in JS.
+// Running any Dart code outside the context of an isolate gives it
+// the change to break the isolate abstraction.
+_Manager get _globalState => JS("_Manager", r"$globalState");
+set _globalState(_Manager val) {
+  JS("void", r"$globalState = #", val);
+}
+
+void _fillStatics(context) {
+  JS("void", r"$globals = #.isolateStatics", context);
+  JS("void", r"$static_init()");
+}
+
+ReceivePort lazyPort;
+
+/** State associated with the current manager. See [globalState]. */
+// TODO(sigmund): split in multiple classes: global, thread, main-worker states?
+class _Manager {
+
+  /** Next available isolate id within this [_Manager]. */
+  int nextIsolateId = 0;
+
+  /** id assigned to this [_Manager]. */
+  int currentManagerId = 0;
+
+  /**
+   * Next available manager id. Only used by the main manager to assign a unique
+   * id to each manager created by it.
+   */
+  int nextManagerId = 1;
+
+  /** Context for the currently running [Isolate]. */
+  _IsolateContext currentContext = null;
+
+  /** Context for the root [Isolate] that first run in this [_Manager]. */
+  _IsolateContext rootContext = null;
+
+  /** The top-level event loop. */
+  _EventLoop topEventLoop;
+
+  /** Whether this program is running from the command line. */
+  bool fromCommandLine;
+
+  /** Whether this [_Manager] is running as a web worker. */
+  bool isWorker;
+
+  /** Whether we support spawning web workers. */
+  bool supportsWorkers;
+
+  /**
+   * Whether to use web workers when implementing isolates. Set to false for
+   * debugging/testing.
+   */
+  bool get useWorkers => supportsWorkers;
+
+  /**
+   * Whether to use the web-worker JSON-based message serialization protocol. By
+   * default this is only used with web workers. For debugging, you can force
+   * using this protocol by changing this field value to [true].
+   */
+  bool get needSerialization => useWorkers;
+
+  /**
+   * Registry of isolates. Isolates must be registered if, and only if, receive
+   * ports are alive.  Normally no open receive-ports means that the isolate is
+   * dead, but DOM callbacks could resurrect it.
+   */
+  Map<int, _IsolateContext> isolates;
+
+  /** Reference to the main [_Manager].  Null in the main [_Manager] itself. */
+  _ManagerStub mainManager;
+
+  /** Registry of active [_ManagerStub]s.  Only used in the main [_Manager]. */
+  Map<int, _ManagerStub> managers;
+
+  _Manager() {
+    _nativeDetectEnvironment();
+    topEventLoop = new _EventLoop();
+    isolates = new Map<int, _IsolateContext>();
+    managers = new Map<int, _ManagerStub>();
+    if (isWorker) {  // "if we are not the main manager ourself" is the intent.
+      mainManager = new _MainManagerStub();
+      _nativeInitWorkerMessageHandler();
+    }
+  }
+
+  void _nativeDetectEnvironment() {
+    isWorker = JS("bool", r"$isWorker");
+    supportsWorkers = JS("bool", r"$supportsWorkers");
+    fromCommandLine = JS("bool", r"typeof(window) == 'undefined'");
+  }
+
+  void _nativeInitWorkerMessageHandler() {
+    JS("void", r"""
+$globalThis.onmessage = function (e) {
+  IsolateNatives._processWorkerMessage(this.mainManager, e);
+}""");
+  }
+  /*: TODO: check that _processWorkerMessage is not discarded while treeshaking.
+  """ {
+    IsolateNatives._processWorkerMessage(null, null);
+  }
+  */
+
+
+  /** Close the worker running this code if all isolates are done. */
+  void maybeCloseWorker() {
+    if (isolates.isEmpty) {
+      mainManager.postMessage(_serializeMessage({'command': 'close'}));
+    }
+  }
+}
+
+/** Context information tracked for each isolate. */
+class _IsolateContext {
+  /** Current isolate id. */
+  int id;
+
+  /** Registry of receive ports currently active on this isolate. */
+  Map<int, ReceivePort> ports;
+
+  /** Holds isolate globals (statics and top-level properties). */
+  var isolateStatics; // native object containing all globals of an isolate.
+
+  _IsolateContext() {
+    id = _globalState.nextIsolateId++;
+    ports = new Map<int, ReceivePort>();
+    initGlobals();
+  }
+
+  // these are filled lazily the first time the isolate starts running.
+  void initGlobals() { JS("void", r'$initGlobals(#)', this); }
+
+  /**
+   * Run [code] in the context of the isolate represented by [this]. Note this
+   * is called from JavaScript (see $wrap_call in corejs.dart).
+   */
+  dynamic eval(Function code) {
+    var old = _globalState.currentContext;
+    _globalState.currentContext = this;
+    this._setGlobals();
+    var result = null;
+    try {
+      result = code();
+    } finally {
+      _globalState.currentContext = old;
+      if (old != null) old._setGlobals();
+    }
+    return result;
+  }
+
+  void _setGlobals() { JS("void", r'$setGlobals(#)', this); }
+
+  /** Lookup a port registered for this isolate. */
+  ReceivePort lookup(int portId) => ports[portId];
+
+  /** Register a port on this isolate. */
+  void register(int portId, ReceivePort port)  {
+    if (ports.containsKey(portId)) {
+      throw new Exception("Registry: ports must be registered only once.");
+    }
+    ports[portId] = port;
+    _globalState.isolates[id] = this; // indicate this isolate is active
+  }
+
+  /** Unregister a port on this isolate. */
+  void unregister(int portId) {
+    ports.remove(portId);
+    if (ports.isEmpty) {
+      _globalState.isolates.remove(id); // indicate this isolate is not active
+    }
+  }
+}
+
+/** Represent the event loop on a javascript thread (DOM or worker). */
+class _EventLoop {
+  Queue<_IsolateEvent> events;
+
+  _EventLoop() : events = new Queue<_IsolateEvent>();
+
+  void enqueue(isolate, fn, msg) {
+    events.addLast(new _IsolateEvent(isolate, fn, msg));
+  }
+
+  _IsolateEvent dequeue() {
+    if (events.isEmpty) return null;
+    return events.removeFirst();
+  }
+
+  /** Process a single event, if any. */
+  bool runIteration() {
+    final event = dequeue();
+    if (event == null) {
+      if (_globalState.isWorker) {
+        _globalState.maybeCloseWorker();
+      } else if (_globalState.rootContext != null &&
+                 _globalState.isolates.containsKey(
+                     _globalState.rootContext.id) &&
+                 _globalState.fromCommandLine &&
+                 _globalState.rootContext.ports.isEmpty) {
+        // We want to reach here only on the main [_Manager] and only
+        // on the command-line.  In the browser the isolate might
+        // still be alive due to DOM callbacks, but the presumption is
+        // that on the command-line, no future events can be injected
+        // into the event queue once it's empty.  Node has setTimeout
+        // so this presumption is incorrect there.  We think(?) that
+        // in d8 this assumption is valid.
+        throw new Exception("Program exited with open ReceivePorts.");
+      }
+      return false;
+    }
+    event.process();
+    return true;
+  }
+
+  /**
+   * Runs multiple iterations of the run-loop. If possible, each iteration is
+   * run asynchronously.
+   */
+  void _runHelper() {
+    if (JS('String', 'typeof window') != 'undefined') {
+      // Run each iteration from the browser's top event loop.
+      void next() {
+        if (!runIteration()) return;
+        JS('void', 'window.setTimeout(#, 0)', convertDartClosureToJS(next, 0));
+      }
+      next();
+    } else {
+      // Run synchronously until no more iterations are available.
+      while (runIteration()) {}
+    }
+  }
+
+  /**
+   * Call [_runHelper] but ensure that worker exceptions are propragated. Note
+   * this is called from JavaScript (see $wrap_call in corejs.dart).
+   */
+  void run() {
+    if (!_globalState.isWorker) {
+      _runHelper();
+    } else {
+      try {
+        _runHelper();
+      } catch (e, trace) {
+        _globalState.mainManager.postMessage(_serializeMessage(
+            {'command': 'error', 'msg': '$e\n$trace' }));
+      }
+    }
+  }
+}
+
+/** An event in the top-level event queue. */
+class _IsolateEvent {
+  _IsolateContext isolate;
+  Function fn;
+  String message;
+
+  _IsolateEvent(this.isolate, this.fn, this.message);
+
+  void process() {
+    isolate.eval(fn);
+  }
+}
+
+/** An interface for a stub used to interact with a manager. */
+abstract class _ManagerStub {
+  get id;
+  void set id(int i);
+  void set onmessage(Function f);
+  void postMessage(msg);
+  void terminate();
+}
+
+/** A stub for interacting with the main manager. */
+class _MainManagerStub implements _ManagerStub {
+  get id => 0;
+  void set id(int i) { throw new UnimplementedError(); }
+  void set onmessage(f) {
+    throw new Exception("onmessage should not be set on MainManagerStub");
+  }
+  void postMessage(msg) { JS("void", r"$globalThis.postMessage(#)", msg); }
+  void terminate() {}  // Nothing useful to do here.
+}
+
+/**
+ * A stub for interacting with a manager built on a web worker. This
+ * definition uses a 'hidden' type (* prefix on the native name) to
+ * enforce that the type is defined dynamically only when web workers
+ * are actually available.
+ */
+// TODO(ngeoffray): We comment this annotation for now because the
+// native feature uses a keyword that this file does not have access
+// to. We should remove the comment once the native feature uses
+// annotations.
+// @Native("*Worker");
+class _WorkerStub implements _ManagerStub {
+  get id => JS("var", "#.id", this);
+  void set id(i) { JS("void", "#.id = #", this, i); }
+  void set onmessage(f) { JS("void", "#.onmessage = #", this, f); }
+  void postMessage(msg) => JS("void", "#.postMessage(#)", this, msg);
+  // terminate() is implemented by Worker.
+  void terminate();
+}
+
+const String _SPAWNED_SIGNAL = "spawned";
+
+var globalThis = JS('', 'function() { return this; }()');
+
+class IsolateNatives {
+
+  /**
+   * The src url for the script tag that loaded this code. Used to create
+   * JavaScript workers.
+   */
+  static String get _thisScript => JS("String", r"$thisScriptUrl");
+
+  /** Starts a new worker with the given URL. */
+  static _WorkerStub _newWorker(url) => JS("_WorkerStub", r"new Worker(#)", url);
+
+  /**
+   * Assume that [e] is a browser message event and extract its message data.
+   * We don't import the dom explicitly so, when workers are disabled, this
+   * library can also run on top of nodejs.
+   */
+  //static _getEventData(e) => JS("Object", "#.data", e);
+  static _getEventData(e) => JS("", "#.data", e);
+
+  /**
+   * Process messages on a worker, either to control the worker instance or to
+   * pass messages along to the isolate running in the worker.
+   */
+  static void _processWorkerMessage(sender, e) {
+    var msg = _deserializeMessage(_getEventData(e));
+    switch (msg['command']) {
+      case 'start':
+        _globalState.currentManagerId = msg['id'];
+        Function entryPoint = _getJSFunctionFromName(msg['functionName']);
+        var replyTo = _deserializeMessage(msg['replyTo']);
+        _globalState.topEventLoop.enqueue(new _IsolateContext(), function() {
+          _startIsolate(entryPoint, replyTo);
+        }, 'worker-start');
+        _globalState.topEventLoop.run();
+        break;
+      case 'spawn-worker':
+        _spawnWorker(msg['functionName'], msg['uri'], msg['replyPort']);
+        break;
+      case 'message':
+        msg['port'].send(msg['msg'], msg['replyTo']);
+        _globalState.topEventLoop.run();
+        break;
+      case 'close':
+        _log("Closing Worker");
+        _globalState.managers.remove(sender.id);
+        sender.terminate();
+        _globalState.topEventLoop.run();
+        break;
+      case 'log':
+        _log(msg['msg']);
+        break;
+      case 'print':
+        if (_globalState.isWorker) {
+          _globalState.mainManager.postMessage(
+              _serializeMessage({'command': 'print', 'msg': msg}));
+        } else {
+          print(msg['msg']);
+        }
+        break;
+      case 'error':
+        throw msg['msg'];
+    }
+  }
+
+  /** Log a message, forwarding to the main [_Manager] if appropriate. */
+  static _log(msg) {
+    if (_globalState.isWorker) {
+      _globalState.mainManager.postMessage(
+          _serializeMessage({'command': 'log', 'msg': msg }));
+    } else {
+      try {
+        _consoleLog(msg);
+      } catch (e, trace) {
+        throw new Exception(trace);
+      }
+    }
+  }
+
+  static void _consoleLog(msg) {
+    JS("void", r"$globalThis.console.log(#)", msg);
+  }
+
+  /**
+   * Extract the constructor of runnable, so it can be allocated in another
+   * isolate.
+   */
+  static dynamic _getJSConstructor(Isolate runnable) {
+    return JS("Object", "#.constructor", runnable);
+  }
+
+  /** Extract the constructor name of a runnable */
+  // TODO(sigmund): find a browser-generic way to support this.
+  // TODO(floitsch): is this function still used? If yes, should we use
+  // Primitives.objectTypeName instead?
+  static dynamic _getJSConstructorName(Isolate runnable) {
+    return JS("Object", "#.constructor.name", runnable);
+  }
+
+  /** Find a constructor given its name. */
+  static dynamic _getJSConstructorFromName(String factoryName) {
+    return JS("Object", r"$globalThis[#]", factoryName);
+  }
+
+  static dynamic _getJSFunctionFromName(String functionName) {
+    return JS("Object", r"$globalThis[#]", functionName);
+  }
+
+  /**
+   * Get a string name for the function, if possible.  The result for
+   * anonymous functions is browser-dependent -- it may be "" or "anonymous"
+   * but you should probably not count on this.
+   */
+  static String _getJSFunctionName(Function f) {
+    return JS("Object", r"(#.$name || #)", f, null);
+  }
+
+  /** Create a new JavaScript object instance given its constructor. */
+  static dynamic _allocate(var ctor) {
+    return JS("Object", "new #()", ctor);
+  }
+
+  static SendPort spawnFunction(void topLevelFunction()) {
+    final name = _getJSFunctionName(topLevelFunction);
+    if (name == null) {
+      throw new UnsupportedError(
+          "only top-level functions can be spawned.");
+    }
+    return spawn(name, null, false);
+  }
+
+  // TODO(sigmund): clean up above, after we make the new API the default:
+
+  static SendPort spawn(String functionName, String uri, bool isLight) {
+    Completer<SendPort> completer = new Completer<SendPort>();
+    ReceivePort port = new ReceivePort();
+    port.receive((msg, SendPort replyPort) {
+      port.close();
+      assert(msg == _SPAWNED_SIGNAL);
+      completer.complete(replyPort);
+    });
+
+    SendPort signalReply = port.toSendPort();
+
+    if (_globalState.useWorkers && !isLight) {
+      _startWorker(functionName, uri, signalReply);
+    } else {
+      _startNonWorker(functionName, uri, signalReply);
+    }
+    return new _BufferingSendPort(
+        _globalState.currentContext.id, completer.future);
+  }
+
+  static SendPort _startWorker(
+      String functionName, String uri, SendPort replyPort) {
+    if (_globalState.isWorker) {
+      _globalState.mainManager.postMessage(_serializeMessage({
+          'command': 'spawn-worker',
+          'functionName': functionName,
+          'uri': uri,
+          'replyPort': replyPort}));
+    } else {
+      _spawnWorker(functionName, uri, replyPort);
+    }
+  }
+
+  static SendPort _startNonWorker(
+      String functionName, String uri, SendPort replyPort) {
+    // TODO(eub): support IE9 using an iframe -- Dart issue 1702.
+    if (uri != null) throw new UnsupportedError(
+            "Currently spawnUri is not supported without web workers.");
+    _globalState.topEventLoop.enqueue(new _IsolateContext(), function() {
+      final func = _getJSFunctionFromName(functionName);
+      _startIsolate(func, replyPort);
+    }, 'nonworker start');
+  }
+
+  static void _startIsolate(Function topLevel, SendPort replyTo) {
+    _fillStatics(_globalState.currentContext);
+    lazyPort = new ReceivePort();
+    replyTo.send(_SPAWNED_SIGNAL, port.toSendPort());
+
+    topLevel();
+  }
+
+  /**
+   * Spawns an isolate in a worker. [factoryName] is the Javascript constructor
+   * name for the isolate entry point class.
+   */
+  static void _spawnWorker(functionName, uri, replyPort) {
+    if (functionName == null) functionName = 'main';
+    if (uri == null) uri = _thisScript;
+    final worker = _newWorker(uri);
+    worker.onmessage = (e) { _processWorkerMessage(worker, e); };
+    var workerId = _globalState.nextManagerId++;
+    // We also store the id on the worker itself so that we can unregister it.
+    worker.id = workerId;
+    _globalState.managers[workerId] = worker;
+    worker.postMessage(_serializeMessage({
+      'command': 'start',
+      'id': workerId,
+      // Note: we serialize replyPort twice because the child worker needs to
+      // first deserialize the worker id, before it can correctly deserialize
+      // the port (port deserialization is sensitive to what is the current
+      // workerId).
+      'replyTo': _serializeMessage(replyPort),
+      'functionName': functionName }));
+  }
+}
+
+/********************************************************
+  Inserted from lib/isolate/dart2js/ports.dart
+ ********************************************************/
+
+/** Common functionality to all send ports. */
+class _BaseSendPort implements SendPort {
+  /** Id for the destination isolate. */
+  final int _isolateId;
+
+  const _BaseSendPort(this._isolateId);
+
+  void _checkReplyTo(SendPort replyTo) {
+    if (replyTo != null
+        && replyTo is! _NativeJsSendPort
+        && replyTo is! _WorkerSendPort
+        && replyTo is! _BufferingSendPort) {
+      throw new Exception("SendPort.send: Illegal replyTo port type");
+    }
+  }
+
+  Future call(var message) {
+    final completer = new Completer();
+    final port = new ReceivePortImpl();
+    send(message, port.toSendPort());
+    port.receive((value, ignoreReplyTo) {
+      port.close();
+      if (value is Exception) {
+        completer.completeException(value);
+      } else {
+        completer.complete(value);
+      }
+    });
+    return completer.future;
+  }
+
+  void send(var message, [SendPort replyTo]);
+  bool operator ==(var other);
+  int get hashCode;
+}
+
+/** A send port that delivers messages in-memory via native JavaScript calls. */
+class _NativeJsSendPort extends _BaseSendPort implements SendPort {
+  final ReceivePortImpl _receivePort;
+
+  const _NativeJsSendPort(this._receivePort, int isolateId) : super(isolateId);
+
+  void send(var message, [SendPort replyTo = null]) {
+    _waitForPendingPorts([message, replyTo], () {
+      _checkReplyTo(replyTo);
+      // Check that the isolate still runs and the port is still open
+      final isolate = _globalState.isolates[_isolateId];
+      if (isolate == null) return;
+      if (_receivePort._callback == null) return;
+
+      // We force serialization/deserialization as a simple way to ensure
+      // isolate communication restrictions are respected between isolates that
+      // live in the same worker. [_NativeJsSendPort] delivers both messages
+      // from the same worker and messages from other workers. In particular,
+      // messages sent from a worker via a [_WorkerSendPort] are received at
+      // [_processWorkerMessage] and forwarded to a native port. In such cases,
+      // here we'll see [_globalState.currentContext == null].
+      final shouldSerialize = _globalState.currentContext != null
+          && _globalState.currentContext.id != _isolateId;
+      var msg = message;
+      var reply = replyTo;
+      if (shouldSerialize) {
+        msg = _serializeMessage(msg);
+        reply = _serializeMessage(reply);
+      }
+      _globalState.topEventLoop.enqueue(isolate, () {
+        if (_receivePort._callback != null) {
+          if (shouldSerialize) {
+            msg = _deserializeMessage(msg);
+            reply = _deserializeMessage(reply);
+          }
+          _receivePort._callback(msg, reply);
+        }
+      }, 'receive $message');
+    });
+  }
+
+  bool operator ==(var other) => (other is _NativeJsSendPort) &&
+      (_receivePort == other._receivePort);
+
+  int get hashCode => _receivePort._id;
+}
+
+/** A send port that delivers messages via worker.postMessage. */
+// TODO(eub): abstract this for iframes.
+class _WorkerSendPort extends _BaseSendPort implements SendPort {
+  final int _workerId;
+  final int _receivePortId;
+
+  const _WorkerSendPort(this._workerId, int isolateId, this._receivePortId)
+      : super(isolateId);
+
+  void send(var message, [SendPort replyTo = null]) {
+    _waitForPendingPorts([message, replyTo], () {
+      _checkReplyTo(replyTo);
+      final workerMessage = _serializeMessage({
+          'command': 'message',
+          'port': this,
+          'msg': message,
+          'replyTo': replyTo});
+
+      if (_globalState.isWorker) {
+        // communication from one worker to another go through the main worker:
+        _globalState.mainManager.postMessage(workerMessage);
+      } else {
+        _globalState.managers[_workerId].postMessage(workerMessage);
+      }
+    });
+  }
+
+  bool operator ==(var other) {
+    return (other is _WorkerSendPort) &&
+        (_workerId == other._workerId) &&
+        (_isolateId == other._isolateId) &&
+        (_receivePortId == other._receivePortId);
+  }
+
+  int get hashCode {
+    // TODO(sigmund): use a standard hash when we get one available in corelib.
+    return (_workerId << 16) ^ (_isolateId << 8) ^ _receivePortId;
+  }
+}
+
+/** A port that buffers messages until an underlying port gets resolved. */
+class _BufferingSendPort extends _BaseSendPort implements SendPort {
+  /** Internal counter to assign unique ids to each port. */
+  static int _idCount = 0;
+
+  /** For implementing equals and hashcode. */
+  final int _id;
+
+  /** Underlying port, when resolved. */
+  SendPort _port;
+
+  /**
+   * Future of the underlying port, so that we can detect when this port can be
+   * sent on messages.
+   */
+  Future<SendPort> _futurePort;
+
+  /** Pending messages (and reply ports). */
+  List pending;
+
+  _BufferingSendPort(isolateId, this._futurePort)
+      : super(isolateId), _id = _idCount, pending = [] {
+    _idCount++;
+    _futurePort.then((p) {
+      _port = p;
+      for (final item in pending) {
+        p.send(item['message'], item['replyTo']);
+      }
+      pending = null;
+    });
+  }
+
+  _BufferingSendPort.fromPort(isolateId, this._port)
+      : super(isolateId), _id = _idCount {
+    _idCount++;
+  }
+
+  void send(var message, [SendPort replyTo]) {
+    if (_port != null) {
+      _port.send(message, replyTo);
+    } else {
+      pending.add({'message': message, 'replyTo': replyTo});
+    }
+  }
+
+  bool operator ==(var other) =>
+      other is _BufferingSendPort && _id == other._id;
+  int get hashCode => _id;
+}
+
+/** Implementation of a multi-use [ReceivePort] on top of JavaScript. */
+class ReceivePortImpl implements ReceivePort {
+  int _id;
+  Function _callback;
+  static int _nextFreeId = 1;
+
+  ReceivePortImpl()
+      : _id = _nextFreeId++ {
+    _globalState.currentContext.register(_id, this);
+  }
+
+  void receive(void onMessage(var message, SendPort replyTo)) {
+    _callback = onMessage;
+  }
+
+  void close() {
+    _callback = null;
+    _globalState.currentContext.unregister(_id);
+  }
+
+  SendPort toSendPort() {
+    return new _NativeJsSendPort(this, _globalState.currentContext.id);
+  }
+}
+
+/** Wait until all ports in a message are resolved. */
+_waitForPendingPorts(var message, void callback()) {
+  final finder = new _PendingSendPortFinder();
+  finder.traverse(message);
+  Futures.wait(finder.ports).then((_) => callback());
+}
+
+
+/** Visitor that finds all unresolved [SendPort]s in a message. */
+class _PendingSendPortFinder extends _MessageTraverser {
+  List<Future<SendPort>> ports;
+  _PendingSendPortFinder() : super(), ports = [] {
+    _visited = new _JsVisitedMap();
+  }
+
+  visitPrimitive(x) {}
+
+  visitList(List list) {
+    final seen = _visited[list];
+    if (seen != null) return;
+    _visited[list] = true;
+    // TODO(sigmund): replace with the following: (bug #1660)
+    // list.forEach(_dispatch);
+    list.forEach((e) => _dispatch(e));
+  }
+
+  visitMap(Map map) {
+    final seen = _visited[map];
+    if (seen != null) return;
+
+    _visited[map] = true;
+    // TODO(sigmund): replace with the following: (bug #1660)
+    // map.values.forEach(_dispatch);
+    map.values.forEach((e) => _dispatch(e));
+  }
+
+  visitSendPort(SendPort port) {
+    if (port is _BufferingSendPort && port._port == null) {
+      ports.add(port._futurePort);
+    }
+  }
+}
+
+/********************************************************
+  Inserted from lib/isolate/dart2js/messages.dart
+ ********************************************************/
+
+// Defines message visitors, serialization, and deserialization.
+
+/** Serialize [message] (or simulate serialization). */
+_serializeMessage(message) {
+  if (_globalState.needSerialization) {
+    return new _JsSerializer().traverse(message);
+  } else {
+    return new _JsCopier().traverse(message);
+  }
+}
+
+/** Deserialize [message] (or simulate deserialization). */
+_deserializeMessage(message) {
+  if (_globalState.needSerialization) {
+    return new _JsDeserializer().deserialize(message);
+  } else {
+    // Nothing more to do.
+    return message;
+  }
+}
+
+class _JsSerializer extends _Serializer {
+
+  _JsSerializer() : super() { _visited = new _JsVisitedMap(); }
+
+  visitSendPort(SendPort x) {
+    if (x is _NativeJsSendPort) return visitNativeJsSendPort(x);
+    if (x is _WorkerSendPort) return visitWorkerSendPort(x);
+    if (x is _BufferingSendPort) return visitBufferingSendPort(x);
+    throw "Illegal underlying port $x";
+  }
+
+  visitNativeJsSendPort(_NativeJsSendPort port) {
+    return ['sendport', _globalState.currentManagerId,
+        port._isolateId, port._receivePort._id];
+  }
+
+  visitWorkerSendPort(_WorkerSendPort port) {
+    return ['sendport', port._workerId, port._isolateId, port._receivePortId];
+  }
+
+  visitBufferingSendPort(_BufferingSendPort port) {
+    if (port._port != null) {
+      return visitSendPort(port._port);
+    } else {
+      // TODO(floitsch): Use real exception (which one?).
+      throw
+          "internal error: must call _waitForPendingPorts to ensure all"
+          " ports are resolved at this point.";
+    }
+  }
+
+}
+
+
+class _JsCopier extends _Copier {
+
+  _JsCopier() : super() { _visited = new _JsVisitedMap(); }
+
+  visitSendPort(SendPort x) {
+    if (x is _NativeJsSendPort) return visitNativeJsSendPort(x);
+    if (x is _WorkerSendPort) return visitWorkerSendPort(x);
+    if (x is _BufferingSendPort) return visitBufferingSendPort(x);
+    throw "Illegal underlying port $p";
+  }
+
+  SendPort visitNativeJsSendPort(_NativeJsSendPort port) {
+    return new _NativeJsSendPort(port._receivePort, port._isolateId);
+  }
+
+  SendPort visitWorkerSendPort(_WorkerSendPort port) {
+    return new _WorkerSendPort(
+        port._workerId, port._isolateId, port._receivePortId);
+  }
+
+  SendPort visitBufferingSendPort(_BufferingSendPort port) {
+    if (port._port != null) {
+      return visitSendPort(port._port);
+    } else {
+      // TODO(floitsch): Use real exception (which one?).
+      throw
+          "internal error: must call _waitForPendingPorts to ensure all"
+          " ports are resolved at this point.";
+    }
+  }
+
+}
+
+class _JsDeserializer extends _Deserializer {
+
+  SendPort deserializeSendPort(List x) {
+    int managerId = x[1];
+    int isolateId = x[2];
+    int receivePortId = x[3];
+    // If two isolates are in the same manager, we use NativeJsSendPorts to
+    // deliver messages directly without using postMessage.
+    if (managerId == _globalState.currentManagerId) {
+      var isolate = _globalState.isolates[isolateId];
+      if (isolate == null) return null; // Isolate has been closed.
+      var receivePort = isolate.lookup(receivePortId);
+      return new _NativeJsSendPort(receivePort, isolateId);
+    } else {
+      return new _WorkerSendPort(managerId, isolateId, receivePortId);
+    }
+  }
+
+}
+
+class _JsVisitedMap implements _MessageTraverserVisitedMap {
+  List tagged;
+
+  /** Retrieves any information stored in the native object [object]. */
+  operator[](var object) {
+    return _getAttachedInfo(object);
+  }
+
+  /** Injects some information into the native [object]. */
+  void operator[]=(var object, var info) {
+    tagged.add(object);
+    _setAttachedInfo(object, info);
+  }
+
+  /** Get ready to rumble. */
+  void reset() {
+    assert(tagged == null);
+    tagged = new List();
+  }
+
+  /** Remove all information injected in the native objects. */
+  void cleanup() {
+    for (int i = 0, length = tagged.length; i < length; i++) {
+      _clearAttachedInfo(tagged[i]);
+    }
+    tagged = null;
+  }
+
+  void _clearAttachedInfo(var o) {
+    JS("void", "#['__MessageTraverser__attached_info__'] = #", o, null);
+  }
+
+  void _setAttachedInfo(var o, var info) {
+    JS("void", "#['__MessageTraverser__attached_info__'] = #", o, info);
+  }
+
+  _getAttachedInfo(var o) {
+    return JS("", "#['__MessageTraverser__attached_info__']", o);
+  }
+}
+
+// only visible for testing purposes
+// TODO(sigmund): remove once we can disable privacy for testing (bug #1882)
+class TestingOnly {
+  static copy(x) {
+    return new _JsCopier().traverse(x);
+  }
+
+  // only visible for testing purposes
+  static serialize(x) {
+    _Serializer serializer = new _JsSerializer();
+    _Deserializer deserializer = new _JsDeserializer();
+    return deserializer.deserialize(serializer.traverse(x));
+  }
+}
+
+/********************************************************
+  Inserted from lib/isolate/serialization.dart
+ ********************************************************/
+
+class _MessageTraverserVisitedMap {
+
+  operator[](var object) => null;
+  void operator[]=(var object, var info) { }
+
+  void reset() { }
+  void cleanup() { }
+
+}
+
+/** Abstract visitor for dart objects that can be sent as isolate messages. */
+class _MessageTraverser {
+
+  _MessageTraverserVisitedMap _visited;
+  _MessageTraverser() : _visited = new _MessageTraverserVisitedMap();
+
+  /** Visitor's entry point. */
+  traverse(var x) {
+    if (isPrimitive(x)) return visitPrimitive(x);
+    _visited.reset();
+    var result;
+    try {
+      result = _dispatch(x);
+    } finally {
+      _visited.cleanup();
+    }
+    return result;
+  }
+
+  _dispatch(var x) {
+    if (isPrimitive(x)) return visitPrimitive(x);
+    if (x is List) return visitList(x);
+    if (x is Map) return visitMap(x);
+    if (x is SendPort) return visitSendPort(x);
+    if (x is SendPortSync) return visitSendPortSync(x);
+
+    // Overridable fallback.
+    return visitObject(x);
+  }
+
+  visitPrimitive(x);
+  visitList(List x);
+  visitMap(Map x);
+  visitSendPort(SendPort x);
+  visitSendPortSync(SendPortSync x);
+
+  visitObject(Object x) {
+    // TODO(floitsch): make this a real exception. (which one)?
+    throw "Message serialization: Illegal value $x passed";
+  }
+
+  static bool isPrimitive(x) {
+    return (x == null) || (x is String) || (x is num) || (x is bool);
+  }
+}
+
+
+/** A visitor that recursively copies a message. */
+class _Copier extends _MessageTraverser {
+
+  visitPrimitive(x) => x;
+
+  List visitList(List list) {
+    List copy = _visited[list];
+    if (copy != null) return copy;
+
+    int len = list.length;
+
+    // TODO(floitsch): we loose the generic type of the List.
+    copy = new List(len);
+    _visited[list] = copy;
+    for (int i = 0; i < len; i++) {
+      copy[i] = _dispatch(list[i]);
+    }
+    return copy;
+  }
+
+  Map visitMap(Map map) {
+    Map copy = _visited[map];
+    if (copy != null) return copy;
+
+    // TODO(floitsch): we loose the generic type of the map.
+    copy = new Map();
+    _visited[map] = copy;
+    map.forEach((key, val) {
+      copy[_dispatch(key)] = _dispatch(val);
+    });
+    return copy;
+  }
+
+}
+
+/** Visitor that serializes a message as a JSON array. */
+class _Serializer extends _MessageTraverser {
+  int _nextFreeRefId = 0;
+
+  visitPrimitive(x) => x;
+
+  visitList(List list) {
+    int copyId = _visited[list];
+    if (copyId != null) return ['ref', copyId];
+
+    int id = _nextFreeRefId++;
+    _visited[list] = id;
+    var jsArray = _serializeList(list);
+    // TODO(floitsch): we are losing the generic type.
+    return ['list', id, jsArray];
+  }
+
+  visitMap(Map map) {
+    int copyId = _visited[map];
+    if (copyId != null) return ['ref', copyId];
+
+    int id = _nextFreeRefId++;
+    _visited[map] = id;
+    var keys = _serializeList(map.keys);
+    var values = _serializeList(map.values);
+    // TODO(floitsch): we are losing the generic type.
+    return ['map', id, keys, values];
+  }
+
+  _serializeList(List list) {
+    int len = list.length;
+    var result = new List(len);
+    for (int i = 0; i < len; i++) {
+      result[i] = _dispatch(list[i]);
+    }
+    return result;
+  }
+}
+
+/** Deserializes arrays created with [_Serializer]. */
+class _Deserializer {
+  Map<int, dynamic> _deserialized;
+
+  _Deserializer();
+
+  static bool isPrimitive(x) {
+    return (x == null) || (x is String) || (x is num) || (x is bool);
+  }
+
+  deserialize(x) {
+    if (isPrimitive(x)) return x;
+    // TODO(floitsch): this should be new HashMap<int, var|Dynamic>()
+    _deserialized = new HashMap();
+    return _deserializeHelper(x);
+  }
+
+  _deserializeHelper(x) {
+    if (isPrimitive(x)) return x;
+    assert(x is List);
+    switch (x[0]) {
+      case 'ref': return _deserializeRef(x);
+      case 'list': return _deserializeList(x);
+      case 'map': return _deserializeMap(x);
+      case 'sendport': return deserializeSendPort(x);
+      default: return deserializeObject(x);
+    }
+  }
+
+  _deserializeRef(List x) {
+    int id = x[1];
+    var result = _deserialized[id];
+    assert(result != null);
+    return result;
+  }
+
+  List _deserializeList(List x) {
+    int id = x[1];
+    // We rely on the fact that Dart-lists are directly mapped to Js-arrays.
+    List dartList = x[2];
+    _deserialized[id] = dartList;
+    int len = dartList.length;
+    for (int i = 0; i < len; i++) {
+      dartList[i] = _deserializeHelper(dartList[i]);
+    }
+    return dartList;
+  }
+
+  Map _deserializeMap(List x) {
+    Map result = new Map();
+    int id = x[1];
+    _deserialized[id] = result;
+    List keys = x[2];
+    List values = x[3];
+    int len = keys.length;
+    assert(len == values.length);
+    for (int i = 0; i < len; i++) {
+      var key = _deserializeHelper(keys[i]);
+      var value = _deserializeHelper(values[i]);
+      result[key] = value;
+    }
+    return result;
+  }
+
+  deserializeSendPort(List x);
+
+  deserializeObject(List x) {
+    // TODO(floitsch): Use real exception (which one?).
+    throw "Unexpected serialized object";
+  }
+}
+
+class TimerImpl implements Timer {
+  final bool _once;
+  int _handle;
+
+  TimerImpl(int milliseconds, void callback(Timer timer))
+      : _once = true {
+    _handle = JS('int', '#.setTimeout(#, #)',
+                 globalThis,
+                 convertDartClosureToJS(() => callback(this), 0),
+                 milliseconds);
+  }
+
+  TimerImpl.repeating(int milliseconds, void callback(Timer timer))
+      : _once = false {
+    _handle = JS('int', '#.setInterval(#, #)',
+                 globalThis,
+                 convertDartClosureToJS(() => callback(this), 0),
+                 milliseconds);
+  }
+
+  void cancel() {
+    if (_once) {
+      JS('void', '#.clearTimeout(#)', globalThis, _handle);
+    } else {
+      JS('void', '#.clearInterval(#)', globalThis, _handle);
+    }
+  }
+}
+
+bool hasTimer() => JS('', '#.setTimeout', globalThis) != null;
diff --git a/sdk/lib/_internal/compiler/implementation/lib/isolate_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/isolate_patch.dart
index 5dd9e44..cd661b1 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/isolate_patch.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/isolate_patch.dart
@@ -4,1295 +4,46 @@
 
 // Patch file for the dart:isolate library.
 
-import 'dart:uri';
-
-/**
- * Called by the compiler to support switching
- * between isolates when we get a callback from the DOM.
- */
-void _callInIsolate(_IsolateContext isolate, Function function) {
-  isolate.eval(function);
-  _globalState.topEventLoop.run();
-}
-
-/**
- * Called by the compiler to fetch the current isolate context.
- */
-_IsolateContext _currentIsolate() => _globalState.currentContext;
-
-/********************************************************
-  Inserted from lib/isolate/dart2js/compiler_hooks.dart
- ********************************************************/
-
-/**
- * Wrapper that takes the dart entry point and runs it within an isolate. The
- * dart2js compiler will inject a call of the form
- * [: startRootIsolate(main); :] when it determines that this wrapping
- * is needed. For single-isolate applications (e.g. hello world), this
- * call is not emitted.
- */
-void startRootIsolate(entry) {
-  _globalState = new _Manager();
-
-  // Don't start the main loop again, if we are in a worker.
-  if (_globalState.isWorker) return;
-  final rootContext = new _IsolateContext();
-  _globalState.rootContext = rootContext;
-  _fillStatics(rootContext);
-
-  // BUG(5151491): Setting currentContext should not be necessary, but
-  // because closures passed to the DOM as event handlers do not bind their
-  // isolate automatically we try to give them a reasonable context to live in
-  // by having a "default" isolate (the first one created).
-  _globalState.currentContext = rootContext;
-
-  rootContext.eval(entry);
-  _globalState.topEventLoop.run();
-}
-
-/********************************************************
-  Inserted from lib/isolate/dart2js/isolateimpl.dart
- ********************************************************/
-
-/**
- * Concepts used here:
- *
- * "manager" - A manager contains one or more isolates, schedules their
- * execution, and performs other plumbing on their behalf.  The isolate
- * present at the creation of the manager is designated as its "root isolate".
- * A manager may, for example, be implemented on a web Worker.
- *
- * [_Manager] - State present within a manager (exactly once, as a global).
- *
- * [_ManagerStub] - A handle held within one manager that allows interaction
- * with another manager.  A target manager may be addressed by zero or more
- * [_ManagerStub]s.
- *
- */
-
-/**
- * A native object that is shared across isolates. This object is visible to all
- * isolates running under the same manager (either UI or background web worker).
- *
- * This is code that is intended to 'escape' the isolate boundaries in order to
- * implement the semantics of isolates in JavaScript. Without this we would have
- * been forced to implement more code (including the top-level event loop) in
- * JavaScript itself.
- */
-// TODO(eub, sigmund): move the "manager" to be entirely in JS.
-// Running any Dart code outside the context of an isolate gives it
-// the change to break the isolate abstraction.
-_Manager get _globalState => JS("_Manager", r"$globalState");
-set _globalState(_Manager val) {
-  JS("void", r"$globalState = #", val);
-}
-
-void _fillStatics(context) {
-  JS("void", r"$globals = #.isolateStatics", context);
-  JS("void", r"$static_init()");
-}
-
-ReceivePort _lazyPort;
 patch ReceivePort get port {
-  if (_lazyPort == null) {
-    _lazyPort = new ReceivePort();
+  if (lazyPort == null) {
+    lazyPort = new ReceivePort();
   }
-  return _lazyPort;
+  return lazyPort;
 }
 
-patch SendPort spawnFunction(void topLevelFunction()) {
-  final name = _IsolateNatives._getJSFunctionName(topLevelFunction);
-  if (name == null) {
-    throw new UnsupportedError(
-        "only top-level functions can be spawned.");
-  }
-  return _IsolateNatives._spawn(name, null, false);
+patch SendPort spawnFunction(void topLevelFunction(),
+    [bool UnhandledExceptionCallback(IsolateUnhandledException e)]) {
+  return IsolateNatives.spawnFunction(topLevelFunction);
 }
 
 patch SendPort spawnUri(String uri) {
-  return _IsolateNatives._spawn(null, uri, false);
+  return IsolateNatives.spawn(null, uri, false);
 }
 
-/** State associated with the current manager. See [globalState]. */
-// TODO(sigmund): split in multiple classes: global, thread, main-worker states?
-class _Manager {
-
-  /** Next available isolate id within this [_Manager]. */
-  int nextIsolateId = 0;
-
-  /** id assigned to this [_Manager]. */
-  int currentManagerId = 0;
-
-  /**
-   * Next available manager id. Only used by the main manager to assign a unique
-   * id to each manager created by it.
-   */
-  int nextManagerId = 1;
-
-  /** Context for the currently running [Isolate]. */
-  _IsolateContext currentContext = null;
-
-  /** Context for the root [Isolate] that first run in this [_Manager]. */
-  _IsolateContext rootContext = null;
-
-  /** The top-level event loop. */
-  _EventLoop topEventLoop;
-
-  /** Whether this program is running from the command line. */
-  bool fromCommandLine;
-
-  /** Whether this [_Manager] is running as a web worker. */
-  bool isWorker;
-
-  /** Whether we support spawning web workers. */
-  bool supportsWorkers;
-
-  /**
-   * Whether to use web workers when implementing isolates. Set to false for
-   * debugging/testing.
-   */
-  bool get useWorkers => supportsWorkers;
-
-  /**
-   * Whether to use the web-worker JSON-based message serialization protocol. By
-   * default this is only used with web workers. For debugging, you can force
-   * using this protocol by changing this field value to [true].
-   */
-  bool get needSerialization => useWorkers;
-
-  /**
-   * Registry of isolates. Isolates must be registered if, and only if, receive
-   * ports are alive.  Normally no open receive-ports means that the isolate is
-   * dead, but DOM callbacks could resurrect it.
-   */
-  Map<int, _IsolateContext> isolates;
-
-  /** Reference to the main [_Manager].  Null in the main [_Manager] itself. */
-  _ManagerStub mainManager;
-
-  /** Registry of active [_ManagerStub]s.  Only used in the main [_Manager]. */
-  Map<int, _ManagerStub> managers;
-
-  _Manager() {
-    _nativeDetectEnvironment();
-    topEventLoop = new _EventLoop();
-    isolates = new Map<int, _IsolateContext>();
-    managers = new Map<int, _ManagerStub>();
-    if (isWorker) {  // "if we are not the main manager ourself" is the intent.
-      mainManager = new _MainManagerStub();
-      _nativeInitWorkerMessageHandler();
-    }
-  }
-
-  void _nativeDetectEnvironment() {
-    isWorker = JS("bool", r"$isWorker");
-    supportsWorkers = JS("bool", r"$supportsWorkers");
-    fromCommandLine = JS("bool", r"typeof(window) == 'undefined'");
-  }
-
-  void _nativeInitWorkerMessageHandler() {
-    JS("void", r"""
-$globalThis.onmessage = function (e) {
-  _IsolateNatives._processWorkerMessage(this.mainManager, e);
-}""");
-  }
-  /*: TODO: check that _processWorkerMessage is not discarded while treeshaking.
-  """ {
-    _IsolateNatives._processWorkerMessage(null, null);
-  }
-  */
-
-
-  /** Close the worker running this code if all isolates are done. */
-  void maybeCloseWorker() {
-    if (isolates.isEmpty) {
-      mainManager.postMessage(_serializeMessage({'command': 'close'}));
-    }
-  }
-}
-
-/** Context information tracked for each isolate. */
-class _IsolateContext {
-  /** Current isolate id. */
-  int id;
-
-  /** Registry of receive ports currently active on this isolate. */
-  Map<int, ReceivePort> ports;
-
-  /** Holds isolate globals (statics and top-level properties). */
-  var isolateStatics; // native object containing all globals of an isolate.
-
-  _IsolateContext() {
-    id = _globalState.nextIsolateId++;
-    ports = new Map<int, ReceivePort>();
-    initGlobals();
-  }
-
-  // these are filled lazily the first time the isolate starts running.
-  void initGlobals() { JS("void", r'$initGlobals(#)', this); }
-
-  /**
-   * Run [code] in the context of the isolate represented by [this]. Note this
-   * is called from JavaScript (see $wrap_call in corejs.dart).
-   */
-  dynamic eval(Function code) {
-    var old = _globalState.currentContext;
-    _globalState.currentContext = this;
-    this._setGlobals();
-    var result = null;
-    try {
-      result = code();
-    } finally {
-      _globalState.currentContext = old;
-      if (old != null) old._setGlobals();
-    }
-    return result;
-  }
-
-  void _setGlobals() { JS("void", r'$setGlobals(#)', this); }
-
-  /** Lookup a port registered for this isolate. */
-  ReceivePort lookup(int portId) => ports[portId];
-
-  /** Register a port on this isolate. */
-  void register(int portId, ReceivePort port)  {
-    if (ports.containsKey(portId)) {
-      throw new Exception("Registry: ports must be registered only once.");
-    }
-    ports[portId] = port;
-    _globalState.isolates[id] = this; // indicate this isolate is active
-  }
-
-  /** Unregister a port on this isolate. */
-  void unregister(int portId) {
-    ports.remove(portId);
-    if (ports.isEmpty) {
-      _globalState.isolates.remove(id); // indicate this isolate is not active
-    }
-  }
-}
-
-/** Represent the event loop on a javascript thread (DOM or worker). */
-class _EventLoop {
-  Queue<_IsolateEvent> events;
-
-  _EventLoop() : events = new Queue<_IsolateEvent>();
-
-  void enqueue(isolate, fn, msg) {
-    events.addLast(new _IsolateEvent(isolate, fn, msg));
-  }
-
-  _IsolateEvent dequeue() {
-    if (events.isEmpty) return null;
-    return events.removeFirst();
-  }
-
-  /** Process a single event, if any. */
-  bool runIteration() {
-    final event = dequeue();
-    if (event == null) {
-      if (_globalState.isWorker) {
-        _globalState.maybeCloseWorker();
-      } else if (_globalState.rootContext != null &&
-                 _globalState.isolates.containsKey(
-                     _globalState.rootContext.id) &&
-                 _globalState.fromCommandLine &&
-                 _globalState.rootContext.ports.isEmpty) {
-        // We want to reach here only on the main [_Manager] and only
-        // on the command-line.  In the browser the isolate might
-        // still be alive due to DOM callbacks, but the presumption is
-        // that on the command-line, no future events can be injected
-        // into the event queue once it's empty.  Node has setTimeout
-        // so this presumption is incorrect there.  We think(?) that
-        // in d8 this assumption is valid.
-        throw new Exception("Program exited with open ReceivePorts.");
-      }
-      return false;
-    }
-    event.process();
-    return true;
-  }
-
-  /**
-   * Runs multiple iterations of the run-loop. If possible, each iteration is
-   * run asynchronously.
-   */
-  void _runHelper() {
-    // [_window] is defined in timer_provider.dart.
-    if (_window != null) {
-      // Run each iteration from the browser's top event loop.
-      void next() {
-        if (!runIteration()) return;
-        _window.setTimeout(next, 0);
-      }
-      next();
-    } else {
-      // Run synchronously until no more iterations are available.
-      while (runIteration()) {}
-    }
-  }
-
-  /**
-   * Call [_runHelper] but ensure that worker exceptions are propragated. Note
-   * this is called from JavaScript (see $wrap_call in corejs.dart).
-   */
-  void run() {
-    if (!_globalState.isWorker) {
-      _runHelper();
-    } else {
-      try {
-        _runHelper();
-      } catch (e, trace) {
-        _globalState.mainManager.postMessage(_serializeMessage(
-            {'command': 'error', 'msg': '$e\n$trace' }));
-      }
-    }
-  }
-}
-
-/** An event in the top-level event queue. */
-class _IsolateEvent {
-  _IsolateContext isolate;
-  Function fn;
-  String message;
-
-  _IsolateEvent(this.isolate, this.fn, this.message);
-
-  void process() {
-    isolate.eval(fn);
-  }
-}
-
-/** An interface for a stub used to interact with a manager. */
-abstract class _ManagerStub {
-  get id;
-  void set id(int i);
-  void set onmessage(Function f);
-  void postMessage(msg);
-  void terminate();
-}
-
-/** A stub for interacting with the main manager. */
-class _MainManagerStub implements _ManagerStub {
-  get id => 0;
-  void set id(int i) { throw new UnimplementedError(); }
-  void set onmessage(f) {
-    throw new Exception("onmessage should not be set on MainManagerStub");
-  }
-  void postMessage(msg) { JS("void", r"$globalThis.postMessage(#)", msg); }
-  void terminate() {}  // Nothing useful to do here.
-}
-
-/**
- * A stub for interacting with a manager built on a web worker. This
- * definition uses a 'hidden' type (* prefix on the native name) to
- * enforce that the type is defined dynamically only when web workers
- * are actually available.
- */
-class _WorkerStub implements _ManagerStub native "*Worker" {
-  get id => JS("var", "#.id", this);
-  void set id(i) { JS("void", "#.id = #", this, i); }
-  void set onmessage(f) { JS("void", "#.onmessage = #", this, f); }
-  void postMessage(msg) => JS("void", "#.postMessage(#)", this, msg);
-  // terminate() is implemented by Worker.
-  void terminate();
-}
-
-const String _SPAWNED_SIGNAL = "spawned";
-
-class _IsolateNatives {
-
-  /**
-   * The src url for the script tag that loaded this code. Used to create
-   * JavaScript workers.
-   */
-  static String get _thisScript => JS("String", r"$thisScriptUrl");
-
-  /** Starts a new worker with the given URL. */
-  static _WorkerStub _newWorker(url) => JS("_WorkerStub", r"new Worker(#)", url);
-
-  /**
-   * Assume that [e] is a browser message event and extract its message data.
-   * We don't import the dom explicitly so, when workers are disabled, this
-   * library can also run on top of nodejs.
-   */
-  //static _getEventData(e) => JS("Object", "#.data", e);
-  static _getEventData(e) => JS("", "#.data", e);
-
-  /**
-   * Process messages on a worker, either to control the worker instance or to
-   * pass messages along to the isolate running in the worker.
-   */
-  static void _processWorkerMessage(sender, e) {
-    var msg = _deserializeMessage(_getEventData(e));
-    switch (msg['command']) {
-      case 'start':
-        _globalState.currentManagerId = msg['id'];
-        Function entryPoint = _getJSFunctionFromName(msg['functionName']);
-        var replyTo = _deserializeMessage(msg['replyTo']);
-        _globalState.topEventLoop.enqueue(new _IsolateContext(), function() {
-          _startIsolate(entryPoint, replyTo);
-        }, 'worker-start');
-        _globalState.topEventLoop.run();
-        break;
-      case 'spawn-worker':
-        _spawnWorker(msg['functionName'], msg['uri'], msg['replyPort']);
-        break;
-      case 'message':
-        msg['port'].send(msg['msg'], msg['replyTo']);
-        _globalState.topEventLoop.run();
-        break;
-      case 'close':
-        _log("Closing Worker");
-        _globalState.managers.remove(sender.id);
-        sender.terminate();
-        _globalState.topEventLoop.run();
-        break;
-      case 'log':
-        _log(msg['msg']);
-        break;
-      case 'print':
-        if (_globalState.isWorker) {
-          _globalState.mainManager.postMessage(
-              _serializeMessage({'command': 'print', 'msg': msg}));
-        } else {
-          print(msg['msg']);
-        }
-        break;
-      case 'error':
-        throw msg['msg'];
-    }
-  }
-
-  /** Log a message, forwarding to the main [_Manager] if appropriate. */
-  static _log(msg) {
-    if (_globalState.isWorker) {
-      _globalState.mainManager.postMessage(
-          _serializeMessage({'command': 'log', 'msg': msg }));
-    } else {
-      try {
-        _consoleLog(msg);
-      } catch (e, trace) {
-        throw new Exception(trace);
-      }
-    }
-  }
-
-  static void _consoleLog(msg) {
-    JS("void", r"$globalThis.console.log(#)", msg);
-  }
-
-  /**
-   * Extract the constructor of runnable, so it can be allocated in another
-   * isolate.
-   */
-  static dynamic _getJSConstructor(Isolate runnable) {
-    return JS("Object", "#.constructor", runnable);
-  }
-
-  /** Extract the constructor name of a runnable */
-  // TODO(sigmund): find a browser-generic way to support this.
-  // TODO(floitsch): is this function still used? If yes, should we use
-  // Primitives.objectTypeName instead?
-  static dynamic _getJSConstructorName(Isolate runnable) {
-    return JS("Object", "#.constructor.name", runnable);
-  }
-
-  /** Find a constructor given its name. */
-  static dynamic _getJSConstructorFromName(String factoryName) {
-    return JS("Object", r"$globalThis[#]", factoryName);
-  }
-
-  static dynamic _getJSFunctionFromName(String functionName) {
-    return JS("Object", r"$globalThis[#]", functionName);
-  }
-
-  /**
-   * Get a string name for the function, if possible.  The result for
-   * anonymous functions is browser-dependent -- it may be "" or "anonymous"
-   * but you should probably not count on this.
-   */
-  static String _getJSFunctionName(Function f) {
-    return JS("Object", r"(#.$name || #)", f, null);
-  }
-
-  /** Create a new JavaScript object instance given its constructor. */
-  static dynamic _allocate(var ctor) {
-    return JS("Object", "new #()", ctor);
-  }
-
-  // TODO(sigmund): clean up above, after we make the new API the default:
-
-  static _spawn(String functionName, String uri, bool isLight) {
-    Completer<SendPort> completer = new Completer<SendPort>();
-    ReceivePort port = new ReceivePort();
-    port.receive((msg, SendPort replyPort) {
-      port.close();
-      assert(msg == _SPAWNED_SIGNAL);
-      completer.complete(replyPort);
-    });
-
-    SendPort signalReply = port.toSendPort();
-
-    if (_globalState.useWorkers && !isLight) {
-      _startWorker(functionName, uri, signalReply);
-    } else {
-      _startNonWorker(functionName, uri, signalReply);
-    }
-    return new _BufferingSendPort(
-        _globalState.currentContext.id, completer.future);
-  }
-
-  static SendPort _startWorker(
-      String functionName, String uri, SendPort replyPort) {
-    if (_globalState.isWorker) {
-      _globalState.mainManager.postMessage(_serializeMessage({
-          'command': 'spawn-worker',
-          'functionName': functionName,
-          'uri': uri,
-          'replyPort': replyPort}));
-    } else {
-      _spawnWorker(functionName, uri, replyPort);
-    }
-  }
-
-  static SendPort _startNonWorker(
-      String functionName, String uri, SendPort replyPort) {
-    // TODO(eub): support IE9 using an iframe -- Dart issue 1702.
-    if (uri != null) throw new UnsupportedError(
-            "Currently spawnUri is not supported without web workers.");
-    _globalState.topEventLoop.enqueue(new _IsolateContext(), function() {
-      final func = _getJSFunctionFromName(functionName);
-      _startIsolate(func, replyPort);
-    }, 'nonworker start');
-  }
-
-  static void _startIsolate(Function topLevel, SendPort replyTo) {
-    _fillStatics(_globalState.currentContext);
-    _lazyPort = new ReceivePort();
-    replyTo.send(_SPAWNED_SIGNAL, port.toSendPort());
-
-    topLevel();
-  }
-
-  /**
-   * Spawns an isolate in a worker. [factoryName] is the Javascript constructor
-   * name for the isolate entry point class.
-   */
-  static void _spawnWorker(functionName, uri, replyPort) {
-    if (functionName == null) functionName = 'main';
-    if (uri == null) uri = _thisScript;
-    if (!(new Uri.fromString(uri).isAbsolute())) {
-      // The constructor of dom workers requires an absolute URL. If we use a
-      // relative path we will get a DOM exception.
-      String prefix = _thisScript.substring(0, _thisScript.lastIndexOf('/'));
-      uri = "$prefix/$uri";
-    }
-    final worker = _newWorker(uri);
-    worker.onmessage = (e) { _processWorkerMessage(worker, e); };
-    var workerId = _globalState.nextManagerId++;
-    // We also store the id on the worker itself so that we can unregister it.
-    worker.id = workerId;
-    _globalState.managers[workerId] = worker;
-    worker.postMessage(_serializeMessage({
-      'command': 'start',
-      'id': workerId,
-      // Note: we serialize replyPort twice because the child worker needs to
-      // first deserialize the worker id, before it can correctly deserialize
-      // the port (port deserialization is sensitive to what is the current
-      // workerId).
-      'replyTo': _serializeMessage(replyPort),
-      'functionName': functionName }));
-  }
-}
-
-/********************************************************
-  Inserted from lib/isolate/dart2js/ports.dart
- ********************************************************/
-
-/** Common functionality to all send ports. */
-class _BaseSendPort implements SendPort {
-  /** Id for the destination isolate. */
-  final int _isolateId;
-
-  const _BaseSendPort(this._isolateId);
-
-  void _checkReplyTo(SendPort replyTo) {
-    if (replyTo != null
-        && replyTo is! _NativeJsSendPort
-        && replyTo is! _WorkerSendPort
-        && replyTo is! _BufferingSendPort) {
-      throw new Exception("SendPort.send: Illegal replyTo port type");
-    }
-  }
-
-  Future call(var message) {
-    final completer = new Completer();
-    final port = new _ReceivePortImpl();
-    send(message, port.toSendPort());
-    port.receive((value, ignoreReplyTo) {
-      port.close();
-      if (value is Exception) {
-        completer.completeException(value);
-      } else {
-        completer.complete(value);
-      }
-    });
-    return completer.future;
-  }
-
-  void send(var message, [SendPort replyTo]);
-  bool operator ==(var other);
-  int get hashCode;
-}
-
-/** A send port that delivers messages in-memory via native JavaScript calls. */
-class _NativeJsSendPort extends _BaseSendPort implements SendPort {
-  final _ReceivePortImpl _receivePort;
-
-  const _NativeJsSendPort(this._receivePort, int isolateId) : super(isolateId);
-
-  void send(var message, [SendPort replyTo = null]) {
-    _waitForPendingPorts([message, replyTo], () {
-      _checkReplyTo(replyTo);
-      // Check that the isolate still runs and the port is still open
-      final isolate = _globalState.isolates[_isolateId];
-      if (isolate == null) return;
-      if (_receivePort._callback == null) return;
-
-      // We force serialization/deserialization as a simple way to ensure
-      // isolate communication restrictions are respected between isolates that
-      // live in the same worker. [_NativeJsSendPort] delivers both messages
-      // from the same worker and messages from other workers. In particular,
-      // messages sent from a worker via a [_WorkerSendPort] are received at
-      // [_processWorkerMessage] and forwarded to a native port. In such cases,
-      // here we'll see [_globalState.currentContext == null].
-      final shouldSerialize = _globalState.currentContext != null
-          && _globalState.currentContext.id != _isolateId;
-      var msg = message;
-      var reply = replyTo;
-      if (shouldSerialize) {
-        msg = _serializeMessage(msg);
-        reply = _serializeMessage(reply);
-      }
-      _globalState.topEventLoop.enqueue(isolate, () {
-        if (_receivePort._callback != null) {
-          if (shouldSerialize) {
-            msg = _deserializeMessage(msg);
-            reply = _deserializeMessage(reply);
-          }
-          _receivePort._callback(msg, reply);
-        }
-      }, 'receive $message');
-    });
-  }
-
-  bool operator ==(var other) => (other is _NativeJsSendPort) &&
-      (_receivePort == other._receivePort);
-
-  int get hashCode => _receivePort._id;
-}
-
-/** A send port that delivers messages via worker.postMessage. */
-// TODO(eub): abstract this for iframes.
-class _WorkerSendPort extends _BaseSendPort implements SendPort {
-  final int _workerId;
-  final int _receivePortId;
-
-  const _WorkerSendPort(this._workerId, int isolateId, this._receivePortId)
-      : super(isolateId);
-
-  void send(var message, [SendPort replyTo = null]) {
-    _waitForPendingPorts([message, replyTo], () {
-      _checkReplyTo(replyTo);
-      final workerMessage = _serializeMessage({
-          'command': 'message',
-          'port': this,
-          'msg': message,
-          'replyTo': replyTo});
-
-      if (_globalState.isWorker) {
-        // communication from one worker to another go through the main worker:
-        _globalState.mainManager.postMessage(workerMessage);
-      } else {
-        _globalState.managers[_workerId].postMessage(workerMessage);
-      }
-    });
-  }
-
-  bool operator ==(var other) {
-    return (other is _WorkerSendPort) &&
-        (_workerId == other._workerId) &&
-        (_isolateId == other._isolateId) &&
-        (_receivePortId == other._receivePortId);
-  }
-
-  int get hashCode {
-    // TODO(sigmund): use a standard hash when we get one available in corelib.
-    return (_workerId << 16) ^ (_isolateId << 8) ^ _receivePortId;
-  }
-}
-
-/** A port that buffers messages until an underlying port gets resolved. */
-class _BufferingSendPort extends _BaseSendPort implements SendPort {
-  /** Internal counter to assign unique ids to each port. */
-  static int _idCount = 0;
-
-  /** For implementing equals and hashcode. */
-  final int _id;
-
-  /** Underlying port, when resolved. */
-  SendPort _port;
-
-  /**
-   * Future of the underlying port, so that we can detect when this port can be
-   * sent on messages.
-   */
-  Future<SendPort> _futurePort;
-
-  /** Pending messages (and reply ports). */
-  List pending;
-
-  _BufferingSendPort(isolateId, this._futurePort)
-      : super(isolateId), _id = _idCount, pending = [] {
-    _idCount++;
-    _futurePort.then((p) {
-      _port = p;
-      for (final item in pending) {
-        p.send(item['message'], item['replyTo']);
-      }
-      pending = null;
-    });
-  }
-
-  _BufferingSendPort.fromPort(isolateId, this._port)
-      : super(isolateId), _id = _idCount {
-    _idCount++;
-  }
-
-  void send(var message, [SendPort replyTo]) {
-    if (_port != null) {
-      _port.send(message, replyTo);
-    } else {
-      pending.add({'message': message, 'replyTo': replyTo});
-    }
-  }
-
-  bool operator ==(var other) =>
-      other is _BufferingSendPort && _id == other._id;
-  int get hashCode => _id;
-}
 
 /** Default factory for receive ports. */
 patch class ReceivePort {
   patch factory ReceivePort() {
-    return new _ReceivePortImpl();
-  }
-
-}
-
-/** Implementation of a multi-use [ReceivePort] on top of JavaScript. */
-class _ReceivePortImpl implements ReceivePort {
-  int _id;
-  Function _callback;
-  static int _nextFreeId = 1;
-
-  _ReceivePortImpl()
-      : _id = _nextFreeId++ {
-    _globalState.currentContext.register(_id, this);
-  }
-
-  void receive(void onMessage(var message, SendPort replyTo)) {
-    _callback = onMessage;
-  }
-
-  void close() {
-    _callback = null;
-    _globalState.currentContext.unregister(_id);
-  }
-
-  SendPort toSendPort() {
-    return new _NativeJsSendPort(this, _globalState.currentContext.id);
-  }
-}
-
-/** Wait until all ports in a message are resolved. */
-_waitForPendingPorts(var message, void callback()) {
-  final finder = new _PendingSendPortFinder();
-  finder.traverse(message);
-  Futures.wait(finder.ports).then((_) => callback());
-}
-
-
-/** Visitor that finds all unresolved [SendPort]s in a message. */
-class _PendingSendPortFinder extends _MessageTraverser {
-  List<Future<SendPort>> ports;
-  _PendingSendPortFinder() : super(), ports = [] {
-    _visited = new _JsVisitedMap();
-  }
-
-  visitPrimitive(x) {}
-
-  visitList(List list) {
-    final seen = _visited[list];
-    if (seen != null) return;
-    _visited[list] = true;
-    // TODO(sigmund): replace with the following: (bug #1660)
-    // list.forEach(_dispatch);
-    list.forEach((e) => _dispatch(e));
-  }
-
-  visitMap(Map map) {
-    final seen = _visited[map];
-    if (seen != null) return;
-
-    _visited[map] = true;
-    // TODO(sigmund): replace with the following: (bug #1660)
-    // map.values.forEach(_dispatch);
-    map.values.forEach((e) => _dispatch(e));
-  }
-
-  visitSendPort(SendPort port) {
-    if (port is _BufferingSendPort && port._port == null) {
-      ports.add(port._futurePort);
-    }
-  }
-}
-
-/********************************************************
-  Inserted from lib/isolate/dart2js/messages.dart
- ********************************************************/
-
-// Defines message visitors, serialization, and deserialization.
-
-/** Serialize [message] (or simulate serialization). */
-_serializeMessage(message) {
-  if (_globalState.needSerialization) {
-    return new _JsSerializer().traverse(message);
-  } else {
-    return new _JsCopier().traverse(message);
-  }
-}
-
-/** Deserialize [message] (or simulate deserialization). */
-_deserializeMessage(message) {
-  if (_globalState.needSerialization) {
-    return new _JsDeserializer().deserialize(message);
-  } else {
-    // Nothing more to do.
-    return message;
-  }
-}
-
-class _JsSerializer extends _Serializer {
-
-  _JsSerializer() : super() { _visited = new _JsVisitedMap(); }
-
-  visitSendPort(SendPort x) {
-    if (x is _NativeJsSendPort) return visitNativeJsSendPort(x);
-    if (x is _WorkerSendPort) return visitWorkerSendPort(x);
-    if (x is _BufferingSendPort) return visitBufferingSendPort(x);
-    throw "Illegal underlying port $x";
-  }
-
-  visitNativeJsSendPort(_NativeJsSendPort port) {
-    return ['sendport', _globalState.currentManagerId,
-        port._isolateId, port._receivePort._id];
-  }
-
-  visitWorkerSendPort(_WorkerSendPort port) {
-    return ['sendport', port._workerId, port._isolateId, port._receivePortId];
-  }
-
-  visitBufferingSendPort(_BufferingSendPort port) {
-    if (port._port != null) {
-      return visitSendPort(port._port);
-    } else {
-      // TODO(floitsch): Use real exception (which one?).
-      throw
-          "internal error: must call _waitForPendingPorts to ensure all"
-          " ports are resolved at this point.";
-    }
-  }
-
-}
-
-
-class _JsCopier extends _Copier {
-
-  _JsCopier() : super() { _visited = new _JsVisitedMap(); }
-
-  visitSendPort(SendPort x) {
-    if (x is _NativeJsSendPort) return visitNativeJsSendPort(x);
-    if (x is _WorkerSendPort) return visitWorkerSendPort(x);
-    if (x is _BufferingSendPort) return visitBufferingSendPort(x);
-    throw "Illegal underlying port $p";
-  }
-
-  SendPort visitNativeJsSendPort(_NativeJsSendPort port) {
-    return new _NativeJsSendPort(port._receivePort, port._isolateId);
-  }
-
-  SendPort visitWorkerSendPort(_WorkerSendPort port) {
-    return new _WorkerSendPort(
-        port._workerId, port._isolateId, port._receivePortId);
-  }
-
-  SendPort visitBufferingSendPort(_BufferingSendPort port) {
-    if (port._port != null) {
-      return visitSendPort(port._port);
-    } else {
-      // TODO(floitsch): Use real exception (which one?).
-      throw
-          "internal error: must call _waitForPendingPorts to ensure all"
-          " ports are resolved at this point.";
-    }
-  }
-
-}
-
-class _JsDeserializer extends _Deserializer {
-
-  SendPort deserializeSendPort(List x) {
-    int managerId = x[1];
-    int isolateId = x[2];
-    int receivePortId = x[3];
-    // If two isolates are in the same manager, we use NativeJsSendPorts to
-    // deliver messages directly without using postMessage.
-    if (managerId == _globalState.currentManagerId) {
-      var isolate = _globalState.isolates[isolateId];
-      if (isolate == null) return null; // Isolate has been closed.
-      var receivePort = isolate.lookup(receivePortId);
-      return new _NativeJsSendPort(receivePort, isolateId);
-    } else {
-      return new _WorkerSendPort(managerId, isolateId, receivePortId);
-    }
-  }
-
-}
-
-class _JsVisitedMap implements _MessageTraverserVisitedMap {
-  List tagged;
-
-  /** Retrieves any information stored in the native object [object]. */
-  operator[](var object) {
-    return _getAttachedInfo(object);
-  }
-
-  /** Injects some information into the native [object]. */
-  void operator[]=(var object, var info) {
-    tagged.add(object);
-    _setAttachedInfo(object, info);
-  }
-
-  /** Get ready to rumble. */
-  void reset() {
-    assert(tagged == null);
-    tagged = new List();
-  }
-
-  /** Remove all information injected in the native objects. */
-  void cleanup() {
-    for (int i = 0, length = tagged.length; i < length; i++) {
-      _clearAttachedInfo(tagged[i]);
-    }
-    tagged = null;
-  }
-
-  void _clearAttachedInfo(var o) {
-    JS("void", "#['__MessageTraverser__attached_info__'] = #", o, null);
-  }
-
-  void _setAttachedInfo(var o, var info) {
-    JS("void", "#['__MessageTraverser__attached_info__'] = #", o, info);
-  }
-
-  _getAttachedInfo(var o) {
-    return JS("", "#['__MessageTraverser__attached_info__']", o);
-  }
-}
-
-// only visible for testing purposes
-// TODO(sigmund): remove once we can disable privacy for testing (bug #1882)
-class TestingOnly {
-  static copy(x) {
-    return new _JsCopier().traverse(x);
-  }
-
-  // only visible for testing purposes
-  static serialize(x) {
-    _Serializer serializer = new _JsSerializer();
-    _Deserializer deserializer = new _JsDeserializer();
-    return deserializer.deserialize(serializer.traverse(x));
-  }
-}
-
-/********************************************************
-  Inserted from lib/isolate/serialization.dart
- ********************************************************/
-
-class _MessageTraverserVisitedMap {
-
-  operator[](var object) => null;
-  void operator[]=(var object, var info) { }
-
-  void reset() { }
-  void cleanup() { }
-
-}
-
-/** Abstract visitor for dart objects that can be sent as isolate messages. */
-class _MessageTraverser {
-
-  _MessageTraverserVisitedMap _visited;
-  _MessageTraverser() : _visited = new _MessageTraverserVisitedMap();
-
-  /** Visitor's entry point. */
-  traverse(var x) {
-    if (isPrimitive(x)) return visitPrimitive(x);
-    _visited.reset();
-    var result;
-    try {
-      result = _dispatch(x);
-    } finally {
-      _visited.cleanup();
-    }
-    return result;
-  }
-
-  _dispatch(var x) {
-    if (isPrimitive(x)) return visitPrimitive(x);
-    if (x is List) return visitList(x);
-    if (x is Map) return visitMap(x);
-    if (x is SendPort) return visitSendPort(x);
-    if (x is SendPortSync) return visitSendPortSync(x);
-
-    // Overridable fallback.
-    return visitObject(x);
-  }
-
-  visitPrimitive(x);
-  visitList(List x);
-  visitMap(Map x);
-  visitSendPort(SendPort x);
-  visitSendPortSync(SendPortSync x);
-
-  visitObject(Object x) {
-    // TODO(floitsch): make this a real exception. (which one)?
-    throw "Message serialization: Illegal value $x passed";
-  }
-
-  static bool isPrimitive(x) {
-    return (x == null) || (x is String) || (x is num) || (x is bool);
-  }
-}
-
-
-/** A visitor that recursively copies a message. */
-class _Copier extends _MessageTraverser {
-
-  visitPrimitive(x) => x;
-
-  List visitList(List list) {
-    List copy = _visited[list];
-    if (copy != null) return copy;
-
-    int len = list.length;
-
-    // TODO(floitsch): we loose the generic type of the List.
-    copy = new List(len);
-    _visited[list] = copy;
-    for (int i = 0; i < len; i++) {
-      copy[i] = _dispatch(list[i]);
-    }
-    return copy;
-  }
-
-  Map visitMap(Map map) {
-    Map copy = _visited[map];
-    if (copy != null) return copy;
-
-    // TODO(floitsch): we loose the generic type of the map.
-    copy = new Map();
-    _visited[map] = copy;
-    map.forEach((key, val) {
-      copy[_dispatch(key)] = _dispatch(val);
-    });
-    return copy;
-  }
-
-}
-
-/** Visitor that serializes a message as a JSON array. */
-class _Serializer extends _MessageTraverser {
-  int _nextFreeRefId = 0;
-
-  visitPrimitive(x) => x;
-
-  visitList(List list) {
-    int copyId = _visited[list];
-    if (copyId != null) return ['ref', copyId];
-
-    int id = _nextFreeRefId++;
-    _visited[list] = id;
-    var jsArray = _serializeList(list);
-    // TODO(floitsch): we are losing the generic type.
-    return ['list', id, jsArray];
-  }
-
-  visitMap(Map map) {
-    int copyId = _visited[map];
-    if (copyId != null) return ['ref', copyId];
-
-    int id = _nextFreeRefId++;
-    _visited[map] = id;
-    var keys = _serializeList(map.keys);
-    var values = _serializeList(map.values);
-    // TODO(floitsch): we are losing the generic type.
-    return ['map', id, keys, values];
-  }
-
-  _serializeList(List list) {
-    int len = list.length;
-    var result = new List(len);
-    for (int i = 0; i < len; i++) {
-      result[i] = _dispatch(list[i]);
-    }
-    return result;
-  }
-}
-
-/** Deserializes arrays created with [_Serializer]. */
-class _Deserializer {
-  Map<int, dynamic> _deserialized;
-
-  _Deserializer();
-
-  static bool isPrimitive(x) {
-    return (x == null) || (x is String) || (x is num) || (x is bool);
-  }
-
-  deserialize(x) {
-    if (isPrimitive(x)) return x;
-    // TODO(floitsch): this should be new HashMap<int, var|Dynamic>()
-    _deserialized = new HashMap();
-    return _deserializeHelper(x);
-  }
-
-  _deserializeHelper(x) {
-    if (isPrimitive(x)) return x;
-    assert(x is List);
-    switch (x[0]) {
-      case 'ref': return _deserializeRef(x);
-      case 'list': return _deserializeList(x);
-      case 'map': return _deserializeMap(x);
-      case 'sendport': return deserializeSendPort(x);
-      default: return deserializeObject(x);
-    }
-  }
-
-  _deserializeRef(List x) {
-    int id = x[1];
-    var result = _deserialized[id];
-    assert(result != null);
-    return result;
-  }
-
-  List _deserializeList(List x) {
-    int id = x[1];
-    // We rely on the fact that Dart-lists are directly mapped to Js-arrays.
-    List dartList = x[2];
-    _deserialized[id] = dartList;
-    int len = dartList.length;
-    for (int i = 0; i < len; i++) {
-      dartList[i] = _deserializeHelper(dartList[i]);
-    }
-    return dartList;
-  }
-
-  Map _deserializeMap(List x) {
-    Map result = new Map();
-    int id = x[1];
-    _deserialized[id] = result;
-    List keys = x[2];
-    List values = x[3];
-    int len = keys.length;
-    assert(len == values.length);
-    for (int i = 0; i < len; i++) {
-      var key = _deserializeHelper(keys[i]);
-      var value = _deserializeHelper(values[i]);
-      result[key] = value;
-    }
-    return result;
-  }
-
-  deserializeSendPort(List x);
-
-  deserializeObject(List x) {
-    // TODO(floitsch): Use real exception (which one?).
-    throw "Unexpected serialized object";
-  }
-}
-
-/********************************************************
-  Inserted from lib/isolate/dart2js/timer_provider.dart
- ********************************************************/
-
-// We don't want to import the DOM library just because of window.setTimeout,
-// so we reconstruct the Window class here. The only conflict that could happen
-// with the other DOMWindow class would be because of subclasses.
-// Currently, none of the two Dart classes have subclasses.
-typedef void _TimeoutHandler();
-
-class _Window native "@*DOMWindow" {
-  int setTimeout(_TimeoutHandler handler, int timeout) native;
-  int setInterval(_TimeoutHandler handler, int timeout) native;
-  void clearTimeout(int handle) native;
-  void clearInterval(int handle) native;
-}
-
-_Window get _window =>
-  JS('bool', 'typeof window != "undefined"') ? JS('_Window', 'window') : null;
-
-class _Timer implements Timer {
-  final bool _once;
-  int _handle;
-
-  _Timer(int milliSeconds, void callback(Timer timer))
-      : _once = true {
-    _handle = _window.setTimeout(() => callback(this), milliSeconds);
-  }
-
-  _Timer.repeating(int milliSeconds, void callback(Timer timer))
-      : _once = false {
-    _handle = _window.setInterval(() => callback(this), milliSeconds);
-  }
-
-  void cancel() {
-    if (_once) {
-      _window.clearTimeout(_handle);
-    } else {
-      _window.clearInterval(_handle);
-    }
+    return new ReceivePortImpl();
   }
 }
 
 patch class Timer {
-  patch factory Timer(int milliSeconds, void callback(Timer timer)) {
-    if (_window == null) {
+  patch factory Timer(int milliseconds, void callback(Timer timer)) {
+    if (!hasTimer()) {
       throw new UnsupportedError("Timer interface not supported.");
     }
-    return new _Timer(milliSeconds, callback);
+    return new TimerImpl(milliseconds, callback);
   }
 
   /**
    * Creates a new repeating timer. The [callback] is invoked every
-   * [milliSeconds] millisecond until cancelled.
+   * [milliseconds] millisecond until cancelled.
    */
-  patch factory Timer.repeating(int milliSeconds, void callback(Timer timer)) {
-    if (_window == null) {
+  patch factory Timer.repeating(int milliseconds, void callback(Timer timer)) {
+    if (!hasTimer()) {
       throw new UnsupportedError("Timer interface not supported.");
     }
-    return new _Timer.repeating(milliSeconds, callback);
+    return new TimerImpl.repeating(milliseconds, callback);
   }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_array.dart b/sdk/lib/_internal/compiler/implementation/lib/js_array.dart
index adbea3c..c998775 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_array.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_array.dart
@@ -181,4 +181,10 @@
     checkGrowable(this, 'set length');
     JS('void', r'#.length = #', this, newLength);
   }
+
+  E operator [](int index) {
+    if (index is !int) throw new ArgumentError(index);
+    if (index >= length || index < 0) throw new RangeError.value(index);
+    return JS('var', '#[#]', this, index);
+  }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
index 3fa0f5d..39e1c5c 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
@@ -557,7 +557,7 @@
       if (end <= kMaxApply) {
         subarray = array;
       } else {
-        subarray = JS('=List', r'array.slice(#, #)',
+        subarray = JS('=List', r'#.slice(#, #)', array,
                       i, i + kMaxApply < end ? i + kMaxApply : end);
       }
       result = JS('String', '# + String.fromCharCode.apply(#, #)',
@@ -1016,9 +1016,11 @@
     if (message is String) {
       if (message.endsWith('is null') ||
           message.endsWith('is undefined') ||
-          message.endsWith('is null or undefined')) {
+          message.endsWith('is null or undefined') ||
+          message.endsWith('of null')) {
         return new NoSuchMethodError(null, '<unknown>', [], {});
-      } else if (contains(message, ' is not a function') ||
+      } else if (contains(message, ' has no method ') ||
+                 contains(message, ' is not a function') ||
                  (ieErrorCode == 438 && ieFacilityNumber == 10)) {
         // Examples:
         //  x.foo is not a function
@@ -1632,23 +1634,22 @@
 }
 
 String getTypeArgumentAsString(List runtimeType) {
-  String className = runtimeTypeToString(runtimeType[0]);
+  String className = getConstructorName(runtimeType[0]);
   if (runtimeType.length == 1) return className;
   return '$className<${joinArguments(runtimeType, 1)}>';
 }
 
+String getConstructorName(type) => JS('String', r'#.builtin$cls', type);
+
 String runtimeTypeToString(type) {
   if (type == null) {
     return 'dynamic';
-  } else if (type is String) {
-    // A native class.  The string is the unique name.
-    return type;
   } else if (isJsArray(type)) {
     // A list representing a type with arguments.
     return getTypeArgumentAsString(type);
   } else {
     // A reference to the constructor.
-    return JS('String', r'#.builtin$cls', type);
+    return getConstructorName(type);
   }
 }
 
@@ -1674,13 +1675,37 @@
   return "$className<${joinArguments(typeInfo, 0)}>";
 }
 
+/**
+ * Check whether the type represented by [s] is a subtype of the type
+ * represented by [t].
+ *
+ * Type representations can be:
+ *  1) a JavaScript constructor for a class C: the represented type is the raw
+ *     type C.
+ *  2) a JavaScript object: this represents a class for which there is no
+ *     JavaScript constructor, because it is only used in type arguments or it
+ *     is native. The represented type is the raw type of this class.
+ *  3) a JavaScript array: the first entry is of type 1 or 2 and identifies the
+ *     class of the type and the rest of the array are the type arguments.
+ *  4) [:null:]: the dynamic type.
+ */
 bool isSubtype(var s, var t) {
+  // If either type is dynamic, [s] is a subtype of [t].
   if (s == null || t == null) return true;
-  if (!isJsArray(s)) return s == t;
-  // TODO(karlklose): support subtyping: if s[0] != t[0], check if there is
-  // a function is$s[0] on t[0] and call it with substitutes type arguments.
-  if (s[0] != t[0]) return false;
+  // Subtyping is reflexive.
+  if (s == t) return true;
+  // Get the object describing the class and check for the subtyping flag
+  // constructed from the type of [t].
+  var typeOfS = isJsArray(s) ? s[0] : s;
+  var typeOfT = isJsArray(t) ? t[0] : t;
+  var test = 'is\$${runtimeTypeToString(typeOfT)}';
+  if (JS('var', r'#[#]', typeOfS, test) == null) return false;
+  // The class of [s] is a subclass of the class of [t]. If either of the types
+  // is raw, [s] is a subtype of [t].
+  if (!isJsArray(s) || !isJsArray(t)) return true;
+  // Recursively check the type arguments.
   int len = s.length;
+  if (len != t.length) return false;
   for (int i = 1; i < len; i++) {
     if (!isSubtype(s[i], t[i])) {
       return false;
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_string.dart b/sdk/lib/_internal/compiler/implementation/lib/js_string.dart
index 48a2d01..3b56198 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_string.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_string.dart
@@ -163,4 +163,10 @@
   Type get runtimeType => String;
 
   int get length => JS('int', r'#.length', this);
+
+  String operator [](int index) {
+    if (index is !int) throw new ArgumentError(index);
+    if (index >= length || index < 0) throw new RangeError.value(index);
+    return JS('String', '#[#]', this, index);
+  }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/lib/mirrors.dart b/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart
similarity index 82%
rename from sdk/lib/_internal/compiler/implementation/lib/mirrors.dart
rename to sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart
index 6728d47..8a2f57c 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/mirrors.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart
@@ -2,30 +2,26 @@
 // for 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_mirrors;
-
-import 'dart:isolate';
-
-part '../../../../mirrors/mirrors.dart';
+/**
+ * Patch library for dart:mirrors.
+ */
 
 /**
  * Stub class for the mirror system.
  */
-class _Mirrors {
-  static MirrorSystem currentMirrorSystem() {
-    _ensureEnabled();
-    throw new UnsupportedError("MirrorSystem not implemented");
-  }
+patch MirrorSystem currentMirrorSystem() {
+  _ensureEnabled();
+  throw new UnsupportedError("MirrorSystem not implemented");
+}
 
-  static Future<MirrorSystem> mirrorSystemOf(SendPort port) {
-    _ensureEnabled();
-    throw new UnsupportedError("MirrorSystem not implemented");
-  }
+patch Future<MirrorSystem> mirrorSystemOf(SendPort port) {
+  _ensureEnabled();
+  throw new UnsupportedError("MirrorSystem not implemented");
+}
 
-  static InstanceMirror reflect(Object reflectee) {
-    _ensureEnabled();
-    return new _InstanceMirror(reflectee);
-  }
+patch InstanceMirror reflect(Object reflectee) {
+  _ensureEnabled();
+  return new _InstanceMirror(reflectee);
 }
 
 class _InstanceMirror extends InstanceMirror {
diff --git a/sdk/lib/_internal/compiler/implementation/lib/native_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/native_helper.dart
index f6f88c7..a41efdc 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/native_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/native_helper.dart
@@ -71,6 +71,13 @@
   if (name == 'MSStyleCSSProperties') return 'CSSStyleDeclaration';
   if (name == 'MouseWheelEvent') return 'WheelEvent';
   if (name == 'Position') return 'Geoposition';
+
+  // Patches for types which report themselves as Objects.
+  if (name == 'Object') {
+    if (JS('bool', 'window.DataView && (# instanceof window.DataView)', obj)) {
+      return 'DataView';
+    }
+  }
   return name;
 }
 
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
index 398d641..acff12a 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
@@ -79,7 +79,9 @@
     // TODO(johnniwinther): We need a mirror on malformed types.
     return system.dynamicType;
   }
-  throw new ArgumentError("Unexpected type $type of kind ${type.kind}");
+  _diagnosticListener.internalError(
+      "Unexpected type $type of kind ${type.kind}");
+  system.compiler.internalError("Unexpected type $type of kind ${type.kind}");
 }
 
 Collection<Dart2JsMemberMirror> _convertElementMemberToMemberMirrors(
@@ -100,7 +102,7 @@
     }
     return members;
   }
-  throw new ArgumentError(
+  library.mirrors.compiler.internalError(
       "Unexpected member type $element ${element.kind}");
 }
 
@@ -113,6 +115,30 @@
   }
 }
 
+InstanceMirror _convertConstantToInstanceMirror(Dart2JsMirrorSystem mirrors,
+                                                Constant constant) {
+  if (constant is BoolConstant) {
+    return new Dart2JsBoolConstantMirror(mirrors, constant);
+  } else if (constant is NumConstant) {
+    return new Dart2JsNumConstantMirror(mirrors, constant);
+  } else if (constant is StringConstant) {
+    return new Dart2JsStringConstantMirror(mirrors, constant);
+  } else if (constant is ListConstant) {
+    return new Dart2JsListConstantMirror(mirrors, constant);
+  } else if (constant is MapConstant) {
+    return new Dart2JsMapConstantMirror(mirrors, constant);
+  } else if (constant is TypeConstant) {
+    return new Dart2JsTypeConstantMirror(mirrors, constant);
+  } else if (constant is FunctionConstant) {
+    return new Dart2JsConstantMirror(mirrors, constant);
+  } else if (constant is NullConstant) {
+    return new Dart2JsNullConstantMirror(mirrors, constant);
+  } else if (constant is ConstructedConstant) {
+    return new Dart2JsConstructedConstantMirror(mirrors, constant);
+  }
+  mirrors.compiler.internalError("Unexpected constant $constant");
+}
+
 class Dart2JsMethodKind {
   static const Dart2JsMethodKind REGULAR = const Dart2JsMethodKind("regular");
   static const Dart2JsMethodKind GENERATIVE =
@@ -407,12 +433,40 @@
   Dart2JsMirrorSystem get mirrors;
 }
 
-abstract class Dart2JsDeclarationMirror
-    implements Dart2JsMirror, DeclarationMirror {
+abstract class Dart2JsDeclarationMirror extends Dart2JsMirror
+    implements DeclarationMirror {
 
   bool get isTopLevel => owner != null && owner is LibraryMirror;
 
   bool get isPrivate => _isPrivate(simpleName);
+
+  /**
+   * Returns the first token for the source of this declaration.
+   */
+  Token getBeginToken();
+
+  /**
+   * Returns the last token for the source of this declaration.
+   */
+  Token getEndToken();
+
+  /**
+   * Returns the script for the source of this declaration.
+   */
+  Script getScript();
+
+  SourceLocation get location {
+    Token beginToken = getBeginToken();
+    Script script = getScript();
+    SourceSpan span;
+    if (beginToken == null) {
+      span = new SourceSpan(script.uri, 0, 0);
+    } else {
+      Token endToken = getEndToken();
+      span = mirrors.compiler.spanFromTokens(beginToken, endToken, script.uri);
+    }
+    return new Dart2JsSourceLocation(script, span);
+  }
 }
 
 abstract class Dart2JsMemberMirror extends Dart2JsElementMirror
@@ -440,6 +494,7 @@
 abstract class Dart2JsElementMirror extends Dart2JsDeclarationMirror {
   final Dart2JsMirrorSystem mirrors;
   final Element _element;
+  List<InstanceMirror> _metadata;
 
   Dart2JsElementMirror(this.mirrors, this._element) {
     assert (mirrors != null);
@@ -450,30 +505,65 @@
 
   String get displayName => simpleName;
 
-  SourceLocation get location => new Dart2JsSourceLocation(
-      _element.getCompilationUnit().script,
-      mirrors.compiler.spanFromElement(_element));
+  /**
+   * Computes the first token for this declaration using the first metadata
+   * annotation, the begin token of the element node or element position as
+   * indicator.
+   */
+  Token getBeginToken() {
+    if (!_element.metadata.isEmpty) {
+      for (MetadataAnnotation metadata in _element.metadata) {
+        if (metadata.beginToken != null) {
+          return metadata.beginToken;
+        }
+      }
+    }
+    // TODO(johnniwinther): Avoid calling [parseNode].
+    Node node = _element.parseNode(mirrors.compiler);
+    if (node == null) {
+      return _element.position();
+    }
+    return node.getBeginToken();
+  }
+
+  /**
+   * Computes the last token for this declaration using the end token of the
+   * element node or element position as indicator.
+   */
+  Token getEndToken() {
+    // TODO(johnniwinther): Avoid calling [parseNode].
+    Node node = _element.parseNode(mirrors.compiler);
+    if (node == null) {
+      return _element.position();
+    }
+    return node.getEndToken();
+  }
+
+  Script getScript() => _element.getCompilationUnit().script;
 
   String toString() => _element.toString();
 
   int get hashCode => qualifiedName.hashCode;
-}
 
-abstract class Dart2JsProxyMirror extends Dart2JsDeclarationMirror {
-  final Dart2JsMirrorSystem mirrors;
-
-  Dart2JsProxyMirror(this.mirrors);
-
-  String get displayName => simpleName;
-
-  int get hashCode => qualifiedName.hashCode;
+  List<InstanceMirror> get metadata {
+    if (_metadata == null) {
+      _metadata = <InstanceMirror>[];
+      for (MetadataAnnotation metadata in _element.metadata) {
+        metadata.ensureResolved(mirrors.compiler);
+        _metadata.add(
+            _convertConstantToInstanceMirror(mirrors, metadata.value));
+      }
+    }
+    // TODO(johnniwinther): Return an unmodifiable list instead.
+    return new List<InstanceMirror>.from(_metadata);
+  }
 }
 
 //------------------------------------------------------------------------------
 // Mirror system implementation.
 //------------------------------------------------------------------------------
 
-class Dart2JsMirrorSystem implements MirrorSystem, Dart2JsMirror {
+class Dart2JsMirrorSystem implements MirrorSystem {
   final api.Compiler compiler;
   Map<String, Dart2JsLibraryMirror> _libraries;
   Map<LibraryElement, Dart2JsLibraryMirror> _libraryMap;
@@ -639,15 +729,35 @@
     return new ImmutableMapWrapper<String, ClassMirror>(_classes);
   }
 
-  SourceLocation get location {
-    var script = _library.getCompilationUnit().script;
-    SourceSpan span;
-    if (_library.libraryTag != null) {
-      span = mirrors.compiler.spanFromNode(_library.libraryTag, script.uri);
-    } else {
-      span = new SourceSpan(script.uri, 0, 0);
+  /**
+   * Computes the first token of this library using the first metadata
+   * annotation or the first library tag as indicator.
+   */
+  Token getBeginToken() {
+    if (!_element.metadata.isEmpty) {
+      for (MetadataAnnotation metadata in _element.metadata) {
+        if (metadata.beginToken != null) {
+          return metadata.beginToken;
+        }
+      }
     }
-    return new Dart2JsSourceLocation(script, span);
+    if (_library.libraryTag != null) {
+      return _library.libraryTag.getBeginToken();
+    } else if (!_library.tags.isEmpty) {
+      return _library.tags.reverse().head.getBeginToken();
+    }
+    return null;
+  }
+
+  /**
+   * Computes the first token of this library using the last library tag as
+   * indicator.
+   */
+  Token getEndToken() {
+    if (!_library.tags.isEmpty) {
+      return _library.tags.head.getEndToken();
+    }
+    return null;
   }
 }
 
@@ -829,18 +939,6 @@
 
   String get qualifiedName => '${library.qualifiedName}.${simpleName}';
 
-  SourceLocation get location {
-    if (_class is PartialClassElement) {
-      var node = _class.parseNode(mirrors.compiler);
-      if (node != null) {
-        var script = _class.getCompilationUnit().script;
-        var span = mirrors.compiler.spanFromNode(node, script.uri);
-        return new Dart2JsSourceLocation(script, span);
-      }
-    }
-    return super.location;
-  }
-
   void _ensureMembers() {
     if (_members == null) {
       _members = <String, Dart2JsMemberMirror>{};
@@ -965,16 +1063,6 @@
 
   String get qualifiedName => '${library.qualifiedName}.${simpleName}';
 
-  SourceLocation get location {
-    var node = _typedef.element.parseNode(_diagnosticListener);
-    if (node != null) {
-      var script = _typedef.element.getCompilationUnit().script;
-      var span = mirrors.compiler.spanFromNode(node, script.uri);
-      return new Dart2JsSourceLocation(script, span);
-    }
-    return super.location;
-  }
-
   LibraryMirror get library => _library;
 
   bool get isTypedef => true;
@@ -1083,21 +1171,16 @@
 // Types
 //------------------------------------------------------------------------------
 
-abstract class Dart2JsTypeElementMirror extends Dart2JsProxyMirror
+abstract class Dart2JsTypeElementMirror extends Dart2JsElementMirror
     implements Dart2JsTypeMirror {
   final DartType _type;
 
-  Dart2JsTypeElementMirror(Dart2JsMirrorSystem system, this._type)
-    : super(system);
+  Dart2JsTypeElementMirror(Dart2JsMirrorSystem system, DartType type)
+    : super(system, type.element),
+      this._type = type;
 
   String get simpleName => _type.name.slowToString();
 
-  SourceLocation get location {
-    var script = _type.element.getCompilationUnit().script;
-    return new Dart2JsSourceLocation(script,
-        mirrors.compiler.spanFromElement(_type.element));
-  }
-
   DeclarationMirror get owner => library;
 
   LibraryMirror get library {
@@ -1116,7 +1199,7 @@
 
   bool get isFunction => false;
 
-  String toString() => _type.element.toString();
+  String toString() => _type.toString();
 
   Map<String, MemberMirror> get members => const <String, MemberMirror>{};
 
@@ -1511,17 +1594,6 @@
   bool get isSetter => _kind == Dart2JsMethodKind.SETTER;
 
   bool get isOperator => _kind == Dart2JsMethodKind.OPERATOR;
-
-  SourceLocation get location {
-    var node = _function.parseNode(_diagnosticListener);
-    if (node != null) {
-      var script = _function.getCompilationUnit().script;
-      var span = mirrors.compiler.spanFromNode(node, script.uri);
-      return new Dart2JsSourceLocation(script, span);
-    }
-    return super.location;
-  }
-
 }
 
 class Dart2JsFieldMirror extends Dart2JsMemberMirror implements VariableMirror {
@@ -1552,16 +1624,181 @@
   TypeMirror get type => _convertTypeToTypeMirror(mirrors,
       _variable.computeType(mirrors.compiler),
       mirrors.compiler.types.dynamicType);
+}
 
-  SourceLocation get location {
-    var script = _variable.getCompilationUnit().script;
-    var node = _variable.variables.parseNode(_diagnosticListener);
-    if (node != null) {
-      var span = mirrors.compiler.spanFromNode(node, script.uri);
-      return new Dart2JsSourceLocation(script, span);
-    } else {
-      var span = mirrors.compiler.spanFromElement(_variable);
-      return new Dart2JsSourceLocation(script, span);
-    }
+////////////////////////////////////////////////////////////////////////////////
+// Mirrors on constant values used for metadata.
+////////////////////////////////////////////////////////////////////////////////
+
+class Dart2JsConstantMirror extends InstanceMirror {
+  final Dart2JsMirrorSystem mirrors;
+  final Constant _constant;
+
+  Dart2JsConstantMirror(this.mirrors, this._constant);
+
+  ClassMirror get type {
+    return new Dart2JsClassMirror(mirrors,
+        _constant.computeType(mirrors.compiler).element);
+  }
+
+  bool get hasReflectee => false;
+
+  get reflectee {
+    // TODO(johnniwinther): Which exception/error should be thrown here?
+    throw new UnsupportedError('InstanceMirror does not have a reflectee');
+  }
+
+  Future<InstanceMirror> getField(String fieldName) {
+    // TODO(johnniwinther): Which exception/error should be thrown here?
+    throw new UnsupportedError('InstanceMirror does not have a reflectee');
   }
 }
+
+class Dart2JsNullConstantMirror extends Dart2JsConstantMirror {
+  Dart2JsNullConstantMirror(Dart2JsMirrorSystem mirrors, NullConstant constant)
+      : super(mirrors, constant);
+
+  NullConstant get _constant => super._constant;
+
+  bool get hasReflectee => true;
+
+  get reflectee => null;
+}
+
+class Dart2JsBoolConstantMirror extends Dart2JsConstantMirror {
+  Dart2JsBoolConstantMirror(Dart2JsMirrorSystem mirrors, BoolConstant constant)
+      : super(mirrors, constant);
+
+  BoolConstant get _constant => super._constant;
+
+  bool get hasReflectee => true;
+
+  get reflectee => _constant is TrueConstant;
+}
+
+class Dart2JsStringConstantMirror extends Dart2JsConstantMirror {
+  Dart2JsStringConstantMirror(Dart2JsMirrorSystem mirrors,
+                              StringConstant constant)
+      : super(mirrors, constant);
+
+  StringConstant get _constant => super._constant;
+
+  bool get hasReflectee => true;
+
+  get reflectee => _constant.value.slowToString();
+}
+
+class Dart2JsNumConstantMirror extends Dart2JsConstantMirror {
+  Dart2JsNumConstantMirror(Dart2JsMirrorSystem mirrors,
+                           NumConstant constant)
+      : super(mirrors, constant);
+
+  NumConstant get _constant => super._constant;
+
+  bool get hasReflectee => true;
+
+  get reflectee => _constant.value;
+}
+
+class Dart2JsListConstantMirror extends Dart2JsConstantMirror
+    implements ListInstanceMirror {
+  Dart2JsListConstantMirror(Dart2JsMirrorSystem mirrors,
+                            ListConstant constant)
+      : super(mirrors, constant);
+
+  ListConstant get _constant => super._constant;
+
+  int get length => _constant.length;
+
+  Future<InstanceMirror> operator[](int index) {
+    if (index < 0) throw new RangeError('Negative index');
+    if (index >= _constant.length) throw new RangeError('Index out of bounds');
+    return new Future<InstanceMirror>.immediate(
+        _convertConstantToInstanceMirror(mirrors, _constant.entries[index]));
+  }
+}
+
+class Dart2JsMapConstantMirror extends Dart2JsConstantMirror
+    implements MapInstanceMirror {
+  List<String> _listCache;
+
+  Dart2JsMapConstantMirror(Dart2JsMirrorSystem mirrors,
+                           MapConstant constant)
+      : super(mirrors, constant);
+
+  MapConstant get _constant => super._constant;
+
+  List<String> get _list {
+    if (_listCache == null) {
+      _listCache = new List<String>(_constant.keys.entries.length);
+      int index = 0;
+      for (StringConstant keyConstant in _constant.keys.entries) {
+        _listCache[index] = keyConstant.value.slowToString();
+        index++;
+      }
+    }
+    return _listCache;
+  }
+
+  int get length => _constant.length;
+
+  Collection<String> get keys {
+    // TODO(johnniwinther): Return an unmodifiable list instead.
+    return new List<String>.from(_list);
+  }
+
+  Future<InstanceMirror> operator[](String key) {
+    int index = _list.indexOf(key);
+    if (index == -1) return null;
+    return new Future<InstanceMirror>.immediate(
+        _convertConstantToInstanceMirror(mirrors, _constant.values[index]));
+  }
+}
+
+class Dart2JsTypeConstantMirror extends Dart2JsConstantMirror
+    implements TypeInstanceMirror {
+
+  Dart2JsTypeConstantMirror(Dart2JsMirrorSystem mirrors,
+                            TypeConstant constant)
+      : super(mirrors, constant);
+
+  TypeConstant get _constant => super._constant;
+
+  TypeMirror get representedType => _convertTypeToTypeMirror(
+      mirrors, _constant.representedType, mirrors.compiler.types.dynamicType);
+}
+
+class Dart2JsConstructedConstantMirror extends Dart2JsConstantMirror {
+  Map<String,Constant> _fieldMapCache;
+
+  Dart2JsConstructedConstantMirror(Dart2JsMirrorSystem mirrors,
+                                   ConstructedConstant constant)
+      : super(mirrors, constant);
+
+  ConstructedConstant get _constant => super._constant;
+
+  Map<String,Constant> get _fieldMap {
+    if (_fieldMapCache == null) {
+      _fieldMapCache = new LinkedHashMap<String,Constant>();
+      if (identical(_constant.type.element.kind, ElementKind.CLASS)) {
+        var index = 0;
+        ClassElement element = _constant.type.element;
+        element.forEachInstanceField((_, Element field) {
+          String fieldName = field.name.slowToString();
+          _fieldMapCache.putIfAbsent(fieldName, () => _constant.fields[index]);
+          index++;
+        }, includeBackendMembers: true, includeSuperMembers: true);
+      }
+    }
+    return _fieldMapCache;
+  }
+
+  Future<InstanceMirror> getField(String fieldName) {
+    Constant fieldConstant = _fieldMap[fieldName];
+    if (fieldConstant != null) {
+      return new Future<InstanceMirror>.immediate(
+          _convertConstantToInstanceMirror(mirrors, fieldConstant));
+    }
+    return super.getField(fieldName);
+  }
+}
\ No newline at end of file
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart b/sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart
index 9b7384b..19e5cc0 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart
@@ -75,6 +75,7 @@
 abstract class Mirror {
   static const String UNARY_MINUS = 'unary-';
 
+  // TODO(johnniwinther): Do we need this on all mirrors?
   /**
    * Returns the mirror system which contains this mirror.
    */
@@ -140,6 +141,94 @@
    *    [:mirror.owner != null && mirror.owner is LibraryMirror:]
    */
   bool get isTopLevel;
+
+  /**
+   * A list of the metadata associated with this declaration.
+   */
+  List<InstanceMirror> get metadata;
+}
+
+abstract class ObjectMirror implements Mirror {
+  /**
+   * Invokes a getter and returns a mirror on the result. The getter
+   * can be the implicit getter for a field or a user-defined getter
+   * method.
+   */
+  Future<InstanceMirror> getField(String fieldName);
+}
+
+/**
+ * An [InstanceMirror] reflects an instance of a Dart language object.
+ */
+abstract class InstanceMirror implements ObjectMirror {
+  /**
+   * A mirror on the type of the reflectee.
+   */
+  ClassMirror get type;
+
+  /**
+   * Does [reflectee] contain the instance reflected by this mirror?
+   * This will always be true in the local case (reflecting instances
+   * in the same isolate), but only true in the remote case if this
+   * mirror reflects a simple value.
+   *
+   * A value is simple if one of the following holds:
+   *  - the value is null
+   *  - the value is of type [num]
+   *  - the value is of type [bool]
+   *  - the value is of type [String]
+   */
+  bool get hasReflectee;
+
+  /**
+   * If the [InstanceMirror] reflects an instance it is meaningful to
+   * have a local reference to, we provide access to the actual
+   * instance here.
+   *
+   * If you access [reflectee] when [hasReflectee] is false, an
+   * exception is thrown.
+   */
+  get reflectee;
+}
+
+/**
+ * Specialized [InstanceMirror] used for reflection on constant lists.
+ */
+abstract class ListInstanceMirror
+    implements InstanceMirror, Sequence<Future<InstanceMirror>> {
+
+}
+
+/**
+ * Specialized [InstanceMirror] used for reflection on constant maps.
+ */
+abstract class MapInstanceMirror implements InstanceMirror {
+  /**
+   * Returns a collection containing all the keys in the map.
+   */
+  Collection<String> get keys;
+
+  /**
+   * Returns a future on the instance mirror of the value for the given key or
+   * null if key is not in the map.
+   */
+  Future<InstanceMirror> operator[](String key);
+
+  /**
+   * The number of {key, value} pairs in the map.
+   */
+  int get length;
+}
+
+/**
+ * Specialized [InstanceMirror] used for reflection on type constants.
+ */
+abstract class TypeInstanceMirror implements InstanceMirror {
+  /**
+   * Returns the type mirror for the type represented by the reflected type
+   * constant.
+   */
+  TypeMirror get representedType;
 }
 
 /**
@@ -620,3 +709,12 @@
    */
   String get sourceText;
 }
+
+/**
+ * Class used for encoding dartdoc comments as metadata annotations.
+ */
+class DartdocComment {
+  final String text;
+
+  const DartdocComment(this.text);
+}
\ No newline at end of file
diff --git a/sdk/lib/_internal/compiler/implementation/native_handler.dart b/sdk/lib/_internal/compiler/implementation/native_handler.dart
index 38f8439..4367c6d 100644
--- a/sdk/lib/_internal/compiler/implementation/native_handler.dart
+++ b/sdk/lib/_internal/compiler/implementation/native_handler.dart
@@ -34,7 +34,6 @@
 class NativeEnqueuer {
   /// Initial entry point to native enqueuer.
   void processNativeClasses(Collection<LibraryElement> libraries) {}
-  void processNativeClassesInLibrary(LibraryElement library) {}
 
   /// Notification of a main Enqueuer worklist element.  For methods, adds
   /// information from metadata attributes, and computes types instantiated due
@@ -104,6 +103,7 @@
 
   void processNativeClasses(Collection<LibraryElement> libraries) {
     libraries.forEach(processNativeClassesInLibrary);
+    processNativeClassesInLibrary(compiler.isolateHelperLibrary);
     if (!enableLiveTypeAnalysis) {
       nativeClasses.forEach((c) => enqueueClass(c, 'forced'));
       flushQueue();
@@ -113,19 +113,19 @@
   void processNativeClassesInLibrary(LibraryElement library) {
     // Use implementation to ensure the inclusion of injected members.
     library.implementation.forEachLocalMember((Element element) {
-      if (element.kind == ElementKind.CLASS) {
-        ClassElement classElement = element;
-        if (classElement.isNative()) {
-          nativeClasses.add(classElement);
-          unusedClasses.add(classElement);
-
-          // Resolve class to ensure the class has valid inheritance info.
-          classElement.ensureResolved(compiler);
-        }
+      if (element.isClass() && element.isNative()) {
+        processNativeClass(element);
       }
     });
   }
 
+  void processNativeClass(ClassElement classElement) {
+    nativeClasses.add(classElement);
+    unusedClasses.add(classElement);
+    // Resolve class to ensure the class has valid inheritance info.
+    classElement.ensureResolved(compiler);
+  }
+
   ClassElement get annotationCreatesClass {
     findAnnotationClasses();
     return _annotationCreatesClass;
@@ -323,7 +323,8 @@
         } else if (type.element == compiler.doubleClass) {
           world.registerInstantiatedClass(compiler.doubleClass);
         } else if (type.element == compiler.numClass) {
-          world.registerInstantiatedClass(compiler.numClass);
+          world.registerInstantiatedClass(compiler.doubleClass);
+          world.registerInstantiatedClass(compiler.intClass);
         } else if (type.element == compiler.stringClass) {
           world.registerInstantiatedClass(compiler.stringClass);
         } else if (type.element == compiler.nullClass) {
@@ -453,7 +454,6 @@
   String libraryName = uri.toString();
   if (library.entryCompilationUnit.script.name.contains(
           'dart/tests/compiler/dart2js_native')
-      || libraryName == 'dart:isolate'
       || libraryName == 'dart:html'
       || libraryName == 'dart:html_common'
       || libraryName == 'dart:indexed_db'
@@ -872,26 +872,11 @@
         new HForeign(jsCode, const LiteralDartString('Object'), inputs));
     builder.close(new HReturn(builder.pop())).addSuccessor(builder.graph.exit);
   } else {
-    // This is JS code written in a Dart file with the construct
-    // native """ ... """;. It does not work well with mangling,
-    // but there should currently be no clash between leg mangling
-    // and the library where this construct is being used. This
-    // mangling problem will go away once we switch these libraries
-    // to use Leg's 'JS' function.
-    parameters.forEachParameter((Element parameter) {
-      DartType type = parameter.computeType(compiler).unalias(compiler);
-      if (type is FunctionType) {
-        // The parameter type is a function type either directly or through
-        // typedef(s).
-        HInstruction jsClosure = convertDartClosure(parameter, type);
-        // Because the JS code references the argument name directly,
-        // we must keep the name and assign the JS closure to it.
-        builder.add(new HForeign(
-            new DartString.literal('${parameter.name.slowToString()} = #'),
-            const LiteralDartString('void'),
-            <HInstruction>[jsClosure]));
-      }
-    });
+    if (parameters.parameterCount != 0) {
+      compiler.cancel(
+          'native "..." syntax is restricted to functions with zero parameters',
+          node: nativeBody);
+    }
     LiteralString jsCode = nativeBody.asLiteralString();
     builder.push(new HForeign.statement(jsCode.dartString, <HInstruction>[]));
   }
diff --git a/sdk/lib/_internal/compiler/implementation/patch_parser.dart b/sdk/lib/_internal/compiler/implementation/patch_parser.dart
index 009e22d..55254bf 100644
--- a/sdk/lib/_internal/compiler/implementation/patch_parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/patch_parser.dart
@@ -502,4 +502,6 @@
   final leg.Constant value = null;
 
   PatchMetadataAnnotation() : super(STATE_DONE);
+
+  Token get beginToken => null;
 }
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart b/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
index 75bbdda..8a018c1 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
@@ -139,6 +139,12 @@
       if (isNested(userLoopHeader, currentLoopHeader)) return true;
     }
 
+    bool isIndexOperatorOnIndexablePrimitive(instruction, types) {
+      return instruction is HIndex
+          || (instruction is HInvokeDynamicMethod
+              && instruction.isIndexOperatorOnIndexablePrimitive(types));
+    }
+
     // To speed up computations on values loaded from arrays, we
     // insert type guards for builtin array indexing operations in
     // nested loops. Since this can blow up code size quite
@@ -146,9 +152,8 @@
     // inserted for this method. The code size price for an additional
     // type guard is much smaller than the first one that causes the
     // generation of a bailout method.
-    if (instruction is HIndex &&
-        (instruction as HIndex).isBuiltin(types) &&
-        hasTypeGuards) {
+    if (hasTypeGuards
+        && isIndexOperatorOnIndexablePrimitive(instruction, types)) {
       HBasicBlock loopHeader = instruction.block.enclosingLoopHeader;
       if (loopHeader != null && loopHeader.parentLoopHeader != null) {
         return true;
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index cc3f726..277be1e 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -2702,13 +2702,7 @@
 
     Operator op = node.selector;
     if (const SourceString("[]") == op.source) {
-      HStatic target = new HStatic(interceptors.getIndexInterceptor());
-      add(target);
-      visit(node.receiver);
-      HInstruction receiver = pop();
-      visit(node.argumentsNode);
-      HInstruction index = pop();
-      push(new HIndex(target, receiver, index));
+      visitDynamicSend(node);
     } else if (const SourceString("&&") == op.source ||
                const SourceString("||") == op.source) {
       visitLogicalAndOr(node, op);
@@ -2950,6 +2944,26 @@
     pushWithPosition(new HInvokeClosure(selector, inputs), node);
   }
 
+  void registerForeignTypes(String specString) {
+    Enqueuer enqueuer = compiler.enqueuer.codegen;
+    for (final typeString in specString.split('|')) {
+      if (typeString == '=List') {
+        enqueuer.registerInstantiatedClass(compiler.listClass);
+      } else if (typeString == 'int') {
+        enqueuer.registerInstantiatedClass(compiler.intClass);
+      } else if (typeString == 'double') {
+        enqueuer.registerInstantiatedClass(compiler.doubleClass);
+      } else if (typeString == 'num') {
+        enqueuer.registerInstantiatedClass(compiler.intClass);
+        enqueuer.registerInstantiatedClass(compiler.doubleClass);
+      } else if (typeString == 'Null') {
+        enqueuer.registerInstantiatedClass(compiler.nullClass);
+      } else if (typeString == 'String') {
+        enqueuer.registerInstantiatedClass(compiler.stringClass);
+      }
+    }
+  }
+
   void handleForeignJs(Send node) {
     Link<Node> link = node.arguments;
     // If the invoke is on foreign code, don't visit the first
@@ -2970,6 +2984,10 @@
                       node: type);
     }
     LiteralString typeString = type;
+    // TODO(ngeoffray): This should be registered in codegen, not here.
+    // Also, we should share the type parsing with the native
+    // enqueuer.
+    registerForeignTypes(typeString.dartString.slowToString());
 
     if (code is StringNode) {
       StringNode codeString = code;
@@ -3027,7 +3045,7 @@
       // Call a helper method from the isolate library. The isolate
       // library uses its own isolate structure, that encapsulates
       // Leg's isolate.
-      Element element = compiler.isolateLibrary.find(
+      Element element = compiler.isolateHelperLibrary.find(
           const SourceString('_currentIsolate'));
       if (element == null) {
         compiler.cancel(
@@ -3047,7 +3065,7 @@
       push(new HInvokeClosure(selector, <HInstruction>[pop()]));
     } else {
       // Call a helper method from the isolate library.
-      Element element = compiler.isolateLibrary.find(
+      Element element = compiler.isolateHelperLibrary.find(
           const SourceString('_callInIsolate'));
       if (element == null) {
         compiler.cancel(
@@ -3139,7 +3157,9 @@
         compiler.findHelper(Compiler.CREATE_INVOCATION_MIRROR);
 
     var arguments = new List<HInstruction>();
-    addGenericSendArgumentsToList(node.arguments, arguments);
+    if (node.argumentsNode != null) {
+      addGenericSendArgumentsToList(node.arguments, arguments);
+    }
     var argumentsInstruction = new HLiteralList(arguments);
     add(argumentsInstruction);
 
@@ -3594,11 +3614,26 @@
         // on type arguments.
         generateRuntimeError(node, '$type is malformed: $reasons');
       } else {
+        // TODO(karlklose): move this type registration to the codegen.
+        compiler.codegenWorld.instantiatedTypes.add(type);
         visitNewSend(node.send, type);
       }
     }
   }
 
+  HInvokeDynamicMethod buildInvokeDynamicWithOneArgument(
+      Node node, Selector selector, HInstruction receiver, HInstruction arg0) {
+    Set<ClassElement> interceptedClasses =
+        getInterceptedClassesOn(node, selector);
+    List<HInstruction> inputs = <HInstruction>[];
+    if (interceptedClasses != null) {
+      inputs.add(invokeInterceptor(interceptedClasses, receiver, node));
+    }
+    inputs.add(receiver);
+    inputs.add(arg0);
+    return new HInvokeDynamicMethod(selector, inputs);
+  }
+
   visitSendSet(SendSet node) {
     Element element = elements[node];
     if (!Elements.isUnresolved(element) && element.impliesType()) {
@@ -3650,9 +3685,9 @@
             index = pop();
             value = graph.addConstantInt(1, constantSystem);
           }
-          HStatic indexMethod = new HStatic(interceptors.getIndexInterceptor());
-          add(indexMethod);
-          HInstruction left = new HIndex(indexMethod, receiver, index);
+
+          HInvokeDynamicMethod left = buildInvokeDynamicWithOneArgument(
+              node, new Selector.index(), receiver, index);
           add(left);
           Element opElement = elements[op];
           visitBinary(left, op, value);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
index bf500a8..324cc59 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
@@ -37,9 +37,8 @@
     return result;
   }
 
-  CodeBuffer prettyPrint(js.Node node, {bool allowVariableMinification: true}) {
-    var code = js.prettyPrint(
-        node, compiler, allowVariableMinification: allowVariableMinification);
+  CodeBuffer prettyPrint(js.Node node) {
+    var code = js.prettyPrint(node, compiler, allowVariableMinification: true);
     return code;
   }
 
@@ -73,7 +72,6 @@
       FunctionElement element = work.element;
       js.Block body;
       ClassElement enclosingClass = element.getEnclosingClass();
-      bool allowVariableMinification = !codegen.inhibitVariableMinification;
 
       if (element.isInstanceMember()
           && enclosingClass.isNative()
@@ -92,8 +90,7 @@
       }
 
       js.Fun fun = buildJavaScriptFunction(element, codegen.parameters, body);
-      return prettyPrint(fun,
-                         allowVariableMinification: allowVariableMinification);
+      return prettyPrint(fun);
     });
   }
 
@@ -163,8 +160,6 @@
    */
   bool isGeneratingExpression = false;
 
-  bool inhibitVariableMinification = false;
-
   final JavaScriptBackend backend;
   final WorkItem work;
   final HTypeMap types;
@@ -1777,17 +1772,8 @@
     assignVariable(variableNames.getName(node.receiver), pop());
   }
 
-  // TODO(sra): We could be more picky about when to inhibit renaming of locals
-  // - most JS strings don't contain free variables, or contain safe ones like
-  // 'Object'.  JS strings like "#.length" and "#[#]" are perfectly safe for
-  // variable renaming.  For now, be shy of any potential identifiers.
-  static final RegExp safeCodeRegExp = new RegExp(r'^[^_$a-zA-Z]*$');
-
   visitForeign(HForeign node) {
     String code = node.code.slowToString();
-    if (!safeCodeRegExp.hasMatch(code)) {
-      inhibitVariableMinification = true;
-    }
     List<HInstruction> inputs = node.inputs;
     if (node.isJsStatement(types)) {
       if (!inputs.isEmpty) {
@@ -2166,14 +2152,10 @@
   }
 
   void visitIndex(HIndex node) {
-    if (node.isBuiltin(types)) {
-      use(node.inputs[1]);
-      js.Expression receiver = pop();
-      use(node.inputs[2]);
-      push(new js.PropertyAccess(receiver, pop()), node);
-    } else {
-      visitInvokeStatic(node);
-    }
+    use(node.receiver);
+    js.Expression receiver = pop();
+    use(node.index);
+    push(new js.PropertyAccess(receiver, pop()), node);
   }
 
   void visitIndexAssign(HIndexAssign node) {
@@ -2274,6 +2256,11 @@
     push(new js.Binary('==', pop(), new js.LiteralNull()));
   }
 
+  void checkNonNull(HInstruction input) {
+    use(input);
+    push(new js.Binary('!=', pop(), new js.LiteralNull()));
+  }
+
   void checkFunction(HInstruction input, DartType type) {
     checkTypeOf(input, '===', 'function');
     js.Expression functionTest = pop();
@@ -2398,6 +2385,12 @@
                || 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 (types[input].canBePrimitive() || types[input].canBeNull()) {
       checkObject(input, '===');
       js.Expression objectTest = pop();
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/js_names.dart b/sdk/lib/_internal/compiler/implementation/ssa/js_names.dart
index 4a4ae60..3600a09 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/js_names.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/js_names.dart
@@ -156,6 +156,7 @@
       const <String>["__PROTO__", "prototype", "constructor"];
 
   static Set<String> _reserved;
+  static Set<String> _reservedNativeProperties;
 
   static Set<String> get reserved {
     if (_reserved == null) {
@@ -167,6 +168,16 @@
     return _reserved;
   }
 
+  static Set<String> get reservedNativeProperties {
+    // TODO(sra): We need a complete list from the DOM.
+    if (_reservedNativeProperties == null) {
+      const names = const <String>["x", "y", "z"];
+      _reservedNativeProperties = new Set<String>();
+      _reservedNativeProperties.addAll(names);
+    }
+    return _reservedNativeProperties;
+  }
+
   // TODO(ngeoffray): only the namer should call this method.
   // Eventually move it there.
   /*
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index afee28a..44a11fd 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -292,7 +292,7 @@
   visitGreaterEqual(HGreaterEqual node) => visitRelational(node);
   visitIdentity(HIdentity node) => visitRelational(node);
   visitIf(HIf node) => visitConditionalBranch(node);
-  visitIndex(HIndex node) => visitInvokeStatic(node);
+  visitIndex(HIndex node) => visitInstruction(node);
   visitIndexAssign(HIndexAssign node) => visitInvokeStatic(node);
   visitIntegerCheck(HIntegerCheck node) => visitCheck(node);
   visitInterceptor(HInterceptor node) => visitInstruction(node);
@@ -1323,8 +1323,34 @@
 class HInvokeDynamicMethod extends HInvokeDynamic {
   HInvokeDynamicMethod(Selector selector, List<HInstruction> inputs)
     : super(selector, null, inputs);
-  toString() => 'invoke dynamic method: $selector';
+  String toString() => 'invoke dynamic method: $selector';
   accept(HVisitor visitor) => visitor.visitInvokeDynamicMethod(this);
+
+  bool isIndexOperatorOnIndexablePrimitive(HTypeMap types) {
+    return isInterceptorCall
+        && selector.kind == SelectorKind.INDEX
+        && inputs[1].isIndexablePrimitive(types);
+  }
+
+  HType computeDesiredTypeForInput(HInstruction input,
+                                   HTypeMap types,
+                                   Compiler compiler) {
+    // TODO(ngeoffray): Move this logic into a different class that
+    // will know what type it wants for a given selector.
+    if (selector.kind != SelectorKind.INDEX) return HType.UNKNOWN;
+    if (!isInterceptorCall) return HType.UNKNOWN;
+
+    HInstruction index = inputs[2];
+    if (input == inputs[1] &&
+        (index.isTypeUnknown(types) || index.isNumber(types))) {
+      return HType.INDEXABLE_PRIMITIVE;
+    }
+    // The index should be an int when the receiver is a string or array.
+    // However it turns out that inserting an integer check in the optimized
+    // version is cheaper than having another bailout case. This is true,
+    // because the integer check will simply throw if it fails.
+    return HType.UNKNOWN;
+  }
 }
 
 abstract class HInvokeDynamicField extends HInvokeDynamic {
@@ -2442,41 +2468,20 @@
   }
 }
 
-class HIndex extends HInvokeStatic {
-  HIndex(HStatic target, HInstruction receiver, HInstruction index)
-      : super(<HInstruction>[target, receiver, index]);
-  toString() => 'index operator';
+class HIndex extends HInstruction {
+  HIndex(HInstruction receiver, HInstruction index)
+      : super(<HInstruction>[receiver, index]);
+  String toString() => 'index operator';
   accept(HVisitor visitor) => visitor.visitIndex(this);
 
   void prepareGvn(HTypeMap types) {
     clearAllSideEffects();
-    if (isBuiltin(types)) {
-      setDependsOnIndexStore();
-      setUseGvn();
-    } else {
-      setAllSideEffects();
-    }
+    setDependsOnIndexStore();
+    setUseGvn();
   }
 
-  HInstruction get receiver => inputs[1];
-  HInstruction get index => inputs[2];
-
-  HType computeDesiredTypeForNonTargetInput(HInstruction input,
-                                            HTypeMap types,
-                                            Compiler compiler) {
-    if (input == receiver &&
-        (index.isTypeUnknown(types) || index.isNumber(types))) {
-      return HType.INDEXABLE_PRIMITIVE;
-    }
-    // The index should be an int when the receiver is a string or array.
-    // However it turns out that inserting an integer check in the optimized
-    // version is cheaper than having another bailout case. This is true,
-    // because the integer check will simply throw if it fails.
-    return HType.UNKNOWN;
-  }
-
-  bool isBuiltin(HTypeMap types)
-      => receiver.isIndexablePrimitive(types) && index.isInteger(types);
+  HInstruction get receiver => inputs[0];
+  HInstruction get index => inputs[1];
 
   int typeCode() => HInstruction.INDEX_TYPECODE;
   bool typeEquals(HInstruction other) => other is HIndex;
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
index 1b582f1..23359cf 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
@@ -207,8 +207,7 @@
     return node;
   }
 
-  HInstruction handleInterceptorCall(HInvokeDynamic node) {
-    if (node is !HInvokeDynamicMethod) return null;
+  HInstruction handleInterceptorCall(HInvokeDynamicMethod node) {
     HInstruction input = node.inputs[1];
     if (input.isString(types)
         && node.selector.name == const SourceString('toString')) {
@@ -230,6 +229,11 @@
     }
 
     Selector selector = node.selector;
+
+    if (node.isIndexOperatorOnIndexablePrimitive(types)) {
+      return new HIndex(node.inputs[1], node.inputs[2]);
+    }
+
     SourceString selectorName = selector.name;
     Element target;
     if (input.isExtendableArray(types)) {
@@ -278,7 +282,7 @@
     return node;
   }
 
-  HInstruction visitInvokeDynamic(HInvokeDynamic node) {
+  HInstruction visitInvokeDynamicMethod(HInvokeDynamicMethod node) {
     if (node.isInterceptorCall) return handleInterceptorCall(node);
     HType receiverType = types[node.receiver];
     if (receiverType.isExact()) {
@@ -305,7 +309,7 @@
    * [HInvokeDynamic] because we know the receiver is not a JS
    * primitive object.
    */
-  HInstruction fromPrimitiveInstructionToDynamicInvocation(HInvokeStatic node,
+  HInstruction fromPrimitiveInstructionToDynamicInvocation(HInstruction node,
                                                            Selector selector) {
     HBoundedType type = types[node.inputs[1]];
     HInvokeDynamicMethod result = new HInvokeDynamicMethod(
@@ -332,15 +336,6 @@
     return node;
   }
 
-
-  HInstruction visitIndex(HIndex node) {
-    if (!node.receiver.canBePrimitive(types)) {
-      Selector selector = new Selector.index();
-      return fromPrimitiveInstructionToDynamicInvocation(node, selector);
-    }
-    return node;
-  }
-
   HInstruction visitIndexAssign(HIndexAssign node) {
     if (!node.receiver.canBePrimitive(types)) {
       Selector selector = new Selector.indexSet();
@@ -804,7 +799,6 @@
   }
 
   void visitIndex(HIndex node) {
-    if (!node.receiver.isIndexablePrimitive(types)) return;
     if (boundsChecked.contains(node)) return;
     HInstruction index = node.index;
     if (!node.index.isInteger(types)) {
@@ -812,7 +806,6 @@
     }
     index = insertBoundsCheck(node, node.receiver, index);
     node.changeUse(node.index, index);
-    assert(node.isBuiltin(types));
   }
 
   void visitIndexAssign(HIndexAssign node) {
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart b/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
index e724bbb..0b46840 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
@@ -306,7 +306,12 @@
     return "$invokeType: $functionName($argumentsString)";
   }
 
-  String visitIndex(HIndex node) => visitInvokeStatic(node);
+  String visitIndex(HIndex node) {
+    String receiver = temporaryId(node.receiver);
+    String index = temporaryId(node.index);
+    return "Index: $receiver[$index]";
+  }
+
   String visitIndexAssign(HIndexAssign node) => visitInvokeStatic(node);
 
   String visitIntegerCheck(HIntegerCheck node) {
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 3b2334c..e33d173 100644
--- a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
@@ -75,24 +75,28 @@
  * concrete type.
  */
 abstract class ConcreteType {
-  factory ConcreteType.empty() => new UnionType(new Set<BaseType>());
+  factory ConcreteType.empty() {
+    return new UnionType(new Set<BaseType>());
+  }
 
   /**
    * The singleton constituted of the unknown base type is the unknown concrete
    * type.
    */
-  factory ConcreteType.singleton(BaseType baseType) {
-    if (baseType.isUnknown()) {
-      return const UnknownConcreteType();
+  factory ConcreteType.singleton(int maxConcreteTypeSize, BaseType baseType) {
+    if (baseType.isUnknown() || maxConcreteTypeSize < 1) {
+      return new UnknownConcreteType();
     }
     Set<BaseType> singletonSet = new Set<BaseType>();
     singletonSet.add(baseType);
     return new UnionType(singletonSet);
   }
 
-  factory ConcreteType.unknown() => const UnknownConcreteType();
+  factory ConcreteType.unknown() {
+    return const UnknownConcreteType();
+  }
 
-  ConcreteType union(ConcreteType other);
+  ConcreteType union(int maxConcreteTypeSize, ConcreteType other);
   bool isUnkown();
   bool isEmpty();
   Set<BaseType> get baseTypes;
@@ -115,7 +119,7 @@
   Set<BaseType> get baseTypes =>
       new Set<BaseType>.from([const UnknownBaseType()]);
   int get hashCode => 0;
-  ConcreteType union(ConcreteType other) => this;
+  ConcreteType union(int maxConcreteTypeSize, ConcreteType other) => this;
   ClassElement getUniqueType() => null;
   toString() => "unknown";
 }
@@ -153,14 +157,16 @@
   // {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(ConcreteType other) {
+  ConcreteType union(int maxConcreteTypeSize, ConcreteType other) {
     if (other.isUnkown()) {
       return const UnknownConcreteType();
     }
     UnionType otherUnion = other;  // cast
     Set<BaseType> newBaseTypes = new Set<BaseType>.from(baseTypes);
     newBaseTypes.addAll(otherUnion.baseTypes);
-    return new UnionType(newBaseTypes);
+    return newBaseTypes.length > maxConcreteTypeSize
+        ? const UnknownConcreteType()
+        : new UnionType(newBaseTypes);
   }
 
   ClassElement getUniqueType() {
@@ -185,12 +191,15 @@
  */
 class ConcreteTypeCartesianProduct
     implements Iterable<ConcreteTypesEnvironment> {
+  final ConcreteTypesInferrer inferrer;
   final BaseType baseTypeOfThis;
   final Map<Element, ConcreteType> concreteTypes;
-  ConcreteTypeCartesianProduct(this.baseTypeOfThis, this.concreteTypes);
+  ConcreteTypeCartesianProduct(this.inferrer, this.baseTypeOfThis,
+                               this.concreteTypes);
   Iterator iterator() => concreteTypes.isEmpty
-      ? [new ConcreteTypesEnvironment(baseTypeOfThis)].iterator()
-      : new ConcreteTypeCartesianProductIterator(baseTypeOfThis, concreteTypes);
+      ? [new ConcreteTypesEnvironment(inferrer, baseTypeOfThis)].iterator()
+      : new ConcreteTypeCartesianProductIterator(inferrer, baseTypeOfThis,
+                                                 concreteTypes);
   String toString() {
     List<ConcreteTypesEnvironment> cartesianProduct =
         new List<ConcreteTypesEnvironment>.from(this);
@@ -202,6 +211,7 @@
  * An helper class for [ConcreteTypeCartesianProduct].
  */
 class ConcreteTypeCartesianProductIterator implements Iterator {
+  final ConcreteTypesInferrer inferrer;
   final BaseType baseTypeOfThis;
   final Map<Element, ConcreteType> concreteTypes;
   final Map<Element, BaseType> nextValues;
@@ -209,11 +219,11 @@
   int size = 1;
   int counter = 0;
 
-  ConcreteTypeCartesianProductIterator(this.baseTypeOfThis,
-      Map<Element, ConcreteType> concreteTypes) :
-    this.concreteTypes = concreteTypes,
-    nextValues = new Map<Element, BaseType>(),
-    state = new Map<Element, Iterator>() {
+  ConcreteTypeCartesianProductIterator(this.inferrer, this.baseTypeOfThis,
+      Map<Element, ConcreteType> concreteTypes)
+      : this.concreteTypes = concreteTypes,
+        nextValues = new Map<Element, BaseType>(),
+        state = new Map<Element, Iterator>() {
     if (concreteTypes.isEmpty) {
       size = 0;
       return;
@@ -230,8 +240,10 @@
 
   ConcreteTypesEnvironment takeSnapshot() {
     Map<Element, ConcreteType> result = new Map<Element, ConcreteType>();
-    nextValues.forEach((k, v) { result[k] = new ConcreteType.singleton(v); });
-    return new ConcreteTypesEnvironment.of(result, baseTypeOfThis);
+    nextValues.forEach((k, v) {
+      result[k] = inferrer.singletonConcreteType(v);
+    });
+    return new ConcreteTypesEnvironment.of(inferrer, result, baseTypeOfThis);
   }
 
   ConcreteTypesEnvironment next() {
@@ -283,24 +295,26 @@
  * [ConcreteTypes]. Each visitor owns one.
  */
 class ConcreteTypesEnvironment {
+  final ConcreteTypesInferrer inferrer;
   final Map<Element, ConcreteType> environment;
   final BaseType typeOfThis;
-  ConcreteTypesEnvironment([this.typeOfThis]) :
+
+  ConcreteTypesEnvironment(this.inferrer, [this.typeOfThis]) :
     this.environment = new Map<Element, ConcreteType>();
-  ConcreteTypesEnvironment.of(this.environment, this.typeOfThis);
+  ConcreteTypesEnvironment.of(this.inferrer, this.environment, this.typeOfThis);
 
   ConcreteType lookupType(Element element) => environment[element];
   ConcreteType lookupTypeOfThis() {
     return (typeOfThis == null)
         ? null
-        : new ConcreteType.singleton(typeOfThis);
+        : inferrer.singletonConcreteType(typeOfThis);
   }
 
   ConcreteTypesEnvironment put(Element element, ConcreteType type) {
     Map<Element, ConcreteType> newMap =
         new Map<Element, ConcreteType>.from(environment);
     newMap[element] = type;
-    return new ConcreteTypesEnvironment.of(newMap, typeOfThis);
+    return new ConcreteTypesEnvironment.of(inferrer, newMap, typeOfThis);
   }
 
   ConcreteTypesEnvironment join(ConcreteTypesEnvironment other) {
@@ -314,10 +328,10 @@
       if (element == null) {
         newMap[element] = type;
       } else {
-        newMap[element] = currentType.union(type);
+        newMap[element] = inferrer.union(currentType, type);
       }
     });
-    return new ConcreteTypesEnvironment.of(newMap, typeOfThis);
+    return new ConcreteTypesEnvironment.of(inferrer, newMap, typeOfThis);
   }
 
   bool operator ==(ConcreteTypesEnvironment other) {
@@ -422,7 +436,10 @@
         inferredParameterTypes = new Map<VariableElement, ConcreteType>(),
         workQueue = new Queue<InferenceWorkItem>(),
         callers = new Map<FunctionElement, Set<FunctionElement>>(),
-        readers = new Map<Element, Set<FunctionElement>>();
+        readers = new Map<Element, Set<FunctionElement>>() {
+    unknownConcreteType = new ConcreteType.unknown();
+    emptyConcreteType = new ConcreteType.empty();
+  }
 
   /**
    * Populates [cache] with ad hoc rules like:
@@ -440,11 +457,11 @@
                                              FunctionElement method,
                                              BaseType argumentType) {
       ArgumentsTypes argumentsTypes = new ArgumentsTypes(
-          [new ConcreteType.singleton(argumentType)],
+          [singletonConcreteType(argumentType)],
           new Map());
       Map<Element, ConcreteType> argumentMap =
           associateArguments(method, argumentsTypes);
-      return new ConcreteTypesEnvironment.of(argumentMap, receiverType);
+      return new ConcreteTypesEnvironment.of(this, argumentMap, receiverType);
     }
 
     // Adds the rule {receiverType}.method({argumentType}) -> {returnType}
@@ -462,7 +479,7 @@
           cache.containsKey(methodElement)
               ? cache[methodElement]
               : new Map<ConcreteTypesEnvironment, ConcreteType>();
-      map[environment] = new ConcreteType.singleton(returnType);
+      map[environment] = singletonConcreteType(returnType);
       cache[methodElement] = map;
     }
 
@@ -487,6 +504,22 @@
 
   // --- utility methods ---
 
+  /** The unknown concrete type */
+  ConcreteType unknownConcreteType;
+
+  /** The empty concrete type */
+  ConcreteType emptyConcreteType;
+
+  /** 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);
+  }
+
   /**
    * Returns all the members with name [methodName].
    */
@@ -510,7 +543,7 @@
     ConcreteType currentType = inferredTypes[node];
     inferredTypes[node] = (currentType == null)
         ? type
-        : currentType.union(type);
+        : union(currentType, type);
   }
 
   /**
@@ -518,7 +551,7 @@
    */
   ConcreteType getFieldType(Element field) {
     ConcreteType result = inferredFieldTypes[field];
-    return (result == null) ? new ConcreteType.empty() : result;
+    return (result == null) ? emptyConcreteType : result;
   }
 
   /**
@@ -528,7 +561,7 @@
   void augmentFieldType(Element field, ConcreteType type) {
     ConcreteType oldType = inferredFieldTypes[field];
     ConcreteType newType = (oldType != null)
-        ? oldType.union(type)
+        ? union(oldType, type)
         : type;
     if (oldType != newType) {
       inferredFieldTypes[field] = newType;
@@ -553,7 +586,7 @@
   void augmentParameterType(VariableElement parameter, ConcreteType type) {
     ConcreteType oldType = inferredParameterTypes[parameter];
     inferredParameterTypes[parameter] =
-        (oldType == null) ? type : oldType.union(type);
+        (oldType == null) ? type : union(oldType, type);
   }
 
   /**
@@ -609,19 +642,19 @@
   ConcreteType getSendReturnType(FunctionElement function,
                                  BaseType receiverType,
                                  ArgumentsTypes argumentsTypes) {
-    ConcreteType result = new ConcreteType.empty();
+    ConcreteType result = emptyConcreteType;
     Map<Element, ConcreteType> argumentMap =
         associateArguments(function, argumentsTypes);
     // if the association failed, this send will never occur or will fail
     if (argumentMap == null) {
-      return new ConcreteType.empty();
+      return emptyConcreteType;
     }
     argumentMap.forEach(augmentParameterType);
     ConcreteTypeCartesianProduct product =
-        new ConcreteTypeCartesianProduct(receiverType, argumentMap);
+        new ConcreteTypeCartesianProduct(this, receiverType, argumentMap);
     for (ConcreteTypesEnvironment environment in product) {
-      result = result.union(
-          getMonomorphicSendReturnType(function, environment));
+      result = union(result,
+                     getMonomorphicSendReturnType(function, environment));
     }
     return result;
   }
@@ -689,7 +722,7 @@
     //     in order to handle "?parameter" tests
     leftOverNamedParameters.forEach((_, Element namedParameter) {
       result[namedParameter] =
-          new ConcreteType.singleton(const NullBaseType());
+          singletonConcreteType(const NullBaseType());
     });
     return result;
   }
@@ -710,7 +743,7 @@
       workQueue.addLast(
         new InferenceWorkItem(function, environment));
       // in case of a constructor, optimize by returning the class
-      return new ConcreteType.empty();
+      return emptyConcreteType;
     }
   }
 
@@ -727,7 +760,7 @@
     // This should never happen since we only deal with concrete types, except
     // for external methods whose typing rules have not been hardcoded yet.
     if (!tree.hasBody()) {
-      return new ConcreteType.unknown();
+      return unknownConcreteType;
     }
     TreeElements elements =
         compiler.enqueuer.resolution.resolvedElements[element];
@@ -773,7 +806,7 @@
       if (enclosingClass != compiler.objectClass) {
         FunctionElement target = superClass.lookupConstructor(
           new Selector.callDefaultConstructor(enclosingClass.getLibrary()));
-        final superClassConcreteType = new ConcreteType.singleton(
+        final superClassConcreteType = singletonConcreteType(
             new ClassBaseType(enclosingClass));
         getSendReturnType(target, new ClassBaseType(enclosingClass),
             new ArgumentsTypes(new List(), new Map()));
@@ -781,7 +814,7 @@
     }
 
     tree.accept(visitor);
-    return new ConcreteType.singleton(new ClassBaseType(enclosingClass));
+    return singletonConcreteType(new ClassBaseType(enclosingClass));
   }
 
   void analyzeMain(Element element) {
@@ -790,7 +823,7 @@
     populateCacheWithBuiltinRules();
     try {
       workQueue.addLast(
-          new InferenceWorkItem(element, new ConcreteTypesEnvironment()));
+          new InferenceWorkItem(element, new ConcreteTypesEnvironment(this)));
       while (!workQueue.isEmpty) {
         InferenceWorkItem item = workQueue.removeFirst();
         ConcreteType concreteType = analyze(item.method, item.environment);
@@ -943,7 +976,7 @@
 
   ConcreteType visitExpressionStatement(ExpressionStatement node) {
     analyze(node.expression);
-    return new ConcreteType.empty();
+    return inferrer.emptyConcreteType;
   }
 
   ConcreteType visitFor(For node) {
@@ -951,7 +984,7 @@
       analyze(node.initializer);
     }
     analyze(node.conditionStatement);
-    ConcreteType result = new ConcreteType.empty();
+    ConcreteType result = inferrer.emptyConcreteType;
     ConcreteTypesEnvironment oldEnvironment;
     do {
       oldEnvironment = environment;
@@ -990,9 +1023,9 @@
     ConcreteType thenType = analyze(node.thenPart);
     ConcreteTypesEnvironment snapshot = environment;
     ConcreteType elseType = node.hasElsePart ? analyze(node.elsePart)
-                                             : new ConcreteType.empty();
+                                             : inferrer.emptyConcreteType;
     environment = environment.join(snapshot);
-    return thenType.union(elseType);
+    return inferrer.union(thenType, elseType);
   }
 
   ConcreteType visitLoop(Loop node) {
@@ -1100,7 +1133,7 @@
       if (operatorName.stringValue == '++'
           || operatorName.stringValue == '--') {
         List<ConcreteType> positionalArguments = <ConcreteType>[
-            new ConcreteType.singleton(inferrer.baseTypes.intBaseType)];
+            inferrer.singletonConcreteType(inferrer.baseTypes.intBaseType)];
         argumentsTypes = new ArgumentsTypes(positionalArguments, new Map());
       } else {
         argumentsTypes = analyzeArguments(node.arguments);
@@ -1122,15 +1155,15 @@
   }
 
   ConcreteType visitLiteralInt(LiteralInt node) {
-    return new ConcreteType.singleton(inferrer.baseTypes.intBaseType);
+    return inferrer.singletonConcreteType(inferrer.baseTypes.intBaseType);
   }
 
   ConcreteType visitLiteralDouble(LiteralDouble node) {
-    return new ConcreteType.singleton(inferrer.baseTypes.doubleBaseType);
+    return inferrer.singletonConcreteType(inferrer.baseTypes.doubleBaseType);
   }
 
   ConcreteType visitLiteralBool(LiteralBool node) {
-    return new ConcreteType.singleton(inferrer.baseTypes.boolBaseType);
+    return inferrer.singletonConcreteType(inferrer.baseTypes.boolBaseType);
   }
 
   ConcreteType visitLiteralString(LiteralString node) {
@@ -1138,19 +1171,19 @@
     // the unknown type.
     if (inferrer.testMode
         && node.dartString.slowToString() == "__dynamic_for_test") {
-      return new ConcreteType.unknown();
+      return inferrer.unknownConcreteType;
     }
-    return new ConcreteType.singleton(inferrer.baseTypes.stringBaseType);
+    return inferrer.singletonConcreteType(inferrer.baseTypes.stringBaseType);
   }
 
   ConcreteType visitStringJuxtaposition(StringJuxtaposition node) {
     analyze(node.first);
     analyze(node.second);
-    return new ConcreteType.singleton(inferrer.baseTypes.stringBaseType);
+    return inferrer.singletonConcreteType(inferrer.baseTypes.stringBaseType);
   }
 
   ConcreteType visitLiteralNull(LiteralNull node) {
-    return new ConcreteType.singleton(const NullBaseType());
+    return inferrer.singletonConcreteType(const NullBaseType());
   }
 
   ConcreteType visitNewExpression(NewExpression node) {
@@ -1163,15 +1196,15 @@
 
   ConcreteType visitLiteralList(LiteralList node) {
     visitNodeList(node.elements);
-    return new ConcreteType.singleton(inferrer.baseTypes.listBaseType);
+    return inferrer.singletonConcreteType(inferrer.baseTypes.listBaseType);
   }
 
   ConcreteType visitNodeList(NodeList node) {
-    ConcreteType type = new ConcreteType.empty();
+    ConcreteType type = inferrer.emptyConcreteType;
     // 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 = type.union(analyze(link.head));
+      type = inferrer.union(type, analyze(link.head));
     }
     return type;
   }
@@ -1183,13 +1216,13 @@
   ConcreteType visitReturn(Return node) {
     final expression = node.expression;
     return (expression == null)
-        ? new ConcreteType.singleton(const NullBaseType())
+        ? inferrer.singletonConcreteType(const NullBaseType())
         : analyze(expression);
   }
 
   ConcreteType visitThrow(Throw node) {
     if (node.expression != null) analyze(node.expression);
-    return new ConcreteType.empty();
+    return inferrer.emptyConcreteType;
   }
 
   ConcreteType visitTypeAnnotation(TypeAnnotation node) {
@@ -1205,12 +1238,12 @@
          link = link.tail) {
       analyze(link.head);
     }
-    return new ConcreteType.empty();
+    return inferrer.emptyConcreteType;
   }
 
   ConcreteType visitWhile(While node) {
     analyze(node.condition);
-    ConcreteType result = new ConcreteType.empty();
+    ConcreteType result = inferrer.emptyConcreteType;
     ConcreteTypesEnvironment oldEnvironment;
     do {
       oldEnvironment = environment;
@@ -1229,7 +1262,7 @@
     analyze(node.condition);
     ConcreteType thenType = analyze(node.thenExpression);
     ConcreteType elseType = analyze(node.elseExpression);
-    return thenType.union(elseType);
+    return inferrer.union(thenType, elseType);
   }
 
   ConcreteType visitModifiers(Modifiers node) {
@@ -1238,25 +1271,25 @@
 
   ConcreteType visitStringInterpolation(StringInterpolation node) {
     node.visitChildren(this);
-    return new ConcreteType.singleton(inferrer.baseTypes.stringBaseType);
+    return inferrer.singletonConcreteType(inferrer.baseTypes.stringBaseType);
   }
 
   ConcreteType visitStringInterpolationPart(StringInterpolationPart node) {
     node.visitChildren(this);
-    return new ConcreteType.singleton(inferrer.baseTypes.stringBaseType);
+    return inferrer.singletonConcreteType(inferrer.baseTypes.stringBaseType);
   }
 
   ConcreteType visitEmptyStatement(EmptyStatement node) {
-    return new ConcreteType.empty();
+    return inferrer.emptyConcreteType;
   }
 
   ConcreteType visitBreakStatement(BreakStatement node) {
-    return new ConcreteType.empty();
+    return inferrer.emptyConcreteType;
   }
 
   ConcreteType visitContinueStatement(ContinueStatement node) {
     // TODO(polux): we can be more precise
-    return new ConcreteType.empty();
+    return inferrer.emptyConcreteType;
   }
 
   ConcreteType visitForIn(ForIn node) {
@@ -1273,7 +1306,7 @@
 
   ConcreteType visitLiteralMap(LiteralMap node) {
     visitNodeList(node.entries);
-    return new ConcreteType.singleton(inferrer.baseTypes.mapBaseType);
+    return inferrer.singletonConcreteType(inferrer.baseTypes.mapBaseType);
   }
 
   ConcreteType visitLiteralMapEntry(LiteralMapEntry node) {
@@ -1357,15 +1390,16 @@
       // node is a field of not(this)
       assert(node.receiver != null);
 
-      ConcreteType result = new ConcreteType.empty();
+      ConcreteType result = inferrer.emptyConcreteType;
       void augmentResult(BaseType baseReceiverType, Element member) {
         if (member.isField()) {
-          result = result.union(analyzeFieldRead(member));
+          result = inferrer.union(result, analyzeFieldRead(member));
         } else if (member.isAbstractField()){
           // call to a getter
           AbstractFieldElement abstractField = member;
-          result = result.union(analyzeGetterSend(baseReceiverType,
-                                                  abstractField.getter));
+          result = inferrer.union(
+              result,
+              analyzeGetterSend(baseReceiverType, abstractField.getter));
         }
         // since this is a get we ignore non-fields
       }
@@ -1403,7 +1437,7 @@
   ConcreteType analyzeDynamicSend(ConcreteType receiverType,
                                   SourceString canonicalizedMethodName,
                                   ArgumentsTypes argumentsTypes) {
-    ConcreteType result = new ConcreteType.empty();
+    ConcreteType result = inferrer.emptyConcreteType;
 
     if (receiverType.isUnkown()) {
       List<Element> methods =
@@ -1416,8 +1450,10 @@
         inferrer.addCaller(method, currentMethod);
         Element classElem = method.enclosingElement;
         ClassBaseType baseReceiverType = new ClassBaseType(classElem);
-        result = result.union(
-          inferrer.getSendReturnType(method, baseReceiverType, argumentsTypes));
+        result = inferrer.union(
+            result,
+            inferrer.getSendReturnType(method,baseReceiverType,
+                                       argumentsTypes));
       }
 
     } else {
@@ -1428,8 +1464,10 @@
               canonicalizedMethodName);
           if (method != null) {
             inferrer.addCaller(method, currentMethod);
-            result = result.union(inferrer.getSendReturnType(method,
-                baseReceiverType, argumentsTypes));
+            result = inferrer.union(
+                result,
+                inferrer.getSendReturnType(method, baseReceiverType,
+                                           argumentsTypes));
           }
         }
       }
@@ -1448,7 +1486,7 @@
   ConcreteType visitDynamicSend(Send node) {
     ConcreteType receiverType = (node.receiver != null)
         ? analyze(node.receiver)
-        : new ConcreteType.singleton(
+        : inferrer.singletonConcreteType(
             new ClassBaseType(currentMethod.getEnclosingClass()));
     SourceString name =
         canonicalizeMethodName(node.selector.asIdentifier().source);
@@ -1459,7 +1497,7 @@
                                                    argumentsTypes);
       return returnType.isEmpty()
           ? returnType
-          : new ConcreteType.singleton(inferrer.baseTypes.boolBaseType);
+          : inferrer.singletonConcreteType(inferrer.baseTypes.boolBaseType);
     } else {
       return analyzeDynamicSend(receiverType, name, argumentsTypes);
     }
@@ -1481,6 +1519,6 @@
   }
 
   ConcreteType visitTypeReferenceSend(Send) {
-    return new ConcreteType.singleton(inferrer.baseTypes.typeBaseType);
+    return inferrer.singletonConcreteType(inferrer.baseTypes.typeBaseType);
   }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/types/types.dart b/sdk/lib/_internal/compiler/implementation/types/types.dart
index c41fd93..9292025 100644
--- a/sdk/lib/_internal/compiler/implementation/types/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/types.dart
@@ -21,10 +21,10 @@
   final Map<Element, Link<Element>> typedSends;
   final ConcreteTypesInferrer concreteTypesInferrer;
 
-  TypesTask(Compiler compiler, bool enableConcreteTypeInference)
+  TypesTask(Compiler compiler)
     : untypedElements = new Set<Element>(),
       typedSends = new Map<Element, Link<Element>>(),
-      concreteTypesInferrer = enableConcreteTypeInference
+      concreteTypesInferrer = compiler.enableConcreteTypeInference
           ? new ConcreteTypesInferrer(compiler) : null,
       super(compiler);
 
@@ -70,7 +70,8 @@
       for (Element parameter in signature.requiredParameters) {
         if (types.isEmpty) return null;
         if (element == parameter) {
-          return new ConcreteType.singleton(new ClassBaseType(types.head));
+          return new ConcreteType.singleton(compiler.maxConcreteTypeSize,
+                                            new ClassBaseType(types.head));
         }
         types = types.tail;
       }
diff --git a/sdk/lib/_internal/compiler/implementation/universe/universe.dart b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
index 446d835..13db4fb 100644
--- a/sdk/lib/_internal/compiler/implementation/universe/universe.dart
+++ b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
@@ -34,7 +34,9 @@
    *
    * Invariant: Elements are declaration elements.
    */
+  // TODO(karlklose): these sets should be merged.
   final Set<ClassElement> instantiatedClasses;
+  final Set<DartType> instantiatedTypes;
 
   /**
    * Documentation wanted -- johnniwinther
@@ -52,6 +54,7 @@
   Universe() : generatedCode = new Map<Element, CodeBuffer>(),
                generatedBailoutCode = new Map<Element, CodeBuffer>(),
                instantiatedClasses = new Set<ClassElement>(),
+               instantiatedTypes = new Set<DartType>(),
                staticFunctionsNeedingGetter = new Set<FunctionElement>(),
                invokedNames = new Map<SourceString, Set<Selector>>(),
                invokedGetters = new Map<SourceString, Set<Selector>>(),
diff --git a/sdk/lib/_internal/dartdoc/bin/dartdoc.dart b/sdk/lib/_internal/dartdoc/bin/dartdoc.dart
index f289ed3..6373784 100755
--- a/sdk/lib/_internal/dartdoc/bin/dartdoc.dart
+++ b/sdk/lib/_internal/dartdoc/bin/dartdoc.dart
@@ -173,7 +173,7 @@
     print('No arguments provided.');
     print(USAGE);
     print(argParser.getUsage());
-    return;
+    exit(1);
   }
 
   final entrypoints = <Path>[];
@@ -199,13 +199,13 @@
     print(e.message);
     print(USAGE);
     print(argParser.getUsage());
-    return;
+    exit(1);
   }
 
   if (entrypoints.isEmpty) {
     print('No entrypoints provided.');
     print(argParser.getUsage());
-    return;
+    exit(1);
   }
   
   if (pkgPath == null) {
diff --git a/sdk/lib/_internal/dartdoc/lib/classify.dart b/sdk/lib/_internal/dartdoc/lib/classify.dart
index de7697d..d41f12a 100644
--- a/sdk/lib/_internal/dartdoc/lib/classify.dart
+++ b/sdk/lib/_internal/dartdoc/lib/classify.dart
@@ -34,43 +34,49 @@
   static const STRING_INTERPOLATION = 'si';
 }
 
+/// Returns a marked up HTML string. If the code does not appear to be valid
+/// Dart code, returns the original [text].
 String classifySource(String text) {
-  var html = new StringBuffer();
-  var tokenizer = new StringScanner(text, includeComments: true);
+  try {
+    var html = new StringBuffer();
+    var tokenizer = new StringScanner(text, includeComments: true);
 
-  var whitespaceOffset = 0;
-  var token = tokenizer.tokenize();
-  var inString = false;
-  while (token.kind != EOF_TOKEN) {
-    html.add(text.substring(whitespaceOffset, token.charOffset));
-    whitespaceOffset = token.charOffset + token.slowCharCount;
+    var whitespaceOffset = 0;
+    var token = tokenizer.tokenize();
+    var inString = false;
+    while (token.kind != EOF_TOKEN) {
+      html.add(text.substring(whitespaceOffset, token.charOffset));
+      whitespaceOffset = token.charOffset + token.slowCharCount;
 
-    // Track whether or not we're in a string.
-    switch (token.kind) {
-      case STRING_TOKEN:
-      case STRING_INTERPOLATION_TOKEN:
-        inString = true;
-        break;
+      // Track whether or not we're in a string.
+      switch (token.kind) {
+        case STRING_TOKEN:
+        case STRING_INTERPOLATION_TOKEN:
+          inString = true;
+          break;
+      }
+
+      final kind = classify(token);
+      final escapedText = md.escapeHtml(token.slowToString());
+      if (kind != null) {
+        // Add a secondary class to tokens appearing within a string so that
+        // we can highlight tokens in an interpolation specially.
+        var stringClass = inString ? Classification.STRING_INTERPOLATION : '';
+        html.add('<span class="$kind $stringClass">$escapedText</span>');
+      } else {
+        html.add(escapedText);
+      }
+
+      // Track whether or not we're in a string.
+      if (token.kind == STRING_TOKEN) {
+        inString = false;
+      }
+      token = token.next;
     }
-
-    final kind = classify(token);
-    final escapedText = md.escapeHtml(token.slowToString());
-    if (kind != null) {
-      // Add a secondary class to tokens appearing within a string so that
-      // we can highlight tokens in an interpolation specially.
-      var stringClass = inString ? Classification.STRING_INTERPOLATION : '';
-      html.add('<span class="$kind $stringClass">$escapedText</span>');
-    } else {
-      html.add(escapedText);
-    }
-
-    // Track whether or not we're in a string.
-    if (token.kind == STRING_TOKEN) {
-      inString = false;
-    }
-    token = token.next;
+    return html.toString();
+  } catch (e) {
+    return text;
   }
-  return html.toString();
 }
 
 bool _looksLikeType(String name) {
diff --git a/sdk/lib/_internal/dartdoc/lib/markdown.dart b/sdk/lib/_internal/dartdoc/lib/markdown.dart
index 8a3bd55..ef111fb 100644
--- a/sdk/lib/_internal/dartdoc/lib/markdown.dart
+++ b/sdk/lib/_internal/dartdoc/lib/markdown.dart
@@ -5,6 +5,8 @@
 /// Parses text in a markdown-like format and renders to HTML.
 library markdown;
 
+import 'classify.dart';
+
 // TODO(rnystrom): Use "package:" URL (#4968).
 part 'src/markdown/ast.dart';
 part 'src/markdown/block_parser.dart';
@@ -15,7 +17,8 @@
 String markdownToHtml(String markdown) {
   final document = new Document();
 
-  final lines = markdown.split('\n');
+  // Replace windows line endings with unix line endings, and split.
+  final lines = markdown.replaceAll('\r\n','\n').split('\n');
   document.parseRefLinks(lines);
   final blocks = document.parseLines(lines);
   return renderToHtml(blocks);
diff --git a/sdk/lib/_internal/dartdoc/lib/src/client/dropdown.dart b/sdk/lib/_internal/dartdoc/lib/src/client/dropdown.dart
index 18a2320..d1db59d 100644
--- a/sdk/lib/_internal/dartdoc/lib/src/client/dropdown.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/client/dropdown.dart
@@ -290,13 +290,13 @@
  * the result link on enter.
  */
 void handleUpDown(KeyboardEvent event) {
-  if (event.keyIdentifier == KeyName.UP) {
+  if (event.keyCode == KeyCode.UP) {
     currentResultIndex--;
     event.preventDefault();
-  } else if (event.keyIdentifier == KeyName.DOWN) {
+  } else if (event.keyCode == KeyCode.DOWN) {
     currentResultIndex++;
     event.preventDefault();
-  } else if (event.keyIdentifier == KeyName.ENTER) {
+  } else if (event.keyCode == KeyCode.ENTER) {
     if (currentResult != null) {
       window.location.href = currentResult.url;
       event.preventDefault();
@@ -326,10 +326,10 @@
 
 /** Activate search on Ctrl+3 and S. */
 void shortcutHandler(KeyboardEvent event) {
-  if (event.keyCode == 0x33/* 3 */ && event.ctrlKey) {
+  if (event.keyCode == KeyCode.THREE && event.ctrlKey) {
     searchInput.focus();
     event.preventDefault();
-  } else if (event.target != searchInput && event.keyCode == 0x53/* S */) {
+  } else if (event.target != searchInput && event.keyCode == KeyCode.S) {
     // Allow writing 's' in the search input.
     searchInput.focus();
     event.preventDefault();
diff --git a/sdk/lib/_internal/dartdoc/lib/src/dartdoc/comment_map.dart b/sdk/lib/_internal/dartdoc/lib/src/dartdoc/comment_map.dart
index 14f17bd..7c8bd59 100644
--- a/sdk/lib/_internal/dartdoc/lib/src/dartdoc/comment_map.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/dartdoc/comment_map.dart
@@ -81,13 +81,10 @@
             lastComment = '$lastComment\n$line';
           }
         }
-      } else if (token.kind == dart2js.HASH_TOKEN) {
+      } else if (token.stringValue == 'library' && lastComment != null) {
         // Look for `library` to find the library comment.
-        final next = token.next;
-        if ((lastComment != null) && (next.stringValue == 'library')) {
-          _libraryComments[source.sourceUri.toString()] = lastComment;
-          lastComment = null;
-        }
+        _libraryComments[source.sourceUri.toString()] = lastComment;
+        lastComment = null;
       } else if (lastComment != null) {
         if (!lastComment.trim().isEmpty) {
           // We haven't attached the last doc comment to something yet, so stick
diff --git a/sdk/lib/_internal/dartdoc/lib/src/markdown/block_parser.dart b/sdk/lib/_internal/dartdoc/lib/src/markdown/block_parser.dart
index f8c970a..afda7ad 100644
--- a/sdk/lib/_internal/dartdoc/lib/src/markdown/block_parser.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/markdown/block_parser.dart
@@ -201,6 +201,32 @@
 class CodeBlockSyntax extends BlockSyntax {
   RegExp get pattern => _RE_INDENT;
 
+  List<String> parseChildLines(BlockParser parser) {
+    final childLines = <String>[];
+
+    while (!parser.isDone) {
+      var match = pattern.firstMatch(parser.current);
+      if (match != null) {
+        childLines.add(match[1]);
+        parser.advance();
+      } else {
+        // If there's a codeblock, then a newline, then a codeblock, keep the
+        // code blocks together.
+        var nextMatch = parser.next != null ?
+            pattern.firstMatch(parser.next) : null;
+        if (parser.current.trim() == '' && nextMatch != null) {
+          childLines.add('');
+          childLines.add(nextMatch[1]);
+          parser.advance();
+          parser.advance();
+        } else {
+          break;
+        }
+      }
+    }
+    return childLines;
+  }
+
   Node parse(BlockParser parser) {
     final childLines = parseChildLines(parser);
 
@@ -208,9 +234,9 @@
     childLines.add('');
 
     // Escape the code.
-    final escaped = escapeHtml(Strings.join(childLines, '\n'));
+    final escaped = classifySource(Strings.join(childLines, '\n'));
 
-    return new Element('pre', [new Element.text('code', escaped)]);
+    return new Element.text('pre', escaped);
   }
 }
 
diff --git a/sdk/lib/_internal/dartdoc/static/styles.css b/sdk/lib/_internal/dartdoc/static/styles.css
index bd9452f..c9813c8 100644
--- a/sdk/lib/_internal/dartdoc/static/styles.css
+++ b/sdk/lib/_internal/dartdoc/static/styles.css
@@ -55,6 +55,10 @@
   overflow-y:hidden;
 }
 
+pre > code {
+  padding: 0;
+}
+
 a {
   color: #15c;
   text-decoration: none;
@@ -73,6 +77,15 @@
   line-height: 22px;
 }
 
+/* First paragraph in an li is snug, but others are spaced out. */
+li p:first-child {
+  margin: 0 0 0 0;
+}
+
+li > p {
+  margin: 22px 0 0 0;
+}
+
 ol, ul {
   padding-left: 22px;
 }
@@ -414,26 +427,26 @@
 
 /* Syntax highlighting. */
 /* Note: these correspond to the constants in classify.dart. */
-pre.source .e { color: hsl(  0, 100%, 70%); } /* Error */
-pre.source .c { color: hsl(220,  20%, 65%); } /* Comment */
-pre.source .i { color: hsl(220,  20%, 20%); } /* Identifier */
-pre.source .k { color: hsl(220, 100%, 50%); } /* Keyword */
-pre.source .p { color: hsl(220,  20%, 50%); } /* Punctuation */
-pre.source .o { color: hsl(220,  40%, 50%); } /* Operator */
-pre.source .s { color: hsl( 40,  90%, 40%); } /* String */
-pre.source .n { color: hsl( 30,  70%, 50%); } /* Number */
-pre.source .t { color: hsl(180,  40%, 40%); } /* Type Name */
-pre.source .r { color: hsl(200, 100%, 50%); } /* Special Identifier */
-pre.source .a { color: hsl(220, 100%, 45%); } /* Arrow */
+.doc pre .e, pre.source .e { color: hsl(  0, 100%, 70%); } /* Error */
+.doc pre .c, pre.source .c { color: hsl(220,  20%, 65%); } /* Comment */
+.doc pre .i, pre.source .i { color: hsl(220,  20%, 20%); } /* Identifier */
+.doc pre .k, pre.source .k { color: hsl(220, 100%, 50%); } /* Keyword */
+.doc pre .p, pre.source .p { color: hsl(220,  20%, 50%); } /* Punctuation */
+.doc pre .o, pre.source .o { color: hsl(220,  40%, 50%); } /* Operator */
+.doc pre .s, pre.source .s { color: hsl( 40,  90%, 40%); } /* String */
+.doc pre .n, pre.source .n { color: hsl( 30,  70%, 50%); } /* Number */
+.doc pre .t, pre.source .t { color: hsl(180,  40%, 40%); } /* Type Name */
+.doc pre .r, pre.source .r { color: hsl(200, 100%, 50%); } /* Special Identifier */
+.doc pre .a, pre.source .a { color: hsl(220, 100%, 45%); } /* Arrow */
 
 /* Interpolated expressions within strings. */
-pre.source .si {
+.doc pre .si, pre.source .si {
   background: hsl(40, 100%, 90%);
 }
 
-pre.source .s.si { background: hsl(40, 80%, 95%); }
-pre.source .i.si { color: hsl(40, 30%, 30%); }
-pre.source .p.si { color: hsl(40, 60%, 40%); }
+.doc pre .s.si, pre.source .s.si { background: hsl(40, 80%, 95%); }
+.doc pre .i.si, pre.source .i.si { color: hsl(40, 30%, 30%); }
+.doc pre .p.si, pre.source .p.si { color: hsl(40, 60%, 40%); }
 
 /* Enable these to debug the grid: */
 
@@ -471,4 +484,4 @@
 section {
   border-left: solid 4px gray;
 }
-*/
\ No newline at end of file
+*/
diff --git a/sdk/lib/_internal/dartdoc/test/dartdoc_test.dart b/sdk/lib/_internal/dartdoc/test/dartdoc_test.dart
index b58195b..3b9b534 100644
--- a/sdk/lib/_internal/dartdoc/test/dartdoc_test.dart
+++ b/sdk/lib/_internal/dartdoc/test/dartdoc_test.dart
@@ -121,7 +121,7 @@
   
   group('integration tests', () {
     test('no entrypoints', () {
-      expect(_runDartdoc([]), completes);
+      expect(_runDartdoc([], exitCode: 1), completes);
     });
 
     test('library with no packages', () {
@@ -141,12 +141,12 @@
   });
 }
 
-Future _runDartdoc(List<String> arguments) {
+Future _runDartdoc(List<String> arguments, {int exitCode: 0}) {
   var dartBin = new Options().executable;
   var dartdoc = 'bin/dartdoc.dart';
   arguments.insertRange(0, 1, dartdoc);
   return Process.run(dartBin, arguments)
       .transform((result) {
-        expect(result.exitCode, 0);
+        expect(result.exitCode, exitCode);
       });
 }
diff --git a/sdk/lib/_internal/dartdoc/test/markdown_test.dart b/sdk/lib/_internal/dartdoc/test/markdown_test.dart
index e55eb95..b786f94 100644
--- a/sdk/lib/_internal/dartdoc/test/markdown_test.dart
+++ b/sdk/lib/_internal/dartdoc/test/markdown_test.dart
@@ -68,6 +68,15 @@
         <p>para
         1. list</p>
         ''');
+
+    // Windows line endings have a \r\n format
+    // instead of the unix \n format.
+    validate('take account of windows line endings', '''
+        line1\r\n\r\n        line2\r\n
+        ''', '''
+        <p>line1</p>
+        <p>line2</p>
+        ''');
   });
 
   group('Setext headers', () {
@@ -265,6 +274,22 @@
         </ul>
         ''');
 
+    validate('can span newlines', '''
+        *   one
+            two
+        *   three
+        ''', '''
+        <ul>
+          <li>
+            <p>one
+            two</p>
+          </li>
+          <li>
+            three
+          </li>
+        </ul>
+        ''');
+
     // TODO(rnystrom): This is how most other markdown parsers handle
     // this but that seems like a nasty special case. For now, let's not
     // worry about it.
@@ -361,6 +386,38 @@
            three</code></pre>
         ''');
 
+    validate('code blocks separated by newlines form one block', '''
+            zero
+            one
+
+            two
+
+            three
+        ''', '''
+        <pre><code>zero
+         one
+
+         two
+
+         three</code></pre>
+        ''');
+
+    validate('code blocks separated by two newlines form multiple blocks', '''
+            zero
+            one
+
+
+            two
+
+
+            three
+        ''', '''
+        <pre><code>zero
+         one</code></pre>
+        <pre><code>two</code></pre>
+        <pre><code>three</code></pre>
+        ''');
+
     validate('escape HTML characters', '''
             <&>
         ''', '''
@@ -771,7 +828,8 @@
   return Strings.join(lines, '\n');
 }
 
-validate(String description, String markdown, String html) {
+validate(String description, String markdown, String html,
+         {bool verbose: false}) {
   test(description, () {
     markdown = cleanUpLiteral(markdown);
     html = cleanUpLiteral(html);
@@ -789,7 +847,7 @@
       print('');
     }
 
-    expect(passed, isTrue);
+    expect(passed, isTrue, verbose: verbose);
   });
 }
 
diff --git a/sdk/lib/_internal/libraries.dart b/sdk/lib/_internal/libraries.dart
index fd8b5ab..29961b0 100644
--- a/sdk/lib/_internal/libraries.dart
+++ b/sdk/lib/_internal/libraries.dart
@@ -68,7 +68,7 @@
 
   "mirrors": const LibraryInfo(
       "mirrors/mirrors.dart",
-      dart2jsPath: "_internal/compiler/implementation/lib/mirrors.dart"),
+      dart2jsPatchPath: "_internal/compiler/implementation/lib/mirrors_patch.dart"),
 
   "nativewrappers": const LibraryInfo(
       "html/dartium/nativewrappers.dart",
@@ -115,6 +115,12 @@
       category: "Internal",
       documented: false,
       platforms: DART2JS_PLATFORM),
+
+  "_isolate_helper": const LibraryInfo(
+      "_internal/compiler/implementation/lib/isolate_helper.dart",
+      category: "Internal",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
 };
 
 /**
diff --git a/sdk/lib/collection/arrays.dart b/sdk/lib/collection/arrays.dart
index ce8f8b4..eab2240 100644
--- a/sdk/lib/collection/arrays.dart
+++ b/sdk/lib/collection/arrays.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.collection;
+
 // TODO(ngeoffray): Rename to Lists.
 class Arrays {
   static void copy(List src, int srcStart,
diff --git a/sdk/lib/collection/collection.dart b/sdk/lib/collection/collection.dart
index 3112e86..3219649 100644
--- a/sdk/lib/collection/collection.dart
+++ b/sdk/lib/collection/collection.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library collection;
+library dart.collection;
 
 part 'arrays.dart';
 part 'collections.dart';
diff --git a/sdk/lib/collection/collections.dart b/sdk/lib/collection/collections.dart
index 646f6e7..9224cd1 100644
--- a/sdk/lib/collection/collections.dart
+++ b/sdk/lib/collection/collections.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.collection;
+
 /**
  * The [Collections] class implements static methods useful when
  * writing a class that implements [Collection] and the [iterator]
diff --git a/sdk/lib/collection/maps.dart b/sdk/lib/collection/maps.dart
index a8b4308..6c9472c 100644
--- a/sdk/lib/collection/maps.dart
+++ b/sdk/lib/collection/maps.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.collection;
+
 /*
  * Helper class which implements complex [Map] operations
  * in term of basic ones ([Map.keys], [Map.operator []],
diff --git a/sdk/lib/collection/splay_tree.dart b/sdk/lib/collection/splay_tree.dart
index cf2b2cf..d9eca77 100644
--- a/sdk/lib/collection/splay_tree.dart
+++ b/sdk/lib/collection/splay_tree.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.collection;
+
 /**
  * A node in a splay tree. It holds the key, the value and the left
  * and right children in the tree.
diff --git a/sdk/lib/core/bool.dart b/sdk/lib/core/bool.dart
index e34b058..2c5da00 100644
--- a/sdk/lib/core/bool.dart
+++ b/sdk/lib/core/bool.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.
 
-// Dart core library.
+part of dart.core;
 
 class bool {
   factory bool._uninstantiable() {
diff --git a/sdk/lib/core/collection.dart b/sdk/lib/core/collection.dart
index 2565c48..703af88 100644
--- a/sdk/lib/core/collection.dart
+++ b/sdk/lib/core/collection.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.core;
+
 /**
  * The common interface of all collections.
  *
diff --git a/sdk/lib/core/comparable.dart b/sdk/lib/core/comparable.dart
index 92df742..e544201 100644
--- a/sdk/lib/core/comparable.dart
+++ b/sdk/lib/core/comparable.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.
 
-// Dart core library.
+part of dart.core;
 
 /**
  * The signature of a generic comparison function.
diff --git a/sdk/lib/core/core.dart b/sdk/lib/core/core.dart
index fb17dc3..d178451 100644
--- a/sdk/lib/core/core.dart
+++ b/sdk/lib/core/core.dart
@@ -2,43 +2,43 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#library("dart:core");
+library dart.core;
 
-#import("dart:collection");
+import "dart:collection";
 
-#source("bool.dart");
-#source("collection.dart");
-#source("comparable.dart");
-#source("date.dart");
-#source("double.dart");
-#source("duration.dart");
-#source("errors.dart");
-#source("exceptions.dart");
-#source("expando.dart");
-#source("expect.dart");
-#source("function.dart");
-#source("future.dart");
-#source("future_impl.dart");
-#source("hashable.dart");
-#source("identical.dart");
-#source("int.dart");
-#source("invocation_mirror.dart");
-#source("iterable.dart");
-#source("iterator.dart");
-#source("list.dart");
-#source("map.dart");
-#source("num.dart");
-#source("object.dart");
-#source("options.dart");
-#source("pattern.dart");
-#source("print.dart");
-#source("queue.dart");
-#source("regexp.dart");
-#source("sequences.dart");
-#source("set.dart");
-#source("sort.dart");
-#source("stopwatch.dart");
-#source("string.dart");
-#source("string_buffer.dart");
-#source("strings.dart");
-#source("type.dart");
+part "bool.dart";
+part "collection.dart";
+part "comparable.dart";
+part "date.dart";
+part "double.dart";
+part "duration.dart";
+part "errors.dart";
+part "exceptions.dart";
+part "expando.dart";
+part "expect.dart";
+part "function.dart";
+part "future.dart";
+part "future_impl.dart";
+part "hashable.dart";
+part "identical.dart";
+part "int.dart";
+part "invocation_mirror.dart";
+part "iterable.dart";
+part "iterator.dart";
+part "list.dart";
+part "map.dart";
+part "num.dart";
+part "object.dart";
+part "options.dart";
+part "pattern.dart";
+part "print.dart";
+part "queue.dart";
+part "regexp.dart";
+part "sequences.dart";
+part "set.dart";
+part "sort.dart";
+part "stopwatch.dart";
+part "string.dart";
+part "string_buffer.dart";
+part "strings.dart";
+part "type.dart";
diff --git a/sdk/lib/core/date.dart b/sdk/lib/core/date.dart
index 3ce0b07..d0c0f01 100644
--- a/sdk/lib/core/date.dart
+++ b/sdk/lib/core/date.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.
 
-// Dart core library.
+part of dart.core;
 
 /**
  * Date is the public interface to a point in time.
diff --git a/sdk/lib/core/double.dart b/sdk/lib/core/double.dart
index 2f8b529..a2a63e5 100644
--- a/sdk/lib/core/double.dart
+++ b/sdk/lib/core/double.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.core;
+
 // TODO: Convert this abstract class into a concrete class double
 // that uses the patch class functionality to account for the
 // different platform implementations.
diff --git a/sdk/lib/core/duration.dart b/sdk/lib/core/duration.dart
index 710d877..d68c9e7 100644
--- a/sdk/lib/core/duration.dart
+++ b/sdk/lib/core/duration.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.
 
-// Dart core library.
+part of dart.core;
 
 /**
  * A [Duration] represents a time span. A duration can be negative.
diff --git a/sdk/lib/core/errors.dart b/sdk/lib/core/errors.dart
index c18e174..5fbd2d9 100644
--- a/sdk/lib/core/errors.dart
+++ b/sdk/lib/core/errors.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.core;
+
 class Error {
   const Error();
 
@@ -75,7 +77,7 @@
 }
 
 /**
- * Exception thrown because of an index outside of the valid range.
+ * Error thrown because of an index outside of the valid range.
  *
  */
 class RangeError extends ArgumentError {
diff --git a/sdk/lib/core/exceptions.dart b/sdk/lib/core/exceptions.dart
index 1a7c436..7a6d332 100644
--- a/sdk/lib/core/exceptions.dart
+++ b/sdk/lib/core/exceptions.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.core;
+
 // Exceptions are thrown either by the VM or from Dart code.
 
 /**
diff --git a/sdk/lib/core/expando.dart b/sdk/lib/core/expando.dart
index f027893..5df0a7b 100644
--- a/sdk/lib/core/expando.dart
+++ b/sdk/lib/core/expando.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.core;
+
 /**
  * An [Expando] allows adding new properties to objects.
  */
diff --git a/sdk/lib/core/expect.dart b/sdk/lib/core/expect.dart
index f59aaa1..6953d06 100644
--- a/sdk/lib/core/expect.dart
+++ b/sdk/lib/core/expect.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.core;
+
 /**
  * Expect is used for tests that do not want to make use of the
  * Dart unit test library - for example, the core language tests.
diff --git a/sdk/lib/core/function.dart b/sdk/lib/core/function.dart
index 2964876..4653294 100644
--- a/sdk/lib/core/function.dart
+++ b/sdk/lib/core/function.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.
 
-// Dart core library.
+part of dart.core;
 
 /**
  * Super-type of all function types.
diff --git a/sdk/lib/core/future.dart b/sdk/lib/core/future.dart
index c6cc374..93bc6c8 100644
--- a/sdk/lib/core/future.dart
+++ b/sdk/lib/core/future.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.core;
+
 /**
  * A [Future] is used to obtain a value sometime in the future.  Receivers of a
  * [Future] can obtain the value by passing a callback to [then]. For example:
diff --git a/sdk/lib/core/future_impl.dart b/sdk/lib/core/future_impl.dart
index 95ee983..693d147 100644
--- a/sdk/lib/core/future_impl.dart
+++ b/sdk/lib/core/future_impl.dart
@@ -1,6 +1,8 @@
 // Copyright 2012 Google Inc. All Rights Reserved.
 // Dart core library.
 
+part of dart.core;
+
 class _FutureImpl<T> implements Future<T> {
 
   bool _isComplete = false;
diff --git a/sdk/lib/core/hashable.dart b/sdk/lib/core/hashable.dart
index b0361d0..485f45c 100644
--- a/sdk/lib/core/hashable.dart
+++ b/sdk/lib/core/hashable.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.
 
-// Dart core library.
+part of dart.core;
 
 /**
  * Temporary interface for backwards compatibility.
diff --git a/sdk/lib/core/identical.dart b/sdk/lib/core/identical.dart
index 5e8f782..236ce20 100644
--- a/sdk/lib/core/identical.dart
+++ b/sdk/lib/core/identical.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.core;
+
 /**
  * Check whether two references are to the same object.
  */
diff --git a/sdk/lib/core/int.dart b/sdk/lib/core/int.dart
index b0f6c13..261d2c4 100644
--- a/sdk/lib/core/int.dart
+++ b/sdk/lib/core/int.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.core;
+
 /**
  * Representation of Dart integers containing integer specific
  * operations and specialization of operations inherited from [num].
diff --git a/sdk/lib/core/invocation_mirror.dart b/sdk/lib/core/invocation_mirror.dart
index 68769e3..3b5cda0 100644
--- a/sdk/lib/core/invocation_mirror.dart
+++ b/sdk/lib/core/invocation_mirror.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.core;
+
 /**
  * Representation of the invocation of a member on an object.
  *
diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart
index 19972c1..8e25885 100644
--- a/sdk/lib/core/iterable.dart
+++ b/sdk/lib/core/iterable.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.core;
+
 /**
  * The [Iterable] interface allows to get an [Iterator] out of an
  * [Iterable] object.
diff --git a/sdk/lib/core/iterator.dart b/sdk/lib/core/iterator.dart
index 5d5e979..bd4a595 100644
--- a/sdk/lib/core/iterator.dart
+++ b/sdk/lib/core/iterator.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.core;
+
 /**
  * The [Iterator] class provides methods to iterate over an object. It
  * is transparently used by the for-in construct to test for the end
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index 030596a..e523099 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.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.core;
+
 /**
  * A [List] is an indexable collection with a length. It can be of
  * fixed size or extendable.
diff --git a/sdk/lib/core/map.dart b/sdk/lib/core/map.dart
index e9b52b6..9a651f9 100644
--- a/sdk/lib/core/map.dart
+++ b/sdk/lib/core/map.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.core;
+
 /**
  * A [Map] is an associative container, mapping a key to a value.
  * Null values are supported, but null keys are not.
diff --git a/sdk/lib/core/num.dart b/sdk/lib/core/num.dart
index a506ade..a1ff247 100644
--- a/sdk/lib/core/num.dart
+++ b/sdk/lib/core/num.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.
 
-// Dart core library.
+part of dart.core;
 
 /**
  * All numbers in dart are instances of [num].
diff --git a/sdk/lib/core/object.dart b/sdk/lib/core/object.dart
index 4ab04bca..74cc651 100644
--- a/sdk/lib/core/object.dart
+++ b/sdk/lib/core/object.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.core;
+
 /**
  * Everything in Dart is an [Object].
  */
diff --git a/sdk/lib/core/options.dart b/sdk/lib/core/options.dart
index 3a4d703..696ad8d 100644
--- a/sdk/lib/core/options.dart
+++ b/sdk/lib/core/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.
 
-// Dart core library.
+part of dart.core;
 
 /**
  * The Options object allows accessing the arguments which have been passed to
diff --git a/sdk/lib/core/pattern.dart b/sdk/lib/core/pattern.dart
index 8c76722..ac7815d 100644
--- a/sdk/lib/core/pattern.dart
+++ b/sdk/lib/core/pattern.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.core;
+
 abstract class Pattern {
   Iterable<Match> allMatches(String str);
 }
diff --git a/sdk/lib/core/print.dart b/sdk/lib/core/print.dart
index 1c25a14..17ef817 100644
--- a/sdk/lib/core/print.dart
+++ b/sdk/lib/core/print.dart
@@ -2,4 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+part of dart.core;
+
 external void print(Object object);
diff --git a/sdk/lib/core/queue.dart b/sdk/lib/core/queue.dart
index 20798a7..e7a9763 100644
--- a/sdk/lib/core/queue.dart
+++ b/sdk/lib/core/queue.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.core;
+
 /**
  * A [Queue] is a collection that can be manipulated at both ends. One
  * can iterate over the elements of a queue through [forEach] or with
diff --git a/sdk/lib/core/regexp.dart b/sdk/lib/core/regexp.dart
index c652db8..1bf1b55 100644
--- a/sdk/lib/core/regexp.dart
+++ b/sdk/lib/core/regexp.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.core;
+
 /**
  * [Match] contains methods to manipulate a regular expression match.
  *
diff --git a/sdk/lib/core/sequences.dart b/sdk/lib/core/sequences.dart
index 5ad8a37..ae0a38c 100644
--- a/sdk/lib/core/sequences.dart
+++ b/sdk/lib/core/sequences.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.core;
+
 /**
  * An indexed sequence of elements of the same type.
  *
diff --git a/sdk/lib/core/set.dart b/sdk/lib/core/set.dart
index 47c706f..111d2a9 100644
--- a/sdk/lib/core/set.dart
+++ b/sdk/lib/core/set.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.core;
+
 /**
  * This class is the public interface of a set. A set is a collection
  * without duplicates.
diff --git a/sdk/lib/core/sort.dart b/sdk/lib/core/sort.dart
index 737d6da..96d987a 100644
--- a/sdk/lib/core/sort.dart
+++ b/sdk/lib/core/sort.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.core;
+
 // TODO(ajohnsen): Remove once dart2js intercepters can work without it.
 /**
  * WARNING: This method is temporary and will go away soon.
diff --git a/sdk/lib/core/stopwatch.dart b/sdk/lib/core/stopwatch.dart
index 14aa551..7d8ce33 100644
--- a/sdk/lib/core/stopwatch.dart
+++ b/sdk/lib/core/stopwatch.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.core;
+
 /**
  * A simple [Stopwatch] interface to measure elapsed time.
  */
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index 19b472e..e4b4c73 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.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.core;
+
 /**
  * The String class represents character strings. Strings are
  * immutable. A string is represented by a list of 32-bit Unicode
diff --git a/sdk/lib/core/string_buffer.dart b/sdk/lib/core/string_buffer.dart
index 78230a0..fda7111 100644
--- a/sdk/lib/core/string_buffer.dart
+++ b/sdk/lib/core/string_buffer.dart
@@ -2,118 +2,86 @@
 // for 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;
+
 /**
  * The StringBuffer class is useful for concatenating strings
  * efficiently. Only on a call to [toString] are the strings
  * concatenated to a single String.
  */
 abstract class StringBuffer {
-  /**
-   * Creates the string buffer with an initial content.
-   */
-  factory StringBuffer([Object content = ""])
-    => new _StringBufferImpl(content);
 
-  /**
-   * Returns the length of the buffer.
-   */
+  /// Creates the string buffer with an initial content.
+  factory StringBuffer([Object content = ""]) => new _StringBufferImpl(content);
+
+  /// Returns the length of the buffer.
   int get length;
 
-  /**
-   * Returns whether the buffer is empty.
-   */
+  // Returns whether the buffer is empty.
   bool get isEmpty;
 
-  /**
-   * Converts [obj] to a string and adds it to the buffer. Returns [:this:].
-   */
-  StringBuffer add(Object obj);
+  /// Converts [obj] to a string and adds it to the buffer.
+  void add(Object obj);
 
-  /**
-   * Adds the string representation of [charCode] to the buffer.
-   * Returns [this].
-   */
-  StringBuffer addCharCode(int charCode);
+  /// Adds the string representation of [charCode] to the buffer.
+  void addCharCode(int charCode);
 
-  /**
-   * Adds all items in [objects] to the buffer. Returns [:this:].
-   */
-  StringBuffer addAll(Collection objects);
+  /// Adds all items in [objects] to the buffer.
+  void addAll(Collection objects);
 
-  /**
-   * Clears the string buffer. Returns [:this:].
-   */
-  StringBuffer clear();
+  /// Clears the string buffer.
+  void clear();
 
-  /**
-   * Returns the contents of buffer as a concatenated string.
-   */
+  /// Returns the contents of buffer as a concatenated string.
   String toString();
 }
 
 class _StringBufferImpl implements StringBuffer {
-  /**
-   * Creates the string buffer with an initial content.
-   */
+
+  List<String> _buffer;
+  int _length;
+
+  /// Creates the string buffer with an initial content.
   _StringBufferImpl(Object content) {
     clear();
     add(content);
   }
 
-  /**
-   * Returns the length of the buffer.
-   */
-  int get length {
-    return _length;
-  }
+  /// Returns the length of the buffer.
+  int get length => _length;
 
-  bool get isEmpty {
-    return _length == 0;
-  }
+  bool get isEmpty => _length == 0;
 
-  /**
-   * Adds [obj] to the buffer. Returns [this].
-   */
-  StringBuffer add(Object obj) {
+  /// Adds [obj] to the buffer.
+  void add(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 = obj.toString();
-    if (str == null || str.isEmpty) {
-      return this;
+    if (str is !String) {
+      throw new ArgumentError('toString() did not return a string');
     }
+    if (str.isEmpty) return;
     _buffer.add(str);
     _length += str.length;
-    return this;
   }
 
-  /**
-   * Adds all items in [objects] to the buffer. Returns [this].
-   */
-  StringBuffer addAll(Collection objects) {
-    for (Object obj in objects) {
-      add(obj);
-    }
-    return this;
+  /// Adds all items in [objects] to the buffer.
+  void addAll(Collection objects) {
+    for (Object obj in objects) add(obj);
   }
 
-  /**
-   * Adds the string representation of [charCode] to the buffer.
-   * Returns [this].
-   */
-  StringBuffer addCharCode(int charCode) {
-    return add(new String.fromCharCodes([charCode]));
+  /// Adds the string representation of [charCode] to the buffer.
+  void addCharCode(int charCode) {
+    add(new String.fromCharCodes([charCode]));
   }
 
-  /**
-   * Clears the string buffer. Returns [this].
-   */
-  StringBuffer clear() {
+  /// Clears the string buffer.
+  void clear() {
     _buffer = new List<String>();
     _length = 0;
-    return this;
   }
 
-  /**
-   * Returns the contents of buffer as a concatenated string.
-   */
+  /// Returns the contents of buffer as a concatenated string.
   String toString() {
     if (_buffer.length == 0) return "";
     if (_buffer.length == 1) return _buffer[0];
@@ -124,7 +92,4 @@
     // need to update it in this function.
     return result;
   }
-
-  List<String> _buffer;
-  int _length;
 }
diff --git a/sdk/lib/core/strings.dart b/sdk/lib/core/strings.dart
index 5029b46..9d565a1 100644
--- a/sdk/lib/core/strings.dart
+++ b/sdk/lib/core/strings.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.core;
+
 abstract class Strings {
   /**
    * Joins all the given strings to create a new string.
diff --git a/sdk/lib/core/type.dart b/sdk/lib/core/type.dart
index dee79b6..d2e107b 100644
--- a/sdk/lib/core/type.dart
+++ b/sdk/lib/core/type.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.core;
+
 /**
  * Runtime representation of a type.
  */
diff --git a/sdk/lib/crypto/crypto.dart b/sdk/lib/crypto/crypto.dart
index 078b21d..ea4e8fe 100644
--- a/sdk/lib/crypto/crypto.dart
+++ b/sdk/lib/crypto/crypto.dart
@@ -2,16 +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.
 
-#library('dart:crypto');
+library dart.crypto;
 
-#import('dart:math');
+import 'dart:math';
 
-#source('crypto_utils.dart');
-#source('hash_utils.dart');
-#source('hmac.dart');
-#source('md5.dart');
-#source('sha1.dart');
-#source('sha256.dart');
+part 'crypto_utils.dart';
+part 'hash_utils.dart';
+part 'hmac.dart';
+part 'md5.dart';
+part 'sha1.dart';
+part 'sha256.dart';
 
 /**
  * Interface for cryptographic hash functions.
diff --git a/sdk/lib/crypto/crypto_utils.dart b/sdk/lib/crypto/crypto_utils.dart
index b9b4305..32096f1 100644
--- a/sdk/lib/crypto/crypto_utils.dart
+++ b/sdk/lib/crypto/crypto_utils.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.crypto;
+
 class _LineWrappingStringBuffer {
   _LineWrappingStringBuffer(int this._lineLength) : _sb = new StringBuffer();
 
diff --git a/sdk/lib/crypto/hash_utils.dart b/sdk/lib/crypto/hash_utils.dart
index d3c23f5..81dcd68 100644
--- a/sdk/lib/crypto/hash_utils.dart
+++ b/sdk/lib/crypto/hash_utils.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.crypto;
+
 // Constants.
 const _MASK_8 = 0xff;
 const _MASK_32 = 0xffffffff;
diff --git a/sdk/lib/crypto/hmac.dart b/sdk/lib/crypto/hmac.dart
index d7e3d98..8844704 100644
--- a/sdk/lib/crypto/hmac.dart
+++ b/sdk/lib/crypto/hmac.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.crypto;
+
 class _HMAC implements HMAC {
   _HMAC(Hash this._hash, List<int> this._key) : _message = [];
 
diff --git a/sdk/lib/crypto/md5.dart b/sdk/lib/crypto/md5.dart
index 1563f0b..7763832 100644
--- a/sdk/lib/crypto/md5.dart
+++ b/sdk/lib/crypto/md5.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.crypto;
+
 // The MD5 hasher is used to compute an MD5 message digest.
 class _MD5 extends _HashBase implements MD5 {
   _MD5() : super(16, 4, false) {
diff --git a/sdk/lib/crypto/sha1.dart b/sdk/lib/crypto/sha1.dart
index 41e6636..83e9217 100644
--- a/sdk/lib/crypto/sha1.dart
+++ b/sdk/lib/crypto/sha1.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.crypto;
+
 // The SHA1 hasher is used to compute an SHA1 message digest.
 class _SHA1 extends _HashBase implements SHA1 {
   // Construct a SHA1 hasher object.
diff --git a/sdk/lib/crypto/sha256.dart b/sdk/lib/crypto/sha256.dart
index e3418fe..3df0ffd 100644
--- a/sdk/lib/crypto/sha256.dart
+++ b/sdk/lib/crypto/sha256.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.crypto;
+
 // The SHA256 hasher is used to compute an SHA256 message digest.
 class _SHA256 extends _HashBase implements SHA256 {
   // Construct a SHA256 hasher object.
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index d1dee9b..5e16988 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -5,6 +5,7 @@
 import 'dart:indexed_db';
 import 'dart:isolate';
 import 'dart:json';
+import 'dart:math';
 import 'dart:svg' as svg;
 import 'dart:web_audio' as web_audio;
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -21,7 +22,7 @@
 
 
 
-LocalWindow get window => JS('LocalWindow', 'window');
+Window get window => JS('Window', 'window');
 
 HtmlDocument get document => JS('Document', 'document');
 
@@ -96,12 +97,6 @@
     return e;
   }
 
-  /// @domName HTMLAnchorElement.charset; @docsEditable true
-  String charset;
-
-  /// @domName HTMLAnchorElement.coords; @docsEditable true
-  String coords;
-
   /// @domName HTMLAnchorElement.download; @docsEditable true
   String download;
 
@@ -141,15 +136,9 @@
   /// @domName HTMLAnchorElement.rel; @docsEditable true
   String rel;
 
-  /// @domName HTMLAnchorElement.rev; @docsEditable true
-  String rev;
-
   /// @domName HTMLAnchorElement.search; @docsEditable true
   String search;
 
-  /// @domName HTMLAnchorElement.shape; @docsEditable true
-  String shape;
-
   /// @domName HTMLAnchorElement.target; @docsEditable true
   String target;
 
@@ -164,59 +153,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-/// @domName WebKitAnimation; @docsEditable true
-class Animation native "*WebKitAnimation" {
-
-  static const int DIRECTION_ALTERNATE = 1;
-
-  static const int DIRECTION_NORMAL = 0;
-
-  static const int FILL_BACKWARDS = 1;
-
-  static const int FILL_BOTH = 3;
-
-  static const int FILL_FORWARDS = 2;
-
-  static const int FILL_NONE = 0;
-
-  /// @domName WebKitAnimation.delay; @docsEditable true
-  final num delay;
-
-  /// @domName WebKitAnimation.direction; @docsEditable true
-  final int direction;
-
-  /// @domName WebKitAnimation.duration; @docsEditable true
-  final num duration;
-
-  /// @domName WebKitAnimation.elapsedTime; @docsEditable true
-  num elapsedTime;
-
-  /// @domName WebKitAnimation.ended; @docsEditable true
-  final bool ended;
-
-  /// @domName WebKitAnimation.fillMode; @docsEditable true
-  final int fillMode;
-
-  /// @domName WebKitAnimation.iterationCount; @docsEditable true
-  final int iterationCount;
-
-  /// @domName WebKitAnimation.name; @docsEditable true
-  final String name;
-
-  /// @domName WebKitAnimation.paused; @docsEditable true
-  final bool paused;
-
-  /// @domName WebKitAnimation.pause; @docsEditable true
-  void pause() native;
-
-  /// @domName WebKitAnimation.play; @docsEditable true
-  void play() 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
-// BSD-style license that can be found in the LICENSE file.
-
-
 /// @domName WebKitAnimationEvent; @docsEditable true
 class AnimationEvent extends Event native "*WebKitAnimationEvent" {
 
@@ -374,9 +310,6 @@
   /// @domName HTMLAreaElement.href; @docsEditable true
   String href;
 
-  /// @domName HTMLAreaElement.noHref; @docsEditable true
-  bool noHref;
-
   /// @domName HTMLAreaElement.pathname; @docsEditable true
   final String pathname;
 
@@ -398,22 +331,58 @@
   /// @domName HTMLAreaElement.target; @docsEditable true
   String target;
 }
-// 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.
 
 
-/// @domName ArrayBuffer; @docsEditable true
+/// @domName ArrayBuffer
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class ArrayBuffer native "*ArrayBuffer" {
 
   ///@docsEditable true
-  factory ArrayBuffer(int length) => _ArrayBufferFactoryProvider.createArrayBuffer(length);
+  factory ArrayBuffer(int length) => ArrayBuffer._create(length);
+  static ArrayBuffer _create(int length) => JS('ArrayBuffer', 'new ArrayBuffer(#)', length);
+
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => JS('bool', 'typeof window.ArrayBuffer != "undefined"');
 
   /// @domName ArrayBuffer.byteLength; @docsEditable true
   final int byteLength;
 
-  /// @domName ArrayBuffer.slice; @docsEditable true
-  ArrayBuffer slice(int begin, [int end]) native;
+  /// @domName ArrayBuffer.slice;
+  ArrayBuffer slice(int begin, [int end]) {
+    // IE10 supports ArrayBuffers but does not have the slice method.
+    if (JS('bool', '!!#.slice', this)) {
+      if (?end) {
+        return JS('ArrayBuffer', '#.slice(#, #)', this, begin, end);
+      }
+      return JS('ArrayBuffer', '#.slice(#)', this, begin);
+    } else {
+      var start = begin;
+      // Negative values go from end.
+      if (start < 0) {
+        start = this.byteLength + start;
+      }
+      var finish = ?end ? min(end, byteLength) : byteLength;
+      if (finish < 0) {
+        finish = this.byteLength + finish;
+      }
+      var length = max(finish - start, 0);
+
+      var clone = new Int8Array(length);
+      var source = new Int8Array.fromBuffer(this, start);
+      for (var i = 0; i < length; ++i) {
+        clone[i] = source[i];
+      }
+      return clone.buffer;
+    }
+  }
 }
 // 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
@@ -421,6 +390,10 @@
 
 
 /// @domName ArrayBufferView; @docsEditable true
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class ArrayBufferView native "*ArrayBufferView" {
 
   /// @domName ArrayBufferView.buffer; @docsEditable true
@@ -466,9 +439,15 @@
   ///@docsEditable true
   factory AudioElement([String src]) {
     if (!?src) {
-      return _AudioElementFactoryProvider.createAudioElement();
+      return AudioElement._create();
     }
-    return _AudioElementFactoryProvider.createAudioElement(src);
+    return AudioElement._create(src);
+  }
+  static AudioElement _create([String src]) {
+    if (!?src) {
+      return JS('AudioElement', 'new Audio()');
+    }
+    return JS('AudioElement', 'new Audio(#)', src);
   }
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -481,9 +460,6 @@
 
   ///@docsEditable true
   factory BRElement() => document.$dom_createElement("br");
-
-  /// @domName HTMLBRElement.clear; @docsEditable true
-  String clear;
 }
 // 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
@@ -606,13 +582,31 @@
   ///@docsEditable true
   factory Blob(List blobParts, [String type, String endings]) {
     if (!?type) {
-      return _BlobFactoryProvider.createBlob(blobParts);
+      return Blob._create(blobParts);
     }
     if (!?endings) {
-      return _BlobFactoryProvider.createBlob(blobParts, type);
+      return Blob._create(blobParts, type);
     }
-    return _BlobFactoryProvider.createBlob(blobParts, type, endings);
+    return Blob._create(blobParts, type, endings);
   }
+  static Blob _create([List blobParts = null, String type, String endings]) {
+    // TODO: validate that blobParts is a JS Array and convert if not.
+    // TODO: any coercions on the elements of blobParts, e.g. coerce a typed
+    // array to ArrayBuffer if it is a total view.
+    if (type == null && endings == null) {
+      return _create_1(blobParts);
+    }
+    var bag = _create_bag();
+    if (type != null) _bag_set(bag, 'type', type);
+    if (endings != null) _bag_set(bag, 'endings', endings);
+    return _create_2(blobParts, bag);
+  }
+
+  static _create_1(parts) => JS('Blob', 'new Blob(#)', parts);
+  static _create_2(parts, bag) => JS('Blob', 'new Blob(#, #)', parts, bag);
+
+  static _create_bag() => JS('var', '{}');
+  static _bag_set(bag, key, value) { JS('void', '#[#] = #', bag, key, value); }
 
   /// @domName Blob.size; @docsEditable true
   final int size;
@@ -638,18 +632,6 @@
   BodyElementEvents get on =>
     new BodyElementEvents(this);
 
-  /// @domName HTMLBodyElement.aLink; @docsEditable true
-  String aLink;
-
-  /// @domName HTMLBodyElement.background; @docsEditable true
-  String background;
-
-  /// @domName HTMLBodyElement.bgColor; @docsEditable true
-  String bgColor;
-
-  /// @domName HTMLBodyElement.link; @docsEditable true
-  String link;
-
   /// @domName HTMLBodyElement.vLink; @docsEditable true
   String vLink;
 }
@@ -1028,9 +1010,6 @@
   /// @domName CanvasRenderingContext2D.clearRect; @docsEditable true
   void clearRect(num x, num y, num width, num height) native;
 
-  /// @domName CanvasRenderingContext2D.clearShadow; @docsEditable true
-  void clearShadow() native;
-
   /// @domName CanvasRenderingContext2D.clip; @docsEditable true
   void clip() native;
 
@@ -1039,12 +1018,12 @@
 
   /// @domName CanvasRenderingContext2D.createImageData; @docsEditable true
   ImageData createImageData(imagedata_OR_sw, [num sh]) {
-    if ((?imagedata_OR_sw && (imagedata_OR_sw is ImageData || imagedata_OR_sw == null)) &&
+    if ((imagedata_OR_sw is ImageData || imagedata_OR_sw == null) &&
         !?sh) {
       var imagedata_1 = _convertDartToNative_ImageData(imagedata_OR_sw);
       return _convertNativeToDart_ImageData(_createImageData_1(imagedata_1));
     }
-    if ((?imagedata_OR_sw && (imagedata_OR_sw is num || imagedata_OR_sw == null))) {
+    if ((imagedata_OR_sw is num || imagedata_OR_sw == null)) {
       return _convertNativeToDart_ImageData(_createImageData_2(imagedata_OR_sw, sh));
     }
     throw new ArgumentError("Incorrect number or type of arguments");
@@ -1068,9 +1047,6 @@
   /// @domName CanvasRenderingContext2D.drawImage; @docsEditable true
   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;
 
-  /// @domName CanvasRenderingContext2D.drawImageFromRect; @docsEditable true
-  void drawImageFromRect(ImageElement image, [num sx, num sy, num sw, num sh, num dx, num dy, num dw, num dh, String compositeOperation]) native;
-
   /// @domName CanvasRenderingContext2D.fill; @docsEditable true
   void fill() native;
 
@@ -1141,30 +1117,9 @@
   /// @domName CanvasRenderingContext2D.scale; @docsEditable true
   void scale(num sx, num sy) native;
 
-  /// @domName CanvasRenderingContext2D.setAlpha; @docsEditable true
-  void setAlpha(num alpha) native;
-
-  /// @domName CanvasRenderingContext2D.setCompositeOperation; @docsEditable true
-  void setCompositeOperation(String compositeOperation) native;
-
-  /// @domName CanvasRenderingContext2D.setLineCap; @docsEditable true
-  void setLineCap(String cap) native;
-
   /// @domName CanvasRenderingContext2D.setLineDash; @docsEditable true
   void setLineDash(List<num> dash) native;
 
-  /// @domName CanvasRenderingContext2D.setLineJoin; @docsEditable true
-  void setLineJoin(String join) native;
-
-  /// @domName CanvasRenderingContext2D.setLineWidth; @docsEditable true
-  void setLineWidth(num width) native;
-
-  /// @domName CanvasRenderingContext2D.setMiterLimit; @docsEditable true
-  void setMiterLimit(num limit) native;
-
-  /// @domName CanvasRenderingContext2D.setShadow; @docsEditable true
-  void setShadow(num width, num height, num blur, [c_OR_color_OR_grayLevel_OR_r, num alpha_OR_g_OR_m, num b_OR_y, num a_OR_k, num a]) native;
-
   /// @domName CanvasRenderingContext2D.setTransform; @docsEditable true
   void setTransform(num m11, num m12, num m21, num m22, num dx, num dy) native;
 
@@ -1379,7 +1334,7 @@
   final String data;
 
   /// @domName CompositionEvent.initCompositionEvent; @docsEditable true
-  void initCompositionEvent(String typeArg, bool canBubbleArg, bool cancelableArg, LocalWindow viewArg, String dataArg) native;
+  void initCompositionEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Window viewArg, String dataArg) 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
@@ -1477,6 +1432,9 @@
   void warn(Object arg) => _isConsoleDefined ?
       JS('void', 'console.warn(#)', arg) : null;
 
+  /// @domName Console.clear; @docsEditable true
+  void clear(Object arg) 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
@@ -1484,11 +1442,18 @@
 
 
 /// @domName HTMLContentElement; @docsEditable true
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Experimental()
 class ContentElement extends Element native "*HTMLContentElement" {
 
   ///@docsEditable true
   factory ContentElement() => document.$dom_createElement("content");
 
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => Element.isTagSupported('content');
+
   /// @domName HTMLContentElement.resetStyleInheritance; @docsEditable true
   bool resetStyleInheritance;
 
@@ -1644,9 +1609,15 @@
   ///@docsEditable true
   factory CssMatrix([String cssValue]) {
     if (!?cssValue) {
-      return _CssMatrixFactoryProvider.createCssMatrix();
+      return CssMatrix._create();
     }
-    return _CssMatrixFactoryProvider.createCssMatrix(cssValue);
+    return CssMatrix._create(cssValue);
+  }
+  static CssMatrix _create([String cssValue]) {
+    if (!?cssValue) {
+      return JS('CssMatrix', 'new WebKitCSSMatrix()');
+    }
+    return JS('CssMatrix', 'new WebKitCSSMatrix(#)', cssValue);
   }
 
   /// @domName WebKitCSSMatrix.a; @docsEditable true
@@ -5294,9 +5265,6 @@
 
   ///@docsEditable true
   factory DListElement() => document.$dom_createElement("dl");
-
-  /// @domName HTMLDListElement.compact; @docsEditable true
-  bool compact;
 }
 // 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
@@ -5304,11 +5272,20 @@
 
 
 /// @domName HTMLDataListElement; @docsEditable true
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class DataListElement extends Element native "*HTMLDataListElement" {
 
   ///@docsEditable true
   factory DataListElement() => document.$dom_createElement("datalist");
 
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => Element.isTagSupported('datalist');
+
   /// @domName HTMLDataListElement.options; @docsEditable true
   final HtmlCollection options;
 }
@@ -5366,12 +5343,21 @@
   ///@docsEditable true
   factory DataView(ArrayBuffer buffer, [int byteOffset, int byteLength]) {
     if (!?byteOffset) {
-      return _DataViewFactoryProvider.createDataView(buffer);
+      return DataView._create(buffer);
     }
     if (!?byteLength) {
-      return _DataViewFactoryProvider.createDataView(buffer, byteOffset);
+      return DataView._create(buffer, byteOffset);
     }
-    return _DataViewFactoryProvider.createDataView(buffer, byteOffset, byteLength);
+    return DataView._create(buffer, byteOffset, byteLength);
+  }
+  static DataView _create(ArrayBuffer buffer, [int byteOffset, int byteLength]) {
+    if (!?byteOffset) {
+      return JS('DataView', 'new DataView(#)', buffer);
+    }
+    if (!?byteLength) {
+      return JS('DataView', 'new DataView(#,#)', buffer, byteOffset);
+    }
+    return JS('DataView', 'new DataView(#,#,#)', buffer, byteOffset, byteLength);
   }
 
   /// @domName DataView.getFloat32; @docsEditable true
@@ -5516,11 +5502,19 @@
 
 
 /// @domName HTMLDetailsElement; @docsEditable true
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental()
 class DetailsElement extends Element native "*HTMLDetailsElement" {
 
   ///@docsEditable true
   factory DetailsElement() => document.$dom_createElement("details");
 
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => Element.isTagSupported('details');
+
   /// @domName HTMLDetailsElement.open; @docsEditable true
   bool open;
 }
@@ -5760,11 +5754,10 @@
   /// @domName Document.cookie; @docsEditable true
   String cookie;
 
-  /// Returns the [Window] associated with the document.
   /// @domName Document.defaultView; @docsEditable true
-  Window get window => _convertNativeToDart_Window(this._window);
+  WindowBase get window => _convertNativeToDart_Window(this._window);
   @JSName('defaultView')
-  @Creates('LocalWindow|=Object') @Returns('LocalWindow|=Object')
+  @Creates('Window|=Object') @Returns('Window|=Object')
   final dynamic _window;
 
   /// @domName Document.documentElement; @docsEditable true
@@ -5877,12 +5870,12 @@
   Text $dom_createTextNode(String data) native;
 
   /// @domName Document.createTouch; @docsEditable true
-  Touch $dom_createTouch(LocalWindow window, EventTarget target, int identifier, int pageX, int pageY, int screenX, int screenY, int webkitRadiusX, int webkitRadiusY, num webkitRotationAngle, num webkitForce) {
+  Touch $dom_createTouch(Window window, EventTarget target, int identifier, int pageX, int pageY, int screenX, int screenY, int webkitRadiusX, int webkitRadiusY, num webkitRotationAngle, num webkitForce) {
     var target_1 = _convertDartToNative_EventTarget(target);
     return _$dom_createTouch_1(window, target_1, identifier, pageX, pageY, screenX, screenY, webkitRadiusX, webkitRadiusY, webkitRotationAngle, webkitForce);
   }
   @JSName('createTouch')
-  Touch _$dom_createTouch_1(LocalWindow window, target, identifier, pageX, pageY, screenX, screenY, webkitRadiusX, webkitRadiusY, webkitRotationAngle, webkitForce) native;
+  Touch _$dom_createTouch_1(Window window, target, identifier, pageX, pageY, screenX, screenY, webkitRadiusX, webkitRadiusY, webkitRotationAngle, webkitForce) native;
 
   /// Use the [TouchList] constructor isntead.
   /// @domName Document.createTouchList; @docsEditable true
@@ -6606,7 +6599,8 @@
 class DomParser native "*DOMParser" {
 
   ///@docsEditable true
-  factory DomParser() => _DomParserFactoryProvider.createDomParser();
+  factory DomParser() => DomParser._create();
+  static DomParser _create() => JS('DomParser', 'new DOMParser()');
 
   /// @domName DOMParser.parseFromString; @docsEditable true
   Document parseFromString(String str, String contentType) native;
@@ -7388,6 +7382,10 @@
    *
    * For standard elements it is more preferable to use the type constructors:
    *     var element = new DivElement();
+   *
+   * See also:
+   *
+   * * [isTagSupported]
    */
   factory Element.tag(String tag) =>
       _ElementFactoryProvider.createElement_tag(tag);
@@ -7601,6 +7599,16 @@
     this.insertAdjacentHtml('beforeend', text);
   }
 
+  /**
+   * Checks to see if the tag name is supported by the current platform.
+   *
+   * The tag should be a valid HTML tag name.
+   */
+  static bool isTagSupported(String tag) {
+    var e = _ElementFactoryProvider.createElement_tag(tag);
+    return e is Element && !(e is UnknownElement);
+  }
+
   // Hooks to support custom WebComponents.
   /**
    * Experimental support for [web components][wc]. This field stores a
@@ -7615,8 +7623,6 @@
   @Creates('Null')  // Set from Dart code; does not instantiate a native type.
   var xtag;
 
-  // TODO(vsm): Implement noSuchMethod or similar for dart2js.
-
   /**
    * Creates a text node and inserts it into the DOM at the specified location.
    *
@@ -7841,6 +7847,12 @@
   /// @domName Element.tagName; @docsEditable true
   final String tagName;
 
+  /// @domName Element.webkitPseudo; @docsEditable true
+  String webkitPseudo;
+
+  /// @domName Element.webkitShadowRoot; @docsEditable true
+  final ShadowRoot webkitShadowRoot;
+
   /// @domName Element.blur; @docsEditable true
   void blur() native;
 
@@ -7915,6 +7927,11 @@
   @JSName('setAttributeNS')
   void $dom_setAttributeNS(String namespaceURI, String qualifiedName, String value) native;
 
+  /// @domName Element.webkitCreateShadowRoot; @docsEditable true
+  @JSName('webkitCreateShadowRoot')
+  @SupportedBrowser(SupportedBrowser.CHROME, '25') @Experimental()
+  ShadowRoot createShadowRoot() native;
+
   /// @domName Element.webkitMatchesSelector; @docsEditable true
   @JSName('webkitMatchesSelector')
   bool matchesSelector(String selectors) native;
@@ -7930,9 +7947,6 @@
 
 }
 
-// Temporary dispatch hook to support WebComponents.
-Function dynamicUnknownElementDispatcher;
-
 final _START_TAG_REGEXP = new RegExp('<(\\w+)');
 class _ElementFactoryProvider {
   static final _CUSTOM_PARENT_TAG_MAP = const {
@@ -7988,7 +8002,7 @@
   /** @domName Document.createElement */
   // Optimization to improve performance until the dart2js compiler inlines this
   // method.
-  static Element createElement_tag(String tag) =>
+  static dynamic createElement_tag(String tag) =>
       JS('Element', 'document.createElement(#)', tag);
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -8177,11 +8191,19 @@
 
 
 /// @domName HTMLEmbedElement; @docsEditable true
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.IE)
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class EmbedElement extends Element native "*HTMLEmbedElement" {
 
   ///@docsEditable true
   factory EmbedElement() => document.$dom_createElement("embed");
 
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => Element.isTagSupported('embed');
+
   /// @domName HTMLEmbedElement.align; @docsEditable true
   String align;
 
@@ -8477,7 +8499,8 @@
 class EventSource extends EventTarget native "*EventSource" {
 
   ///@docsEditable true
-  factory EventSource(String scriptUrl) => _EventSourceFactoryProvider.createEventSource(scriptUrl);
+  factory EventSource(String scriptUrl) => EventSource._create(scriptUrl);
+  static EventSource _create(String scriptUrl) => JS('EventSource', 'new EventSource(#)', scriptUrl);
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   EventSourceEvents get on =>
@@ -8926,7 +8949,8 @@
 class FileReader extends EventTarget native "*FileReader" {
 
   ///@docsEditable true
-  factory FileReader() => _FileReaderFactoryProvider.createFileReader();
+  factory FileReader() => FileReader._create();
+  static FileReader _create() => JS('FileReader', 'new FileReader()');
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   FileReaderEvents get on =>
@@ -9009,7 +9033,8 @@
 class FileReaderSync native "*FileReaderSync" {
 
   ///@docsEditable true
-  factory FileReaderSync() => _FileReaderSyncFactoryProvider.createFileReaderSync();
+  factory FileReaderSync() => FileReaderSync._create();
+  static FileReaderSync _create() => JS('FileReaderSync', 'new FileReaderSync()');
 
   /// @domName FileReaderSync.readAsArrayBuffer; @docsEditable true
   ArrayBuffer readAsArrayBuffer(Blob blob) native;
@@ -9449,9 +9474,15 @@
   ///@docsEditable true
   factory FormData([FormElement form]) {
     if (!?form) {
-      return _FormDataFactoryProvider.createFormData();
+      return FormData._create();
     }
-    return _FormDataFactoryProvider.createFormData(form);
+    return FormData._create(form);
+  }
+  static FormData _create([FormElement form]) {
+    if (!?form) {
+      return JS('FormData', 'new FormData()');
+    }
+    return JS('FormData', 'new FormData(#)', form);
   }
 
   /// @domName DOMFormData.append; @docsEditable true
@@ -9516,9 +9547,9 @@
 class FrameElement extends Element native "*HTMLFrameElement" {
 
   /// @domName HTMLFrameElement.contentWindow; @docsEditable true
-  Window get contentWindow => _convertNativeToDart_Window(this._contentWindow);
+  WindowBase get contentWindow => _convertNativeToDart_Window(this._contentWindow);
   @JSName('contentWindow')
-  @Creates('LocalWindow|=Object') @Returns('LocalWindow|=Object')
+  @Creates('Window|=Object') @Returns('Window|=Object')
   final dynamic _contentWindow;
 
   /// @domName HTMLFrameElement.frameBorder; @docsEditable true
@@ -9681,18 +9712,6 @@
 
   ///@docsEditable true
   factory HRElement() => document.$dom_createElement("hr");
-
-  /// @domName HTMLHRElement.align; @docsEditable true
-  String align;
-
-  /// @domName HTMLHRElement.noShade; @docsEditable true
-  bool noShade;
-
-  /// @domName HTMLHRElement.size; @docsEditable true
-  String size;
-
-  /// @domName HTMLHRElement.width; @docsEditable true
-  String 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
@@ -9723,9 +9742,6 @@
 
   ///@docsEditable true
   factory HeadElement() => document.$dom_createElement("head");
-
-  /// @domName HTMLHeadElement.profile; @docsEditable true
-  String profile;
 }
 // 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
@@ -9752,9 +9768,51 @@
 
   ///@docsEditable true
   factory HeadingElement.h6() => document.$dom_createElement("h6");
+}
+// 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.
 
-  /// @domName HTMLHeadingElement.align; @docsEditable true
-  String align;
+
+/// @domName History; @docsEditable true
+class History implements HistoryBase native "*History" {
+
+  /**
+   * Checks if the State APIs are supported on the current platform.
+   *
+   * See also:
+   *
+   * * [pushState]
+   * * [replaceState]
+   * * [state]
+   */
+  static bool get supportsState => JS('bool', '!!window.history.pushState');
+
+  /// @domName History.length; @docsEditable true
+  final int length;
+
+  /// @domName History.state; @docsEditable true
+  dynamic get state => _convertNativeToDart_SerializedScriptValue(this._state);
+  @JSName('state')
+  @annotation_Creates_SerializedScriptValue @annotation_Returns_SerializedScriptValue
+  final dynamic _state;
+
+  /// @domName History.back; @docsEditable true
+  void back() native;
+
+  /// @domName History.forward; @docsEditable true
+  void forward() native;
+
+  /// @domName History.go; @docsEditable true
+  void go(int distance) native;
+
+  /// @domName History.pushState; @docsEditable true
+  @SupportedBrowser(SupportedBrowser.CHROME) @SupportedBrowser(SupportedBrowser.FIREFOX) @SupportedBrowser(SupportedBrowser.IE, '10') @SupportedBrowser(SupportedBrowser.SAFARI)
+  void pushState(Object data, String title, [String url]) native;
+
+  /// @domName History.replaceState; @docsEditable true
+  @SupportedBrowser(SupportedBrowser.CHROME) @SupportedBrowser(SupportedBrowser.FIREFOX) @SupportedBrowser(SupportedBrowser.IE, '10') @SupportedBrowser(SupportedBrowser.SAFARI)
+  void replaceState(Object data, String title, [String url]) 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
@@ -10110,6 +10168,17 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
+/// @domName HTMLFormControlsCollection; @docsEditable true
+class HtmlFormControlsCollection extends HtmlCollection native "*HTMLFormControlsCollection" {
+
+  /// @domName HTMLFormControlsCollection.namedItem; @docsEditable true
+  Node namedItem(String name) 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
+// BSD-style license that can be found in the LICENSE file.
+
+
 /// @domName HTMLOptionsCollection; @docsEditable true
 class HtmlOptionsCollection extends HtmlCollection native "*HTMLOptionsCollection" {
 
@@ -10125,6 +10194,9 @@
   /// @domName HTMLOptionsCollection.selectedIndex; @docsEditable true
   int selectedIndex;
 
+  /// @domName HTMLOptionsCollection.namedItem; @docsEditable true
+  Node namedItem(String name) native;
+
   /// @domName HTMLOptionsCollection.remove; @docsEditable true
   void remove(int index) native;
 }
@@ -10167,39 +10239,34 @@
    * [onComplete] callback.
    */
   factory HttpRequest.get(String url, onComplete(HttpRequest request)) =>
-      _HttpRequestFactoryProvider.createHttpRequest_get(url, onComplete);
+      _HttpRequestUtils.get(url, onComplete, false);
 
+  // 80 char issue for comments in lists: dartbug.com/7588.
   /**
    * Creates a URL GET request for the specified `url` with
    * credentials such a cookie (already) set in the header or
-   * (authorization headers)[http://tools.ietf.org/html/rfc1945#section-10.2].
+   * [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2).
    * 
    * After completing the request, the object will call the user-provided 
    * [onComplete] callback.
+   *
+   * A few other details to keep in mind when using credentials:
+   *
+   * * Using credentials is only useful for cross-origin requests.
+   * * The `Access-Control-Allow-Origin` header of `url` cannot contain a wildcard (*).
+   * * The `Access-Control-Allow-Credentials` header of `url` must be set to true.
+   * * If `Access-Control-Expose-Headers` has not been set to true, only a subset of all the response headers will be returned when calling [getAllRequestHeaders].
    * 
-   * See also: (authorization headers)[http://en.wikipedia.org/wiki/Basic_access_authentication].
+   * See also: [authorization headers](http://en.wikipedia.org/wiki/Basic_access_authentication).
    */
   factory HttpRequest.getWithCredentials(String url,
       onComplete(HttpRequest request)) =>
-      _HttpRequestFactoryProvider.createHttpRequest_getWithCredentials(url,
-      onComplete);
+      _HttpRequestUtils.get(url, onComplete, true);
 
 
-  /**
-   * General constructor for any type of request (GET, POST, etc).
-   *
-   * This call is used in conjunction with [open]:
-   * 
-   *     var request = new HttpRequest();
-   *     request.open('GET', 'http://dartlang.org')
-   *     request.on.load.add((event) => print('Request complete'));
-   * 
-   * is the (more verbose) equivalent of
-   * 
-   *     var request = new HttpRequest.get('http://dartlang.org', (event) => print('Request complete'));
-   */
   ///@docsEditable true
-  factory HttpRequest() => _HttpRequestFactoryProvider.createHttpRequest();
+  factory HttpRequest() => HttpRequest._create();
+  static HttpRequest _create() => JS('HttpRequest', 'new XMLHttpRequest()');
 
   /**
    * Get the set of [HttpRequestEvents] that this request can respond to.
@@ -10220,7 +10287,38 @@
 
   static const int UNSENT = 0;
 
-  /** @domName XMLHttpRequest.readyState */
+  /**
+   * Indicator of the current state of the request:
+   *
+   * <table>
+   *   <tr>
+   *     <td>Value</td>
+   *     <td>State</td>
+   *     <td>Meaning</td>
+   *   </tr>
+   *   <tr>
+   *     <td>0</td>
+   *     <td>unsent</td>
+   *     <td><code>open()</code> has not yet been called</td>
+   *   </tr>
+   *   <tr>
+   *     <td>1</td>
+   *     <td>opened</td>
+   *     <td><code>send()</code> has not yet been called</td>
+   *   </tr>
+   *   <tr>
+   *     <td>2</td>
+   *     <td>headers received</td>
+   *     <td><code>sent()</code> has been called; response headers and <code>status</code> are available</td>
+   *   </tr>
+   *   <tr>
+   *     <td>3</td> <td>loading</td> <td><code>responseText</code> holds some data</td>
+   *   </tr>
+   *   <tr>
+   *     <td>4</td> <td>done</td> <td>request is complete</td>
+   *   </tr>
+   * </table>
+   */
   /// @domName XMLHttpRequest.readyState; @docsEditable true
   final int readyState;
 
@@ -10236,7 +10334,7 @@
   final Object response;
 
   /**
-   * The response in string form or `null` on failure.
+   * The response in string form or null on failure.
    */
   /// @domName XMLHttpRequest.responseText; @docsEditable true
   final String responseText;
@@ -10246,7 +10344,7 @@
    *
    * Default is `String`.
    * Other options are one of 'arraybuffer', 'blob', 'document', 'json',
-   * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if
+   * 'text'. Some newer browsers will throw `NS_ERROR_DOM_INVALID_ACCESS_ERR` if
    * `responseType` is set while performing a synchronous request.
    *
    * See also: [MDN responseType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType)
@@ -10254,6 +10352,13 @@
   /// @domName XMLHttpRequest.responseType; @docsEditable true
   String responseType;
 
+  /**
+   * The request response, or null on failure.
+   * 
+   * The response is processed as
+   * `text/xml` stream, unless responseType = 'document' and the request is
+   * synchronous.
+   */
   /// @domName XMLHttpRequest.responseXML; @docsEditable true
   @JSName('responseXML')
   final Document responseXml;
@@ -10538,39 +10643,21 @@
   ///@docsEditable true
   factory IFrameElement() => document.$dom_createElement("iframe");
 
-  /// @domName HTMLIFrameElement.align; @docsEditable true
-  String align;
-
   /// @domName HTMLIFrameElement.contentWindow; @docsEditable true
-  Window get contentWindow => _convertNativeToDart_Window(this._contentWindow);
+  WindowBase get contentWindow => _convertNativeToDart_Window(this._contentWindow);
   @JSName('contentWindow')
-  @Creates('LocalWindow|=Object') @Returns('LocalWindow|=Object')
+  @Creates('Window|=Object') @Returns('Window|=Object')
   final dynamic _contentWindow;
 
-  /// @domName HTMLIFrameElement.frameBorder; @docsEditable true
-  String frameBorder;
-
   /// @domName HTMLIFrameElement.height; @docsEditable true
   String height;
 
-  /// @domName HTMLIFrameElement.longDesc; @docsEditable true
-  String longDesc;
-
-  /// @domName HTMLIFrameElement.marginHeight; @docsEditable true
-  String marginHeight;
-
-  /// @domName HTMLIFrameElement.marginWidth; @docsEditable true
-  String marginWidth;
-
   /// @domName HTMLIFrameElement.name; @docsEditable true
   String name;
 
   /// @domName HTMLIFrameElement.sandbox; @docsEditable true
   String sandbox;
 
-  /// @domName HTMLIFrameElement.scrolling; @docsEditable true
-  String scrolling;
-
   /// @domName HTMLIFrameElement.src; @docsEditable true
   String src;
 
@@ -10584,31 +10671,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.
-
-
-typedef void IceCallback(IceCandidate candidate, bool moreToFollow, PeerConnection00 source);
-// 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.
-
-
-/// @domName IceCandidate; @docsEditable true
-class IceCandidate native "*IceCandidate" {
-
-  ///@docsEditable true
-  factory IceCandidate(String label, String candidateLine) => _IceCandidateFactoryProvider.createIceCandidate(label, candidateLine);
-
-  /// @domName IceCandidate.label; @docsEditable true
-  final String label;
-
-  /// @domName IceCandidate.toSdp; @docsEditable true
-  String toSdp() 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
-// BSD-style license that can be found in the LICENSE file.
-
 
 /// @domName ImageData; @docsEditable true
 class ImageData native "*ImageData" {
@@ -10639,9 +10701,6 @@
     return e;
   }
 
-  /// @domName HTMLImageElement.align; @docsEditable true
-  String align;
-
   /// @domName HTMLImageElement.alt; @docsEditable true
   String alt;
 
@@ -10657,21 +10716,12 @@
   /// @domName HTMLImageElement.height; @docsEditable true
   int height;
 
-  /// @domName HTMLImageElement.hspace; @docsEditable true
-  int hspace;
-
   /// @domName HTMLImageElement.isMap; @docsEditable true
   bool isMap;
 
-  /// @domName HTMLImageElement.longDesc; @docsEditable true
-  String longDesc;
-
   /// @domName HTMLImageElement.lowsrc; @docsEditable true
   String lowsrc;
 
-  /// @domName HTMLImageElement.name; @docsEditable true
-  String name;
-
   /// @domName HTMLImageElement.naturalHeight; @docsEditable true
   final int naturalHeight;
 
@@ -10684,9 +10734,6 @@
   /// @domName HTMLImageElement.useMap; @docsEditable true
   String useMap;
 
-  /// @domName HTMLImageElement.vspace; @docsEditable true
-  int vspace;
-
   /// @domName HTMLImageElement.width; @docsEditable true
   int width;
 
@@ -10730,7 +10777,12 @@
   ///@docsEditable true
   factory InputElement({String type}) {
     var e = document.$dom_createElement("input");
-    if (type != null) e.type = type;
+    if (type != null) {
+      try {
+        // IE throws an exception for unknown types.
+        e.type = type;
+      } catch(_) {}
+    }
     return e;
   }
 
@@ -10741,9 +10793,6 @@
   /// @domName HTMLInputElement.accept; @docsEditable true
   String accept;
 
-  /// @domName HTMLInputElement.align; @docsEditable true
-  String align;
-
   /// @domName HTMLInputElement.alt; @docsEditable true
   String alt;
 
@@ -11012,7 +11061,13 @@
 /**
  * Similar to [TextInputElement], but on platforms where search is styled
  * differently this will get the search style.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 abstract class SearchInputElement implements TextInputElementBase {
   factory SearchInputElement() => new InputElement(type: 'search');
 
@@ -11021,6 +11076,11 @@
 
   /// @domName HTMLInputElement.list;
   Element get list;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'search')).type == 'search';
+  }
 }
 
 /**
@@ -11038,12 +11098,23 @@
 
 /**
  * A control for editing an absolute URL.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 abstract class UrlInputElement implements TextInputElementBase {
   factory UrlInputElement() => new InputElement(type: 'url');
 
   /// @domName HTMLInputElement.list;
   Element get list;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'url')).type == 'url';
+  }
 }
 
 /**
@@ -11051,17 +11122,34 @@
  *
  * This provides a single line of text with minimal formatting help since
  * there is a wide variety of telephone numbers.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 abstract class TelephoneInputElement implements TextInputElementBase {
   factory TelephoneInputElement() => new InputElement(type: 'tel');
 
   /// @domName HTMLInputElement.list;
   Element get list;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'tel')).type == 'tel';
+  }
 }
 
 /**
  * An e-mail address or list of e-mail addresses.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 abstract class EmailInputElement implements TextInputElementBase {
   factory EmailInputElement() => new InputElement(type: 'email');
 
@@ -11094,6 +11182,11 @@
 
   /// @domName HTMLInputElement.size
   int size;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'email')).type == 'email';
+  }
 }
 
 /**
@@ -11133,7 +11226,11 @@
 /**
  * A date and time (year, month, day, hour, minute, second, fraction of a
  * second) with the time zone set to UTC.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Experimental()
 abstract class DateTimeInputElement implements RangeInputElementBase {
   factory DateTimeInputElement() => new InputElement(type: 'datetime');
 
@@ -11145,11 +11242,20 @@
 
   /// @domName HTMLInputElement.required
   bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'datetime')).type == 'datetime';
+  }
 }
 
 /**
  * A date (year, month, day) with no time zone.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Experimental()
 abstract class DateInputElement implements RangeInputElementBase {
   factory DateInputElement() => new InputElement(type: 'date');
 
@@ -11161,11 +11267,20 @@
 
   /// @domName HTMLInputElement.required
   bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'date')).type == 'date';
+  }
 }
 
 /**
  * A date consisting of a year and a month with no time zone.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Experimental()
 abstract class MonthInputElement implements RangeInputElementBase {
   factory MonthInputElement() => new InputElement(type: 'month');
 
@@ -11177,11 +11292,20 @@
 
   /// @domName HTMLInputElement.required
   bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'month')).type == 'month';
+  }
 }
 
 /**
  * A date consisting of a week-year number and a week number with no time zone.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Experimental()
 abstract class WeekInputElement implements RangeInputElementBase {
   factory WeekInputElement() => new InputElement(type: 'week');
 
@@ -11193,11 +11317,20 @@
 
   /// @domName HTMLInputElement.required
   bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'week')).type == 'week';
+  }
 }
 
 /**
  * A time (hour, minute, seconds, fractional seconds) with no time zone.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@Experimental()
 abstract class TimeInputElement implements RangeInputElementBase {
   factory TimeInputElement() => new InputElement(type: 'time');
 
@@ -11209,12 +11342,21 @@
 
   /// @domName HTMLInputElement.required
   bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'time')).type == 'time';
+  }
 }
 
 /**
  * A date and time (year, month, day, hour, minute, second, fraction of a
  * second) with no time zone.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Experimental()
 abstract class LocalDateTimeInputElement implements RangeInputElementBase {
   factory LocalDateTimeInputElement() =>
       new InputElement(type: 'datetime-local');
@@ -11224,11 +11366,20 @@
 
   /// @domName HTMLInputElement.required
   bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'datetime-local')).type == 'datetime-local';
+  }
 }
 
 /**
  * A numeric editor control.
  */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.IE)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental()
 abstract class NumberInputElement implements RangeInputElementBase {
   factory NumberInputElement() => new InputElement(type: 'number');
 
@@ -11240,14 +11391,29 @@
 
   /// @domName HTMLInputElement.required
   bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'number')).type == 'number';
+  }
 }
 
 /**
  * Similar to [NumberInputElement] but the browser may provide more optimal
  * styling (such as a slider control).
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@Experimental()
 abstract class RangeInputElement implements RangeInputElementBase {
   factory RangeInputElement() => new InputElement(type: 'range');
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'range')).type == 'range';
+  }
 }
 
 /**
@@ -11825,7 +11991,7 @@
 class KeyboardEvent extends UIEvent native "*KeyboardEvent" {
 
   factory KeyboardEvent(String type, Window view,
-      [bool canBubble = true, bool cancelable = true, 
+      [bool canBubble = true, bool cancelable = true,
       String keyIdentifier = "", int keyLocation = 1, bool ctrlKey = false,
       bool altKey = false, bool shiftKey = false, bool metaKey = false,
       bool altGraphKey = false]) {
@@ -11837,7 +12003,7 @@
 
   /** @domName KeyboardEvent.initKeyboardEvent */
   void $dom_initKeyboardEvent(String type, bool canBubble, bool cancelable,
-      LocalWindow view, String keyIdentifier, int keyLocation, bool ctrlKey,
+      Window view, String keyIdentifier, int keyLocation, bool ctrlKey,
       bool altKey, bool shiftKey, bool metaKey, bool altGraphKey) {
     if (JS('bool', 'typeof(#.initKeyEvent) == "function"', this)) {
       // initKeyEvent is only in Firefox (instead of initKeyboardEvent). It has
@@ -11845,7 +12011,7 @@
       // charCode as the last two arguments, but we just set them as the default
       // since they can't be specified in other browsers.
       JS('void', '#.initKeyEvent(#, #, #, #, #, #, #, #, 0, 0)', this,
-          type, canBubble, cancelable, view, 
+          type, canBubble, cancelable, view,
           ctrlKey, altKey, shiftKey, metaKey);
     } else {
       // initKeyboardEvent is for all other browsers.
@@ -11890,11 +12056,19 @@
 
 
 /// @domName HTMLKeygenElement; @docsEditable true
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental()
 class KeygenElement extends Element native "*HTMLKeygenElement" {
 
   ///@docsEditable true
   factory KeygenElement() => document.$dom_createElement("keygen");
 
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => Element.isTagSupported('keygen') && (new Element.tag('keygen') is KeygenElement);
+
   /// @domName HTMLKeygenElement.autofocus; @docsEditable true
   bool autofocus;
 
@@ -12000,9 +12174,6 @@
   ///@docsEditable true
   factory LinkElement() => document.$dom_createElement("link");
 
-  /// @domName HTMLLinkElement.charset; @docsEditable true
-  String charset;
-
   /// @domName HTMLLinkElement.disabled; @docsEditable true
   bool disabled;
 
@@ -12018,18 +12189,12 @@
   /// @domName HTMLLinkElement.rel; @docsEditable true
   String rel;
 
-  /// @domName HTMLLinkElement.rev; @docsEditable true
-  String rev;
-
   /// @domName HTMLLinkElement.sheet; @docsEditable true
   final StyleSheet sheet;
 
   /// @domName HTMLLinkElement.sizes; @docsEditable true
   DomSettableTokenList sizes;
 
-  /// @domName HTMLLinkElement.target; @docsEditable true
-  String target;
-
   /// @domName HTMLLinkElement.type; @docsEditable true
   String type;
 }
@@ -12038,32 +12203,11 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-/// @domName History; @docsEditable true
-class LocalHistory implements History native "*History" {
+/// @domName LocalMediaStream; @docsEditable true
+class LocalMediaStream extends MediaStream implements EventTarget native "*LocalMediaStream" {
 
-  /// @domName History.length; @docsEditable true
-  final int length;
-
-  /// @domName History.state; @docsEditable true
-  dynamic get state => _convertNativeToDart_SerializedScriptValue(this._state);
-  @JSName('state')
-  @annotation_Creates_SerializedScriptValue @annotation_Returns_SerializedScriptValue
-  final dynamic _state;
-
-  /// @domName History.back; @docsEditable true
-  void back() native;
-
-  /// @domName History.forward; @docsEditable true
-  void forward() native;
-
-  /// @domName History.go; @docsEditable true
-  void go(int distance) native;
-
-  /// @domName History.pushState; @docsEditable true
-  void pushState(Object data, String title, [String url]) native;
-
-  /// @domName History.replaceState; @docsEditable true
-  void replaceState(Object data, String title, [String url]) native;
+  /// @domName LocalMediaStream.stop; @docsEditable true
+  void stop() 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
@@ -12071,7 +12215,7 @@
 
 
 /// @domName Location; @docsEditable true
-class LocalLocation implements Location native "*Location" {
+class Location implements LocationBase native "*Location" {
 
   /// @domName Location.ancestorOrigins; @docsEditable true
   @Returns('DomStringList') @Creates('DomStringList')
@@ -12121,677 +12265,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-/// @domName LocalMediaStream; @docsEditable true
-class LocalMediaStream extends MediaStream implements EventTarget native "*LocalMediaStream" {
-
-  /// @domName LocalMediaStream.stop; @docsEditable true
-  void stop() 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
-// BSD-style license that can be found in the LICENSE file.
-
-
-/// @domName Window
-class LocalWindow extends EventTarget implements Window native "@*DOMWindow" {
-
-  Document get document => JS('Document', '#.document', this);
-
-  Window _open2(url, name) => JS('Window', '#.open(#,#)', this, url, name);
-
-  Window _open3(url, name, options) =>
-      JS('Window', '#.open(#,#,#)', this, url, name, options);
-
-  Window open(String url, String name, [String options]) {
-    if (options == null) {
-      return _DOMWindowCrossFrame._createSafe(_open2(url, name));
-    } else {
-      return _DOMWindowCrossFrame._createSafe(_open3(url, name, options));
-    }
-  }
-
-  // API level getter and setter for Location.
-  // TODO: The cross domain safe wrapper can be inserted here or folded into
-  // _LocationWrapper.
-  LocalLocation get location {
-    // Firefox work-around for Location.  The Firefox location object cannot be
-    // made to behave like a Dart object so must be wrapped.
-    var result = _location;
-    if (_isDartLocation(result)) return result;  // e.g. on Chrome.
-    if (null == _location_wrapper) {
-      _location_wrapper = new _LocationWrapper(result);
-    }
-    return _location_wrapper;
-  }
-
-  // TODO: consider forcing users to do: window.location.assign('string').
-  /**
-   * Sets the window's location, which causes the browser to navigate to the new
-   * location. [value] may be a Location object or a string.
-   */
-  void set location(value) {
-    if (value is _LocationWrapper) {
-      _location = value._ptr;
-    } else {
-      _location = value;
-    }
-  }
-
-  _LocationWrapper _location_wrapper;  // Cached wrapped Location object.
-
-  // Native getter and setter to access raw Location object.
-  Location get _location => JS('Location', '#.location', this);
-  void set _location(Location value) {
-    JS('void', '#.location = #', this, value);
-  }
-  // Prevent compiled from thinking 'location' property is available for a Dart
-  // member.
-  @JSName('location')
-  _protect_location() native;
-
-  static _isDartLocation(thing) {
-    // On Firefox the code that implements 'is Location' fails to find the patch
-    // stub on Object.prototype and throws an exception.
-    try {
-      return thing is Location;
-    } catch (e) {
-      return false;
-    }
-  }
-
-  /**
-   * Executes a [callback] after the next batch of browser layout measurements
-   * has completed or would have completed if any browser layout measurements
-   * had been scheduled.
-   */
-  void requestLayoutFrame(TimeoutHandler callback) {
-    _addMeasurementFrameCallback(callback);
-  }
-
-  /** @domName DOMWindow.requestAnimationFrame */
-  int requestAnimationFrame(RequestAnimationFrameCallback callback) {
-    _ensureRequestAnimationFrame();
-    return _requestAnimationFrame(callback);
-  }
-
-  void cancelAnimationFrame(id) {
-    _ensureRequestAnimationFrame();
-    _cancelAnimationFrame(id);
-  }
-
-  @JSName('requestAnimationFrame')
-  int _requestAnimationFrame(RequestAnimationFrameCallback callback) native;
-
-  @JSName('cancelAnimationFrame')
-  void _cancelAnimationFrame(int id) native;
-
-  _ensureRequestAnimationFrame() {
-    if (JS('bool',
-           '!!(#.requestAnimationFrame && #.cancelAnimationFrame)', this, this))
-      return;
-
-    JS('void',
-       r"""
-  (function($this) {
-   var vendors = ['ms', 'moz', 'webkit', 'o'];
-   for (var i = 0; i < vendors.length && !$this.requestAnimationFrame; ++i) {
-     $this.requestAnimationFrame = $this[vendors[i] + 'RequestAnimationFrame'];
-     $this.cancelAnimationFrame =
-         $this[vendors[i]+'CancelAnimationFrame'] ||
-         $this[vendors[i]+'CancelRequestAnimationFrame'];
-   }
-   if ($this.requestAnimationFrame && $this.cancelAnimationFrame) return;
-   $this.requestAnimationFrame = function(callback) {
-      return window.setTimeout(function() {
-        callback(Date.now());
-      }, 16 /* 16ms ~= 60fps */);
-   };
-   $this.cancelAnimationFrame = function(id) { clearTimeout(id); }
-  })(#)""",
-       this);
-  }
-
-  IdbFactory get indexedDB =>
-      JS('IdbFactory',
-         '#.indexedDB || #.webkitIndexedDB || #.mozIndexedDB',
-         this, this, this);
-
-  /**
-   * Lookup a port by its [name].  Return null if no port is
-   * registered under [name].
-   */
-  SendPortSync lookupPort(String name) {
-    var port = JSON.parse(document.documentElement.attributes['dart-port:$name']);
-    return _deserialize(port);
-  }
-
-  /**
-   * Register a [port] on this window under the given [name].  This
-   * port may be retrieved by any isolate (or JavaScript script)
-   * running in this window.
-   */
-  void registerPort(String name, var port) {
-    var serialized = _serialize(port);
-    document.documentElement.attributes['dart-port:$name'] = JSON.stringify(serialized);
-  }
-  
-  /// @domName Window.console; @docsEditable true
-  Console get console => Console.safeConsole;
-
-
-  /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
-  LocalWindowEvents get on =>
-    new LocalWindowEvents(this);
-
-  static const int PERSISTENT = 1;
-
-  static const int TEMPORARY = 0;
-
-  /// @domName Window.applicationCache; @docsEditable true
-  final ApplicationCache applicationCache;
-
-  /// @domName Window.closed; @docsEditable true
-  final bool closed;
-
-  /// @domName Window.crypto; @docsEditable true
-  final Crypto crypto;
-
-  /// @domName Window.defaultStatus; @docsEditable true
-  String defaultStatus;
-
-  /// @domName Window.defaultstatus; @docsEditable true
-  String defaultstatus;
-
-  /// @domName Window.devicePixelRatio; @docsEditable true
-  final num devicePixelRatio;
-
-  /// @domName Window.event; @docsEditable true
-  final Event event;
-
-  /// @domName Window.history; @docsEditable true
-  final LocalHistory history;
-
-  /// @domName Window.innerHeight; @docsEditable true
-  final int innerHeight;
-
-  /// @domName Window.innerWidth; @docsEditable true
-  final int innerWidth;
-
-  /// @domName Window.localStorage; @docsEditable true
-  final Storage localStorage;
-
-  /// @domName Window.locationbar; @docsEditable true
-  final BarInfo locationbar;
-
-  /// @domName Window.menubar; @docsEditable true
-  final BarInfo menubar;
-
-  /// @domName Window.name; @docsEditable true
-  String name;
-
-  /// @domName Window.navigator; @docsEditable true
-  final Navigator navigator;
-
-  /// @domName Window.offscreenBuffering; @docsEditable true
-  final bool offscreenBuffering;
-
-  /// @domName Window.opener; @docsEditable true
-  Window get opener => _convertNativeToDart_Window(this._opener);
-  @JSName('opener')
-  @Creates('LocalWindow|=Object') @Returns('LocalWindow|=Object')
-  final dynamic _opener;
-
-  /// @domName Window.outerHeight; @docsEditable true
-  final int outerHeight;
-
-  /// @domName Window.outerWidth; @docsEditable true
-  final int outerWidth;
-
-  /// @domName DOMWindow.pagePopupController; @docsEditable true
-  final PagePopupController pagePopupController;
-
-  /// @domName Window.pageXOffset; @docsEditable true
-  final int pageXOffset;
-
-  /// @domName Window.pageYOffset; @docsEditable true
-  final int pageYOffset;
-
-  /// @domName Window.parent; @docsEditable true
-  Window get parent => _convertNativeToDart_Window(this._parent);
-  @JSName('parent')
-  @Creates('LocalWindow|=Object') @Returns('LocalWindow|=Object')
-  final dynamic _parent;
-
-  /// @domName Window.performance; @docsEditable true
-  final Performance performance;
-
-  /// @domName Window.personalbar; @docsEditable true
-  final BarInfo personalbar;
-
-  /// @domName Window.screen; @docsEditable true
-  final Screen screen;
-
-  /// @domName Window.screenLeft; @docsEditable true
-  final int screenLeft;
-
-  /// @domName Window.screenTop; @docsEditable true
-  final int screenTop;
-
-  /// @domName Window.screenX; @docsEditable true
-  final int screenX;
-
-  /// @domName Window.screenY; @docsEditable true
-  final int screenY;
-
-  /// @domName Window.scrollX; @docsEditable true
-  final int scrollX;
-
-  /// @domName Window.scrollY; @docsEditable true
-  final int scrollY;
-
-  /// @domName Window.scrollbars; @docsEditable true
-  final BarInfo scrollbars;
-
-  /// @domName Window.self; @docsEditable true
-  Window get self => _convertNativeToDart_Window(this._self);
-  @JSName('self')
-  @Creates('LocalWindow|=Object') @Returns('LocalWindow|=Object')
-  final dynamic _self;
-
-  /// @domName Window.sessionStorage; @docsEditable true
-  final Storage sessionStorage;
-
-  /// @domName Window.status; @docsEditable true
-  String status;
-
-  /// @domName Window.statusbar; @docsEditable true
-  final BarInfo statusbar;
-
-  /// @domName Window.styleMedia; @docsEditable true
-  final StyleMedia styleMedia;
-
-  /// @domName Window.toolbar; @docsEditable true
-  final BarInfo toolbar;
-
-  /// @domName Window.top; @docsEditable true
-  Window get top => _convertNativeToDart_Window(this._top);
-  @JSName('top')
-  @Creates('LocalWindow|=Object') @Returns('LocalWindow|=Object')
-  final dynamic _top;
-
-  /// @domName DOMWindow.webkitNotifications; @docsEditable true
-  final NotificationCenter webkitNotifications;
-
-  /// @domName DOMWindow.webkitStorageInfo; @docsEditable true
-  final StorageInfo webkitStorageInfo;
-
-  /// @domName Window.window; @docsEditable true
-  Window get window => _convertNativeToDart_Window(this._window);
-  @JSName('window')
-  @Creates('LocalWindow|=Object') @Returns('LocalWindow|=Object')
-  final dynamic _window;
-
-  /// @domName Window.addEventListener; @docsEditable true
-  @JSName('addEventListener')
-  void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
-
-  /// @domName Window.alert; @docsEditable true
-  void alert(String message) native;
-
-  /// @domName Window.atob; @docsEditable true
-  String atob(String string) native;
-
-  /// @domName Window.btoa; @docsEditable true
-  String btoa(String string) native;
-
-  /// @domName Window.captureEvents; @docsEditable true
-  void captureEvents() native;
-
-  /// @domName Window.clearInterval; @docsEditable true
-  void clearInterval(int handle) native;
-
-  /// @domName Window.clearTimeout; @docsEditable true
-  void clearTimeout(int handle) native;
-
-  /// @domName Window.close; @docsEditable true
-  void close() native;
-
-  /// @domName Window.confirm; @docsEditable true
-  bool confirm(String message) native;
-
-  /// @domName Window.dispatchEvent; @docsEditable true
-  @JSName('dispatchEvent')
-  bool $dom_dispatchEvent(Event evt) native;
-
-  /// @domName Window.find; @docsEditable true
-  bool find(String string, bool caseSensitive, bool backwards, bool wrap, bool wholeWord, bool searchInFrames, bool showDialog) native;
-
-  /// @domName Window.getComputedStyle; @docsEditable true
-  @JSName('getComputedStyle')
-  CssStyleDeclaration $dom_getComputedStyle(Element element, String pseudoElement) native;
-
-  /// @domName Window.getMatchedCSSRules; @docsEditable true
-  @JSName('getMatchedCSSRules')
-  @Returns('_CssRuleList') @Creates('_CssRuleList')
-  List<CssRule> getMatchedCssRules(Element element, String pseudoElement) native;
-
-  /// @domName Window.getSelection; @docsEditable true
-  DomSelection getSelection() native;
-
-  /// @domName Window.matchMedia; @docsEditable true
-  MediaQueryList matchMedia(String query) native;
-
-  /// @domName Window.moveBy; @docsEditable true
-  void moveBy(num x, num y) native;
-
-  /// @domName Window.moveTo; @docsEditable true
-  void moveTo(num x, num y) native;
-
-  /// @domName DOMWindow.openDatabase; @docsEditable true
-  @Creates('Database') @Creates('DatabaseSync')
-  Database openDatabase(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) native;
-
-  /// @domName Window.postMessage; @docsEditable true
-  void postMessage(/*SerializedScriptValue*/ message, String targetOrigin, [List messagePorts]) {
-    if (?message &&
-        !?messagePorts) {
-      var message_1 = convertDartToNative_SerializedScriptValue(message);
-      _postMessage_1(message_1, targetOrigin);
-      return;
-    }
-    if (?message) {
-      var message_2 = convertDartToNative_SerializedScriptValue(message);
-      _postMessage_2(message_2, targetOrigin, messagePorts);
-      return;
-    }
-    throw new ArgumentError("Incorrect number or type of arguments");
-  }
-  @JSName('postMessage')
-  void _postMessage_1(message, targetOrigin) native;
-  @JSName('postMessage')
-  void _postMessage_2(message, targetOrigin, List messagePorts) native;
-
-  /// @domName Window.print; @docsEditable true
-  void print() native;
-
-  /// @domName Window.releaseEvents; @docsEditable true
-  void releaseEvents() native;
-
-  /// @domName Window.removeEventListener; @docsEditable true
-  @JSName('removeEventListener')
-  void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
-
-  /// @domName Window.resizeBy; @docsEditable true
-  void resizeBy(num x, num y) native;
-
-  /// @domName Window.resizeTo; @docsEditable true
-  void resizeTo(num width, num height) native;
-
-  /// @domName Window.scroll; @docsEditable true
-  void scroll(int x, int y) native;
-
-  /// @domName Window.scrollBy; @docsEditable true
-  void scrollBy(int x, int y) native;
-
-  /// @domName Window.scrollTo; @docsEditable true
-  void scrollTo(int x, int y) native;
-
-  /// @domName Window.setInterval; @docsEditable true
-  int setInterval(TimeoutHandler handler, int timeout) native;
-
-  /// @domName Window.setTimeout; @docsEditable true
-  int setTimeout(TimeoutHandler handler, int timeout) native;
-
-  /// @domName Window.showModalDialog; @docsEditable true
-  Object showModalDialog(String url, [Object dialogArgs, String featureArgs]) native;
-
-  /// @domName Window.stop; @docsEditable true
-  void stop() native;
-
-  /// @domName Window.webkitConvertPointFromNodeToPage; @docsEditable true
-  Point webkitConvertPointFromNodeToPage(Node node, Point p) native;
-
-  /// @domName Window.webkitConvertPointFromPageToNode; @docsEditable true
-  Point webkitConvertPointFromPageToNode(Node node, Point p) native;
-
-  /// @domName DOMWindow.webkitRequestFileSystem; @docsEditable true
-  void webkitRequestFileSystem(int type, int size, FileSystemCallback successCallback, [ErrorCallback errorCallback]) native;
-
-  /// @domName DOMWindow.webkitResolveLocalFileSystemURL; @docsEditable true
-  @JSName('webkitResolveLocalFileSystemURL')
-  void webkitResolveLocalFileSystemUrl(String url, EntryCallback successCallback, [ErrorCallback errorCallback]) native;
-
-}
-
-/// @docsEditable true
-class LocalWindowEvents extends Events {
-  /// @docsEditable true
-  LocalWindowEvents(EventTarget _ptr) : super(_ptr);
-
-  /// @docsEditable true
-  EventListenerList get abort => this['abort'];
-
-  /// @docsEditable true
-  EventListenerList get beforeUnload => this['beforeunload'];
-
-  /// @docsEditable true
-  EventListenerList get blur => this['blur'];
-
-  /// @docsEditable true
-  EventListenerList get canPlay => this['canplay'];
-
-  /// @docsEditable true
-  EventListenerList get canPlayThrough => this['canplaythrough'];
-
-  /// @docsEditable true
-  EventListenerList get change => this['change'];
-
-  /// @docsEditable true
-  EventListenerList get click => this['click'];
-
-  /// @docsEditable true
-  EventListenerList get contextMenu => this['contextmenu'];
-
-  /// @docsEditable true
-  EventListenerList get doubleClick => this['dblclick'];
-
-  /// @docsEditable true
-  EventListenerList get deviceMotion => this['devicemotion'];
-
-  /// @docsEditable true
-  EventListenerList get deviceOrientation => this['deviceorientation'];
-
-  /// @docsEditable true
-  EventListenerList get drag => this['drag'];
-
-  /// @docsEditable true
-  EventListenerList get dragEnd => this['dragend'];
-
-  /// @docsEditable true
-  EventListenerList get dragEnter => this['dragenter'];
-
-  /// @docsEditable true
-  EventListenerList get dragLeave => this['dragleave'];
-
-  /// @docsEditable true
-  EventListenerList get dragOver => this['dragover'];
-
-  /// @docsEditable true
-  EventListenerList get dragStart => this['dragstart'];
-
-  /// @docsEditable true
-  EventListenerList get drop => this['drop'];
-
-  /// @docsEditable true
-  EventListenerList get durationChange => this['durationchange'];
-
-  /// @docsEditable true
-  EventListenerList get emptied => this['emptied'];
-
-  /// @docsEditable true
-  EventListenerList get ended => this['ended'];
-
-  /// @docsEditable true
-  EventListenerList get error => this['error'];
-
-  /// @docsEditable true
-  EventListenerList get focus => this['focus'];
-
-  /// @docsEditable true
-  EventListenerList get hashChange => this['hashchange'];
-
-  /// @docsEditable true
-  EventListenerList get input => this['input'];
-
-  /// @docsEditable true
-  EventListenerList get invalid => this['invalid'];
-
-  /// @docsEditable true
-  EventListenerList get keyDown => this['keydown'];
-
-  /// @docsEditable true
-  EventListenerList get keyPress => this['keypress'];
-
-  /// @docsEditable true
-  EventListenerList get keyUp => this['keyup'];
-
-  /// @docsEditable true
-  EventListenerList get load => this['load'];
-
-  /// @docsEditable true
-  EventListenerList get loadedData => this['loadeddata'];
-
-  /// @docsEditable true
-  EventListenerList get loadedMetadata => this['loadedmetadata'];
-
-  /// @docsEditable true
-  EventListenerList get loadStart => this['loadstart'];
-
-  /// @docsEditable true
-  EventListenerList get message => this['message'];
-
-  /// @docsEditable true
-  EventListenerList get mouseDown => this['mousedown'];
-
-  /// @docsEditable true
-  EventListenerList get mouseMove => this['mousemove'];
-
-  /// @docsEditable true
-  EventListenerList get mouseOut => this['mouseout'];
-
-  /// @docsEditable true
-  EventListenerList get mouseOver => this['mouseover'];
-
-  /// @docsEditable true
-  EventListenerList get mouseUp => this['mouseup'];
-
-  /// @docsEditable true
-  EventListenerList get mouseWheel => this['mousewheel'];
-
-  /// @docsEditable true
-  EventListenerList get offline => this['offline'];
-
-  /// @docsEditable true
-  EventListenerList get online => this['online'];
-
-  /// @docsEditable true
-  EventListenerList get pageHide => this['pagehide'];
-
-  /// @docsEditable true
-  EventListenerList get pageShow => this['pageshow'];
-
-  /// @docsEditable true
-  EventListenerList get pause => this['pause'];
-
-  /// @docsEditable true
-  EventListenerList get play => this['play'];
-
-  /// @docsEditable true
-  EventListenerList get playing => this['playing'];
-
-  /// @docsEditable true
-  EventListenerList get popState => this['popstate'];
-
-  /// @docsEditable true
-  EventListenerList get progress => this['progress'];
-
-  /// @docsEditable true
-  EventListenerList get rateChange => this['ratechange'];
-
-  /// @docsEditable true
-  EventListenerList get reset => this['reset'];
-
-  /// @docsEditable true
-  EventListenerList get resize => this['resize'];
-
-  /// @docsEditable true
-  EventListenerList get scroll => this['scroll'];
-
-  /// @docsEditable true
-  EventListenerList get search => this['search'];
-
-  /// @docsEditable true
-  EventListenerList get seeked => this['seeked'];
-
-  /// @docsEditable true
-  EventListenerList get seeking => this['seeking'];
-
-  /// @docsEditable true
-  EventListenerList get select => this['select'];
-
-  /// @docsEditable true
-  EventListenerList get stalled => this['stalled'];
-
-  /// @docsEditable true
-  EventListenerList get storage => this['storage'];
-
-  /// @docsEditable true
-  EventListenerList get submit => this['submit'];
-
-  /// @docsEditable true
-  EventListenerList get suspend => this['suspend'];
-
-  /// @docsEditable true
-  EventListenerList get timeUpdate => this['timeupdate'];
-
-  /// @docsEditable true
-  EventListenerList get touchCancel => this['touchcancel'];
-
-  /// @docsEditable true
-  EventListenerList get touchEnd => this['touchend'];
-
-  /// @docsEditable true
-  EventListenerList get touchMove => this['touchmove'];
-
-  /// @docsEditable true
-  EventListenerList get touchStart => this['touchstart'];
-
-  /// @docsEditable true
-  EventListenerList get unload => this['unload'];
-
-  /// @docsEditable true
-  EventListenerList get volumeChange => this['volumechange'];
-
-  /// @docsEditable true
-  EventListenerList get waiting => this['waiting'];
-
-  /// @docsEditable true
-  EventListenerList get animationEnd => this['webkitAnimationEnd'];
-
-  /// @docsEditable true
-  EventListenerList get animationIteration => this['webkitAnimationIteration'];
-
-  /// @docsEditable true
-  EventListenerList get animationStart => this['webkitAnimationStart'];
-
-  /// @docsEditable true
-  EventListenerList get transitionEnd => this['webkitTransitionEnd'];
-}
-// 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.
-
-
 /// @domName HTMLMapElement; @docsEditable true
 class MapElement extends Element native "*HTMLMapElement" {
 
@@ -12812,6 +12285,11 @@
 /// @domName HTMLMarqueeElement; @docsEditable true
 class MarqueeElement extends Element native "*HTMLMarqueeElement" {
 
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => Element.isTagSupported('marquee')&& (new Element.tag('marquee') is MarqueeElement);
+
   /// @domName HTMLMarqueeElement.behavior; @docsEditable true
   String behavior;
 
@@ -12860,7 +12338,8 @@
 class MediaController extends EventTarget native "*MediaController" {
 
   ///@docsEditable true
-  factory MediaController() => _MediaControllerFactoryProvider.createMediaController();
+  factory MediaController() => MediaController._create();
+  static MediaController _create() => JS('MediaController', 'new MediaController()');
 
   /// @domName MediaController.buffered; @docsEditable true
   final TimeRanges buffered;
@@ -12883,6 +12362,9 @@
   /// @domName MediaController.playbackRate; @docsEditable true
   num playbackRate;
 
+  /// @domName MediaController.playbackState; @docsEditable true
+  final String playbackState;
+
   /// @domName MediaController.played; @docsEditable true
   final TimeRanges played;
 
@@ -12909,6 +12391,9 @@
   /// @domName MediaController.removeEventListener; @docsEditable true
   @JSName('removeEventListener')
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
+
+  /// @domName MediaController.unpause; @docsEditable true
+  void unpause() 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
@@ -13278,7 +12763,8 @@
 class MediaSource extends EventTarget native "*MediaSource" {
 
   ///@docsEditable true
-  factory MediaSource() => _MediaSourceFactoryProvider.createMediaSource();
+  factory MediaSource() => MediaSource._create();
+  static MediaSource _create() => JS('MediaSource', 'new MediaSource()');
 
   /// @domName MediaSource.activeSourceBuffers; @docsEditable true
   final SourceBufferList activeSourceBuffers;
@@ -13322,7 +12808,8 @@
 class MediaStream extends EventTarget native "*MediaStream" {
 
   ///@docsEditable true
-  factory MediaStream(MediaStreamTrackList audioTracks, MediaStreamTrackList videoTracks) => _MediaStreamFactoryProvider.createMediaStream(audioTracks, videoTracks);
+  factory MediaStream(MediaStreamTrackList audioTracks, MediaStreamTrackList videoTracks) => MediaStream._create(audioTracks, videoTracks);
+  static MediaStream _create(MediaStreamTrackList audioTracks, MediaStreamTrackList videoTracks) => JS('MediaStream', 'new MediaStream(#,#)', audioTracks, videoTracks);
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   MediaStreamEvents get on =>
@@ -13539,7 +13026,8 @@
 class MessageChannel native "*MessageChannel" {
 
   ///@docsEditable true
-  factory MessageChannel() => _MessageChannelFactoryProvider.createMessageChannel();
+  factory MessageChannel() => MessageChannel._create();
+  static MessageChannel _create() => JS('MessageChannel', 'new MessageChannel()');
 
   /// @domName MessageChannel.port1; @docsEditable true
   final MessagePort port1;
@@ -13572,16 +13060,16 @@
   final List ports;
 
   /// @domName MessageEvent.source; @docsEditable true
-  Window get source => _convertNativeToDart_Window(this._source);
+  WindowBase get source => _convertNativeToDart_Window(this._source);
   @JSName('source')
-  @Creates('LocalWindow|=Object') @Returns('LocalWindow|=Object')
+  @Creates('Window|=Object') @Returns('Window|=Object')
   final dynamic _source;
 
   /// @domName MessageEvent.initMessageEvent; @docsEditable true
-  void initMessageEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Object dataArg, String originArg, String lastEventIdArg, LocalWindow sourceArg, List messagePorts) native;
+  void initMessageEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Object dataArg, String originArg, String lastEventIdArg, Window sourceArg, List messagePorts) native;
 
   /// @domName MessageEvent.webkitInitMessageEvent; @docsEditable true
-  void webkitInitMessageEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Object dataArg, String originArg, String lastEventIdArg, LocalWindow sourceArg, List transferables) native;
+  void webkitInitMessageEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Object dataArg, String originArg, String lastEventIdArg, Window sourceArg, List transferables) 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
@@ -13654,9 +13142,6 @@
 
   /// @domName HTMLMetaElement.name; @docsEditable true
   String name;
-
-  /// @domName HTMLMetaElement.scheme; @docsEditable true
-  String scheme;
 }
 // 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
@@ -13686,11 +13171,19 @@
 
 
 /// @domName HTMLMeterElement; @docsEditable true
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class MeterElement extends Element native "*HTMLMeterElement" {
 
   ///@docsEditable true
   factory MeterElement() => document.$dom_createElement("meter");
 
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => Element.isTagSupported('meter');
+
   /// @domName HTMLMeterElement.high; @docsEditable true
   num high;
 
@@ -13800,13 +13293,13 @@
   final int y;
 
   /// @domName MouseEvent.initMouseEvent; @docsEditable true
-  void $dom_initMouseEvent(String type, bool canBubble, bool cancelable, LocalWindow view, int detail, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, int button, EventTarget relatedTarget) {
+  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) {
     var relatedTarget_1 = _convertDartToNative_EventTarget(relatedTarget);
     _$dom_initMouseEvent_1(type, canBubble, cancelable, view, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget_1);
     return;
   }
   @JSName('initMouseEvent')
-  void _$dom_initMouseEvent_1(type, canBubble, cancelable, LocalWindow view, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget) native;
+  void _$dom_initMouseEvent_1(type, canBubble, cancelable, Window view, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget) native;
 
 
   int get offsetX {
@@ -13883,10 +13376,23 @@
 
 
 /// @domName MutationObserver
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental()
 class MutationObserver native "*MutationObserver" {
 
   ///@docsEditable true
-  factory MutationObserver(MutationCallback callback) => _MutationObserverFactoryProvider.createMutationObserver(callback);
+  factory MutationObserver(MutationCallback callback) => MutationObserver._create(callback);
+  static MutationObserver _create(MutationCallback callback) {
+    // Dummy statement to mark types as instantiated.
+    JS('MutationObserver|MutationRecord', '0');
+
+    return JS('MutationObserver',
+        'new(window.MutationObserver||window.WebKitMutationObserver||'
+        'window.MozMutationObserver)(#)',
+        convertDartClosureToJS(callback, 2));
+  }
 
   /// @domName MutationObserver.disconnect; @docsEditable true
   void disconnect() native;
@@ -13903,6 +13409,15 @@
   /// @domName MutationObserver.takeRecords; @docsEditable true
   List<MutationRecord> takeRecords() native;
 
+  /**
+   * Checks to see if the mutation observer API is supported on the current
+   * platform.
+   */
+  static bool get supported {
+    return JS('bool',
+        '!!(window.MutationObserver || window.WebKitMutationObserver)');
+  }
+
   void observe(Node target,
                {Map options,
                 bool childList,
@@ -14760,9 +14275,15 @@
   ///@docsEditable true
   factory Notification(String title, [Map options]) {
     if (!?options) {
-      return _NotificationFactoryProvider.createNotification(title);
+      return Notification._create(title);
     }
-    return _NotificationFactoryProvider.createNotification(title, options);
+    return Notification._create(title, options);
+  }
+  static Notification _create(String title, [Map options]) {
+    if (!?options) {
+      return JS('Notification', 'new Notification(#)', title);
+    }
+    return JS('Notification', 'new Notification(#,#)', title, options);
   }
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
@@ -14866,9 +14387,6 @@
   ///@docsEditable true
   factory OListElement() => document.$dom_createElement("ol");
 
-  /// @domName HTMLOListElement.compact; @docsEditable true
-  bool compact;
-
   /// @domName HTMLOListElement.reversed; @docsEditable true
   bool reversed;
 
@@ -14884,50 +14402,34 @@
 
 
 /// @domName HTMLObjectElement; @docsEditable true
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class ObjectElement extends Element native "*HTMLObjectElement" {
 
   ///@docsEditable true
   factory ObjectElement() => document.$dom_createElement("object");
 
-  /// @domName HTMLObjectElement.align; @docsEditable true
-  String align;
-
-  /// @domName HTMLObjectElement.archive; @docsEditable true
-  String archive;
-
-  /// @domName HTMLObjectElement.border; @docsEditable true
-  String border;
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => Element.isTagSupported('object');
 
   /// @domName HTMLObjectElement.code; @docsEditable true
   String code;
 
-  /// @domName HTMLObjectElement.codeBase; @docsEditable true
-  String codeBase;
-
-  /// @domName HTMLObjectElement.codeType; @docsEditable true
-  String codeType;
-
   /// @domName HTMLObjectElement.data; @docsEditable true
   String data;
 
-  /// @domName HTMLObjectElement.declare; @docsEditable true
-  bool declare;
-
   /// @domName HTMLObjectElement.form; @docsEditable true
   final FormElement form;
 
   /// @domName HTMLObjectElement.height; @docsEditable true
   String height;
 
-  /// @domName HTMLObjectElement.hspace; @docsEditable true
-  int hspace;
-
   /// @domName HTMLObjectElement.name; @docsEditable true
   String name;
 
-  /// @domName HTMLObjectElement.standby; @docsEditable true
-  String standby;
-
   /// @domName HTMLObjectElement.type; @docsEditable true
   String type;
 
@@ -14940,9 +14442,6 @@
   /// @domName HTMLObjectElement.validity; @docsEditable true
   final ValidityState validity;
 
-  /// @domName HTMLObjectElement.vspace; @docsEditable true
-  int vspace;
-
   /// @domName HTMLObjectElement.width; @docsEditable true
   String width;
 
@@ -15035,18 +14534,33 @@
   ///@docsEditable true
   factory OptionElement([String data, String value, bool defaultSelected, bool selected]) {
     if (!?data) {
-      return _OptionElementFactoryProvider.createOptionElement();
+      return OptionElement._create();
     }
     if (!?value) {
-      return _OptionElementFactoryProvider.createOptionElement(data);
+      return OptionElement._create(data);
     }
     if (!?defaultSelected) {
-      return _OptionElementFactoryProvider.createOptionElement(data, value);
+      return OptionElement._create(data, value);
     }
     if (!?selected) {
-      return _OptionElementFactoryProvider.createOptionElement(data, value, defaultSelected);
+      return OptionElement._create(data, value, defaultSelected);
     }
-    return _OptionElementFactoryProvider.createOptionElement(data, value, defaultSelected, selected);
+    return OptionElement._create(data, value, defaultSelected, selected);
+  }
+  static OptionElement _create([String data, String value, bool defaultSelected, bool selected]) {
+    if (!?data) {
+      return JS('OptionElement', 'new Option()');
+    }
+    if (!?value) {
+      return JS('OptionElement', 'new Option(#)', data);
+    }
+    if (!?defaultSelected) {
+      return JS('OptionElement', 'new Option(#,#)', data, value);
+    }
+    if (!?selected) {
+      return JS('OptionElement', 'new Option(#,#,#)', data, value, defaultSelected);
+    }
+    return JS('OptionElement', 'new Option(#,#,#,#)', data, value, defaultSelected, selected);
   }
 
   /// @domName HTMLOptionElement.defaultSelected; @docsEditable true
@@ -15076,11 +14590,19 @@
 
 
 /// @domName HTMLOutputElement; @docsEditable true
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class OutputElement extends Element native "*HTMLOutputElement" {
 
   ///@docsEditable true
   factory OutputElement() => document.$dom_createElement("output");
 
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => Element.isTagSupported('output');
+
   /// @domName HTMLOutputElement.defaultValue; @docsEditable true
   String defaultValue;
 
@@ -15149,6 +14671,12 @@
 /// @domName PagePopupController; @docsEditable true
 class PagePopupController native "*PagePopupController" {
 
+  /// @domName PagePopupController.formatMonth; @docsEditable true
+  String formatMonth(int year, int zeroBaseMonth) native;
+
+  /// @domName PagePopupController.histogramEnumeration; @docsEditable true
+  void histogramEnumeration(String name, int sample, int boundaryValue) native;
+
   /// @domName PagePopupController.localizeNumberString; @docsEditable true
   String localizeNumberString(String numberString) native;
 
@@ -15176,9 +14704,6 @@
 
   ///@docsEditable true
   factory ParagraphElement() => document.$dom_createElement("p");
-
-  /// @domName HTMLParagraphElement.align; @docsEditable true
-  String align;
 }
 // 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
@@ -15194,181 +14719,8 @@
   /// @domName HTMLParamElement.name; @docsEditable true
   String name;
 
-  /// @domName HTMLParamElement.type; @docsEditable true
-  String type;
-
   /// @domName HTMLParamElement.value; @docsEditable true
   String value;
-
-  /// @domName HTMLParamElement.valueType; @docsEditable true
-  String valueType;
-}
-// 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.
-
-
-/// @domName PeerConnection00; @docsEditable true
-class PeerConnection00 extends EventTarget native "*PeerConnection00" {
-
-  ///@docsEditable true
-  factory PeerConnection00(String serverConfiguration, IceCallback iceCallback) => _PeerConnection00FactoryProvider.createPeerConnection00(serverConfiguration, iceCallback);
-
-  /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
-  PeerConnection00Events get on =>
-    new PeerConnection00Events(this);
-
-  static const int ACTIVE = 2;
-
-  static const int CLOSED = 3;
-
-  static const int ICE_CHECKING = 0x300;
-
-  static const int ICE_CLOSED = 0x700;
-
-  static const int ICE_COMPLETED = 0x500;
-
-  static const int ICE_CONNECTED = 0x400;
-
-  static const int ICE_FAILED = 0x600;
-
-  static const int ICE_GATHERING = 0x100;
-
-  static const int ICE_WAITING = 0x200;
-
-  static const int NEW = 0;
-
-  static const int OPENING = 1;
-
-  static const int SDP_ANSWER = 0x300;
-
-  static const int SDP_OFFER = 0x100;
-
-  static const int SDP_PRANSWER = 0x200;
-
-  /// @domName PeerConnection00.iceState; @docsEditable true
-  final int iceState;
-
-  /// @domName PeerConnection00.localDescription; @docsEditable true
-  final SessionDescription localDescription;
-
-  /// @domName PeerConnection00.localStreams; @docsEditable true
-  @Returns('_MediaStreamList') @Creates('_MediaStreamList')
-  final List<MediaStream> localStreams;
-
-  /// @domName PeerConnection00.readyState; @docsEditable true
-  final int readyState;
-
-  /// @domName PeerConnection00.remoteDescription; @docsEditable true
-  final SessionDescription remoteDescription;
-
-  /// @domName PeerConnection00.remoteStreams; @docsEditable true
-  @Returns('_MediaStreamList') @Creates('_MediaStreamList')
-  final List<MediaStream> remoteStreams;
-
-  /// @domName PeerConnection00.addEventListener; @docsEditable true
-  @JSName('addEventListener')
-  void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
-
-  /// @domName PeerConnection00.addStream; @docsEditable true
-  void addStream(MediaStream stream, [Map mediaStreamHints]) {
-    if (?mediaStreamHints) {
-      var mediaStreamHints_1 = convertDartToNative_Dictionary(mediaStreamHints);
-      _addStream_1(stream, mediaStreamHints_1);
-      return;
-    }
-    _addStream_2(stream);
-    return;
-  }
-  @JSName('addStream')
-  void _addStream_1(MediaStream stream, mediaStreamHints) native;
-  @JSName('addStream')
-  void _addStream_2(MediaStream stream) native;
-
-  /// @domName PeerConnection00.close; @docsEditable true
-  void close() native;
-
-  /// @domName PeerConnection00.createAnswer; @docsEditable true
-  SessionDescription createAnswer(String offer, [Map mediaHints]) {
-    if (?mediaHints) {
-      var mediaHints_1 = convertDartToNative_Dictionary(mediaHints);
-      return _createAnswer_1(offer, mediaHints_1);
-    }
-    return _createAnswer_2(offer);
-  }
-  @JSName('createAnswer')
-  SessionDescription _createAnswer_1(offer, mediaHints) native;
-  @JSName('createAnswer')
-  SessionDescription _createAnswer_2(offer) native;
-
-  /// @domName PeerConnection00.createOffer; @docsEditable true
-  SessionDescription createOffer([Map mediaHints]) {
-    if (?mediaHints) {
-      var mediaHints_1 = convertDartToNative_Dictionary(mediaHints);
-      return _createOffer_1(mediaHints_1);
-    }
-    return _createOffer_2();
-  }
-  @JSName('createOffer')
-  SessionDescription _createOffer_1(mediaHints) native;
-  @JSName('createOffer')
-  SessionDescription _createOffer_2() native;
-
-  /// @domName PeerConnection00.dispatchEvent; @docsEditable true
-  @JSName('dispatchEvent')
-  bool $dom_dispatchEvent(Event event) native;
-
-  /// @domName PeerConnection00.processIceMessage; @docsEditable true
-  void processIceMessage(IceCandidate candidate) native;
-
-  /// @domName PeerConnection00.removeEventListener; @docsEditable true
-  @JSName('removeEventListener')
-  void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
-
-  /// @domName PeerConnection00.removeStream; @docsEditable true
-  void removeStream(MediaStream stream) native;
-
-  /// @domName PeerConnection00.setLocalDescription; @docsEditable true
-  void setLocalDescription(int action, SessionDescription desc) native;
-
-  /// @domName PeerConnection00.setRemoteDescription; @docsEditable true
-  void setRemoteDescription(int action, SessionDescription desc) native;
-
-  /// @domName PeerConnection00.startIce; @docsEditable true
-  void startIce([Map iceOptions]) {
-    if (?iceOptions) {
-      var iceOptions_1 = convertDartToNative_Dictionary(iceOptions);
-      _startIce_1(iceOptions_1);
-      return;
-    }
-    _startIce_2();
-    return;
-  }
-  @JSName('startIce')
-  void _startIce_1(iceOptions) native;
-  @JSName('startIce')
-  void _startIce_2() native;
-}
-
-/// @docsEditable true
-class PeerConnection00Events extends Events {
-  /// @docsEditable true
-  PeerConnection00Events(EventTarget _ptr) : super(_ptr);
-
-  /// @docsEditable true
-  EventListenerList get addStream => this['addstream'];
-
-  /// @docsEditable true
-  EventListenerList get connecting => this['connecting'];
-
-  /// @docsEditable true
-  EventListenerList get open => this['open'];
-
-  /// @docsEditable true
-  EventListenerList get removeStream => this['removestream'];
-
-  /// @docsEditable true
-  EventListenerList get stateChange => this['statechange'];
 }
 // 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
@@ -15487,19 +14839,19 @@
 // for 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.
 
-
-/// @domName WebKitPoint
+/// @domName WebKitPoint; @docsEditable true
 class Point native "*WebKitPoint" {
-  factory Point(num x, num y) => _PointFactoryProvider.createPoint(x, y);
+
+  ///@docsEditable true
+  factory Point(num x, num y) => Point._create(x, y);
+  static Point _create(num x, num y) => JS('Point', 'new WebKitPoint(#,#)', x, y);
 
   /// @domName WebKitPoint.x; @docsEditable true
   num x;
 
   /// @domName WebKitPoint.y; @docsEditable true
   num 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
@@ -15562,9 +14914,6 @@
   ///@docsEditable true
   factory PreElement() => document.$dom_createElement("pre");
 
-  /// @domName HTMLPreElement.width; @docsEditable true
-  int width;
-
   /// @domName HTMLPreElement.wrap; @docsEditable true
   bool wrap;
 }
@@ -15591,11 +14940,20 @@
 
 
 /// @domName HTMLProgressElement; @docsEditable true
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class ProgressElement extends Element native "*HTMLProgressElement" {
 
   ///@docsEditable true
   factory ProgressElement() => document.$dom_createElement("progress");
 
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => Element.isTagSupported('progress');
+
   /// @domName HTMLProgressElement.labels; @docsEditable true
   @Returns('NodeList') @Creates('NodeList')
   final List<Node> labels;
@@ -15947,7 +15305,8 @@
 class RtcIceCandidate native "*RTCIceCandidate" {
 
   ///@docsEditable true
-  factory RtcIceCandidate(Map dictionary) => _RtcIceCandidateFactoryProvider.createRtcIceCandidate(dictionary);
+  factory RtcIceCandidate(Map dictionary) => RtcIceCandidate._create(dictionary);
+  static RtcIceCandidate _create(Map dictionary) => JS('RtcIceCandidate', 'new RTCIceCandidate(#)', dictionary);
 
   /// @domName RTCIceCandidate.candidate; @docsEditable true
   final String candidate;
@@ -15980,15 +15339,24 @@
   ///@docsEditable true
   factory RtcPeerConnection(Map rtcIceServers, [Map mediaConstraints]) {
     if (!?mediaConstraints) {
-      return _RtcPeerConnectionFactoryProvider.createRtcPeerConnection(rtcIceServers);
+      return RtcPeerConnection._create(rtcIceServers);
     }
-    return _RtcPeerConnectionFactoryProvider.createRtcPeerConnection(rtcIceServers, mediaConstraints);
+    return RtcPeerConnection._create(rtcIceServers, mediaConstraints);
+  }
+  static RtcPeerConnection _create(Map rtcIceServers, [Map mediaConstraints]) {
+    if (!?mediaConstraints) {
+      return JS('RtcPeerConnection', 'new RTCPeerConnection(#)', rtcIceServers);
+    }
+    return JS('RtcPeerConnection', 'new RTCPeerConnection(#,#)', rtcIceServers, mediaConstraints);
   }
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   RtcPeerConnectionEvents get on =>
     new RtcPeerConnectionEvents(this);
 
+  /// @domName RTCPeerConnection.iceGatheringState; @docsEditable true
+  final String iceGatheringState;
+
   /// @domName RTCPeerConnection.iceState; @docsEditable true
   final String iceState;
 
@@ -16156,7 +15524,8 @@
 class RtcSessionDescription native "*RTCSessionDescription" {
 
   ///@docsEditable true
-  factory RtcSessionDescription(Map dictionary) => _RtcSessionDescriptionFactoryProvider.createRtcSessionDescription(dictionary);
+  factory RtcSessionDescription(Map dictionary) => RtcSessionDescription._create(dictionary);
+  static RtcSessionDescription _create(Map dictionary) => JS('RtcSessionDescription', 'new RTCSessionDescription(#)', dictionary);
 
   /// @domName RTCSessionDescription.sdp; @docsEditable true
   String sdp;
@@ -16175,6 +15544,9 @@
   /// @domName RTCStatsElement.timestamp; @docsEditable true
   final Date timestamp;
 
+  /// @domName RTCStatsElement.names; @docsEditable true
+  List<String> names() native;
+
   /// @domName RTCStatsElement.stat; @docsEditable true
   String stat(String name) native;
 }
@@ -16436,7 +15808,7 @@
   // Override default options, since IE returns SelectElement itself and it
   // does not operate as a List.
   List<OptionElement> get options {
-    return this.elements.filter((e) => e is OptionElement);
+    return this.children.filter((e) => e is OptionElement);
   }
 
   List<OptionElement> get selectedOptions {
@@ -16453,26 +15825,19 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-/// @domName SessionDescription; @docsEditable true
-class SessionDescription native "*SessionDescription" {
-
-  ///@docsEditable true
-  factory SessionDescription(String sdp) => _SessionDescriptionFactoryProvider.createSessionDescription(sdp);
-
-  /// @domName SessionDescription.addCandidate; @docsEditable true
-  void addCandidate(IceCandidate candidate) native;
-
-  /// @domName SessionDescription.toSdp; @docsEditable true
-  String toSdp() 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
-// BSD-style license that can be found in the LICENSE file.
-
-
 /// @domName HTMLShadowElement; @docsEditable true
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Experimental()
 class ShadowElement extends Element native "*HTMLShadowElement" {
 
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => Element.isTagSupported('shadow');
+
+  /// @domName HTMLShadowElement.olderShadowRoot; @docsEditable true
+  final ShadowRoot olderShadowRoot;
+
   /// @domName HTMLShadowElement.resetStyleInheritance; @docsEditable true
   bool resetStyleInheritance;
 }
@@ -16484,11 +15849,10 @@
 
 
 /// @domName ShadowRoot
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Experimental()
 class ShadowRoot extends DocumentFragment native "*ShadowRoot" {
 
-  ///@docsEditable true
-  factory ShadowRoot(Element host) => _ShadowRootFactoryProvider.createShadowRoot(host);
-
   /// @domName ShadowRoot.activeElement; @docsEditable true
   final Element activeElement;
 
@@ -16524,7 +15888,7 @@
   DomSelection getSelection() native;
 
   static bool get supported =>
-      JS('bool', '!!(window.ShadowRoot || window.WebKitShadowRoot)');
+      JS('bool', '!!(Element.prototype.webkitCreateShadowRoot)');
 }
 // 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
@@ -16537,9 +15901,15 @@
   ///@docsEditable true
   factory SharedWorker(String scriptURL, [String name]) {
     if (!?name) {
-      return _SharedWorkerFactoryProvider.createSharedWorker(scriptURL);
+      return SharedWorker._create(scriptURL);
     }
-    return _SharedWorkerFactoryProvider.createSharedWorker(scriptURL, name);
+    return SharedWorker._create(scriptURL, name);
+  }
+  static SharedWorker _create(String scriptURL, [String name]) {
+    if (!?name) {
+      return JS('SharedWorker', 'new SharedWorker(#)', scriptURL);
+    }
+    return JS('SharedWorker', 'new SharedWorker(#,#)', scriptURL, name);
   }
 
   /// @domName SharedWorker.port; @docsEditable true
@@ -16755,7 +16125,8 @@
 class SpeechGrammar native "*SpeechGrammar" {
 
   ///@docsEditable true
-  factory SpeechGrammar() => _SpeechGrammarFactoryProvider.createSpeechGrammar();
+  factory SpeechGrammar() => SpeechGrammar._create();
+  static SpeechGrammar _create() => JS('SpeechGrammar', 'new SpeechGrammar()');
 
   /// @domName SpeechGrammar.src; @docsEditable true
   String src;
@@ -16772,7 +16143,8 @@
 class SpeechGrammarList implements JavaScriptIndexingBehavior, List<SpeechGrammar> native "*SpeechGrammarList" {
 
   ///@docsEditable true
-  factory SpeechGrammarList() => _SpeechGrammarListFactoryProvider.createSpeechGrammarList();
+  factory SpeechGrammarList() => SpeechGrammarList._create();
+  static SpeechGrammarList _create() => JS('SpeechGrammarList', 'new SpeechGrammarList()');
 
   /// @domName SpeechGrammarList.length; @docsEditable true
   int get length => JS("int", "#.length", this);
@@ -16921,7 +16293,8 @@
 class SpeechRecognition extends EventTarget native "*SpeechRecognition" {
 
   ///@docsEditable true
-  factory SpeechRecognition() => _SpeechRecognitionFactoryProvider.createSpeechRecognition();
+  factory SpeechRecognition() => SpeechRecognition._create();
+  static SpeechRecognition _create() => JS('SpeechRecognition', 'new SpeechRecognition()');
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   SpeechRecognitionEvents get on =>
@@ -17024,26 +16397,8 @@
 /// @domName SpeechRecognitionError; @docsEditable true
 class SpeechRecognitionError extends Event native "*SpeechRecognitionError" {
 
-  static const int ABORTED = 2;
-
-  static const int AUDIO_CAPTURE = 3;
-
-  static const int BAD_GRAMMAR = 7;
-
-  static const int LANGUAGE_NOT_SUPPORTED = 8;
-
-  static const int NETWORK = 4;
-
-  static const int NOT_ALLOWED = 5;
-
-  static const int NO_SPEECH = 1;
-
-  static const int OTHER = 0;
-
-  static const int SERVICE_NOT_ALLOWED = 6;
-
-  /// @domName SpeechRecognitionError.code; @docsEditable true
-  final int code;
+  /// @domName SpeechRecognitionError.error; @docsEditable true
+  final String error;
 
   /// @domName SpeechRecognitionError.message; @docsEditable true
   final String message;
@@ -17065,6 +16420,10 @@
 
   /// @domName SpeechRecognitionEvent.resultIndex; @docsEditable true
   final int resultIndex;
+
+  /// @domName SpeechRecognitionEvent.results; @docsEditable true
+  @Returns('_SpeechRecognitionResultList') @Creates('_SpeechRecognitionResultList')
+  final List<SpeechRecognitionResult> results;
 }
 // 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
@@ -17074,12 +16433,8 @@
 /// @domName SpeechRecognitionResult; @docsEditable true
 class SpeechRecognitionResult native "*SpeechRecognitionResult" {
 
-  /// @domName SpeechRecognitionResult.emma; @docsEditable true
-  final Document emma;
-
-  /// @domName SpeechRecognitionResult.finalValue; @docsEditable true
-  @JSName('final')
-  final bool finalValue;
+  /// @domName SpeechRecognitionResult.isFinal; @docsEditable true
+  final bool isFinal;
 
   /// @domName SpeechRecognitionResult.length; @docsEditable true
   final int length;
@@ -17540,9 +16895,6 @@
 
   ///@docsEditable true
   factory TableCaptionElement() => document.$dom_createElement("caption");
-
-  /// @domName HTMLTableCaptionElement.align; @docsEditable true
-  String align;
 }
 // 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
@@ -17555,50 +16907,17 @@
   ///@docsEditable true
   factory TableCellElement() => document.$dom_createElement("td");
 
-  /// @domName HTMLTableCellElement.abbr; @docsEditable true
-  String abbr;
-
-  /// @domName HTMLTableCellElement.align; @docsEditable true
-  String align;
-
-  /// @domName HTMLTableCellElement.axis; @docsEditable true
-  String axis;
-
-  /// @domName HTMLTableCellElement.bgColor; @docsEditable true
-  String bgColor;
-
   /// @domName HTMLTableCellElement.cellIndex; @docsEditable true
   final int cellIndex;
 
-  /// @domName HTMLTableCellElement.ch; @docsEditable true
-  String ch;
-
-  /// @domName HTMLTableCellElement.chOff; @docsEditable true
-  String chOff;
-
   /// @domName HTMLTableCellElement.colSpan; @docsEditable true
   int colSpan;
 
   /// @domName HTMLTableCellElement.headers; @docsEditable true
   String headers;
 
-  /// @domName HTMLTableCellElement.height; @docsEditable true
-  String height;
-
-  /// @domName HTMLTableCellElement.noWrap; @docsEditable true
-  bool noWrap;
-
   /// @domName HTMLTableCellElement.rowSpan; @docsEditable true
   int rowSpan;
-
-  /// @domName HTMLTableCellElement.scope; @docsEditable true
-  String scope;
-
-  /// @domName HTMLTableCellElement.vAlign; @docsEditable true
-  String vAlign;
-
-  /// @domName HTMLTableCellElement.width; @docsEditable true
-  String 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
@@ -17611,23 +16930,8 @@
   ///@docsEditable true
   factory TableColElement() => document.$dom_createElement("col");
 
-  /// @domName HTMLTableColElement.align; @docsEditable true
-  String align;
-
-  /// @domName HTMLTableColElement.ch; @docsEditable true
-  String ch;
-
-  /// @domName HTMLTableColElement.chOff; @docsEditable true
-  String chOff;
-
   /// @domName HTMLTableColElement.span; @docsEditable true
   int span;
-
-  /// @domName HTMLTableColElement.vAlign; @docsEditable true
-  String vAlign;
-
-  /// @domName HTMLTableColElement.width; @docsEditable true
-  String 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
@@ -17640,36 +16944,15 @@
   ///@docsEditable true
   factory TableElement() => document.$dom_createElement("table");
 
-  /// @domName HTMLTableElement.align; @docsEditable true
-  String align;
-
-  /// @domName HTMLTableElement.bgColor; @docsEditable true
-  String bgColor;
-
   /// @domName HTMLTableElement.border; @docsEditable true
   String border;
 
   /// @domName HTMLTableElement.caption; @docsEditable true
   TableCaptionElement caption;
 
-  /// @domName HTMLTableElement.cellPadding; @docsEditable true
-  String cellPadding;
-
-  /// @domName HTMLTableElement.cellSpacing; @docsEditable true
-  String cellSpacing;
-
-  /// @domName HTMLTableElement.frame; @docsEditable true
-  String frame;
-
   /// @domName HTMLTableElement.rows; @docsEditable true
   final HtmlCollection rows;
 
-  /// @domName HTMLTableElement.rules; @docsEditable true
-  String rules;
-
-  /// @domName HTMLTableElement.summary; @docsEditable true
-  String summary;
-
   /// @domName HTMLTableElement.tBodies; @docsEditable true
   final HtmlCollection tBodies;
 
@@ -17679,9 +16962,6 @@
   /// @domName HTMLTableElement.tHead; @docsEditable true
   TableSectionElement tHead;
 
-  /// @domName HTMLTableElement.width; @docsEditable true
-  String width;
-
   /// @domName HTMLTableElement.createCaption; @docsEditable true
   Element createCaption() native;
 
@@ -17730,30 +17010,15 @@
   ///@docsEditable true
   factory TableRowElement() => document.$dom_createElement("tr");
 
-  /// @domName HTMLTableRowElement.align; @docsEditable true
-  String align;
-
-  /// @domName HTMLTableRowElement.bgColor; @docsEditable true
-  String bgColor;
-
   /// @domName HTMLTableRowElement.cells; @docsEditable true
   final HtmlCollection cells;
 
-  /// @domName HTMLTableRowElement.ch; @docsEditable true
-  String ch;
-
-  /// @domName HTMLTableRowElement.chOff; @docsEditable true
-  String chOff;
-
   /// @domName HTMLTableRowElement.rowIndex; @docsEditable true
   final int rowIndex;
 
   /// @domName HTMLTableRowElement.sectionRowIndex; @docsEditable true
   final int sectionRowIndex;
 
-  /// @domName HTMLTableRowElement.vAlign; @docsEditable true
-  String vAlign;
-
   /// @domName HTMLTableRowElement.deleteCell; @docsEditable true
   void deleteCell(int index) native;
 
@@ -17768,21 +17033,12 @@
 /// @domName HTMLTableSectionElement; @docsEditable true
 class TableSectionElement extends Element native "*HTMLTableSectionElement" {
 
-  /// @domName HTMLTableSectionElement.align; @docsEditable true
-  String align;
-
-  /// @domName HTMLTableSectionElement.ch; @docsEditable true
-  String ch;
-
   /// @domName HTMLTableSectionElement.chOff; @docsEditable true
   String chOff;
 
   /// @domName HTMLTableSectionElement.rows; @docsEditable true
   final HtmlCollection rows;
 
-  /// @domName HTMLTableSectionElement.vAlign; @docsEditable true
-  String vAlign;
-
   /// @domName HTMLTableSectionElement.deleteRow; @docsEditable true
   void deleteRow(int index) native;
 
@@ -17918,7 +17174,7 @@
   final String data;
 
   /// @domName TextEvent.initTextEvent; @docsEditable true
-  void initTextEvent(String typeArg, bool canBubbleArg, bool cancelableArg, LocalWindow viewArg, String dataArg) native;
+  void initTextEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Window viewArg, String dataArg) 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
@@ -17997,7 +17253,8 @@
 class TextTrackCue extends EventTarget native "*TextTrackCue" {
 
   ///@docsEditable true
-  factory TextTrackCue(num startTime, num endTime, String text) => _TextTrackCueFactoryProvider.createTextTrackCue(startTime, endTime, text);
+  factory TextTrackCue(num startTime, num endTime, String text) => TextTrackCue._create(startTime, endTime, text);
+  static TextTrackCue _create(num startTime, num endTime, String text) => JS('TextTrackCue', 'new TextTrackCue(#,#,#)', startTime, endTime, text);
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   TextTrackCueEvents get on =>
@@ -18436,7 +17693,7 @@
   final TouchList touches;
 
   /// @domName TouchEvent.initTouchEvent; @docsEditable true
-  void initTouchEvent(TouchList touches, TouchList targetTouches, TouchList changedTouches, String type, LocalWindow view, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) native;
+  void initTouchEvent(TouchList touches, TouchList targetTouches, TouchList changedTouches, String type, Window view, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) 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
@@ -18558,11 +17815,19 @@
 
 
 /// @domName HTMLTrackElement; @docsEditable true
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class TrackElement extends Element native "*HTMLTrackElement" {
 
   ///@docsEditable true
   factory TrackElement() => document.$dom_createElement("track");
 
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => Element.isTagSupported('track');
+
   static const int ERROR = 3;
 
   static const int LOADED = 2;
@@ -18708,9 +17973,9 @@
   final int pageY;
 
   /// @domName UIEvent.view; @docsEditable true
-  Window get view => _convertNativeToDart_Window(this._view);
+  WindowBase get view => _convertNativeToDart_Window(this._view);
   @JSName('view')
-  @Creates('LocalWindow|=Object') @Returns('LocalWindow|=Object')
+  @Creates('Window|=Object') @Returns('Window|=Object')
   final dynamic _view;
 
   /// @domName UIEvent.which; @docsEditable true
@@ -18718,7 +17983,7 @@
 
   /// @domName UIEvent.initUIEvent; @docsEditable true
   @JSName('initUIEvent')
-  void $dom_initUIEvent(String type, bool canBubble, bool cancelable, LocalWindow view, int detail) native;
+  void $dom_initUIEvent(String type, bool canBubble, bool cancelable, Window view, int detail) native;
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -18731,12 +17996,6 @@
 
   ///@docsEditable true
   factory UListElement() => document.$dom_createElement("ul");
-
-  /// @domName HTMLUListElement.compact; @docsEditable true
-  bool compact;
-
-  /// @domName HTMLUListElement.type; @docsEditable true
-  String type;
 }
 // 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
@@ -19177,6 +18436,9 @@
 /// @domName ValidityState; @docsEditable true
 class ValidityState native "*ValidityState" {
 
+  /// @domName ValidityState.badInput; @docsEditable true
+  final bool badInput;
+
   /// @domName ValidityState.customError; @docsEditable true
   final bool customError;
 
@@ -20323,11 +19585,11 @@
 
   /// @domName WebGLRenderingContext.texImage2D; @docsEditable true
   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 && (border_OR_canvas_OR_image_OR_pixels_OR_video is int || border_OR_canvas_OR_image_OR_pixels_OR_video == null))) {
+    if ((border_OR_canvas_OR_image_OR_pixels_OR_video is int || border_OR_canvas_OR_image_OR_pixels_OR_video == 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;
     }
-    if ((?border_OR_canvas_OR_image_OR_pixels_OR_video && (border_OR_canvas_OR_image_OR_pixels_OR_video is ImageData || border_OR_canvas_OR_image_OR_pixels_OR_video == null)) &&
+    if ((border_OR_canvas_OR_image_OR_pixels_OR_video is ImageData || border_OR_canvas_OR_image_OR_pixels_OR_video == null) &&
         !?format &&
         !?type &&
         !?pixels) {
@@ -20335,21 +19597,21 @@
       _texImage2D_2(target, level, internalformat, format_OR_width, height_OR_type, pixels_1);
       return;
     }
-    if ((?border_OR_canvas_OR_image_OR_pixels_OR_video && (border_OR_canvas_OR_image_OR_pixels_OR_video is ImageElement || border_OR_canvas_OR_image_OR_pixels_OR_video == null)) &&
+    if ((border_OR_canvas_OR_image_OR_pixels_OR_video is ImageElement || border_OR_canvas_OR_image_OR_pixels_OR_video == null) &&
         !?format &&
         !?type &&
         !?pixels) {
       _texImage2D_3(target, level, internalformat, format_OR_width, height_OR_type, border_OR_canvas_OR_image_OR_pixels_OR_video);
       return;
     }
-    if ((?border_OR_canvas_OR_image_OR_pixels_OR_video && (border_OR_canvas_OR_image_OR_pixels_OR_video is CanvasElement || border_OR_canvas_OR_image_OR_pixels_OR_video == null)) &&
+    if ((border_OR_canvas_OR_image_OR_pixels_OR_video is CanvasElement || border_OR_canvas_OR_image_OR_pixels_OR_video == null) &&
         !?format &&
         !?type &&
         !?pixels) {
       _texImage2D_4(target, level, internalformat, format_OR_width, height_OR_type, border_OR_canvas_OR_image_OR_pixels_OR_video);
       return;
     }
-    if ((?border_OR_canvas_OR_image_OR_pixels_OR_video && (border_OR_canvas_OR_image_OR_pixels_OR_video is VideoElement || border_OR_canvas_OR_image_OR_pixels_OR_video == null)) &&
+    if ((border_OR_canvas_OR_image_OR_pixels_OR_video is VideoElement || border_OR_canvas_OR_image_OR_pixels_OR_video == null) &&
         !?format &&
         !?type &&
         !?pixels) {
@@ -20377,30 +19639,30 @@
 
   /// @domName WebGLRenderingContext.texSubImage2D; @docsEditable true
   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 && (canvas_OR_format_OR_image_OR_pixels_OR_video is int || canvas_OR_format_OR_image_OR_pixels_OR_video == null))) {
+    if ((canvas_OR_format_OR_image_OR_pixels_OR_video is int || canvas_OR_format_OR_image_OR_pixels_OR_video == 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;
     }
-    if ((?canvas_OR_format_OR_image_OR_pixels_OR_video && (canvas_OR_format_OR_image_OR_pixels_OR_video is ImageData || canvas_OR_format_OR_image_OR_pixels_OR_video == null)) &&
+    if ((canvas_OR_format_OR_image_OR_pixels_OR_video is ImageData || canvas_OR_format_OR_image_OR_pixels_OR_video == null) &&
         !?type &&
         !?pixels) {
       var pixels_1 = _convertDartToNative_ImageData(canvas_OR_format_OR_image_OR_pixels_OR_video);
       _texSubImage2D_2(target, level, xoffset, yoffset, format_OR_width, height_OR_type, pixels_1);
       return;
     }
-    if ((?canvas_OR_format_OR_image_OR_pixels_OR_video && (canvas_OR_format_OR_image_OR_pixels_OR_video is ImageElement || canvas_OR_format_OR_image_OR_pixels_OR_video == null)) &&
+    if ((canvas_OR_format_OR_image_OR_pixels_OR_video is ImageElement || canvas_OR_format_OR_image_OR_pixels_OR_video == null) &&
         !?type &&
         !?pixels) {
       _texSubImage2D_3(target, level, xoffset, yoffset, format_OR_width, height_OR_type, canvas_OR_format_OR_image_OR_pixels_OR_video);
       return;
     }
-    if ((?canvas_OR_format_OR_image_OR_pixels_OR_video && (canvas_OR_format_OR_image_OR_pixels_OR_video is CanvasElement || canvas_OR_format_OR_image_OR_pixels_OR_video == null)) &&
+    if ((canvas_OR_format_OR_image_OR_pixels_OR_video is CanvasElement || canvas_OR_format_OR_image_OR_pixels_OR_video == null) &&
         !?type &&
         !?pixels) {
       _texSubImage2D_4(target, level, xoffset, yoffset, format_OR_width, height_OR_type, canvas_OR_format_OR_image_OR_pixels_OR_video);
       return;
     }
-    if ((?canvas_OR_format_OR_image_OR_pixels_OR_video && (canvas_OR_format_OR_image_OR_pixels_OR_video is VideoElement || canvas_OR_format_OR_image_OR_pixels_OR_video == null)) &&
+    if ((canvas_OR_format_OR_image_OR_pixels_OR_video is VideoElement || canvas_OR_format_OR_image_OR_pixels_OR_video == null) &&
         !?type &&
         !?pixels) {
       _texSubImage2D_5(target, level, xoffset, yoffset, format_OR_width, height_OR_type, canvas_OR_format_OR_image_OR_pixels_OR_video);
@@ -20601,6 +19863,14 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
+/// @domName WebKitCSSMixFunctionValue; @docsEditable true
+class WebKitCssMixFunctionValue extends _CssValueList native "*WebKitCSSMixFunctionValue" {
+}
+// 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.
+
+
 /// @domName WebKitNamedFlow; @docsEditable true
 class WebKitNamedFlow extends EventTarget native "*WebKitNamedFlow" {
 
@@ -20641,12 +19911,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// WARNING: Do not edit - generated code.
 
-
-/// @domName WebSocket
+/// @domName WebSocket; @docsEditable true
 class WebSocket extends EventTarget native "*WebSocket" {
-  factory WebSocket(String url) => _WebSocketFactoryProvider.createWebSocket(url);
+
+  ///@docsEditable true
+  factory WebSocket(String url) => WebSocket._create(url);
+  static WebSocket _create(String url) => JS('WebSocket', 'new WebSocket(#)', url);
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   WebSocketEvents get on =>
@@ -20698,8 +19969,7 @@
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
 
   /// @domName WebSocket.send; @docsEditable true
-  void send(data) native;
-
+  bool send(data) native;
 }
 
 /// @docsEditable true
@@ -20731,7 +20001,7 @@
   final bool webkitDirectionInvertedFromDevice;
 
   /// @domName WheelEvent.initWebKitWheelEvent; @docsEditable true
-  void initWebKitWheelEvent(int wheelDeltaX, int wheelDeltaY, LocalWindow view, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) native;
+  void initWebKitWheelEvent(int wheelDeltaX, int wheelDeltaY, Window view, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) native;
 
 
   /** @domName WheelEvent.deltaY */
@@ -20812,11 +20082,685 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
+/// @domName Window
+class Window extends EventTarget implements WindowBase native "@*DOMWindow" {
+
+  Document get document => JS('Document', '#.document', this);
+
+  WindowBase _open2(url, name) => JS('Window', '#.open(#,#)', this, url, name);
+
+  WindowBase _open3(url, name, options) =>
+      JS('Window', '#.open(#,#,#)', this, url, name, options);
+
+  WindowBase open(String url, String name, [String options]) {
+    if (options == null) {
+      return _DOMWindowCrossFrame._createSafe(_open2(url, name));
+    } else {
+      return _DOMWindowCrossFrame._createSafe(_open3(url, name, options));
+    }
+  }
+
+  // API level getter and setter for Location.
+  // TODO: The cross domain safe wrapper can be inserted here or folded into
+  // _LocationWrapper.
+  Location get location {
+    // Firefox work-around for Location.  The Firefox location object cannot be
+    // made to behave like a Dart object so must be wrapped.
+    var result = _location;
+    if (_isDartLocation(result)) return result;  // e.g. on Chrome.
+    if (null == _location_wrapper) {
+      _location_wrapper = new _LocationWrapper(result);
+    }
+    return _location_wrapper;
+  }
+
+  // TODO: consider forcing users to do: window.location.assign('string').
+  /**
+   * Sets the window's location, which causes the browser to navigate to the new
+   * location. [value] may be a Location object or a string.
+   */
+  void set location(value) {
+    if (value is _LocationWrapper) {
+      _location = value._ptr;
+    } else {
+      _location = value;
+    }
+  }
+
+  _LocationWrapper _location_wrapper;  // Cached wrapped Location object.
+
+  // Native getter and setter to access raw Location object.
+  dynamic get _location => JS('Location|=Object', '#.location', this);
+  void set _location(value) {
+    JS('void', '#.location = #', this, value);
+  }
+  // Prevent compiled from thinking 'location' property is available for a Dart
+  // member.
+  @JSName('location')
+  _protect_location() native;
+
+  static _isDartLocation(thing) {
+    // On Firefox the code that implements 'is Location' fails to find the patch
+    // stub on Object.prototype and throws an exception.
+    try {
+      return thing is Location;
+    } catch (e) {
+      return false;
+    }
+  }
+
+  /**
+   * Executes a [callback] after the next batch of browser layout measurements
+   * has completed or would have completed if any browser layout measurements
+   * had been scheduled.
+   */
+  void requestLayoutFrame(TimeoutHandler callback) {
+    _addMeasurementFrameCallback(callback);
+  }
+
+  /** @domName DOMWindow.requestAnimationFrame */
+  int requestAnimationFrame(RequestAnimationFrameCallback callback) {
+    _ensureRequestAnimationFrame();
+    return _requestAnimationFrame(callback);
+  }
+
+  void cancelAnimationFrame(id) {
+    _ensureRequestAnimationFrame();
+    _cancelAnimationFrame(id);
+  }
+
+  @JSName('requestAnimationFrame')
+  int _requestAnimationFrame(RequestAnimationFrameCallback callback) native;
+
+  @JSName('cancelAnimationFrame')
+  void _cancelAnimationFrame(int id) native;
+
+  _ensureRequestAnimationFrame() {
+    if (JS('bool',
+           '!!(#.requestAnimationFrame && #.cancelAnimationFrame)', this, this))
+      return;
+
+    JS('void',
+       r"""
+  (function($this) {
+   var vendors = ['ms', 'moz', 'webkit', 'o'];
+   for (var i = 0; i < vendors.length && !$this.requestAnimationFrame; ++i) {
+     $this.requestAnimationFrame = $this[vendors[i] + 'RequestAnimationFrame'];
+     $this.cancelAnimationFrame =
+         $this[vendors[i]+'CancelAnimationFrame'] ||
+         $this[vendors[i]+'CancelRequestAnimationFrame'];
+   }
+   if ($this.requestAnimationFrame && $this.cancelAnimationFrame) return;
+   $this.requestAnimationFrame = function(callback) {
+      return window.setTimeout(function() {
+        callback(Date.now());
+      }, 16 /* 16ms ~= 60fps */);
+   };
+   $this.cancelAnimationFrame = function(id) { clearTimeout(id); }
+  })(#)""",
+       this);
+  }
+
+  /**
+   * Gets an instance of the Indexed DB factory to being using Indexed DB.
+   *
+   * Use [IdbFactory.supported] to check if Indexed DB is supported on the
+   * current platform.
+   */
+  @SupportedBrowser(SupportedBrowser.CHROME, '23.0')
+  @SupportedBrowser(SupportedBrowser.FIREFOX, '15.0')
+  @SupportedBrowser(SupportedBrowser.IE, '10.0')
+  @Experimental()
+  IdbFactory get indexedDB =>
+      JS('IdbFactory',
+         '#.indexedDB || #.webkitIndexedDB || #.mozIndexedDB',
+         this, this, this);
+
+  /**
+   * Lookup a port by its [name].  Return null if no port is
+   * registered under [name].
+   */
+  SendPortSync lookupPort(String name) {
+    var port = JSON.parse(document.documentElement.attributes['dart-port:$name']);
+    return _deserialize(port);
+  }
+
+  /**
+   * Register a [port] on this window under the given [name].  This
+   * port may be retrieved by any isolate (or JavaScript script)
+   * running in this window.
+   */
+  void registerPort(String name, var port) {
+    var serialized = _serialize(port);
+    document.documentElement.attributes['dart-port:$name'] = JSON.stringify(serialized);
+  }
+
+  /// @domName Window.console; @docsEditable true
+  Console get console => Console.safeConsole;
+
+
+  /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
+  WindowEvents get on =>
+    new WindowEvents(this);
+
+  static const int PERSISTENT = 1;
+
+  static const int TEMPORARY = 0;
+
+  /// @domName Window.applicationCache; @docsEditable true
+  final ApplicationCache applicationCache;
+
+  /// @domName Window.closed; @docsEditable true
+  final bool closed;
+
+  /// @domName Window.crypto; @docsEditable true
+  final Crypto crypto;
+
+  /// @domName Window.defaultStatus; @docsEditable true
+  String defaultStatus;
+
+  /// @domName Window.defaultstatus; @docsEditable true
+  String defaultstatus;
+
+  /// @domName Window.devicePixelRatio; @docsEditable true
+  final num devicePixelRatio;
+
+  /// @domName Window.event; @docsEditable true
+  final Event event;
+
+  /// @domName Window.history; @docsEditable true
+  final History history;
+
+  /// @domName Window.innerHeight; @docsEditable true
+  final int innerHeight;
+
+  /// @domName Window.innerWidth; @docsEditable true
+  final int innerWidth;
+
+  /// @domName Window.localStorage; @docsEditable true
+  final Storage localStorage;
+
+  /// @domName Window.locationbar; @docsEditable true
+  final BarInfo locationbar;
+
+  /// @domName Window.menubar; @docsEditable true
+  final BarInfo menubar;
+
+  /// @domName Window.name; @docsEditable true
+  String name;
+
+  /// @domName Window.navigator; @docsEditable true
+  final Navigator navigator;
+
+  /// @domName Window.offscreenBuffering; @docsEditable true
+  final bool offscreenBuffering;
+
+  /// @domName Window.opener; @docsEditable true
+  WindowBase get opener => _convertNativeToDart_Window(this._opener);
+  @JSName('opener')
+  @Creates('Window|=Object') @Returns('Window|=Object')
+  final dynamic _opener;
+
+  /// @domName Window.outerHeight; @docsEditable true
+  final int outerHeight;
+
+  /// @domName Window.outerWidth; @docsEditable true
+  final int outerWidth;
+
+  /// @domName DOMWindow.pagePopupController; @docsEditable true
+  final PagePopupController pagePopupController;
+
+  /// @domName Window.pageXOffset; @docsEditable true
+  final int pageXOffset;
+
+  /// @domName Window.pageYOffset; @docsEditable true
+  final int pageYOffset;
+
+  /// @domName Window.parent; @docsEditable true
+  WindowBase get parent => _convertNativeToDart_Window(this._parent);
+  @JSName('parent')
+  @Creates('Window|=Object') @Returns('Window|=Object')
+  final dynamic _parent;
+
+  /// @domName Window.performance; @docsEditable true
+  final Performance performance;
+
+  /// @domName Window.personalbar; @docsEditable true
+  final BarInfo personalbar;
+
+  /// @domName Window.screen; @docsEditable true
+  final Screen screen;
+
+  /// @domName Window.screenLeft; @docsEditable true
+  final int screenLeft;
+
+  /// @domName Window.screenTop; @docsEditable true
+  final int screenTop;
+
+  /// @domName Window.screenX; @docsEditable true
+  final int screenX;
+
+  /// @domName Window.screenY; @docsEditable true
+  final int screenY;
+
+  /// @domName Window.scrollX; @docsEditable true
+  final int scrollX;
+
+  /// @domName Window.scrollY; @docsEditable true
+  final int scrollY;
+
+  /// @domName Window.scrollbars; @docsEditable true
+  final BarInfo scrollbars;
+
+  /// @domName Window.self; @docsEditable true
+  WindowBase get self => _convertNativeToDart_Window(this._self);
+  @JSName('self')
+  @Creates('Window|=Object') @Returns('Window|=Object')
+  final dynamic _self;
+
+  /// @domName Window.sessionStorage; @docsEditable true
+  final Storage sessionStorage;
+
+  /// @domName Window.status; @docsEditable true
+  String status;
+
+  /// @domName Window.statusbar; @docsEditable true
+  final BarInfo statusbar;
+
+  /// @domName Window.styleMedia; @docsEditable true
+  final StyleMedia styleMedia;
+
+  /// @domName Window.toolbar; @docsEditable true
+  final BarInfo toolbar;
+
+  /// @domName Window.top; @docsEditable true
+  WindowBase get top => _convertNativeToDart_Window(this._top);
+  @JSName('top')
+  @Creates('Window|=Object') @Returns('Window|=Object')
+  final dynamic _top;
+
+  /// @domName DOMWindow.webkitNotifications; @docsEditable true
+  final NotificationCenter webkitNotifications;
+
+  /// @domName DOMWindow.webkitStorageInfo; @docsEditable true
+  final StorageInfo webkitStorageInfo;
+
+  /// @domName Window.window; @docsEditable true
+  WindowBase get window => _convertNativeToDart_Window(this._window);
+  @JSName('window')
+  @Creates('Window|=Object') @Returns('Window|=Object')
+  final dynamic _window;
+
+  /// @domName Window.addEventListener; @docsEditable true
+  @JSName('addEventListener')
+  void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
+
+  /// @domName Window.alert; @docsEditable true
+  void alert(String message) native;
+
+  /// @domName Window.atob; @docsEditable true
+  String atob(String string) native;
+
+  /// @domName Window.btoa; @docsEditable true
+  String btoa(String string) native;
+
+  /// @domName Window.captureEvents; @docsEditable true
+  void captureEvents() native;
+
+  /// @domName Window.clearInterval; @docsEditable true
+  void clearInterval(int handle) native;
+
+  /// @domName Window.clearTimeout; @docsEditable true
+  void clearTimeout(int handle) native;
+
+  /// @domName Window.close; @docsEditable true
+  void close() native;
+
+  /// @domName Window.confirm; @docsEditable true
+  bool confirm(String message) native;
+
+  /// @domName Window.dispatchEvent; @docsEditable true
+  @JSName('dispatchEvent')
+  bool $dom_dispatchEvent(Event evt) native;
+
+  /// @domName Window.find; @docsEditable true
+  bool find(String string, bool caseSensitive, bool backwards, bool wrap, bool wholeWord, bool searchInFrames, bool showDialog) native;
+
+  /// @domName Window.getComputedStyle; @docsEditable true
+  @JSName('getComputedStyle')
+  CssStyleDeclaration $dom_getComputedStyle(Element element, String pseudoElement) native;
+
+  /// @domName Window.getMatchedCSSRules; @docsEditable true
+  @JSName('getMatchedCSSRules')
+  @Returns('_CssRuleList') @Creates('_CssRuleList')
+  List<CssRule> getMatchedCssRules(Element element, String pseudoElement) native;
+
+  /// @domName Window.getSelection; @docsEditable true
+  DomSelection getSelection() native;
+
+  /// @domName Window.matchMedia; @docsEditable true
+  MediaQueryList matchMedia(String query) native;
+
+  /// @domName Window.moveBy; @docsEditable true
+  void moveBy(num x, num y) native;
+
+  /// @domName Window.moveTo; @docsEditable true
+  void moveTo(num x, num y) native;
+
+  /// @domName DOMWindow.openDatabase; @docsEditable true
+  @Creates('Database') @Creates('DatabaseSync')
+  Database openDatabase(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) native;
+
+  /// @domName Window.postMessage; @docsEditable true
+  void postMessage(/*SerializedScriptValue*/ message, String targetOrigin, [List messagePorts]) {
+    if (?message &&
+        !?messagePorts) {
+      var message_1 = convertDartToNative_SerializedScriptValue(message);
+      _postMessage_1(message_1, targetOrigin);
+      return;
+    }
+    if (?message) {
+      var message_2 = convertDartToNative_SerializedScriptValue(message);
+      _postMessage_2(message_2, targetOrigin, messagePorts);
+      return;
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+  @JSName('postMessage')
+  void _postMessage_1(message, targetOrigin) native;
+  @JSName('postMessage')
+  void _postMessage_2(message, targetOrigin, List messagePorts) native;
+
+  /// @domName Window.print; @docsEditable true
+  void print() native;
+
+  /// @domName Window.releaseEvents; @docsEditable true
+  void releaseEvents() native;
+
+  /// @domName Window.removeEventListener; @docsEditable true
+  @JSName('removeEventListener')
+  void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
+
+  /// @domName Window.resizeBy; @docsEditable true
+  void resizeBy(num x, num y) native;
+
+  /// @domName Window.resizeTo; @docsEditable true
+  void resizeTo(num width, num height) native;
+
+  /// @domName Window.scroll; @docsEditable true
+  void scroll(int x, int y) native;
+
+  /// @domName Window.scrollBy; @docsEditable true
+  void scrollBy(int x, int y) native;
+
+  /// @domName Window.scrollTo; @docsEditable true
+  void scrollTo(int x, int y) native;
+
+  /// @domName Window.setInterval; @docsEditable true
+  int setInterval(TimeoutHandler handler, int timeout) native;
+
+  /// @domName Window.setTimeout; @docsEditable true
+  int setTimeout(TimeoutHandler handler, int timeout) native;
+
+  /// @domName Window.showModalDialog; @docsEditable true
+  Object showModalDialog(String url, [Object dialogArgs, String featureArgs]) native;
+
+  /// @domName Window.stop; @docsEditable true
+  void stop() native;
+
+  /// @domName Window.webkitConvertPointFromNodeToPage; @docsEditable true
+  Point webkitConvertPointFromNodeToPage(Node node, Point p) native;
+
+  /// @domName Window.webkitConvertPointFromPageToNode; @docsEditable true
+  Point webkitConvertPointFromPageToNode(Node node, Point p) native;
+
+  /// @domName DOMWindow.webkitRequestFileSystem; @docsEditable true
+  void webkitRequestFileSystem(int type, int size, FileSystemCallback successCallback, [ErrorCallback errorCallback]) native;
+
+  /// @domName DOMWindow.webkitResolveLocalFileSystemURL; @docsEditable true
+  @JSName('webkitResolveLocalFileSystemURL')
+  void webkitResolveLocalFileSystemUrl(String url, EntryCallback successCallback, [ErrorCallback errorCallback]) native;
+
+}
+
+/// @docsEditable true
+class WindowEvents extends Events {
+  /// @docsEditable true
+  WindowEvents(EventTarget _ptr) : super(_ptr);
+
+  /// @docsEditable true
+  EventListenerList get contentLoaded => this['DOMContentLoaded'];
+
+  /// @docsEditable true
+  EventListenerList get abort => this['abort'];
+
+  /// @docsEditable true
+  EventListenerList get beforeUnload => this['beforeunload'];
+
+  /// @docsEditable true
+  EventListenerList get blur => this['blur'];
+
+  /// @docsEditable true
+  EventListenerList get canPlay => this['canplay'];
+
+  /// @docsEditable true
+  EventListenerList get canPlayThrough => this['canplaythrough'];
+
+  /// @docsEditable true
+  EventListenerList get change => this['change'];
+
+  /// @docsEditable true
+  EventListenerList get click => this['click'];
+
+  /// @docsEditable true
+  EventListenerList get contextMenu => this['contextmenu'];
+
+  /// @docsEditable true
+  EventListenerList get doubleClick => this['dblclick'];
+
+  /// @docsEditable true
+  EventListenerList get deviceMotion => this['devicemotion'];
+
+  /// @docsEditable true
+  EventListenerList get deviceOrientation => this['deviceorientation'];
+
+  /// @docsEditable true
+  EventListenerList get drag => this['drag'];
+
+  /// @docsEditable true
+  EventListenerList get dragEnd => this['dragend'];
+
+  /// @docsEditable true
+  EventListenerList get dragEnter => this['dragenter'];
+
+  /// @docsEditable true
+  EventListenerList get dragLeave => this['dragleave'];
+
+  /// @docsEditable true
+  EventListenerList get dragOver => this['dragover'];
+
+  /// @docsEditable true
+  EventListenerList get dragStart => this['dragstart'];
+
+  /// @docsEditable true
+  EventListenerList get drop => this['drop'];
+
+  /// @docsEditable true
+  EventListenerList get durationChange => this['durationchange'];
+
+  /// @docsEditable true
+  EventListenerList get emptied => this['emptied'];
+
+  /// @docsEditable true
+  EventListenerList get ended => this['ended'];
+
+  /// @docsEditable true
+  EventListenerList get error => this['error'];
+
+  /// @docsEditable true
+  EventListenerList get focus => this['focus'];
+
+  /// @docsEditable true
+  EventListenerList get hashChange => this['hashchange'];
+
+  /// @docsEditable true
+  EventListenerList get input => this['input'];
+
+  /// @docsEditable true
+  EventListenerList get invalid => this['invalid'];
+
+  /// @docsEditable true
+  EventListenerList get keyDown => this['keydown'];
+
+  /// @docsEditable true
+  EventListenerList get keyPress => this['keypress'];
+
+  /// @docsEditable true
+  EventListenerList get keyUp => this['keyup'];
+
+  /// @docsEditable true
+  EventListenerList get load => this['load'];
+
+  /// @docsEditable true
+  EventListenerList get loadedData => this['loadeddata'];
+
+  /// @docsEditable true
+  EventListenerList get loadedMetadata => this['loadedmetadata'];
+
+  /// @docsEditable true
+  EventListenerList get loadStart => this['loadstart'];
+
+  /// @docsEditable true
+  EventListenerList get message => this['message'];
+
+  /// @docsEditable true
+  EventListenerList get mouseDown => this['mousedown'];
+
+  /// @docsEditable true
+  EventListenerList get mouseMove => this['mousemove'];
+
+  /// @docsEditable true
+  EventListenerList get mouseOut => this['mouseout'];
+
+  /// @docsEditable true
+  EventListenerList get mouseOver => this['mouseover'];
+
+  /// @docsEditable true
+  EventListenerList get mouseUp => this['mouseup'];
+
+  /// @docsEditable true
+  EventListenerList get mouseWheel => this['mousewheel'];
+
+  /// @docsEditable true
+  EventListenerList get offline => this['offline'];
+
+  /// @docsEditable true
+  EventListenerList get online => this['online'];
+
+  /// @docsEditable true
+  EventListenerList get pageHide => this['pagehide'];
+
+  /// @docsEditable true
+  EventListenerList get pageShow => this['pageshow'];
+
+  /// @docsEditable true
+  EventListenerList get pause => this['pause'];
+
+  /// @docsEditable true
+  EventListenerList get play => this['play'];
+
+  /// @docsEditable true
+  EventListenerList get playing => this['playing'];
+
+  /// @docsEditable true
+  EventListenerList get popState => this['popstate'];
+
+  /// @docsEditable true
+  EventListenerList get progress => this['progress'];
+
+  /// @docsEditable true
+  EventListenerList get rateChange => this['ratechange'];
+
+  /// @docsEditable true
+  EventListenerList get reset => this['reset'];
+
+  /// @docsEditable true
+  EventListenerList get resize => this['resize'];
+
+  /// @docsEditable true
+  EventListenerList get scroll => this['scroll'];
+
+  /// @docsEditable true
+  EventListenerList get search => this['search'];
+
+  /// @docsEditable true
+  EventListenerList get seeked => this['seeked'];
+
+  /// @docsEditable true
+  EventListenerList get seeking => this['seeking'];
+
+  /// @docsEditable true
+  EventListenerList get select => this['select'];
+
+  /// @docsEditable true
+  EventListenerList get stalled => this['stalled'];
+
+  /// @docsEditable true
+  EventListenerList get storage => this['storage'];
+
+  /// @docsEditable true
+  EventListenerList get submit => this['submit'];
+
+  /// @docsEditable true
+  EventListenerList get suspend => this['suspend'];
+
+  /// @docsEditable true
+  EventListenerList get timeUpdate => this['timeupdate'];
+
+  /// @docsEditable true
+  EventListenerList get touchCancel => this['touchcancel'];
+
+  /// @docsEditable true
+  EventListenerList get touchEnd => this['touchend'];
+
+  /// @docsEditable true
+  EventListenerList get touchMove => this['touchmove'];
+
+  /// @docsEditable true
+  EventListenerList get touchStart => this['touchstart'];
+
+  /// @docsEditable true
+  EventListenerList get unload => this['unload'];
+
+  /// @docsEditable true
+  EventListenerList get volumeChange => this['volumechange'];
+
+  /// @docsEditable true
+  EventListenerList get waiting => this['waiting'];
+
+  /// @docsEditable true
+  EventListenerList get animationEnd => this['webkitAnimationEnd'];
+
+  /// @docsEditable true
+  EventListenerList get animationIteration => this['webkitAnimationIteration'];
+
+  /// @docsEditable true
+  EventListenerList get animationStart => this['webkitAnimationStart'];
+
+  /// @docsEditable true
+  EventListenerList get transitionEnd => this['webkitTransitionEnd'];
+}
+// 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.
+
+
 /// @domName Worker; @docsEditable true
 class Worker extends AbstractWorker native "*Worker" {
 
   ///@docsEditable true
-  factory Worker(String scriptUrl) => _WorkerFactoryProvider.createWorker(scriptUrl);
+  factory Worker(String scriptUrl) => Worker._create(scriptUrl);
+  static Worker _create(String scriptUrl) => JS('Worker', 'new Worker(#)', scriptUrl);
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   WorkerEvents get on =>
@@ -20929,6 +20873,16 @@
   void webkitResolveLocalFileSystemUrl(String url, EntryCallback successCallback, [ErrorCallback errorCallback]) native;
 
 
+  /**
+   * Gets an instance of the Indexed DB factory to being using Indexed DB.
+   *
+   * Use [IdbFactory.supported] to check if Indexed DB is supported on the
+   * current platform.
+   */
+  @SupportedBrowser(SupportedBrowser.CHROME, '23.0')
+  @SupportedBrowser(SupportedBrowser.FIREFOX, '15.0')
+  @SupportedBrowser(SupportedBrowser.IE, '10.0')
+  @Experimental()
   IdbFactory get indexedDB =>
       JS('IdbFactory',
          '#.indexedDB || #.webkitIndexedDB || #.mozIndexedDB',
@@ -21010,7 +20964,8 @@
 class XPathEvaluator native "*XPathEvaluator" {
 
   ///@docsEditable true
-  factory XPathEvaluator() => _XPathEvaluatorFactoryProvider.createXPathEvaluator();
+  factory XPathEvaluator() => XPathEvaluator._create();
+  static XPathEvaluator _create() => JS('XPathEvaluator', 'new XPathEvaluator()');
 
   /// @domName XPathEvaluator.createExpression; @docsEditable true
   XPathExpression createExpression(String expression, XPathNSResolver resolver) native;
@@ -21132,7 +21087,8 @@
 class XmlSerializer native "*XMLSerializer" {
 
   ///@docsEditable true
-  factory XmlSerializer() => _XmlSerializerFactoryProvider.createXmlSerializer();
+  factory XmlSerializer() => XmlSerializer._create();
+  static XmlSerializer _create() => JS('XmlSerializer', 'new XMLSerializer()');
 
   /// @domName XMLSerializer.serializeToString; @docsEditable true
   String serializeToString(Node node) native;
@@ -21146,7 +21102,8 @@
 class XsltProcessor native "*XSLTProcessor" {
 
   ///@docsEditable true
-  factory XsltProcessor() => _XsltProcessorFactoryProvider.createXsltProcessor();
+  factory XsltProcessor() => XsltProcessor._create();
+  static XsltProcessor _create() => JS('XsltProcessor', 'new XSLTProcessor()');
 
   /// @domName XSLTProcessor.clearParameters; @docsEditable true
   void clearParameters() native;
@@ -21177,51 +21134,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-class _ArrayBufferFactoryProvider {
-  static ArrayBuffer createArrayBuffer(int length) =>
-      JS('ArrayBuffer', 'new ArrayBuffer(#)', length);
-}
-// 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.
-
-
-class _AudioElementFactoryProvider {
-  static AudioElement createAudioElement([String src = null]) {
-    if (src == null) return JS('AudioElement', 'new Audio()');
-    return JS('AudioElement', 'new Audio(#)', src);
-  }
-}
-// 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.
-
-
-class _BlobFactoryProvider {
-  static Blob createBlob([List blobParts = null, String type, String endings]) {
-    // TODO: validate that blobParts is a JS Array and convert if not.
-    // TODO: any coercions on the elements of blobParts, e.g. coerce a typed
-    // array to ArrayBuffer if it is a total view.
-    if (type == null && endings == null) {
-      return _create_1(blobParts);
-    }
-    var bag = _create_bag();
-    if (type != null) _bag_set(bag, 'type', type);
-    if (endings != null) _bag_set(bag, 'endings', endings);
-    return _create_2(blobParts, bag);
-  }
-
-  static _create_1(parts) => JS('Blob', 'new Blob(#)', parts);
-  static _create_2(parts, bag) => JS('Blob', 'new Blob(#, #)', parts, bag);
-
-  static _create_bag() => JS('var', '{}');
-  static _bag_set(bag, key, value) { JS('void', '#[#] = #', bag, key, value); }
-}
-// 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.
-
-
 /// @domName ClientRectList; @docsEditable true
 class _ClientRectList implements JavaScriptIndexingBehavior, List<ClientRect> native "*ClientRectList" {
 
@@ -21336,15 +21248,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-class _CssMatrixFactoryProvider {
-  static CssMatrix createCssMatrix([String cssValue = '']) =>
-      JS('CssMatrix', 'new WebKitCSSMatrix(#)', cssValue);
-}
-// 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.
-
-
 /// @domName CSSRuleList; @docsEditable true
 class _CssRuleList implements JavaScriptIndexingBehavior, List<CssRule> native "*CSSRuleList" {
 
@@ -21573,32 +21476,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-class _DataViewFactoryProvider {
-  static DataView createDataView(
-      ArrayBuffer buffer, [int byteOffset = null, int byteLength = null]) {
-    if (byteOffset == null) {
-      return JS('DataView', 'new DataView(#)', buffer);
-    }
-    if (byteLength == null) {
-      return JS('DataView', 'new DataView(#,#)', buffer, byteOffset);
-    }
-    return JS('DataView', 'new DataView(#,#,#)', buffer, byteOffset, byteLength);
-  }
-}
-// 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.
-
-
-class _DomParserFactoryProvider {
-  static DomParser createDomParser() =>
-      JS('DomParser', 'new DOMParser()' );
-}
-// 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.
-
-
 /// @domName EntryArray; @docsEditable true
 class _EntryArray implements JavaScriptIndexingBehavior, List<Entry> native "*EntryArray" {
 
@@ -21827,44 +21704,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-class _EventSourceFactoryProvider {
-  static EventSource createEventSource(String scriptUrl) =>
-      JS('EventSource', 'new EventSource(#)', scriptUrl);
-}
-// 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.
-
-
-class _FileReaderFactoryProvider {
-  static FileReader createFileReader() =>
-      JS('FileReader', 'new FileReader()' );
-}
-// 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.
-
-
-class _FileReaderSyncFactoryProvider {
-  static FileReaderSync createFileReaderSync() =>
-      JS('FileReaderSync', 'new FileReaderSync()' );
-}
-// 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.
-
-
-class _FormDataFactoryProvider {
-  static FormData createFormData([FormElement form = null]) {
-    if (form == null) return JS('FormData', 'new FormData()');
-    return JS('FormData', 'new FormData(#)', form);
-  }
-}
-// 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.
-
-
 /// @domName GamepadList; @docsEditable true
 class _GamepadList implements JavaScriptIndexingBehavior, List<Gamepad> native "*GamepadList" {
 
@@ -21979,59 +21818,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-class _HttpRequestFactoryProvider {
-  static HttpRequest createHttpRequest() =>
-      JS('HttpRequest', 'new XMLHttpRequest()');
-
-  static HttpRequest createHttpRequest_get(String url,
-      onComplete(HttpRequest request)) =>
-      _HttpRequestUtils.get(url, onComplete, false);
-
-  static HttpRequest createHttpRequest_getWithCredentials(String url,
-      onComplete(HttpRequest request)) =>
-      _HttpRequestUtils.get(url, onComplete, true);
-}
-// 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.
-
-
-class _IceCandidateFactoryProvider {
-  static IceCandidate createIceCandidate(String label, String candidateLine) =>
-      JS('IceCandidate', 'new IceCandidate(#,#)', label, candidateLine);
-}
-// 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.
-
-
-class _MediaControllerFactoryProvider {
-  static MediaController createMediaController() =>
-      JS('MediaController', 'new MediaController()' );
-}
-// 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.
-
-
-class _MediaSourceFactoryProvider {
-  static MediaSource createMediaSource() =>
-      JS('MediaSource', 'new MediaSource()' );
-}
-// 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.
-
-
-class _MediaStreamFactoryProvider {
-  static MediaStream createMediaStream(MediaStreamTrackList audioTracks, MediaStreamTrackList videoTracks) =>
-      JS('MediaStream', 'new MediaStream(#,#)', audioTracks, videoTracks);
-}
-// 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.
-
-
 /// @domName MediaStreamList; @docsEditable true
 class _MediaStreamList implements JavaScriptIndexingBehavior, List<MediaStream> native "*MediaStreamList" {
 
@@ -22146,159 +21932,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-class _MessageChannelFactoryProvider {
-  static MessageChannel createMessageChannel() =>
-      JS('MessageChannel', 'new MessageChannel()' );
-}
-// 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.
-
-
-class _MutationObserverFactoryProvider {
-
-  @Creates('MutationObserver')
-  @Creates('MutationRecord')
-  static MutationObserver createMutationObserver(MutationCallback callback) native '''
-    var constructor =
-        window.MutationObserver || window.WebKitMutationObserver ||
-        window.MozMutationObserver;
-    return new constructor(callback);
-  ''';
-
-  // TODO(sra): Dart2js inserts a conversion when a Dart function (i.e. an
-  // object with a call method) is passed to a native method.  This is so the
-  // native code sees a JavaScript function.
-  //
-  // This does not happen when a function is 'passed' to a JS-form so it is not
-  // possible to rewrite the above code to, e.g. (simplified):
-  //
-  // static createMutationObserver(MutationCallback callback) =>
-  //    JS('var', 'new (window.MutationObserver)(#)', callback);
-}
-// 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.
-
-
-class _NotificationFactoryProvider {
-  static Notification createNotification(String title, [Map options]) =>
-      JS('Notification', 'new Notification(#,#)', title, options);
-}
-// 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.
-
-
-class _OptionElementFactoryProvider {
-  static OptionElement createOptionElement(
-      [String data, String value, bool defaultSelected, bool selected]) {
-    if (data == null) {
-      return JS('OptionElement', 'new Option()');
-    }
-    if (value == null) {
-      return JS('OptionElement', 'new Option(#)', data);
-    }
-    if (defaultSelected == null) {
-      return JS('OptionElement', 'new Option(#,#)', data, value);
-    }
-    if (selected == null) {
-      return JS('OptionElement', 'new Option(#,#,#)',
-                data, value, defaultSelected);
-    }
-    return JS('OptionElement', 'new Option(#,#,#,#)',
-              data, value, defaultSelected, selected);
-  }
-}
-// 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.
-
-
-class _PeerConnection00FactoryProvider {
-  static PeerConnection00 createPeerConnection00(String serverConfiguration, IceCallback iceCallback) =>
-      JS('PeerConnection00', 'new PeerConnection00(#,#)', serverConfiguration, iceCallback);
-}
-// 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.
-
-
-class _RtcIceCandidateFactoryProvider {
-  static RtcIceCandidate createRtcIceCandidate(Map dictionary) =>
-      JS('RtcIceCandidate', 'new RTCIceCandidate(#)', dictionary);
-}
-// 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.
-
-
-class _RtcPeerConnectionFactoryProvider {
-  static RtcPeerConnection createRtcPeerConnection(Map rtcIceServers, [Map mediaConstraints]) =>
-      JS('RtcPeerConnection', 'new RTCPeerConnection(#,#)', rtcIceServers, mediaConstraints);
-}
-// 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.
-
-
-class _RtcSessionDescriptionFactoryProvider {
-  static RtcSessionDescription createRtcSessionDescription(Map dictionary) =>
-      JS('RtcSessionDescription', 'new RTCSessionDescription(#)', dictionary);
-}
-// 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.
-
-
-class _SessionDescriptionFactoryProvider {
-  static SessionDescription createSessionDescription(String sdp) =>
-      JS('SessionDescription', 'new SessionDescription(#)', 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.
-
-
-class _ShadowRootFactoryProvider {
-  static ShadowRoot createShadowRoot(Element host) =>
-      JS('ShadowRoot',
-         'new (window.ShadowRoot || window.WebKitShadowRoot)(#)', host);
-}
-// 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.
-
-
-class _SharedWorkerFactoryProvider {
-  static SharedWorker createSharedWorker(String scriptURL, [String name]) {
-    if (name == null) return JS('SharedWorker', 'new SharedWorker(#)', scriptURL);
-    return JS('SharedWorker', 'new SharedWorker(#,#)', scriptURL, name);
-  }
-}
-// 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.
-
-
-class _SpeechGrammarFactoryProvider {
-  static SpeechGrammar createSpeechGrammar() =>
-      JS('SpeechGrammar', 'new SpeechGrammar()' );
-}
-// 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.
-
-
-class _SpeechGrammarListFactoryProvider {
-  static SpeechGrammarList createSpeechGrammarList() =>
-      JS('SpeechGrammarList', 'new SpeechGrammarList()' );
-}
-// 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.
-
-
 /// @domName SpeechInputResultList; @docsEditable true
 class _SpeechInputResultList implements JavaScriptIndexingBehavior, List<SpeechInputResult> native "*SpeechInputResultList" {
 
@@ -22413,15 +22046,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-class _SpeechRecognitionFactoryProvider {
-  static SpeechRecognition createSpeechRecognition() =>
-      JS('SpeechRecognition', 'new SpeechRecognition()' );
-}
-// 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.
-
-
 /// @domName SpeechRecognitionResultList; @docsEditable true
 class _SpeechRecognitionResultList implements JavaScriptIndexingBehavior, List<SpeechRecognitionResult> native "*SpeechRecognitionResultList" {
 
@@ -22650,180 +22274,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-class _TextTrackCueFactoryProvider {
-  static TextTrackCue createTextTrackCue(
-      num startTime, num endTime, String text,
-      [String settings, bool pauseOnExit]) {
-        if (settings == null) {
-          return JS('TextTrackCue',
-                    'new TextTrackCue(#,#,#)',
-                    startTime, endTime, text);
-        }
-        if (pauseOnExit == null) {
-          return JS('TextTrackCue',
-                    'new TextTrackCue(#,#,#,#)',
-                    startTime, endTime, text, settings);
-        }
-        return JS('TextTrackCue',
-                  'new TextTrackCue(#,#,#,#,#)',
-                  startTime, endTime, text, settings, pauseOnExit);
-  }
-}
-// 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.
-
-
-/// @domName WebKitAnimationList; @docsEditable true
-class _WebKitAnimationList implements JavaScriptIndexingBehavior, List<Animation> native "*WebKitAnimationList" {
-
-  /// @domName WebKitAnimationList.length; @docsEditable true
-  int get length => JS("int", "#.length", this);
-
-  Animation operator[](int index) => JS("Animation", "#[#]", this, index);
-
-  void operator[]=(int index, Animation value) {
-    throw new UnsupportedError("Cannot assign element of immutable List.");
-  }
-  // -- start List<Animation> mixins.
-  // Animation is the element type.
-
-  // From Iterable<Animation>:
-
-  Iterator<Animation> 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<Animation>(this);
-  }
-
-  // From Collection<Animation>:
-
-  void add(Animation value) {
-    throw new UnsupportedError("Cannot add to immutable List.");
-  }
-
-  void addLast(Animation value) {
-    throw new UnsupportedError("Cannot add to immutable List.");
-  }
-
-  void addAll(Collection<Animation> collection) {
-    throw new UnsupportedError("Cannot add to immutable List.");
-  }
-
-  dynamic reduce(dynamic initialValue, dynamic combine(dynamic, Animation)) {
-    return Collections.reduce(this, initialValue, combine);
-  }
-
-  bool contains(Animation element) => Collections.contains(this, element);
-
-  void forEach(void f(Animation element)) => Collections.forEach(this, f);
-
-  Collection map(f(Animation element)) => Collections.map(this, [], f);
-
-  Collection<Animation> filter(bool f(Animation element)) =>
-     Collections.filter(this, <Animation>[], f);
-
-  bool every(bool f(Animation element)) => Collections.every(this, f);
-
-  bool some(bool f(Animation element)) => Collections.some(this, f);
-
-  bool get isEmpty => this.length == 0;
-
-  // From List<Animation>:
-  void set length(int value) {
-    throw new UnsupportedError("Cannot resize immutable List.");
-  }
-
-  void clear() {
-    throw new UnsupportedError("Cannot clear immutable List.");
-  }
-
-  void sort([int compare(Animation a, Animation b)]) {
-    throw new UnsupportedError("Cannot sort immutable List.");
-  }
-
-  int indexOf(Animation element, [int start = 0]) =>
-      Lists.indexOf(this, element, start, this.length);
-
-  int lastIndexOf(Animation element, [int start]) {
-    if (start == null) start = length - 1;
-    return Lists.lastIndexOf(this, element, start);
-  }
-
-  Animation get first => this[0];
-
-  Animation get last => this[length - 1];
-
-  Animation removeAt(int pos) {
-    throw new UnsupportedError("Cannot removeAt on immutable List.");
-  }
-
-  Animation removeLast() {
-    throw new UnsupportedError("Cannot removeLast on immutable List.");
-  }
-
-  void setRange(int start, int rangeLength, List<Animation> from, [int startFrom]) {
-    throw new UnsupportedError("Cannot setRange on immutable List.");
-  }
-
-  void removeRange(int start, int rangeLength) {
-    throw new UnsupportedError("Cannot removeRange on immutable List.");
-  }
-
-  void insertRange(int start, int rangeLength, [Animation initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
-  }
-
-  List<Animation> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Animation>[]);
-
-  // -- end List<Animation> mixins.
-
-  /// @domName WebKitAnimationList.item; @docsEditable true
-  Animation 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
-// BSD-style license that can be found in the LICENSE file.
-
-
-class _WorkerFactoryProvider {
-  static Worker createWorker(String scriptUrl) =>
-      JS('Worker', 'new Worker(#)', scriptUrl);
-}
-// 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.
-
-
-class _XPathEvaluatorFactoryProvider {
-  static XPathEvaluator createXPathEvaluator() =>
-      JS('XPathEvaluator', 'new XPathEvaluator()' );
-}
-// 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.
-
-
-class _XmlSerializerFactoryProvider {
-  static XmlSerializer createXmlSerializer() =>
-      JS('XmlSerializer', 'new XMLSerializer()' );
-}
-// 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.
-
-
-class _XsltProcessorFactoryProvider {
-  static XsltProcessor createXsltProcessor() =>
-      JS('XsltProcessor', 'new XSLTProcessor()' );
-}
-// 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.
-
-
 abstract class _AttributeMap implements Map<String, String> {
   final Element _element;
 
@@ -23054,7 +22504,7 @@
  * is the container that displays a [Document]'s content. All web scripting
  * happens within the context of a [Window] object.
  *
- * **Note:** This class represents any window, whereas [LocalWindow] is
+ * **Note:** This class represents any window, whereas [Window] is
  * used to access the properties and content of the current window.
  *
  * See also:
@@ -23062,7 +22512,7 @@
  * * [DOM Window](https://developer.mozilla.org/en-US/docs/DOM/window) from MDN.
  * * [Window](http://www.w3.org/TR/Window/) from the W3C.
  */
-abstract class Window {
+abstract class WindowBase {
   // Fields.
 
   /**
@@ -23071,8 +22521,8 @@
    *     Location currentLocation = window.location;
    *     print(currentLocation.href); // 'http://www.example.com:80/'
    */
-  Location get location;
-  History get history;
+  LocationBase get location;
+  HistoryBase get history;
 
   /**
    * Indicates whether this window has been closed.
@@ -23087,16 +22537,16 @@
    * A reference to the window that opened this one.
    *
    *     Window thisWindow = window;
-   *     Window otherWindow = thisWindow.open('http://www.example.com/', 'foo');
+   *     WindowBase otherWindow = thisWindow.open('http://www.example.com/', 'foo');
    *     print(otherWindow.opener == thisWindow); // 'true'
    */
-  Window get opener;
+  WindowBase get opener;
 
   /**
    * A reference to the parent of this window.
    *
-   * If this [Window] has no parent, [parent] will return a reference to
-   * the [Window] itself.
+   * If this [WindowBase] has no parent, [parent] will return a reference to
+   * the [WindowBase] itself.
    *
    *     IFrameElement myIFrame = new IFrameElement();
    *     window.document.body.elements.add(myIFrame);
@@ -23104,13 +22554,13 @@
    *
    *     print(window.parent == window) // 'true'
    */
-  Window get parent;
+  WindowBase get parent;
 
   /**
    * A reference to the topmost window in the window hierarchy.
    *
-   * If this [Window] is the topmost [Window], [top] will return a reference to
-   * the [Window] itself.
+   * If this [WindowBase] is the topmost [WindowBase], [top] will return a
+   * reference to the [WindowBase] itself.
    *
    *     // Add an IFrame to the current window.
    *     IFrameElement myIFrame = new IFrameElement();
@@ -23125,13 +22575,13 @@
    *
    *     print(window.top == window) // 'true'
    */
-  Window get top;
+  WindowBase get top;
 
   // Methods.
   /**
    * Closes the window.
    *
-   * This method should only succeed if the [Window] object is
+   * This method should only succeed if the [WindowBase] object is
    * **script-closeable** and the window calling [close] is allowed to navigate
    * the window.
    *
@@ -23160,11 +22610,11 @@
   void postMessage(var message, String targetOrigin, [List messagePorts]);
 }
 
-abstract class Location {
+abstract class LocationBase {
   void set href(String val);
 }
 
-abstract class History {
+abstract class HistoryBase {
   void back();
   void forward();
   void go(int distance);
@@ -24815,7 +24265,6 @@
 
 typedef void _MeasurementCallback();
 
-
 /**
  * This class attempts to invoke a callback as soon as the current event stack
  * unwinds, but before the browser repaints.
@@ -24830,7 +24279,7 @@
    * Creates the best possible measurement scheduler for the current platform.
    */
   factory _MeasurementScheduler.best(_MeasurementCallback callback) {
-    if (_isMutationObserverSupported()) {
+    if (MutationObserver.supported) {
       return new _MutationObserverScheduler(callback);
     }
     return new _PostMessageScheduler(callback);
@@ -25272,7 +24721,7 @@
 // window as a parameter.
 
 
-Window _convertNativeToDart_Window(win) {
+WindowBase _convertNativeToDart_Window(win) {
   return _DOMWindowCrossFrame._createSafe(win);
 }
 
@@ -25342,27 +24791,27 @@
 
 
 // TODO(vsm): Unify with Dartium version.
-class _DOMWindowCrossFrame implements Window {
+class _DOMWindowCrossFrame implements WindowBase {
   // Private window.  Note, this is a window in another frame, so it
   // cannot be typed as "Window" as its prototype is not patched
   // properly.  Its fields and methods can only be accessed via JavaScript.
   var _window;
 
   // Fields.
-  History get history =>
-    _HistoryCrossFrame._createSafe(JS('History', '#.history', _window));
-  Location get location =>
-    _LocationCrossFrame._createSafe(JS('Location', '#.location', _window));
+  HistoryBase get history =>
+    _HistoryCrossFrame._createSafe(JS('HistoryBase', '#.history', _window));
+  LocationBase get location =>
+    _LocationCrossFrame._createSafe(JS('LocationBase', '#.location', _window));
 
   // TODO(vsm): Add frames to navigate subframes.  See 2312.
 
   bool get closed => JS('bool', '#.closed', _window);
 
-  Window get opener => _createSafe(JS('Window', '#.opener', _window));
+  WindowBase get opener => _createSafe(JS('WindowBase', '#.opener', _window));
 
-  Window get parent => _createSafe(JS('Window', '#.parent', _window));
+  WindowBase get parent => _createSafe(JS('WindowBase', '#.parent', _window));
 
-  Window get top => _createSafe(JS('Window', '#.top', _window));
+  WindowBase get top => _createSafe(JS('WindowBase', '#.top', _window));
 
   // Methods.
   void close() => JS('void', '#.close()', _window);
@@ -25378,7 +24827,7 @@
   // Implementation support.
   _DOMWindowCrossFrame(this._window);
 
-  static Window _createSafe(w) {
+  static WindowBase _createSafe(w) {
     if (identical(w, window)) {
       return w;
     } else {
@@ -25388,7 +24837,7 @@
   }
 }
 
-class _LocationCrossFrame implements Location {
+class _LocationCrossFrame implements LocationBase {
   // Private location.  Note, this is a location object in another frame, so it
   // cannot be typed as "Location" as its prototype is not patched
   // properly.  Its fields and methods can only be accessed via JavaScript.
@@ -25402,7 +24851,7 @@
   // Implementation support.
   _LocationCrossFrame(this._location);
 
-  static Location _createSafe(location) {
+  static LocationBase _createSafe(location) {
     if (identical(location, window.location)) {
       return location;
     } else {
@@ -25412,7 +24861,7 @@
   }
 }
 
-class _HistoryCrossFrame implements History {
+class _HistoryCrossFrame implements HistoryBase {
   // Private history.  Note, this is a history object in another frame, so it
   // cannot be typed as "History" as its prototype is not patched
   // properly.  Its fields and methods can only be accessed via JavaScript.
@@ -25427,7 +24876,7 @@
   // Implementation support.
   _HistoryCrossFrame(this._history);
 
-  static History _createSafe(h) {
+  static HistoryBase _createSafe(h) {
     if (identical(h, window.history)) {
       return h;
     } else {
@@ -25534,7 +24983,7 @@
   void stopImmediatePropagation() => _parent.stopImmediatePropagation();
   void stopPropagation() => _parent.stopPropagation();
   void $dom_initUIEvent(String type, bool canBubble, bool cancelable,
-      LocalWindow view, int detail) {
+      Window view, int detail) {
     throw new UnsupportedError("Cannot initialize a UI Event from a KeyEvent.");
   }
   void $dom_initEvent(String eventTypeArg, bool canBubbleArg,
@@ -25550,7 +24999,7 @@
     throw new UnsupportedError("keyIdentifier is unsupported.");
   }
   void $dom_initKeyboardEvent(String type, bool canBubble, bool cancelable,
-      LocalWindow view, String keyIdentifier, int keyLocation, bool ctrlKey,
+      Window view, String keyIdentifier, int keyLocation, bool ctrlKey,
       bool altKey, bool shiftKey, bool metaKey,
       bool altGraphKey) {
     throw new UnsupportedError(
@@ -25562,16 +25011,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-class _PointFactoryProvider {
-  static Point createPoint(num x, num y) =>
-      JS('Point', 'new WebKitPoint(#, #)', x, y);
-}
-
-class _WebSocketFactoryProvider {
-  static WebSocket createWebSocket(String url) =>
-      JS('WebSocket', 'new WebSocket(#)', url);
-}
-
 class _TextFactoryProvider {
   static Text createText(String data) =>
       JS('Text', 'document.createTextNode(#)', data);
@@ -25585,7 +25024,7 @@
 // It can't be monkey-patched and seems immune to putting methods on
 // Object.prototype.  We are forced to wrap the object.
 
-class _LocationWrapper implements LocalLocation {
+class _LocationWrapper implements Location {
 
   final _ptr;  // Opaque reference to real location.
 
@@ -25664,17 +25103,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-/**
- * Checks to see if the mutation observer API is supported on the current
- * platform.
- */
-bool _isMutationObserverSupported() =>
-  JS('bool', '!!(window.MutationObserver || window.WebKitMutationObserver)');
-// 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.
-
-
 class _TypedArrayFactoryProvider {
 
   static Float32Array createFloat32Array(int length) => _F32(length);
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 9396f1e..b515403 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -22,9 +22,9 @@
 
 
 
-LocalWindow _window;
+Window _window;
 
-LocalWindow get window {
+Window get window {
   if (_window != null) {
     return _window;
   }
@@ -73,7 +73,7 @@
 
 /// @domName AbstractWorker
 class AbstractWorker extends EventTarget {
-  AbstractWorker.internal(): super.internal();
+  AbstractWorker.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   AbstractWorkerEvents get on =>
@@ -110,6 +110,7 @@
 
 /// @domName HTMLAnchorElement
 class AnchorElement extends _Element_Merged {
+  AnchorElement.internal() : super.internal();
 
   ///@docsEditable true
   factory AnchorElement({String href}) {
@@ -117,23 +118,6 @@
     if (href != null) e.href = href;
     return e;
   }
-  AnchorElement.internal(): super.internal();
-
-
-  /** @domName HTMLAnchorElement.charset */
-  String get charset native "HTMLAnchorElement_charset_Getter";
-
-
-  /** @domName HTMLAnchorElement.charset */
-  void set charset(String value) native "HTMLAnchorElement_charset_Setter";
-
-
-  /** @domName HTMLAnchorElement.coords */
-  String get coords native "HTMLAnchorElement_coords_Getter";
-
-
-  /** @domName HTMLAnchorElement.coords */
-  void set coords(String value) native "HTMLAnchorElement_coords_Setter";
 
 
   /** @domName HTMLAnchorElement.download */
@@ -236,14 +220,6 @@
   void set rel(String value) native "HTMLAnchorElement_rel_Setter";
 
 
-  /** @domName HTMLAnchorElement.rev */
-  String get rev native "HTMLAnchorElement_rev_Getter";
-
-
-  /** @domName HTMLAnchorElement.rev */
-  void set rev(String value) native "HTMLAnchorElement_rev_Setter";
-
-
   /** @domName HTMLAnchorElement.search */
   String get search native "HTMLAnchorElement_search_Getter";
 
@@ -252,14 +228,6 @@
   void set search(String value) native "HTMLAnchorElement_search_Setter";
 
 
-  /** @domName HTMLAnchorElement.shape */
-  String get shape native "HTMLAnchorElement_shape_Getter";
-
-
-  /** @domName HTMLAnchorElement.shape */
-  void set shape(String value) native "HTMLAnchorElement_shape_Setter";
-
-
   /** @domName HTMLAnchorElement.target */
   String get target native "HTMLAnchorElement_target_Getter";
 
@@ -287,81 +255,9 @@
 // WARNING: Do not edit - generated code.
 
 
-/// @domName WebKitAnimation
-class Animation extends NativeFieldWrapperClass1 {
-  Animation.internal();
-
-  static const int DIRECTION_ALTERNATE = 1;
-
-  static const int DIRECTION_NORMAL = 0;
-
-  static const int FILL_BACKWARDS = 1;
-
-  static const int FILL_BOTH = 3;
-
-  static const int FILL_FORWARDS = 2;
-
-  static const int FILL_NONE = 0;
-
-
-  /** @domName WebKitAnimation.delay */
-  num get delay native "WebKitAnimation_delay_Getter";
-
-
-  /** @domName WebKitAnimation.direction */
-  int get direction native "WebKitAnimation_direction_Getter";
-
-
-  /** @domName WebKitAnimation.duration */
-  num get duration native "WebKitAnimation_duration_Getter";
-
-
-  /** @domName WebKitAnimation.elapsedTime */
-  num get elapsedTime native "WebKitAnimation_elapsedTime_Getter";
-
-
-  /** @domName WebKitAnimation.elapsedTime */
-  void set elapsedTime(num value) native "WebKitAnimation_elapsedTime_Setter";
-
-
-  /** @domName WebKitAnimation.ended */
-  bool get ended native "WebKitAnimation_ended_Getter";
-
-
-  /** @domName WebKitAnimation.fillMode */
-  int get fillMode native "WebKitAnimation_fillMode_Getter";
-
-
-  /** @domName WebKitAnimation.iterationCount */
-  int get iterationCount native "WebKitAnimation_iterationCount_Getter";
-
-
-  /** @domName WebKitAnimation.name */
-  String get name native "WebKitAnimation_name_Getter";
-
-
-  /** @domName WebKitAnimation.paused */
-  bool get paused native "WebKitAnimation_paused_Getter";
-
-
-  /** @domName WebKitAnimation.pause */
-  void pause() native "WebKitAnimation_pause_Callback";
-
-
-  /** @domName WebKitAnimation.play */
-  void play() native "WebKitAnimation_play_Callback";
-
-}
-// 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.
-
-
 /// @domName WebKitAnimationEvent
 class AnimationEvent extends Event {
-  AnimationEvent.internal(): super.internal();
+  AnimationEvent.internal() : super.internal();
 
 
   /** @domName WebKitAnimationEvent.animationName */
@@ -381,7 +277,7 @@
 
 /// @domName HTMLAppletElement
 class AppletElement extends _Element_Merged {
-  AppletElement.internal(): super.internal();
+  AppletElement.internal() : super.internal();
 
 
   /** @domName HTMLAppletElement.align */
@@ -481,7 +377,7 @@
 
 /// @domName DOMApplicationCache
 class ApplicationCache extends EventTarget {
-  ApplicationCache.internal(): super.internal();
+  ApplicationCache.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   ApplicationCacheEvents get on =>
@@ -567,10 +463,10 @@
 
 /// @domName HTMLAreaElement
 class AreaElement extends _Element_Merged {
+  AreaElement.internal() : super.internal();
 
   ///@docsEditable true
   factory AreaElement() => document.$dom_createElement("area");
-  AreaElement.internal(): super.internal();
 
 
   /** @domName HTMLAreaElement.alt */
@@ -609,14 +505,6 @@
   void set href(String value) native "HTMLAreaElement_href_Setter";
 
 
-  /** @domName HTMLAreaElement.noHref */
-  bool get noHref native "HTMLAreaElement_noHref_Getter";
-
-
-  /** @domName HTMLAreaElement.noHref */
-  void set noHref(bool value) native "HTMLAreaElement_noHref_Setter";
-
-
   /** @domName HTMLAreaElement.pathname */
   String get pathname native "HTMLAreaElement_pathname_Getter";
 
@@ -665,11 +553,21 @@
 
 
 /// @domName ArrayBuffer
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class ArrayBuffer extends NativeFieldWrapperClass1 {
+  ArrayBuffer.internal();
 
   ///@docsEditable true
-  factory ArrayBuffer(int length) => _ArrayBufferFactoryProvider.createArrayBuffer(length);
-  ArrayBuffer.internal();
+  factory ArrayBuffer(int length) => ArrayBuffer._create(length);
+  static ArrayBuffer _create(int length) native "ArrayBuffer_constructor_Callback";
+
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => true;
 
 
   /** @domName ArrayBuffer.byteLength */
@@ -699,6 +597,10 @@
 
 
 /// @domName ArrayBufferView
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class ArrayBufferView extends NativeFieldWrapperClass1 {
   ArrayBufferView.internal();
 
@@ -724,7 +626,7 @@
 
 /// @domName Attr
 class Attr extends Node {
-  Attr.internal(): super.internal();
+  Attr.internal() : super.internal();
 
 
   /** @domName Attr.isId */
@@ -760,15 +662,16 @@
 
 /// @domName HTMLAudioElement
 class AudioElement extends MediaElement {
+  AudioElement.internal() : super.internal();
 
   ///@docsEditable true
   factory AudioElement([String src]) {
     if (!?src) {
-      return _AudioElementFactoryProvider.createAudioElement();
+      return AudioElement._create();
     }
-    return _AudioElementFactoryProvider.createAudioElement(src);
+    return AudioElement._create(src);
   }
-  AudioElement.internal(): super.internal();
+  static AudioElement _create([String src]) native "HTMLAudioElement_constructor_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -780,18 +683,10 @@
 
 /// @domName HTMLBRElement
 class BRElement extends _Element_Merged {
+  BRElement.internal() : super.internal();
 
   ///@docsEditable true
   factory BRElement() => document.$dom_createElement("br");
-  BRElement.internal(): super.internal();
-
-
-  /** @domName HTMLBRElement.clear */
-  String get clear native "HTMLBRElement_clear_Getter";
-
-
-  /** @domName HTMLBRElement.clear */
-  void set clear(String value) native "HTMLBRElement_clear_Setter";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -819,10 +714,10 @@
 
 /// @domName HTMLBaseElement
 class BaseElement extends _Element_Merged {
+  BaseElement.internal() : super.internal();
 
   ///@docsEditable true
   factory BaseElement() => document.$dom_createElement("base");
-  BaseElement.internal(): super.internal();
 
 
   /** @domName HTMLBaseElement.href */
@@ -850,7 +745,7 @@
 
 /// @domName HTMLBaseFontElement
 class BaseFontElement extends _Element_Merged {
-  BaseFontElement.internal(): super.internal();
+  BaseFontElement.internal() : super.internal();
 
 
   /** @domName HTMLBaseFontElement.color */
@@ -886,7 +781,7 @@
 
 /// @domName BatteryManager
 class BatteryManager extends EventTarget {
-  BatteryManager.internal(): super.internal();
+  BatteryManager.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   BatteryManagerEvents get on =>
@@ -948,7 +843,7 @@
 
 /// @domName BeforeLoadEvent
 class BeforeLoadEvent extends Event {
-  BeforeLoadEvent.internal(): super.internal();
+  BeforeLoadEvent.internal() : super.internal();
 
 
   /** @domName BeforeLoadEvent.url */
@@ -964,18 +859,19 @@
 
 /// @domName Blob
 class Blob extends NativeFieldWrapperClass1 {
+  Blob.internal();
 
   ///@docsEditable true
   factory Blob(List blobParts, [String type, String endings]) {
     if (!?type) {
-      return _BlobFactoryProvider.createBlob(blobParts);
+      return Blob._create(blobParts);
     }
     if (!?endings) {
-      return _BlobFactoryProvider.createBlob(blobParts, type);
+      return Blob._create(blobParts, type);
     }
-    return _BlobFactoryProvider.createBlob(blobParts, type, endings);
+    return Blob._create(blobParts, type, endings);
   }
-  Blob.internal();
+  static Blob _create(List blobParts, [String type, String endings]) native "Blob_constructor_Callback";
 
 
   /** @domName Blob.size */
@@ -1024,48 +920,16 @@
 
 /// @domName HTMLBodyElement
 class BodyElement extends _Element_Merged {
+  BodyElement.internal() : super.internal();
 
   ///@docsEditable true
   factory BodyElement() => document.$dom_createElement("body");
-  BodyElement.internal(): super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   BodyElementEvents get on =>
     new BodyElementEvents(this);
 
 
-  /** @domName HTMLBodyElement.aLink */
-  String get aLink native "HTMLBodyElement_aLink_Getter";
-
-
-  /** @domName HTMLBodyElement.aLink */
-  void set aLink(String value) native "HTMLBodyElement_aLink_Setter";
-
-
-  /** @domName HTMLBodyElement.background */
-  String get background native "HTMLBodyElement_background_Getter";
-
-
-  /** @domName HTMLBodyElement.background */
-  void set background(String value) native "HTMLBodyElement_background_Setter";
-
-
-  /** @domName HTMLBodyElement.bgColor */
-  String get bgColor native "HTMLBodyElement_bgColor_Getter";
-
-
-  /** @domName HTMLBodyElement.bgColor */
-  void set bgColor(String value) native "HTMLBodyElement_bgColor_Setter";
-
-
-  /** @domName HTMLBodyElement.link */
-  String get link native "HTMLBodyElement_link_Getter";
-
-
-  /** @domName HTMLBodyElement.link */
-  void set link(String value) native "HTMLBodyElement_link_Setter";
-
-
   /** @domName HTMLBodyElement.vLink */
   String get vLink native "HTMLBodyElement_vLink_Getter";
 
@@ -1128,10 +992,10 @@
 
 /// @domName HTMLButtonElement
 class ButtonElement extends _Element_Merged {
+  ButtonElement.internal() : super.internal();
 
   ///@docsEditable true
   factory ButtonElement() => document.$dom_createElement("button");
-  ButtonElement.internal(): super.internal();
 
 
   /** @domName HTMLButtonElement.autofocus */
@@ -1251,7 +1115,7 @@
 
 /// @domName CDATASection
 class CDataSection extends Text {
-  CDataSection.internal(): super.internal();
+  CDataSection.internal() : super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -1261,6 +1125,7 @@
 
 /// @domName HTMLCanvasElement
 class CanvasElement extends _Element_Merged {
+  CanvasElement.internal() : super.internal();
 
   ///@docsEditable true
   factory CanvasElement({int width, int height}) {
@@ -1269,7 +1134,6 @@
     if (height != null) e.height = height;
     return e;
   }
-  CanvasElement.internal(): super.internal();
 
 
   /** @domName HTMLCanvasElement.height */
@@ -1349,7 +1213,7 @@
 
 /// @domName CanvasRenderingContext2D
 class CanvasRenderingContext2D extends CanvasRenderingContext {
-  CanvasRenderingContext2D.internal(): super.internal();
+  CanvasRenderingContext2D.internal() : super.internal();
 
 
   /** @domName CanvasRenderingContext2D.fillStyle */
@@ -1528,10 +1392,6 @@
   void clearRect(num x, num y, num width, num height) native "CanvasRenderingContext2D_clearRect_Callback";
 
 
-  /** @domName CanvasRenderingContext2D.clearShadow */
-  void clearShadow() native "CanvasRenderingContext2D_clearShadow_Callback";
-
-
   /** @domName CanvasRenderingContext2D.clip */
   void clip() native "CanvasRenderingContext2D_clip_Callback";
 
@@ -1659,86 +1519,6 @@
   /** @domName CanvasRenderingContext2D.drawImage_9 */
   void _drawImage_9(canvas_OR_image_OR_video, sx_OR_x, sy_OR_y, sw_OR_width, height_OR_sh, dx, dy, dw, dh) native "CanvasRenderingContext2D_drawImage_9_Callback";
 
-  void drawImageFromRect(/*HTMLImageElement*/ image, [/*float*/ sx, /*float*/ sy, /*float*/ sw, /*float*/ sh, /*float*/ dx, /*float*/ dy, /*float*/ dw, /*float*/ dh, /*DOMString*/ compositeOperation]) {
-    if (?compositeOperation) {
-      _drawImageFromRect_1(image, sx, sy, sw, sh, dx, dy, dw, dh, compositeOperation);
-      return;
-    }
-    if (?dh) {
-      _drawImageFromRect_2(image, sx, sy, sw, sh, dx, dy, dw, dh);
-      return;
-    }
-    if (?dw) {
-      _drawImageFromRect_3(image, sx, sy, sw, sh, dx, dy, dw);
-      return;
-    }
-    if (?dy) {
-      _drawImageFromRect_4(image, sx, sy, sw, sh, dx, dy);
-      return;
-    }
-    if (?dx) {
-      _drawImageFromRect_5(image, sx, sy, sw, sh, dx);
-      return;
-    }
-    if (?sh) {
-      _drawImageFromRect_6(image, sx, sy, sw, sh);
-      return;
-    }
-    if (?sw) {
-      _drawImageFromRect_7(image, sx, sy, sw);
-      return;
-    }
-    if (?sy) {
-      _drawImageFromRect_8(image, sx, sy);
-      return;
-    }
-    if (?sx) {
-      _drawImageFromRect_9(image, sx);
-      return;
-    }
-    _drawImageFromRect_10(image);
-  }
-
-
-  /** @domName CanvasRenderingContext2D.drawImageFromRect_1 */
-  void _drawImageFromRect_1(image, sx, sy, sw, sh, dx, dy, dw, dh, compositeOperation) native "CanvasRenderingContext2D_drawImageFromRect_1_Callback";
-
-
-  /** @domName CanvasRenderingContext2D.drawImageFromRect_2 */
-  void _drawImageFromRect_2(image, sx, sy, sw, sh, dx, dy, dw, dh) native "CanvasRenderingContext2D_drawImageFromRect_2_Callback";
-
-
-  /** @domName CanvasRenderingContext2D.drawImageFromRect_3 */
-  void _drawImageFromRect_3(image, sx, sy, sw, sh, dx, dy, dw) native "CanvasRenderingContext2D_drawImageFromRect_3_Callback";
-
-
-  /** @domName CanvasRenderingContext2D.drawImageFromRect_4 */
-  void _drawImageFromRect_4(image, sx, sy, sw, sh, dx, dy) native "CanvasRenderingContext2D_drawImageFromRect_4_Callback";
-
-
-  /** @domName CanvasRenderingContext2D.drawImageFromRect_5 */
-  void _drawImageFromRect_5(image, sx, sy, sw, sh, dx) native "CanvasRenderingContext2D_drawImageFromRect_5_Callback";
-
-
-  /** @domName CanvasRenderingContext2D.drawImageFromRect_6 */
-  void _drawImageFromRect_6(image, sx, sy, sw, sh) native "CanvasRenderingContext2D_drawImageFromRect_6_Callback";
-
-
-  /** @domName CanvasRenderingContext2D.drawImageFromRect_7 */
-  void _drawImageFromRect_7(image, sx, sy, sw) native "CanvasRenderingContext2D_drawImageFromRect_7_Callback";
-
-
-  /** @domName CanvasRenderingContext2D.drawImageFromRect_8 */
-  void _drawImageFromRect_8(image, sx, sy) native "CanvasRenderingContext2D_drawImageFromRect_8_Callback";
-
-
-  /** @domName CanvasRenderingContext2D.drawImageFromRect_9 */
-  void _drawImageFromRect_9(image, sx) native "CanvasRenderingContext2D_drawImageFromRect_9_Callback";
-
-
-  /** @domName CanvasRenderingContext2D.drawImageFromRect_10 */
-  void _drawImageFromRect_10(image) native "CanvasRenderingContext2D_drawImageFromRect_10_Callback";
-
 
   /** @domName CanvasRenderingContext2D.fill */
   void fill() native "CanvasRenderingContext2D_fill_Callback";
@@ -1832,94 +1612,10 @@
   void scale(num sx, num sy) native "CanvasRenderingContext2D_scale_Callback";
 
 
-  /** @domName CanvasRenderingContext2D.setAlpha */
-  void setAlpha(num alpha) native "CanvasRenderingContext2D_setAlpha_Callback";
-
-
-  /** @domName CanvasRenderingContext2D.setCompositeOperation */
-  void setCompositeOperation(String compositeOperation) native "CanvasRenderingContext2D_setCompositeOperation_Callback";
-
-
-  /** @domName CanvasRenderingContext2D.setLineCap */
-  void setLineCap(String cap) native "CanvasRenderingContext2D_setLineCap_Callback";
-
-
   /** @domName CanvasRenderingContext2D.setLineDash */
   void setLineDash(List<num> dash) native "CanvasRenderingContext2D_setLineDash_Callback";
 
 
-  /** @domName CanvasRenderingContext2D.setLineJoin */
-  void setLineJoin(String join) native "CanvasRenderingContext2D_setLineJoin_Callback";
-
-
-  /** @domName CanvasRenderingContext2D.setLineWidth */
-  void setLineWidth(num width) native "CanvasRenderingContext2D_setLineWidth_Callback";
-
-
-  /** @domName CanvasRenderingContext2D.setMiterLimit */
-  void setMiterLimit(num limit) native "CanvasRenderingContext2D_setMiterLimit_Callback";
-
-  void setShadow(/*float*/ width, /*float*/ height, /*float*/ blur, [c_OR_color_OR_grayLevel_OR_r, /*float*/ alpha_OR_g_OR_m, /*float*/ b_OR_y, /*float*/ a_OR_k, /*float*/ a]) {
-    if ((width is num || width == null) && (height is num || height == null) && (blur is num || blur == null) && !?c_OR_color_OR_grayLevel_OR_r && !?alpha_OR_g_OR_m && !?b_OR_y && !?a_OR_k && !?a) {
-      _setShadow_1(width, height, blur);
-      return;
-    }
-    if ((width is num || width == null) && (height is num || height == null) && (blur is num || blur == null) && (c_OR_color_OR_grayLevel_OR_r is String || c_OR_color_OR_grayLevel_OR_r == null) && !?alpha_OR_g_OR_m && !?b_OR_y && !?a_OR_k && !?a) {
-      _setShadow_2(width, height, blur, c_OR_color_OR_grayLevel_OR_r);
-      return;
-    }
-    if ((width is num || width == null) && (height is num || height == null) && (blur is num || blur == null) && (c_OR_color_OR_grayLevel_OR_r is String || c_OR_color_OR_grayLevel_OR_r == null) && (alpha_OR_g_OR_m is num || alpha_OR_g_OR_m == null) && !?b_OR_y && !?a_OR_k && !?a) {
-      _setShadow_3(width, height, blur, c_OR_color_OR_grayLevel_OR_r, alpha_OR_g_OR_m);
-      return;
-    }
-    if ((width is num || width == null) && (height is num || height == null) && (blur is num || blur == null) && (c_OR_color_OR_grayLevel_OR_r is num || c_OR_color_OR_grayLevel_OR_r == null) && !?alpha_OR_g_OR_m && !?b_OR_y && !?a_OR_k && !?a) {
-      _setShadow_4(width, height, blur, c_OR_color_OR_grayLevel_OR_r);
-      return;
-    }
-    if ((width is num || width == null) && (height is num || height == null) && (blur is num || blur == null) && (c_OR_color_OR_grayLevel_OR_r is num || c_OR_color_OR_grayLevel_OR_r == null) && (alpha_OR_g_OR_m is num || alpha_OR_g_OR_m == null) && !?b_OR_y && !?a_OR_k && !?a) {
-      _setShadow_5(width, height, blur, c_OR_color_OR_grayLevel_OR_r, alpha_OR_g_OR_m);
-      return;
-    }
-    if ((width is num || width == null) && (height is num || height == null) && (blur is num || blur == null) && (c_OR_color_OR_grayLevel_OR_r is num || c_OR_color_OR_grayLevel_OR_r == null) && (alpha_OR_g_OR_m is num || alpha_OR_g_OR_m == null) && (b_OR_y is num || b_OR_y == null) && (a_OR_k is num || a_OR_k == null) && !?a) {
-      _setShadow_6(width, height, blur, c_OR_color_OR_grayLevel_OR_r, alpha_OR_g_OR_m, b_OR_y, a_OR_k);
-      return;
-    }
-    if ((width is num || width == null) && (height is num || height == null) && (blur is num || blur == null) && (c_OR_color_OR_grayLevel_OR_r is num || c_OR_color_OR_grayLevel_OR_r == null) && (alpha_OR_g_OR_m is num || alpha_OR_g_OR_m == null) && (b_OR_y is num || b_OR_y == null) && (a_OR_k is num || a_OR_k == null) && (a is num || a == null)) {
-      _setShadow_7(width, height, blur, c_OR_color_OR_grayLevel_OR_r, alpha_OR_g_OR_m, b_OR_y, a_OR_k, a);
-      return;
-    }
-    throw "Incorrect number or type of arguments";
-  }
-
-
-  /** @domName CanvasRenderingContext2D.setShadow_1 */
-  void _setShadow_1(width, height, blur) native "CanvasRenderingContext2D_setShadow_1_Callback";
-
-
-  /** @domName CanvasRenderingContext2D.setShadow_2 */
-  void _setShadow_2(width, height, blur, c_OR_color_OR_grayLevel_OR_r) native "CanvasRenderingContext2D_setShadow_2_Callback";
-
-
-  /** @domName CanvasRenderingContext2D.setShadow_3 */
-  void _setShadow_3(width, height, blur, c_OR_color_OR_grayLevel_OR_r, alpha_OR_g_OR_m) native "CanvasRenderingContext2D_setShadow_3_Callback";
-
-
-  /** @domName CanvasRenderingContext2D.setShadow_4 */
-  void _setShadow_4(width, height, blur, c_OR_color_OR_grayLevel_OR_r) native "CanvasRenderingContext2D_setShadow_4_Callback";
-
-
-  /** @domName CanvasRenderingContext2D.setShadow_5 */
-  void _setShadow_5(width, height, blur, c_OR_color_OR_grayLevel_OR_r, alpha_OR_g_OR_m) native "CanvasRenderingContext2D_setShadow_5_Callback";
-
-
-  /** @domName CanvasRenderingContext2D.setShadow_6 */
-  void _setShadow_6(width, height, blur, c_OR_color_OR_grayLevel_OR_r, alpha_OR_g_OR_m, b_OR_y, a_OR_k) native "CanvasRenderingContext2D_setShadow_6_Callback";
-
-
-  /** @domName CanvasRenderingContext2D.setShadow_7 */
-  void _setShadow_7(width, height, blur, c_OR_color_OR_grayLevel_OR_r, alpha_OR_g_OR_m, b_OR_y, a_OR_k, a) native "CanvasRenderingContext2D_setShadow_7_Callback";
-
-
   /** @domName CanvasRenderingContext2D.setTransform */
   void setTransform(num m11, num m12, num m21, num m22, num dx, num dy) native "CanvasRenderingContext2D_setTransform_Callback";
 
@@ -2037,7 +1733,7 @@
 
 /// @domName CharacterData
 class CharacterData extends Node {
-  CharacterData.internal(): super.internal();
+  CharacterData.internal() : super.internal();
 
 
   /** @domName CharacterData.data */
@@ -2177,7 +1873,7 @@
 
 /// @domName CloseEvent
 class CloseEvent extends Event {
-  CloseEvent.internal(): super.internal();
+  CloseEvent.internal() : super.internal();
 
 
   /** @domName CloseEvent.code */
@@ -2201,7 +1897,7 @@
 
 /// @domName Comment
 class Comment extends CharacterData {
-  Comment.internal(): super.internal();
+  Comment.internal() : super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -2213,7 +1909,7 @@
 
 /// @domName CompositionEvent
 class CompositionEvent extends UIEvent {
-  CompositionEvent.internal(): super.internal();
+  CompositionEvent.internal() : super.internal();
 
 
   /** @domName CompositionEvent.data */
@@ -2221,7 +1917,7 @@
 
 
   /** @domName CompositionEvent.initCompositionEvent */
-  void initCompositionEvent(String typeArg, bool canBubbleArg, bool cancelableArg, LocalWindow viewArg, String dataArg) native "CompositionEvent_initCompositionEvent_Callback";
+  void initCompositionEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Window viewArg, String dataArg) native "CompositionEvent_initCompositionEvent_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -2248,6 +1944,10 @@
   void assertCondition(bool condition, Object arg) native "Console_assertCondition_Callback";
 
 
+  /** @domName Console.clear */
+  void clear(Object arg) native "Console_clear_Callback";
+
+
   /** @domName Console.count */
   void count(Object arg) native "Console_count_Callback";
 
@@ -2289,7 +1989,7 @@
 
 
   /** @domName Console.markTimeline */
-  void markTimeline(Object arg) native "Console_markTimeline_Callback";
+  void markTimeline() native "Console_markTimeline_Callback";
 
 
   /** @domName Console.profile */
@@ -2305,11 +2005,11 @@
 
 
   /** @domName Console.timeEnd */
-  void timeEnd(String title, Object arg) native "Console_timeEnd_Callback";
+  void timeEnd(String title) native "Console_timeEnd_Callback";
 
 
   /** @domName Console.timeStamp */
-  void timeStamp(Object arg) native "Console_timeStamp_Callback";
+  void timeStamp() native "Console_timeStamp_Callback";
 
 
   /** @domName Console.trace */
@@ -2328,11 +2028,18 @@
 
 
 /// @domName HTMLContentElement
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Experimental()
 class ContentElement extends _Element_Merged {
+  ContentElement.internal() : super.internal();
 
   ///@docsEditable true
   factory ContentElement() => document.$dom_createElement("content");
-  ContentElement.internal(): super.internal();
+
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => true;
 
 
   /** @domName HTMLContentElement.resetStyleInheritance */
@@ -2444,7 +2151,7 @@
 
 /// @domName CSSCharsetRule
 class CssCharsetRule extends CssRule {
-  CssCharsetRule.internal(): super.internal();
+  CssCharsetRule.internal() : super.internal();
 
 
   /** @domName CSSCharsetRule.encoding */
@@ -2464,7 +2171,7 @@
 
 /// @domName CSSFontFaceRule
 class CssFontFaceRule extends CssRule {
-  CssFontFaceRule.internal(): super.internal();
+  CssFontFaceRule.internal() : super.internal();
 
 
   /** @domName CSSFontFaceRule.style */
@@ -2480,7 +2187,7 @@
 
 /// @domName CSSImportRule
 class CssImportRule extends CssRule {
-  CssImportRule.internal(): super.internal();
+  CssImportRule.internal() : super.internal();
 
 
   /** @domName CSSImportRule.href */
@@ -2504,7 +2211,7 @@
 
 /// @domName WebKitCSSKeyframeRule
 class CssKeyframeRule extends CssRule {
-  CssKeyframeRule.internal(): super.internal();
+  CssKeyframeRule.internal() : super.internal();
 
 
   /** @domName WebKitCSSKeyframeRule.keyText */
@@ -2528,7 +2235,7 @@
 
 /// @domName WebKitCSSKeyframesRule
 class CssKeyframesRule extends CssRule {
-  CssKeyframesRule.internal(): super.internal();
+  CssKeyframesRule.internal() : super.internal();
 
 
   /** @domName WebKitCSSKeyframesRule.cssRules */
@@ -2564,15 +2271,16 @@
 
 /// @domName WebKitCSSMatrix
 class CssMatrix extends NativeFieldWrapperClass1 {
+  CssMatrix.internal();
 
   ///@docsEditable true
   factory CssMatrix([String cssValue]) {
     if (!?cssValue) {
-      return _CssMatrixFactoryProvider.createCssMatrix();
+      return CssMatrix._create();
     }
-    return _CssMatrixFactoryProvider.createCssMatrix(cssValue);
+    return CssMatrix._create(cssValue);
   }
-  CssMatrix.internal();
+  static CssMatrix _create([String cssValue]) native "WebKitCSSMatrix_constructor_Callback";
 
 
   /** @domName WebKitCSSMatrix.a */
@@ -2800,7 +2508,7 @@
 
 /// @domName CSSMediaRule
 class CssMediaRule extends CssRule {
-  CssMediaRule.internal(): super.internal();
+  CssMediaRule.internal() : super.internal();
 
 
   /** @domName CSSMediaRule.cssRules */
@@ -2828,7 +2536,7 @@
 
 /// @domName CSSPageRule
 class CssPageRule extends CssRule {
-  CssPageRule.internal(): super.internal();
+  CssPageRule.internal() : super.internal();
 
 
   /** @domName CSSPageRule.selectorText */
@@ -2852,7 +2560,7 @@
 
 /// @domName CSSPrimitiveValue
 class CssPrimitiveValue extends CssValue {
-  CssPrimitiveValue.internal(): super.internal();
+  CssPrimitiveValue.internal() : super.internal();
 
   static const int CSS_ATTR = 22;
 
@@ -6240,7 +5948,7 @@
 
 /// @domName CSSStyleRule
 class CssStyleRule extends CssRule {
-  CssStyleRule.internal(): super.internal();
+  CssStyleRule.internal() : super.internal();
 
 
   /** @domName CSSStyleRule.selectorText */
@@ -6264,7 +5972,7 @@
 
 /// @domName CSSStyleSheet
 class CssStyleSheet extends StyleSheet {
-  CssStyleSheet.internal(): super.internal();
+  CssStyleSheet.internal() : super.internal();
 
 
   /** @domName CSSStyleSheet.cssRules */
@@ -6315,7 +6023,7 @@
 
 /// @domName WebKitCSSTransformValue
 class CssTransformValue extends _CssValueList {
-  CssTransformValue.internal(): super.internal();
+  CssTransformValue.internal() : super.internal();
 
   static const int CSS_MATRIX = 11;
 
@@ -6373,7 +6081,7 @@
 
 /// @domName CSSUnknownRule
 class CssUnknownRule extends CssRule {
-  CssUnknownRule.internal(): super.internal();
+  CssUnknownRule.internal() : super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6420,7 +6128,7 @@
   factory CustomEvent(String type, [bool canBubble = true, bool cancelable = true,
       Object detail]) => _CustomEventFactoryProvider.createCustomEvent(
       type, canBubble, cancelable, detail);
-  CustomEvent.internal(): super.internal();
+  CustomEvent.internal() : super.internal();
 
 
   /** @domName CustomEvent.detail */
@@ -6440,18 +6148,10 @@
 
 /// @domName HTMLDListElement
 class DListElement extends _Element_Merged {
+  DListElement.internal() : super.internal();
 
   ///@docsEditable true
   factory DListElement() => document.$dom_createElement("dl");
-  DListElement.internal(): super.internal();
-
-
-  /** @domName HTMLDListElement.compact */
-  bool get compact native "HTMLDListElement_compact_Getter";
-
-
-  /** @domName HTMLDListElement.compact */
-  void set compact(bool value) native "HTMLDListElement_compact_Setter";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6462,11 +6162,20 @@
 
 
 /// @domName HTMLDataListElement
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class DataListElement extends _Element_Merged {
+  DataListElement.internal() : super.internal();
 
   ///@docsEditable true
   factory DataListElement() => document.$dom_createElement("datalist");
-  DataListElement.internal(): super.internal();
+
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => true;
 
 
   /** @domName HTMLDataListElement.options */
@@ -6558,18 +6267,19 @@
 
 /// @domName DataView
 class DataView extends ArrayBufferView {
+  DataView.internal() : super.internal();
 
   ///@docsEditable true
   factory DataView(ArrayBuffer buffer, [int byteOffset, int byteLength]) {
     if (!?byteOffset) {
-      return _DataViewFactoryProvider.createDataView(buffer);
+      return DataView._create(buffer);
     }
     if (!?byteLength) {
-      return _DataViewFactoryProvider.createDataView(buffer, byteOffset);
+      return DataView._create(buffer, byteOffset);
     }
-    return _DataViewFactoryProvider.createDataView(buffer, byteOffset, byteLength);
+    return DataView._create(buffer, byteOffset, byteLength);
   }
-  DataView.internal(): super.internal();
+  static DataView _create(ArrayBuffer buffer, [int byteOffset, int byteLength]) native "DataView_constructor_Callback";
 
   num getFloat32(/*unsigned long*/ byteOffset, {/*boolean*/ littleEndian}) {
     if (?littleEndian) {
@@ -6851,7 +6561,7 @@
 
 /// @domName DedicatedWorkerContext
 class DedicatedWorkerContext extends WorkerContext {
-  DedicatedWorkerContext.internal(): super.internal();
+  DedicatedWorkerContext.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   DedicatedWorkerContextEvents get on =>
@@ -6879,11 +6589,19 @@
 
 
 /// @domName HTMLDetailsElement
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental()
 class DetailsElement extends _Element_Merged {
+  DetailsElement.internal() : super.internal();
 
   ///@docsEditable true
   factory DetailsElement() => document.$dom_createElement("details");
-  DetailsElement.internal(): super.internal();
+
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => true;
 
 
   /** @domName HTMLDetailsElement.open */
@@ -6903,7 +6621,7 @@
 
 /// @domName DeviceMotionEvent
 class DeviceMotionEvent extends Event {
-  DeviceMotionEvent.internal(): super.internal();
+  DeviceMotionEvent.internal() : super.internal();
 
 
   /** @domName DeviceMotionEvent.interval */
@@ -6919,7 +6637,7 @@
 
 /// @domName DeviceOrientationEvent
 class DeviceOrientationEvent extends Event {
-  DeviceOrientationEvent.internal(): super.internal();
+  DeviceOrientationEvent.internal() : super.internal();
 
 
   /** @domName DeviceOrientationEvent.absolute */
@@ -6951,7 +6669,7 @@
 
 /// @domName HTMLDirectoryElement
 class DirectoryElement extends _Element_Merged {
-  DirectoryElement.internal(): super.internal();
+  DirectoryElement.internal() : super.internal();
 
 
   /** @domName HTMLDirectoryElement.compact */
@@ -6971,7 +6689,7 @@
 
 /// @domName DirectoryEntry
 class DirectoryEntry extends Entry {
-  DirectoryEntry.internal(): super.internal();
+  DirectoryEntry.internal() : super.internal();
 
 
   /** @domName DirectoryEntry.createReader */
@@ -6999,7 +6717,7 @@
 
 /// @domName DirectoryEntrySync
 class DirectoryEntrySync extends EntrySync {
-  DirectoryEntrySync.internal(): super.internal();
+  DirectoryEntrySync.internal() : super.internal();
 
 
   /** @domName DirectoryEntrySync.createReader */
@@ -7059,10 +6777,10 @@
 
 /// @domName HTMLDivElement
 class DivElement extends _Element_Merged {
+  DivElement.internal() : super.internal();
 
   ///@docsEditable true
   factory DivElement() => document.$dom_createElement("div");
-  DivElement.internal(): super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -7083,7 +6801,7 @@
 class Document extends Node 
 {
 
-  Document.internal(): super.internal();
+  Document.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   DocumentEvents get on =>
@@ -7115,7 +6833,7 @@
 
 
   /** @domName Document.defaultView */
-  Window get window native "Document_defaultView_Getter";
+  WindowBase get window native "Document_defaultView_Getter";
 
 
   /** @domName Document.documentElement */
@@ -7227,7 +6945,7 @@
 
 
   /** @domName Document.createTouch */
-  Touch $dom_createTouch(LocalWindow window, EventTarget target, int identifier, int pageX, int pageY, int screenX, int screenY, int webkitRadiusX, int webkitRadiusY, num webkitRotationAngle, num webkitForce) native "Document_createTouch_Callback";
+  Touch $dom_createTouch(Window window, EventTarget target, int identifier, int pageX, int pageY, int screenX, int screenY, int webkitRadiusX, int webkitRadiusY, num webkitRotationAngle, num webkitForce) native "Document_createTouch_Callback";
 
 
   /** @domName Document.createTouchList */
@@ -7646,7 +7364,7 @@
       "WebKit region overflow can't be set for document fragments.");
   }
 
-  DocumentFragment.internal(): super.internal();
+  DocumentFragment.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   ElementEvents get on =>
@@ -7670,7 +7388,7 @@
 
 /// @domName DocumentType
 class DocumentType extends Node {
-  DocumentType.internal(): super.internal();
+  DocumentType.internal() : super.internal();
 
 
   /** @domName DocumentType.entities */
@@ -7988,10 +7706,11 @@
 
 /// @domName DOMParser
 class DomParser extends NativeFieldWrapperClass1 {
+  DomParser.internal();
 
   ///@docsEditable true
-  factory DomParser() => _DomParserFactoryProvider.createDomParser();
-  DomParser.internal();
+  factory DomParser() => DomParser._create();
+  static DomParser _create() native "DOMParser_constructor_Callback";
 
 
   /** @domName DOMParser.parseFromString */
@@ -8287,7 +8006,7 @@
 
 /// @domName DOMSettableTokenList
 class DomSettableTokenList extends DomTokenList {
-  DomSettableTokenList.internal(): super.internal();
+  DomSettableTokenList.internal() : super.internal();
 
 
   /** @domName DOMSettableTokenList.value */
@@ -8863,6 +8582,10 @@
    *
    * For standard elements it is more preferable to use the type constructors:
    *     var element = new DivElement();
+   *
+   * See also:
+   *
+   * * [isTagSupported]
    */
   factory Element.tag(String tag) =>
       _ElementFactoryProvider.createElement_tag(tag);
@@ -9076,6 +8799,16 @@
     this.insertAdjacentHtml('beforeend', text);
   }
 
+  /**
+   * Checks to see if the tag name is supported by the current platform.
+   *
+   * The tag should be a valid HTML tag name.
+   */
+  static bool isTagSupported(String tag) {
+    var e = _ElementFactoryProvider.createElement_tag(tag);
+    return e is Element && !(e is UnknownElement);
+  }
+
   // Hooks to support custom WebComponents.
   /**
    * Experimental support for [web components][wc]. This field stores a
@@ -9089,23 +8822,8 @@
    */
   var xtag;
 
-  noSuchMethod(InvocationMirror invocation) {
-    if (dynamicUnknownElementDispatcher == null) {
-      throw new NoSuchMethodError(this, invocation.memberName,
-                                        invocation.positionalArguments,
-                                        invocation.namedArguments);
-    } else {
-      String hackedName = invocation.memberName;
-      if (invocation.isGetter) hackedName = "get:$hackedName";
-      if (invocation.isSetter) hackedName = "set:$hackedName";
-      return dynamicUnknownElementDispatcher(this,
-                                             hackedName,
-                                             invocation.positionalArguments);
-    }
-  }
 
-
-  Element.internal(): super.internal();
+  Element.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   ElementEvents get on =>
@@ -9271,6 +8989,18 @@
   String get tagName native "Element_tagName_Getter";
 
 
+  /** @domName Element.webkitPseudo */
+  String get webkitPseudo native "Element_webkitPseudo_Getter";
+
+
+  /** @domName Element.webkitPseudo */
+  void set webkitPseudo(String value) native "Element_webkitPseudo_Setter";
+
+
+  /** @domName Element.webkitShadowRoot */
+  ShadowRoot get webkitShadowRoot native "Element_webkitShadowRoot_Getter";
+
+
   /** @domName Element.blur */
   void blur() native "Element_blur_Callback";
 
@@ -9363,6 +9093,12 @@
   void $dom_setAttributeNS(String namespaceURI, String qualifiedName, String value) native "Element_setAttributeNS_Callback";
 
 
+  /** @domName Element.webkitCreateShadowRoot */
+  @SupportedBrowser(SupportedBrowser.CHROME, '25')
+  @Experimental()
+  ShadowRoot createShadowRoot() native "Element_webkitCreateShadowRoot_Callback";
+
+
   /** @domName Element.webkitMatchesSelector */
   bool matchesSelector(String selectors) native "Element_webkitMatchesSelector_Callback";
 
@@ -9380,9 +9116,6 @@
 
 }
 
-// Temporary dispatch hook to support WebComponents.
-Function dynamicUnknownElementDispatcher;
-
 final _START_TAG_REGEXP = new RegExp('<(\\w+)');
 class _ElementFactoryProvider {
   static final _CUSTOM_PARENT_TAG_MAP = const {
@@ -9629,11 +9362,19 @@
 
 
 /// @domName HTMLEmbedElement
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.IE)
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class EmbedElement extends _Element_Merged {
+  EmbedElement.internal() : super.internal();
 
   ///@docsEditable true
   factory EmbedElement() => document.$dom_createElement("embed");
-  EmbedElement.internal(): super.internal();
+
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => true;
 
 
   /** @domName HTMLEmbedElement.align */
@@ -9693,7 +9434,7 @@
 
 /// @domName EntityReference
 class EntityReference extends Node {
-  EntityReference.internal(): super.internal();
+  EntityReference.internal() : super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -9865,7 +9606,7 @@
 
 /// @domName ErrorEvent
 class ErrorEvent extends Event {
-  ErrorEvent.internal(): super.internal();
+  ErrorEvent.internal() : super.internal();
 
 
   /** @domName ErrorEvent.filename */
@@ -10049,10 +9790,11 @@
 
 /// @domName EventSource
 class EventSource extends EventTarget {
+  EventSource.internal() : super.internal();
 
   ///@docsEditable true
-  factory EventSource(String scriptUrl) => _EventSourceFactoryProvider.createEventSource(scriptUrl);
-  EventSource.internal(): super.internal();
+  factory EventSource(String scriptUrl) => EventSource._create(scriptUrl);
+  static EventSource _create(String scriptUrl) native "EventSource_constructor_Callback";
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   EventSourceEvents get on =>
@@ -10223,10 +9965,10 @@
 
 /// @domName HTMLFieldSetElement
 class FieldSetElement extends _Element_Merged {
+  FieldSetElement.internal() : super.internal();
 
   ///@docsEditable true
   factory FieldSetElement() => document.$dom_createElement("fieldset");
-  FieldSetElement.internal(): super.internal();
 
 
   /** @domName HTMLFieldSetElement.disabled */
@@ -10286,7 +10028,7 @@
 
 /// @domName File
 class File extends Blob {
-  File.internal(): super.internal();
+  File.internal() : super.internal();
 
 
   /** @domName File.lastModifiedDate */
@@ -10318,7 +10060,7 @@
 
 /// @domName FileEntry
 class FileEntry extends Entry {
-  FileEntry.internal(): super.internal();
+  FileEntry.internal() : super.internal();
 
 
   /** @domName FileEntry.createWriter */
@@ -10338,7 +10080,7 @@
 
 /// @domName FileEntrySync
 class FileEntrySync extends EntrySync {
-  FileEntrySync.internal(): super.internal();
+  FileEntrySync.internal() : super.internal();
 
 
   /** @domName FileEntrySync.createWriter */
@@ -10570,10 +10312,11 @@
 
 /// @domName FileReader
 class FileReader extends EventTarget {
+  FileReader.internal() : super.internal();
 
   ///@docsEditable true
-  factory FileReader() => _FileReaderFactoryProvider.createFileReader();
-  FileReader.internal(): super.internal();
+  factory FileReader() => FileReader._create();
+  static FileReader _create() native "FileReader_constructor_Callback";
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   FileReaderEvents get on =>
@@ -10675,10 +10418,11 @@
 
 /// @domName FileReaderSync
 class FileReaderSync extends NativeFieldWrapperClass1 {
+  FileReaderSync.internal();
 
   ///@docsEditable true
-  factory FileReaderSync() => _FileReaderSyncFactoryProvider.createFileReaderSync();
-  FileReaderSync.internal();
+  factory FileReaderSync() => FileReaderSync._create();
+  static FileReaderSync _create() native "FileReaderSync_constructor_Callback";
 
 
   /** @domName FileReaderSync.readAsArrayBuffer */
@@ -10765,7 +10509,7 @@
 
 /// @domName FileWriter
 class FileWriter extends EventTarget {
-  FileWriter.internal(): super.internal();
+  FileWriter.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   FileWriterEvents get on =>
@@ -10895,6 +10639,7 @@
 
 /// @domName Float32Array
 class Float32Array extends ArrayBufferView implements List<num> {
+  Float32Array.internal() : super.internal();
 
   factory Float32Array(int length) =>
     _TypedArrayFactoryProvider.createFloat32Array(length);
@@ -10904,7 +10649,6 @@
 
   factory Float32Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createFloat32Array_fromBuffer(buffer, byteOffset, length);
-  Float32Array.internal(): super.internal();
 
   static const int BYTES_PER_ELEMENT = 4;
 
@@ -11043,6 +10787,7 @@
 
 /// @domName Float64Array
 class Float64Array extends ArrayBufferView implements List<num> {
+  Float64Array.internal() : super.internal();
 
   factory Float64Array(int length) =>
     _TypedArrayFactoryProvider.createFloat64Array(length);
@@ -11052,7 +10797,6 @@
 
   factory Float64Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createFloat64Array_fromBuffer(buffer, byteOffset, length);
-  Float64Array.internal(): super.internal();
 
   static const int BYTES_PER_ELEMENT = 8;
 
@@ -11191,7 +10935,7 @@
 
 /// @domName HTMLFontElement
 class FontElement extends _Element_Merged {
-  FontElement.internal(): super.internal();
+  FontElement.internal() : super.internal();
 
 
   /** @domName HTMLFontElement.color */
@@ -11227,15 +10971,16 @@
 
 /// @domName FormData
 class FormData extends NativeFieldWrapperClass1 {
+  FormData.internal();
 
   ///@docsEditable true
   factory FormData([FormElement form]) {
     if (!?form) {
-      return _FormDataFactoryProvider.createFormData();
+      return FormData._create();
     }
-    return _FormDataFactoryProvider.createFormData(form);
+    return FormData._create(form);
   }
-  FormData.internal();
+  static FormData _create([FormElement form]) native "DOMFormData_constructor_Callback";
 
 
   /** @domName DOMFormData.append */
@@ -11251,10 +10996,10 @@
 
 /// @domName HTMLFormElement
 class FormElement extends _Element_Merged {
+  FormElement.internal() : super.internal();
 
   ///@docsEditable true
   factory FormElement() => document.$dom_createElement("form");
-  FormElement.internal(): super.internal();
 
 
   /** @domName HTMLFormElement.acceptCharset */
@@ -11354,11 +11099,11 @@
 
 /// @domName HTMLFrameElement
 class FrameElement extends _Element_Merged {
-  FrameElement.internal(): super.internal();
+  FrameElement.internal() : super.internal();
 
 
   /** @domName HTMLFrameElement.contentWindow */
-  Window get contentWindow native "HTMLFrameElement_contentWindow_Getter";
+  WindowBase get contentWindow native "HTMLFrameElement_contentWindow_Getter";
 
 
   /** @domName HTMLFrameElement.frameBorder */
@@ -11450,7 +11195,7 @@
 
 /// @domName HTMLFrameSetElement
 class FrameSetElement extends _Element_Merged {
-  FrameSetElement.internal(): super.internal();
+  FrameSetElement.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   FrameSetElementEvents get on =>
@@ -11603,42 +11348,10 @@
 
 /// @domName HTMLHRElement
 class HRElement extends _Element_Merged {
+  HRElement.internal() : super.internal();
 
   ///@docsEditable true
   factory HRElement() => document.$dom_createElement("hr");
-  HRElement.internal(): super.internal();
-
-
-  /** @domName HTMLHRElement.align */
-  String get align native "HTMLHRElement_align_Getter";
-
-
-  /** @domName HTMLHRElement.align */
-  void set align(String value) native "HTMLHRElement_align_Setter";
-
-
-  /** @domName HTMLHRElement.noShade */
-  bool get noShade native "HTMLHRElement_noShade_Getter";
-
-
-  /** @domName HTMLHRElement.noShade */
-  void set noShade(bool value) native "HTMLHRElement_noShade_Setter";
-
-
-  /** @domName HTMLHRElement.size */
-  String get size native "HTMLHRElement_size_Getter";
-
-
-  /** @domName HTMLHRElement.size */
-  void set size(String value) native "HTMLHRElement_size_Setter";
-
-
-  /** @domName HTMLHRElement.width */
-  String get width native "HTMLHRElement_width_Getter";
-
-
-  /** @domName HTMLHRElement.width */
-  void set width(String value) native "HTMLHRElement_width_Setter";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -11650,7 +11363,7 @@
 
 /// @domName HashChangeEvent
 class HashChangeEvent extends Event {
-  HashChangeEvent.internal(): super.internal();
+  HashChangeEvent.internal() : super.internal();
 
 
   /** @domName HashChangeEvent.newURL */
@@ -11674,18 +11387,10 @@
 
 /// @domName HTMLHeadElement
 class HeadElement extends _Element_Merged {
+  HeadElement.internal() : super.internal();
 
   ///@docsEditable true
   factory HeadElement() => document.$dom_createElement("head");
-  HeadElement.internal(): super.internal();
-
-
-  /** @domName HTMLHeadElement.profile */
-  String get profile native "HTMLHeadElement_profile_Getter";
-
-
-  /** @domName HTMLHeadElement.profile */
-  void set profile(String value) native "HTMLHeadElement_profile_Setter";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -11697,6 +11402,7 @@
 
 /// @domName HTMLHeadingElement
 class HeadingElement extends _Element_Merged {
+  HeadingElement.internal() : super.internal();
 
   ///@docsEditable true
   factory HeadingElement.h1() => document.$dom_createElement("h1");
@@ -11715,16 +11421,63 @@
 
   ///@docsEditable true
   factory HeadingElement.h6() => document.$dom_createElement("h6");
-  HeadingElement.internal(): super.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.
 
 
-  /** @domName HTMLHeadingElement.align */
-  String get align native "HTMLHeadingElement_align_Getter";
+/// @domName History; @docsEditable true
+class History extends NativeFieldWrapperClass1 implements HistoryBase {
+
+  /**
+   * Checks if the State APIs are supported on the current platform.
+   *
+   * See also:
+   *
+   * * [pushState]
+   * * [replaceState]
+   * * [state]
+   */
+  static bool get supportsState => true;
+  History.internal();
 
 
-  /** @domName HTMLHeadingElement.align */
-  void set align(String value) native "HTMLHeadingElement_align_Setter";
+  /** @domName History.length */
+  int get length native "History_length_Getter";
 
+
+  /** @domName History.state */
+  dynamic get state native "History_state_Getter";
+
+
+  /** @domName History.back */
+  void back() native "History_back_Callback";
+
+
+  /** @domName History.forward */
+  void forward() native "History_forward_Callback";
+
+
+  /** @domName History.go */
+  void go(int distance) native "History_go_Callback";
+
+
+  /** @domName History.pushState */
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  void pushState(Object data, String title, [String url]) native "History_pushState_Callback";
+
+
+  /** @domName History.replaceState */
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  void replaceState(Object data, String title, [String url]) native "History_replaceState_Callback";
 }
 // 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
@@ -11987,7 +11740,7 @@
 
 /// @domName HTMLDocument
 class HtmlDocument extends Document {
-  HtmlDocument.internal(): super.internal();
+  HtmlDocument.internal() : super.internal();
 
 
   /** @domName HTMLDocument.activeElement */
@@ -12089,10 +11842,26 @@
 
 /// @domName HTMLHtmlElement
 class HtmlElement extends _Element_Merged {
+  HtmlElement.internal() : super.internal();
 
   ///@docsEditable true
   factory HtmlElement() => document.$dom_createElement("html");
-  HtmlElement.internal(): super.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.
+
+
+/// @domName HTMLFormControlsCollection
+class HtmlFormControlsCollection extends HtmlCollection {
+  HtmlFormControlsCollection.internal() : super.internal();
+
+
+  /** @domName HTMLFormControlsCollection.namedItem */
+  Node namedItem(String name) native "HTMLFormControlsCollection_namedItem_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -12104,7 +11873,7 @@
 
 /// @domName HTMLOptionsCollection
 class HtmlOptionsCollection extends HtmlCollection {
-  HtmlOptionsCollection.internal(): super.internal();
+  HtmlOptionsCollection.internal() : super.internal();
 
 
   /** @domName HTMLOptionsCollection.length */
@@ -12127,6 +11896,10 @@
   void operator[]=(int index, Node value) native "HTMLOptionsCollection_numericIndexSetter_Callback";
 
 
+  /** @domName HTMLOptionsCollection.namedItem */
+  Node namedItem(String name) native "HTMLOptionsCollection_namedItem_Callback";
+
+
   /** @domName HTMLOptionsCollection.remove */
   void remove(int index) native "HTMLOptionsCollection_remove_Callback";
 
@@ -12170,27 +11943,35 @@
    * [onComplete] callback.
    */
   factory HttpRequest.get(String url, onComplete(HttpRequest request)) =>
-      _HttpRequestFactoryProvider.createHttpRequest_get(url, onComplete);
+      _HttpRequestUtils.get(url, onComplete, false);
 
+  // 80 char issue for comments in lists: dartbug.com/7588.
   /**
    * Creates a URL GET request for the specified `url` with
    * credentials such a cookie (already) set in the header or
-   * (authorization headers)[http://tools.ietf.org/html/rfc1945#section-10.2].
+   * [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2).
    * 
    * After completing the request, the object will call the user-provided 
    * [onComplete] callback.
+   *
+   * A few other details to keep in mind when using credentials:
+   *
+   * * Using credentials is only useful for cross-origin requests.
+   * * The `Access-Control-Allow-Origin` header of `url` cannot contain a wildcard (*).
+   * * The `Access-Control-Allow-Credentials` header of `url` must be set to true.
+   * * If `Access-Control-Expose-Headers` has not been set to true, only a subset of all the response headers will be returned when calling [getAllRequestHeaders].
    * 
-   * See also: (authorization headers)[http://en.wikipedia.org/wiki/Basic_access_authentication].
+   * See also: [authorization headers](http://en.wikipedia.org/wiki/Basic_access_authentication).
    */
   factory HttpRequest.getWithCredentials(String url,
       onComplete(HttpRequest request)) =>
-      _HttpRequestFactoryProvider.createHttpRequest_getWithCredentials(url,
-      onComplete);
+      _HttpRequestUtils.get(url, onComplete, true);
 
+  HttpRequest.internal() : super.internal();
 
   ///@docsEditable true
-  factory HttpRequest() => _HttpRequestFactoryProvider.createHttpRequest();
-  HttpRequest.internal(): super.internal();
+  factory HttpRequest() => HttpRequest._create();
+  static HttpRequest _create() native "XMLHttpRequest_constructor_Callback";
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   HttpRequestEvents get on =>
@@ -12359,7 +12140,7 @@
 
 /// @domName XMLHttpRequestProgressEvent
 class HttpRequestProgressEvent extends ProgressEvent {
-  HttpRequestProgressEvent.internal(): super.internal();
+  HttpRequestProgressEvent.internal() : super.internal();
 
 
   /** @domName XMLHttpRequestProgressEvent.position */
@@ -12379,7 +12160,7 @@
 
 /// @domName XMLHttpRequestUpload
 class HttpRequestUpload extends EventTarget {
-  HttpRequestUpload.internal(): super.internal();
+  HttpRequestUpload.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   HttpRequestUploadEvents get on =>
@@ -12431,30 +12212,14 @@
 
 /// @domName HTMLIFrameElement
 class IFrameElement extends _Element_Merged {
+  IFrameElement.internal() : super.internal();
 
   ///@docsEditable true
   factory IFrameElement() => document.$dom_createElement("iframe");
-  IFrameElement.internal(): super.internal();
-
-
-  /** @domName HTMLIFrameElement.align */
-  String get align native "HTMLIFrameElement_align_Getter";
-
-
-  /** @domName HTMLIFrameElement.align */
-  void set align(String value) native "HTMLIFrameElement_align_Setter";
 
 
   /** @domName HTMLIFrameElement.contentWindow */
-  Window get contentWindow native "HTMLIFrameElement_contentWindow_Getter";
-
-
-  /** @domName HTMLIFrameElement.frameBorder */
-  String get frameBorder native "HTMLIFrameElement_frameBorder_Getter";
-
-
-  /** @domName HTMLIFrameElement.frameBorder */
-  void set frameBorder(String value) native "HTMLIFrameElement_frameBorder_Setter";
+  WindowBase get contentWindow native "HTMLIFrameElement_contentWindow_Getter";
 
 
   /** @domName HTMLIFrameElement.height */
@@ -12465,30 +12230,6 @@
   void set height(String value) native "HTMLIFrameElement_height_Setter";
 
 
-  /** @domName HTMLIFrameElement.longDesc */
-  String get longDesc native "HTMLIFrameElement_longDesc_Getter";
-
-
-  /** @domName HTMLIFrameElement.longDesc */
-  void set longDesc(String value) native "HTMLIFrameElement_longDesc_Setter";
-
-
-  /** @domName HTMLIFrameElement.marginHeight */
-  String get marginHeight native "HTMLIFrameElement_marginHeight_Getter";
-
-
-  /** @domName HTMLIFrameElement.marginHeight */
-  void set marginHeight(String value) native "HTMLIFrameElement_marginHeight_Setter";
-
-
-  /** @domName HTMLIFrameElement.marginWidth */
-  String get marginWidth native "HTMLIFrameElement_marginWidth_Getter";
-
-
-  /** @domName HTMLIFrameElement.marginWidth */
-  void set marginWidth(String value) native "HTMLIFrameElement_marginWidth_Setter";
-
-
   /** @domName HTMLIFrameElement.name */
   String get name native "HTMLIFrameElement_name_Getter";
 
@@ -12505,14 +12246,6 @@
   void set sandbox(String value) native "HTMLIFrameElement_sandbox_Setter";
 
 
-  /** @domName HTMLIFrameElement.scrolling */
-  String get scrolling native "HTMLIFrameElement_scrolling_Getter";
-
-
-  /** @domName HTMLIFrameElement.scrolling */
-  void set scrolling(String value) native "HTMLIFrameElement_scrolling_Setter";
-
-
   /** @domName HTMLIFrameElement.src */
   String get src native "HTMLIFrameElement_src_Getter";
 
@@ -12544,37 +12277,6 @@
 // WARNING: Do not edit - generated code.
 
 
-typedef void IceCallback(IceCandidate candidate, bool moreToFollow, PeerConnection00 source);
-// 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.
-
-
-/// @domName IceCandidate
-class IceCandidate extends NativeFieldWrapperClass1 {
-
-  ///@docsEditable true
-  factory IceCandidate(String label, String candidateLine) => _IceCandidateFactoryProvider.createIceCandidate(label, candidateLine);
-  IceCandidate.internal();
-
-
-  /** @domName IceCandidate.label */
-  String get label native "IceCandidate_label_Getter";
-
-
-  /** @domName IceCandidate.toSdp */
-  String toSdp() native "IceCandidate_toSdp_Callback";
-
-}
-// 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.
-
-
 /// @domName ImageData
 class ImageData extends NativeFieldWrapperClass1 {
   ImageData.internal();
@@ -12601,6 +12303,7 @@
 
 /// @domName HTMLImageElement
 class ImageElement extends _Element_Merged {
+  ImageElement.internal() : super.internal();
 
   ///@docsEditable true
   factory ImageElement({String src, int width, int height}) {
@@ -12610,15 +12313,6 @@
     if (height != null) e.height = height;
     return e;
   }
-  ImageElement.internal(): super.internal();
-
-
-  /** @domName HTMLImageElement.align */
-  String get align native "HTMLImageElement_align_Getter";
-
-
-  /** @domName HTMLImageElement.align */
-  void set align(String value) native "HTMLImageElement_align_Setter";
 
 
   /** @domName HTMLImageElement.alt */
@@ -12657,14 +12351,6 @@
   void set height(int value) native "HTMLImageElement_height_Setter";
 
 
-  /** @domName HTMLImageElement.hspace */
-  int get hspace native "HTMLImageElement_hspace_Getter";
-
-
-  /** @domName HTMLImageElement.hspace */
-  void set hspace(int value) native "HTMLImageElement_hspace_Setter";
-
-
   /** @domName HTMLImageElement.isMap */
   bool get isMap native "HTMLImageElement_isMap_Getter";
 
@@ -12673,14 +12359,6 @@
   void set isMap(bool value) native "HTMLImageElement_isMap_Setter";
 
 
-  /** @domName HTMLImageElement.longDesc */
-  String get longDesc native "HTMLImageElement_longDesc_Getter";
-
-
-  /** @domName HTMLImageElement.longDesc */
-  void set longDesc(String value) native "HTMLImageElement_longDesc_Setter";
-
-
   /** @domName HTMLImageElement.lowsrc */
   String get lowsrc native "HTMLImageElement_lowsrc_Getter";
 
@@ -12689,14 +12367,6 @@
   void set lowsrc(String value) native "HTMLImageElement_lowsrc_Setter";
 
 
-  /** @domName HTMLImageElement.name */
-  String get name native "HTMLImageElement_name_Getter";
-
-
-  /** @domName HTMLImageElement.name */
-  void set name(String value) native "HTMLImageElement_name_Setter";
-
-
   /** @domName HTMLImageElement.naturalHeight */
   int get naturalHeight native "HTMLImageElement_naturalHeight_Getter";
 
@@ -12721,14 +12391,6 @@
   void set useMap(String value) native "HTMLImageElement_useMap_Setter";
 
 
-  /** @domName HTMLImageElement.vspace */
-  int get vspace native "HTMLImageElement_vspace_Getter";
-
-
-  /** @domName HTMLImageElement.vspace */
-  void set vspace(int value) native "HTMLImageElement_vspace_Setter";
-
-
   /** @domName HTMLImageElement.width */
   int get width native "HTMLImageElement_width_Getter";
 
@@ -12779,10 +12441,15 @@
   ///@docsEditable true
   factory InputElement({String type}) {
     var e = document.$dom_createElement("input");
-    if (type != null) e.type = type;
+    if (type != null) {
+      try {
+        // IE throws an exception for unknown types.
+        e.type = type;
+      } catch(_) {}
+    }
     return e;
   }
-  InputElement.internal(): super.internal();
+  InputElement.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   InputElementEvents get on =>
@@ -12797,14 +12464,6 @@
   void set accept(String value) native "HTMLInputElement_accept_Setter";
 
 
-  /** @domName HTMLInputElement.align */
-  String get align native "HTMLInputElement_align_Getter";
-
-
-  /** @domName HTMLInputElement.align */
-  void set align(String value) native "HTMLInputElement_align_Setter";
-
-
   /** @domName HTMLInputElement.alt */
   String get alt native "HTMLInputElement_alt_Getter";
 
@@ -13328,7 +12987,13 @@
 /**
  * Similar to [TextInputElement], but on platforms where search is styled
  * differently this will get the search style.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 abstract class SearchInputElement implements TextInputElementBase {
   factory SearchInputElement() => new InputElement(type: 'search');
 
@@ -13337,6 +13002,11 @@
 
   /// @domName HTMLInputElement.list;
   Element get list;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'search')).type == 'search';
+  }
 }
 
 /**
@@ -13354,12 +13024,23 @@
 
 /**
  * A control for editing an absolute URL.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 abstract class UrlInputElement implements TextInputElementBase {
   factory UrlInputElement() => new InputElement(type: 'url');
 
   /// @domName HTMLInputElement.list;
   Element get list;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'url')).type == 'url';
+  }
 }
 
 /**
@@ -13367,17 +13048,34 @@
  *
  * This provides a single line of text with minimal formatting help since
  * there is a wide variety of telephone numbers.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 abstract class TelephoneInputElement implements TextInputElementBase {
   factory TelephoneInputElement() => new InputElement(type: 'tel');
 
   /// @domName HTMLInputElement.list;
   Element get list;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'tel')).type == 'tel';
+  }
 }
 
 /**
  * An e-mail address or list of e-mail addresses.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 abstract class EmailInputElement implements TextInputElementBase {
   factory EmailInputElement() => new InputElement(type: 'email');
 
@@ -13410,6 +13108,11 @@
 
   /// @domName HTMLInputElement.size
   int size;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'email')).type == 'email';
+  }
 }
 
 /**
@@ -13449,7 +13152,11 @@
 /**
  * A date and time (year, month, day, hour, minute, second, fraction of a
  * second) with the time zone set to UTC.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Experimental()
 abstract class DateTimeInputElement implements RangeInputElementBase {
   factory DateTimeInputElement() => new InputElement(type: 'datetime');
 
@@ -13461,11 +13168,20 @@
 
   /// @domName HTMLInputElement.required
   bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'datetime')).type == 'datetime';
+  }
 }
 
 /**
  * A date (year, month, day) with no time zone.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Experimental()
 abstract class DateInputElement implements RangeInputElementBase {
   factory DateInputElement() => new InputElement(type: 'date');
 
@@ -13477,11 +13193,20 @@
 
   /// @domName HTMLInputElement.required
   bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'date')).type == 'date';
+  }
 }
 
 /**
  * A date consisting of a year and a month with no time zone.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Experimental()
 abstract class MonthInputElement implements RangeInputElementBase {
   factory MonthInputElement() => new InputElement(type: 'month');
 
@@ -13493,11 +13218,20 @@
 
   /// @domName HTMLInputElement.required
   bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'month')).type == 'month';
+  }
 }
 
 /**
  * A date consisting of a week-year number and a week number with no time zone.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Experimental()
 abstract class WeekInputElement implements RangeInputElementBase {
   factory WeekInputElement() => new InputElement(type: 'week');
 
@@ -13509,11 +13243,20 @@
 
   /// @domName HTMLInputElement.required
   bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'week')).type == 'week';
+  }
 }
 
 /**
  * A time (hour, minute, seconds, fractional seconds) with no time zone.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@Experimental()
 abstract class TimeInputElement implements RangeInputElementBase {
   factory TimeInputElement() => new InputElement(type: 'time');
 
@@ -13525,12 +13268,21 @@
 
   /// @domName HTMLInputElement.required
   bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'time')).type == 'time';
+  }
 }
 
 /**
  * A date and time (year, month, day, hour, minute, second, fraction of a
  * second) with no time zone.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Experimental()
 abstract class LocalDateTimeInputElement implements RangeInputElementBase {
   factory LocalDateTimeInputElement() =>
       new InputElement(type: 'datetime-local');
@@ -13540,11 +13292,20 @@
 
   /// @domName HTMLInputElement.required
   bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'datetime-local')).type == 'datetime-local';
+  }
 }
 
 /**
  * A numeric editor control.
  */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.IE)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental()
 abstract class NumberInputElement implements RangeInputElementBase {
   factory NumberInputElement() => new InputElement(type: 'number');
 
@@ -13556,14 +13317,29 @@
 
   /// @domName HTMLInputElement.required
   bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'number')).type == 'number';
+  }
 }
 
 /**
  * Similar to [NumberInputElement] but the browser may provide more optimal
  * styling (such as a slider control).
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@Experimental()
 abstract class RangeInputElement implements RangeInputElementBase {
   factory RangeInputElement() => new InputElement(type: 'range');
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'range')).type == 'range';
+  }
 }
 
 /**
@@ -13712,6 +13488,7 @@
 
 /// @domName Int16Array
 class Int16Array extends ArrayBufferView implements List<int> {
+  Int16Array.internal() : super.internal();
 
   factory Int16Array(int length) =>
     _TypedArrayFactoryProvider.createInt16Array(length);
@@ -13721,7 +13498,6 @@
 
   factory Int16Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createInt16Array_fromBuffer(buffer, byteOffset, length);
-  Int16Array.internal(): super.internal();
 
   static const int BYTES_PER_ELEMENT = 2;
 
@@ -13860,6 +13636,7 @@
 
 /// @domName Int32Array
 class Int32Array extends ArrayBufferView implements List<int> {
+  Int32Array.internal() : super.internal();
 
   factory Int32Array(int length) =>
     _TypedArrayFactoryProvider.createInt32Array(length);
@@ -13869,7 +13646,6 @@
 
   factory Int32Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createInt32Array_fromBuffer(buffer, byteOffset, length);
-  Int32Array.internal(): super.internal();
 
   static const int BYTES_PER_ELEMENT = 4;
 
@@ -14008,6 +13784,7 @@
 
 /// @domName Int8Array
 class Int8Array extends ArrayBufferView implements List<int> {
+  Int8Array.internal() : super.internal();
 
   factory Int8Array(int length) =>
     _TypedArrayFactoryProvider.createInt8Array(length);
@@ -14017,7 +13794,6 @@
 
   factory Int8Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createInt8Array_fromBuffer(buffer, byteOffset, length);
-  Int8Array.internal(): super.internal();
 
   static const int BYTES_PER_ELEMENT = 1;
 
@@ -14237,7 +14013,7 @@
   
   /** @domName KeyboardEvent.charCode */
   int get charCode => $dom_charCode;
-  KeyboardEvent.internal(): super.internal();
+  KeyboardEvent.internal() : super.internal();
 
 
   /** @domName KeyboardEvent.altGraphKey */
@@ -14269,7 +14045,7 @@
 
 
   /** @domName KeyboardEvent.initKeyboardEvent */
-  void $dom_initKeyboardEvent(String type, bool canBubble, bool cancelable, LocalWindow view, String keyIdentifier, int keyLocation, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool altGraphKey) native "KeyboardEvent_initKeyboardEvent_Callback";
+  void $dom_initKeyboardEvent(String type, bool canBubble, bool cancelable, Window view, String keyIdentifier, int keyLocation, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool altGraphKey) native "KeyboardEvent_initKeyboardEvent_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -14280,11 +14056,19 @@
 
 
 /// @domName HTMLKeygenElement
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental()
 class KeygenElement extends _Element_Merged {
+  KeygenElement.internal() : super.internal();
 
   ///@docsEditable true
   factory KeygenElement() => document.$dom_createElement("keygen");
-  KeygenElement.internal(): super.internal();
+
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => true;
 
 
   /** @domName HTMLKeygenElement.autofocus */
@@ -14368,10 +14152,10 @@
 
 /// @domName HTMLLIElement
 class LIElement extends _Element_Merged {
+  LIElement.internal() : super.internal();
 
   ///@docsEditable true
   factory LIElement() => document.$dom_createElement("li");
-  LIElement.internal(): super.internal();
 
 
   /** @domName HTMLLIElement.type */
@@ -14399,10 +14183,10 @@
 
 /// @domName HTMLLabelElement
 class LabelElement extends _Element_Merged {
+  LabelElement.internal() : super.internal();
 
   ///@docsEditable true
   factory LabelElement() => document.$dom_createElement("label");
-  LabelElement.internal(): super.internal();
 
 
   /** @domName HTMLLabelElement.control */
@@ -14430,10 +14214,10 @@
 
 /// @domName HTMLLegendElement
 class LegendElement extends _Element_Merged {
+  LegendElement.internal() : super.internal();
 
   ///@docsEditable true
   factory LegendElement() => document.$dom_createElement("legend");
-  LegendElement.internal(): super.internal();
 
 
   /** @domName HTMLLegendElement.align */
@@ -14457,18 +14241,10 @@
 
 /// @domName HTMLLinkElement
 class LinkElement extends _Element_Merged {
+  LinkElement.internal() : super.internal();
 
   ///@docsEditable true
   factory LinkElement() => document.$dom_createElement("link");
-  LinkElement.internal(): super.internal();
-
-
-  /** @domName HTMLLinkElement.charset */
-  String get charset native "HTMLLinkElement_charset_Getter";
-
-
-  /** @domName HTMLLinkElement.charset */
-  void set charset(String value) native "HTMLLinkElement_charset_Setter";
 
 
   /** @domName HTMLLinkElement.disabled */
@@ -14511,14 +14287,6 @@
   void set rel(String value) native "HTMLLinkElement_rel_Setter";
 
 
-  /** @domName HTMLLinkElement.rev */
-  String get rev native "HTMLLinkElement_rev_Getter";
-
-
-  /** @domName HTMLLinkElement.rev */
-  void set rev(String value) native "HTMLLinkElement_rev_Setter";
-
-
   /** @domName HTMLLinkElement.sheet */
   StyleSheet get sheet native "HTMLLinkElement_sheet_Getter";
 
@@ -14531,14 +14299,6 @@
   void set sizes(DomSettableTokenList value) native "HTMLLinkElement_sizes_Setter";
 
 
-  /** @domName HTMLLinkElement.target */
-  String get target native "HTMLLinkElement_target_Getter";
-
-
-  /** @domName HTMLLinkElement.target */
-  void set target(String value) native "HTMLLinkElement_target_Setter";
-
-
   /** @domName HTMLLinkElement.type */
   String get type native "HTMLLinkElement_type_Getter";
 
@@ -14554,37 +14314,13 @@
 // WARNING: Do not edit - generated code.
 
 
-/// @domName History
-class LocalHistory extends NativeFieldWrapperClass1 implements History {
-  LocalHistory.internal();
+/// @domName LocalMediaStream
+class LocalMediaStream extends MediaStream implements EventTarget {
+  LocalMediaStream.internal() : super.internal();
 
 
-  /** @domName History.length */
-  int get length native "History_length_Getter";
-
-
-  /** @domName History.state */
-  dynamic get state native "History_state_Getter";
-
-
-  /** @domName History.back */
-  void back() native "History_back_Callback";
-
-
-  /** @domName History.forward */
-  void forward() native "History_forward_Callback";
-
-
-  /** @domName History.go */
-  void go(int distance) native "History_go_Callback";
-
-
-  /** @domName History.pushState */
-  void pushState(Object data, String title, [String url]) native "History_pushState_Callback";
-
-
-  /** @domName History.replaceState */
-  void replaceState(Object data, String title, [String url]) native "History_replaceState_Callback";
+  /** @domName LocalMediaStream.stop */
+  void stop() native "LocalMediaStream_stop_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -14595,8 +14331,8 @@
 
 
 /// @domName Location
-class LocalLocation extends NativeFieldWrapperClass1 implements Location {
-  LocalLocation.internal();
+class Location extends NativeFieldWrapperClass1 implements LocationBase {
+  Location.internal();
 
 
   /** @domName Location.ancestorOrigins */
@@ -14694,668 +14430,12 @@
 // WARNING: Do not edit - generated code.
 
 
-/// @domName LocalMediaStream
-class LocalMediaStream extends MediaStream implements EventTarget {
-  LocalMediaStream.internal(): super.internal();
-
-
-  /** @domName LocalMediaStream.stop */
-  void stop() native "LocalMediaStream_stop_Callback";
-
-}
-// 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.
-
-
-/// @domName Window
-class LocalWindow extends EventTarget implements Window {
-
-  /**
-   * Executes a [callback] after the next batch of browser layout measurements
-   * has completed or would have completed if any browser layout measurements
-   * had been scheduled.
-   */
-  void requestLayoutFrame(TimeoutHandler callback) {
-    _addMeasurementFrameCallback(callback);
-  }
-
-  /**
-   * Lookup a port by its [name].  Return null if no port is
-   * registered under [name].
-   */
-  lookupPort(String name) {
-    var port = JSON.parse(document.documentElement.attributes['dart-port:$name']);
-    return _deserialize(port);
-  }
-
-  /**
-   * Register a [port] on this window under the given [name].  This
-   * port may be retrieved by any isolate (or JavaScript script)
-   * running in this window.
-   */
-  registerPort(String name, var port) {
-    var serialized = _serialize(port);
-    document.documentElement.attributes['dart-port:$name'] = JSON.stringify(serialized);
-  }
-
-  LocalWindow.internal(): super.internal();
-
-  /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
-  LocalWindowEvents get on =>
-    new LocalWindowEvents(this);
-
-  static const int PERSISTENT = 1;
-
-  static const int TEMPORARY = 0;
-
-
-  /** @domName DOMWindow.applicationCache */
-  ApplicationCache get applicationCache native "DOMWindow_applicationCache_Getter";
-
-
-  /** @domName DOMWindow.closed */
-  bool get closed native "DOMWindow_closed_Getter";
-
-
-  /** @domName DOMWindow.console */
-  Console get console native "DOMWindow_console_Getter";
-
-
-  /** @domName DOMWindow.crypto */
-  Crypto get crypto native "DOMWindow_crypto_Getter";
-
-
-  /** @domName DOMWindow.defaultStatus */
-  String get defaultStatus native "DOMWindow_defaultStatus_Getter";
-
-
-  /** @domName DOMWindow.defaultStatus */
-  void set defaultStatus(String value) native "DOMWindow_defaultStatus_Setter";
-
-
-  /** @domName DOMWindow.defaultstatus */
-  String get defaultstatus native "DOMWindow_defaultstatus_Getter";
-
-
-  /** @domName DOMWindow.defaultstatus */
-  void set defaultstatus(String value) native "DOMWindow_defaultstatus_Setter";
-
-
-  /** @domName DOMWindow.devicePixelRatio */
-  num get devicePixelRatio native "DOMWindow_devicePixelRatio_Getter";
-
-
-  /** @domName DOMWindow.document */
-  Document get document native "DOMWindow_document_Getter";
-
-
-  /** @domName DOMWindow.event */
-  Event get event native "DOMWindow_event_Getter";
-
-
-  /** @domName DOMWindow.history */
-  LocalHistory get history native "DOMWindow_history_Getter";
-
-
-  /** @domName DOMWindow.indexedDB */
-  IdbFactory get indexedDB native "DOMWindow_indexedDB_Getter";
-
-
-  /** @domName DOMWindow.innerHeight */
-  int get innerHeight native "DOMWindow_innerHeight_Getter";
-
-
-  /** @domName DOMWindow.innerWidth */
-  int get innerWidth native "DOMWindow_innerWidth_Getter";
-
-
-  /** @domName DOMWindow.localStorage */
-  Storage get localStorage native "DOMWindow_localStorage_Getter";
-
-
-  /** @domName DOMWindow.location */
-  LocalLocation get location native "DOMWindow_location_Getter";
-
-
-  /** @domName DOMWindow.location */
-  void set location(LocalLocation value) native "DOMWindow_location_Setter";
-
-
-  /** @domName DOMWindow.locationbar */
-  BarInfo get locationbar native "DOMWindow_locationbar_Getter";
-
-
-  /** @domName DOMWindow.menubar */
-  BarInfo get menubar native "DOMWindow_menubar_Getter";
-
-
-  /** @domName DOMWindow.name */
-  String get name native "DOMWindow_name_Getter";
-
-
-  /** @domName DOMWindow.name */
-  void set name(String value) native "DOMWindow_name_Setter";
-
-
-  /** @domName DOMWindow.navigator */
-  Navigator get navigator native "DOMWindow_navigator_Getter";
-
-
-  /** @domName DOMWindow.offscreenBuffering */
-  bool get offscreenBuffering native "DOMWindow_offscreenBuffering_Getter";
-
-
-  /** @domName DOMWindow.opener */
-  Window get opener native "DOMWindow_opener_Getter";
-
-
-  /** @domName DOMWindow.outerHeight */
-  int get outerHeight native "DOMWindow_outerHeight_Getter";
-
-
-  /** @domName DOMWindow.outerWidth */
-  int get outerWidth native "DOMWindow_outerWidth_Getter";
-
-
-  /** @domName DOMWindow.pagePopupController */
-  PagePopupController get pagePopupController native "DOMWindow_pagePopupController_Getter";
-
-
-  /** @domName DOMWindow.pageXOffset */
-  int get pageXOffset native "DOMWindow_pageXOffset_Getter";
-
-
-  /** @domName DOMWindow.pageYOffset */
-  int get pageYOffset native "DOMWindow_pageYOffset_Getter";
-
-
-  /** @domName DOMWindow.parent */
-  Window get parent native "DOMWindow_parent_Getter";
-
-
-  /** @domName DOMWindow.performance */
-  Performance get performance native "DOMWindow_performance_Getter";
-
-
-  /** @domName DOMWindow.personalbar */
-  BarInfo get personalbar native "DOMWindow_personalbar_Getter";
-
-
-  /** @domName DOMWindow.screen */
-  Screen get screen native "DOMWindow_screen_Getter";
-
-
-  /** @domName DOMWindow.screenLeft */
-  int get screenLeft native "DOMWindow_screenLeft_Getter";
-
-
-  /** @domName DOMWindow.screenTop */
-  int get screenTop native "DOMWindow_screenTop_Getter";
-
-
-  /** @domName DOMWindow.screenX */
-  int get screenX native "DOMWindow_screenX_Getter";
-
-
-  /** @domName DOMWindow.screenY */
-  int get screenY native "DOMWindow_screenY_Getter";
-
-
-  /** @domName DOMWindow.scrollX */
-  int get scrollX native "DOMWindow_scrollX_Getter";
-
-
-  /** @domName DOMWindow.scrollY */
-  int get scrollY native "DOMWindow_scrollY_Getter";
-
-
-  /** @domName DOMWindow.scrollbars */
-  BarInfo get scrollbars native "DOMWindow_scrollbars_Getter";
-
-
-  /** @domName DOMWindow.self */
-  Window get self native "DOMWindow_self_Getter";
-
-
-  /** @domName DOMWindow.sessionStorage */
-  Storage get sessionStorage native "DOMWindow_sessionStorage_Getter";
-
-
-  /** @domName DOMWindow.status */
-  String get status native "DOMWindow_status_Getter";
-
-
-  /** @domName DOMWindow.status */
-  void set status(String value) native "DOMWindow_status_Setter";
-
-
-  /** @domName DOMWindow.statusbar */
-  BarInfo get statusbar native "DOMWindow_statusbar_Getter";
-
-
-  /** @domName DOMWindow.styleMedia */
-  StyleMedia get styleMedia native "DOMWindow_styleMedia_Getter";
-
-
-  /** @domName DOMWindow.toolbar */
-  BarInfo get toolbar native "DOMWindow_toolbar_Getter";
-
-
-  /** @domName DOMWindow.top */
-  Window get top native "DOMWindow_top_Getter";
-
-
-  /** @domName DOMWindow.webkitNotifications */
-  NotificationCenter get webkitNotifications native "DOMWindow_webkitNotifications_Getter";
-
-
-  /** @domName DOMWindow.webkitStorageInfo */
-  StorageInfo get webkitStorageInfo native "DOMWindow_webkitStorageInfo_Getter";
-
-
-  /** @domName DOMWindow.window */
-  Window get window native "DOMWindow_window_Getter";
-
-
-  /** @domName DOMWindow.addEventListener */
-  void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "DOMWindow_addEventListener_Callback";
-
-
-  /** @domName DOMWindow.alert */
-  void alert(String message) native "DOMWindow_alert_Callback";
-
-
-  /** @domName DOMWindow.atob */
-  String atob(String string) native "DOMWindow_atob_Callback";
-
-
-  /** @domName DOMWindow.btoa */
-  String btoa(String string) native "DOMWindow_btoa_Callback";
-
-
-  /** @domName DOMWindow.cancelAnimationFrame */
-  void cancelAnimationFrame(int id) native "DOMWindow_cancelAnimationFrame_Callback";
-
-
-  /** @domName DOMWindow.captureEvents */
-  void captureEvents() native "DOMWindow_captureEvents_Callback";
-
-
-  /** @domName DOMWindow.clearInterval */
-  void clearInterval(int handle) native "DOMWindow_clearInterval_Callback";
-
-
-  /** @domName DOMWindow.clearTimeout */
-  void clearTimeout(int handle) native "DOMWindow_clearTimeout_Callback";
-
-
-  /** @domName DOMWindow.close */
-  void close() native "DOMWindow_close_Callback";
-
-
-  /** @domName DOMWindow.confirm */
-  bool confirm(String message) native "DOMWindow_confirm_Callback";
-
-
-  /** @domName DOMWindow.dispatchEvent */
-  bool $dom_dispatchEvent(Event evt) native "DOMWindow_dispatchEvent_Callback";
-
-
-  /** @domName DOMWindow.find */
-  bool find(String string, bool caseSensitive, bool backwards, bool wrap, bool wholeWord, bool searchInFrames, bool showDialog) native "DOMWindow_find_Callback";
-
-
-  /** @domName DOMWindow.getComputedStyle */
-  CssStyleDeclaration $dom_getComputedStyle(Element element, String pseudoElement) native "DOMWindow_getComputedStyle_Callback";
-
-
-  /** @domName DOMWindow.getMatchedCSSRules */
-  List<CssRule> getMatchedCssRules(Element element, String pseudoElement) native "DOMWindow_getMatchedCSSRules_Callback";
-
-
-  /** @domName DOMWindow.getSelection */
-  DomSelection getSelection() native "DOMWindow_getSelection_Callback";
-
-
-  /** @domName DOMWindow.matchMedia */
-  MediaQueryList matchMedia(String query) native "DOMWindow_matchMedia_Callback";
-
-
-  /** @domName DOMWindow.moveBy */
-  void moveBy(num x, num y) native "DOMWindow_moveBy_Callback";
-
-
-  /** @domName DOMWindow.moveTo */
-  void moveTo(num x, num y) native "DOMWindow_moveTo_Callback";
-
-
-  /** @domName DOMWindow.open */
-  Window open(String url, String name, [String options]) native "DOMWindow_open_Callback";
-
-
-  /** @domName DOMWindow.openDatabase */
-  Database openDatabase(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) native "DOMWindow_openDatabase_Callback";
-
-
-  /** @domName DOMWindow.postMessage */
-  void postMessage(/*SerializedScriptValue*/ message, String targetOrigin, [List messagePorts]) native "DOMWindow_postMessage_Callback";
-
-
-  /** @domName DOMWindow.print */
-  void print() native "DOMWindow_print_Callback";
-
-
-  /** @domName DOMWindow.releaseEvents */
-  void releaseEvents() native "DOMWindow_releaseEvents_Callback";
-
-
-  /** @domName DOMWindow.removeEventListener */
-  void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "DOMWindow_removeEventListener_Callback";
-
-
-  /** @domName DOMWindow.requestAnimationFrame */
-  int requestAnimationFrame(RequestAnimationFrameCallback callback) native "DOMWindow_requestAnimationFrame_Callback";
-
-
-  /** @domName DOMWindow.resizeBy */
-  void resizeBy(num x, num y) native "DOMWindow_resizeBy_Callback";
-
-
-  /** @domName DOMWindow.resizeTo */
-  void resizeTo(num width, num height) native "DOMWindow_resizeTo_Callback";
-
-
-  /** @domName DOMWindow.scroll */
-  void scroll(int x, int y) native "DOMWindow_scroll_Callback";
-
-
-  /** @domName DOMWindow.scrollBy */
-  void scrollBy(int x, int y) native "DOMWindow_scrollBy_Callback";
-
-
-  /** @domName DOMWindow.scrollTo */
-  void scrollTo(int x, int y) native "DOMWindow_scrollTo_Callback";
-
-
-  /** @domName DOMWindow.setInterval */
-  int setInterval(TimeoutHandler handler, int timeout) native "DOMWindow_setInterval_Callback";
-
-
-  /** @domName DOMWindow.setTimeout */
-  int setTimeout(TimeoutHandler handler, int timeout) native "DOMWindow_setTimeout_Callback";
-
-
-  /** @domName DOMWindow.showModalDialog */
-  Object showModalDialog(String url, [Object dialogArgs, String featureArgs]) native "DOMWindow_showModalDialog_Callback";
-
-
-  /** @domName DOMWindow.stop */
-  void stop() native "DOMWindow_stop_Callback";
-
-
-  /** @domName DOMWindow.webkitCancelAnimationFrame */
-  void webkitCancelAnimationFrame(int id) native "DOMWindow_webkitCancelAnimationFrame_Callback";
-
-
-  /** @domName DOMWindow.webkitConvertPointFromNodeToPage */
-  Point webkitConvertPointFromNodeToPage(Node node, Point p) native "DOMWindow_webkitConvertPointFromNodeToPage_Callback";
-
-
-  /** @domName DOMWindow.webkitConvertPointFromPageToNode */
-  Point webkitConvertPointFromPageToNode(Node node, Point p) native "DOMWindow_webkitConvertPointFromPageToNode_Callback";
-
-
-  /** @domName DOMWindow.webkitRequestAnimationFrame */
-  int webkitRequestAnimationFrame(RequestAnimationFrameCallback callback) native "DOMWindow_webkitRequestAnimationFrame_Callback";
-
-
-  /** @domName DOMWindow.webkitRequestFileSystem */
-  void webkitRequestFileSystem(int type, int size, FileSystemCallback successCallback, [ErrorCallback errorCallback]) native "DOMWindow_webkitRequestFileSystem_Callback";
-
-
-  /** @domName DOMWindow.webkitResolveLocalFileSystemURL */
-  void webkitResolveLocalFileSystemUrl(String url, EntryCallback successCallback, [ErrorCallback errorCallback]) native "DOMWindow_webkitResolveLocalFileSystemURL_Callback";
-
-}
-
-/// @docsEditable true
-class LocalWindowEvents extends Events {
-  /// @docsEditable true
-  LocalWindowEvents(EventTarget _ptr) : super(_ptr);
-
-  /// @docsEditable true
-  EventListenerList get abort => this['abort'];
-
-  /// @docsEditable true
-  EventListenerList get beforeUnload => this['beforeunload'];
-
-  /// @docsEditable true
-  EventListenerList get blur => this['blur'];
-
-  /// @docsEditable true
-  EventListenerList get canPlay => this['canplay'];
-
-  /// @docsEditable true
-  EventListenerList get canPlayThrough => this['canplaythrough'];
-
-  /// @docsEditable true
-  EventListenerList get change => this['change'];
-
-  /// @docsEditable true
-  EventListenerList get click => this['click'];
-
-  /// @docsEditable true
-  EventListenerList get contextMenu => this['contextmenu'];
-
-  /// @docsEditable true
-  EventListenerList get doubleClick => this['dblclick'];
-
-  /// @docsEditable true
-  EventListenerList get deviceMotion => this['devicemotion'];
-
-  /// @docsEditable true
-  EventListenerList get deviceOrientation => this['deviceorientation'];
-
-  /// @docsEditable true
-  EventListenerList get drag => this['drag'];
-
-  /// @docsEditable true
-  EventListenerList get dragEnd => this['dragend'];
-
-  /// @docsEditable true
-  EventListenerList get dragEnter => this['dragenter'];
-
-  /// @docsEditable true
-  EventListenerList get dragLeave => this['dragleave'];
-
-  /// @docsEditable true
-  EventListenerList get dragOver => this['dragover'];
-
-  /// @docsEditable true
-  EventListenerList get dragStart => this['dragstart'];
-
-  /// @docsEditable true
-  EventListenerList get drop => this['drop'];
-
-  /// @docsEditable true
-  EventListenerList get durationChange => this['durationchange'];
-
-  /// @docsEditable true
-  EventListenerList get emptied => this['emptied'];
-
-  /// @docsEditable true
-  EventListenerList get ended => this['ended'];
-
-  /// @docsEditable true
-  EventListenerList get error => this['error'];
-
-  /// @docsEditable true
-  EventListenerList get focus => this['focus'];
-
-  /// @docsEditable true
-  EventListenerList get hashChange => this['hashchange'];
-
-  /// @docsEditable true
-  EventListenerList get input => this['input'];
-
-  /// @docsEditable true
-  EventListenerList get invalid => this['invalid'];
-
-  /// @docsEditable true
-  EventListenerList get keyDown => this['keydown'];
-
-  /// @docsEditable true
-  EventListenerList get keyPress => this['keypress'];
-
-  /// @docsEditable true
-  EventListenerList get keyUp => this['keyup'];
-
-  /// @docsEditable true
-  EventListenerList get load => this['load'];
-
-  /// @docsEditable true
-  EventListenerList get loadedData => this['loadeddata'];
-
-  /// @docsEditable true
-  EventListenerList get loadedMetadata => this['loadedmetadata'];
-
-  /// @docsEditable true
-  EventListenerList get loadStart => this['loadstart'];
-
-  /// @docsEditable true
-  EventListenerList get message => this['message'];
-
-  /// @docsEditable true
-  EventListenerList get mouseDown => this['mousedown'];
-
-  /// @docsEditable true
-  EventListenerList get mouseMove => this['mousemove'];
-
-  /// @docsEditable true
-  EventListenerList get mouseOut => this['mouseout'];
-
-  /// @docsEditable true
-  EventListenerList get mouseOver => this['mouseover'];
-
-  /// @docsEditable true
-  EventListenerList get mouseUp => this['mouseup'];
-
-  /// @docsEditable true
-  EventListenerList get mouseWheel => this['mousewheel'];
-
-  /// @docsEditable true
-  EventListenerList get offline => this['offline'];
-
-  /// @docsEditable true
-  EventListenerList get online => this['online'];
-
-  /// @docsEditable true
-  EventListenerList get pageHide => this['pagehide'];
-
-  /// @docsEditable true
-  EventListenerList get pageShow => this['pageshow'];
-
-  /// @docsEditable true
-  EventListenerList get pause => this['pause'];
-
-  /// @docsEditable true
-  EventListenerList get play => this['play'];
-
-  /// @docsEditable true
-  EventListenerList get playing => this['playing'];
-
-  /// @docsEditable true
-  EventListenerList get popState => this['popstate'];
-
-  /// @docsEditable true
-  EventListenerList get progress => this['progress'];
-
-  /// @docsEditable true
-  EventListenerList get rateChange => this['ratechange'];
-
-  /// @docsEditable true
-  EventListenerList get reset => this['reset'];
-
-  /// @docsEditable true
-  EventListenerList get resize => this['resize'];
-
-  /// @docsEditable true
-  EventListenerList get scroll => this['scroll'];
-
-  /// @docsEditable true
-  EventListenerList get search => this['search'];
-
-  /// @docsEditable true
-  EventListenerList get seeked => this['seeked'];
-
-  /// @docsEditable true
-  EventListenerList get seeking => this['seeking'];
-
-  /// @docsEditable true
-  EventListenerList get select => this['select'];
-
-  /// @docsEditable true
-  EventListenerList get stalled => this['stalled'];
-
-  /// @docsEditable true
-  EventListenerList get storage => this['storage'];
-
-  /// @docsEditable true
-  EventListenerList get submit => this['submit'];
-
-  /// @docsEditable true
-  EventListenerList get suspend => this['suspend'];
-
-  /// @docsEditable true
-  EventListenerList get timeUpdate => this['timeupdate'];
-
-  /// @docsEditable true
-  EventListenerList get touchCancel => this['touchcancel'];
-
-  /// @docsEditable true
-  EventListenerList get touchEnd => this['touchend'];
-
-  /// @docsEditable true
-  EventListenerList get touchMove => this['touchmove'];
-
-  /// @docsEditable true
-  EventListenerList get touchStart => this['touchstart'];
-
-  /// @docsEditable true
-  EventListenerList get unload => this['unload'];
-
-  /// @docsEditable true
-  EventListenerList get volumeChange => this['volumechange'];
-
-  /// @docsEditable true
-  EventListenerList get waiting => this['waiting'];
-
-  /// @docsEditable true
-  EventListenerList get animationEnd => this['webkitAnimationEnd'];
-
-  /// @docsEditable true
-  EventListenerList get animationIteration => this['webkitAnimationIteration'];
-
-  /// @docsEditable true
-  EventListenerList get animationStart => this['webkitAnimationStart'];
-
-  /// @docsEditable true
-  EventListenerList get transitionEnd => this['webkitTransitionEnd'];
-}
-// 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.
-
-
 /// @domName HTMLMapElement
 class MapElement extends _Element_Merged {
+  MapElement.internal() : super.internal();
 
   ///@docsEditable true
   factory MapElement() => document.$dom_createElement("map");
-  MapElement.internal(): super.internal();
 
 
   /** @domName HTMLMapElement.areas */
@@ -15379,7 +14459,12 @@
 
 /// @domName HTMLMarqueeElement
 class MarqueeElement extends _Element_Merged {
-  MarqueeElement.internal(): super.internal();
+  MarqueeElement.internal() : super.internal();
+
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => true;
 
 
   /** @domName HTMLMarqueeElement.behavior */
@@ -15487,10 +14572,11 @@
 
 /// @domName MediaController
 class MediaController extends EventTarget {
+  MediaController.internal() : super.internal();
 
   ///@docsEditable true
-  factory MediaController() => _MediaControllerFactoryProvider.createMediaController();
-  MediaController.internal(): super.internal();
+  factory MediaController() => MediaController._create();
+  static MediaController _create() native "MediaController_constructor_Callback";
 
 
   /** @domName MediaController.buffered */
@@ -15537,6 +14623,10 @@
   void set playbackRate(num value) native "MediaController_playbackRate_Setter";
 
 
+  /** @domName MediaController.playbackState */
+  String get playbackState native "MediaController_playbackState_Getter";
+
+
   /** @domName MediaController.played */
   TimeRanges get played native "MediaController_played_Getter";
 
@@ -15572,6 +14662,10 @@
   /** @domName MediaController.removeEventListener */
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "MediaController_removeEventListener_Callback";
 
+
+  /** @domName MediaController.unpause */
+  void unpause() native "MediaController_unpause_Callback";
+
 }
 // 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
@@ -15582,7 +14676,7 @@
 
 /// @domName HTMLMediaElement
 class MediaElement extends _Element_Merged {
-  MediaElement.internal(): super.internal();
+  MediaElement.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   MediaElementEvents get on =>
@@ -16013,7 +15107,7 @@
 
 /// @domName MediaKeyEvent
 class MediaKeyEvent extends Event {
-  MediaKeyEvent.internal(): super.internal();
+  MediaKeyEvent.internal() : super.internal();
 
 
   /** @domName MediaKeyEvent.defaultURL */
@@ -16133,10 +15227,11 @@
 
 /// @domName MediaSource
 class MediaSource extends EventTarget {
+  MediaSource.internal() : super.internal();
 
   ///@docsEditable true
-  factory MediaSource() => _MediaSourceFactoryProvider.createMediaSource();
-  MediaSource.internal(): super.internal();
+  factory MediaSource() => MediaSource._create();
+  static MediaSource _create() native "MediaSource_constructor_Callback";
 
 
   /** @domName MediaSource.activeSourceBuffers */
@@ -16192,10 +15287,11 @@
 
 /// @domName MediaStream
 class MediaStream extends EventTarget {
+  MediaStream.internal() : super.internal();
 
   ///@docsEditable true
-  factory MediaStream(MediaStreamTrackList audioTracks, MediaStreamTrackList videoTracks) => _MediaStreamFactoryProvider.createMediaStream(audioTracks, videoTracks);
-  MediaStream.internal(): super.internal();
+  factory MediaStream(MediaStreamTrackList audioTracks, MediaStreamTrackList videoTracks) => MediaStream._create(audioTracks, videoTracks);
+  static MediaStream _create(MediaStreamTrackList audioTracks, MediaStreamTrackList videoTracks) native "MediaStream_constructor_Callback";
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   MediaStreamEvents get on =>
@@ -16252,7 +15348,7 @@
 
 /// @domName MediaStreamEvent
 class MediaStreamEvent extends Event {
-  MediaStreamEvent.internal(): super.internal();
+  MediaStreamEvent.internal() : super.internal();
 
 
   /** @domName MediaStreamEvent.stream */
@@ -16268,7 +15364,7 @@
 
 /// @domName MediaStreamTrack
 class MediaStreamTrack extends EventTarget {
-  MediaStreamTrack.internal(): super.internal();
+  MediaStreamTrack.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   MediaStreamTrackEvents get on =>
@@ -16337,7 +15433,7 @@
 
 /// @domName MediaStreamTrackEvent
 class MediaStreamTrackEvent extends Event {
-  MediaStreamTrackEvent.internal(): super.internal();
+  MediaStreamTrackEvent.internal() : super.internal();
 
 
   /** @domName MediaStreamTrackEvent.track */
@@ -16353,7 +15449,7 @@
 
 /// @domName MediaStreamTrackList
 class MediaStreamTrackList extends EventTarget {
-  MediaStreamTrackList.internal(): super.internal();
+  MediaStreamTrackList.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   MediaStreamTrackListEvents get on =>
@@ -16433,10 +15529,10 @@
 
 /// @domName HTMLMenuElement
 class MenuElement extends _Element_Merged {
+  MenuElement.internal() : super.internal();
 
   ///@docsEditable true
   factory MenuElement() => document.$dom_createElement("menu");
-  MenuElement.internal(): super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -16448,10 +15544,11 @@
 
 /// @domName MessageChannel
 class MessageChannel extends NativeFieldWrapperClass1 {
+  MessageChannel.internal();
 
   ///@docsEditable true
-  factory MessageChannel() => _MessageChannelFactoryProvider.createMessageChannel();
-  MessageChannel.internal();
+  factory MessageChannel() => MessageChannel._create();
+  static MessageChannel _create() native "MessageChannel_constructor_Callback";
 
 
   /** @domName MessageChannel.port1 */
@@ -16471,7 +15568,7 @@
 
 /// @domName MessageEvent
 class MessageEvent extends Event {
-  MessageEvent.internal(): super.internal();
+  MessageEvent.internal() : super.internal();
 
 
   /** @domName MessageEvent.data */
@@ -16491,15 +15588,15 @@
 
 
   /** @domName MessageEvent.source */
-  Window get source native "MessageEvent_source_Getter";
+  WindowBase get source native "MessageEvent_source_Getter";
 
 
   /** @domName MessageEvent.initMessageEvent */
-  void initMessageEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Object dataArg, String originArg, String lastEventIdArg, LocalWindow sourceArg, List messagePorts) native "MessageEvent_initMessageEvent_Callback";
+  void initMessageEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Object dataArg, String originArg, String lastEventIdArg, Window sourceArg, List messagePorts) native "MessageEvent_initMessageEvent_Callback";
 
 
   /** @domName MessageEvent.webkitInitMessageEvent */
-  void webkitInitMessageEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Object dataArg, String originArg, String lastEventIdArg, LocalWindow sourceArg, List transferables) native "MessageEvent_webkitInitMessageEvent_Callback";
+  void webkitInitMessageEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Object dataArg, String originArg, String lastEventIdArg, Window sourceArg, List transferables) native "MessageEvent_webkitInitMessageEvent_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -16511,7 +15608,7 @@
 
 /// @domName MessagePort
 class MessagePort extends EventTarget {
-  MessagePort.internal(): super.internal();
+  MessagePort.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   MessagePortEvents get on =>
@@ -16560,7 +15657,7 @@
 
 /// @domName HTMLMetaElement
 class MetaElement extends _Element_Merged {
-  MetaElement.internal(): super.internal();
+  MetaElement.internal() : super.internal();
 
 
   /** @domName HTMLMetaElement.content */
@@ -16586,14 +15683,6 @@
   /** @domName HTMLMetaElement.name */
   void set name(String value) native "HTMLMetaElement_name_Setter";
 
-
-  /** @domName HTMLMetaElement.scheme */
-  String get scheme native "HTMLMetaElement_scheme_Getter";
-
-
-  /** @domName HTMLMetaElement.scheme */
-  void set scheme(String value) native "HTMLMetaElement_scheme_Setter";
-
 }
 // 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
@@ -16631,11 +15720,19 @@
 
 
 /// @domName HTMLMeterElement
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class MeterElement extends _Element_Merged {
+  MeterElement.internal() : super.internal();
 
   ///@docsEditable true
   factory MeterElement() => document.$dom_createElement("meter");
-  MeterElement.internal(): super.internal();
+
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => true;
 
 
   /** @domName HTMLMeterElement.high */
@@ -16699,7 +15796,7 @@
 
 /// @domName HTMLModElement
 class ModElement extends _Element_Merged {
-  ModElement.internal(): super.internal();
+  ModElement.internal() : super.internal();
 
 
   /** @domName HTMLModElement.cite */
@@ -16737,7 +15834,7 @@
           clientX, clientY, button, canBubble, cancelable,
           ctrlKey, altKey, shiftKey, metaKey,
           relatedTarget);
-  MouseEvent.internal(): super.internal();
+  MouseEvent.internal() : super.internal();
 
 
   /** @domName MouseEvent.altKey */
@@ -16817,7 +15914,7 @@
 
 
   /** @domName MouseEvent.initMouseEvent */
-  void $dom_initMouseEvent(String type, bool canBubble, bool cancelable, LocalWindow 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";
+  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";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -16837,7 +15934,7 @@
 
 /// @domName MutationEvent
 class MutationEvent extends Event {
-  MutationEvent.internal(): super.internal();
+  MutationEvent.internal() : super.internal();
 
   static const int ADDITION = 2;
 
@@ -16876,11 +15973,16 @@
 
 
 /// @domName MutationObserver
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental()
 class MutationObserver extends NativeFieldWrapperClass1 {
+  MutationObserver.internal();
 
   ///@docsEditable true
-  factory MutationObserver(MutationCallback callback) => _MutationObserverFactoryProvider.createMutationObserver(callback);
-  MutationObserver.internal();
+  factory MutationObserver(MutationCallback callback) => MutationObserver._create(callback);
+  static MutationObserver _create(MutationCallback callback) native "MutationObserver_constructor_Callback";
 
 
   /** @domName MutationObserver.disconnect */
@@ -16894,6 +15996,14 @@
   /** @domName MutationObserver.takeRecords */
   List<MutationRecord> takeRecords() native "MutationObserver_takeRecords_Callback";
 
+  /**
+   * Checks to see if the mutation observer API is supported on the current
+   * platform.
+   */
+  static bool get supported {
+    return true;
+  }
+
   void observe(Node target,
                {Map options,
                 bool childList,
@@ -17443,7 +16553,7 @@
     return this;
   }
 
-  Node.internal(): super.internal();
+  Node.internal() : super.internal();
 
   static const int ATTRIBUTE_NODE = 2;
 
@@ -17803,7 +16913,7 @@
 
 /// @domName Notation
 class Notation extends Node {
-  Notation.internal(): super.internal();
+  Notation.internal() : super.internal();
 
 
   /** @domName Notation.publicId */
@@ -17823,15 +16933,16 @@
 
 /// @domName Notification
 class Notification extends EventTarget {
+  Notification.internal() : super.internal();
 
   ///@docsEditable true
   factory Notification(String title, [Map options]) {
     if (!?options) {
-      return _NotificationFactoryProvider.createNotification(title);
+      return Notification._create(title);
     }
-    return _NotificationFactoryProvider.createNotification(title, options);
+    return Notification._create(title, options);
   }
-  Notification.internal(): super.internal();
+  static Notification _create(String title, [Map options]) native "Notification_constructor_Callback";
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   NotificationEvents get on =>
@@ -17960,18 +17071,10 @@
 
 /// @domName HTMLOListElement
 class OListElement extends _Element_Merged {
+  OListElement.internal() : super.internal();
 
   ///@docsEditable true
   factory OListElement() => document.$dom_createElement("ol");
-  OListElement.internal(): super.internal();
-
-
-  /** @domName HTMLOListElement.compact */
-  bool get compact native "HTMLOListElement_compact_Getter";
-
-
-  /** @domName HTMLOListElement.compact */
-  void set compact(bool value) native "HTMLOListElement_compact_Setter";
 
 
   /** @domName HTMLOListElement.reversed */
@@ -18006,35 +17109,19 @@
 
 
 /// @domName HTMLObjectElement
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class ObjectElement extends _Element_Merged {
+  ObjectElement.internal() : super.internal();
 
   ///@docsEditable true
   factory ObjectElement() => document.$dom_createElement("object");
-  ObjectElement.internal(): super.internal();
 
-
-  /** @domName HTMLObjectElement.align */
-  String get align native "HTMLObjectElement_align_Getter";
-
-
-  /** @domName HTMLObjectElement.align */
-  void set align(String value) native "HTMLObjectElement_align_Setter";
-
-
-  /** @domName HTMLObjectElement.archive */
-  String get archive native "HTMLObjectElement_archive_Getter";
-
-
-  /** @domName HTMLObjectElement.archive */
-  void set archive(String value) native "HTMLObjectElement_archive_Setter";
-
-
-  /** @domName HTMLObjectElement.border */
-  String get border native "HTMLObjectElement_border_Getter";
-
-
-  /** @domName HTMLObjectElement.border */
-  void set border(String value) native "HTMLObjectElement_border_Setter";
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => true;
 
 
   /** @domName HTMLObjectElement.code */
@@ -18045,22 +17132,6 @@
   void set code(String value) native "HTMLObjectElement_code_Setter";
 
 
-  /** @domName HTMLObjectElement.codeBase */
-  String get codeBase native "HTMLObjectElement_codeBase_Getter";
-
-
-  /** @domName HTMLObjectElement.codeBase */
-  void set codeBase(String value) native "HTMLObjectElement_codeBase_Setter";
-
-
-  /** @domName HTMLObjectElement.codeType */
-  String get codeType native "HTMLObjectElement_codeType_Getter";
-
-
-  /** @domName HTMLObjectElement.codeType */
-  void set codeType(String value) native "HTMLObjectElement_codeType_Setter";
-
-
   /** @domName HTMLObjectElement.data */
   String get data native "HTMLObjectElement_data_Getter";
 
@@ -18069,14 +17140,6 @@
   void set data(String value) native "HTMLObjectElement_data_Setter";
 
 
-  /** @domName HTMLObjectElement.declare */
-  bool get declare native "HTMLObjectElement_declare_Getter";
-
-
-  /** @domName HTMLObjectElement.declare */
-  void set declare(bool value) native "HTMLObjectElement_declare_Setter";
-
-
   /** @domName HTMLObjectElement.form */
   FormElement get form native "HTMLObjectElement_form_Getter";
 
@@ -18089,14 +17152,6 @@
   void set height(String value) native "HTMLObjectElement_height_Setter";
 
 
-  /** @domName HTMLObjectElement.hspace */
-  int get hspace native "HTMLObjectElement_hspace_Getter";
-
-
-  /** @domName HTMLObjectElement.hspace */
-  void set hspace(int value) native "HTMLObjectElement_hspace_Setter";
-
-
   /** @domName HTMLObjectElement.name */
   String get name native "HTMLObjectElement_name_Getter";
 
@@ -18105,14 +17160,6 @@
   void set name(String value) native "HTMLObjectElement_name_Setter";
 
 
-  /** @domName HTMLObjectElement.standby */
-  String get standby native "HTMLObjectElement_standby_Getter";
-
-
-  /** @domName HTMLObjectElement.standby */
-  void set standby(String value) native "HTMLObjectElement_standby_Setter";
-
-
   /** @domName HTMLObjectElement.type */
   String get type native "HTMLObjectElement_type_Getter";
 
@@ -18137,14 +17184,6 @@
   ValidityState get validity native "HTMLObjectElement_validity_Getter";
 
 
-  /** @domName HTMLObjectElement.vspace */
-  int get vspace native "HTMLObjectElement_vspace_Getter";
-
-
-  /** @domName HTMLObjectElement.vspace */
-  void set vspace(int value) native "HTMLObjectElement_vspace_Setter";
-
-
   /** @domName HTMLObjectElement.width */
   String get width native "HTMLObjectElement_width_Getter";
 
@@ -18242,10 +17281,10 @@
 
 /// @domName HTMLOptGroupElement
 class OptGroupElement extends _Element_Merged {
+  OptGroupElement.internal() : super.internal();
 
   ///@docsEditable true
   factory OptGroupElement() => document.$dom_createElement("optgroup");
-  OptGroupElement.internal(): super.internal();
 
 
   /** @domName HTMLOptGroupElement.disabled */
@@ -18273,24 +17312,25 @@
 
 /// @domName HTMLOptionElement
 class OptionElement extends _Element_Merged {
+  OptionElement.internal() : super.internal();
 
   ///@docsEditable true
   factory OptionElement([String data, String value, bool defaultSelected, bool selected]) {
     if (!?data) {
-      return _OptionElementFactoryProvider.createOptionElement();
+      return OptionElement._create();
     }
     if (!?value) {
-      return _OptionElementFactoryProvider.createOptionElement(data);
+      return OptionElement._create(data);
     }
     if (!?defaultSelected) {
-      return _OptionElementFactoryProvider.createOptionElement(data, value);
+      return OptionElement._create(data, value);
     }
     if (!?selected) {
-      return _OptionElementFactoryProvider.createOptionElement(data, value, defaultSelected);
+      return OptionElement._create(data, value, defaultSelected);
     }
-    return _OptionElementFactoryProvider.createOptionElement(data, value, defaultSelected, selected);
+    return OptionElement._create(data, value, defaultSelected, selected);
   }
-  OptionElement.internal(): super.internal();
+  static OptionElement _create([String data, String value, bool defaultSelected, bool selected]) native "HTMLOptionElement_constructor_Callback";
 
 
   /** @domName HTMLOptionElement.defaultSelected */
@@ -18349,11 +17389,19 @@
 
 
 /// @domName HTMLOutputElement
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class OutputElement extends _Element_Merged {
+  OutputElement.internal() : super.internal();
 
   ///@docsEditable true
   factory OutputElement() => document.$dom_createElement("output");
-  OutputElement.internal(): super.internal();
+
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => true;
 
 
   /** @domName HTMLOutputElement.defaultValue */
@@ -18429,7 +17477,7 @@
 
 /// @domName OverflowEvent
 class OverflowEvent extends Event {
-  OverflowEvent.internal(): super.internal();
+  OverflowEvent.internal() : super.internal();
 
   static const int BOTH = 2;
 
@@ -18462,6 +17510,14 @@
   PagePopupController.internal();
 
 
+  /** @domName PagePopupController.formatMonth */
+  String formatMonth(int year, int zeroBaseMonth) native "PagePopupController_formatMonth_Callback";
+
+
+  /** @domName PagePopupController.histogramEnumeration */
+  void histogramEnumeration(String name, int sample, int boundaryValue) native "PagePopupController_histogramEnumeration_Callback";
+
+
   /** @domName PagePopupController.localizeNumberString */
   String localizeNumberString(String numberString) native "PagePopupController_localizeNumberString_Callback";
 
@@ -18479,7 +17535,7 @@
 
 /// @domName PageTransitionEvent
 class PageTransitionEvent extends Event {
-  PageTransitionEvent.internal(): super.internal();
+  PageTransitionEvent.internal() : super.internal();
 
 
   /** @domName PageTransitionEvent.persisted */
@@ -18495,18 +17551,10 @@
 
 /// @domName HTMLParagraphElement
 class ParagraphElement extends _Element_Merged {
+  ParagraphElement.internal() : super.internal();
 
   ///@docsEditable true
   factory ParagraphElement() => document.$dom_createElement("p");
-  ParagraphElement.internal(): super.internal();
-
-
-  /** @domName HTMLParagraphElement.align */
-  String get align native "HTMLParagraphElement_align_Getter";
-
-
-  /** @domName HTMLParagraphElement.align */
-  void set align(String value) native "HTMLParagraphElement_align_Setter";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -18518,10 +17566,10 @@
 
 /// @domName HTMLParamElement
 class ParamElement extends _Element_Merged {
+  ParamElement.internal() : super.internal();
 
   ///@docsEditable true
   factory ParamElement() => document.$dom_createElement("param");
-  ParamElement.internal(): super.internal();
 
 
   /** @domName HTMLParamElement.name */
@@ -18532,14 +17580,6 @@
   void set name(String value) native "HTMLParamElement_name_Setter";
 
 
-  /** @domName HTMLParamElement.type */
-  String get type native "HTMLParamElement_type_Getter";
-
-
-  /** @domName HTMLParamElement.type */
-  void set type(String value) native "HTMLParamElement_type_Setter";
-
-
   /** @domName HTMLParamElement.value */
   String get value native "HTMLParamElement_value_Getter";
 
@@ -18547,154 +17587,6 @@
   /** @domName HTMLParamElement.value */
   void set value(String value) native "HTMLParamElement_value_Setter";
 
-
-  /** @domName HTMLParamElement.valueType */
-  String get valueType native "HTMLParamElement_valueType_Getter";
-
-
-  /** @domName HTMLParamElement.valueType */
-  void set valueType(String value) native "HTMLParamElement_valueType_Setter";
-
-}
-// 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.
-
-
-/// @domName PeerConnection00
-class PeerConnection00 extends EventTarget {
-
-  ///@docsEditable true
-  factory PeerConnection00(String serverConfiguration, IceCallback iceCallback) => _PeerConnection00FactoryProvider.createPeerConnection00(serverConfiguration, iceCallback);
-  PeerConnection00.internal(): super.internal();
-
-  /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
-  PeerConnection00Events get on =>
-    new PeerConnection00Events(this);
-
-  static const int ACTIVE = 2;
-
-  static const int CLOSED = 3;
-
-  static const int ICE_CHECKING = 0x300;
-
-  static const int ICE_CLOSED = 0x700;
-
-  static const int ICE_COMPLETED = 0x500;
-
-  static const int ICE_CONNECTED = 0x400;
-
-  static const int ICE_FAILED = 0x600;
-
-  static const int ICE_GATHERING = 0x100;
-
-  static const int ICE_WAITING = 0x200;
-
-  static const int NEW = 0;
-
-  static const int OPENING = 1;
-
-  static const int SDP_ANSWER = 0x300;
-
-  static const int SDP_OFFER = 0x100;
-
-  static const int SDP_PRANSWER = 0x200;
-
-
-  /** @domName PeerConnection00.iceState */
-  int get iceState native "PeerConnection00_iceState_Getter";
-
-
-  /** @domName PeerConnection00.localDescription */
-  SessionDescription get localDescription native "PeerConnection00_localDescription_Getter";
-
-
-  /** @domName PeerConnection00.localStreams */
-  List<MediaStream> get localStreams native "PeerConnection00_localStreams_Getter";
-
-
-  /** @domName PeerConnection00.readyState */
-  int get readyState native "PeerConnection00_readyState_Getter";
-
-
-  /** @domName PeerConnection00.remoteDescription */
-  SessionDescription get remoteDescription native "PeerConnection00_remoteDescription_Getter";
-
-
-  /** @domName PeerConnection00.remoteStreams */
-  List<MediaStream> get remoteStreams native "PeerConnection00_remoteStreams_Getter";
-
-
-  /** @domName PeerConnection00.addEventListener */
-  void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "PeerConnection00_addEventListener_Callback";
-
-
-  /** @domName PeerConnection00.addStream */
-  void addStream(MediaStream stream, [Map mediaStreamHints]) native "PeerConnection00_addStream_Callback";
-
-
-  /** @domName PeerConnection00.close */
-  void close() native "PeerConnection00_close_Callback";
-
-
-  /** @domName PeerConnection00.createAnswer */
-  SessionDescription createAnswer(String offer, [Map mediaHints]) native "PeerConnection00_createAnswer_Callback";
-
-
-  /** @domName PeerConnection00.createOffer */
-  SessionDescription createOffer([Map mediaHints]) native "PeerConnection00_createOffer_Callback";
-
-
-  /** @domName PeerConnection00.dispatchEvent */
-  bool $dom_dispatchEvent(Event event) native "PeerConnection00_dispatchEvent_Callback";
-
-
-  /** @domName PeerConnection00.processIceMessage */
-  void processIceMessage(IceCandidate candidate) native "PeerConnection00_processIceMessage_Callback";
-
-
-  /** @domName PeerConnection00.removeEventListener */
-  void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "PeerConnection00_removeEventListener_Callback";
-
-
-  /** @domName PeerConnection00.removeStream */
-  void removeStream(MediaStream stream) native "PeerConnection00_removeStream_Callback";
-
-
-  /** @domName PeerConnection00.setLocalDescription */
-  void setLocalDescription(int action, SessionDescription desc) native "PeerConnection00_setLocalDescription_Callback";
-
-
-  /** @domName PeerConnection00.setRemoteDescription */
-  void setRemoteDescription(int action, SessionDescription desc) native "PeerConnection00_setRemoteDescription_Callback";
-
-
-  /** @domName PeerConnection00.startIce */
-  void startIce([Map iceOptions]) native "PeerConnection00_startIce_Callback";
-
-}
-
-/// @docsEditable true
-class PeerConnection00Events extends Events {
-  /// @docsEditable true
-  PeerConnection00Events(EventTarget _ptr) : super(_ptr);
-
-  /// @docsEditable true
-  EventListenerList get addStream => this['addstream'];
-
-  /// @docsEditable true
-  EventListenerList get connecting => this['connecting'];
-
-  /// @docsEditable true
-  EventListenerList get open => this['open'];
-
-  /// @docsEditable true
-  EventListenerList get removeStream => this['removestream'];
-
-  /// @docsEditable true
-  EventListenerList get stateChange => this['statechange'];
 }
 // 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
@@ -18705,7 +17597,7 @@
 
 /// @domName Performance
 class Performance extends EventTarget {
-  Performance.internal(): super.internal();
+  Performance.internal() : super.internal();
 
 
   /** @domName Performance.memory */
@@ -18857,9 +17749,12 @@
 
 /// @domName WebKitPoint
 class Point extends NativeFieldWrapperClass1 {
-  factory Point(num x, num y) => _PointFactoryProvider.createPoint(x, y);
   Point.internal();
 
+  ///@docsEditable true
+  factory Point(num x, num y) => Point._create(x, y);
+  static Point _create(num x, num y) native "WebKitPoint_constructor_Callback";
+
 
   /** @domName WebKitPoint.x */
   num get x native "WebKitPoint_x_Getter";
@@ -18886,7 +17781,7 @@
 
 /// @domName PopStateEvent
 class PopStateEvent extends Event {
-  PopStateEvent.internal(): super.internal();
+  PopStateEvent.internal() : super.internal();
 
 
   /** @domName PopStateEvent.state */
@@ -18944,18 +17839,10 @@
 
 /// @domName HTMLPreElement
 class PreElement extends _Element_Merged {
+  PreElement.internal() : super.internal();
 
   ///@docsEditable true
   factory PreElement() => document.$dom_createElement("pre");
-  PreElement.internal(): super.internal();
-
-
-  /** @domName HTMLPreElement.width */
-  int get width native "HTMLPreElement_width_Getter";
-
-
-  /** @domName HTMLPreElement.width */
-  void set width(int value) native "HTMLPreElement_width_Setter";
 
 
   /** @domName HTMLPreElement.wrap */
@@ -18975,7 +17862,7 @@
 
 /// @domName ProcessingInstruction
 class ProcessingInstruction extends Node {
-  ProcessingInstruction.internal(): super.internal();
+  ProcessingInstruction.internal() : super.internal();
 
 
   /** @domName ProcessingInstruction.data */
@@ -19002,11 +17889,20 @@
 
 
 /// @domName HTMLProgressElement
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class ProgressElement extends _Element_Merged {
+  ProgressElement.internal() : super.internal();
 
   ///@docsEditable true
   factory ProgressElement() => document.$dom_createElement("progress");
-  ProgressElement.internal(): super.internal();
+
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => true;
 
 
   /** @domName HTMLProgressElement.labels */
@@ -19042,7 +17938,7 @@
 
 /// @domName ProgressEvent
 class ProgressEvent extends Event {
-  ProgressEvent.internal(): super.internal();
+  ProgressEvent.internal() : super.internal();
 
 
   /** @domName ProgressEvent.lengthComputable */
@@ -19066,7 +17962,7 @@
 
 /// @domName HTMLQuoteElement
 class QuoteElement extends _Element_Merged {
-  QuoteElement.internal(): super.internal();
+  QuoteElement.internal() : super.internal();
 
 
   /** @domName HTMLQuoteElement.cite */
@@ -19110,7 +18006,7 @@
 
 /// @domName RadioNodeList
 class RadioNodeList extends NodeList {
-  RadioNodeList.internal(): super.internal();
+  RadioNodeList.internal() : super.internal();
 
 
   /** @domName RadioNodeList.value */
@@ -19376,7 +18272,7 @@
 
 /// @domName RTCDataChannel
 class RtcDataChannel extends EventTarget {
-  RtcDataChannel.internal(): super.internal();
+  RtcDataChannel.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   RtcDataChannelEvents get on =>
@@ -19486,7 +18382,7 @@
 
 /// @domName RTCDataChannelEvent
 class RtcDataChannelEvent extends Event {
-  RtcDataChannelEvent.internal(): super.internal();
+  RtcDataChannelEvent.internal() : super.internal();
 
 
   /** @domName RTCDataChannelEvent.channel */
@@ -19502,10 +18398,11 @@
 
 /// @domName RTCIceCandidate
 class RtcIceCandidate extends NativeFieldWrapperClass1 {
+  RtcIceCandidate.internal();
 
   ///@docsEditable true
-  factory RtcIceCandidate(Map dictionary) => _RtcIceCandidateFactoryProvider.createRtcIceCandidate(dictionary);
-  RtcIceCandidate.internal();
+  factory RtcIceCandidate(Map dictionary) => RtcIceCandidate._create(dictionary);
+  static RtcIceCandidate _create(Map dictionary) native "RTCIceCandidate_constructor_Callback";
 
 
   /** @domName RTCIceCandidate.candidate */
@@ -19529,7 +18426,7 @@
 
 /// @domName RTCIceCandidateEvent
 class RtcIceCandidateEvent extends Event {
-  RtcIceCandidateEvent.internal(): super.internal();
+  RtcIceCandidateEvent.internal() : super.internal();
 
 
   /** @domName RTCIceCandidateEvent.candidate */
@@ -19545,21 +18442,26 @@
 
 /// @domName RTCPeerConnection
 class RtcPeerConnection extends EventTarget {
+  RtcPeerConnection.internal() : super.internal();
 
   ///@docsEditable true
   factory RtcPeerConnection(Map rtcIceServers, [Map mediaConstraints]) {
     if (!?mediaConstraints) {
-      return _RtcPeerConnectionFactoryProvider.createRtcPeerConnection(rtcIceServers);
+      return RtcPeerConnection._create(rtcIceServers);
     }
-    return _RtcPeerConnectionFactoryProvider.createRtcPeerConnection(rtcIceServers, mediaConstraints);
+    return RtcPeerConnection._create(rtcIceServers, mediaConstraints);
   }
-  RtcPeerConnection.internal(): super.internal();
+  static RtcPeerConnection _create(Map rtcIceServers, [Map mediaConstraints]) native "RTCPeerConnection_constructor_Callback";
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   RtcPeerConnectionEvents get on =>
     new RtcPeerConnectionEvents(this);
 
 
+  /** @domName RTCPeerConnection.iceGatheringState */
+  String get iceGatheringState native "RTCPeerConnection_iceGatheringState_Getter";
+
+
   /** @domName RTCPeerConnection.iceState */
   String get iceState native "RTCPeerConnection_iceState_Getter";
 
@@ -19676,10 +18578,11 @@
 
 /// @domName RTCSessionDescription
 class RtcSessionDescription extends NativeFieldWrapperClass1 {
+  RtcSessionDescription.internal();
 
   ///@docsEditable true
-  factory RtcSessionDescription(Map dictionary) => _RtcSessionDescriptionFactoryProvider.createRtcSessionDescription(dictionary);
-  RtcSessionDescription.internal();
+  factory RtcSessionDescription(Map dictionary) => RtcSessionDescription._create(dictionary);
+  static RtcSessionDescription _create(Map dictionary) native "RTCSessionDescription_constructor_Callback";
 
 
   /** @domName RTCSessionDescription.sdp */
@@ -19714,6 +18617,10 @@
   Date get timestamp native "RTCStatsElement_timestamp_Getter";
 
 
+  /** @domName RTCStatsElement.names */
+  List<String> names() native "RTCStatsElement_names_Callback";
+
+
   /** @domName RTCStatsElement.stat */
   String stat(String name) native "RTCStatsElement_stat_Callback";
 
@@ -19847,10 +18754,10 @@
 
 /// @domName HTMLScriptElement
 class ScriptElement extends _Element_Merged {
+  ScriptElement.internal() : super.internal();
 
   ///@docsEditable true
   factory ScriptElement() => document.$dom_createElement("script");
-  ScriptElement.internal(): super.internal();
 
 
   /** @domName HTMLScriptElement.async */
@@ -19993,15 +18900,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// WARNING: Do not edit - generated code.
-
 
 /// @domName HTMLSelectElement
 class SelectElement extends _Element_Merged {
+  SelectElement.internal() : super.internal();
 
   ///@docsEditable true
   factory SelectElement() => document.$dom_createElement("select");
-  SelectElement.internal(): super.internal();
 
 
   /** @domName HTMLSelectElement.autofocus */
@@ -20052,10 +18957,6 @@
   void set name(String value) native "HTMLSelectElement_name_Setter";
 
 
-  /** @domName HTMLSelectElement.options */
-  HtmlOptionsCollection get options native "HTMLSelectElement_options_Getter";
-
-
   /** @domName HTMLSelectElement.required */
   bool get required native "HTMLSelectElement_required_Getter";
 
@@ -20072,10 +18973,6 @@
   void set selectedIndex(int value) native "HTMLSelectElement_selectedIndex_Setter";
 
 
-  /** @domName HTMLSelectElement.selectedOptions */
-  HtmlCollection get selectedOptions native "HTMLSelectElement_selectedOptions_Getter";
-
-
   /** @domName HTMLSelectElement.size */
   int get size native "HTMLSelectElement_size_Getter";
 
@@ -20123,29 +19020,21 @@
   /** @domName HTMLSelectElement.setCustomValidity */
   void setCustomValidity(String error) native "HTMLSelectElement_setCustomValidity_Callback";
 
-}
-// 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.
+  // Override default options, since IE returns SelectElement itself and it
+  // does not operate as a List.
+  List<OptionElement> get options {
+    return this.children.filter((e) => e is OptionElement);
+  }
 
-
-/// @domName SessionDescription
-class SessionDescription extends NativeFieldWrapperClass1 {
-
-  ///@docsEditable true
-  factory SessionDescription(String sdp) => _SessionDescriptionFactoryProvider.createSessionDescription(sdp);
-  SessionDescription.internal();
-
-
-  /** @domName SessionDescription.addCandidate */
-  void addCandidate(IceCandidate candidate) native "SessionDescription_addCandidate_Callback";
-
-
-  /** @domName SessionDescription.toSdp */
-  String toSdp() native "SessionDescription_toSdp_Callback";
-
+  List<OptionElement> get selectedOptions {
+    // IE does not change the selected flag for single-selection items.
+    if (this.multiple) {
+      return this.options.filter((o) => o.selected);
+    } else {
+      return [this.options[this.selectedIndex]];
+    }
+  }
 }
 // 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
@@ -20155,8 +19044,19 @@
 
 
 /// @domName HTMLShadowElement
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Experimental()
 class ShadowElement extends _Element_Merged {
-  ShadowElement.internal(): super.internal();
+  ShadowElement.internal() : super.internal();
+
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => true;
+
+
+  /** @domName HTMLShadowElement.olderShadowRoot */
+  ShadowRoot get olderShadowRoot native "HTMLShadowElement_olderShadowRoot_Getter";
 
 
   /** @domName HTMLShadowElement.resetStyleInheritance */
@@ -20175,11 +19075,10 @@
 
 
 /// @domName ShadowRoot
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Experimental()
 class ShadowRoot extends DocumentFragment {
-
-  ///@docsEditable true
-  factory ShadowRoot(Element host) => _ShadowRootFactoryProvider.createShadowRoot(host);
-  ShadowRoot.internal(): super.internal();
+  ShadowRoot.internal() : super.internal();
 
 
   /** @domName ShadowRoot.activeElement */
@@ -20240,15 +19139,16 @@
 
 /// @domName SharedWorker
 class SharedWorker extends AbstractWorker {
+  SharedWorker.internal() : super.internal();
 
   ///@docsEditable true
   factory SharedWorker(String scriptURL, [String name]) {
     if (!?name) {
-      return _SharedWorkerFactoryProvider.createSharedWorker(scriptURL);
+      return SharedWorker._create(scriptURL);
     }
-    return _SharedWorkerFactoryProvider.createSharedWorker(scriptURL, name);
+    return SharedWorker._create(scriptURL, name);
   }
-  SharedWorker.internal(): super.internal();
+  static SharedWorker _create(String scriptURL, [String name]) native "SharedWorker_constructor_Callback";
 
 
   /** @domName SharedWorker.port */
@@ -20264,7 +19164,7 @@
 
 /// @domName SharedWorkerContext
 class SharedWorkerContext extends WorkerContext {
-  SharedWorkerContext.internal(): super.internal();
+  SharedWorkerContext.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   SharedWorkerContextEvents get on =>
@@ -20325,7 +19225,7 @@
 
 /// @domName SourceBufferList
 class SourceBufferList extends EventTarget implements List<SourceBuffer> {
-  SourceBufferList.internal(): super.internal();
+  SourceBufferList.internal() : super.internal();
 
 
   /** @domName SourceBufferList.length */
@@ -20457,10 +19357,10 @@
 
 /// @domName HTMLSourceElement
 class SourceElement extends _Element_Merged {
+  SourceElement.internal() : super.internal();
 
   ///@docsEditable true
   factory SourceElement() => document.$dom_createElement("source");
-  SourceElement.internal(): super.internal();
 
 
   /** @domName HTMLSourceElement.media */
@@ -20496,10 +19396,10 @@
 
 /// @domName HTMLSpanElement
 class SpanElement extends _Element_Merged {
+  SpanElement.internal() : super.internal();
 
   ///@docsEditable true
   factory SpanElement() => document.$dom_createElement("span");
-  SpanElement.internal(): super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -20511,10 +19411,11 @@
 
 /// @domName SpeechGrammar
 class SpeechGrammar extends NativeFieldWrapperClass1 {
+  SpeechGrammar.internal();
 
   ///@docsEditable true
-  factory SpeechGrammar() => _SpeechGrammarFactoryProvider.createSpeechGrammar();
-  SpeechGrammar.internal();
+  factory SpeechGrammar() => SpeechGrammar._create();
+  static SpeechGrammar _create() native "SpeechGrammar_constructor_Callback";
 
 
   /** @domName SpeechGrammar.src */
@@ -20542,10 +19443,11 @@
 
 /// @domName SpeechGrammarList
 class SpeechGrammarList extends NativeFieldWrapperClass1 implements List<SpeechGrammar> {
+  SpeechGrammarList.internal();
 
   ///@docsEditable true
-  factory SpeechGrammarList() => _SpeechGrammarListFactoryProvider.createSpeechGrammarList();
-  SpeechGrammarList.internal();
+  factory SpeechGrammarList() => SpeechGrammarList._create();
+  static SpeechGrammarList _create() native "SpeechGrammarList_constructor_Callback";
 
 
   /** @domName SpeechGrammarList.length */
@@ -20697,7 +19599,7 @@
 
 /// @domName SpeechInputEvent
 class SpeechInputEvent extends Event {
-  SpeechInputEvent.internal(): super.internal();
+  SpeechInputEvent.internal() : super.internal();
 
 
   /** @domName SpeechInputEvent.results */
@@ -20733,10 +19635,11 @@
 
 /// @domName SpeechRecognition
 class SpeechRecognition extends EventTarget {
+  SpeechRecognition.internal() : super.internal();
 
   ///@docsEditable true
-  factory SpeechRecognition() => _SpeechRecognitionFactoryProvider.createSpeechRecognition();
-  SpeechRecognition.internal(): super.internal();
+  factory SpeechRecognition() => SpeechRecognition._create();
+  static SpeechRecognition _create() native "SpeechRecognition_constructor_Callback";
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   SpeechRecognitionEvents get on =>
@@ -20875,29 +19778,11 @@
 
 /// @domName SpeechRecognitionError
 class SpeechRecognitionError extends Event {
-  SpeechRecognitionError.internal(): super.internal();
-
-  static const int ABORTED = 2;
-
-  static const int AUDIO_CAPTURE = 3;
-
-  static const int BAD_GRAMMAR = 7;
-
-  static const int LANGUAGE_NOT_SUPPORTED = 8;
-
-  static const int NETWORK = 4;
-
-  static const int NOT_ALLOWED = 5;
-
-  static const int NO_SPEECH = 1;
-
-  static const int OTHER = 0;
-
-  static const int SERVICE_NOT_ALLOWED = 6;
+  SpeechRecognitionError.internal() : super.internal();
 
 
-  /** @domName SpeechRecognitionError.code */
-  int get code native "SpeechRecognitionError_code_Getter";
+  /** @domName SpeechRecognitionError.error */
+  String get error native "SpeechRecognitionError_error_Getter";
 
 
   /** @domName SpeechRecognitionError.message */
@@ -20913,7 +19798,7 @@
 
 /// @domName SpeechRecognitionEvent
 class SpeechRecognitionEvent extends Event {
-  SpeechRecognitionEvent.internal(): super.internal();
+  SpeechRecognitionEvent.internal() : super.internal();
 
 
   /** @domName SpeechRecognitionEvent.result */
@@ -20927,6 +19812,10 @@
   /** @domName SpeechRecognitionEvent.resultIndex */
   int get resultIndex native "SpeechRecognitionEvent_resultIndex_Getter";
 
+
+  /** @domName SpeechRecognitionEvent.results */
+  List<SpeechRecognitionResult> get results native "SpeechRecognitionEvent_results_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
@@ -20940,12 +19829,8 @@
   SpeechRecognitionResult.internal();
 
 
-  /** @domName SpeechRecognitionResult.emma */
-  Document get emma native "SpeechRecognitionResult_emma_Getter";
-
-
-  /** @domName SpeechRecognitionResult.final */
-  bool get finalValue native "SpeechRecognitionResult_final_Getter";
+  /** @domName SpeechRecognitionResult.isFinal */
+  bool get isFinal native "SpeechRecognitionResult_isFinal_Getter";
 
 
   /** @domName SpeechRecognitionResult.length */
@@ -21294,7 +20179,7 @@
 
 /// @domName StorageEvent
 class StorageEvent extends Event {
-  StorageEvent.internal(): super.internal();
+  StorageEvent.internal() : super.internal();
 
 
   /** @domName StorageEvent.key */
@@ -21386,10 +20271,10 @@
 
 /// @domName HTMLStyleElement
 class StyleElement extends _Element_Merged {
+  StyleElement.internal() : super.internal();
 
   ///@docsEditable true
   factory StyleElement() => document.$dom_createElement("style");
-  StyleElement.internal(): super.internal();
 
 
   /** @domName HTMLStyleElement.disabled */
@@ -21501,18 +20386,10 @@
 
 /// @domName HTMLTableCaptionElement
 class TableCaptionElement extends _Element_Merged {
+  TableCaptionElement.internal() : super.internal();
 
   ///@docsEditable true
   factory TableCaptionElement() => document.$dom_createElement("caption");
-  TableCaptionElement.internal(): super.internal();
-
-
-  /** @domName HTMLTableCaptionElement.align */
-  String get align native "HTMLTableCaptionElement_align_Getter";
-
-
-  /** @domName HTMLTableCaptionElement.align */
-  void set align(String value) native "HTMLTableCaptionElement_align_Setter";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -21524,64 +20401,16 @@
 
 /// @domName HTMLTableCellElement
 class TableCellElement extends _Element_Merged {
+  TableCellElement.internal() : super.internal();
 
   ///@docsEditable true
   factory TableCellElement() => document.$dom_createElement("td");
-  TableCellElement.internal(): super.internal();
-
-
-  /** @domName HTMLTableCellElement.abbr */
-  String get abbr native "HTMLTableCellElement_abbr_Getter";
-
-
-  /** @domName HTMLTableCellElement.abbr */
-  void set abbr(String value) native "HTMLTableCellElement_abbr_Setter";
-
-
-  /** @domName HTMLTableCellElement.align */
-  String get align native "HTMLTableCellElement_align_Getter";
-
-
-  /** @domName HTMLTableCellElement.align */
-  void set align(String value) native "HTMLTableCellElement_align_Setter";
-
-
-  /** @domName HTMLTableCellElement.axis */
-  String get axis native "HTMLTableCellElement_axis_Getter";
-
-
-  /** @domName HTMLTableCellElement.axis */
-  void set axis(String value) native "HTMLTableCellElement_axis_Setter";
-
-
-  /** @domName HTMLTableCellElement.bgColor */
-  String get bgColor native "HTMLTableCellElement_bgColor_Getter";
-
-
-  /** @domName HTMLTableCellElement.bgColor */
-  void set bgColor(String value) native "HTMLTableCellElement_bgColor_Setter";
 
 
   /** @domName HTMLTableCellElement.cellIndex */
   int get cellIndex native "HTMLTableCellElement_cellIndex_Getter";
 
 
-  /** @domName HTMLTableCellElement.ch */
-  String get ch native "HTMLTableCellElement_ch_Getter";
-
-
-  /** @domName HTMLTableCellElement.ch */
-  void set ch(String value) native "HTMLTableCellElement_ch_Setter";
-
-
-  /** @domName HTMLTableCellElement.chOff */
-  String get chOff native "HTMLTableCellElement_chOff_Getter";
-
-
-  /** @domName HTMLTableCellElement.chOff */
-  void set chOff(String value) native "HTMLTableCellElement_chOff_Setter";
-
-
   /** @domName HTMLTableCellElement.colSpan */
   int get colSpan native "HTMLTableCellElement_colSpan_Getter";
 
@@ -21598,22 +20427,6 @@
   void set headers(String value) native "HTMLTableCellElement_headers_Setter";
 
 
-  /** @domName HTMLTableCellElement.height */
-  String get height native "HTMLTableCellElement_height_Getter";
-
-
-  /** @domName HTMLTableCellElement.height */
-  void set height(String value) native "HTMLTableCellElement_height_Setter";
-
-
-  /** @domName HTMLTableCellElement.noWrap */
-  bool get noWrap native "HTMLTableCellElement_noWrap_Getter";
-
-
-  /** @domName HTMLTableCellElement.noWrap */
-  void set noWrap(bool value) native "HTMLTableCellElement_noWrap_Setter";
-
-
   /** @domName HTMLTableCellElement.rowSpan */
   int get rowSpan native "HTMLTableCellElement_rowSpan_Getter";
 
@@ -21621,30 +20434,6 @@
   /** @domName HTMLTableCellElement.rowSpan */
   void set rowSpan(int value) native "HTMLTableCellElement_rowSpan_Setter";
 
-
-  /** @domName HTMLTableCellElement.scope */
-  String get scope native "HTMLTableCellElement_scope_Getter";
-
-
-  /** @domName HTMLTableCellElement.scope */
-  void set scope(String value) native "HTMLTableCellElement_scope_Setter";
-
-
-  /** @domName HTMLTableCellElement.vAlign */
-  String get vAlign native "HTMLTableCellElement_vAlign_Getter";
-
-
-  /** @domName HTMLTableCellElement.vAlign */
-  void set vAlign(String value) native "HTMLTableCellElement_vAlign_Setter";
-
-
-  /** @domName HTMLTableCellElement.width */
-  String get width native "HTMLTableCellElement_width_Getter";
-
-
-  /** @domName HTMLTableCellElement.width */
-  void set width(String value) native "HTMLTableCellElement_width_Setter";
-
 }
 // 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
@@ -21655,34 +20444,10 @@
 
 /// @domName HTMLTableColElement
 class TableColElement extends _Element_Merged {
+  TableColElement.internal() : super.internal();
 
   ///@docsEditable true
   factory TableColElement() => document.$dom_createElement("col");
-  TableColElement.internal(): super.internal();
-
-
-  /** @domName HTMLTableColElement.align */
-  String get align native "HTMLTableColElement_align_Getter";
-
-
-  /** @domName HTMLTableColElement.align */
-  void set align(String value) native "HTMLTableColElement_align_Setter";
-
-
-  /** @domName HTMLTableColElement.ch */
-  String get ch native "HTMLTableColElement_ch_Getter";
-
-
-  /** @domName HTMLTableColElement.ch */
-  void set ch(String value) native "HTMLTableColElement_ch_Setter";
-
-
-  /** @domName HTMLTableColElement.chOff */
-  String get chOff native "HTMLTableColElement_chOff_Getter";
-
-
-  /** @domName HTMLTableColElement.chOff */
-  void set chOff(String value) native "HTMLTableColElement_chOff_Setter";
 
 
   /** @domName HTMLTableColElement.span */
@@ -21692,22 +20457,6 @@
   /** @domName HTMLTableColElement.span */
   void set span(int value) native "HTMLTableColElement_span_Setter";
 
-
-  /** @domName HTMLTableColElement.vAlign */
-  String get vAlign native "HTMLTableColElement_vAlign_Getter";
-
-
-  /** @domName HTMLTableColElement.vAlign */
-  void set vAlign(String value) native "HTMLTableColElement_vAlign_Setter";
-
-
-  /** @domName HTMLTableColElement.width */
-  String get width native "HTMLTableColElement_width_Getter";
-
-
-  /** @domName HTMLTableColElement.width */
-  void set width(String value) native "HTMLTableColElement_width_Setter";
-
 }
 // 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
@@ -21718,26 +20467,10 @@
 
 /// @domName HTMLTableElement
 class TableElement extends _Element_Merged {
+  TableElement.internal() : super.internal();
 
   ///@docsEditable true
   factory TableElement() => document.$dom_createElement("table");
-  TableElement.internal(): super.internal();
-
-
-  /** @domName HTMLTableElement.align */
-  String get align native "HTMLTableElement_align_Getter";
-
-
-  /** @domName HTMLTableElement.align */
-  void set align(String value) native "HTMLTableElement_align_Setter";
-
-
-  /** @domName HTMLTableElement.bgColor */
-  String get bgColor native "HTMLTableElement_bgColor_Getter";
-
-
-  /** @domName HTMLTableElement.bgColor */
-  void set bgColor(String value) native "HTMLTableElement_bgColor_Setter";
 
 
   /** @domName HTMLTableElement.border */
@@ -21756,50 +20489,10 @@
   void set caption(TableCaptionElement value) native "HTMLTableElement_caption_Setter";
 
 
-  /** @domName HTMLTableElement.cellPadding */
-  String get cellPadding native "HTMLTableElement_cellPadding_Getter";
-
-
-  /** @domName HTMLTableElement.cellPadding */
-  void set cellPadding(String value) native "HTMLTableElement_cellPadding_Setter";
-
-
-  /** @domName HTMLTableElement.cellSpacing */
-  String get cellSpacing native "HTMLTableElement_cellSpacing_Getter";
-
-
-  /** @domName HTMLTableElement.cellSpacing */
-  void set cellSpacing(String value) native "HTMLTableElement_cellSpacing_Setter";
-
-
-  /** @domName HTMLTableElement.frame */
-  String get frame native "HTMLTableElement_frame_Getter";
-
-
-  /** @domName HTMLTableElement.frame */
-  void set frame(String value) native "HTMLTableElement_frame_Setter";
-
-
   /** @domName HTMLTableElement.rows */
   HtmlCollection get rows native "HTMLTableElement_rows_Getter";
 
 
-  /** @domName HTMLTableElement.rules */
-  String get rules native "HTMLTableElement_rules_Getter";
-
-
-  /** @domName HTMLTableElement.rules */
-  void set rules(String value) native "HTMLTableElement_rules_Setter";
-
-
-  /** @domName HTMLTableElement.summary */
-  String get summary native "HTMLTableElement_summary_Getter";
-
-
-  /** @domName HTMLTableElement.summary */
-  void set summary(String value) native "HTMLTableElement_summary_Setter";
-
-
   /** @domName HTMLTableElement.tBodies */
   HtmlCollection get tBodies native "HTMLTableElement_tBodies_Getter";
 
@@ -21820,14 +20513,6 @@
   void set tHead(TableSectionElement value) native "HTMLTableElement_tHead_Setter";
 
 
-  /** @domName HTMLTableElement.width */
-  String get width native "HTMLTableElement_width_Getter";
-
-
-  /** @domName HTMLTableElement.width */
-  void set width(String value) native "HTMLTableElement_width_Setter";
-
-
   /** @domName HTMLTableElement.createCaption */
   Element createCaption() native "HTMLTableElement_createCaption_Callback";
 
@@ -21873,48 +20558,16 @@
 
 /// @domName HTMLTableRowElement
 class TableRowElement extends _Element_Merged {
+  TableRowElement.internal() : super.internal();
 
   ///@docsEditable true
   factory TableRowElement() => document.$dom_createElement("tr");
-  TableRowElement.internal(): super.internal();
-
-
-  /** @domName HTMLTableRowElement.align */
-  String get align native "HTMLTableRowElement_align_Getter";
-
-
-  /** @domName HTMLTableRowElement.align */
-  void set align(String value) native "HTMLTableRowElement_align_Setter";
-
-
-  /** @domName HTMLTableRowElement.bgColor */
-  String get bgColor native "HTMLTableRowElement_bgColor_Getter";
-
-
-  /** @domName HTMLTableRowElement.bgColor */
-  void set bgColor(String value) native "HTMLTableRowElement_bgColor_Setter";
 
 
   /** @domName HTMLTableRowElement.cells */
   HtmlCollection get cells native "HTMLTableRowElement_cells_Getter";
 
 
-  /** @domName HTMLTableRowElement.ch */
-  String get ch native "HTMLTableRowElement_ch_Getter";
-
-
-  /** @domName HTMLTableRowElement.ch */
-  void set ch(String value) native "HTMLTableRowElement_ch_Setter";
-
-
-  /** @domName HTMLTableRowElement.chOff */
-  String get chOff native "HTMLTableRowElement_chOff_Getter";
-
-
-  /** @domName HTMLTableRowElement.chOff */
-  void set chOff(String value) native "HTMLTableRowElement_chOff_Setter";
-
-
   /** @domName HTMLTableRowElement.rowIndex */
   int get rowIndex native "HTMLTableRowElement_rowIndex_Getter";
 
@@ -21923,14 +20576,6 @@
   int get sectionRowIndex native "HTMLTableRowElement_sectionRowIndex_Getter";
 
 
-  /** @domName HTMLTableRowElement.vAlign */
-  String get vAlign native "HTMLTableRowElement_vAlign_Getter";
-
-
-  /** @domName HTMLTableRowElement.vAlign */
-  void set vAlign(String value) native "HTMLTableRowElement_vAlign_Setter";
-
-
   /** @domName HTMLTableRowElement.deleteCell */
   void deleteCell(int index) native "HTMLTableRowElement_deleteCell_Callback";
 
@@ -21948,23 +20593,7 @@
 
 /// @domName HTMLTableSectionElement
 class TableSectionElement extends _Element_Merged {
-  TableSectionElement.internal(): super.internal();
-
-
-  /** @domName HTMLTableSectionElement.align */
-  String get align native "HTMLTableSectionElement_align_Getter";
-
-
-  /** @domName HTMLTableSectionElement.align */
-  void set align(String value) native "HTMLTableSectionElement_align_Setter";
-
-
-  /** @domName HTMLTableSectionElement.ch */
-  String get ch native "HTMLTableSectionElement_ch_Getter";
-
-
-  /** @domName HTMLTableSectionElement.ch */
-  void set ch(String value) native "HTMLTableSectionElement_ch_Setter";
+  TableSectionElement.internal() : super.internal();
 
 
   /** @domName HTMLTableSectionElement.chOff */
@@ -21979,14 +20608,6 @@
   HtmlCollection get rows native "HTMLTableSectionElement_rows_Getter";
 
 
-  /** @domName HTMLTableSectionElement.vAlign */
-  String get vAlign native "HTMLTableSectionElement_vAlign_Getter";
-
-
-  /** @domName HTMLTableSectionElement.vAlign */
-  void set vAlign(String value) native "HTMLTableSectionElement_vAlign_Setter";
-
-
   /** @domName HTMLTableSectionElement.deleteRow */
   void deleteRow(int index) native "HTMLTableSectionElement_deleteRow_Callback";
 
@@ -22005,7 +20626,7 @@
 /// @domName Text
 class Text extends CharacterData {
   factory Text(String data) => _TextFactoryProvider.createText(data);
-  Text.internal(): super.internal();
+  Text.internal() : super.internal();
 
 
   /** @domName Text.wholeText */
@@ -22029,10 +20650,10 @@
 
 /// @domName HTMLTextAreaElement
 class TextAreaElement extends _Element_Merged {
+  TextAreaElement.internal() : super.internal();
 
   ///@docsEditable true
   factory TextAreaElement() => document.$dom_createElement("textarea");
-  TextAreaElement.internal(): super.internal();
 
 
   /** @domName HTMLTextAreaElement.autofocus */
@@ -22248,7 +20869,7 @@
 
 /// @domName TextEvent
 class TextEvent extends UIEvent {
-  TextEvent.internal(): super.internal();
+  TextEvent.internal() : super.internal();
 
 
   /** @domName TextEvent.data */
@@ -22256,7 +20877,7 @@
 
 
   /** @domName TextEvent.initTextEvent */
-  void initTextEvent(String typeArg, bool canBubbleArg, bool cancelableArg, LocalWindow viewArg, String dataArg) native "TextEvent_initTextEvent_Callback";
+  void initTextEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Window viewArg, String dataArg) native "TextEvent_initTextEvent_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -22284,7 +20905,7 @@
 
 /// @domName TextTrack
 class TextTrack extends EventTarget {
-  TextTrack.internal(): super.internal();
+  TextTrack.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   TextTrackEvents get on =>
@@ -22357,10 +20978,11 @@
 
 /// @domName TextTrackCue
 class TextTrackCue extends EventTarget {
+  TextTrackCue.internal() : super.internal();
 
   ///@docsEditable true
-  factory TextTrackCue(num startTime, num endTime, String text) => _TextTrackCueFactoryProvider.createTextTrackCue(startTime, endTime, text);
-  TextTrackCue.internal(): super.internal();
+  factory TextTrackCue(num startTime, num endTime, String text) => TextTrackCue._create(startTime, endTime, text);
+  static TextTrackCue _create(num startTime, num endTime, String text) native "TextTrackCue_constructor_Callback";
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   TextTrackCueEvents get on =>
@@ -22620,7 +21242,7 @@
 
 /// @domName TextTrackList
 class TextTrackList extends EventTarget implements List<TextTrack> {
-  TextTrackList.internal(): super.internal();
+  TextTrackList.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   TextTrackListEvents get on =>
@@ -22797,10 +21419,10 @@
 
 /// @domName HTMLTitleElement
 class TitleElement extends _Element_Merged {
+  TitleElement.internal() : super.internal();
 
   ///@docsEditable true
   factory TitleElement() => document.$dom_createElement("title");
-  TitleElement.internal(): super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -22872,7 +21494,7 @@
 
 /// @domName TouchEvent
 class TouchEvent extends UIEvent {
-  TouchEvent.internal(): super.internal();
+  TouchEvent.internal() : super.internal();
 
 
   /** @domName TouchEvent.altKey */
@@ -22904,7 +21526,7 @@
 
 
   /** @domName TouchEvent.initTouchEvent */
-  void initTouchEvent(TouchList touches, TouchList targetTouches, TouchList changedTouches, String type, LocalWindow view, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) native "TouchEvent_initTouchEvent_Callback";
+  void initTouchEvent(TouchList touches, TouchList targetTouches, TouchList changedTouches, String type, Window view, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) native "TouchEvent_initTouchEvent_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -23035,11 +21657,19 @@
 
 
 /// @domName HTMLTrackElement
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class TrackElement extends _Element_Merged {
+  TrackElement.internal() : super.internal();
 
   ///@docsEditable true
   factory TrackElement() => document.$dom_createElement("track");
-  TrackElement.internal(): super.internal();
+
+  /**
+   * Checks if this type is supported on the current platform
+   */
+  static bool get supported => true;
 
   static const int ERROR = 3;
 
@@ -23107,7 +21737,7 @@
 
 /// @domName TrackEvent
 class TrackEvent extends Event {
-  TrackEvent.internal(): super.internal();
+  TrackEvent.internal() : super.internal();
 
 
   /** @domName TrackEvent.track */
@@ -23123,7 +21753,7 @@
 
 /// @domName WebKitTransitionEvent
 class TransitionEvent extends Event {
-  TransitionEvent.internal(): super.internal();
+  TransitionEvent.internal() : super.internal();
 
 
   /** @domName WebKitTransitionEvent.elapsedTime */
@@ -23219,7 +21849,7 @@
     e.$dom_initUIEvent(type, canBubble, cancelable, view, detail);
     return e;
   }
-  UIEvent.internal(): super.internal();
+  UIEvent.internal() : super.internal();
 
 
   /** @domName UIEvent.charCode */
@@ -23251,7 +21881,7 @@
 
 
   /** @domName UIEvent.view */
-  Window get view native "UIEvent_view_Getter";
+  WindowBase get view native "UIEvent_view_Getter";
 
 
   /** @domName UIEvent.which */
@@ -23259,7 +21889,7 @@
 
 
   /** @domName UIEvent.initUIEvent */
-  void $dom_initUIEvent(String type, bool canBubble, bool cancelable, LocalWindow view, int detail) native "UIEvent_initUIEvent_Callback";
+  void $dom_initUIEvent(String type, bool canBubble, bool cancelable, Window view, int detail) native "UIEvent_initUIEvent_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -23271,26 +21901,10 @@
 
 /// @domName HTMLUListElement
 class UListElement extends _Element_Merged {
+  UListElement.internal() : super.internal();
 
   ///@docsEditable true
   factory UListElement() => document.$dom_createElement("ul");
-  UListElement.internal(): super.internal();
-
-
-  /** @domName HTMLUListElement.compact */
-  bool get compact native "HTMLUListElement_compact_Getter";
-
-
-  /** @domName HTMLUListElement.compact */
-  void set compact(bool value) native "HTMLUListElement_compact_Setter";
-
-
-  /** @domName HTMLUListElement.type */
-  String get type native "HTMLUListElement_type_Getter";
-
-
-  /** @domName HTMLUListElement.type */
-  void set type(String value) native "HTMLUListElement_type_Setter";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -23302,6 +21916,7 @@
 
 /// @domName Uint16Array
 class Uint16Array extends ArrayBufferView implements List<int> {
+  Uint16Array.internal() : super.internal();
 
   factory Uint16Array(int length) =>
     _TypedArrayFactoryProvider.createUint16Array(length);
@@ -23311,7 +21926,6 @@
 
   factory Uint16Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createUint16Array_fromBuffer(buffer, byteOffset, length);
-  Uint16Array.internal(): super.internal();
 
   static const int BYTES_PER_ELEMENT = 2;
 
@@ -23450,6 +22064,7 @@
 
 /// @domName Uint32Array
 class Uint32Array extends ArrayBufferView implements List<int> {
+  Uint32Array.internal() : super.internal();
 
   factory Uint32Array(int length) =>
     _TypedArrayFactoryProvider.createUint32Array(length);
@@ -23459,7 +22074,6 @@
 
   factory Uint32Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createUint32Array_fromBuffer(buffer, byteOffset, length);
-  Uint32Array.internal(): super.internal();
 
   static const int BYTES_PER_ELEMENT = 4;
 
@@ -23598,6 +22212,7 @@
 
 /// @domName Uint8Array
 class Uint8Array extends ArrayBufferView implements List<int> {
+  Uint8Array.internal() : super.internal();
 
   factory Uint8Array(int length) =>
     _TypedArrayFactoryProvider.createUint8Array(length);
@@ -23607,7 +22222,6 @@
 
   factory Uint8Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createUint8Array_fromBuffer(buffer, byteOffset, length);
-  Uint8Array.internal(): super.internal();
 
   static const int BYTES_PER_ELEMENT = 1;
 
@@ -23746,6 +22360,7 @@
 
 /// @domName Uint8ClampedArray
 class Uint8ClampedArray extends Uint8Array {
+  Uint8ClampedArray.internal() : super.internal();
 
   factory Uint8ClampedArray(int length) =>
     _TypedArrayFactoryProvider.createUint8ClampedArray(length);
@@ -23755,7 +22370,6 @@
 
   factory Uint8ClampedArray.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createUint8ClampedArray_fromBuffer(buffer, byteOffset, length);
-  Uint8ClampedArray.internal(): super.internal();
 
 
   /** @domName Uint8ClampedArray.length */
@@ -23798,7 +22412,7 @@
 
 /// @domName HTMLUnknownElement
 class UnknownElement extends _Element_Merged {
-  UnknownElement.internal(): super.internal();
+  UnknownElement.internal() : super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -23854,6 +22468,10 @@
   ValidityState.internal();
 
 
+  /** @domName ValidityState.badInput */
+  bool get badInput native "ValidityState_badInput_Getter";
+
+
   /** @domName ValidityState.customError */
   bool get customError native "ValidityState_customError_Getter";
 
@@ -23899,10 +22517,10 @@
 
 /// @domName HTMLVideoElement
 class VideoElement extends MediaElement {
+  VideoElement.internal() : super.internal();
 
   ///@docsEditable true
   factory VideoElement() => document.$dom_createElement("video");
-  VideoElement.internal(): super.internal();
 
 
   /** @domName HTMLVideoElement.height */
@@ -24102,7 +22720,7 @@
 
 /// @domName WebGLContextEvent
 class WebGLContextEvent extends Event {
-  WebGLContextEvent.internal(): super.internal();
+  WebGLContextEvent.internal() : super.internal();
 
 
   /** @domName WebGLContextEvent.statusMessage */
@@ -24220,7 +22838,7 @@
 
 /// @domName WebGLRenderingContext
 class WebGLRenderingContext extends CanvasRenderingContext {
-  WebGLRenderingContext.internal(): super.internal();
+  WebGLRenderingContext.internal() : super.internal();
 
   static const int ACTIVE_ATTRIBUTES = 0x8B89;
 
@@ -25570,7 +24188,7 @@
 
 /// @domName WebKitCSSFilterValue
 class WebKitCssFilterValue extends _CssValueList {
-  WebKitCssFilterValue.internal(): super.internal();
+  WebKitCssFilterValue.internal() : super.internal();
 
   static const int CSS_FILTER_BLUR = 10;
 
@@ -25608,9 +24226,21 @@
 // WARNING: Do not edit - generated code.
 
 
+/// @domName WebKitCSSMixFunctionValue
+class WebKitCssMixFunctionValue extends _CssValueList {
+  WebKitCssMixFunctionValue.internal() : super.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.
+
+
 /// @domName WebKitNamedFlow
 class WebKitNamedFlow extends EventTarget {
-  WebKitNamedFlow.internal(): super.internal();
+  WebKitNamedFlow.internal() : super.internal();
 
 
   /** @domName WebKitNamedFlow.firstEmptyRegionIndex */
@@ -25658,8 +24288,11 @@
 
 /// @domName WebSocket
 class WebSocket extends EventTarget {
-  factory WebSocket(String url) => _WebSocketFactoryProvider.createWebSocket(url);
-  WebSocket.internal(): super.internal();
+  WebSocket.internal() : super.internal();
+
+  ///@docsEditable true
+  factory WebSocket(String url) => WebSocket._create(url);
+  static WebSocket _create(String url) native "WebSocket_constructor_Callback";
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   WebSocketEvents get on =>
@@ -25741,9 +24374,62 @@
   /** @domName WebSocket.removeEventListener */
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "WebSocket_removeEventListener_Callback";
 
+  bool send(data) {
+    if ((data is ArrayBuffer || data == null)) {
+      return _send_1(data);
+    }
+    if ((data is ArrayBufferView || data == null)) {
+      return _send_2(data);
+    }
+    if ((data is Blob || data == null)) {
+      return _send_3(data);
+    }
+    if ((data is String || data == null)) {
+      _send_4(data);
+      return;
+    }
+    if ((data is ArrayBufferView || data == null)) {
+      _send_5(data);
+      return;
+    }
+    if ((data is Blob || data == null)) {
+      _send_6(data);
+      return;
+    }
+    if ((data is ArrayBuffer || data == null)) {
+      _send_7(data);
+      return;
+    }
+    throw "Incorrect number or type of arguments";
+  }
 
-  /** @domName WebSocket.send */
-  void send(data) native "WebSocket_send_Callback";
+
+  /** @domName WebSocket.send_1 */
+  bool _send_1(data) native "WebSocket_send_1_Callback";
+
+
+  /** @domName WebSocket.send_2 */
+  bool _send_2(data) native "WebSocket_send_2_Callback";
+
+
+  /** @domName WebSocket.send_3 */
+  bool _send_3(data) native "WebSocket_send_3_Callback";
+
+
+  /** @domName WebSocket.send_4 */
+  void _send_4(data) native "WebSocket_send_4_Callback";
+
+
+  /** @domName WebSocket.send_5 */
+  void _send_5(data) native "WebSocket_send_5_Callback";
+
+
+  /** @domName WebSocket.send_6 */
+  void _send_6(data) native "WebSocket_send_6_Callback";
+
+
+  /** @domName WebSocket.send_7 */
+  void _send_7(data) native "WebSocket_send_7_Callback";
 
 }
 
@@ -25771,7 +24457,7 @@
 
 /// @domName WheelEvent
 class WheelEvent extends MouseEvent {
-  WheelEvent.internal(): super.internal();
+  WheelEvent.internal() : super.internal();
 
 
   /** @domName WheelEvent.webkitDirectionInvertedFromDevice */
@@ -25787,7 +24473,7 @@
 
 
   /** @domName WheelEvent.initWebKitWheelEvent */
-  void initWebKitWheelEvent(int wheelDeltaX, int wheelDeltaY, LocalWindow view, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) native "WheelEvent_initWebKitWheelEvent_Callback";
+  void initWebKitWheelEvent(int wheelDeltaX, int wheelDeltaY, Window view, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) native "WheelEvent_initWebKitWheelEvent_Callback";
 
 
   /** @domName WheelEvent.deltaX */
@@ -25802,15 +24488,663 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+
+/// @domName Window
+class Window extends EventTarget implements WindowBase {
+
+  /**
+   * Executes a [callback] after the next batch of browser layout measurements
+   * has completed or would have completed if any browser layout measurements
+   * had been scheduled.
+   */
+  void requestLayoutFrame(TimeoutHandler callback) {
+    _addMeasurementFrameCallback(callback);
+  }
+
+  /**
+   * Lookup a port by its [name].  Return null if no port is
+   * registered under [name].
+   */
+  lookupPort(String name) {
+    var port = JSON.parse(document.documentElement.attributes['dart-port:$name']);
+    return _deserialize(port);
+  }
+
+  /**
+   * Register a [port] on this window under the given [name].  This
+   * port may be retrieved by any isolate (or JavaScript script)
+   * running in this window.
+   */
+  registerPort(String name, var port) {
+    var serialized = _serialize(port);
+    document.documentElement.attributes['dart-port:$name'] = JSON.stringify(serialized);
+  }
+
+  Window.internal() : super.internal();
+
+  /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
+  WindowEvents get on =>
+    new WindowEvents(this);
+
+  static const int PERSISTENT = 1;
+
+  static const int TEMPORARY = 0;
+
+
+  /** @domName DOMWindow.applicationCache */
+  ApplicationCache get applicationCache native "DOMWindow_applicationCache_Getter";
+
+
+  /** @domName DOMWindow.closed */
+  bool get closed native "DOMWindow_closed_Getter";
+
+
+  /** @domName DOMWindow.console */
+  Console get console native "DOMWindow_console_Getter";
+
+
+  /** @domName DOMWindow.crypto */
+  Crypto get crypto native "DOMWindow_crypto_Getter";
+
+
+  /** @domName DOMWindow.defaultStatus */
+  String get defaultStatus native "DOMWindow_defaultStatus_Getter";
+
+
+  /** @domName DOMWindow.defaultStatus */
+  void set defaultStatus(String value) native "DOMWindow_defaultStatus_Setter";
+
+
+  /** @domName DOMWindow.defaultstatus */
+  String get defaultstatus native "DOMWindow_defaultstatus_Getter";
+
+
+  /** @domName DOMWindow.defaultstatus */
+  void set defaultstatus(String value) native "DOMWindow_defaultstatus_Setter";
+
+
+  /** @domName DOMWindow.devicePixelRatio */
+  num get devicePixelRatio native "DOMWindow_devicePixelRatio_Getter";
+
+
+  /** @domName DOMWindow.document */
+  Document get document native "DOMWindow_document_Getter";
+
+
+  /** @domName DOMWindow.event */
+  Event get event native "DOMWindow_event_Getter";
+
+
+  /** @domName DOMWindow.history */
+  History get history native "DOMWindow_history_Getter";
+
+
+  /** @domName DOMWindow.indexedDB */
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX, '15')
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @Experimental()
+  IdbFactory get indexedDB native "DOMWindow_indexedDB_Getter";
+
+
+  /** @domName DOMWindow.innerHeight */
+  int get innerHeight native "DOMWindow_innerHeight_Getter";
+
+
+  /** @domName DOMWindow.innerWidth */
+  int get innerWidth native "DOMWindow_innerWidth_Getter";
+
+
+  /** @domName DOMWindow.localStorage */
+  Storage get localStorage native "DOMWindow_localStorage_Getter";
+
+
+  /** @domName DOMWindow.location */
+  Location get location native "DOMWindow_location_Getter";
+
+
+  /** @domName DOMWindow.location */
+  void set location(Location value) native "DOMWindow_location_Setter";
+
+
+  /** @domName DOMWindow.locationbar */
+  BarInfo get locationbar native "DOMWindow_locationbar_Getter";
+
+
+  /** @domName DOMWindow.menubar */
+  BarInfo get menubar native "DOMWindow_menubar_Getter";
+
+
+  /** @domName DOMWindow.name */
+  String get name native "DOMWindow_name_Getter";
+
+
+  /** @domName DOMWindow.name */
+  void set name(String value) native "DOMWindow_name_Setter";
+
+
+  /** @domName DOMWindow.navigator */
+  Navigator get navigator native "DOMWindow_navigator_Getter";
+
+
+  /** @domName DOMWindow.offscreenBuffering */
+  bool get offscreenBuffering native "DOMWindow_offscreenBuffering_Getter";
+
+
+  /** @domName DOMWindow.opener */
+  WindowBase get opener native "DOMWindow_opener_Getter";
+
+
+  /** @domName DOMWindow.outerHeight */
+  int get outerHeight native "DOMWindow_outerHeight_Getter";
+
+
+  /** @domName DOMWindow.outerWidth */
+  int get outerWidth native "DOMWindow_outerWidth_Getter";
+
+
+  /** @domName DOMWindow.pagePopupController */
+  PagePopupController get pagePopupController native "DOMWindow_pagePopupController_Getter";
+
+
+  /** @domName DOMWindow.pageXOffset */
+  int get pageXOffset native "DOMWindow_pageXOffset_Getter";
+
+
+  /** @domName DOMWindow.pageYOffset */
+  int get pageYOffset native "DOMWindow_pageYOffset_Getter";
+
+
+  /** @domName DOMWindow.parent */
+  WindowBase get parent native "DOMWindow_parent_Getter";
+
+
+  /** @domName DOMWindow.performance */
+  Performance get performance native "DOMWindow_performance_Getter";
+
+
+  /** @domName DOMWindow.personalbar */
+  BarInfo get personalbar native "DOMWindow_personalbar_Getter";
+
+
+  /** @domName DOMWindow.screen */
+  Screen get screen native "DOMWindow_screen_Getter";
+
+
+  /** @domName DOMWindow.screenLeft */
+  int get screenLeft native "DOMWindow_screenLeft_Getter";
+
+
+  /** @domName DOMWindow.screenTop */
+  int get screenTop native "DOMWindow_screenTop_Getter";
+
+
+  /** @domName DOMWindow.screenX */
+  int get screenX native "DOMWindow_screenX_Getter";
+
+
+  /** @domName DOMWindow.screenY */
+  int get screenY native "DOMWindow_screenY_Getter";
+
+
+  /** @domName DOMWindow.scrollX */
+  int get scrollX native "DOMWindow_scrollX_Getter";
+
+
+  /** @domName DOMWindow.scrollY */
+  int get scrollY native "DOMWindow_scrollY_Getter";
+
+
+  /** @domName DOMWindow.scrollbars */
+  BarInfo get scrollbars native "DOMWindow_scrollbars_Getter";
+
+
+  /** @domName DOMWindow.self */
+  WindowBase get self native "DOMWindow_self_Getter";
+
+
+  /** @domName DOMWindow.sessionStorage */
+  Storage get sessionStorage native "DOMWindow_sessionStorage_Getter";
+
+
+  /** @domName DOMWindow.status */
+  String get status native "DOMWindow_status_Getter";
+
+
+  /** @domName DOMWindow.status */
+  void set status(String value) native "DOMWindow_status_Setter";
+
+
+  /** @domName DOMWindow.statusbar */
+  BarInfo get statusbar native "DOMWindow_statusbar_Getter";
+
+
+  /** @domName DOMWindow.styleMedia */
+  StyleMedia get styleMedia native "DOMWindow_styleMedia_Getter";
+
+
+  /** @domName DOMWindow.toolbar */
+  BarInfo get toolbar native "DOMWindow_toolbar_Getter";
+
+
+  /** @domName DOMWindow.top */
+  WindowBase get top native "DOMWindow_top_Getter";
+
+
+  /** @domName DOMWindow.webkitNotifications */
+  NotificationCenter get webkitNotifications native "DOMWindow_webkitNotifications_Getter";
+
+
+  /** @domName DOMWindow.webkitStorageInfo */
+  StorageInfo get webkitStorageInfo native "DOMWindow_webkitStorageInfo_Getter";
+
+
+  /** @domName DOMWindow.window */
+  WindowBase get window native "DOMWindow_window_Getter";
+
+
+  /** @domName DOMWindow.addEventListener */
+  void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "DOMWindow_addEventListener_Callback";
+
+
+  /** @domName DOMWindow.alert */
+  void alert(String message) native "DOMWindow_alert_Callback";
+
+
+  /** @domName DOMWindow.atob */
+  String atob(String string) native "DOMWindow_atob_Callback";
+
+
+  /** @domName DOMWindow.btoa */
+  String btoa(String string) native "DOMWindow_btoa_Callback";
+
+
+  /** @domName DOMWindow.cancelAnimationFrame */
+  void cancelAnimationFrame(int id) native "DOMWindow_cancelAnimationFrame_Callback";
+
+
+  /** @domName DOMWindow.captureEvents */
+  void captureEvents() native "DOMWindow_captureEvents_Callback";
+
+
+  /** @domName DOMWindow.clearInterval */
+  void clearInterval(int handle) native "DOMWindow_clearInterval_Callback";
+
+
+  /** @domName DOMWindow.clearTimeout */
+  void clearTimeout(int handle) native "DOMWindow_clearTimeout_Callback";
+
+
+  /** @domName DOMWindow.close */
+  void close() native "DOMWindow_close_Callback";
+
+
+  /** @domName DOMWindow.confirm */
+  bool confirm(String message) native "DOMWindow_confirm_Callback";
+
+
+  /** @domName DOMWindow.dispatchEvent */
+  bool $dom_dispatchEvent(Event evt) native "DOMWindow_dispatchEvent_Callback";
+
+
+  /** @domName DOMWindow.find */
+  bool find(String string, bool caseSensitive, bool backwards, bool wrap, bool wholeWord, bool searchInFrames, bool showDialog) native "DOMWindow_find_Callback";
+
+
+  /** @domName DOMWindow.getComputedStyle */
+  CssStyleDeclaration $dom_getComputedStyle(Element element, String pseudoElement) native "DOMWindow_getComputedStyle_Callback";
+
+
+  /** @domName DOMWindow.getMatchedCSSRules */
+  List<CssRule> getMatchedCssRules(Element element, String pseudoElement) native "DOMWindow_getMatchedCSSRules_Callback";
+
+
+  /** @domName DOMWindow.getSelection */
+  DomSelection getSelection() native "DOMWindow_getSelection_Callback";
+
+
+  /** @domName DOMWindow.matchMedia */
+  MediaQueryList matchMedia(String query) native "DOMWindow_matchMedia_Callback";
+
+
+  /** @domName DOMWindow.moveBy */
+  void moveBy(num x, num y) native "DOMWindow_moveBy_Callback";
+
+
+  /** @domName DOMWindow.moveTo */
+  void moveTo(num x, num y) native "DOMWindow_moveTo_Callback";
+
+
+  /** @domName DOMWindow.open */
+  WindowBase open(String url, String name, [String options]) native "DOMWindow_open_Callback";
+
+
+  /** @domName DOMWindow.openDatabase */
+  Database openDatabase(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) native "DOMWindow_openDatabase_Callback";
+
+
+  /** @domName DOMWindow.postMessage */
+  void postMessage(/*SerializedScriptValue*/ message, String targetOrigin, [List messagePorts]) native "DOMWindow_postMessage_Callback";
+
+
+  /** @domName DOMWindow.print */
+  void print() native "DOMWindow_print_Callback";
+
+
+  /** @domName DOMWindow.releaseEvents */
+  void releaseEvents() native "DOMWindow_releaseEvents_Callback";
+
+
+  /** @domName DOMWindow.removeEventListener */
+  void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "DOMWindow_removeEventListener_Callback";
+
+
+  /** @domName DOMWindow.requestAnimationFrame */
+  int requestAnimationFrame(RequestAnimationFrameCallback callback) native "DOMWindow_requestAnimationFrame_Callback";
+
+
+  /** @domName DOMWindow.resizeBy */
+  void resizeBy(num x, num y) native "DOMWindow_resizeBy_Callback";
+
+
+  /** @domName DOMWindow.resizeTo */
+  void resizeTo(num width, num height) native "DOMWindow_resizeTo_Callback";
+
+
+  /** @domName DOMWindow.scroll */
+  void scroll(int x, int y) native "DOMWindow_scroll_Callback";
+
+
+  /** @domName DOMWindow.scrollBy */
+  void scrollBy(int x, int y) native "DOMWindow_scrollBy_Callback";
+
+
+  /** @domName DOMWindow.scrollTo */
+  void scrollTo(int x, int y) native "DOMWindow_scrollTo_Callback";
+
+
+  /** @domName DOMWindow.setInterval */
+  int setInterval(TimeoutHandler handler, int timeout) native "DOMWindow_setInterval_Callback";
+
+
+  /** @domName DOMWindow.setTimeout */
+  int setTimeout(TimeoutHandler handler, int timeout) native "DOMWindow_setTimeout_Callback";
+
+
+  /** @domName DOMWindow.showModalDialog */
+  Object showModalDialog(String url, [Object dialogArgs, String featureArgs]) native "DOMWindow_showModalDialog_Callback";
+
+
+  /** @domName DOMWindow.stop */
+  void stop() native "DOMWindow_stop_Callback";
+
+
+  /** @domName DOMWindow.webkitCancelAnimationFrame */
+  void webkitCancelAnimationFrame(int id) native "DOMWindow_webkitCancelAnimationFrame_Callback";
+
+
+  /** @domName DOMWindow.webkitConvertPointFromNodeToPage */
+  Point webkitConvertPointFromNodeToPage(Node node, Point p) native "DOMWindow_webkitConvertPointFromNodeToPage_Callback";
+
+
+  /** @domName DOMWindow.webkitConvertPointFromPageToNode */
+  Point webkitConvertPointFromPageToNode(Node node, Point p) native "DOMWindow_webkitConvertPointFromPageToNode_Callback";
+
+
+  /** @domName DOMWindow.webkitRequestAnimationFrame */
+  int webkitRequestAnimationFrame(RequestAnimationFrameCallback callback) native "DOMWindow_webkitRequestAnimationFrame_Callback";
+
+
+  /** @domName DOMWindow.webkitRequestFileSystem */
+  void webkitRequestFileSystem(int type, int size, FileSystemCallback successCallback, [ErrorCallback errorCallback]) native "DOMWindow_webkitRequestFileSystem_Callback";
+
+
+  /** @domName DOMWindow.webkitResolveLocalFileSystemURL */
+  void webkitResolveLocalFileSystemUrl(String url, EntryCallback successCallback, [ErrorCallback errorCallback]) native "DOMWindow_webkitResolveLocalFileSystemURL_Callback";
+
+}
+
+/// @docsEditable true
+class WindowEvents extends Events {
+  /// @docsEditable true
+  WindowEvents(EventTarget _ptr) : super(_ptr);
+
+  /// @docsEditable true
+  EventListenerList get contentLoaded => this['DOMContentLoaded'];
+
+  /// @docsEditable true
+  EventListenerList get abort => this['abort'];
+
+  /// @docsEditable true
+  EventListenerList get beforeUnload => this['beforeunload'];
+
+  /// @docsEditable true
+  EventListenerList get blur => this['blur'];
+
+  /// @docsEditable true
+  EventListenerList get canPlay => this['canplay'];
+
+  /// @docsEditable true
+  EventListenerList get canPlayThrough => this['canplaythrough'];
+
+  /// @docsEditable true
+  EventListenerList get change => this['change'];
+
+  /// @docsEditable true
+  EventListenerList get click => this['click'];
+
+  /// @docsEditable true
+  EventListenerList get contextMenu => this['contextmenu'];
+
+  /// @docsEditable true
+  EventListenerList get doubleClick => this['dblclick'];
+
+  /// @docsEditable true
+  EventListenerList get deviceMotion => this['devicemotion'];
+
+  /// @docsEditable true
+  EventListenerList get deviceOrientation => this['deviceorientation'];
+
+  /// @docsEditable true
+  EventListenerList get drag => this['drag'];
+
+  /// @docsEditable true
+  EventListenerList get dragEnd => this['dragend'];
+
+  /// @docsEditable true
+  EventListenerList get dragEnter => this['dragenter'];
+
+  /// @docsEditable true
+  EventListenerList get dragLeave => this['dragleave'];
+
+  /// @docsEditable true
+  EventListenerList get dragOver => this['dragover'];
+
+  /// @docsEditable true
+  EventListenerList get dragStart => this['dragstart'];
+
+  /// @docsEditable true
+  EventListenerList get drop => this['drop'];
+
+  /// @docsEditable true
+  EventListenerList get durationChange => this['durationchange'];
+
+  /// @docsEditable true
+  EventListenerList get emptied => this['emptied'];
+
+  /// @docsEditable true
+  EventListenerList get ended => this['ended'];
+
+  /// @docsEditable true
+  EventListenerList get error => this['error'];
+
+  /// @docsEditable true
+  EventListenerList get focus => this['focus'];
+
+  /// @docsEditable true
+  EventListenerList get hashChange => this['hashchange'];
+
+  /// @docsEditable true
+  EventListenerList get input => this['input'];
+
+  /// @docsEditable true
+  EventListenerList get invalid => this['invalid'];
+
+  /// @docsEditable true
+  EventListenerList get keyDown => this['keydown'];
+
+  /// @docsEditable true
+  EventListenerList get keyPress => this['keypress'];
+
+  /// @docsEditable true
+  EventListenerList get keyUp => this['keyup'];
+
+  /// @docsEditable true
+  EventListenerList get load => this['load'];
+
+  /// @docsEditable true
+  EventListenerList get loadedData => this['loadeddata'];
+
+  /// @docsEditable true
+  EventListenerList get loadedMetadata => this['loadedmetadata'];
+
+  /// @docsEditable true
+  EventListenerList get loadStart => this['loadstart'];
+
+  /// @docsEditable true
+  EventListenerList get message => this['message'];
+
+  /// @docsEditable true
+  EventListenerList get mouseDown => this['mousedown'];
+
+  /// @docsEditable true
+  EventListenerList get mouseMove => this['mousemove'];
+
+  /// @docsEditable true
+  EventListenerList get mouseOut => this['mouseout'];
+
+  /// @docsEditable true
+  EventListenerList get mouseOver => this['mouseover'];
+
+  /// @docsEditable true
+  EventListenerList get mouseUp => this['mouseup'];
+
+  /// @docsEditable true
+  EventListenerList get mouseWheel => this['mousewheel'];
+
+  /// @docsEditable true
+  EventListenerList get offline => this['offline'];
+
+  /// @docsEditable true
+  EventListenerList get online => this['online'];
+
+  /// @docsEditable true
+  EventListenerList get pageHide => this['pagehide'];
+
+  /// @docsEditable true
+  EventListenerList get pageShow => this['pageshow'];
+
+  /// @docsEditable true
+  EventListenerList get pause => this['pause'];
+
+  /// @docsEditable true
+  EventListenerList get play => this['play'];
+
+  /// @docsEditable true
+  EventListenerList get playing => this['playing'];
+
+  /// @docsEditable true
+  EventListenerList get popState => this['popstate'];
+
+  /// @docsEditable true
+  EventListenerList get progress => this['progress'];
+
+  /// @docsEditable true
+  EventListenerList get rateChange => this['ratechange'];
+
+  /// @docsEditable true
+  EventListenerList get reset => this['reset'];
+
+  /// @docsEditable true
+  EventListenerList get resize => this['resize'];
+
+  /// @docsEditable true
+  EventListenerList get scroll => this['scroll'];
+
+  /// @docsEditable true
+  EventListenerList get search => this['search'];
+
+  /// @docsEditable true
+  EventListenerList get seeked => this['seeked'];
+
+  /// @docsEditable true
+  EventListenerList get seeking => this['seeking'];
+
+  /// @docsEditable true
+  EventListenerList get select => this['select'];
+
+  /// @docsEditable true
+  EventListenerList get stalled => this['stalled'];
+
+  /// @docsEditable true
+  EventListenerList get storage => this['storage'];
+
+  /// @docsEditable true
+  EventListenerList get submit => this['submit'];
+
+  /// @docsEditable true
+  EventListenerList get suspend => this['suspend'];
+
+  /// @docsEditable true
+  EventListenerList get timeUpdate => this['timeupdate'];
+
+  /// @docsEditable true
+  EventListenerList get touchCancel => this['touchcancel'];
+
+  /// @docsEditable true
+  EventListenerList get touchEnd => this['touchend'];
+
+  /// @docsEditable true
+  EventListenerList get touchMove => this['touchmove'];
+
+  /// @docsEditable true
+  EventListenerList get touchStart => this['touchstart'];
+
+  /// @docsEditable true
+  EventListenerList get unload => this['unload'];
+
+  /// @docsEditable true
+  EventListenerList get volumeChange => this['volumechange'];
+
+  /// @docsEditable true
+  EventListenerList get waiting => this['waiting'];
+
+  /// @docsEditable true
+  EventListenerList get animationEnd => this['webkitAnimationEnd'];
+
+  /// @docsEditable true
+  EventListenerList get animationIteration => this['webkitAnimationIteration'];
+
+  /// @docsEditable true
+  EventListenerList get animationStart => this['webkitAnimationStart'];
+
+  /// @docsEditable true
+  EventListenerList get transitionEnd => this['webkitTransitionEnd'];
+}
+// 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.
 
 
 /// @domName Worker
 class Worker extends AbstractWorker {
+  Worker.internal() : super.internal();
 
   ///@docsEditable true
-  factory Worker(String scriptUrl) => _WorkerFactoryProvider.createWorker(scriptUrl);
-  Worker.internal(): super.internal();
+  factory Worker(String scriptUrl) => Worker._create(scriptUrl);
+  static Worker _create(String scriptUrl) native "Worker_constructor_Callback";
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   WorkerEvents get on =>
@@ -25843,7 +25177,7 @@
 
 /// @domName WorkerContext
 class WorkerContext extends EventTarget {
-  WorkerContext.internal(): super.internal();
+  WorkerContext.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   WorkerContextEvents get on =>
@@ -25855,6 +25189,10 @@
 
 
   /** @domName WorkerContext.indexedDB */
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX, '15')
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @Experimental()
   IdbFactory get indexedDB native "WorkerContext_indexedDB_Getter";
 
 
@@ -26032,10 +25370,11 @@
 
 /// @domName XPathEvaluator
 class XPathEvaluator extends NativeFieldWrapperClass1 {
+  XPathEvaluator.internal();
 
   ///@docsEditable true
-  factory XPathEvaluator() => _XPathEvaluatorFactoryProvider.createXPathEvaluator();
-  XPathEvaluator.internal();
+  factory XPathEvaluator() => XPathEvaluator._create();
+  static XPathEvaluator _create() native "XPathEvaluator_constructor_Callback";
 
 
   /** @domName XPathEvaluator.createExpression */
@@ -26191,10 +25530,11 @@
 
 /// @domName XMLSerializer
 class XmlSerializer extends NativeFieldWrapperClass1 {
+  XmlSerializer.internal();
 
   ///@docsEditable true
-  factory XmlSerializer() => _XmlSerializerFactoryProvider.createXmlSerializer();
-  XmlSerializer.internal();
+  factory XmlSerializer() => XmlSerializer._create();
+  static XmlSerializer _create() native "XMLSerializer_constructor_Callback";
 
 
   /** @domName XMLSerializer.serializeToString */
@@ -26210,10 +25550,11 @@
 
 /// @domName XSLTProcessor
 class XsltProcessor extends NativeFieldWrapperClass1 {
+  XsltProcessor.internal();
 
   ///@docsEditable true
-  factory XsltProcessor() => _XsltProcessorFactoryProvider.createXsltProcessor();
-  XsltProcessor.internal();
+  factory XsltProcessor() => XsltProcessor._create();
+  static XsltProcessor _create() native "XSLTProcessor_constructor_Callback";
 
 
   /** @domName XSLTProcessor.clearParameters */
@@ -26252,30 +25593,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.
 
-
-class _ArrayBufferFactoryProvider {
-  static ArrayBuffer createArrayBuffer(int length) native "ArrayBuffer_constructor_Callback";
-}
-// 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.
-
-
-class _AudioElementFactoryProvider {
-  static AudioElement createAudioElement([String src]) native "HTMLAudioElement_constructor_Callback";
-}
-// 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.
-
-
-class _BlobFactoryProvider {
-  static Blob createBlob(List blobParts, [String type, String endings]) native "Blob_constructor_Callback";
-}
-// 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.
 
 
@@ -26396,14 +25713,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.
 
-
-class _CssMatrixFactoryProvider {
-  static CssMatrix createCssMatrix([String cssValue]) native "WebKitCSSMatrix_constructor_Callback";
-}
-// 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.
 
 
@@ -26529,7 +25838,7 @@
 
 /// @domName CSSValueList
 class _CssValueList extends CssValue implements List<CssValue> {
-  _CssValueList.internal(): super.internal();
+  _CssValueList.internal() : super.internal();
 
 
   /** @domName CSSValueList.length */
@@ -26644,28 +25953,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 _DataViewFactoryProvider {
-  static DataView createDataView(ArrayBuffer buffer, [int byteOffset, int byteLength]) native "DataView_constructor_Callback";
-}
-// 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.
-
-
-class _DomParserFactoryProvider {
-  static DomParser createDomParser() native "DOMParser_constructor_Callback";
-}
-// 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.
 
 
 /// @domName HTMLElement
 class _Element_Merged extends Element {
-  _Element_Merged.internal(): super.internal();
+  _Element_Merged.internal() : super.internal();
 
 
   /** @domName HTMLElement.children */
@@ -27036,38 +26329,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.
 
-
-class _EventSourceFactoryProvider {
-  static EventSource createEventSource(String scriptUrl) native "EventSource_constructor_Callback";
-}
-// 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.
-
-
-class _FileReaderFactoryProvider {
-  static FileReader createFileReader() native "FileReader_constructor_Callback";
-}
-// 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.
-
-
-class _FileReaderSyncFactoryProvider {
-  static FileReaderSync createFileReaderSync() native "FileReaderSync_constructor_Callback";
-}
-// 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.
-
-
-class _FormDataFactoryProvider {
-  static FormData createFormData([FormElement form]) native "DOMFormData_constructor_Callback";
-}
-// 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.
 
 
@@ -27188,55 +26449,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.
 
-
-class _HttpRequestFactoryProvider {
-  static HttpRequest createHttpRequest() => _createHttpRequest();
-  static HttpRequest _createHttpRequest() native "XMLHttpRequest_constructor_Callback";
-
-  static HttpRequest createHttpRequest_get(String url,
-                                     onSuccess(HttpRequest request)) =>
-      _HttpRequestUtils.get(url, onSuccess, false);
-
-  static HttpRequest createHttpRequest_getWithCredentials(String url,
-                                     onSuccess(HttpRequest request)) =>
-      _HttpRequestUtils.get(url, onSuccess, true);
-}
-// 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.
-
-
-class _IceCandidateFactoryProvider {
-  static IceCandidate createIceCandidate(String label, String candidateLine) native "IceCandidate_constructor_Callback";
-}
-// 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.
-
-
-class _MediaControllerFactoryProvider {
-  static MediaController createMediaController() native "MediaController_constructor_Callback";
-}
-// 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.
-
-
-class _MediaSourceFactoryProvider {
-  static MediaSource createMediaSource() native "MediaSource_constructor_Callback";
-}
-// 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.
-
-
-class _MediaStreamFactoryProvider {
-  static MediaStream createMediaStream(MediaStreamTrackList audioTracks, MediaStreamTrackList videoTracks) native "MediaStream_constructor_Callback";
-}
-// 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.
 
 
@@ -27357,110 +26569,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.
 
-
-class _MessageChannelFactoryProvider {
-  static MessageChannel createMessageChannel() native "MessageChannel_constructor_Callback";
-}
-// 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.
-
-
-class _MutationObserverFactoryProvider {
-  static MutationObserver createMutationObserver(MutationCallback callback) native "MutationObserver_constructor_Callback";
-}
-// 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.
-
-
-class _NotificationFactoryProvider {
-  static Notification createNotification(String title, [Map options]) native "Notification_constructor_Callback";
-}
-// 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.
-
-
-class _OptionElementFactoryProvider {
-  static OptionElement createOptionElement([String data, String value, bool defaultSelected, bool selected]) native "HTMLOptionElement_constructor_Callback";
-}
-// 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.
-
-
-class _PeerConnection00FactoryProvider {
-  static PeerConnection00 createPeerConnection00(String serverConfiguration, IceCallback iceCallback) native "PeerConnection00_constructor_Callback";
-}
-// 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.
-
-
-class _RtcIceCandidateFactoryProvider {
-  static RtcIceCandidate createRtcIceCandidate(Map dictionary) native "RTCIceCandidate_constructor_Callback";
-}
-// 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.
-
-
-class _RtcPeerConnectionFactoryProvider {
-  static RtcPeerConnection createRtcPeerConnection(Map rtcIceServers, [Map mediaConstraints]) native "RTCPeerConnection_constructor_Callback";
-}
-// 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.
-
-
-class _RtcSessionDescriptionFactoryProvider {
-  static RtcSessionDescription createRtcSessionDescription(Map dictionary) native "RTCSessionDescription_constructor_Callback";
-}
-// 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.
-
-
-class _SessionDescriptionFactoryProvider {
-  static SessionDescription createSessionDescription(String sdp) native "SessionDescription_constructor_Callback";
-}
-// 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.
-
-
-class _ShadowRootFactoryProvider {
-  static ShadowRoot createShadowRoot(Element host) native "ShadowRoot_constructor_Callback";
-}
-// 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.
-
-
-class _SharedWorkerFactoryProvider {
-  static SharedWorker createSharedWorker(String scriptURL, [String name]) native "SharedWorker_constructor_Callback";
-}
-// 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.
-
-
-class _SpeechGrammarFactoryProvider {
-  static SpeechGrammar createSpeechGrammar() native "SpeechGrammar_constructor_Callback";
-}
-// 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.
-
-
-class _SpeechGrammarListFactoryProvider {
-  static SpeechGrammarList createSpeechGrammarList() native "SpeechGrammarList_constructor_Callback";
-}
-// 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.
 
 
@@ -27581,14 +26689,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.
 
-
-class _SpeechRecognitionFactoryProvider {
-  static SpeechRecognition createSpeechRecognition() native "SpeechRecognition_constructor_Callback";
-}
-// 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.
 
 
@@ -27830,166 +26930,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-class _TextTrackCueFactoryProvider {
-  static TextTrackCue createTextTrackCue(num startTime, num endTime, String text) native "TextTrackCue_constructor_Callback";
-}
-// 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.
-
-
-/// @domName WebKitAnimationList
-class _WebKitAnimationList extends NativeFieldWrapperClass1 implements List<Animation> {
-  _WebKitAnimationList.internal();
-
-
-  /** @domName WebKitAnimationList.length */
-  int get length native "WebKitAnimationList_length_Getter";
-
-  Animation operator[](int index) native "WebKitAnimationList_item_Callback";
-
-  void operator[]=(int index, Animation value) {
-    throw new UnsupportedError("Cannot assign element of immutable List.");
-  }
-  // -- start List<Animation> mixins.
-  // Animation is the element type.
-
-  // From Iterable<Animation>:
-
-  Iterator<Animation> 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<Animation>(this);
-  }
-
-  // From Collection<Animation>:
-
-  void add(Animation value) {
-    throw new UnsupportedError("Cannot add to immutable List.");
-  }
-
-  void addLast(Animation value) {
-    throw new UnsupportedError("Cannot add to immutable List.");
-  }
-
-  void addAll(Collection<Animation> collection) {
-    throw new UnsupportedError("Cannot add to immutable List.");
-  }
-
-  dynamic reduce(dynamic initialValue, dynamic combine(dynamic, Animation)) {
-    return Collections.reduce(this, initialValue, combine);
-  }
-
-  bool contains(Animation element) => Collections.contains(this, element);
-
-  void forEach(void f(Animation element)) => Collections.forEach(this, f);
-
-  Collection map(f(Animation element)) => Collections.map(this, [], f);
-
-  Collection<Animation> filter(bool f(Animation element)) =>
-     Collections.filter(this, <Animation>[], f);
-
-  bool every(bool f(Animation element)) => Collections.every(this, f);
-
-  bool some(bool f(Animation element)) => Collections.some(this, f);
-
-  bool get isEmpty => this.length == 0;
-
-  // From List<Animation>:
-  void set length(int value) {
-    throw new UnsupportedError("Cannot resize immutable List.");
-  }
-
-  void clear() {
-    throw new UnsupportedError("Cannot clear immutable List.");
-  }
-
-  void sort([int compare(Animation a, Animation b)]) {
-    throw new UnsupportedError("Cannot sort immutable List.");
-  }
-
-  int indexOf(Animation element, [int start = 0]) =>
-      Lists.indexOf(this, element, start, this.length);
-
-  int lastIndexOf(Animation element, [int start]) {
-    if (start == null) start = length - 1;
-    return Lists.lastIndexOf(this, element, start);
-  }
-
-  Animation get first => this[0];
-
-  Animation get last => this[length - 1];
-
-  Animation removeAt(int pos) {
-    throw new UnsupportedError("Cannot removeAt on immutable List.");
-  }
-
-  Animation removeLast() {
-    throw new UnsupportedError("Cannot removeLast on immutable List.");
-  }
-
-  void setRange(int start, int rangeLength, List<Animation> from, [int startFrom]) {
-    throw new UnsupportedError("Cannot setRange on immutable List.");
-  }
-
-  void removeRange(int start, int rangeLength) {
-    throw new UnsupportedError("Cannot removeRange on immutable List.");
-  }
-
-  void insertRange(int start, int rangeLength, [Animation initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
-  }
-
-  List<Animation> getRange(int start, int rangeLength) =>
-      Lists.getRange(this, start, rangeLength, <Animation>[]);
-
-  // -- end List<Animation> mixins.
-
-
-  /** @domName WebKitAnimationList.item */
-  Animation item(int index) native "WebKitAnimationList_item_Callback";
-
-}
-// 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.
-
-
-class _WorkerFactoryProvider {
-  static Worker createWorker(String scriptUrl) native "Worker_constructor_Callback";
-}
-// 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.
-
-
-class _XPathEvaluatorFactoryProvider {
-  static XPathEvaluator createXPathEvaluator() native "XPathEvaluator_constructor_Callback";
-}
-// 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.
-
-
-class _XmlSerializerFactoryProvider {
-  static XmlSerializer createXmlSerializer() native "XMLSerializer_constructor_Callback";
-}
-// 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.
-
-
-class _XsltProcessorFactoryProvider {
-  static XsltProcessor createXsltProcessor() native "XSLTProcessor_constructor_Callback";
-}
-// 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.
-
-
 abstract class _AttributeMap implements Map<String, String> {
   final Element _element;
 
@@ -28220,7 +27160,7 @@
  * is the container that displays a [Document]'s content. All web scripting
  * happens within the context of a [Window] object.
  *
- * **Note:** This class represents any window, whereas [LocalWindow] is
+ * **Note:** This class represents any window, whereas [Window] is
  * used to access the properties and content of the current window.
  *
  * See also:
@@ -28228,7 +27168,7 @@
  * * [DOM Window](https://developer.mozilla.org/en-US/docs/DOM/window) from MDN.
  * * [Window](http://www.w3.org/TR/Window/) from the W3C.
  */
-abstract class Window {
+abstract class WindowBase {
   // Fields.
 
   /**
@@ -28237,8 +27177,8 @@
    *     Location currentLocation = window.location;
    *     print(currentLocation.href); // 'http://www.example.com:80/'
    */
-  Location get location;
-  History get history;
+  LocationBase get location;
+  HistoryBase get history;
 
   /**
    * Indicates whether this window has been closed.
@@ -28253,16 +27193,16 @@
    * A reference to the window that opened this one.
    *
    *     Window thisWindow = window;
-   *     Window otherWindow = thisWindow.open('http://www.example.com/', 'foo');
+   *     WindowBase otherWindow = thisWindow.open('http://www.example.com/', 'foo');
    *     print(otherWindow.opener == thisWindow); // 'true'
    */
-  Window get opener;
+  WindowBase get opener;
 
   /**
    * A reference to the parent of this window.
    *
-   * If this [Window] has no parent, [parent] will return a reference to
-   * the [Window] itself.
+   * If this [WindowBase] has no parent, [parent] will return a reference to
+   * the [WindowBase] itself.
    *
    *     IFrameElement myIFrame = new IFrameElement();
    *     window.document.body.elements.add(myIFrame);
@@ -28270,13 +27210,13 @@
    *
    *     print(window.parent == window) // 'true'
    */
-  Window get parent;
+  WindowBase get parent;
 
   /**
    * A reference to the topmost window in the window hierarchy.
    *
-   * If this [Window] is the topmost [Window], [top] will return a reference to
-   * the [Window] itself.
+   * If this [WindowBase] is the topmost [WindowBase], [top] will return a
+   * reference to the [WindowBase] itself.
    *
    *     // Add an IFrame to the current window.
    *     IFrameElement myIFrame = new IFrameElement();
@@ -28291,13 +27231,13 @@
    *
    *     print(window.top == window) // 'true'
    */
-  Window get top;
+  WindowBase get top;
 
   // Methods.
   /**
    * Closes the window.
    *
-   * This method should only succeed if the [Window] object is
+   * This method should only succeed if the [WindowBase] object is
    * **script-closeable** and the window calling [close] is allowed to navigate
    * the window.
    *
@@ -28326,11 +27266,11 @@
   void postMessage(var message, String targetOrigin, [List messagePorts]);
 }
 
-abstract class Location {
+abstract class LocationBase {
   void set href(String val);
 }
 
-abstract class History {
+abstract class HistoryBase {
   void back();
   void forward();
   void go(int distance);
@@ -29905,7 +28845,7 @@
   void stopImmediatePropagation() => _parent.stopImmediatePropagation();
   void stopPropagation() => _parent.stopPropagation();
   void $dom_initUIEvent(String type, bool canBubble, bool cancelable,
-      LocalWindow view, int detail) {
+      Window view, int detail) {
     throw new UnsupportedError("Cannot initialize a UI Event from a KeyEvent.");
   }
   void $dom_initEvent(String eventTypeArg, bool canBubbleArg,
@@ -29921,7 +28861,7 @@
     throw new UnsupportedError("keyIdentifier is unsupported.");
   }
   void $dom_initKeyboardEvent(String type, bool canBubble, bool cancelable,
-      LocalWindow view, String keyIdentifier, int keyLocation, bool ctrlKey,
+      Window view, String keyIdentifier, int keyLocation, bool ctrlKey,
       bool altKey, bool shiftKey, bool metaKey,
       bool altGraphKey) {
     throw new UnsupportedError(
@@ -30001,16 +28941,6 @@
   static ensureNative(List list) => list;  // TODO: make sure.
 }
 
-class _PointFactoryProvider {
-  static Point createPoint(num x, num y) => _createWebKitPoint(x, y);
-  static _createWebKitPoint(num x, num y) native "WebKitPoint_constructor_Callback";
-}
-
-class _WebSocketFactoryProvider {
-  static WebSocket createWebSocket(String url) => _createWebSocket(url);
-  static _createWebSocket(String url) native "WebSocket_constructor_Callback";
-}
-
 class _TextFactoryProvider {
   static Text createText(String data) => document.$dom_createTextNode(data);
 }
@@ -30271,7 +29201,6 @@
 
 typedef void _MeasurementCallback();
 
-
 /**
  * This class attempts to invoke a callback as soon as the current event stack
  * unwinds, but before the browser repaints.
@@ -30286,7 +29215,7 @@
    * Creates the best possible measurement scheduler for the current platform.
    */
   factory _MeasurementScheduler.best(_MeasurementCallback callback) {
-    if (_isMutationObserverSupported()) {
+    if (MutationObserver.supported) {
       return new _MutationObserverScheduler(callback);
     }
     return new _PostMessageScheduler(callback);
@@ -30638,18 +29567,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-/**
- * Checks to see if the mutation observer API is supported on the current
- * platform.
- */
-bool _isMutationObserverSupported() {
-  return true;
-}
-// 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.
-
-
 // TODO(rnystrom): add a way to supress public classes from DartDoc output.
 // TODO(jacobr): we can remove this class now that we are using the $dom_
 // convention for deprecated methods rather than truly private methods.
@@ -30777,17 +29694,18 @@
   invoke(String methodName, [List args = null]) native "NPObject_invoke";
 }
 
-class _DOMWindowCrossFrame extends NativeFieldWrapperClass1 implements Window {
+class _DOMWindowCrossFrame extends NativeFieldWrapperClass1 implements
+    WindowBase {
   _DOMWindowCrossFrame.internal();
 
   // Fields.
-  History get history native "DOMWindow_history_cross_frame_Getter";
-  Location get location native "DOMWindow_location_cross_frame_Getter";
+  HistoryBase get history native "DOMWindow_history_cross_frame_Getter";
+  LocationBase get location native "DOMWindow_location_cross_frame_Getter";
   bool get closed native "DOMWindow_closed_Getter";
   int get length native "DOMWindow_length_Getter";
-  Window get opener native "DOMWindow_opener_Getter";
-  Window get parent native "DOMWindow_parent_Getter";
-  Window get top native "DOMWindow_top_Getter";
+  WindowBase get opener native "DOMWindow_opener_Getter";
+  WindowBase get parent native "DOMWindow_parent_Getter";
+  WindowBase get top native "DOMWindow_top_Getter";
 
   // Methods.
   void close() native "DOMWindow_close_Callback";
@@ -30797,7 +29715,7 @@
   String get typeName => "DOMWindow";
 }
 
-class _HistoryCrossFrame extends NativeFieldWrapperClass1 implements History {
+class _HistoryCrossFrame extends NativeFieldWrapperClass1 implements HistoryBase {
   _HistoryCrossFrame.internal();
 
   // Methods.
@@ -30809,7 +29727,7 @@
   String get typeName => "History";
 }
 
-class _LocationCrossFrame extends NativeFieldWrapperClass1 implements Location {
+class _LocationCrossFrame extends NativeFieldWrapperClass1 implements LocationBase {
   _LocationCrossFrame.internal();
 
   // Fields.
diff --git a/sdk/lib/html/doc/html.dartdoc b/sdk/lib/html/doc/html.dartdoc
deleted file mode 100644
index 20d1e3a..0000000
--- a/sdk/lib/html/doc/html.dartdoc
+++ /dev/null
@@ -1,37 +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.
-
-// Fake dart:html library for documentation.
-
-/// The Dart HTML5 Library.
-#library("dart:html");
-
-#source('interface/AbstractWorker.dartdoc');
-#source('interface/Element.dartdoc');
-#source('interface/Event.dartdoc');
-#source('interface/EventTarget.dartdoc');
-#source('interface/HttpRequest.dartdoc');
-#source('interface/MouseEvent.dartdoc');
-#source('interface/Storage.dartdoc');
-#source('interface/Node.dartdoc');
-#source('interface/UIEvent.dartdoc');
-#source('interface/WebSocket.dartdoc');
-
-// Implementation files that appear to be necessary to load the sources.
-
-//#source('nodoc-src/SomeFile.dart');
-
-// Global definitions.
-
-/**
- * The top-level Window object.
- */
-Window get window() => null;
-
-/**
- * The top-level Document object.
- */
-Document get document() => null;
-
-typedef void EventListener(Event event);
diff --git a/sdk/lib/html/html_common/html_common.dart b/sdk/lib/html/html_common/html_common.dart
index 18c63a9..102308d 100644
--- a/sdk/lib/html/html_common/html_common.dart
+++ b/sdk/lib/html/html_common/html_common.dart
@@ -9,6 +9,7 @@
 
 part 'filtered_element_list.dart';
 part 'lists.dart';
+part 'metadata.dart';
 
 // For annotating deprecated APIs.
 // TODO: remove once @deprecated is added to dart core.
diff --git a/sdk/lib/html/html_common/html_common_dart2js.dart b/sdk/lib/html/html_common/html_common_dart2js.dart
index 559f983..81745d3c 100644
--- a/sdk/lib/html/html_common/html_common_dart2js.dart
+++ b/sdk/lib/html/html_common/html_common_dart2js.dart
@@ -10,6 +10,7 @@
 part 'conversions.dart';
 part 'filtered_element_list.dart';
 part 'lists.dart';
+part 'metadata.dart';
 
 // For annotating deprecated APIs.
 // TODO: remove once @deprecated is added to dart core.
diff --git a/sdk/lib/html/html_common/metadata.dart b/sdk/lib/html/html_common/metadata.dart
new file mode 100644
index 0000000..577d1a1
--- /dev/null
+++ b/sdk/lib/html/html_common/metadata.dart
@@ -0,0 +1,42 @@
+// 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_common;
+
+/**
+ * An annotation used to mark a feature as only being supported by a subset
+ * of the browsers that Dart supports by default.
+ *
+ * If an API is not annotated with [SupportedBrowser] then it is assumed to
+ * work on all browsers Dart supports.
+ */
+class SupportedBrowser {
+  static const String CHROME = "Chrome";
+  static const String FIREFOX = "Firefox";
+  static const String IE = "Internet Explorer";
+  static const String SAFARI = "Safari";
+
+  /// The name of the browser.
+  final String browserName;
+  /// The minimum version of the browser that supports the feature, or null
+  /// if supported on all versions.
+  final String minimumVersion;
+
+  const SupportedBrowser(this.browserName, [this.minimumVersion]);
+}
+
+
+/**
+ * An annotation used to mark an API as being experimental.
+ *
+ * An API is considered to be experimental if it is still going through the
+ * process of stabilizing and is subject to change or removal.
+ *
+ * See also:
+ *
+ * * [W3C recommendation](http://en.wikipedia.org/wiki/W3C_recommendation)
+ */
+class Experimental {
+  const Experimental();
+}
diff --git a/sdk/lib/html/idl/dart/dart.idl b/sdk/lib/html/idl/dart/dart.idl
deleted file mode 100644
index 74f7e96..0000000
--- a/sdk/lib/html/idl/dart/dart.idl
+++ /dev/null
@@ -1,346 +0,0 @@
-
-// This file introduces / supplements and forces Dart declarations.
-
-module core {
-  [Supplemental]
-  interface Document {
-    [Suppressed] DOMObject getCSSCanvasContext(in DOMString contextId, in DOMString name, in long width, in long height);
-    CanvasRenderingContext getCSSCanvasContext(in DOMString contextId, in DOMString name, in long width, in long height);
-  };
-};
-
-module dom {
-  // Force ElementTraversal. WebKit defines these directly.
-  interface ElementTraversal {
-    readonly attribute unsigned long childElementCount;
-    readonly attribute Element firstElementChild;
-    readonly attribute Element lastElementChild;
-    readonly attribute Element nextElementSibling;
-    readonly attribute Element previousElementSibling;
-  };
-  Element implements ElementTraversal;
-
-  [Callback]
-  interface TimeoutHandler {
-    void handleEvent();
-  };
-};
-
-module html {
-  [Supplemental]
-  interface Console {
-    [Suppressed] void assert(in boolean condition);
-    [CallWith=ScriptArguments|CallStack] void assertCondition(boolean condition);
-  };
-
-  interface HTMLCanvasElement {
-    [Suppressed] DOMString toDataURL([TreatNullAs=NullString, TreatUndefinedAs=NullString,Optional=DefaultIsUndefined] in DOMString type) raises(DOMException);
-    [Custom] DOMString toDataURL([TreatNullAs=NullString, TreatUndefinedAs=NullString,Optional=DefaultIsUndefined] in DOMString type, [Optional] in float quality) raises(DOMException);
-  };
-
-  [Supplemental]
-  interface HTMLOptionsCollection {
-    [Suppressed] void add([Optional] in HTMLOptionElement element, [Optional] in long before);
-  };
-
-  [Supplemental]
-  interface HTMLSelectElement {
-    [Suppressed] void add([Optional=DefaultIsUndefined] in HTMLElement element, [Optional=DefaultIsUndefined] in HTMLElement before);
-    [Suppressed, Custom] void remove();
-    [Custom] void remove(in long index);
-    [Custom] void remove(in HTMLOptionElement option);
-  };
-
-  [Supplemental]
-  interface ImageData {
-    readonly attribute Uint8ClampedArray data;
-  };
-
-  [Supplemental]
-  interface HTMLMediaElement {
-    // Adding media events.
-    attribute EventListener oncanplay;
-    attribute EventListener oncanplaythrough;
-    attribute EventListener ondurationchange;
-    attribute EventListener onemptied;
-    attribute EventListener onended;
-    attribute EventListener onloadeddata;
-    attribute EventListener onloadedmetadata;
-    attribute EventListener onloadstart;
-    attribute EventListener onpause;
-    attribute EventListener onplay;
-    attribute EventListener onplaying;
-    attribute EventListener onprogress;
-    attribute EventListener onratechange;
-    attribute EventListener onseeked;
-    attribute EventListener onseeking;
-    attribute EventListener onshow;
-    attribute EventListener onstalled;
-    attribute EventListener onsuspend;
-    attribute EventListener ontimeupdate;
-    attribute EventListener onvolumechange;
-    attribute EventListener onwaiting;
-  };
-
-  [Supplemental]
-  interface WebGLContextEvent {
-    [Suppressed] void initEvent([Optional] in DOMString eventTypeArg,
-                                [Optional] in boolean canBubbleArg,
-                                [Optional] in boolean cancelableArg,
-                                [Optional] in DOMString statusMessageArg);
-  };
-};
-
-module html {
-  [Supplemental]
-  interface WebGLRenderingContext {
-
-    //void         compressedTexImage2D(in unsigned long target, in long level, in unsigned long internalformat, in unsigned long width, in unsigned long height, in long border, in unsigned long imageSize, const void* data);
-    //void         compressedTexSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset, in unsigned long width, in unsigned long height, in unsigned long format, in unsigned long imageSize, const void* data);
-
-    [Custom] any getBufferParameter(in unsigned long target, in unsigned long pname) raises(DOMException);
-    [Suppressed, StrictTypeChecking, Custom] void getBufferParameter();
-
-    [Custom] any getFramebufferAttachmentParameter(in unsigned long target, in unsigned long attachment, in unsigned long pname) raises(DOMException);
-    [Suppressed, StrictTypeChecking, Custom] void getFramebufferAttachmentParameter();
-
-    [Custom] any getParameter(in unsigned long pname) raises(DOMException);
-    [Suppressed, StrictTypeChecking, Custom] void getParameter();
-
-    [Custom] any getProgramParameter(in WebGLProgram program, in unsigned long pname) raises(DOMException);
-    [Suppressed, StrictTypeChecking, Custom] void getProgramParameter();
-
-    [Custom] any getRenderbufferParameter(in unsigned long target, in unsigned long pname) raises(DOMException);
-    [Suppressed, StrictTypeChecking, Custom] void getRenderbufferParameter();
-
-    [Custom] any getShaderParameter(in WebGLShader shader, in unsigned long pname) raises(DOMException);
-    [Suppressed, StrictTypeChecking, Custom] void getShaderParameter() raises(DOMException);
-
-    // TBD
-    // void glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
-
-    [Custom] any getExtension(DOMString name);
-    [Suppressed, StrictTypeChecking, Custom] void getExtension(DOMString name);
-    [Custom] DOMString[] getSupportedExtensions();
-    [Suppressed, StrictTypeChecking, Custom] void getSupportedExtensions();
-
-    [Custom] any getTexParameter(in unsigned long target, in unsigned long pname) raises(DOMException);
-    [Suppressed, StrictTypeChecking, Custom] void getTexParameter();
-
-    [Custom] any getUniform(in WebGLProgram program, in WebGLUniformLocation location) raises(DOMException);
-    [Suppressed, StrictTypeChecking, Custom] void getUniform();
-
-    [Custom] any getVertexAttrib(in unsigned long index, in unsigned long pname) raises(DOMException);
-    [Suppressed, StrictTypeChecking, Custom] void getVertexAttrib();
-  };
-}
-
-module css {
-  [Supplemental]
-  interface CSSStyleDeclaration {
-    void setProperty(in DOMString propertyName, in DOMString value, [Optional] in DOMString priority);
-    [DartName=_getPropertyValue] DOMString getPropertyValue(in DOMString propertyName);
-  };
-};
-
-module canvas {
-  [Supplemental,
-   Constructor(in long length)]  // Add constructor signature.
-  interface ArrayBuffer {
-  };
-  [Supplemental]
-  interface Float32Array {
-    [Suppressed] void set();
-    [DartName=setElements, Custom] void set(in any array, [Optional] in unsigned long offset);
-  };
-  [Supplemental]
-  interface Float64Array {
-    [Suppressed] void set();
-    [DartName=setElements, Custom] void set(in any array, [Optional] in unsigned long offset);
-  };
-  [Supplemental]
-  interface Int16Array {
-    [Suppressed] void set();
-    [DartName=setElements, Custom] void set(in any array, [Optional] in unsigned long offset);
-  };
-  [Supplemental]
-  interface Int32Array {
-    [Suppressed] void set();
-    [DartName=setElements, Custom] void set(in any array, [Optional] in unsigned long offset);
-  };
-  [Supplemental]
-  interface Int8Array {
-    [Suppressed] void set();
-    [DartName=setElements, Custom] void set(in any array, [Optional] in unsigned long offset);
-  };
-  [Supplemental]
-  interface Uint16Array {
-    [Suppressed] void set();
-    [DartName=setElements, Custom] void set(in any array, [Optional] in unsigned long offset);
-  };
-  [Supplemental]
-  interface Uint32Array {
-    [Suppressed] void set();
-    [DartName=setElements, Custom] void set(in any array, [Optional] in unsigned long offset);
-  };
-  [Supplemental]
-  interface Uint8Array {
-    [Suppressed] void set();
-    [DartName=setElements, Custom] void set(in any array, [Optional] in unsigned long offset);
-  };
-
-  [Supplemental]
-  interface Uint8ClampedArray {
-    // Avoid 'overriding static member BYTES_PER_ELEMENT'.
-    [Suppressed] const long BYTES_PER_ELEMENT = 1;
-
-    [Suppressed] void set();
-    [DartName=setElements, Custom] void set(in any array, [Optional] in unsigned long offset);
-  };
-
-  [Supplemental,
-   Constructor(in ArrayBuffer buffer,
-               [Optional] in unsigned long byteOffset,
-               [Optional] in unsigned long byteLength)
-   ]
-  interface DataView {
-    // Undo this:
-    // We have to use custom code because our code generator does not support int8_t type.
-    // int8_t getInt8(in unsigned long byteOffset);
-    // uint8_t getUint8(in unsigned long byteOffset);
-    [Suppressed] DOMObject getInt8();
-    [Suppressed] DOMObject getUint8();
-    byte getInt8(in unsigned long byteOffset)
-        raises (DOMException);
-    octet getUint8(in unsigned long byteOffset)
-        raises (DOMException);
-
-    // We have to use custom code because our code generator does not support uint8_t type.
-    // void setInt8(in unsigned long byteOffset, in int8_t value);
-    // void setUint8(in unsigned long byteOffset, in uint8_t value);
-    [Suppressed] void setInt8();
-    [Suppressed] void setUint8();
-    void setInt8(in unsigned long byteOffset, in byte value)
-        raises (DOMException);
-    void setUint8(in unsigned long byteOffset, in octet value)
-        raises (DOMException);
-  };
-};
-
-module storage {
-  // TODO(vsm): Define new names for these (see b/4436830).
-  [Supplemental]
-  interface IDBCursor {
-    [DartName=continueFunction] void continue([Optional] in IDBKey key);
-  };
-  [Supplemental]
-  interface IDBDatabase {
-    // These variants are slated for removal from WebKit.  Suppress to bring our
-    // API in line with the most recent spec.
-    [Suppressed, CallWith=ScriptExecutionContext] IDBTransaction transaction(in DOMStringList storeNames, in unsigned short mode)
-        raises (IDBDatabaseException);
-    [Suppressed, CallWith=ScriptExecutionContext] IDBTransaction transaction(in DOMString[] storeNames, in unsigned short mode)
-        raises (IDBDatabaseException);
-    [Suppressed, CallWith=ScriptExecutionContext] IDBTransaction transaction(in DOMString storeName, in unsigned short mode)
-        raises (IDBDatabaseException);
-  };
-  [Supplemental]
-  interface IDBIndex {
-    [DartName=getObject] IDBRequest get(in IDBKey key);
-  };
-  [Supplemental]
-  interface IDBObjectStore {
-    [DartName=getObject] IDBRequest get(in IDBKey key);
-    [DartName=getObject] IDBRequest get(in IDBKeyRange key);
-  };
-
-  [Supplemental]
-  interface IDBKeyRange {
-    [DartName=only_] static IDBKeyRange only(in IDBKey value) raises (IDBDatabaseException);
-    [DartName=lowerBound_] static IDBKeyRange lowerBound(in IDBKey bound, [Optional] in boolean open) raises (IDBDatabaseException);
-    [DartName=upperBound_] static IDBKeyRange upperBound(in IDBKey bound, [Optional] in boolean open) raises (IDBDatabaseException);
-    [DartName=bound_] static IDBKeyRange bound(in IDBKey lower, in IDBKey upper, [Optional] in boolean lowerOpen, [Optional] in boolean upperOpen) raises (IDBDatabaseException);
-  };
-
-  interface EntrySync {
-    // Native implementation is declared to return EntrySync.
-    [Suppressed] DirectoryEntrySync getParent();
-    EntrySync getParent();
-  };
-};
-
-
-module html {
-  [Supplemental,
-   CustomConstructor,
-   Constructor(in Array blobParts,
-               [Optional] in DOMString type, [Optional] in DOMString endings)
-   ]
-  interface Blob {
-  };
-};
-
-module html {
-  [Supplemental, Callback] // Add missing Callback attribute.
-  interface VoidCallback {
-  };
-};
-
-module svg {
-  interface SVGNumber {
-    [StrictTypeChecking, Custom] attribute float value;
-  };
-}
-
-module core {
-  [Supplemental,
-   CustomConstructor,
-   // Provide missing constructor signature.
-   Constructor(MutationCallback callback)]
-  interface MutationObserver {
-    // Rename 'observe' so we can define a new 'observe' API that calls the
-    // original.
-    [DartName=_observe] void observe(in Node target, in Dictionary options)
-        raises(DOMException);
-  };
-}
-
-module html {
-    [Supplemental,
-     CustomConstructor,
-     // Provide missing constructor signature.
-     Constructor([Optional] in HTMLFormElement form)]
-    interface DOMFormData {
-      [Suppressed] void append(in DOMString name, in DOMString value, in DOMString filename);
-      [Custom] void append(in DOMString name, in DOMString value);
-      [Custom] void append(in DOMString name, in Blob value, [Optional] in DOMString filename);
-    };
-}
-
-module storage {
-  [Supplemental]
-  interface SQLResultSetRowList {
-    // Change the return type to Dictionary so that rows are exposed in the Dart
-    // API as a Maps, with the appropriate conversion in JavaScript.
-    [Suppressed] DOMObject item(in unsigned long index);
-    [Custom] Dictionary item(in unsigned long index);
-  };
-}
-
-module websockets {
-  [Supplemental]
-  interface WebSocket {
-    // Suppress the default since it has non-standard return type and add
-    // overrides.
-    [Suppressed] boolean send(in DOMString data) raises(DOMException);
-    [Custom] void send(DOMString data) raises(DOMException);
-    [Custom] void send(Blob data) raises(DOMException);
-    [Custom] void send(ArrayBuffer data) raises(DOMException);
-    [Custom] void send(ArrayBufferView data) raises(DOMException);
-  };
-}
-
-module core {
-  [Suppressed]
-  interface Entity {};
-}
diff --git a/sdk/lib/html/scripts/htmlrenamer.py b/sdk/lib/html/scripts/htmlrenamer.py
deleted file mode 100644
index 89b8273..0000000
--- a/sdk/lib/html/scripts/htmlrenamer.py
+++ /dev/null
@@ -1,414 +0,0 @@
-#!/usr/bin/python
-# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-import re
-
-html_interface_renames = {
-    'CDATASection': 'CDataSection',
-    'DOMApplicationCache': 'ApplicationCache',
-    'DOMCoreException': 'DomException',
-    'DOMFileSystem': 'FileSystem',
-    'DOMFileSystemSync': 'FileSystemSync',
-    'DOMFormData': 'FormData',
-    'DOMURL': 'Url',
-    'DOMWindow': 'LocalWindow',
-    'History': 'LocalHistory',
-    'HTMLDocument' : 'HtmlDocument',
-    'IDBAny': '_Any', # Suppressed, but needs to exist for Dartium.
-    'IDBFactory': 'IdbFactory', # Manual to avoid name conflicts.
-    'Location': 'LocalLocation',
-    'SVGDocument': 'SvgDocument', # Manual to avoid name conflicts.
-    'SVGElement': 'SvgElement', # Manual to avoid name conflicts.
-    'SVGException': 'SvgException', # Manual of avoid conflict with Exception.
-    'SVGSVGElement': 'SvgSvgElement', # Manual to avoid name conflicts.
-    'WebGLVertexArrayObjectOES': 'WebGLVertexArrayObject',
-    'WebKitAnimation': 'Animation',
-    'WebKitAnimationEvent': 'AnimationEvent',
-    'WebKitBlobBuilder': 'BlobBuilder',
-    'WebKitCSSKeyframeRule': 'CssKeyframeRule',
-    'WebKitCSSKeyframesRule': 'CssKeyframesRule',
-    'WebKitCSSMatrix': 'CssMatrix',
-    'WebKitCSSTransformValue': 'CssTransformValue',
-    'WebKitFlags': 'Flags',
-    'WebKitLoseContext': 'LoseContext',
-    'WebKitPoint': 'Point',
-    'WebKitTransitionEvent': 'TransitionEvent',
-    'XMLHttpRequest': 'HttpRequest',
-    'XMLHttpRequestException': 'HttpRequestException',
-    'XMLHttpRequestProgressEvent': 'HttpRequestProgressEvent',
-    'XMLHttpRequestUpload': 'HttpRequestUpload',
-}
-
-# 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 = set([
-  'CustomEvent.initCustomEvent',
-  'Document.createElement',
-  'Document.createElementNS',
-  'Document.createEvent',
-  'Document.createRange',
-  'Document.createTextNode',
-  'Document.createTouch',
-  'Document.createTouchList',
-  'Document.getElementById',
-  'Document.getElementsByClassName',
-  'Document.getElementsByName',
-  'Document.getElementsByTagName',
-  'Document.querySelector',
-  'Document.querySelectorAll',
-
-  # Moved to HTMLDocument.
-  'Document.body',
-  'Document.caretRangeFromPoint',
-  'Document.elementFromPoint',
-  'Document.getCSSCanvasContext',
-  'Document.head',
-  'Document.lastModified',
-  'Document.preferredStylesheetSet',
-  'Document.referrer',
-  'Document.selectedStylesheetSet',
-  'Document.styleSheets',
-  'Document.title',
-  'Document.webkitCancelFullScreen',
-  'Document.webkitExitFullscreen',
-  'Document.webkitExitPointerLock',
-  'Document.webkitFullscreenElement',
-  'Document.webkitFullscreenEnabled',
-  'Document.webkitHidden',
-  'Document.webkitIsFullScreen',
-  'Document.webkitPointerLockElement',
-  'Document.webkitVisibilityState',
-
-  'DocumentFragment.querySelector',
-  'DocumentFragment.querySelectorAll',
-  'Element.childElementCount',
-  'Element.children',
-  'Element.className',
-  'Element.firstElementChild',
-  'Element.getAttribute',
-  'Element.getAttributeNS',
-  'Element.getElementsByClassName',
-  'Element.getElementsByTagName',
-  'Element.hasAttribute',
-  'Element.hasAttributeNS',
-  'Element.lastElementChild',
-  'Element.querySelector',
-  'Element.querySelectorAll',
-  'Element.removeAttribute',
-  'Element.removeAttributeNS',
-  'Element.setAttribute',
-  'Element.setAttributeNS',
-  'ElementTraversal.childElementCount',
-  'ElementTraversal.firstElementChild',
-  'ElementTraversal.lastElementChild',
-  'Event.initEvent',
-  'UIEvent.initUIEvent',
-  'EventTarget.addEventListener',
-  'EventTarget.dispatchEvent',
-  'EventTarget.removeEventListener',
-  'KeyboardEvent.keyIdentifier',
-  'KeyboardEvent.initKeyboardEvent',
-  'LocalWindow.getComputedStyle',
-  'MouseEvent.initMouseEvent',
-  'Node.appendChild',
-  'Node.attributes',
-  'Node.childNodes',
-  'Node.firstChild',
-  'Node.lastChild',
-  "Node.localName",
-  'Node.namespaceURI',
-  'Node.removeChild',
-  'Node.replaceChild',
-  'UIEvent.keyCode',
-  'UIEvent.charCode',
-  'ShadowRoot.getElementById',
-  'ShadowRoot.getElementsByClassName',
-  'ShadowRoot.getElementsByTagName',
-  'Storage.clear',
-  'Storage.getItem',
-  'Storage.key',
-  'Storage.length',
-  'Storage.removeItem',
-  'Storage.setItem',
-  'WheelEvent.wheelDeltaX',
-  'WheelEvent.wheelDeltaY',
-])
-
-# Members from the standard dom that exist in the dart:html library with
-# identical functionality but with cleaner names.
-_renamed_html_members = {
-    'Document.createCDATASection': 'createCDataSection',
-    'Document.defaultView': 'window',
-    'Element.webkitMatchesSelector' : 'matchesSelector',
-    'Element.scrollIntoViewIfNeeded': 'scrollIntoView',
-    'Node.cloneNode': 'clone',
-    'Node.nextSibling': 'nextNode',
-    'Node.ownerDocument': 'document',
-    'Node.parentElement': 'parent',
-    'Node.previousSibling': 'previousNode',
-    'Node.textContent': 'text',
-    'SvgElement.className': '$dom_svgClassName',
-    'AnimatedString.className': '$dom_svgClassName',
-    'Stylable.className': '$dom_svgClassName',
-    'Url.createObjectURL': 'createObjectUrl',
-    'Url.revokeObjectURL': 'revokeObjectUrl',
-}
-
-# 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.
-# Syntax is: ClassName.(get\.|set\.)?MemberName
-# Using get: and set: is optional and should only be used when a getter needs
-# to be suppressed but not the setter, etc.
-# TODO(jacobr): cleanup and augment this list.
-_removed_html_members = set([
-    'NodeList.item',
-    "Attr.*",
-#    "BarProp.*",
-#    "BarInfo.*",
-#    "Blob.webkitSlice",
-#    "CDATASection.*",
-#    "Comment.*",
-#    "DOMImplementation.*",
-    "CanvasRenderingContext2D.setFillColor",
-    "CanvasRenderingContext2D.setStrokeColor",
-    "DivElement.align",
-    'Document.applets',
-    "Document.get:forms",
-#    "Document.get:selectedStylesheetSet",
-#    "Document.set:selectedStylesheetSet",
-#    "Document.get:preferredStylesheetSet",
-    "Document.get:links",
-    "Document.set:domain",
-    "Document.createAttributeNS",
-    "Document.get:inputEncoding",
-    "Document.get:height",
-    "Document.get:width",
-    "Element.getElementsByTagNameNS",
-    "Document.get:compatMode",
-    'Document.images',
-    "Document.importNode",
-    "Document.evaluate",
-    "Document.get:images",
-    "Document.createExpression",
-    "Document.getOverrideStyle",
-    "Document.xmlStandalone",
-    "Document.createComment",
-    "Document.adoptNode",
-    "Document.get:characterSet",
-    "Document.createAttribute",
-    "Document.get:URL",
-    "Document.createEntityReference",
-    "Document.get:documentURI",
-    "Document.set:documentURI",
-    "Document.createNodeIterator",
-    "Document.createProcessingInstruction",
-    "Document.get:doctype",
-    "Document.createTreeWalker",
-    "Document.location",
-    "Document.createNSResolver",
-    "Document.get:xmlEncoding",
-    "Document.get:defaultCharset",
-    "Document.get:applets",
-    "Document.getSelection",
-    "Document.xmlVersion",
-    "Document.get:anchors",
-    "Document.getElementsByTagNameNS",
-    'Document.webkitCurrentFullScreenElement',
-    'Document.webkitFullScreenKeyboardInputAllowed',
-    "DocumentType.*",
-    "Element.setAttributeNode",
-    "Element.getAttributeNode",
-    "Element.removeAttributeNode",
-    "Element.setAttributeNodeNS",
-    "Element.getAttributeNodeNS",
-    "Event.srcElement",
-    "EventSource.URL",
-    "BodyElement.text",
-    "AnchorElement.text",
-    "OptionElement.text",
-    "ScriptElement.text",
-    "TitleElement.text",
-#    "EventSource.get:url",
-# TODO(jacobr): should these be removed?
-    "Document.close",
-    "Document.hasFocus",
-
-    "Document.vlinkColor",
-    "Document.captureEvents",
-    "Document.releaseEvents",
-    "Document.get:compatMode",
-    "Document.designMode",
-    "Document.dir",
-    "Document.all",
-    "Document.write",
-    "Document.fgColor",
-    "Document.bgColor",
-    "Document.get:plugins",
-    "Document.alinkColor",
-    "Document.get:embeds",
-    "Document.open",
-    "Document.clear",
-    "Document.get:scripts",
-    "Document.writeln",
-    "Document.linkColor",
-    "Element.get:itemRef",
-    "Element.outerText",
-    "Element.accessKey",
-    "Element.get:itemType",
-    "Element.innerText",
-    "Element.set:outerHTML",
-    "Element.itemScope",
-    "Element.itemValue",
-    "Element.itemId",
-    "Element.get:itemProp",
-    'Element.scrollIntoView',
-    'Element.get:classList',
-    "FormElement.get:elements",
-    "HTMLFrameElement.*",
-    "HTMLFrameSetElement.*",
-    "HtmlElement.version",
-    "HtmlElement.manifest",
-    "Document.version",
-    "Document.manifest",
-    "HTMLIsIndexElement.*",
-    "MenuElement.compact",
-    "HTMLOptionsCollection.*",
-    "HTMLPropertiesCollection.*",
-    "SelectElement.remove",
-    "NamedNodeMap.*",
-    "Node.isEqualNode",
-    "Node.get:TEXT_NODE",
-    "Node.hasAttributes",
-    "Node.get:DOCUMENT_TYPE_NODE",
-    "Node.get:DOCUMENT_POSITION_FOLLOWING",
-    "Node.lookupNamespaceURI",
-    "Node.get:ELEMENT_NODE",
-    "Node.get:DOCUMENT_FRAGMENT_NODE",
-    "Node.isDefaultNamespace",
-    "Node.compareDocumentPosition",
-    "Node.get:baseURI",
-    "Node.isSameNode",
-    "Node.get:DOCUMENT_POSITION_DISCONNECTED",
-    "Node.get:DOCUMENT_NODE",
-    "Node.get:DOCUMENT_POSITION_CONTAINS",
-    "Node.get:COMMENT_NODE",
-    "Node.get:ENTITY_REFERENCE_NODE",
-    "Node.isSupported",
-    "Node.get:DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC",
-    "Node.get:NOTATION_NODE",
-    "Node.normalize",
-    "Node.get:ATTRIBUTE_NODE",
-    "Node.get:ENTITY_NODE",
-    "Node.get:DOCUMENT_POSITION_CONTAINED_BY",
-    "Node.get:prefix",
-    "Node.set:prefix",
-    "Node.get:DOCUMENT_POSITION_PRECEDING",
-    "Node.get:nodeValue",
-    "Node.set:nodeValue",
-    "Node.get:CDATA_SECTION_NODE",
-    "Node.get:nodeName",
-    "Node.lookupPrefix",
-    "Node.get:PROCESSING_INSTRUCTION_NODE",
-    'ShadowRoot.getElementsByTagNameNS',
-    "LocalWindow.blur",
-    "LocalWindow.clientInformation",
-    "LocalWindow.get:frames",
-    "LocalWindow.get:length",
-    "LocalWindow.focus",
-    "LocalWindow.prompt",
-    "LocalWindow.webkitIndexedDB",
-    "LocalWindow.webkitCancelRequestAnimationFrame",
-    "WheelEvent.wheelDelta",
-    "WorkerContext.webkitIndexedDB",
-    ])
-
-class HtmlRenamer(object):
-  def __init__(self, database):
-    self._database = database
-
-  def RenameInterface(self, interface):
-    if interface.id in html_interface_renames:
-      return html_interface_renames[interface.id]
-    elif interface.id.startswith('HTML'):
-      if any(interface.id in ['Element', 'Document']
-             for interface in self._database.Hierarchy(interface)):
-        return interface.id[len('HTML'):]
-    return self.DartifyTypeName(interface.id)
-
-
-  def RenameMember(self, interface_name, member_node, member, member_prefix=''):
-    """
-    Returns the name of the member in the HTML library or None if the member is
-    suppressed in the HTML library
-    """
-    interface = self._database.GetInterface(interface_name)
-
-    if self._FindMatch(interface, member, member_prefix, _removed_html_members):
-      return None
-
-    if 'CheckSecurityForNode' in member_node.ext_attrs:
-      return None
-
-    name = self._FindMatch(interface, member, member_prefix,
-                           _renamed_html_members)
-
-    target_name = _renamed_html_members[name] if name else member
-    if self._FindMatch(interface, member, member_prefix, _private_html_members):
-      if not target_name.startswith('$dom_'):  # e.g. $dom_svgClassName
-        target_name = '$dom_' + target_name
-
-    target_name = self._DartifyMemberName(target_name)
-    return target_name
-
-  def _FindMatch(self, interface, member, member_prefix, candidates):
-    for interface in self._database.Hierarchy(interface):
-      html_interface_name = self.RenameInterface(interface)
-      member_name = html_interface_name + '.' + member
-      if member_name in candidates:
-        return member_name
-      member_name = html_interface_name + '.' + member_prefix + member
-      if member_name in candidates:
-        return member_name
-
-  def GetLibraryName(self, interface):
-    if 'Conditional' in interface.ext_attrs:
-      if 'WEB_AUDIO' in interface.ext_attrs['Conditional']:
-        return 'web_audio'
-      if 'SVG' in interface.ext_attrs['Conditional']:
-        return 'svg'
-      if 'INDEXED_DATABASE' in interface.ext_attrs['Conditional']:
-        return 'indexed_db'
-
-    return 'html'
-
-  def DartifyTypeName(self, type_name):
-    """Converts a DOM name to a Dart-friendly class name. """
-
-    # Strip off any standard prefixes.
-    name = re.sub(r'^SVG', '', type_name)
-    name = re.sub(r'^IDB', '', name)
-
-    return self._CamelCaseName(name)
-
-  def _DartifyMemberName(self, member_name):
-    # Strip off any OpenGL ES suffixes.
-    name = re.sub(r'OES$', '', member_name)
-    return self._CamelCaseName(name)
-
-  def _CamelCaseName(self, name):
-
-    def toLower(match):
-      return match.group(1) + match.group(2).lower() + match.group(3)
-
-    # We're looking for a sequence of letters which start with capital letter
-    # then a series of caps and finishes with either the end of the string or
-    # a capital letter.
-    # The [0-9] check is for names such as 2D or 3D
-    # The following test cases should match as:
-    #   WebKitCSSFilterValue: WebKit(C)(SS)(F)ilterValue
-    #   XPathNSResolver: (X)()(P)ath(N)(S)(R)esolver (no change)
-    #   IFrameElement: (I)()(F)rameElement (no change)
-    return re.sub(r'([A-Z])([A-Z]{2,})([A-Z]|$)', toLower, name)
diff --git a/sdk/lib/html/src/dart2js_FactoryProviders.dart b/sdk/lib/html/src/dart2js_FactoryProviders.dart
deleted file mode 100644
index 09c7efa..0000000
--- a/sdk/lib/html/src/dart2js_FactoryProviders.dart
+++ /dev/null
@@ -1,20 +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.
-
-part of html;
-
-class _PointFactoryProvider {
-  static Point createPoint(num x, num y) =>
-      JS('Point', 'new WebKitPoint(#, #)', x, y);
-}
-
-class _WebSocketFactoryProvider {
-  static WebSocket createWebSocket(String url) =>
-      JS('WebSocket', 'new WebSocket(#)', url);
-}
-
-class _TextFactoryProvider {
-  static Text createText(String data) =>
-      JS('Text', 'document.createTextNode(#)', data);
-}
diff --git a/sdk/lib/html/src/dart2js_MutationObserverSupported.dart b/sdk/lib/html/src/dart2js_MutationObserverSupported.dart
deleted file mode 100644
index 87fe26b..0000000
--- a/sdk/lib/html/src/dart2js_MutationObserverSupported.dart
+++ /dev/null
@@ -1,12 +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.
-
-part of html;
-
-/**
- * Checks to see if the mutation observer API is supported on the current
- * platform.
- */
-bool _isMutationObserverSupported() =>
-  JS('bool', '!!(window.MutationObserver || window.WebKitMutationObserver)');
diff --git a/sdk/lib/html/src/dartium_MutationObserverSupported.dart b/sdk/lib/html/src/dartium_MutationObserverSupported.dart
deleted file mode 100644
index be94537..0000000
--- a/sdk/lib/html/src/dartium_MutationObserverSupported.dart
+++ /dev/null
@@ -1,13 +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.
-
-part of html;
-
-/**
- * Checks to see if the mutation observer API is supported on the current
- * platform.
- */
-bool _isMutationObserverSupported() {
-  return true;
-}
diff --git a/sdk/lib/html/templates/html/dart2js/factoryprovider.darttemplate b/sdk/lib/html/templates/html/dart2js/factoryprovider.darttemplate
deleted file mode 100644
index 9a44cbc..0000000
--- a/sdk/lib/html/templates/html/dart2js/factoryprovider.darttemplate
+++ /dev/null
@@ -1,10 +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.
-
-part of html;
-
-class $FACTORYPROVIDER {
-  static $CONSTRUCTOR create$(CONSTRUCTOR)($PARAMETERS) =>
-      JS('$CONSTRUCTOR', 'new $NAMED_CONSTRUCTOR($ARGUMENTS_PATTERN)'$PRE_ARGUMENTS_COMMA $ARGUMENTS);
-}
diff --git a/sdk/lib/html/templates/html/dart2js/factoryprovider_DataView.darttemplate b/sdk/lib/html/templates/html/dart2js/factoryprovider_DataView.darttemplate
deleted file mode 100644
index fb75e50..0000000
--- a/sdk/lib/html/templates/html/dart2js/factoryprovider_DataView.darttemplate
+++ /dev/null
@@ -1,18 +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.
-
-part of html;
-
-class $FACTORYPROVIDER {
-  static DataView createDataView(
-      ArrayBuffer buffer, [int byteOffset = null, int byteLength = null]) {
-    if (byteOffset == null) {
-      return JS('DataView', 'new DataView(#)', buffer);
-    }
-    if (byteLength == null) {
-      return JS('DataView', 'new DataView(#,#)', buffer, byteOffset);
-    }
-    return JS('DataView', 'new DataView(#,#,#)', buffer, byteOffset, byteLength);
-  }
-}
diff --git a/sdk/lib/html/templates/html/dart2js/factoryprovider_FormData.darttemplate b/sdk/lib/html/templates/html/dart2js/factoryprovider_FormData.darttemplate
deleted file mode 100644
index 2e5d2cd..0000000
--- a/sdk/lib/html/templates/html/dart2js/factoryprovider_FormData.darttemplate
+++ /dev/null
@@ -1,12 +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.
-
-part of html;
-
-class $FACTORYPROVIDER {
-  static FormData createFormData([FormElement form = null]) {
-    if (form == null) return JS('FormData', 'new FormData()');
-    return JS('FormData', 'new FormData(#)', form);
-  }
-}
diff --git a/sdk/lib/html/templates/html/dart2js/factoryprovider_HTMLAudioElement.darttemplate b/sdk/lib/html/templates/html/dart2js/factoryprovider_HTMLAudioElement.darttemplate
deleted file mode 100644
index 25dda96..0000000
--- a/sdk/lib/html/templates/html/dart2js/factoryprovider_HTMLAudioElement.darttemplate
+++ /dev/null
@@ -1,12 +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.
-
-part of html;
-
-class $FACTORYPROVIDER {
-  static AudioElement createAudioElement([String src = null]) {
-    if (src == null) return JS('AudioElement', 'new Audio()');
-    return JS('AudioElement', 'new Audio(#)', src);
-  }
-}
diff --git a/sdk/lib/html/templates/html/dart2js/factoryprovider_HTMLOptionElement.darttemplate b/sdk/lib/html/templates/html/dart2js/factoryprovider_HTMLOptionElement.darttemplate
deleted file mode 100644
index eef4e6d..0000000
--- a/sdk/lib/html/templates/html/dart2js/factoryprovider_HTMLOptionElement.darttemplate
+++ /dev/null
@@ -1,26 +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.
-
-part of html;
-
-class $FACTORYPROVIDER {
-  static OptionElement createOptionElement(
-      [String data, String value, bool defaultSelected, bool selected]) {
-    if (data == null) {
-      return JS('OptionElement', 'new Option()');
-    }
-    if (value == null) {
-      return JS('OptionElement', 'new Option(#)', data);
-    }
-    if (defaultSelected == null) {
-      return JS('OptionElement', 'new Option(#,#)', data, value);
-    }
-    if (selected == null) {
-      return JS('OptionElement', 'new Option(#,#,#)',
-                data, value, defaultSelected);
-    }
-    return JS('OptionElement', 'new Option(#,#,#,#)',
-              data, value, defaultSelected, selected);
-  }
-}
diff --git a/sdk/lib/html/templates/html/dart2js/factoryprovider_MutationObserver.darttemplate b/sdk/lib/html/templates/html/dart2js/factoryprovider_MutationObserver.darttemplate
deleted file mode 100644
index affcb7c..0000000
--- a/sdk/lib/html/templates/html/dart2js/factoryprovider_MutationObserver.darttemplate
+++ /dev/null
@@ -1,27 +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.
-
-part of html;
-
-class $FACTORYPROVIDER {
-
-  @Creates('MutationObserver')
-  @Creates('MutationRecord')
-  static $CONSTRUCTOR create$(CONSTRUCTOR)(MutationCallback callback) native '''
-    var constructor =
-        window.MutationObserver || window.WebKitMutationObserver ||
-        window.MozMutationObserver;
-    return new constructor(callback);
-  ''';
-
-  // TODO(sra): Dart2js inserts a conversion when a Dart function (i.e. an
-  // object with a call method) is passed to a native method.  This is so the
-  // native code sees a JavaScript function.
-  //
-  // This does not happen when a function is 'passed' to a JS-form so it is not
-  // possible to rewrite the above code to, e.g. (simplified):
-  //
-  // static createMutationObserver(MutationCallback callback) =>
-  //    JS('var', 'new (window.MutationObserver)(#)', callback);
-}
diff --git a/sdk/lib/html/templates/html/dart2js/factoryprovider_ShadowRoot.darttemplate b/sdk/lib/html/templates/html/dart2js/factoryprovider_ShadowRoot.darttemplate
deleted file mode 100644
index 804c247..0000000
--- a/sdk/lib/html/templates/html/dart2js/factoryprovider_ShadowRoot.darttemplate
+++ /dev/null
@@ -1,11 +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.
-
-part of html;
-
-class $FACTORYPROVIDER {
-  static ShadowRoot createShadowRoot(Element host) =>
-      JS('ShadowRoot',
-         'new (window.ShadowRoot || window.WebKitShadowRoot)(#)', host);
-}
diff --git a/sdk/lib/html/templates/html/dart2js/factoryprovider_SharedWorker.darttemplate b/sdk/lib/html/templates/html/dart2js/factoryprovider_SharedWorker.darttemplate
deleted file mode 100644
index 9d5d745..0000000
--- a/sdk/lib/html/templates/html/dart2js/factoryprovider_SharedWorker.darttemplate
+++ /dev/null
@@ -1,12 +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.
-
-part of html;
-
-class $FACTORYPROVIDER {
-  static SharedWorker createSharedWorker(String scriptURL, [String name]) {
-    if (name == null) return JS('SharedWorker', 'new SharedWorker(#)', scriptURL);
-    return JS('SharedWorker', 'new SharedWorker(#,#)', scriptURL, name);
-  }
-}
diff --git a/sdk/lib/html/templates/html/dart2js/factoryprovider_TextTrackCue.darttemplate b/sdk/lib/html/templates/html/dart2js/factoryprovider_TextTrackCue.darttemplate
deleted file mode 100644
index 63cad24..0000000
--- a/sdk/lib/html/templates/html/dart2js/factoryprovider_TextTrackCue.darttemplate
+++ /dev/null
@@ -1,25 +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.
-
-part of html;
-
-class $FACTORYPROVIDER {
-  static TextTrackCue createTextTrackCue(
-      num startTime, num endTime, String text,
-      [String settings, bool pauseOnExit]) {
-        if (settings == null) {
-          return JS('TextTrackCue',
-                    'new TextTrackCue(#,#,#)',
-                    startTime, endTime, text);
-        }
-        if (pauseOnExit == null) {
-          return JS('TextTrackCue',
-                    'new TextTrackCue(#,#,#,#)',
-                    startTime, endTime, text, settings);
-        }
-        return JS('TextTrackCue',
-                  'new TextTrackCue(#,#,#,#,#)',
-                  startTime, endTime, text, settings, pauseOnExit);
-  }
-}
diff --git a/sdk/lib/html/templates/html/dart2js/factoryprovider_WebKitCSSMatrix.darttemplate b/sdk/lib/html/templates/html/dart2js/factoryprovider_WebKitCSSMatrix.darttemplate
deleted file mode 100644
index 7d7b7bb..0000000
--- a/sdk/lib/html/templates/html/dart2js/factoryprovider_WebKitCSSMatrix.darttemplate
+++ /dev/null
@@ -1,10 +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.
-
-part of html;
-
-class $FACTORYPROVIDER {
-  static CssMatrix createCssMatrix([String cssValue = '']) =>
-      JS('CssMatrix', 'new WebKitCSSMatrix(#)', cssValue);
-}
diff --git a/sdk/lib/html/templates/html/dart2js/factoryprovider_XMLHttpRequest.darttemplate b/sdk/lib/html/templates/html/dart2js/factoryprovider_XMLHttpRequest.darttemplate
deleted file mode 100644
index a739f36..0000000
--- a/sdk/lib/html/templates/html/dart2js/factoryprovider_XMLHttpRequest.darttemplate
+++ /dev/null
@@ -1,18 +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.
-
-part of html;
-
-class $FACTORYPROVIDER {
-  static HttpRequest createHttpRequest() =>
-      JS('HttpRequest', 'new XMLHttpRequest()');
-
-  static HttpRequest createHttpRequest_get(String url,
-      onComplete(HttpRequest request)) =>
-      _HttpRequestUtils.get(url, onComplete, false);
-
-  static HttpRequest createHttpRequest_getWithCredentials(String url,
-      onComplete(HttpRequest request)) =>
-      _HttpRequestUtils.get(url, onComplete, true);
-}
diff --git a/sdk/lib/html/templates/html/dart2js/impl_IDBDatabase.darttemplate b/sdk/lib/html/templates/html/dart2js/impl_IDBDatabase.darttemplate
deleted file mode 100644
index d2eee5a..0000000
--- a/sdk/lib/html/templates/html/dart2js/impl_IDBDatabase.darttemplate
+++ /dev/null
@@ -1,56 +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.
-
-part of indexed_db;
-
-/// @domName $DOMNAME
-class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
-
-  Transaction transaction(storeName_OR_storeNames, String mode) {
-    if (mode != 'readonly' && mode != 'readwrite') {
-      throw new ArgumentError(mode);
-    }
-
-    // TODO(sra): Ensure storeName_OR_storeNames is a string or List<String>,
-    // and copy to JavaScript array if necessary.
-
-    if (_transaction_fn != null) {
-      return _transaction_fn(this, storeName_OR_storeNames, mode);
-    }
-
-    // Try and create a transaction with a string mode.  Browsers that expect a
-    // numeric mode tend to convert the string into a number.  This fails
-    // silently, resulting in zero ('readonly').
-    var txn = _transaction(storeName_OR_storeNames, mode);
-    if (_hasNumericMode(txn)) {
-      _transaction_fn = _transaction_numeric_mode;
-      txn = _transaction_fn(this, storeName_OR_storeNames, mode);
-    } else {
-      _transaction_fn = _transaction_string_mode;
-    }
-    return txn;
-  }
-
-  static Transaction _transaction_string_mode($CLASSNAME db, stores, mode) {
-    return db._transaction(stores, mode);
-  }
-
-  static Transaction _transaction_numeric_mode($CLASSNAME db, stores, mode) {
-    int intMode;
-    if (mode == 'readonly') intMode = Transaction.READ_ONLY;
-    if (mode == 'readwrite') intMode = Transaction.READ_WRITE;
-    return db._transaction(stores, intMode);
-  }
-
-  @JSName('transaction')
-  Transaction _transaction(stores, mode) native;
-
-  static bool _hasNumericMode(txn) =>
-      JS('bool', 'typeof(#.mode) === "number"', txn);
-
-$!MEMBERS}
-
-// TODO(sra): This should be a static member of IDBTransaction but dart2js
-// can't handle that.  Move it back after dart2js is completely done.
-var _transaction_fn;  // Assigned one of the static methods.
diff --git a/sdk/lib/html/templates/html/dart2js/impl_WorkerContext.darttemplate b/sdk/lib/html/templates/html/dart2js/impl_WorkerContext.darttemplate
deleted file mode 100644
index 157b791..0000000
--- a/sdk/lib/html/templates/html/dart2js/impl_WorkerContext.darttemplate
+++ /dev/null
@@ -1,15 +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.
-
-part of html;
-
-/// @domName $DOMNAME
-class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
-$!MEMBERS
-
-  IdbFactory get indexedDB =>
-      JS('IdbFactory',
-         '#.indexedDB || #.webkitIndexedDB || #.mozIndexedDB',
-         this, this, this);
-}
diff --git a/sdk/lib/html/templates/html/dartium/factoryprovider.darttemplate b/sdk/lib/html/templates/html/dartium/factoryprovider.darttemplate
deleted file mode 100644
index 16f3515..0000000
--- a/sdk/lib/html/templates/html/dartium/factoryprovider.darttemplate
+++ /dev/null
@@ -1,9 +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.
-
-part of html;
-
-class $FACTORYPROVIDER {
-  static $INTERFACE create$INTERFACE($PARAMETERS) native "$NATIVE_NAME";
-}
diff --git a/sdk/lib/html/templates/html/dartium/factoryprovider_XMLHttpRequest.darttemplate b/sdk/lib/html/templates/html/dartium/factoryprovider_XMLHttpRequest.darttemplate
deleted file mode 100644
index b97cf21..0000000
--- a/sdk/lib/html/templates/html/dartium/factoryprovider_XMLHttpRequest.darttemplate
+++ /dev/null
@@ -1,18 +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.
-
-part of html;
-
-class $FACTORYPROVIDER {
-  static $INTERFACE create$INTERFACE($PARAMETERS) => _create$INTERFACE($ARGUMENTS);
-  static $INTERFACE _create$INTERFACE($PARAMETERS) native "$NATIVE_NAME";
-
-  static HttpRequest createHttpRequest_get(String url,
-                                     onSuccess(HttpRequest request)) =>
-      _HttpRequestUtils.get(url, onSuccess, false);
-
-  static HttpRequest createHttpRequest_getWithCredentials(String url,
-                                     onSuccess(HttpRequest request)) =>
-      _HttpRequestUtils.get(url, onSuccess, true);
-}
diff --git a/sdk/lib/html/templates/html/impl/impl_WebKitPoint.darttemplate b/sdk/lib/html/templates/html/impl/impl_WebKitPoint.darttemplate
deleted file mode 100644
index bfa4684..0000000
--- a/sdk/lib/html/templates/html/impl/impl_WebKitPoint.darttemplate
+++ /dev/null
@@ -1,13 +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.
-
-// WARNING: Do not edit - generated code.
-
-part of html;
-
-/// @domName $DOMNAME
-class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
-  factory $CLASSNAME(num x, num y) => _$(CLASSNAME)FactoryProvider.create$CLASSNAME(x, y);
-$!MEMBERS
-}
diff --git a/sdk/lib/html/templates/html/impl/impl_WebSocket.darttemplate b/sdk/lib/html/templates/html/impl/impl_WebSocket.darttemplate
deleted file mode 100644
index 6fb4d40..0000000
--- a/sdk/lib/html/templates/html/impl/impl_WebSocket.darttemplate
+++ /dev/null
@@ -1,13 +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.
-
-// WARNING: Do not edit - generated code.
-
-part of html;
-
-/// @domName $DOMNAME
-class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
-  factory $CLASSNAME(String url) => _$(CLASSNAME)FactoryProvider.create$CLASSNAME(url);
-$!MEMBERS
-}
diff --git a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
index 4d6beaf..45d6565 100644
--- a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
+++ b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
@@ -135,14 +135,6 @@
 /// @domName IDBCursor; @docsEditable true
 class Cursor native "*IDBCursor" {
 
-  static const int NEXT = 0;
-
-  static const int NEXT_NO_DUPLICATE = 1;
-
-  static const int PREV = 2;
-
-  static const int PREV_NO_DUPLICATE = 3;
-
   /// @domName IDBCursor.direction; @docsEditable true
   final String direction;
 
@@ -213,40 +205,15 @@
     // TODO(sra): Ensure storeName_OR_storeNames is a string or List<String>,
     // and copy to JavaScript array if necessary.
 
-    if (_transaction_fn != null) {
-      return _transaction_fn(this, storeName_OR_storeNames, mode);
-    }
-
     // Try and create a transaction with a string mode.  Browsers that expect a
     // numeric mode tend to convert the string into a number.  This fails
     // silently, resulting in zero ('readonly').
-    var txn = _transaction(storeName_OR_storeNames, mode);
-    if (_hasNumericMode(txn)) {
-      _transaction_fn = _transaction_numeric_mode;
-      txn = _transaction_fn(this, storeName_OR_storeNames, mode);
-    } else {
-      _transaction_fn = _transaction_string_mode;
-    }
-    return txn;
-  }
-
-  static Transaction _transaction_string_mode(Database db, stores, mode) {
-    return db._transaction(stores, mode);
-  }
-
-  static Transaction _transaction_numeric_mode(Database db, stores, mode) {
-    int intMode;
-    if (mode == 'readonly') intMode = Transaction.READ_ONLY;
-    if (mode == 'readwrite') intMode = Transaction.READ_WRITE;
-    return db._transaction(stores, intMode);
+    return _transaction(storeName_OR_storeNames, mode);
   }
 
   @JSName('transaction')
   Transaction _transaction(stores, mode) native;
 
-  static bool _hasNumericMode(txn) =>
-      JS('bool', 'typeof(#.mode) === "number"', txn);
-
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   DatabaseEvents get on =>
@@ -292,15 +259,8 @@
   /// @domName IDBDatabase.removeEventListener; @docsEditable true
   @JSName('removeEventListener')
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
-
-  /// @domName IDBDatabase.setVersion; @docsEditable true
-  VersionChangeRequest setVersion(String version) native;
 }
 
-// TODO(sra): This should be a static member of IDBTransaction but dart2js
-// can't handle that.  Move it back after dart2js is completely done.
-var _transaction_fn;  // Assigned one of the static methods.
-
 /// @docsEditable true
 class DatabaseEvents extends Events {
   /// @docsEditable true
@@ -320,54 +280,22 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-/// @domName IDBDatabaseException; @docsEditable true
-class DatabaseException native "*IDBDatabaseException" {
-
-  static const int ABORT_ERR = 20;
-
-  static const int CONSTRAINT_ERR = 4;
-
-  static const int DATA_ERR = 5;
-
-  static const int NON_TRANSIENT_ERR = 2;
-
-  static const int NOT_ALLOWED_ERR = 6;
-
-  static const int NOT_FOUND_ERR = 8;
-
-  static const int NO_ERR = 0;
-
-  static const int QUOTA_ERR = 22;
-
-  static const int READ_ONLY_ERR = 9;
-
-  static const int TIMEOUT_ERR = 23;
-
-  static const int TRANSACTION_INACTIVE_ERR = 7;
-
-  static const int UNKNOWN_ERR = 1;
-
-  static const int VER_ERR = 12;
-
-  /// @domName IDBDatabaseException.code; @docsEditable true
-  final int code;
-
-  /// @domName IDBDatabaseException.message; @docsEditable true
-  final String message;
-
-  /// @domName IDBDatabaseException.name; @docsEditable true
-  final String name;
-
-  /// @domName IDBDatabaseException.toString; @docsEditable true
-  String toString() 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
-// BSD-style license that can be found in the LICENSE file.
-
-
-/// @domName IDBFactory; @docsEditable true
+/// @domName IDBFactory
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX, '15')
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@Experimental()
 class IdbFactory native "*IDBFactory" {
+  /**
+   * Checks to see if Indexed DB is supported on the current platform.
+   */
+  static bool get supported {
+    return JS('bool',
+        '!!(window.indexedDB || '
+        'window.webkitIndexedDB || '
+        'window.mozIndexedDB)');
+  }
+
 
   /// @domName IDBFactory.cmp; @docsEditable true
   int cmp(/*IDBKey*/ first, /*IDBKey*/ second) {
@@ -387,6 +315,7 @@
 
   /// @domName IDBFactory.webkitGetDatabaseNames; @docsEditable true
   Request webkitGetDatabaseNames() 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
@@ -416,7 +345,7 @@
     if (!?key_OR_range) {
       return _count_1();
     }
-    if ((?key_OR_range && (key_OR_range is KeyRange || key_OR_range == null))) {
+    if ((key_OR_range is KeyRange || key_OR_range == null)) {
       return _count_2(key_OR_range);
     }
     if (?key_OR_range) {
@@ -434,7 +363,7 @@
 
   /// @domName IDBIndex.get; @docsEditable true
   Request get(key) {
-    if ((?key && (key is KeyRange || key == null))) {
+    if ((key is KeyRange || key == null)) {
       return _get_1(key);
     }
     if (?key) {
@@ -452,7 +381,7 @@
 
   /// @domName IDBIndex.getKey; @docsEditable true
   Request getKey(key) {
-    if ((?key && (key is KeyRange || key == null))) {
+    if ((key is KeyRange || key == null)) {
       return _getKey_1(key);
     }
     if (?key) {
@@ -474,11 +403,11 @@
         !?direction) {
       return _openCursor_1();
     }
-    if ((?key_OR_range && (key_OR_range is KeyRange || key_OR_range == null)) &&
+    if ((key_OR_range is KeyRange || key_OR_range == null) &&
         !?direction) {
       return _openCursor_2(key_OR_range);
     }
-    if ((?key_OR_range && (key_OR_range is KeyRange || key_OR_range == null))) {
+    if ((key_OR_range is KeyRange || key_OR_range == null)) {
       return _openCursor_3(key_OR_range, direction);
     }
     if (?key_OR_range &&
@@ -514,11 +443,11 @@
         !?direction) {
       return _openKeyCursor_1();
     }
-    if ((?key_OR_range && (key_OR_range is KeyRange || key_OR_range == null)) &&
+    if ((key_OR_range is KeyRange || key_OR_range == null) &&
         !?direction) {
       return _openKeyCursor_2(key_OR_range);
     }
-    if ((?key_OR_range && (key_OR_range is KeyRange || key_OR_range == null))) {
+    if ((key_OR_range is KeyRange || key_OR_range == null)) {
       return _openKeyCursor_3(key_OR_range, direction);
     }
     if (?key_OR_range &&
@@ -715,7 +644,7 @@
     if (!?key_OR_range) {
       return _count_1();
     }
-    if ((?key_OR_range && (key_OR_range is KeyRange || key_OR_range == null))) {
+    if ((key_OR_range is KeyRange || key_OR_range == null)) {
       return _count_2(key_OR_range);
     }
     if (?key_OR_range) {
@@ -733,30 +662,28 @@
 
   /// @domName IDBObjectStore.createIndex; @docsEditable true
   Index createIndex(String name, keyPath, [Map options]) {
-    if ((?keyPath && (keyPath is List<String> || keyPath == null)) &&
+    if ((keyPath is List<String> || keyPath == null) &&
         !?options) {
-      List keyPath_1 = convertDartToNative_StringArray(keyPath);
-      return _createIndex_1(name, keyPath_1);
+      return _createIndex_1(name, keyPath);
     }
-    if ((?keyPath && (keyPath is List<String> || keyPath == null))) {
-      List keyPath_2 = convertDartToNative_StringArray(keyPath);
-      var options_3 = convertDartToNative_Dictionary(options);
-      return _createIndex_2(name, keyPath_2, options_3);
+    if ((keyPath is List<String> || keyPath == null)) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return _createIndex_2(name, keyPath, options_1);
     }
-    if ((?keyPath && (keyPath is String || keyPath == null)) &&
+    if ((keyPath is String || keyPath == null) &&
         !?options) {
       return _createIndex_3(name, keyPath);
     }
-    if ((?keyPath && (keyPath is String || keyPath == null))) {
-      var options_4 = convertDartToNative_Dictionary(options);
-      return _createIndex_4(name, keyPath, options_4);
+    if ((keyPath is String || keyPath == null)) {
+      var options_2 = convertDartToNative_Dictionary(options);
+      return _createIndex_4(name, keyPath, options_2);
     }
     throw new ArgumentError("Incorrect number or type of arguments");
   }
   @JSName('createIndex')
-  Index _createIndex_1(name, List keyPath) native;
+  Index _createIndex_1(name, List<String> keyPath) native;
   @JSName('createIndex')
-  Index _createIndex_2(name, List keyPath, options) native;
+  Index _createIndex_2(name, List<String> keyPath, options) native;
   @JSName('createIndex')
   Index _createIndex_3(name, String keyPath) native;
   @JSName('createIndex')
@@ -764,7 +691,7 @@
 
   /// @domName IDBObjectStore.delete; @docsEditable true
   Request delete(key_OR_keyRange) {
-    if ((?key_OR_keyRange && (key_OR_keyRange is KeyRange || key_OR_keyRange == null))) {
+    if ((key_OR_keyRange is KeyRange || key_OR_keyRange == null)) {
       return _delete_1(key_OR_keyRange);
     }
     if (?key_OR_keyRange) {
@@ -783,7 +710,7 @@
 
   /// @domName IDBObjectStore.getObject; @docsEditable true
   Request getObject(key) {
-    if ((?key && (key is KeyRange || key == null))) {
+    if ((key is KeyRange || key == null)) {
       return _getObject_1(key);
     }
     if (?key) {
@@ -808,11 +735,11 @@
         !?direction) {
       return _openCursor_1();
     }
-    if ((?key_OR_range && (key_OR_range is KeyRange || key_OR_range == null)) &&
+    if ((key_OR_range is KeyRange || key_OR_range == null) &&
         !?direction) {
       return _openCursor_2(key_OR_range);
     }
-    if ((?key_OR_range && (key_OR_range is KeyRange || key_OR_range == null))) {
+    if ((key_OR_range is KeyRange || key_OR_range == null)) {
       return _openCursor_3(key_OR_range, direction);
     }
     if (?key_OR_range &&
@@ -898,9 +825,6 @@
   /// @domName IDBRequest.error; @docsEditable true
   final DomError error;
 
-  /// @domName IDBRequest.errorCode; @docsEditable true
-  final int errorCode;
-
   /// @domName IDBRequest.readyState; @docsEditable true
   final String readyState;
 
@@ -956,12 +880,6 @@
   TransactionEvents get on =>
     new TransactionEvents(this);
 
-  static const int READ_ONLY = 0;
-
-  static const int READ_WRITE = 1;
-
-  static const int VERSION_CHANGE = 2;
-
   /// @domName IDBTransaction.db; @docsEditable true
   final Database db;
 
@@ -971,6 +889,9 @@
   /// @domName IDBTransaction.mode; @docsEditable true
   final String mode;
 
+  /// @domName IDBTransaction.webkitErrorMessage; @docsEditable true
+  final String webkitErrorMessage;
+
   /// @domName IDBTransaction.abort; @docsEditable true
   void abort() native;
 
diff --git a/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart b/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
index e01edb1..9b6a4d8 100644
--- a/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
+++ b/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
@@ -43,14 +43,6 @@
 class Cursor extends NativeFieldWrapperClass1 {
   Cursor.internal();
 
-  static const int NEXT = 0;
-
-  static const int NEXT_NO_DUPLICATE = 1;
-
-  static const int PREV = 2;
-
-  static const int PREV_NO_DUPLICATE = 3;
-
 
   /** @domName IDBCursor.direction */
   String get direction native "IDBCursor_direction_Getter";
@@ -105,7 +97,7 @@
 
 /// @domName IDBCursorWithValue
 class CursorWithValue extends Cursor {
-  CursorWithValue.internal(): super.internal();
+  CursorWithValue.internal() : super.internal();
 
 
   /** @domName IDBCursorWithValue.value */
@@ -120,8 +112,12 @@
 
 
 /// @domName IDBDatabase
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX, '15')
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@Experimental()
 class Database extends EventTarget {
-  Database.internal(): super.internal();
+  Database.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   DatabaseEvents get on =>
@@ -163,10 +159,6 @@
   /** @domName IDBDatabase.removeEventListener */
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "IDBDatabase_removeEventListener_Callback";
 
-
-  /** @domName IDBDatabase.setVersion */
-  VersionChangeRequest setVersion(String version) native "IDBDatabase_setVersion_Callback";
-
   Transaction transaction(storeName_OR_storeNames, /*DOMString*/ mode) {
     if ((storeName_OR_storeNames is List<String> || storeName_OR_storeNames == null) && (mode is String || mode == null)) {
       return _transaction_1(storeName_OR_storeNames, mode);
@@ -212,65 +204,20 @@
 // for 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.
-
-
-/// @domName IDBDatabaseException
-class DatabaseException extends NativeFieldWrapperClass1 {
-  DatabaseException.internal();
-
-  static const int ABORT_ERR = 20;
-
-  static const int CONSTRAINT_ERR = 4;
-
-  static const int DATA_ERR = 5;
-
-  static const int NON_TRANSIENT_ERR = 2;
-
-  static const int NOT_ALLOWED_ERR = 6;
-
-  static const int NOT_FOUND_ERR = 8;
-
-  static const int NO_ERR = 0;
-
-  static const int QUOTA_ERR = 22;
-
-  static const int READ_ONLY_ERR = 9;
-
-  static const int TIMEOUT_ERR = 23;
-
-  static const int TRANSACTION_INACTIVE_ERR = 7;
-
-  static const int UNKNOWN_ERR = 1;
-
-  static const int VER_ERR = 12;
-
-
-  /** @domName IDBDatabaseException.code */
-  int get code native "IDBDatabaseException_code_Getter";
-
-
-  /** @domName IDBDatabaseException.message */
-  String get message native "IDBDatabaseException_message_Getter";
-
-
-  /** @domName IDBDatabaseException.name */
-  String get name native "IDBDatabaseException_name_Getter";
-
-
-  /** @domName IDBDatabaseException.toString */
-  String toString() native "IDBDatabaseException_toString_Callback";
-
-}
-// 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.
-
 
 /// @domName IDBFactory
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX, '15')
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@Experimental()
 class IdbFactory extends NativeFieldWrapperClass1 {
+  /**
+   * Checks to see if Indexed DB is supported on the current platform.
+   */
+  static bool get supported {
+    return true;
+  }
+
   IdbFactory.internal();
 
 
@@ -339,7 +286,9 @@
     if ((key_OR_range is KeyRange || key_OR_range == null)) {
       return _count_2(key_OR_range);
     }
-    return _count_3(key_OR_range);
+    if (?key_OR_range) {
+      return _count_3(key_OR_range);
+    }
     throw "Incorrect number or type of arguments";
   }
 
@@ -359,7 +308,9 @@
     if ((key is KeyRange || key == null)) {
       return _get_1(key);
     }
-    return _get_2(key);
+    if (?key) {
+      return _get_2(key);
+    }
     throw "Incorrect number or type of arguments";
   }
 
@@ -375,7 +326,9 @@
     if ((key is KeyRange || key == null)) {
       return _getKey_1(key);
     }
-    return _getKey_2(key);
+    if (?key) {
+      return _getKey_2(key);
+    }
     throw "Incorrect number or type of arguments";
   }
 
@@ -397,10 +350,10 @@
     if ((key_OR_range is KeyRange || key_OR_range == null) && (direction is String || direction == null)) {
       return _openCursor_3(key_OR_range, direction);
     }
-    if (!?direction) {
+    if (?key_OR_range && !?direction) {
       return _openCursor_4(key_OR_range);
     }
-    if ((direction is String || direction == null)) {
+    if (?key_OR_range && (direction is String || direction == null)) {
       return _openCursor_5(key_OR_range, direction);
     }
     throw "Incorrect number or type of arguments";
@@ -436,10 +389,10 @@
     if ((key_OR_range is KeyRange || key_OR_range == null) && (direction is String || direction == null)) {
       return _openKeyCursor_3(key_OR_range, direction);
     }
-    if (!?direction) {
+    if (?key_OR_range && !?direction) {
       return _openKeyCursor_4(key_OR_range);
     }
-    if ((direction is String || direction == null)) {
+    if (?key_OR_range && (direction is String || direction == null)) {
       return _openKeyCursor_5(key_OR_range, direction);
     }
     throw "Incorrect number or type of arguments";
@@ -643,7 +596,9 @@
     if ((key_OR_range is KeyRange || key_OR_range == null)) {
       return _count_2(key_OR_range);
     }
-    return _count_3(key_OR_range);
+    if (?key_OR_range) {
+      return _count_3(key_OR_range);
+    }
     throw "Incorrect number or type of arguments";
   }
 
@@ -681,7 +636,9 @@
     if ((key_OR_keyRange is KeyRange || key_OR_keyRange == null)) {
       return _delete_1(key_OR_keyRange);
     }
-    return _delete_2(key_OR_keyRange);
+    if (?key_OR_keyRange) {
+      return _delete_2(key_OR_keyRange);
+    }
     throw "Incorrect number or type of arguments";
   }
 
@@ -701,7 +658,9 @@
     if ((key is KeyRange || key == null)) {
       return _get_1(key);
     }
-    return _get_2(key);
+    if (?key) {
+      return _get_2(key);
+    }
     throw "Incorrect number or type of arguments";
   }
 
@@ -727,10 +686,10 @@
     if ((key_OR_range is KeyRange || key_OR_range == null) && (direction is String || direction == null)) {
       return _openCursor_3(key_OR_range, direction);
     }
-    if (!?direction) {
+    if (?key_OR_range && !?direction) {
       return _openCursor_4(key_OR_range);
     }
-    if ((direction is String || direction == null)) {
+    if (?key_OR_range && (direction is String || direction == null)) {
       return _openCursor_5(key_OR_range, direction);
     }
     throw "Incorrect number or type of arguments";
@@ -781,7 +740,7 @@
 
 /// @domName IDBOpenDBRequest
 class OpenDBRequest extends Request implements EventTarget {
-  OpenDBRequest.internal(): super.internal();
+  OpenDBRequest.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   OpenDBRequestEvents get on =>
@@ -809,7 +768,7 @@
 
 /// @domName IDBRequest
 class Request extends EventTarget {
-  Request.internal(): super.internal();
+  Request.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   RequestEvents get on =>
@@ -820,10 +779,6 @@
   DomError get error native "IDBRequest_error_Getter";
 
 
-  /** @domName IDBRequest.errorCode */
-  int get errorCode native "IDBRequest_errorCode_Getter";
-
-
   /** @domName IDBRequest.readyState */
   String get readyState native "IDBRequest_readyState_Getter";
 
@@ -877,18 +832,12 @@
 
 /// @domName IDBTransaction
 class Transaction extends EventTarget {
-  Transaction.internal(): super.internal();
+  Transaction.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   TransactionEvents get on =>
     new TransactionEvents(this);
 
-  static const int READ_ONLY = 0;
-
-  static const int READ_WRITE = 1;
-
-  static const int VERSION_CHANGE = 2;
-
 
   /** @domName IDBTransaction.db */
   Database get db native "IDBTransaction_db_Getter";
@@ -902,6 +851,10 @@
   String get mode native "IDBTransaction_mode_Getter";
 
 
+  /** @domName IDBTransaction.webkitErrorMessage */
+  String get webkitErrorMessage native "IDBTransaction_webkitErrorMessage_Getter";
+
+
   /** @domName IDBTransaction.abort */
   void abort() native "IDBTransaction_abort_Callback";
 
@@ -946,7 +899,7 @@
 
 /// @domName IDBVersionChangeEvent
 class UpgradeNeededEvent extends Event {
-  UpgradeNeededEvent.internal(): super.internal();
+  UpgradeNeededEvent.internal() : super.internal();
 
 
   /** @domName IDBUpgradeNeededEvent.newVersion */
@@ -966,7 +919,7 @@
 
 /// @domName IDBVersionChangeEvent
 class VersionChangeEvent extends Event {
-  VersionChangeEvent.internal(): super.internal();
+  VersionChangeEvent.internal() : super.internal();
 
 
   /** @domName IDBVersionChangeEvent.version */
@@ -982,7 +935,7 @@
 
 /// @domName IDBVersionChangeRequest
 class VersionChangeRequest extends Request implements EventTarget {
-  VersionChangeRequest.internal(): super.internal();
+  VersionChangeRequest.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   VersionChangeRequestEvents get on =>
diff --git a/sdk/lib/io/base64.dart b/sdk/lib/io/base64.dart
index 905d177..f57eea6 100644
--- a/sdk/lib/io/base64.dart
+++ b/sdk/lib/io/base64.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.io;
+
 class _Base64 {
   static const List<String> _encodingTable = const [
       'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
diff --git a/sdk/lib/io/buffer_list.dart b/sdk/lib/io/buffer_list.dart
index 0dab719..4f0a3f7 100644
--- a/sdk/lib/io/buffer_list.dart
+++ b/sdk/lib/io/buffer_list.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.io;
+
 /**
  * Utility class that holds a number of byte buffers and can deliver
  * the bytes either one by one or in chunks.
diff --git a/sdk/lib/io/chunked_stream.dart b/sdk/lib/io/chunked_stream.dart
index e908175..c74a057 100644
--- a/sdk/lib/io/chunked_stream.dart
+++ b/sdk/lib/io/chunked_stream.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.io;
+
 class _ChunkedInputStream implements ChunkedInputStream {
   _ChunkedInputStream(InputStream this._input, int this._chunkSize)
       : _bufferList = new _BufferList() {
diff --git a/sdk/lib/io/common.dart b/sdk/lib/io/common.dart
index 5a39a46..3f8c550 100644
--- a/sdk/lib/io/common.dart
+++ b/sdk/lib/io/common.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.io;
+
 // Constants used when working with native ports.
 const int _SUCCESS_RESPONSE = 0;
 const int _ILLEGAL_ARGUMENT_RESPONSE = 1;
diff --git a/sdk/lib/io/directory.dart b/sdk/lib/io/directory.dart
index 76b9d2e..60717b8 100644
--- a/sdk/lib/io/directory.dart
+++ b/sdk/lib/io/directory.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.io;
+
 /**
  * [Directory] objects are used for working with directories.
  */
@@ -138,6 +140,18 @@
   DirectoryLister list({bool recursive: false});
 
   /**
+   * List the sub-directories and files of this
+   * [Directory]. Optionally recurse into sub-directories. Returns a
+   * List containing Directory and File objects.
+   */
+  List listSync({bool recursive: false});
+
+  /**
+   * Returns a human readable string for this Directory instance.
+   */
+  String toString();
+
+  /**
    * Gets the path of this directory.
    */
   final String path;
diff --git a/sdk/lib/io/directory_impl.dart b/sdk/lib/io/directory_impl.dart
index c24bedb..8017e95 100644
--- a/sdk/lib/io/directory_impl.dart
+++ b/sdk/lib/io/directory_impl.dart
@@ -2,6 +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.io;
 
 class _Directory implements Directory {
   static const CREATE_REQUEST = 0;
@@ -25,6 +26,7 @@
   external static _create(String path);
   external static _delete(String path, bool recursive);
   external static _rename(String path, String newPath);
+  external static List _list(String path, bool recursive);
   external static SendPort _newServicePort();
 
   Future<bool> exists() {
@@ -51,22 +53,25 @@
     return (result == 1);
   }
 
+  // Compute the index of the first directory in the list that exists. If
+  // none of the directories exist dirsToCreate.length is returned.
   Future<int> _computeExistingIndex(List dirsToCreate) {
     var future;
+    var notFound = dirsToCreate.length;
     for (var i = 0; i < dirsToCreate.length; i++) {
       if (future == null) {
-        future = dirsToCreate[i].exists().transform((e) => e ? i : -1);
+        future = dirsToCreate[i].exists().transform((e) => e ? i : notFound);
       } else {
         future = future.chain((index) {
-          if (index != -1) {
+          if (index != notFound) {
             return new Future.immediate(index);
           }
-          return dirsToCreate[i].exists().transform((e) => e ? i : -1);
+          return dirsToCreate[i].exists().transform((e) => e ? i : notFound);
         });
       }
     }
     if (future == null) {
-      return new Future.immediate(-1);
+      return new Future.immediate(notFound);
     } else {
       return future;
     }
@@ -225,7 +230,16 @@
     return new _DirectoryLister(_path, recursive);
   }
 
-  String get path { return _path; }
+  List listSync({bool recursive: false}) {
+    if (_path is! String || recursive is! bool) {
+      throw new ArgumentError();
+    }
+    return _list(_path, recursive);
+  }
+
+  String get path => _path;
+
+  String toString() => "Directory: '$path'";
 
   bool _isErrorResponse(response) {
     return response is List && response[0] != _SUCCESS_RESPONSE;
diff --git a/sdk/lib/io/eventhandler.dart b/sdk/lib/io/eventhandler.dart
index f925b01..003c3ed 100644
--- a/sdk/lib/io/eventhandler.dart
+++ b/sdk/lib/io/eventhandler.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.io;
+
 class _EventHandler {
   external static void _start();
   external static _sendData(Object sender, ReceivePort receivePort, int data);
diff --git a/sdk/lib/io/file.dart b/sdk/lib/io/file.dart
index bef2d68..e3be26b 100644
--- a/sdk/lib/io/file.dart
+++ b/sdk/lib/io/file.dart
@@ -2,6 +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.io;
 
 /**
  * FileMode describes the modes in which a file can be opened.
@@ -249,8 +250,8 @@
    * file pass [:FileMode.APPEND:] as the optional mode parameter.
    */
   Future<File> writeAsString(String contents,
-                             [Encoding encoding = Encoding.UTF_8,
-                              FileMode mode = FileMode.WRITE]);
+                             {FileMode mode: FileMode.WRITE,
+                              Encoding encoding: Encoding.UTF_8});
 
   /**
    * Synchronously write a string to a file.
@@ -264,8 +265,8 @@
    * parameter.
    */
   void writeAsStringSync(String contents,
-                         [Encoding encoding = Encoding.UTF_8,
-                          FileMode mode = FileMode.WRITE]);
+                         {FileMode mode: FileMode.WRITE,
+                          Encoding encoding: Encoding.UTF_8});
 
   /**
    * Get the name of the file.
@@ -427,6 +428,11 @@
   void flushSync();
 
   /**
+   * Returns a human readable string for this File instance.
+   */
+  String toString();
+
+  /**
    * Get the name of the file.
    */
   String get name;
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index 0d7a548..a634400 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_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.io;
+
 class _FileInputStream extends _BaseDataInputStream implements InputStream {
   _FileInputStream(String name)
       : _data = const [],
@@ -681,8 +683,8 @@
   }
 
   Future<File> writeAsString(String contents,
-                             [FileMode mode = FileMode.WRITE,
-                              Encoding encoding = Encoding.UTF_8]) {
+                             {FileMode mode: FileMode.WRITE,
+                              Encoding encoding: Encoding.UTF_8}) {
     try {
       var data = _StringEncoders.encoder(encoding).encodeString(contents);
       return writeAsBytes(data, mode);
@@ -694,14 +696,16 @@
   }
 
   void writeAsStringSync(String contents,
-                         [FileMode mode = FileMode.WRITE,
-                          Encoding encoding = Encoding.UTF_8]) {
+                         {FileMode mode: FileMode.WRITE,
+                          Encoding encoding: Encoding.UTF_8}) {
     var data = _StringEncoders.encoder(encoding).encodeString(contents);
     writeAsBytesSync(data, mode);
   }
 
   String get name => _name;
 
+  String toString() => "File: '$name'";
+
   void _ensureFileService() {
     if (_fileService == null) {
       _fileService = _FileUtils._newServicePort();
diff --git a/sdk/lib/io/http.dart b/sdk/lib/io/http.dart
index 24cb85b..5b1809f 100644
--- a/sdk/lib/io/http.dart
+++ b/sdk/lib/io/http.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.io;
+
 /**
  * HTTP status codes.
  */
@@ -63,15 +65,16 @@
    * [port]. If a [port] of 0 is specified the server will choose an
    * ephemeral port. The optional argument [backlog] can be used to
    * specify the listen backlog for the underlying OS listen.
-   * The optional argument [certificate_name] is used by the HttpsServer
-   * class, which shares the same interface.
+   * The optional arguments [certificate_name] and [requestClientCertificate]
+   * are used by the HttpsServer class, which shares the same interface.
    * See [addRequestHandler] and [defaultRequestHandler] for
    * information on how incoming HTTP requests are handled.
    */
   void listen(String host,
               int port,
               {int backlog: 128,
-              String certificate_name});
+               String certificate_name,
+               bool requestClientCertificate: false});
 
   /**
    * Attach the HTTP server to an existing [:ServerSocket:]. If the
@@ -637,6 +640,14 @@
   List<Cookie> get cookies;
 
   /**
+   * Returns the client certificate of the client making the request.
+   * Returns null if the connection is not a secure TLS or SSL connection,
+   * or if the server does not request a client certificate, or if the client
+   * does not provide one.
+   */
+  X509Certificate get certificate;
+
+  /**
    * Returns, or initialize, a session for the given request. If the session is
    * being initialized by this call, [init] will be called with the
    * newly create session. Here the [:HttpSession.data:] field can be set, if
@@ -821,6 +832,23 @@
   void addCredentials(Uri url, String realm, HttpClientCredentials credentials);
 
   /**
+   * If [sendClientCertificate] is set to true, authenticate with a client
+   * certificate when connecting with an HTTPS server that requests one.
+   * Select the certificate from the certificate database that matches
+   * the authorities listed by the HTTPS server as valid.
+   * If [clientCertificate] is set, send the certificate with that nickname
+   * instead.
+   */
+  set sendClientCertificate(bool send);
+
+  /**
+   * If [clientCertificate] is non-null and [sendClientCertificate] is true,
+   * use [clientCertificate] to select the certificate to send from the
+   * certificate database, looking it up by its nickname.
+   */
+  set clientCertificate(String nickname);
+
+  /**
    * Sets the function used to resolve the proxy server to be used for
    * opening a HTTP connection to the specified [url]. If this
    * function is not set, direct connections will always be used.
@@ -1036,6 +1064,12 @@
   List<Cookie> get cookies;
 
   /**
+   * Returns the certificate of the HTTPS server providing the response.
+   * Returns null if the connection is not a secure TLS or SSL connection.
+   */
+  X509Certificate get certificate;
+
+  /**
    * Returns the input stream for the response. This is used to read
    * the response data.
    */
diff --git a/sdk/lib/io/http_headers.dart b/sdk/lib/io/http_headers.dart
index 55a9a89..beb9b89 100644
--- a/sdk/lib/io/http_headers.dart
+++ b/sdk/lib/io/http_headers.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.io;
+
 class _HttpHeaders implements HttpHeaders {
   _HttpHeaders() : _headers = new Map<String, List<String>>();
 
@@ -65,6 +67,33 @@
     _noFoldingHeaders.add(name);
   }
 
+  int get contentLength => _contentLength;
+
+  void set contentLength(int contentLength) {
+    _checkMutable();
+    _contentLength = contentLength;
+    if (_contentLength >= 0) {
+      _set("content-length", contentLength.toString());
+    } else {
+      removeAll("content-length");
+    }
+  }
+
+  bool get chunkedTransferEncoding => _chunkedTransferEncoding;
+
+  void set chunkedTransferEncoding(bool chunkedTransferEncoding) {
+    _checkMutable();
+    _chunkedTransferEncoding = chunkedTransferEncoding;
+    List<String> values = _headers["transfer-encoding"];
+    if (values == null || values[values.length - 1] != "chunked") {
+      // Headers does not specify chunked encoding - add it if set.
+      if (chunkedTransferEncoding) _addValue("transfer-encoding", "chunked");
+    } else {
+      // Headers does specify chunked encoding - remove it if not set.
+      if (!chunkedTransferEncoding) remove("transfer-encoding", "chunked");
+    }
+  }
+
   String get host => _host;
 
   void set host(String host) {
@@ -155,7 +184,21 @@
   void _add(String name, Object value) {
     var lowerCaseName = name.toLowerCase();
     // TODO(sgjesse): Add immutable state throw HttpException is immutable.
-    if (lowerCaseName == "date") {
+    if (lowerCaseName == "content-length") {
+      if (value is int) {
+        contentLength = value;
+      } else if (value is String) {
+        contentLength = parseInt(value);
+      } else {
+        throw new HttpException("Unexpected type for header named $name");
+      }
+    } else if (lowerCaseName == "transfer-encoding") {
+      if (value == "chunked") {
+        chunkedTransferEncoding = true;
+      } else {
+        _addValue(lowerCaseName, value);
+      }
+    } else if (lowerCaseName == "date") {
       if (value is Date) {
         date = value;
       } else if (value is String) {
@@ -204,17 +247,20 @@
     } else if (lowerCaseName == "content-type") {
       _set("content-type", value);
     } else {
-      name = lowerCaseName;
-      List<String> values = _headers[name];
-      if (values == null) {
-        values = new List<String>();
-        _headers[name] = values;
-      }
-      if (value is Date) {
-        values.add(_HttpUtils.formatDate(value));
-      } else {
-        values.add(value.toString());
-      }
+        _addValue(lowerCaseName, value);
+    }
+  }
+
+  void _addValue(String name, Object value) {
+    List<String> values = _headers[name];
+    if (values == null) {
+      values = new List<String>();
+      _headers[name] = values;
+    }
+    if (value is Date) {
+      values.add(_HttpUtils.formatDate(value));
+    } else {
+      values.add(value.toString());
     }
   }
 
@@ -244,6 +290,22 @@
     return true;
   }
 
+  void _finalize(String protocolVersion) {
+    // If the content length is not known make sure chunked transfer
+    // encoding is used for HTTP 1.1.
+    if (contentLength < 0 && protocolVersion == "1.1") {
+      chunkedTransferEncoding = true;
+    }
+    // If a Transfer-Encoding header field is present the
+    // Content-Length header MUST NOT be sent (RFC 2616 section 4.4).
+    if (chunkedTransferEncoding &&
+        contentLength >= 0 &&
+        protocolVersion == "1.1") {
+      contentLength = -1;
+    }
+    _mutable = false;
+  }
+
   _write(_HttpConnectionBase connection) {
     final COLONSP = const [_CharCode.COLON, _CharCode.SP];
     final COMMASP = const [_CharCode.COMMA, _CharCode.SP];
@@ -323,6 +385,8 @@
   Map<String, List<String>> _headers;
   List<String> _noFoldingHeaders;
 
+  int _contentLength = -1;
+  bool _chunkedTransferEncoding = false;
   String _host;
   int _port;
 }
diff --git a/sdk/lib/io/http_impl.dart b/sdk/lib/io/http_impl.dart
index 30fe2c1..fb82ba2 100644
--- a/sdk/lib/io/http_impl.dart
+++ b/sdk/lib/io/http_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.io;
+
 // The close queue handles graceful closing of HTTP connections. When
 // a connection is added to the queue it will enter a wait state
 // waiting for all data written and possibly socket shutdown from
@@ -32,7 +34,7 @@
     connection._state |= _HttpConnectionBase.CLOSING;
     _q.add(connection);
 
-    // If output stream is not closed for writing close it now and
+    // If the output stream is not closed for writing, close it now and
     // wait for callback when closed.
     if (!connection._isWriteClosed) {
       connection._socket.outputStream.close();
@@ -44,14 +46,15 @@
       connection._socket.outputStream.onClosed = () { assert(false); };
     }
 
-    // If socket is not closed for reading wait for callback.
+    // If the request is not already fully read wait for the socket to close.
+    // As the _isReadClosed state from the HTTP request processing indicate
+    // that the response has been parsed this does not necesarily mean tha
+    // the socket is closed.
     if (!connection._isReadClosed) {
       connection._socket.onClosed = () {
         connection._state |= _HttpConnectionBase.READ_CLOSED;
         closeIfDone();
       };
-    } else {
-      connection._socket.onClosed = () { assert(false); };
     }
 
     // Ignore any data on a socket in the close queue.
@@ -84,7 +87,7 @@
   _HttpRequestResponseBase(_HttpConnectionBase this._httpConnection)
       : _state = START, _headResponse = false;
 
-  int get contentLength => _contentLength;
+  int get contentLength => _headers.contentLength;
   HttpHeaders get headers => _headers;
 
   bool get persistentConnection {
@@ -100,6 +103,11 @@
     }
   }
 
+  X509Certificate get certificate {
+    var socket = _httpConnection._socket as SecureSocket;
+    return socket == null ? socket : socket.peerCertificate;
+  }
+
   void set persistentConnection(bool persistentConnection) {
     if (_outputStream != null) throw new HttpException("Header already sent");
 
@@ -119,7 +127,7 @@
     _ensureHeadersSent();
     bool allWritten = true;
     if (data.length > 0) {
-      if (_contentLength < 0) {
+      if (_headers.chunkedTransferEncoding) {
         // Write chunk size if transfer encoding is chunked.
         _writeHexString(data.length);
         _writeCRLF();
@@ -138,7 +146,7 @@
     _ensureHeadersSent();
     bool allWritten = true;
     if (count > 0) {
-      if (_contentLength < 0) {
+      if (_headers.chunkedTransferEncoding) {
         // Write chunk size if transfer encoding is chunked.
         _writeHexString(count);
         _writeCRLF();
@@ -154,20 +162,19 @@
 
   bool _writeDone() {
     bool allWritten = true;
-    if (_contentLength < 0) {
+    if (_headers.chunkedTransferEncoding) {
       // Terminate the content if transfer encoding is chunked.
       allWritten = _httpConnection._write(_Const.END_CHUNKED);
     } else {
-      if (!_headResponse && _bodyBytesWritten < _contentLength) {
+      if (!_headResponse && _bodyBytesWritten < _headers.contentLength) {
         throw new HttpException("Sending less than specified content length");
       }
-      assert(_headResponse || _bodyBytesWritten == _contentLength);
+      assert(_headResponse || _bodyBytesWritten == _headers.contentLength);
     }
     return allWritten;
   }
 
   bool _writeHeaders() {
-    _headers._mutable = false;
     _headers._write(_httpConnection);
     // Terminate header.
     return _writeCRLF();
@@ -205,7 +212,7 @@
   }
 
   void _updateContentLength(int bytes) {
-    if (_bodyBytesWritten + bytes > _contentLength) {
+    if (_bodyBytesWritten + bytes > _headers.contentLength) {
       throw new HttpException("Writing more than specified content length");
     }
     _bodyBytesWritten += bytes;
@@ -223,10 +230,6 @@
   List<Cookie> _cookies;
   String _protocolVersion = "1.1";
 
-  // Length of the content body. If this is set to -1 (default value)
-  // when starting to send data chunked transfer encoding will be
-  // used.
-  int _contentLength = -1;
   // Number of body bytes written. This is only actual body data not
   // including headers or chunk information of using chinked transfer
   // encoding.
@@ -354,11 +357,7 @@
       }
     }
 
-    // Get parsed content length.
-    _contentLength = _httpConnection._httpParser.contentLength;
-
     // Prepare for receiving data.
-    _headers._mutable = false;
     _buffer = new _BufferList();
   }
 
@@ -432,7 +431,7 @@
     if (_state >= _HttpRequestResponseBase.HEADER_SENT) {
       throw new HttpException("Header already sent");
     }
-    _contentLength = contentLength;
+    _headers.contentLength = contentLength;
   }
 
   int get statusCode => _statusCode;
@@ -589,15 +588,6 @@
     _httpConnection._write(data);
     _writeCRLF();
 
-    // Determine the value of the "Transfer-Encoding" header based on
-    // whether the content length is known. HTTP/1.0 does not support
-    // chunked.
-    if (_contentLength >= 0) {
-      _headers.set(HttpHeaders.CONTENT_LENGTH, _contentLength.toString());
-    } else if (_contentLength < 0 && _protocolVersion == "1.1") {
-      _headers.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
-    }
-
     var session = _httpConnection._request._session;
     if (session != null && !session._destroyed) {
       // Make sure we only send the current session id.
@@ -622,6 +612,7 @@
     }
 
     // Write headers.
+    _headers._finalize(_protocolVersion);
     bool allWritten = _writeHeaders();
     _state = _HttpRequestResponseBase.HEADER_SENT;
     return allWritten;
@@ -929,10 +920,11 @@
       // body.
       bool close =
           !_response.persistentConnection ||
-          (_response._protocolVersion == "1.0" && _response._contentLength < 0);
+          (_response._protocolVersion == "1.0" && _response.contentLength < 0);
       _request = null;
       _response = null;
       if (close) {
+        _httpParser.cancel();
         _server._closeQueue.add(this);
       } else {
         _state = _HttpConnectionBase.IDLE;
@@ -944,7 +936,7 @@
       // not care to read the request body) this is send.
       assert(!_isRequestDone);
       _writeBufferedResponse();
-      _close();
+      _httpParser.cancel();
       _server._closeQueue.add(this);
     }
   }
@@ -1000,9 +992,15 @@
   void listen(String host,
               int port,
               {int backlog: 128,
-              String certificate_name}) {
+               String certificate_name,
+               bool requestClientCertificate: false}) {
     if (_secure) {
-      listenOn(new SecureServerSocket(host, port, backlog, certificate_name));
+      listenOn(new SecureServerSocket(
+          host,
+          port,
+          backlog,
+          certificate_name,
+          requestClientCertificate: requestClientCertificate));
     } else {
       listenOn(new ServerSocket(host, port, backlog));
     }
@@ -1152,7 +1150,7 @@
     _connection = connection;
     // Default GET and HEAD requests to have no content.
     if (_method == "GET" || _method == "HEAD") {
-      _contentLength = 0;
+      contentLength = 0;
     }
   }
 
@@ -1160,7 +1158,7 @@
     if (_state >= _HttpRequestResponseBase.HEADER_SENT) {
       throw new HttpException("Header already sent");
     }
-    _contentLength = contentLength;
+    _headers.contentLength = contentLength;
   }
 
   List<Cookie> get cookies {
@@ -1245,15 +1243,6 @@
     _httpConnection._write(_Const.HTTP11);
     _writeCRLF();
 
-    // Determine the value of the "Transfer-Encoding" header based on
-    // whether the content length is known. If there is no content
-    // neither "Content-Length" nor "Transfer-Encoding" is set.
-    if (_contentLength > 0) {
-      _headers.set(HttpHeaders.CONTENT_LENGTH, _contentLength.toString());
-    } else if (_contentLength < 0) {
-      _headers.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
-    }
-
     // Add the cookies to the headers.
     if (_cookies != null) {
       StringBuffer sb = new StringBuffer();
@@ -1267,6 +1256,7 @@
     }
 
     // Write headers.
+    _headers._finalize("1.1");
     _writeHeaders();
     _state = _HttpRequestResponseBase.HEADER_SENT;
   }
@@ -1330,11 +1320,8 @@
     _statusCode = statusCode;
     _reasonPhrase = reasonPhrase;
     _headers = headers;
-    // Get parsed content length.
-    _contentLength = _httpConnection._httpParser.contentLength;
 
     // Prepare for receiving data.
-    _headers._mutable = false;
     _buffer = new _BufferList();
     if (isRedirect && _connection.followRedirects) {
       if (_connection._redirects == null ||
@@ -1550,7 +1537,7 @@
           _client._closedSocketConnection(_socketConn);
         };
         _client._closeQueue.add(this);
-      } else {
+      } else if (_socket != null) {
         _client._returnSocketConnection(_socketConn);
         _socket = null;
         _socketConn = null;
@@ -1750,7 +1737,7 @@
     _httpClientConnection = null;
   }
 
-  void _markRetreived() {
+  void _markRetrieved() {
     _socket.onData = null;
     _socket.onClosed = null;
     _socket.onError = null;
@@ -1899,6 +1886,10 @@
     credentials.add(new _Credentials(url, realm, cr));
   }
 
+  set sendClientCertificate(bool send) => _sendClientCertificate = send;
+
+  set clientCertificate(String nickname) => _clientCertificate = nickname;
+
   set findProxy(String f(Uri uri)) => _findProxy = f;
 
   void shutdown({bool force: false}) {
@@ -1992,15 +1983,26 @@
       Queue socketConnections = _openSockets[key];
       // Remove active connections that are not valid any more or of
       // the wrong type (HTTP or HTTPS).
-      while (socketConnections != null &&
-             !socketConnections.isEmpty &&
-             (!socketConnections.first._valid ||
-              secure != (socketConnections.first._socket is SecureSocket))) {
-        socketConnections.removeFirst()._close();
+      if (socketConnections != null) {
+        while (!socketConnections.isEmpty) {
+          if (socketConnections.first._valid) {
+            // If socket has the same properties, exit loop with found socket.
+            var socket = socketConnections.first._socket;
+            if (!secure && socket is! SecureSocket) break;
+            if (secure && socket is SecureSocket &&
+                 _sendClientCertificate == socket.sendClientCertificate &&
+                 _clientCertificate == socket.certificateName) break;
+          }
+          socketConnections.removeFirst()._close();
+        }
       }
       if (socketConnections == null || socketConnections.isEmpty) {
-        Socket socket = secure ? new SecureSocket(connectHost, connectPort) :
-                                 new Socket(connectHost, connectPort);
+        Socket socket = secure ?
+            new SecureSocket(connectHost,
+                             connectPort,
+                             sendClientCertificate: _sendClientCertificate,
+                             certificateName: _clientCertificate) :
+            new Socket(connectHost, connectPort);
         // Until the connection is established handle connection errors
         // here as the HttpClientConnection object is not yet associated
         // with the socket.
@@ -2029,7 +2031,7 @@
         };
       } else {
         _SocketConnection socketConn = socketConnections.removeFirst();
-        socketConn._markRetreived();
+        socketConn._markRetrieved();
         _activeSockets.add(socketConn);
         new Timer(0, (ignored) =>
                   _connectionOpened(socketConn, connection, !proxy.isDirect));
@@ -2172,6 +2174,8 @@
   Timer _evictionTimer;
   Function _findProxy;
   Function _authenticate;
+  bool _sendClientCertificate = false;
+  String _clientCertificate;
   bool _shutdown;  // Has this HTTP client been shutdown?
 }
 
diff --git a/sdk/lib/io/http_parser.dart b/sdk/lib/io/http_parser.dart
index fbbd43d..5a726da 100644
--- a/sdk/lib/io/http_parser.dart
+++ b/sdk/lib/io/http_parser.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.io;
+
 // Global constants.
 class _Const {
   // Bytes for "HTTP".
@@ -96,7 +98,7 @@
 
 /**
  * HTTP parser which parses the HTTP stream as data is supplied
- * through the [:writeList:] and [:connectionClosed:] methods. As the
+ * through the [:streamData:] and [:streamDone:] methods. As the
  * data is parsed the following callbacks are called:
  *
  *   [:requestStart:]
@@ -107,7 +109,7 @@
  *   [:error:]
  *
  * If an HTTP parser error occours it is possible to get an exception
- * thrown from the [:writeList:] and [:connectionClosed:] methods if
+ * thrown from the [:streamData:] and [:streamDone:] methods if
  * the error callback is not set.
  *
  * The connection upgrades (e.g. switching from HTTP/1.1 to the
@@ -385,11 +387,7 @@
               String headerField = new String.fromCharCodes(_headerField);
               String headerValue = new String.fromCharCodes(_headerValue);
               bool reportHeader = true;
-              if (headerField == "content-length" && !_chunked) {
-                // Ignore the Content-Length header if Transfer-Encoding
-                // is chunked (RFC 2616 section 4.4)
-                _contentLength = parseInt(headerValue);
-              } else if (headerField == "connection") {
+              if (headerField == "connection") {
                 List<String> tokens = _tokenizeFieldValue(headerValue);
                 for (int i = 0; i < tokens.length; i++) {
                   String token = tokens[i].toLowerCase();
@@ -406,10 +404,7 @@
                 reportHeader = false;
               } else if (headerField == "transfer-encoding" &&
                          headerValue.toLowerCase() == "chunked") {
-                // Ignore the Content-Length header if Transfer-Encoding
-                // is chunked (RFC 2616 section 4.4)
                 _chunked = true;
-                _contentLength = -1;
               }
               if (reportHeader) {
                 _headers.add(headerField, headerValue);
@@ -429,6 +424,13 @@
 
           case _State.HEADER_ENDING:
             _expect(byte, _CharCode.LF);
+            _headers._mutable = false;
+
+            _contentLength = _headers.contentLength;
+            // Ignore the Content-Length header if Transfer-Encoding
+            // is chunked (RFC 2616 section 4.4)
+            if (_chunked) _contentLength = -1;
+
             // If a request message has neither Content-Length nor
             // Transfer-Encoding the message must not have a body (RFC
             // 2616 section 4.3).
diff --git a/sdk/lib/io/http_session.dart b/sdk/lib/io/http_session.dart
index d23f642..84eb08a 100644
--- a/sdk/lib/io/http_session.dart
+++ b/sdk/lib/io/http_session.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.io;
+
 const String _DART_SESSION_ID = "DARTSESSID";
 
 // A _HttpSession is a node in a double-linked list, with _next and _prev being
diff --git a/sdk/lib/io/http_utils.dart b/sdk/lib/io/http_utils.dart
index d1161f8..9e23613 100644
--- a/sdk/lib/io/http_utils.dart
+++ b/sdk/lib/io/http_utils.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.io;
+
 class _HttpUtils {
   static String decodeUrlEncodedString(String urlEncoded) {
     // First check the string for any encoding.
@@ -29,12 +31,14 @@
           var charCode = urlEncoded.charCodeAt(i + j + 1);
           if (0x30 <= charCode && charCode <= 0x39) {
             byte = byte * 16 + charCode - 0x30;
-          } else if (0x41 <= charCode && charCode <= 0x46) {
-            byte = byte * 16 + charCode - 0x37;
-          } else if (0x61 <= charCode && charCode <= 0x66) {
-            byte = byte * 16 + charCode - 0x57;
           } else {
-            throw new HttpException("Invalid URL encoding");
+            // Check ranges A-F (0x41-0x46) and a-f (0x61-0x66).
+            charCode |= 0x20;
+            if (0x61 <= charCode && charCode <= 0x66) {
+              byte = byte * 16 + charCode - 0x57;
+            } else {
+              throw new ArgumentError("Invalid URL encoding");
+            }
           }
         }
         bytes.add(byte);
diff --git a/sdk/lib/io/input_stream.dart b/sdk/lib/io/input_stream.dart
index a2e4701..8db5e19 100644
--- a/sdk/lib/io/input_stream.dart
+++ b/sdk/lib/io/input_stream.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.io;
+
 /**
  * Basic input stream which supplies binary data.
  *
diff --git a/sdk/lib/io/io.dart b/sdk/lib/io/io.dart
index 3900b61..b976aae 100644
--- a/sdk/lib/io/io.dart
+++ b/sdk/lib/io/io.dart
@@ -10,47 +10,47 @@
  * This library allows you to work with files, directories,
  * sockets, processes, HTTP servers and clients, and more.
  */
-#library('dart:io');
+library dart.io;
 
-#import('dart:crypto');
-#import('dart:isolate');
-#import('dart:math');
-#import('dart:uri');
-#import('dart:utf');
-#import('dart:scalarlist');
+import 'dart:crypto';
+import 'dart:isolate';
+import 'dart:math';
+import 'dart:uri';
+import 'dart:utf';
+import 'dart:scalarlist';
 
-#source('base64.dart');
-#source('buffer_list.dart');
-#source('chunked_stream.dart');
-#source('common.dart');
-#source('directory.dart');
-#source('directory_impl.dart');
-#source('eventhandler.dart');
-#source('file.dart');
-#source('file_impl.dart');
-#source('http.dart');
-#source('http_headers.dart');
-#source('http_impl.dart');
-#source('http_parser.dart');
-#source('http_session.dart');
-#source('http_utils.dart');
-#source('input_stream.dart');
-#source('list_stream.dart');
-#source('list_stream_impl.dart');
-#source('mime_multipart_parser.dart');
-#source('output_stream.dart');
-#source('path.dart');
-#source('path_impl.dart');
-#source('platform.dart');
-#source('platform_impl.dart');
-#source('process.dart');
-#source('socket.dart');
-#source('socket_stream_impl.dart');
-#source('stdio.dart');
-#source('stream_util.dart');
-#source('string_stream.dart');
-#source('timer_impl.dart');
-#source('secure_socket.dart');
-#source('secure_server_socket.dart');
-#source('websocket.dart');
-#source('websocket_impl.dart');
+part 'base64.dart';
+part 'buffer_list.dart';
+part 'chunked_stream.dart';
+part 'common.dart';
+part 'directory.dart';
+part 'directory_impl.dart';
+part 'eventhandler.dart';
+part 'file.dart';
+part 'file_impl.dart';
+part 'http.dart';
+part 'http_headers.dart';
+part 'http_impl.dart';
+part 'http_parser.dart';
+part 'http_session.dart';
+part 'http_utils.dart';
+part 'input_stream.dart';
+part 'list_stream.dart';
+part 'list_stream_impl.dart';
+part 'mime_multipart_parser.dart';
+part 'output_stream.dart';
+part 'path.dart';
+part 'path_impl.dart';
+part 'platform.dart';
+part 'platform_impl.dart';
+part 'process.dart';
+part 'socket.dart';
+part 'socket_stream_impl.dart';
+part 'stdio.dart';
+part 'stream_util.dart';
+part 'string_stream.dart';
+part 'timer_impl.dart';
+part 'secure_socket.dart';
+part 'secure_server_socket.dart';
+part 'websocket.dart';
+part 'websocket_impl.dart';
diff --git a/sdk/lib/io/list_stream.dart b/sdk/lib/io/list_stream.dart
index 849d5e7..a56476d 100644
--- a/sdk/lib/io/list_stream.dart
+++ b/sdk/lib/io/list_stream.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.io;
+
 /**
  * [ListInputStream] makes it possible to use the [InputStream]
  * interface to stream over data that is received in chunks as lists
diff --git a/sdk/lib/io/list_stream_impl.dart b/sdk/lib/io/list_stream_impl.dart
index 824fa24..9d279c0 100644
--- a/sdk/lib/io/list_stream_impl.dart
+++ b/sdk/lib/io/list_stream_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.io;
+
 /**
  * Default implementation of [ListInputStream].
  */
diff --git a/sdk/lib/io/mime_multipart_parser.dart b/sdk/lib/io/mime_multipart_parser.dart
index b0af4ad..beb971e 100644
--- a/sdk/lib/io/mime_multipart_parser.dart
+++ b/sdk/lib/io/mime_multipart_parser.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.io;
+
 /**
  * Parser for MIME multipart types of data as described in RFC 2046
  * section 5.1.1. The data to parse is supplied through the [:update:]
diff --git a/sdk/lib/io/output_stream.dart b/sdk/lib/io/output_stream.dart
index c20f271..ecccced 100644
--- a/sdk/lib/io/output_stream.dart
+++ b/sdk/lib/io/output_stream.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.io;
+
 /**
  * Output streams are used to write data sequentially to a data
  * destination e.g. a connected socket or an open file.
diff --git a/sdk/lib/io/path.dart b/sdk/lib/io/path.dart
index dcf492e..82a7302 100644
--- a/sdk/lib/io/path.dart
+++ b/sdk/lib/io/path.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.io;
+
 /**
  * A Path, which is a String interpreted as a sequence of path segments,
  * which are strings, separated by forward slashes.
diff --git a/sdk/lib/io/path_impl.dart b/sdk/lib/io/path_impl.dart
index 2a661e0..6f3e892 100644
--- a/sdk/lib/io/path_impl.dart
+++ b/sdk/lib/io/path_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.io;
+
 class _Path implements Path {
   final String _path;
   final bool isWindowsShare;
diff --git a/sdk/lib/io/platform.dart b/sdk/lib/io/platform.dart
index b1dc0db..156238a 100644
--- a/sdk/lib/io/platform.dart
+++ b/sdk/lib/io/platform.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.io;
+
 /**
  * The [Platform] class exposes details of the machine and operating
  * system.
@@ -31,6 +33,11 @@
 
   /**
    * Get the environment for this process.
+   *
+   * Environment variables on Windows are case-insensitive. The map
+   * returned on Windows is therefore case-insensitive and will convert
+   * all keys to upper case. On other platforms the returned map is
+   * a standard case-sensitive map.
    */
   static Map<String, String> get environment => _Platform.environment;
 }
diff --git a/sdk/lib/io/platform_impl.dart b/sdk/lib/io/platform_impl.dart
index f8e0411..cbc8443 100644
--- a/sdk/lib/io/platform_impl.dart
+++ b/sdk/lib/io/platform_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.io;
+
 class _Platform {
   external static int _numberOfProcessors();
   external static String _pathSeparator();
@@ -35,7 +37,8 @@
     if (env is OSError) {
       throw env;
     } else {
-      var result = new Map();
+      var isWindows = operatingSystem == 'windows';
+      var result = isWindows ? new _CaseInsensitiveStringMap() : new Map();
       for (var str in env) {
         // When running on Windows through cmd.exe there are strange
         // environment variables that are used to record the current
@@ -55,3 +58,35 @@
     }
   }
 }
+
+// Environment variables are case-insensitive on Windows. In order
+// to reflect that we use a case-insensitive string map on Windows.
+class _CaseInsensitiveStringMap<V> implements Map<String, V> {
+  _CaseInsensitiveStringMap() : _map = new Map<String, V>();
+
+  _CaseInsensitiveStringMap.from(Map<String, V> other)
+      : _map = new Map<String, V>() {
+    other.forEach((String key, V value) {
+      _map[key.toUpperCase()] = value;
+    });
+  }
+
+  bool containsKey(String key) => _map.containsKey(key.toUpperCase());
+  bool containsValue(V value) => _map.containsValue(value);
+  V operator [](String key) => _map[key.toUpperCase()];
+  void operator []=(String key, V value) {
+    _map[key.toUpperCase()] = value;
+  }
+  V putIfAbsent(String key, V ifAbsent()) {
+    _map.putIfAbsent(key.toUpperCase(), ifAbsent);
+  }
+  V remove(String key) => _map.remove(key.toUpperCase());
+  void clear() => _map.clear();
+  void forEach(void f(String key, V value)) => _map.forEach(f);
+  Collection<String> get keys => _map.keys;
+  Collection<V> get values => _map.values;
+  int get length => _map.length;
+  bool get isEmpty => _map.isEmpty;
+
+  Map<String, V> _map;
+}
diff --git a/sdk/lib/io/process.dart b/sdk/lib/io/process.dart
index 87ff798..34e0140 100644
--- a/sdk/lib/io/process.dart
+++ b/sdk/lib/io/process.dart
@@ -2,21 +2,43 @@
 // for 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;
+
 // TODO(ager): The only reason for this class is that we
 // cannot patch a top-level at this point.
 class _ProcessUtils {
   external static _exit(int status);
+  external static _setExitCode(int status);
 }
 
-/** Exit the Dart VM process with the given [status] code. */
+/**
+ * Exit the Dart VM process immediately with the given [status] code.
+ *
+ * This does not wait for any asynchronous operations to terminate. Using
+ * [exit] is therefore very likely to lose data.
+ */
 void exit(int status) {
   if (status is !int) {
-    throw new ArgumentError("int status expected");
+    throw new ArgumentError("exit: int status expected");
   }
   _ProcessUtils._exit(status);
 }
 
 /**
+ * Global exit code for the Dart VM.
+ *
+ * The exit code is global for the Dart VM and the last assignment to
+ * exitCode from any isolate determines the exit code of the Dart VM
+ * on normal termination.
+ */
+set exitCode(int status) {
+  if (status is !int) {
+    throw new ArgumentError("setExitCode: int status expected");
+  }
+  _ProcessUtils._setExitCode(status);
+}
+
+/**
  * [Process] is used to start new processes using the static
  * [start] and [run] methods.
  */
diff --git a/sdk/lib/io/secure_server_socket.dart b/sdk/lib/io/secure_server_socket.dart
index fb55196..7c8d78f 100644
--- a/sdk/lib/io/secure_server_socket.dart
+++ b/sdk/lib/io/secure_server_socket.dart
@@ -2,6 +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.io;
 
 abstract class SecureServerSocket implements ServerSocket {
   /**
diff --git a/sdk/lib/io/secure_socket.dart b/sdk/lib/io/secure_socket.dart
index 02742f7..2ece3c9 100644
--- a/sdk/lib/io/secure_socket.dart
+++ b/sdk/lib/io/secure_socket.dart
@@ -2,10 +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.
 
+part of dart.io;
+
 /**
  * SecureSocket provides a secure (SSL or TLS) client connection to a server.
  * The certificate provided by the server is checked
- * using the certificate database provided in setCertificateDatabase.
+ * using the certificate database (optionally) provided in initialize().
  */
 abstract class SecureSocket implements Socket {
   /**
@@ -47,12 +49,16 @@
   X509Certificate get peerCertificate;
 
    /**
-   * Initializes the NSS library with the path to a certificate database
+   * Initializes the NSS library.  If [initialize] is not called, the library
+   * is automatically initialized as if [initialize] were called with no
+   * arguments.
+   *
+   * The optional argument [database] is the path to a certificate database
    * containing root certificates for verifying certificate paths on
    * client connections, and server certificates to provide on server
-   * connections.  The password argument should be used when creating
+   * connections.  The argument [password] should be used when creating
    * secure server sockets, to allow the private key of the server
-   * certificate to be fetched.  If useBuiltinRoots is true (the default),
+   * certificate to be fetched.  If [useBuiltinRoots] is true (the default),
    * then a built-in set of root certificates for trusted certificate
    * authorities is merged with the certificates in the database.
    *
@@ -73,7 +79,7 @@
    * containing a cert9.db file, not a cert8.db file.  This version of
    * the database can be created using the NSS certutil tool with "sql:" in
    * front of the absolute path of the database directory, or setting the
-   * environment variable NSS_DEFAULT_DB_TYPE to "sql".
+   * environment variable [[NSS_DEFAULT_DB_TYPE]] to "sql".
    */
   external static void initialize({String database,
                                    String password,
@@ -304,7 +310,8 @@
         toRead = len;
       }
     }
-    List<int> result = buffer.data.getRange(buffer.start, toRead);
+    List<int> result = (toRead == 0) ? null :
+        buffer.data.getRange(buffer.start, toRead);
     buffer.advanceStart(toRead);
     _setHandlersAfterRead();
     return result;
diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart
index 19fc0eb..84b5e75 100644
--- a/sdk/lib/io/socket.dart
+++ b/sdk/lib/io/socket.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.io;
+
 abstract class ServerSocket {
   /**
    * Constructs a new server socket, binds it to a given address and port,
diff --git a/sdk/lib/io/socket_stream_impl.dart b/sdk/lib/io/socket_stream_impl.dart
index 08127d3..ffa0cbf 100644
--- a/sdk/lib/io/socket_stream_impl.dart
+++ b/sdk/lib/io/socket_stream_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.io;
+
 class _SocketInputStream implements InputStream {
   _SocketInputStream(Socket socket) : _socket = socket {
     if (_socket._closed) _closed = true;
@@ -107,7 +109,7 @@
   }
 
   void destroy() {
-    _socket.onWrite = null;
+    _socket._onWrite = null;
     _pendingWrites.clear();
     _socket.close();
     _closed = true;
@@ -189,12 +191,12 @@
   }
 
   bool _onSocketError(e) {
-    close();
+    destroy();
     if (_onError != null) {
       _onError(e);
       return true;
     } else {
-      return false;
+      throw e;
     }
   }
 
diff --git a/sdk/lib/io/stdio.dart b/sdk/lib/io/stdio.dart
index 246fe31..fc893bf 100644
--- a/sdk/lib/io/stdio.dart
+++ b/sdk/lib/io/stdio.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.io;
+
 const int _STDIO_HANDLE_TYPE_TERMINAL = 0;
 const int _STDIO_HANDLE_TYPE_PIPE = 1;
 const int _STDIO_HANDLE_TYPE_FILE = 2;
diff --git a/sdk/lib/io/stream_util.dart b/sdk/lib/io/stream_util.dart
index f111a64..1f782cc 100644
--- a/sdk/lib/io/stream_util.dart
+++ b/sdk/lib/io/stream_util.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.io;
+
 abstract class _BaseDataInputStream {
   int available();
 
diff --git a/sdk/lib/io/string_stream.dart b/sdk/lib/io/string_stream.dart
index 4c73d15..b8101f0 100644
--- a/sdk/lib/io/string_stream.dart
+++ b/sdk/lib/io/string_stream.dart
@@ -1,7 +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.
 
+part of dart.io;
+
 // Interface for decoders decoding binary data into string data. The
 // decoder keeps track of line breaks during decoding.
 abstract class _StringDecoder {
@@ -9,6 +11,8 @@
   // is transfered to the decoder and the caller most not modify it any more.
   int write(List<int> buffer);
 
+  void done();
+
   // Returns whether any decoded data is available.
   bool get isEmpty;
 
@@ -86,6 +90,8 @@
     return buffer.length;
   }
 
+  void done() { }
+
   bool get isEmpty => _result.isEmpty;
 
   int get lineBreaks => _lineBreaks;
@@ -180,6 +186,24 @@
 // Utility class for decoding UTF-8 from data delivered as a stream of
 // bytes.
 class _UTF8Decoder extends _StringDecoderBase {
+  static const kMaxCodePoint = 0x10FFFF;
+  static const kReplacementCodePoint = 0x3f;
+
+  void done() {
+    if (!_bufferList.isEmpty) {
+      _reportError(new DecoderException("Illegal UTF-8"));
+    }
+  }
+
+  bool _reportError(error) {
+    if (onError != null) {
+      onError(error);
+      return false;
+    } else {
+      throw error;
+    }
+  }
+
   // Process the next UTF-8 encoded character.
   bool _processNext() {
     // Peek the next byte to calculate the number of bytes required for
@@ -193,9 +217,17 @@
       } else if ((value & 0xf0) == 0xe0) {  // 1110xxxx
         value = value & 0x0F;
         additionalBytes = 2;
-      } else {  // 11110xxx
+      } else if ((value & 0xf8) == 0xf0) {  // 11110xxx
         value = value & 0x07;
         additionalBytes = 3;
+      } else if ((value & 0xfc) == 0xf8) {  // 111110xx
+        value = value & 0x03;
+        additionalBytes = 4;
+      } else if ((value & 0xfe) == 0xfc) {  // 1111110x
+        value = value & 0x01;
+        additionalBytes = 5;
+      } else {
+        return _reportError(new DecoderException("Illegal UTF-8"));
       }
       // Check if there are enough bytes to decode the character. Otherwise
       // return false.
@@ -206,13 +238,20 @@
       _bufferList.next();
       for (int i = 0; i < additionalBytes; i++) {
         int byte = _bufferList.next();
+        if ((byte & 0xc0) != 0x80) {
+          return _reportError(new DecoderException("Illegal UTF-8"));
+        }
         value = value << 6 | (byte & 0x3F);
       }
     } else {
       // Remove the value peeked from the buffer list.
       _bufferList.next();
     }
-    addChar(value);
+    if (value > kMaxCodePoint) {
+      addChar(kReplacementCodePoint);
+    } else {
+      addChar(value);
+    }
     return true;
   }
 }
@@ -448,6 +487,7 @@
 
   void _onClosed() {
     _inputClosed = true;
+    _decoder.done();
     if (_decoder.isEmpty && _clientCloseHandler !=  null) {
       _clientCloseHandler();
     } else {
diff --git a/sdk/lib/io/timer_impl.dart b/sdk/lib/io/timer_impl.dart
index 2e78eba..b1e4d42 100644
--- a/sdk/lib/io/timer_impl.dart
+++ b/sdk/lib/io/timer_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.io;
+
 class _Timer implements Timer {
   // Set jitter to wake up timer events that would happen in _TIMER_JITTER ms.
   static const int _TIMER_JITTER = 0;
diff --git a/sdk/lib/io/websocket.dart b/sdk/lib/io/websocket.dart
index 34c92dc..0c1c476 100644
--- a/sdk/lib/io/websocket.dart
+++ b/sdk/lib/io/websocket.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.io;
+
 /**
  * Web socket status codes used when closing a web socket connection.
  */
diff --git a/sdk/lib/io/websocket_impl.dart b/sdk/lib/io/websocket_impl.dart
index 5d6f7d6..bcd44f0 100644
--- a/sdk/lib/io/websocket_impl.dart
+++ b/sdk/lib/io/websocket_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.io;
+
 const String _webSocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
 
 class _WebSocketMessageType {
diff --git a/sdk/lib/isolate/base.dart b/sdk/lib/isolate/base.dart
index e43e3bb..93f8efe 100644
--- a/sdk/lib/isolate/base.dart
+++ b/sdk/lib/isolate/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.isolate;
+
 class IsolateSpawnException implements Exception {
   const IsolateSpawnException(String this._s);
   String toString() => "IsolateSpawnException: '$_s'";
@@ -32,8 +34,8 @@
  * See comments at the top of this library for more details.
  */
 // Note this feature is not yet available in the dartvm.
-external SendPort spawnFunction(void topLevelFunction());
-
+external SendPort spawnFunction(void topLevelFunction(),
+    [bool UnhandledExceptionCallback(IsolateUnhandledException e)]);
 /**
  * Creates and spawns an isolate whose code is available at [uri].  Like with
  * [spawnFunction], the child isolate will have a default [ReceivePort], and a
@@ -142,3 +144,29 @@
   callSync(var message);
 
 }
+
+/**
+ * Wraps unhandled exceptions thrown during isolate execution. It is
+ * used to show both the error message and the stack trace for unhandled
+ * exceptions.
+ */
+class IsolateUnhandledException implements Exception {
+  /** Message being handled when exception occurred. */
+  final message;
+
+  /** Wrapped exception. */
+  final source;
+
+  /** Trace for the wrapped exception. */
+  final Object stackTrace;
+
+  const IsolateUnhandledException(this.message, this.source, this.stackTrace);
+
+  String toString() {
+    return 'IsolateUnhandledException: exception while handling message: '
+        '${message} \n  '
+        '${source.toString().replaceAll("\n", "\n  ")}\n'
+        'original stack trace:\n  '
+        '${stackTrace.toString().replaceAll("\n","\n  ")}';
+  }
+}
diff --git a/sdk/lib/isolate/isolate.dart b/sdk/lib/isolate/isolate.dart
index da5ff32..ab4c71d 100644
--- a/sdk/lib/isolate/isolate.dart
+++ b/sdk/lib/isolate/isolate.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#library("dart:isolate");
+library dart.isolate;
 
-#source("base.dart");
-#source("timer.dart");
+part "base.dart";
+part "timer.dart";
diff --git a/sdk/lib/isolate/timer.dart b/sdk/lib/isolate/timer.dart
index 838348a..40d4cd9 100644
--- a/sdk/lib/isolate/timer.dart
+++ b/sdk/lib/isolate/timer.dart
@@ -2,18 +2,20 @@
 // for 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.isolate;
+
 abstract class Timer {
   /**
    * Creates a new timer. The [callback] callback is invoked after
-   * [milliSeconds] milliseconds.
+   * [milliseconds] milliseconds.
    */
-  external factory Timer(int milliSeconds, void callback(Timer timer));
+  external factory Timer(int milliseconds, void callback(Timer timer));
 
   /**
    * Creates a new repeating timer. The [callback] is invoked every
-   * [milliSeconds] millisecond until cancelled.
+   * [milliseconds] millisecond until cancelled.
    */
-  external factory Timer.repeating(int milliSeconds,
+  external factory Timer.repeating(int milliseconds,
                                    void callback(Timer timer));
 
   /**
diff --git a/sdk/lib/json/json.dart b/sdk/lib/json/json.dart
index c0297fa..5ba8a74 100644
--- a/sdk/lib/json/json.dart
+++ b/sdk/lib/json/json.dart
@@ -2,9 +2,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.
 
-#library("dart:json");
+library dart.json;
 
-#import('dart:math');
+import 'dart:math';
 
 // JSON parsing and serialization.
 
diff --git a/sdk/lib/math/base.dart b/sdk/lib/math/base.dart
index b2e7fae..4aab467 100644
--- a/sdk/lib/math/base.dart
+++ b/sdk/lib/math/base.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.
 
-// A part of the dart:math library.
+part of dart.math;
 
 /**
  * Base of the natural logarithms.
diff --git a/sdk/lib/math/math.dart b/sdk/lib/math/math.dart
index d30b1e2..428f6ce 100644
--- a/sdk/lib/math/math.dart
+++ b/sdk/lib/math/math.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#library("dart:math");
+library dart.math;
 
-#source("base.dart");
-#source("random.dart");
+part "base.dart";
+part "random.dart";
diff --git a/sdk/lib/math/random.dart b/sdk/lib/math/random.dart
index bba1867..cefba24 100644
--- a/sdk/lib/math/random.dart
+++ b/sdk/lib/math/random.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.
 
-// A part of the dart:math library.
+part of dart.math;
 
 /**
  * A random number generator. The default implementation supplies a stream of
diff --git a/sdk/lib/mirrors/mirrors.dart b/sdk/lib/mirrors/mirrors.dart
index 303cec4..1b3ad7b 100644
--- a/sdk/lib/mirrors/mirrors.dart
+++ b/sdk/lib/mirrors/mirrors.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// The dart:mirrors library provides reflective access for Dart program.
-//
 // For the purposes of the mirrors library, we adopt a naming
 // convention with respect to getters and setters.  Specifically, for
 // some variable or field...
@@ -14,732 +12,8 @@
 // 'myField='.  This allows us to assign unique names to getters and
 // setters for the purposes of member lookup.
 
-// #library("mirrors");
+library dart.mirrors;
 
-/**
- * A [MirrorSystem] is the main interface used to reflect on a set of
- * associated libraries.
- *
- * At runtime each running isolate has a distinct [MirrorSystem].
- *
- * It is also possible to have a [MirrorSystem] which represents a set
- * of libraries which are not running -- perhaps at compile-time.  In
- * this case, all available reflective functionality would be
- * supported, but runtime functionality (such as invoking a function
- * or inspecting the contents of a variable) would fail dynamically.
- */
-abstract class MirrorSystem {
-  /**
-   * An immutable map from from library names to mirrors for all
-   * libraries known to this mirror system.
-   */
-  Map<String, LibraryMirror> get libraries;
+import 'dart:isolate';
 
-  /**
-   * A mirror on the isolate associated with this [MirrorSystem].
-   * This may be null if this mirror system is not running.
-   */
-  IsolateMirror get isolate;
-
-  /**
-   * A mirror on the [:dynamic:] type.
-   */
-  TypeMirror get dynamicType;
-
-  /**
-   * A mirror on the [:void:] type.
-   */
-  TypeMirror get voidType;
-}
-
-/**
- * Returns a [MirrorSystem] for the current isolate.
- */
-MirrorSystem currentMirrorSystem() {
-  return _Mirrors.currentMirrorSystem();
-}
-
-/**
- * Creates a [MirrorSystem] for the isolate which is listening on
- * the [SendPort].
- */
-Future<MirrorSystem> mirrorSystemOf(SendPort port) {
-  return _Mirrors.mirrorSystemOf(port);
-}
-
-/**
- * Returns an [InstanceMirror] for some Dart language object.
- *
- * This only works if this mirror system is associated with the
- * current running isolate.
- */
-InstanceMirror reflect(Object reflectee) {
-  return _Mirrors.reflect(reflectee);
-}
-
-/**
- * A [Mirror] reflects some Dart language entity.
- *
- * Every [Mirror] originates from some [MirrorSystem].
- */
-abstract class Mirror {
-  /**
-   * The [MirrorSystem] that contains this mirror.
-   */
-  MirrorSystem get mirrors;
-}
-
-/**
- * An [IsolateMirror] reflects an isolate.
- */
-abstract class IsolateMirror implements Mirror {
-  /**
-   * A unique name used to refer to an isolate in debugging messages.
-   */
-  String get debugName;
-
-  /**
-   * Does this mirror reflect the currently running isolate?
-   */
-  bool get isCurrent;
-
-  /**
-   * A mirror on the root library for this isolate.
-   */
-  LibraryMirror get rootLibrary;
-}
-
-/**
- * A [DeclarationMirror] reflects some entity declared in a Dart program.
- */
-abstract class DeclarationMirror implements Mirror {
-  /**
-   * The simple name for this Dart language entity.
-   *
-   * The simple name is in most cases the the identifier name of the
-   * entity, such as 'method' for a method [:void method() {...}:] or
-   * 'mylibrary' for a [:#library('mylibrary');:] declaration.
-   */
-  String get simpleName;
-
-  /**
-   * The fully-qualified name for this Dart language entity.
-   *
-   * This name is qualified by the name of the owner. For instance,
-   * the qualified name of a method 'method' in class 'Class' in
-   * library 'library' is 'library.Class.method'.
-   *
-   * TODO(turnidge): Specify whether this name is unique.  Currently
-   * this is a gray area due to lack of clarity over whether library
-   * names are unique.
-   */
-  String get qualifiedName;
-
-  /**
-   * A mirror on the owner of this function.  This is the declaration
-   * immediately surrounding the reflectee.
-   *
-   * Note that for libraries, the owner will be [:null:].
-   */
-  DeclarationMirror get owner;
-
-  /**
-   * Is this declaration private?
-   *
-   * Note that for libraries, this will be [:false:].
-   */
-  bool get isPrivate;
-
-  /**
-   * Is this declaration top-level?
-   *
-   * This is defined to be equivalent to:
-   *    [:mirror.owner != null && mirror.owner is LibraryMirror:]
-   */
-  bool get isTopLevel;
-
-  /**
-   * The source location of this Dart language entity.
-   */
-  SourceLocation get location;
-}
-
-/**
- * An [ObjectMirror] is a common superinterface of [InstanceMirror],
- * [ClassMirror], and [LibraryMirror] that represents their shared
- * functionality.
- *
- * For the purposes of the mirrors library, these types are all
- * object-like, in that they support method invocation and field
- * access.  Real Dart objects are represented by the [InstanceMirror]
- * type.
- *
- * See [InstanceMirror], [ClassMirror], and [LibraryMirror].
- */
-abstract class ObjectMirror implements Mirror {
-  /**
-   * Invokes the named function and returns a mirror on the result.
-   *
-   * TODO(turnidge): Properly document.
-   * TODO(turnidge): Handle ambiguous names.
-   * TODO(turnidge): Handle optional & named arguments.
-   */
-  Future<InstanceMirror> invoke(String memberName,
-                                List<Object> positionalArguments,
-                                [Map<String,Object> namedArguments]);
-
-  /**
-   * Invokes a getter and returns a mirror on the result. The getter
-   * can be the implicit getter for a field or a user-defined getter
-   * method.
-   *
-   * TODO(turnidge): Handle ambiguous names.
-   */
-  Future<InstanceMirror> getField(String fieldName);
-
-  /**
-   * Invokes a setter and returns a mirror on the result. The setter
-   * may be either the implicit setter for a non-final field or a
-   * user-defined setter method.
-   *
-   * TODO(turnidge): Handle ambiguous names.
-   */
-  Future<InstanceMirror> setField(String fieldName, Object value);
-}
-
-/**
- * An [InstanceMirror] reflects an instance of a Dart language object.
- */
-abstract class InstanceMirror implements ObjectMirror {
-  /**
-   * A mirror on the type of the reflectee.
-   */
-  ClassMirror get type;
-
-  /**
-   * Does [reflectee] contain the instance reflected by this mirror?
-   * This will always be true in the local case (reflecting instances
-   * in the same isolate), but only true in the remote case if this
-   * mirror reflects a simple value.
-   *
-   * A value is simple if one of the following holds:
-   *  - the value is null
-   *  - the value is of type [num]
-   *  - the value is of type [bool]
-   *  - the value is of type [String]
-   */
-  bool get hasReflectee;
-
-  /**
-   * If the [InstanceMirror] reflects an instance it is meaningful to
-   * have a local reference to, we provide access to the actual
-   * instance here.
-   *
-   * If you access [reflectee] when [hasReflectee] is false, an
-   * exception is thrown.
-   */
-  get reflectee;
-}
-
-/**
- * A [ClosureMirror] reflects a closure.
- *
- * A [ClosureMirror] provides access to its captured variables and
- * provides the ability to execute its reflectee.
- */
-abstract class ClosureMirror implements InstanceMirror {
-  /**
-   * A mirror on the function associated with this closure.
-   */
-  MethodMirror get function;
-
-  /**
-   * The source code for this closure, if available.  Otherwise null.
-   *
-   * TODO(turnidge): Would this just be available in function?
-   */
-  String get source;
-
-  /**
-   * Executes the closure. The arguments given in the descriptor need to
-   * be InstanceMirrors or simple values.
-   *
-   * A value is simple if one of the following holds:
-   *  - the value is null
-   *  - the value is of type [num]
-   *  - the value is of type [bool]
-   *  - the value is of type [String]
-   */
-  Future<InstanceMirror> apply(List<Object> positionalArguments,
-                               [Map<String,Object> namedArguments]);
-
-  /**
-   * Looks up the value of a name in the scope of the closure. The
-   * result is a mirror on that value.
-   */
-  Future<InstanceMirror> findInContext(String name);
-}
-
-/**
- * A [LibraryMirror] reflects a Dart language library, providing
- * access to the variables, functions, and classes of the
- * library.
- */
-abstract class LibraryMirror implements DeclarationMirror, ObjectMirror {
-  /**
-   * The url of the library.
-   *
-   * TODO(turnidge): Document where this url comes from.  Will this
-   * value be sensible?
-   */
-  String get url;
-
-  /**
-   * An immutable map from from names to mirrors for all members in
-   * this library.
-   *
-   * The members of a library are its top-level classes,
-   * functions, variables, getters, and setters.
-   */
-  Map<String, Mirror> get members;
-
-  /**
-   * An immutable map from names to mirrors for all class
-   * declarations in this library.
-   */
-  Map<String, ClassMirror> get classes;
-
-  /**
-   * An immutable map from names to mirrors for all function, getter,
-   * and setter declarations in this library.
-   */
-  Map<String, MethodMirror> get functions;
-
-  /**
-   * An immutable map from names to mirrors for all getter
-   * declarations in this library.
-   */
-  Map<String, MethodMirror> get getters;
-
-  /**
-   * An immutable map from names to mirrors for all setter
-   * declarations in this library.
-   */
-  Map<String, MethodMirror> get setters;
-
-  /**
-   * An immutable map from names to mirrors for all variable
-   * declarations in this library.
-   */
-  Map<String, VariableMirror> get variables;
-}
-
-/**
- * A [TypeMirror] reflects a Dart language class, typedef
- * or type variable.
- */
-abstract class TypeMirror implements DeclarationMirror {
-}
-
-/**
- * A [ClassMirror] reflects a Dart language class.
- */
-abstract class ClassMirror implements TypeMirror, ObjectMirror {
-  /**
-   * A mirror on the superclass on the reflectee.
-   *
-   * If this type is [:Object:] or a typedef, the superClass will be
-   * null.
-   */
-  ClassMirror get superclass;
-
-  /**
-   * A list of mirrors on the superinterfaces of the reflectee.
-   */
-  List<ClassMirror> get superinterfaces;
-
-  /**
-   * An immutable map from from names to mirrors for all members of
-   * this type.
-   *
-   * The members of a type are its methods, fields, getters, and
-   * setters.  Note that constructors and type variables are not
-   * considered to be members of a type.
-   *
-   * This does not include inherited members.
-   */
-  Map<String, Mirror> get members;
-
-  /**
-   * An immutable map from names to mirrors for all method,
-   * declarations for this type.  This does not include getters and
-   * setters.
-   */
-  Map<String, MethodMirror> get methods;
-
-  /**
-   * An immutable map from names to mirrors for all getter
-   * declarations for this type.
-   */
-  Map<String, MethodMirror> get getters;
-
-  /**
-   * An immutable map from names to mirrors for all setter
-   * declarations for this type.
-   */
-  Map<String, MethodMirror> get setters;
-
-  /**
-   * An immutable map from names to mirrors for all variable
-   * declarations for this type.
-   */
-  Map<String, VariableMirror> get variables;
-
-  /**
-   * An immutable map from names to mirrors for all constructor
-   * declarations for this type.
-   */
-   Map<String, MethodMirror> get constructors;
-
-  /**
-   * An immutable map from names to mirrors for all type variables for
-   * this type.
-   *
-   * This map preserves the order of declaration of the type variables.
-   */
-   Map<String, TypeVariableMirror> get typeVariables;
-
-  /**
-   * An immutable map from names to mirrors for all type arguments for
-   * this type.
-   *
-   * This map preserves the order of declaration of the type variables.
-   */
-  Map<String, TypeMirror> get typeArguments;
-
-  /**
-   * Is this the original declaration of this type?
-   *
-   * For most classes, they are their own original declaration.  For
-   * generic classes, however, there is a distinction between the
-   * original class declaration, which has unbound type variables, and
-   * the instantiations of generic classes, which have bound type
-   * variables.
-   */
-  bool get isOriginalDeclaration;
-
-  /**
-   * A mirror on the original declaration of this type.
-   *
-   * For most classes, they are their own original declaration.  For
-   * generic classes, however, there is a distinction between the
-   * original class declaration, which has unbound type variables, and
-   * the instantiations of generic classes, which have bound type
-   * variables.
-   */
-  ClassMirror get originalDeclaration;
-
-  /**
-   * Invokes the named constructor and returns a mirror on the result.
-   *
-   * TODO(turnidge): Properly document.
-   */
-  Future<InstanceMirror> newInstance(String constructorName,
-                                     List<Object> positionalArguments,
-                                     [Map<String,Object> namedArguments]);
-
-  /**
-   * Does this mirror represent a class?
-   *
-   * TODO(turnidge): This functions goes away after the
-   * class/interface changes.
-   */
-  bool get isClass;
-
-  /**
-   * A mirror on the default factory class or null if there is none.
-   *
-   * TODO(turnidge): This functions goes away after the
-   * class/interface changes.
-   */
-  ClassMirror get defaultFactory;
-}
-
-/**
- * A [FunctionTypeMirror] represents the type of a function in the
- * Dart language.
- */
-abstract class FunctionTypeMirror implements ClassMirror {
-  /**
-   * The return type of the reflectee.
-   */
-  TypeMirror get returnType;
-
-  /**
-   * A list of the parameter types of the reflectee.
-   */
-  List<ParameterMirror> get parameters;
-
-  /**
-   * A mirror on the [:call:] method for the reflectee.
-   *
-   * TODO(turnidge): What is this and what is it for?
-   */
-  MethodMirror get callMethod;
-}
-
-/**
- * A [TypeVariableMirror] represents a type parameter of a generic
- * type.
- */
-abstract class TypeVariableMirror extends TypeMirror {
-  /**
-   * A mirror on the type that is the upper bound of this type variable.
-   */
-  TypeMirror get upperBound;
-}
-
-/**
- * A [TypedefMirror] represents a typedef in a Dart language program.
- */
-abstract class TypedefMirror implements ClassMirror {
-  /**
-   * The defining type for this typedef.
-   *
-   * For instance [:void f(int):] is the value for [:typedef void f(int):].
-   */
-  TypeMirror get value;
-}
-
-/**
- * A [MethodMirror] reflects a Dart language function, method,
- * constructor, getter, or setter.
- */
-abstract class MethodMirror implements DeclarationMirror {
-  /**
-   * A mirror on the return type for the reflectee.
-   */
-  TypeMirror get returnType;
-
-  /**
-   * A list of mirrors on the parameters for the reflectee.
-   */
-  List<ParameterMirror> get parameters;
-
-  /**
-   * Is the reflectee static?
-   *
-   * For the purposes of the mirrors library, a top-level function is
-   * considered static.
-   */
-  bool get isStatic;
-
-  /**
-   * Is the reflectee abstract?
-   */
-  bool get isAbstract;
-
-  /**
-   * Is the reflectee a regular function or method?
-   *
-   * A function or method is regular if it is not a getter, setter, or
-   * constructor.  Note that operators, by this definition, are
-   * regular methods.
-   */
-  bool get isRegularMethod;
-
-  /**
-   * Is the reflectee an operator?
-   */
-  bool get isOperator;
-
-  /**
-   * Is the reflectee a getter?
-   */
-  bool get isGetter;
-
-  /**
-   * Is the reflectee a setter?
-   */
-  bool get isSetter;
-
-  /**
-   * Is the reflectee a constructor?
-   */
-  bool get isConstructor;
-
-  /**
-   * The constructor name for named constructors and factory methods.
-   *
-   * For unnamed constructors, this is the empty string.  For
-   * non-constructors, this is the empty string.
-   *
-   * For example, [:'bar':] is the constructor name for constructor
-   * [:Foo.bar:] of type [:Foo:].
-   */
-  String get constructorName;
-
-  /**
-   * Is the reflectee a const constructor?
-   */
-  bool get isConstConstructor;
-
-  /**
-   * Is the reflectee a generative constructor?
-   */
-  bool get isGenerativeConstructor;
-
-  /**
-   * Is the reflectee a redirecting constructor?
-   */
-  bool get isRedirectingConstructor;
-
-  /**
-   * Is the reflectee a factory constructor?
-   */
-  bool get isFactoryConstructor;
-}
-
-/**
- * A [VariableMirror] reflects a Dart language variable declaration.
- */
-abstract class VariableMirror implements DeclarationMirror {
-  /**
-   * A mirror on the type of the reflectee.
-   */
-  TypeMirror get type;
-
-  /**
-   * Is the reflectee a static variable?
-   *
-   * For the purposes of the mirror library, top-level variables are
-   * implicitly declared static.
-   */
-  bool get isStatic;
-
-  /**
-   * Is the reflectee a final variable?
-   */
-  bool get isFinal;
-}
-
-/**
- * A [ParameterMirror] reflects a Dart formal parameter declaration.
- */
-abstract class ParameterMirror implements VariableMirror {
-  /**
-   * A mirror on the type of this parameter.
-   */
-  TypeMirror get type;
-
-  /**
-   * Is this parameter optional?
-   */
-  bool get isOptional;
-
-  /**
-   * Is this parameter named?
-   */
-  bool get isNamed;
-
-  /**
-   * Does this parameter have a default value?
-   */
-  bool get hasDefaultValue;
-
-  /**
-   * A mirror on the default value for this parameter, if it exists.
-   *
-   * TODO(turnidge): String may not be a good representation of this
-   * at runtime.
-   */
-  String get defaultValue;
-}
-
-/**
- * A [SourceLocation] describes the span of an entity in Dart source code.
- */
-abstract class SourceLocation {
-}
-
-/**
- * When an error occurs during the mirrored execution of code, a
- * [MirroredError] is thrown.
- *
- * In general, there are three main classes of failure that can happen
- * during mirrored execution of code in some isolate:
- *
- * - An exception is thrown but not caught.  This is caught by the
- *   mirrors framework and a [MirroredUncaughtExceptionError] is
- *   created and thrown.
- *
- * - A compile-time error occurs, such as a syntax error.  This is
- *   suppressed by the mirrors framework and a
- *   [MirroredCompilationError] is created and thrown.
- *
- * - A truly fatal error occurs, causing the isolate to be exited.  If
- *   the reflector and reflectee share the same isolate, then they
- *   will both suffer.  If the reflector and reflectee are in distinct
- *   isolates, then we hope to provide some information about the
- *   isolate death, but this has yet to be implemented.
- *
- * TODO(turnidge): Specify the behavior for remote fatal errors.
- */
-abstract class MirroredError implements Exception {
-}
-
-/**
- * When an uncaught exception occurs during the mirrored execution
- * of code, a [MirroredUncaughtExceptionError] is thrown.
- *
- * This exception contains a mirror on the original exception object.
- * It also contains an object which can be used to recover the
- * stacktrace.
- */
-class MirroredUncaughtExceptionError extends MirroredError {
-  MirroredUncaughtExceptionError(this.exception_mirror,
-                                 this.exception_string,
-                                 this.stacktrace) {}
-
-  /** A mirror on the exception object. */
-  final InstanceMirror exception_mirror;
-
-  /** The result of toString() for the exception object. */
-  final String exception_string;
-
-  /** A stacktrace object for the uncaught exception. */
-  final Object stacktrace;
-
-  String toString() {
-    return
-        "Uncaught exception during mirrored execution: <${exception_string}>";
-  }
-}
-
-/**
- * When a compile-time error occurs during the mirrored execution
- * of code, a [MirroredCompilationError] is thrown.
- *
- * This exception includes the compile-time error message that would
- * have been displayed to the user, if the function had not been
- * invoked via mirror.
- */
-class MirroredCompilationError extends MirroredError {
-  MirroredCompilationError(this.message) {}
-
-  final String message;
-
-  String toString() {
-    return "Compile-time error during mirrored execution: <$message>";
-  }
-}
-
-/**
- * A [MirrorException] is used to indicate errors within the mirrors
- * framework.
- */
-class MirrorException implements Exception {
-  const MirrorException(String this._message);
-  String toString() => "MirrorException: '$_message'";
-  final String _message;
-}
+part 'mirrors_impl.dart';
diff --git a/sdk/lib/mirrors/mirrors_impl.dart b/sdk/lib/mirrors/mirrors_impl.dart
new file mode 100644
index 0000000..31effd0
--- /dev/null
+++ b/sdk/lib/mirrors/mirrors_impl.dart
@@ -0,0 +1,725 @@
+// 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.
+
+/**
+ * A [MirrorSystem] is the main interface used to reflect on a set of
+ * associated libraries.
+ *
+ * At runtime each running isolate has a distinct [MirrorSystem].
+ *
+ * It is also possible to have a [MirrorSystem] which represents a set
+ * of libraries which are not running -- perhaps at compile-time.  In
+ * this case, all available reflective functionality would be
+ * supported, but runtime functionality (such as invoking a function
+ * or inspecting the contents of a variable) would fail dynamically.
+ */
+abstract class MirrorSystem {
+  /**
+   * An immutable map from from library names to mirrors for all
+   * libraries known to this mirror system.
+   */
+  Map<String, LibraryMirror> get libraries;
+
+  /**
+   * A mirror on the isolate associated with this [MirrorSystem].
+   * This may be null if this mirror system is not running.
+   */
+  IsolateMirror get isolate;
+
+  /**
+   * A mirror on the [:dynamic:] type.
+   */
+  TypeMirror get dynamicType;
+
+  /**
+   * A mirror on the [:void:] type.
+   */
+  TypeMirror get voidType;
+}
+
+/**
+ * Returns a [MirrorSystem] for the current isolate.
+ */
+external MirrorSystem currentMirrorSystem();
+
+/**
+ * Creates a [MirrorSystem] for the isolate which is listening on
+ * the [SendPort].
+ */
+external Future<MirrorSystem> mirrorSystemOf(SendPort port);
+
+/**
+ * Returns an [InstanceMirror] for some Dart language object.
+ *
+ * This only works if this mirror system is associated with the
+ * current running isolate.
+ */
+external InstanceMirror reflect(Object reflectee);
+
+/**
+ * A [Mirror] reflects some Dart language entity.
+ *
+ * Every [Mirror] originates from some [MirrorSystem].
+ */
+abstract class Mirror {
+  /**
+   * The [MirrorSystem] that contains this mirror.
+   */
+  MirrorSystem get mirrors;
+}
+
+/**
+ * An [IsolateMirror] reflects an isolate.
+ */
+abstract class IsolateMirror implements Mirror {
+  /**
+   * A unique name used to refer to an isolate in debugging messages.
+   */
+  String get debugName;
+
+  /**
+   * Does this mirror reflect the currently running isolate?
+   */
+  bool get isCurrent;
+
+  /**
+   * A mirror on the root library for this isolate.
+   */
+  LibraryMirror get rootLibrary;
+}
+
+/**
+ * A [DeclarationMirror] reflects some entity declared in a Dart program.
+ */
+abstract class DeclarationMirror implements Mirror {
+  /**
+   * The simple name for this Dart language entity.
+   *
+   * The simple name is in most cases the the identifier name of the
+   * entity, such as 'method' for a method [:void method() {...}:] or
+   * 'mylibrary' for a [:#library('mylibrary');:] declaration.
+   */
+  String get simpleName;
+
+  /**
+   * The fully-qualified name for this Dart language entity.
+   *
+   * This name is qualified by the name of the owner. For instance,
+   * the qualified name of a method 'method' in class 'Class' in
+   * library 'library' is 'library.Class.method'.
+   *
+   * TODO(turnidge): Specify whether this name is unique.  Currently
+   * this is a gray area due to lack of clarity over whether library
+   * names are unique.
+   */
+  String get qualifiedName;
+
+  /**
+   * A mirror on the owner of this function.  This is the declaration
+   * immediately surrounding the reflectee.
+   *
+   * Note that for libraries, the owner will be [:null:].
+   */
+  DeclarationMirror get owner;
+
+  /**
+   * Is this declaration private?
+   *
+   * Note that for libraries, this will be [:false:].
+   */
+  bool get isPrivate;
+
+  /**
+   * Is this declaration top-level?
+   *
+   * This is defined to be equivalent to:
+   *    [:mirror.owner != null && mirror.owner is LibraryMirror:]
+   */
+  bool get isTopLevel;
+
+  /**
+   * The source location of this Dart language entity.
+   */
+  SourceLocation get location;
+}
+
+/**
+ * An [ObjectMirror] is a common superinterface of [InstanceMirror],
+ * [ClassMirror], and [LibraryMirror] that represents their shared
+ * functionality.
+ *
+ * For the purposes of the mirrors library, these types are all
+ * object-like, in that they support method invocation and field
+ * access.  Real Dart objects are represented by the [InstanceMirror]
+ * type.
+ *
+ * See [InstanceMirror], [ClassMirror], and [LibraryMirror].
+ */
+abstract class ObjectMirror implements Mirror {
+  /**
+   * Invokes the named function and returns a mirror on the result.
+   *
+   * TODO(turnidge): Properly document.
+   * TODO(turnidge): Handle ambiguous names.
+   * TODO(turnidge): Handle optional & named arguments.
+   */
+  Future<InstanceMirror> invoke(String memberName,
+                                List<Object> positionalArguments,
+                                [Map<String,Object> namedArguments]);
+
+  /**
+   * Invokes a getter and returns a mirror on the result. The getter
+   * can be the implicit getter for a field or a user-defined getter
+   * method.
+   *
+   * TODO(turnidge): Handle ambiguous names.
+   */
+  Future<InstanceMirror> getField(String fieldName);
+
+  /**
+   * Invokes a setter and returns a mirror on the result. The setter
+   * may be either the implicit setter for a non-final field or a
+   * user-defined setter method.
+   *
+   * TODO(turnidge): Handle ambiguous names.
+   */
+  Future<InstanceMirror> setField(String fieldName, Object value);
+}
+
+/**
+ * An [InstanceMirror] reflects an instance of a Dart language object.
+ */
+abstract class InstanceMirror implements ObjectMirror {
+  /**
+   * A mirror on the type of the reflectee.
+   */
+  ClassMirror get type;
+
+  /**
+   * Does [reflectee] contain the instance reflected by this mirror?
+   * This will always be true in the local case (reflecting instances
+   * in the same isolate), but only true in the remote case if this
+   * mirror reflects a simple value.
+   *
+   * A value is simple if one of the following holds:
+   *  - the value is null
+   *  - the value is of type [num]
+   *  - the value is of type [bool]
+   *  - the value is of type [String]
+   */
+  bool get hasReflectee;
+
+  /**
+   * If the [InstanceMirror] reflects an instance it is meaningful to
+   * have a local reference to, we provide access to the actual
+   * instance here.
+   *
+   * If you access [reflectee] when [hasReflectee] is false, an
+   * exception is thrown.
+   */
+  get reflectee;
+}
+
+/**
+ * A [ClosureMirror] reflects a closure.
+ *
+ * A [ClosureMirror] provides access to its captured variables and
+ * provides the ability to execute its reflectee.
+ */
+abstract class ClosureMirror implements InstanceMirror {
+  /**
+   * A mirror on the function associated with this closure.
+   */
+  MethodMirror get function;
+
+  /**
+   * The source code for this closure, if available.  Otherwise null.
+   *
+   * TODO(turnidge): Would this just be available in function?
+   */
+  String get source;
+
+  /**
+   * Executes the closure. The arguments given in the descriptor need to
+   * be InstanceMirrors or simple values.
+   *
+   * A value is simple if one of the following holds:
+   *  - the value is null
+   *  - the value is of type [num]
+   *  - the value is of type [bool]
+   *  - the value is of type [String]
+   */
+  Future<InstanceMirror> apply(List<Object> positionalArguments,
+                               [Map<String,Object> namedArguments]);
+
+  /**
+   * Looks up the value of a name in the scope of the closure. The
+   * result is a mirror on that value.
+   */
+  Future<InstanceMirror> findInContext(String name);
+}
+
+/**
+ * A [LibraryMirror] reflects a Dart language library, providing
+ * access to the variables, functions, and classes of the
+ * library.
+ */
+abstract class LibraryMirror implements DeclarationMirror, ObjectMirror {
+  /**
+   * The url of the library.
+   *
+   * TODO(turnidge): Document where this url comes from.  Will this
+   * value be sensible?
+   */
+  String get url;
+
+  /**
+   * An immutable map from from names to mirrors for all members in
+   * this library.
+   *
+   * The members of a library are its top-level classes,
+   * functions, variables, getters, and setters.
+   */
+  Map<String, Mirror> get members;
+
+  /**
+   * An immutable map from names to mirrors for all class
+   * declarations in this library.
+   */
+  Map<String, ClassMirror> get classes;
+
+  /**
+   * An immutable map from names to mirrors for all function, getter,
+   * and setter declarations in this library.
+   */
+  Map<String, MethodMirror> get functions;
+
+  /**
+   * An immutable map from names to mirrors for all getter
+   * declarations in this library.
+   */
+  Map<String, MethodMirror> get getters;
+
+  /**
+   * An immutable map from names to mirrors for all setter
+   * declarations in this library.
+   */
+  Map<String, MethodMirror> get setters;
+
+  /**
+   * An immutable map from names to mirrors for all variable
+   * declarations in this library.
+   */
+  Map<String, VariableMirror> get variables;
+}
+
+/**
+ * A [TypeMirror] reflects a Dart language class, typedef
+ * or type variable.
+ */
+abstract class TypeMirror implements DeclarationMirror {
+}
+
+/**
+ * A [ClassMirror] reflects a Dart language class.
+ */
+abstract class ClassMirror implements TypeMirror, ObjectMirror {
+  /**
+   * A mirror on the superclass on the reflectee.
+   *
+   * If this type is [:Object:] or a typedef, the superClass will be
+   * null.
+   */
+  ClassMirror get superclass;
+
+  /**
+   * A list of mirrors on the superinterfaces of the reflectee.
+   */
+  List<ClassMirror> get superinterfaces;
+
+  /**
+   * An immutable map from from names to mirrors for all members of
+   * this type.
+   *
+   * The members of a type are its methods, fields, getters, and
+   * setters.  Note that constructors and type variables are not
+   * considered to be members of a type.
+   *
+   * This does not include inherited members.
+   */
+  Map<String, Mirror> get members;
+
+  /**
+   * An immutable map from names to mirrors for all method,
+   * declarations for this type.  This does not include getters and
+   * setters.
+   */
+  Map<String, MethodMirror> get methods;
+
+  /**
+   * An immutable map from names to mirrors for all getter
+   * declarations for this type.
+   */
+  Map<String, MethodMirror> get getters;
+
+  /**
+   * An immutable map from names to mirrors for all setter
+   * declarations for this type.
+   */
+  Map<String, MethodMirror> get setters;
+
+  /**
+   * An immutable map from names to mirrors for all variable
+   * declarations for this type.
+   */
+  Map<String, VariableMirror> get variables;
+
+  /**
+   * An immutable map from names to mirrors for all constructor
+   * declarations for this type.
+   */
+   Map<String, MethodMirror> get constructors;
+
+  /**
+   * An immutable map from names to mirrors for all type variables for
+   * this type.
+   *
+   * This map preserves the order of declaration of the type variables.
+   */
+   Map<String, TypeVariableMirror> get typeVariables;
+
+  /**
+   * An immutable map from names to mirrors for all type arguments for
+   * this type.
+   *
+   * This map preserves the order of declaration of the type variables.
+   */
+  Map<String, TypeMirror> get typeArguments;
+
+  /**
+   * Is this the original declaration of this type?
+   *
+   * For most classes, they are their own original declaration.  For
+   * generic classes, however, there is a distinction between the
+   * original class declaration, which has unbound type variables, and
+   * the instantiations of generic classes, which have bound type
+   * variables.
+   */
+  bool get isOriginalDeclaration;
+
+  /**
+   * A mirror on the original declaration of this type.
+   *
+   * For most classes, they are their own original declaration.  For
+   * generic classes, however, there is a distinction between the
+   * original class declaration, which has unbound type variables, and
+   * the instantiations of generic classes, which have bound type
+   * variables.
+   */
+  ClassMirror get originalDeclaration;
+
+  /**
+   * Invokes the named constructor and returns a mirror on the result.
+   *
+   * TODO(turnidge): Properly document.
+   */
+  Future<InstanceMirror> newInstance(String constructorName,
+                                     List<Object> positionalArguments,
+                                     [Map<String,Object> namedArguments]);
+
+  /**
+   * Does this mirror represent a class?
+   *
+   * TODO(turnidge): This functions goes away after the
+   * class/interface changes.
+   */
+  bool get isClass;
+
+  /**
+   * A mirror on the default factory class or null if there is none.
+   *
+   * TODO(turnidge): This functions goes away after the
+   * class/interface changes.
+   */
+  ClassMirror get defaultFactory;
+}
+
+/**
+ * A [FunctionTypeMirror] represents the type of a function in the
+ * Dart language.
+ */
+abstract class FunctionTypeMirror implements ClassMirror {
+  /**
+   * The return type of the reflectee.
+   */
+  TypeMirror get returnType;
+
+  /**
+   * A list of the parameter types of the reflectee.
+   */
+  List<ParameterMirror> get parameters;
+
+  /**
+   * A mirror on the [:call:] method for the reflectee.
+   *
+   * TODO(turnidge): What is this and what is it for?
+   */
+  MethodMirror get callMethod;
+}
+
+/**
+ * A [TypeVariableMirror] represents a type parameter of a generic
+ * type.
+ */
+abstract class TypeVariableMirror extends TypeMirror {
+  /**
+   * A mirror on the type that is the upper bound of this type variable.
+   */
+  TypeMirror get upperBound;
+}
+
+/**
+ * A [TypedefMirror] represents a typedef in a Dart language program.
+ */
+abstract class TypedefMirror implements ClassMirror {
+  /**
+   * The defining type for this typedef.
+   *
+   * For instance [:void f(int):] is the value for [:typedef void f(int):].
+   */
+  TypeMirror get value;
+}
+
+/**
+ * A [MethodMirror] reflects a Dart language function, method,
+ * constructor, getter, or setter.
+ */
+abstract class MethodMirror implements DeclarationMirror {
+  /**
+   * A mirror on the return type for the reflectee.
+   */
+  TypeMirror get returnType;
+
+  /**
+   * A list of mirrors on the parameters for the reflectee.
+   */
+  List<ParameterMirror> get parameters;
+
+  /**
+   * Is the reflectee static?
+   *
+   * For the purposes of the mirrors library, a top-level function is
+   * considered static.
+   */
+  bool get isStatic;
+
+  /**
+   * Is the reflectee abstract?
+   */
+  bool get isAbstract;
+
+  /**
+   * Is the reflectee a regular function or method?
+   *
+   * A function or method is regular if it is not a getter, setter, or
+   * constructor.  Note that operators, by this definition, are
+   * regular methods.
+   */
+  bool get isRegularMethod;
+
+  /**
+   * Is the reflectee an operator?
+   */
+  bool get isOperator;
+
+  /**
+   * Is the reflectee a getter?
+   */
+  bool get isGetter;
+
+  /**
+   * Is the reflectee a setter?
+   */
+  bool get isSetter;
+
+  /**
+   * Is the reflectee a constructor?
+   */
+  bool get isConstructor;
+
+  /**
+   * The constructor name for named constructors and factory methods.
+   *
+   * For unnamed constructors, this is the empty string.  For
+   * non-constructors, this is the empty string.
+   *
+   * For example, [:'bar':] is the constructor name for constructor
+   * [:Foo.bar:] of type [:Foo:].
+   */
+  String get constructorName;
+
+  /**
+   * Is the reflectee a const constructor?
+   */
+  bool get isConstConstructor;
+
+  /**
+   * Is the reflectee a generative constructor?
+   */
+  bool get isGenerativeConstructor;
+
+  /**
+   * Is the reflectee a redirecting constructor?
+   */
+  bool get isRedirectingConstructor;
+
+  /**
+   * Is the reflectee a factory constructor?
+   */
+  bool get isFactoryConstructor;
+}
+
+/**
+ * A [VariableMirror] reflects a Dart language variable declaration.
+ */
+abstract class VariableMirror implements DeclarationMirror {
+  /**
+   * A mirror on the type of the reflectee.
+   */
+  TypeMirror get type;
+
+  /**
+   * Is the reflectee a static variable?
+   *
+   * For the purposes of the mirror library, top-level variables are
+   * implicitly declared static.
+   */
+  bool get isStatic;
+
+  /**
+   * Is the reflectee a final variable?
+   */
+  bool get isFinal;
+}
+
+/**
+ * A [ParameterMirror] reflects a Dart formal parameter declaration.
+ */
+abstract class ParameterMirror implements VariableMirror {
+  /**
+   * A mirror on the type of this parameter.
+   */
+  TypeMirror get type;
+
+  /**
+   * Is this parameter optional?
+   */
+  bool get isOptional;
+
+  /**
+   * Is this parameter named?
+   */
+  bool get isNamed;
+
+  /**
+   * Does this parameter have a default value?
+   */
+  bool get hasDefaultValue;
+
+  /**
+   * A mirror on the default value for this parameter, if it exists.
+   *
+   * TODO(turnidge): String may not be a good representation of this
+   * at runtime.
+   */
+  String get defaultValue;
+}
+
+/**
+ * A [SourceLocation] describes the span of an entity in Dart source code.
+ */
+abstract class SourceLocation {
+}
+
+/**
+ * When an error occurs during the mirrored execution of code, a
+ * [MirroredError] is thrown.
+ *
+ * In general, there are three main classes of failure that can happen
+ * during mirrored execution of code in some isolate:
+ *
+ * - An exception is thrown but not caught.  This is caught by the
+ *   mirrors framework and a [MirroredUncaughtExceptionError] is
+ *   created and thrown.
+ *
+ * - A compile-time error occurs, such as a syntax error.  This is
+ *   suppressed by the mirrors framework and a
+ *   [MirroredCompilationError] is created and thrown.
+ *
+ * - A truly fatal error occurs, causing the isolate to be exited.  If
+ *   the reflector and reflectee share the same isolate, then they
+ *   will both suffer.  If the reflector and reflectee are in distinct
+ *   isolates, then we hope to provide some information about the
+ *   isolate death, but this has yet to be implemented.
+ *
+ * TODO(turnidge): Specify the behavior for remote fatal errors.
+ */
+abstract class MirroredError implements Exception {
+}
+
+/**
+ * When an uncaught exception occurs during the mirrored execution
+ * of code, a [MirroredUncaughtExceptionError] is thrown.
+ *
+ * This exception contains a mirror on the original exception object.
+ * It also contains an object which can be used to recover the
+ * stacktrace.
+ */
+class MirroredUncaughtExceptionError extends MirroredError {
+  MirroredUncaughtExceptionError(this.exception_mirror,
+                                 this.exception_string,
+                                 this.stacktrace) {}
+
+  /** A mirror on the exception object. */
+  final InstanceMirror exception_mirror;
+
+  /** The result of toString() for the exception object. */
+  final String exception_string;
+
+  /** A stacktrace object for the uncaught exception. */
+  final Object stacktrace;
+
+  String toString() {
+    return
+        "Uncaught exception during mirrored execution: <${exception_string}>";
+  }
+}
+
+/**
+ * When a compile-time error occurs during the mirrored execution
+ * of code, a [MirroredCompilationError] is thrown.
+ *
+ * This exception includes the compile-time error message that would
+ * have been displayed to the user, if the function had not been
+ * invoked via mirror.
+ */
+class MirroredCompilationError extends MirroredError {
+  MirroredCompilationError(this.message) {}
+
+  final String message;
+
+  String toString() {
+    return "Compile-time error during mirrored execution: <$message>";
+  }
+}
+
+/**
+ * A [MirrorException] is used to indicate errors within the mirrors
+ * framework.
+ */
+class MirrorException implements Exception {
+  const MirrorException(String this._message);
+  String toString() => "MirrorException: '$_message'";
+  final String _message;
+}
diff --git a/sdk/lib/mirrors/mirrors_sources.gypi b/sdk/lib/mirrors/mirrors_sources.gypi
index 8134666..5f55725 100644
--- a/sdk/lib/mirrors/mirrors_sources.gypi
+++ b/sdk/lib/mirrors/mirrors_sources.gypi
@@ -4,6 +4,6 @@
 
 {
   'sources': [
-    '../../../runtime/lib/empty_source.dart',
+    'mirrors_impl.dart',
   ],
 }
diff --git a/sdk/lib/scalarlist/byte_arrays.dart b/sdk/lib/scalarlist/byte_arrays.dart
index df3ab98..d843259 100644
--- a/sdk/lib/scalarlist/byte_arrays.dart
+++ b/sdk/lib/scalarlist/byte_arrays.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.scalarlist;
+
 /**
  * A random-access sequence of bytes that also provides random access to
  * the fixed-width integers and floating point numbers represented by
diff --git a/sdk/lib/scalarlist/scalarlist.dart b/sdk/lib/scalarlist/scalarlist.dart
index 7027378..508b20e 100644
--- a/sdk/lib/scalarlist/scalarlist.dart
+++ b/sdk/lib/scalarlist/scalarlist.dart
@@ -10,9 +10,9 @@
  * This library allows you to work with arrays of scalar values
  * of various sizes.
  */
-#library('dart:scalarlist');
+library dart.scalarlist;
 
 // TODO(ager): Inline the contents of byte_arrays.dart here and get
 // rid of scalarlist_sources.gypi when the VM understands normal
 // library structure for builtin libraries.
-#source('byte_arrays.dart');
+part 'byte_arrays.dart';
diff --git a/sdk/lib/svg/dartium/svg_dartium.dart b/sdk/lib/svg/dartium/svg_dartium.dart
index 620d78b..77648fa 100644
--- a/sdk/lib/svg/dartium/svg_dartium.dart
+++ b/sdk/lib/svg/dartium/svg_dartium.dart
@@ -60,10 +60,10 @@
 
 /// @domName SVGAElement
 class AElement extends SvgElement implements Transformable, Tests, UriReference, Stylable, ExternalResourcesRequired, LangSpace {
+  AElement.internal() : super.internal();
 
   ///@docsEditable true
   factory AElement() => _SvgElementFactoryProvider.createSvgElement_tag("a");
-  AElement.internal(): super.internal();
 
 
   /** @domName SVGAElement.target */
@@ -159,7 +159,7 @@
 
 /// @domName SVGAltGlyphDefElement
 class AltGlyphDefElement extends SvgElement {
-  AltGlyphDefElement.internal(): super.internal();
+  AltGlyphDefElement.internal() : super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -171,7 +171,7 @@
 
 /// @domName SVGAltGlyphElement
 class AltGlyphElement extends TextPositioningElement implements UriReference {
-  AltGlyphElement.internal(): super.internal();
+  AltGlyphElement.internal() : super.internal();
 
 
   /** @domName SVGAltGlyphElement.format */
@@ -203,7 +203,7 @@
 
 /// @domName SVGAltGlyphItemElement
 class AltGlyphItemElement extends SvgElement {
-  AltGlyphItemElement.internal(): super.internal();
+  AltGlyphItemElement.internal() : super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -273,10 +273,10 @@
 
 /// @domName SVGAnimateColorElement
 class AnimateColorElement extends AnimationElement {
+  AnimateColorElement.internal() : super.internal();
 
   ///@docsEditable true
   factory AnimateColorElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateColor");
-  AnimateColorElement.internal(): super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -288,10 +288,10 @@
 
 /// @domName SVGAnimateElement
 class AnimateElement extends AnimationElement {
+  AnimateElement.internal() : super.internal();
 
   ///@docsEditable true
   factory AnimateElement() => _SvgElementFactoryProvider.createSvgElement_tag("animate");
-  AnimateElement.internal(): super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -303,10 +303,10 @@
 
 /// @domName SVGAnimateMotionElement
 class AnimateMotionElement extends AnimationElement {
+  AnimateMotionElement.internal() : super.internal();
 
   ///@docsEditable true
   factory AnimateMotionElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateMotion");
-  AnimateMotionElement.internal(): super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -318,10 +318,10 @@
 
 /// @domName SVGAnimateTransformElement
 class AnimateTransformElement extends AnimationElement {
+  AnimateTransformElement.internal() : super.internal();
 
   ///@docsEditable true
   factory AnimateTransformElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateTransform");
-  AnimateTransformElement.internal(): super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -593,10 +593,10 @@
 
 /// @domName SVGAnimationElement
 class AnimationElement extends SvgElement implements Tests, ElementTimeControl, ExternalResourcesRequired {
+  AnimationElement.internal() : super.internal();
 
   ///@docsEditable true
   factory AnimationElement() => _SvgElementFactoryProvider.createSvgElement_tag("animation");
-  AnimationElement.internal(): super.internal();
 
 
   /** @domName SVGAnimationElement.targetElement */
@@ -660,10 +660,10 @@
 
 /// @domName SVGCircleElement
 class CircleElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+  CircleElement.internal() : super.internal();
 
   ///@docsEditable true
   factory CircleElement() => _SvgElementFactoryProvider.createSvgElement_tag("circle");
-  CircleElement.internal(): super.internal();
 
 
   /** @domName SVGCircleElement.cx */
@@ -763,10 +763,10 @@
 
 /// @domName SVGClipPathElement
 class ClipPathElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+  ClipPathElement.internal() : super.internal();
 
   ///@docsEditable true
   factory ClipPathElement() => _SvgElementFactoryProvider.createSvgElement_tag("clipPath");
-  ClipPathElement.internal(): super.internal();
 
 
   /** @domName SVGClipPathElement.clipPathUnits */
@@ -858,7 +858,7 @@
 
 /// @domName SVGColor
 class Color extends CssValue {
-  Color.internal(): super.internal();
+  Color.internal() : super.internal();
 
   static const int SVG_COLORTYPE_CURRENTCOLOR = 3;
 
@@ -898,7 +898,7 @@
 
 /// @domName SVGComponentTransferFunctionElement
 class ComponentTransferFunctionElement extends SvgElement {
-  ComponentTransferFunctionElement.internal(): super.internal();
+  ComponentTransferFunctionElement.internal() : super.internal();
 
   static const int SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE = 3;
 
@@ -950,10 +950,10 @@
 
 /// @domName SVGCursorElement
 class CursorElement extends SvgElement implements UriReference, Tests, ExternalResourcesRequired {
+  CursorElement.internal() : super.internal();
 
   ///@docsEditable true
   factory CursorElement() => _SvgElementFactoryProvider.createSvgElement_tag("cursor");
-  CursorElement.internal(): super.internal();
 
 
   /** @domName SVGCursorElement.x */
@@ -997,10 +997,10 @@
 
 /// @domName SVGDefsElement
 class DefsElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+  DefsElement.internal() : super.internal();
 
   ///@docsEditable true
   factory DefsElement() => _SvgElementFactoryProvider.createSvgElement_tag("defs");
-  DefsElement.internal(): super.internal();
 
 
   /** @domName SVGDefsElement.externalResourcesRequired */
@@ -1088,10 +1088,10 @@
 
 /// @domName SVGDescElement
 class DescElement extends SvgElement implements Stylable, LangSpace {
+  DescElement.internal() : super.internal();
 
   ///@docsEditable true
   factory DescElement() => _SvgElementFactoryProvider.createSvgElement_tag("desc");
-  DescElement.internal(): super.internal();
 
 
   /** @domName SVGDescElement.xmllang */
@@ -1131,7 +1131,7 @@
 
 /// @domName SVGElementInstance
 class ElementInstance extends EventTarget {
-  ElementInstance.internal(): super.internal();
+  ElementInstance.internal() : super.internal();
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   ElementInstanceEvents get on =>
@@ -1333,10 +1333,10 @@
 
 /// @domName SVGEllipseElement
 class EllipseElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+  EllipseElement.internal() : super.internal();
 
   ///@docsEditable true
   factory EllipseElement() => _SvgElementFactoryProvider.createSvgElement_tag("ellipse");
-  EllipseElement.internal(): super.internal();
 
 
   /** @domName SVGEllipseElement.cx */
@@ -1456,7 +1456,7 @@
 
 /// @domName SVGFEBlendElement
 class FEBlendElement extends SvgElement implements FilterPrimitiveStandardAttributes {
-  FEBlendElement.internal(): super.internal();
+  FEBlendElement.internal() : super.internal();
 
   static const int SVG_FEBLEND_MODE_DARKEN = 4;
 
@@ -1524,7 +1524,7 @@
 
 /// @domName SVGFEColorMatrixElement
 class FEColorMatrixElement extends SvgElement implements FilterPrimitiveStandardAttributes {
-  FEColorMatrixElement.internal(): super.internal();
+  FEColorMatrixElement.internal() : super.internal();
 
   static const int SVG_FECOLORMATRIX_TYPE_HUEROTATE = 3;
 
@@ -1590,7 +1590,7 @@
 
 /// @domName SVGFEComponentTransferElement
 class FEComponentTransferElement extends SvgElement implements FilterPrimitiveStandardAttributes {
-  FEComponentTransferElement.internal(): super.internal();
+  FEComponentTransferElement.internal() : super.internal();
 
 
   /** @domName SVGFEComponentTransferElement.in1 */
@@ -1638,7 +1638,7 @@
 
 /// @domName SVGFECompositeElement
 class FECompositeElement extends SvgElement implements FilterPrimitiveStandardAttributes {
-  FECompositeElement.internal(): super.internal();
+  FECompositeElement.internal() : super.internal();
 
   static const int SVG_FECOMPOSITE_OPERATOR_ARITHMETIC = 6;
 
@@ -1724,7 +1724,7 @@
 
 /// @domName SVGFEConvolveMatrixElement
 class FEConvolveMatrixElement extends SvgElement implements FilterPrimitiveStandardAttributes {
-  FEConvolveMatrixElement.internal(): super.internal();
+  FEConvolveMatrixElement.internal() : super.internal();
 
   static const int SVG_EDGEMODE_DUPLICATE = 1;
 
@@ -1824,7 +1824,7 @@
 
 /// @domName SVGFEDiffuseLightingElement
 class FEDiffuseLightingElement extends SvgElement implements FilterPrimitiveStandardAttributes {
-  FEDiffuseLightingElement.internal(): super.internal();
+  FEDiffuseLightingElement.internal() : super.internal();
 
 
   /** @domName SVGFEDiffuseLightingElement.diffuseConstant */
@@ -1888,7 +1888,7 @@
 
 /// @domName SVGFEDisplacementMapElement
 class FEDisplacementMapElement extends SvgElement implements FilterPrimitiveStandardAttributes {
-  FEDisplacementMapElement.internal(): super.internal();
+  FEDisplacementMapElement.internal() : super.internal();
 
   static const int SVG_CHANNEL_A = 4;
 
@@ -1962,7 +1962,7 @@
 
 /// @domName SVGFEDistantLightElement
 class FEDistantLightElement extends SvgElement {
-  FEDistantLightElement.internal(): super.internal();
+  FEDistantLightElement.internal() : super.internal();
 
 
   /** @domName SVGFEDistantLightElement.azimuth */
@@ -1982,7 +1982,7 @@
 
 /// @domName SVGFEDropShadowElement
 class FEDropShadowElement extends SvgElement implements FilterPrimitiveStandardAttributes {
-  FEDropShadowElement.internal(): super.internal();
+  FEDropShadowElement.internal() : super.internal();
 
 
   /** @domName SVGFEDropShadowElement.dx */
@@ -2050,7 +2050,7 @@
 
 /// @domName SVGFEFloodElement
 class FEFloodElement extends SvgElement implements FilterPrimitiveStandardAttributes {
-  FEFloodElement.internal(): super.internal();
+  FEFloodElement.internal() : super.internal();
 
 
   /** @domName SVGFEFloodElement.height */
@@ -2094,7 +2094,7 @@
 
 /// @domName SVGFEFuncAElement
 class FEFuncAElement extends ComponentTransferFunctionElement {
-  FEFuncAElement.internal(): super.internal();
+  FEFuncAElement.internal() : super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -2106,7 +2106,7 @@
 
 /// @domName SVGFEFuncBElement
 class FEFuncBElement extends ComponentTransferFunctionElement {
-  FEFuncBElement.internal(): super.internal();
+  FEFuncBElement.internal() : super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -2118,7 +2118,7 @@
 
 /// @domName SVGFEFuncGElement
 class FEFuncGElement extends ComponentTransferFunctionElement {
-  FEFuncGElement.internal(): super.internal();
+  FEFuncGElement.internal() : super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -2130,7 +2130,7 @@
 
 /// @domName SVGFEFuncRElement
 class FEFuncRElement extends ComponentTransferFunctionElement {
-  FEFuncRElement.internal(): super.internal();
+  FEFuncRElement.internal() : super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -2142,7 +2142,7 @@
 
 /// @domName SVGFEGaussianBlurElement
 class FEGaussianBlurElement extends SvgElement implements FilterPrimitiveStandardAttributes {
-  FEGaussianBlurElement.internal(): super.internal();
+  FEGaussianBlurElement.internal() : super.internal();
 
 
   /** @domName SVGFEGaussianBlurElement.in1 */
@@ -2202,7 +2202,7 @@
 
 /// @domName SVGFEImageElement
 class FEImageElement extends SvgElement implements FilterPrimitiveStandardAttributes, UriReference, ExternalResourcesRequired, LangSpace {
-  FEImageElement.internal(): super.internal();
+  FEImageElement.internal() : super.internal();
 
 
   /** @domName SVGFEImageElement.preserveAspectRatio */
@@ -2274,7 +2274,7 @@
 
 /// @domName SVGFEMergeElement
 class FEMergeElement extends SvgElement implements FilterPrimitiveStandardAttributes {
-  FEMergeElement.internal(): super.internal();
+  FEMergeElement.internal() : super.internal();
 
 
   /** @domName SVGFEMergeElement.height */
@@ -2318,7 +2318,7 @@
 
 /// @domName SVGFEMergeNodeElement
 class FEMergeNodeElement extends SvgElement {
-  FEMergeNodeElement.internal(): super.internal();
+  FEMergeNodeElement.internal() : super.internal();
 
 
   /** @domName SVGFEMergeNodeElement.in1 */
@@ -2334,7 +2334,7 @@
 
 /// @domName SVGFEMorphologyElement
 class FEMorphologyElement extends SvgElement implements FilterPrimitiveStandardAttributes {
-  FEMorphologyElement.internal(): super.internal();
+  FEMorphologyElement.internal() : super.internal();
 
   static const int SVG_MORPHOLOGY_OPERATOR_DILATE = 2;
 
@@ -2404,7 +2404,7 @@
 
 /// @domName SVGFEOffsetElement
 class FEOffsetElement extends SvgElement implements FilterPrimitiveStandardAttributes {
-  FEOffsetElement.internal(): super.internal();
+  FEOffsetElement.internal() : super.internal();
 
 
   /** @domName SVGFEOffsetElement.dx */
@@ -2460,7 +2460,7 @@
 
 /// @domName SVGFEPointLightElement
 class FEPointLightElement extends SvgElement {
-  FEPointLightElement.internal(): super.internal();
+  FEPointLightElement.internal() : super.internal();
 
 
   /** @domName SVGFEPointLightElement.x */
@@ -2484,7 +2484,7 @@
 
 /// @domName SVGFESpecularLightingElement
 class FESpecularLightingElement extends SvgElement implements FilterPrimitiveStandardAttributes {
-  FESpecularLightingElement.internal(): super.internal();
+  FESpecularLightingElement.internal() : super.internal();
 
 
   /** @domName SVGFESpecularLightingElement.in1 */
@@ -2544,7 +2544,7 @@
 
 /// @domName SVGFESpotLightElement
 class FESpotLightElement extends SvgElement {
-  FESpotLightElement.internal(): super.internal();
+  FESpotLightElement.internal() : super.internal();
 
 
   /** @domName SVGFESpotLightElement.limitingConeAngle */
@@ -2588,7 +2588,7 @@
 
 /// @domName SVGFETileElement
 class FETileElement extends SvgElement implements FilterPrimitiveStandardAttributes {
-  FETileElement.internal(): super.internal();
+  FETileElement.internal() : super.internal();
 
 
   /** @domName SVGFETileElement.in1 */
@@ -2636,7 +2636,7 @@
 
 /// @domName SVGFETurbulenceElement
 class FETurbulenceElement extends SvgElement implements FilterPrimitiveStandardAttributes {
-  FETurbulenceElement.internal(): super.internal();
+  FETurbulenceElement.internal() : super.internal();
 
   static const int SVG_STITCHTYPE_NOSTITCH = 2;
 
@@ -2716,10 +2716,10 @@
 
 /// @domName SVGFilterElement
 class FilterElement extends SvgElement implements UriReference, ExternalResourcesRequired, Stylable, LangSpace {
+  FilterElement.internal() : super.internal();
 
   ///@docsEditable true
   factory FilterElement() => _SvgElementFactoryProvider.createSvgElement_tag("filter");
-  FilterElement.internal(): super.internal();
 
 
   /** @domName SVGFilterElement.filterResX */
@@ -2867,10 +2867,10 @@
 
 /// @domName SVGFontElement
 class FontElement extends SvgElement {
+  FontElement.internal() : super.internal();
 
   ///@docsEditable true
   factory FontElement() => _SvgElementFactoryProvider.createSvgElement_tag("font");
-  FontElement.internal(): super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -2882,10 +2882,10 @@
 
 /// @domName SVGFontFaceElement
 class FontFaceElement extends SvgElement {
+  FontFaceElement.internal() : super.internal();
 
   ///@docsEditable true
   factory FontFaceElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face");
-  FontFaceElement.internal(): super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -2897,10 +2897,10 @@
 
 /// @domName SVGFontFaceFormatElement
 class FontFaceFormatElement extends SvgElement {
+  FontFaceFormatElement.internal() : super.internal();
 
   ///@docsEditable true
   factory FontFaceFormatElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-format");
-  FontFaceFormatElement.internal(): super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -2912,10 +2912,10 @@
 
 /// @domName SVGFontFaceNameElement
 class FontFaceNameElement extends SvgElement {
+  FontFaceNameElement.internal() : super.internal();
 
   ///@docsEditable true
   factory FontFaceNameElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-name");
-  FontFaceNameElement.internal(): super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -2927,10 +2927,10 @@
 
 /// @domName SVGFontFaceSrcElement
 class FontFaceSrcElement extends SvgElement {
+  FontFaceSrcElement.internal() : super.internal();
 
   ///@docsEditable true
   factory FontFaceSrcElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-src");
-  FontFaceSrcElement.internal(): super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -2942,10 +2942,10 @@
 
 /// @domName SVGFontFaceUriElement
 class FontFaceUriElement extends SvgElement {
+  FontFaceUriElement.internal() : super.internal();
 
   ///@docsEditable true
   factory FontFaceUriElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-uri");
-  FontFaceUriElement.internal(): super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -2957,10 +2957,10 @@
 
 /// @domName SVGForeignObjectElement
 class ForeignObjectElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+  ForeignObjectElement.internal() : super.internal();
 
   ///@docsEditable true
   factory ForeignObjectElement() => _SvgElementFactoryProvider.createSvgElement_tag("foreignObject");
-  ForeignObjectElement.internal(): super.internal();
 
 
   /** @domName SVGForeignObjectElement.height */
@@ -3064,10 +3064,10 @@
 
 /// @domName SVGGElement
 class GElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+  GElement.internal() : super.internal();
 
   ///@docsEditable true
   factory GElement() => _SvgElementFactoryProvider.createSvgElement_tag("g");
-  GElement.internal(): super.internal();
 
 
   /** @domName SVGGElement.externalResourcesRequired */
@@ -3155,10 +3155,10 @@
 
 /// @domName SVGGlyphElement
 class GlyphElement extends SvgElement {
+  GlyphElement.internal() : super.internal();
 
   ///@docsEditable true
   factory GlyphElement() => _SvgElementFactoryProvider.createSvgElement_tag("glyph");
-  GlyphElement.internal(): super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -3170,7 +3170,7 @@
 
 /// @domName SVGGlyphRefElement
 class GlyphRefElement extends SvgElement implements UriReference, Stylable {
-  GlyphRefElement.internal(): super.internal();
+  GlyphRefElement.internal() : super.internal();
 
 
   /** @domName SVGGlyphRefElement.dx */
@@ -3246,7 +3246,7 @@
 
 /// @domName SVGGradientElement
 class GradientElement extends SvgElement implements UriReference, ExternalResourcesRequired, Stylable {
-  GradientElement.internal(): super.internal();
+  GradientElement.internal() : super.internal();
 
   static const int SVG_SPREADMETHOD_PAD = 1;
 
@@ -3298,10 +3298,10 @@
 
 /// @domName SVGHKernElement
 class HKernElement extends SvgElement {
+  HKernElement.internal() : super.internal();
 
   ///@docsEditable true
   factory HKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("hkern");
-  HKernElement.internal(): super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -3313,10 +3313,10 @@
 
 /// @domName SVGImageElement
 class ImageElement extends SvgElement implements Transformable, Tests, UriReference, Stylable, ExternalResourcesRequired, LangSpace {
+  ImageElement.internal() : super.internal();
 
   ///@docsEditable true
   factory ImageElement() => _SvgElementFactoryProvider.createSvgElement_tag("image");
-  ImageElement.internal(): super.internal();
 
 
   /** @domName SVGImageElement.height */
@@ -3670,10 +3670,10 @@
 
 /// @domName SVGLineElement
 class LineElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+  LineElement.internal() : super.internal();
 
   ///@docsEditable true
   factory LineElement() => _SvgElementFactoryProvider.createSvgElement_tag("line");
-  LineElement.internal(): super.internal();
 
 
   /** @domName SVGLineElement.x1 */
@@ -3777,10 +3777,10 @@
 
 /// @domName SVGLinearGradientElement
 class LinearGradientElement extends GradientElement {
+  LinearGradientElement.internal() : super.internal();
 
   ///@docsEditable true
   factory LinearGradientElement() => _SvgElementFactoryProvider.createSvgElement_tag("linearGradient");
-  LinearGradientElement.internal(): super.internal();
 
 
   /** @domName SVGLinearGradientElement.x1 */
@@ -3844,10 +3844,10 @@
 
 /// @domName SVGMPathElement
 class MPathElement extends SvgElement implements UriReference, ExternalResourcesRequired {
+  MPathElement.internal() : super.internal();
 
   ///@docsEditable true
   factory MPathElement() => _SvgElementFactoryProvider.createSvgElement_tag("mpath");
-  MPathElement.internal(): super.internal();
 
 
   /** @domName SVGMPathElement.externalResourcesRequired */
@@ -3867,10 +3867,10 @@
 
 /// @domName SVGMarkerElement
 class MarkerElement extends SvgElement implements FitToViewBox, ExternalResourcesRequired, Stylable, LangSpace {
+  MarkerElement.internal() : super.internal();
 
   ///@docsEditable true
   factory MarkerElement() => _SvgElementFactoryProvider.createSvgElement_tag("marker");
-  MarkerElement.internal(): super.internal();
 
   static const int SVG_MARKERUNITS_STROKEWIDTH = 2;
 
@@ -3970,10 +3970,10 @@
 
 /// @domName SVGMaskElement
 class MaskElement extends SvgElement implements Tests, Stylable, ExternalResourcesRequired, LangSpace {
+  MaskElement.internal() : super.internal();
 
   ///@docsEditable true
   factory MaskElement() => _SvgElementFactoryProvider.createSvgElement_tag("mask");
-  MaskElement.internal(): super.internal();
 
 
   /** @domName SVGMaskElement.height */
@@ -4161,7 +4161,7 @@
 
 /// @domName SVGMetadataElement
 class MetadataElement extends SvgElement {
-  MetadataElement.internal(): super.internal();
+  MetadataElement.internal() : super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -4173,7 +4173,7 @@
 
 /// @domName SVGMissingGlyphElement
 class MissingGlyphElement extends SvgElement {
-  MissingGlyphElement.internal(): super.internal();
+  MissingGlyphElement.internal() : super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -4349,7 +4349,7 @@
 
 /// @domName SVGPaint
 class Paint extends Color {
-  Paint.internal(): super.internal();
+  Paint.internal() : super.internal();
 
   static const int SVG_PAINTTYPE_CURRENTCOLOR = 102;
 
@@ -4397,10 +4397,10 @@
 
 /// @domName SVGPathElement
 class PathElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+  PathElement.internal() : super.internal();
 
   ///@docsEditable true
   factory PathElement() => _SvgElementFactoryProvider.createSvgElement_tag("path");
-  PathElement.internal(): super.internal();
 
 
   /** @domName SVGPathElement.animatedNormalizedPathSegList */
@@ -4656,7 +4656,7 @@
 
 /// @domName SVGPathSegArcAbs
 class PathSegArcAbs extends PathSeg {
-  PathSegArcAbs.internal(): super.internal();
+  PathSegArcAbs.internal() : super.internal();
 
 
   /** @domName SVGPathSegArcAbs.angle */
@@ -4724,7 +4724,7 @@
 
 /// @domName SVGPathSegArcRel
 class PathSegArcRel extends PathSeg {
-  PathSegArcRel.internal(): super.internal();
+  PathSegArcRel.internal() : super.internal();
 
 
   /** @domName SVGPathSegArcRel.angle */
@@ -4792,7 +4792,7 @@
 
 /// @domName SVGPathSegClosePath
 class PathSegClosePath extends PathSeg {
-  PathSegClosePath.internal(): super.internal();
+  PathSegClosePath.internal() : super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -4804,7 +4804,7 @@
 
 /// @domName SVGPathSegCurvetoCubicAbs
 class PathSegCurvetoCubicAbs extends PathSeg {
-  PathSegCurvetoCubicAbs.internal(): super.internal();
+  PathSegCurvetoCubicAbs.internal() : super.internal();
 
 
   /** @domName SVGPathSegCurvetoCubicAbs.x */
@@ -4864,7 +4864,7 @@
 
 /// @domName SVGPathSegCurvetoCubicRel
 class PathSegCurvetoCubicRel extends PathSeg {
-  PathSegCurvetoCubicRel.internal(): super.internal();
+  PathSegCurvetoCubicRel.internal() : super.internal();
 
 
   /** @domName SVGPathSegCurvetoCubicRel.x */
@@ -4924,7 +4924,7 @@
 
 /// @domName SVGPathSegCurvetoCubicSmoothAbs
 class PathSegCurvetoCubicSmoothAbs extends PathSeg {
-  PathSegCurvetoCubicSmoothAbs.internal(): super.internal();
+  PathSegCurvetoCubicSmoothAbs.internal() : super.internal();
 
 
   /** @domName SVGPathSegCurvetoCubicSmoothAbs.x */
@@ -4968,7 +4968,7 @@
 
 /// @domName SVGPathSegCurvetoCubicSmoothRel
 class PathSegCurvetoCubicSmoothRel extends PathSeg {
-  PathSegCurvetoCubicSmoothRel.internal(): super.internal();
+  PathSegCurvetoCubicSmoothRel.internal() : super.internal();
 
 
   /** @domName SVGPathSegCurvetoCubicSmoothRel.x */
@@ -5012,7 +5012,7 @@
 
 /// @domName SVGPathSegCurvetoQuadraticAbs
 class PathSegCurvetoQuadraticAbs extends PathSeg {
-  PathSegCurvetoQuadraticAbs.internal(): super.internal();
+  PathSegCurvetoQuadraticAbs.internal() : super.internal();
 
 
   /** @domName SVGPathSegCurvetoQuadraticAbs.x */
@@ -5056,7 +5056,7 @@
 
 /// @domName SVGPathSegCurvetoQuadraticRel
 class PathSegCurvetoQuadraticRel extends PathSeg {
-  PathSegCurvetoQuadraticRel.internal(): super.internal();
+  PathSegCurvetoQuadraticRel.internal() : super.internal();
 
 
   /** @domName SVGPathSegCurvetoQuadraticRel.x */
@@ -5100,7 +5100,7 @@
 
 /// @domName SVGPathSegCurvetoQuadraticSmoothAbs
 class PathSegCurvetoQuadraticSmoothAbs extends PathSeg {
-  PathSegCurvetoQuadraticSmoothAbs.internal(): super.internal();
+  PathSegCurvetoQuadraticSmoothAbs.internal() : super.internal();
 
 
   /** @domName SVGPathSegCurvetoQuadraticSmoothAbs.x */
@@ -5128,7 +5128,7 @@
 
 /// @domName SVGPathSegCurvetoQuadraticSmoothRel
 class PathSegCurvetoQuadraticSmoothRel extends PathSeg {
-  PathSegCurvetoQuadraticSmoothRel.internal(): super.internal();
+  PathSegCurvetoQuadraticSmoothRel.internal() : super.internal();
 
 
   /** @domName SVGPathSegCurvetoQuadraticSmoothRel.x */
@@ -5156,7 +5156,7 @@
 
 /// @domName SVGPathSegLinetoAbs
 class PathSegLinetoAbs extends PathSeg {
-  PathSegLinetoAbs.internal(): super.internal();
+  PathSegLinetoAbs.internal() : super.internal();
 
 
   /** @domName SVGPathSegLinetoAbs.x */
@@ -5184,7 +5184,7 @@
 
 /// @domName SVGPathSegLinetoHorizontalAbs
 class PathSegLinetoHorizontalAbs extends PathSeg {
-  PathSegLinetoHorizontalAbs.internal(): super.internal();
+  PathSegLinetoHorizontalAbs.internal() : super.internal();
 
 
   /** @domName SVGPathSegLinetoHorizontalAbs.x */
@@ -5204,7 +5204,7 @@
 
 /// @domName SVGPathSegLinetoHorizontalRel
 class PathSegLinetoHorizontalRel extends PathSeg {
-  PathSegLinetoHorizontalRel.internal(): super.internal();
+  PathSegLinetoHorizontalRel.internal() : super.internal();
 
 
   /** @domName SVGPathSegLinetoHorizontalRel.x */
@@ -5224,7 +5224,7 @@
 
 /// @domName SVGPathSegLinetoRel
 class PathSegLinetoRel extends PathSeg {
-  PathSegLinetoRel.internal(): super.internal();
+  PathSegLinetoRel.internal() : super.internal();
 
 
   /** @domName SVGPathSegLinetoRel.x */
@@ -5252,7 +5252,7 @@
 
 /// @domName SVGPathSegLinetoVerticalAbs
 class PathSegLinetoVerticalAbs extends PathSeg {
-  PathSegLinetoVerticalAbs.internal(): super.internal();
+  PathSegLinetoVerticalAbs.internal() : super.internal();
 
 
   /** @domName SVGPathSegLinetoVerticalAbs.y */
@@ -5272,7 +5272,7 @@
 
 /// @domName SVGPathSegLinetoVerticalRel
 class PathSegLinetoVerticalRel extends PathSeg {
-  PathSegLinetoVerticalRel.internal(): super.internal();
+  PathSegLinetoVerticalRel.internal() : super.internal();
 
 
   /** @domName SVGPathSegLinetoVerticalRel.y */
@@ -5436,7 +5436,7 @@
 
 /// @domName SVGPathSegMovetoAbs
 class PathSegMovetoAbs extends PathSeg {
-  PathSegMovetoAbs.internal(): super.internal();
+  PathSegMovetoAbs.internal() : super.internal();
 
 
   /** @domName SVGPathSegMovetoAbs.x */
@@ -5464,7 +5464,7 @@
 
 /// @domName SVGPathSegMovetoRel
 class PathSegMovetoRel extends PathSeg {
-  PathSegMovetoRel.internal(): super.internal();
+  PathSegMovetoRel.internal() : super.internal();
 
 
   /** @domName SVGPathSegMovetoRel.x */
@@ -5492,10 +5492,10 @@
 
 /// @domName SVGPatternElement
 class PatternElement extends SvgElement implements FitToViewBox, Tests, UriReference, Stylable, ExternalResourcesRequired, LangSpace {
+  PatternElement.internal() : super.internal();
 
   ///@docsEditable true
   factory PatternElement() => _SvgElementFactoryProvider.createSvgElement_tag("pattern");
-  PatternElement.internal(): super.internal();
 
 
   /** @domName SVGPatternElement.height */
@@ -5671,10 +5671,10 @@
 
 /// @domName SVGPolygonElement
 class PolygonElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+  PolygonElement.internal() : super.internal();
 
   ///@docsEditable true
   factory PolygonElement() => _SvgElementFactoryProvider.createSvgElement_tag("polygon");
-  PolygonElement.internal(): super.internal();
 
 
   /** @domName SVGPolygonElement.animatedPoints */
@@ -5770,10 +5770,10 @@
 
 /// @domName SVGPolylineElement
 class PolylineElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+  PolylineElement.internal() : super.internal();
 
   ///@docsEditable true
   factory PolylineElement() => _SvgElementFactoryProvider.createSvgElement_tag("polyline");
-  PolylineElement.internal(): super.internal();
 
 
   /** @domName SVGPolylineElement.animatedPoints */
@@ -5925,10 +5925,10 @@
 
 /// @domName SVGRadialGradientElement
 class RadialGradientElement extends GradientElement {
+  RadialGradientElement.internal() : super.internal();
 
   ///@docsEditable true
   factory RadialGradientElement() => _SvgElementFactoryProvider.createSvgElement_tag("radialGradient");
-  RadialGradientElement.internal(): super.internal();
 
 
   /** @domName SVGRadialGradientElement.cx */
@@ -6008,10 +6008,10 @@
 
 /// @domName SVGRectElement
 class RectElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+  RectElement.internal() : super.internal();
 
   ///@docsEditable true
   factory RectElement() => _SvgElementFactoryProvider.createSvgElement_tag("rect");
-  RectElement.internal(): super.internal();
 
 
   /** @domName SVGRectElement.height */
@@ -6147,10 +6147,10 @@
 
 /// @domName SVGScriptElement
 class ScriptElement extends SvgElement implements UriReference, ExternalResourcesRequired {
+  ScriptElement.internal() : super.internal();
 
   ///@docsEditable true
   factory ScriptElement() => _SvgElementFactoryProvider.createSvgElement_tag("script");
-  ScriptElement.internal(): super.internal();
 
 
   /** @domName SVGScriptElement.type */
@@ -6178,10 +6178,10 @@
 
 /// @domName SVGSetElement
 class SetElement extends AnimationElement {
+  SetElement.internal() : super.internal();
 
   ///@docsEditable true
   factory SetElement() => _SvgElementFactoryProvider.createSvgElement_tag("set");
-  SetElement.internal(): super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6193,10 +6193,10 @@
 
 /// @domName SVGStopElement
 class StopElement extends SvgElement implements Stylable {
+  StopElement.internal() : super.internal();
 
   ///@docsEditable true
   factory StopElement() => _SvgElementFactoryProvider.createSvgElement_tag("stop");
-  StopElement.internal(): super.internal();
 
 
   /** @domName SVGStopElement.offset */
@@ -6392,10 +6392,10 @@
 
 /// @domName SVGStyleElement
 class StyleElement extends SvgElement implements LangSpace {
+  StyleElement.internal() : super.internal();
 
   ///@docsEditable true
   factory StyleElement() => _SvgElementFactoryProvider.createSvgElement_tag("style");
-  StyleElement.internal(): super.internal();
 
 
   /** @domName SVGStyleElement.disabled */
@@ -6455,7 +6455,7 @@
 
 /// @domName SVGDocument
 class SvgDocument extends Document {
-  SvgDocument.internal(): super.internal();
+  SvgDocument.internal() : super.internal();
 
 
   /** @domName SVGDocument.rootElement */
@@ -6579,7 +6579,7 @@
     throw new UnsupportedError("Cannot invoke click SVG.");
   }
 
-  SvgElement.internal(): super.internal();
+  SvgElement.internal() : super.internal();
 
 
   /** @domName SVGElement.id */
@@ -6649,7 +6649,7 @@
 class SvgSvgElement extends SvgElement implements FitToViewBox, Tests, Stylable, Locatable, ExternalResourcesRequired, ZoomAndPan, LangSpace {
   factory SvgSvgElement() => _SvgSvgElementFactoryProvider.createSvgSvgElement();
 
-  SvgSvgElement.internal(): super.internal();
+  SvgSvgElement.internal() : super.internal();
 
 
   /** @domName SVGSVGElement.contentScriptType */
@@ -6913,10 +6913,10 @@
 
 /// @domName SVGSwitchElement
 class SwitchElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+  SwitchElement.internal() : super.internal();
 
   ///@docsEditable true
   factory SwitchElement() => _SvgElementFactoryProvider.createSvgElement_tag("switch");
-  SwitchElement.internal(): super.internal();
 
 
   /** @domName SVGSwitchElement.externalResourcesRequired */
@@ -7004,10 +7004,10 @@
 
 /// @domName SVGSymbolElement
 class SymbolElement extends SvgElement implements FitToViewBox, ExternalResourcesRequired, Stylable, LangSpace {
+  SymbolElement.internal() : super.internal();
 
   ///@docsEditable true
   factory SymbolElement() => _SvgElementFactoryProvider.createSvgElement_tag("symbol");
-  SymbolElement.internal(): super.internal();
 
 
   /** @domName SVGSymbolElement.externalResourcesRequired */
@@ -7059,10 +7059,10 @@
 
 /// @domName SVGTRefElement
 class TRefElement extends TextPositioningElement implements UriReference {
+  TRefElement.internal() : super.internal();
 
   ///@docsEditable true
   factory TRefElement() => _SvgElementFactoryProvider.createSvgElement_tag("tref");
-  TRefElement.internal(): super.internal();
 
 
   /** @domName SVGTRefElement.href */
@@ -7078,10 +7078,10 @@
 
 /// @domName SVGTSpanElement
 class TSpanElement extends TextPositioningElement {
+  TSpanElement.internal() : super.internal();
 
   ///@docsEditable true
   factory TSpanElement() => _SvgElementFactoryProvider.createSvgElement_tag("tspan");
-  TSpanElement.internal(): super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -7121,7 +7121,7 @@
 
 /// @domName SVGTextContentElement
 class TextContentElement extends SvgElement implements Tests, Stylable, ExternalResourcesRequired, LangSpace {
-  TextContentElement.internal(): super.internal();
+  TextContentElement.internal() : super.internal();
 
   static const int LENGTHADJUST_SPACING = 1;
 
@@ -7231,10 +7231,10 @@
 
 /// @domName SVGTextElement
 class TextElement extends TextPositioningElement implements Transformable {
+  TextElement.internal() : super.internal();
 
   ///@docsEditable true
   factory TextElement() => _SvgElementFactoryProvider.createSvgElement_tag("text");
-  TextElement.internal(): super.internal();
 
 
   /** @domName SVGTextElement.farthestViewportElement */
@@ -7274,7 +7274,7 @@
 
 /// @domName SVGTextPathElement
 class TextPathElement extends TextContentElement implements UriReference {
-  TextPathElement.internal(): super.internal();
+  TextPathElement.internal() : super.internal();
 
   static const int TEXTPATH_METHODTYPE_ALIGN = 1;
 
@@ -7314,7 +7314,7 @@
 
 /// @domName SVGTextPositioningElement
 class TextPositioningElement extends TextContentElement {
-  TextPositioningElement.internal(): super.internal();
+  TextPositioningElement.internal() : super.internal();
 
 
   /** @domName SVGTextPositioningElement.dx */
@@ -7346,10 +7346,10 @@
 
 /// @domName SVGTitleElement
 class TitleElement extends SvgElement implements Stylable, LangSpace {
+  TitleElement.internal() : super.internal();
 
   ///@docsEditable true
   factory TitleElement() => _SvgElementFactoryProvider.createSvgElement_tag("title");
-  TitleElement.internal(): super.internal();
 
 
   /** @domName SVGTitleElement.xmllang */
@@ -7677,10 +7677,10 @@
 
 /// @domName SVGUseElement
 class UseElement extends SvgElement implements Transformable, Tests, UriReference, Stylable, ExternalResourcesRequired, LangSpace {
+  UseElement.internal() : super.internal();
 
   ///@docsEditable true
   factory UseElement() => _SvgElementFactoryProvider.createSvgElement_tag("use");
-  UseElement.internal(): super.internal();
 
 
   /** @domName SVGUseElement.animatedInstanceRoot */
@@ -7796,10 +7796,10 @@
 
 /// @domName SVGVKernElement
 class VKernElement extends SvgElement {
+  VKernElement.internal() : super.internal();
 
   ///@docsEditable true
   factory VKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("vkern");
-  VKernElement.internal(): super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -7811,10 +7811,10 @@
 
 /// @domName SVGViewElement
 class ViewElement extends SvgElement implements FitToViewBox, ExternalResourcesRequired, ZoomAndPan {
+  ViewElement.internal() : super.internal();
 
   ///@docsEditable true
   factory ViewElement() => _SvgElementFactoryProvider.createSvgElement_tag("view");
-  ViewElement.internal(): super.internal();
 
 
   /** @domName SVGViewElement.viewTarget */
@@ -7928,7 +7928,7 @@
 
 /// @domName SVGZoomEvent
 class ZoomEvent extends UIEvent {
-  ZoomEvent.internal(): super.internal();
+  ZoomEvent.internal() : super.internal();
 
 
   /** @domName SVGZoomEvent.newScale */
diff --git a/sdk/lib/uri/encode_decode.dart b/sdk/lib/uri/encode_decode.dart
index 6338518..e13d284 100644
--- a/sdk/lib/uri/encode_decode.dart
+++ b/sdk/lib/uri/encode_decode.dart
@@ -1,7 +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.
 
+part of dart.uri;
+
 /**
  * Javascript-like URI encode/decode functions.
  * The documentation here borrows heavily from the original Javascript
@@ -19,9 +21,26 @@
  * It returns the escaped URI.
  */
 String encodeUri(String uri) {
-  return _uriEncode(
-    "-_.!~*'()#;,/?:@&=+\$0123456789"
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", uri);
+  // Bit vector of 128 bits where each bit indicate whether a
+  // character code on the 0-127 needs to be escaped or not.
+  const canonicalTable = const [
+                //             LSB            MSB
+                //              |              |
+      0x0000,   // 0x00 - 0x0f  0000000000000000
+      0x0000,   // 0x10 - 0x1f  0000000000000000
+                //               ! #$ &'()*+,-./
+      0xf7da,   // 0x20 - 0x2f  0101101111101111
+                //              0123456789:; = ?
+      0xafff,   // 0x30 - 0x3f  1111111111110101
+                //              @ABCDEFGHIJKLMNO
+      0xffff,   // 0x40 - 0x4f  1111111111111111
+                //              PQRSTUVWXYZ    _
+      0x87ff,   // 0x50 - 0x5f  1111111111100001
+                //               abcdefghijklmno
+      0xfffe,   // 0x60 - 0x6f  0111111111111111
+                //              pqrstuvwxyz   ~
+      0x47ff];  // 0x70 - 0x7f  1111111111100010
+  return _uriEncode(canonicalTable, uri);
 }
 
 /**
@@ -53,9 +72,26 @@
  * It returns the escaped string.
  */
 String encodeUriComponent(String component) {
-  return _uriEncode(
-    "-_.!~*'()0123456789"
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", component);
+  // Bit vector of 128 bits where each bit indicate whether a
+  // character code on the 0-127 needs to be escaped or not.
+  const canonicalTable = const [
+                //             LSB            MSB
+                //              |              |
+      0x0000,   // 0x00 - 0x0f  0000000000000000
+      0x0000,   // 0x10 - 0x1f  0000000000000000
+                //               !     '()*  -.
+      0x6782,   // 0x20 - 0x2f  0100000111100110
+                //              0123456789
+      0x03ff,   // 0x30 - 0x3f  1111111111000000
+                //              @ABCDEFGHIJKLMNO
+      0xfffe,   // 0x40 - 0x4f  0111111111111111
+                //              PQRSTUVWXYZ    _
+      0x87ff,   // 0x50 - 0x5f  1111111111100001
+                //               abcdefghijklmno
+      0xfffe,   // 0x60 - 0x6f  0111111111111111
+                //              pqrstuvwxyz   ~
+      0x47ff];  // 0x70 - 0x7f  1111111111100010
+  return _uriEncode(canonicalTable, component);
 }
 
 /**
@@ -71,17 +107,19 @@
 /**
  * This is the internal implementation of JavaScript's encodeURI function.
  * It encodes all characters in the string [text] except for those
- * that appear in [canonical], and returns the escaped string.
+ * that appear in [canonicalTable], and returns the escaped string.
  */
-String _uriEncode(String canonical, String text) {
+String _uriEncode(List<int> canonicalTable, String text) {
   final String hex = '0123456789ABCDEF';
-  var byteToHex = (int v) => '%${hex[v >> 4]}${hex[v&0xf]}';
+  var byteToHex = (int v) => '%${hex[v >> 4]}${hex[v & 0x0f]}';
   StringBuffer result = new StringBuffer();
   for (int i = 0; i < text.length; i++) {
-    if (canonical.indexOf(text[i]) >= 0) {
+    int ch = text.charCodeAt(i);
+    if (ch < 128 && ((canonicalTable[ch >> 4] & (1 << (ch & 0x0f))) != 0)) {
       result.add(text[i]);
+    } else if (text[i] == " ") {
+      result.add("+");
     } else {
-      int ch = text.charCodeAt(i);
       if (ch >= 0xD800 && ch < 0xDC00) {
         // Low surrogate. We expect a next char high surrogate.
         ++i;
@@ -107,13 +145,22 @@
  */
 
 int _hexCharPairToByte(String s, int pos) {
-  // An alternative to calling [int.parse] twice would be to take a
-  // two character substring and call it once, but that may be less
-  // efficient.
-  // TODO(lrn): I fail to see how that could possibly be slower than this.
-  int d1 = int.parse("0x${s[pos]}");
-  int d2 = int.parse("0x${s[pos+1]}");
-  return d1 * 16 + d2;
+  int byte = 0;
+  for (int i = 0; i < 2; i++) {
+    var charCode = s.charCodeAt(pos + i);
+    if (0x30 <= charCode && charCode <= 0x39) {
+      byte = byte * 16 + charCode - 0x30;
+    } else {
+      // Check ranges A-F (0x41-0x46) and a-f (0x61-0x66).
+      charCode |= 0x20;
+      if (0x61 <= charCode && charCode <= 0x66) {
+        byte = byte * 16 + charCode - 0x57;
+      } else {
+        throw new ArgumentError("Invalid URL encoding");
+      }
+    }
+  }
+  return byte;
 }
 
 /**
@@ -126,7 +173,11 @@
   for (int i = 0; i < text.length;) {
     String ch = text[i];
     if (ch != '%') {
-      result.add(ch);
+      if (ch == '+') {
+        result.add(" ");
+      } else {
+        result.add(ch);
+      }
       i++;
     } else {
       codepoints.clear();
diff --git a/sdk/lib/uri/helpers.dart b/sdk/lib/uri/helpers.dart
index bcc1e56..d17810f 100644
--- a/sdk/lib/uri/helpers.dart
+++ b/sdk/lib/uri/helpers.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.uri;
+
 String merge(String base, String reference) {
   if (base == "") return "/$reference";
   return "${base.substring(0, base.lastIndexOf("/") + 1)}$reference";
diff --git a/sdk/lib/uri/uri.dart b/sdk/lib/uri/uri.dart
index 9f1d73b..4933d9d 100644
--- a/sdk/lib/uri/uri.dart
+++ b/sdk/lib/uri/uri.dart
@@ -2,13 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#library('dart:uri');
+library dart.uri;
 
-#import('dart:math');
-#import('dart:utf');
+import 'dart:math';
+import 'dart:utf';
 
-#source('encode_decode.dart');
-#source('helpers.dart');
+part 'encode_decode.dart';
+part 'helpers.dart';
 
 /**
  * A parsed URI, inspired by Closure's [URI][] class. Implements [RFC-3986][].
diff --git a/sdk/lib/utf/utf.dart b/sdk/lib/utf/utf.dart
index a5f2a0c..cc3c573 100644
--- a/sdk/lib/utf/utf.dart
+++ b/sdk/lib/utf/utf.dart
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#library("dart:utf");
-#source("utf_core.dart");
-#source("utf8.dart");
-#source("utf16.dart");
-#source("utf32.dart");
+library dart.utf;
+part "utf_core.dart";
+part "utf8.dart";
+part "utf16.dart";
+part "utf32.dart";
diff --git a/sdk/lib/utf/utf16.dart b/sdk/lib/utf/utf16.dart
index e37c603..7c67a30 100644
--- a/sdk/lib/utf/utf16.dart
+++ b/sdk/lib/utf/utf16.dart
@@ -2,6 +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.utf;
 
 /**
  * Decodes the UTF-16 bytes as an iterable. Thus, the consumer can only convert
diff --git a/sdk/lib/utf/utf32.dart b/sdk/lib/utf/utf32.dart
index 8472b52..e4a13fe 100644
--- a/sdk/lib/utf/utf32.dart
+++ b/sdk/lib/utf/utf32.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.utf;
+
 /**
  * Decodes the UTF-32 bytes as an iterable. Thus, the consumer can only convert
  * as much of the input as needed. Determines the byte order from the BOM,
diff --git a/sdk/lib/utf/utf8.dart b/sdk/lib/utf/utf8.dart
index 48933af..fff010b 100644
--- a/sdk/lib/utf/utf8.dart
+++ b/sdk/lib/utf/utf8.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.utf;
+
 const int _UTF8_ONE_BYTE_MAX = 0x7f;
 const int _UTF8_TWO_BYTE_MAX = 0x7ff;
 const int _UTF8_THREE_BYTE_MAX = 0xffff;
diff --git a/sdk/lib/utf/utf_core.dart b/sdk/lib/utf/utf_core.dart
index 8b1751d..cdc1ddf 100644
--- a/sdk/lib/utf/utf_core.dart
+++ b/sdk/lib/utf/utf_core.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.utf;
+
 // TODO(jmesserly): would be nice to have this on String (dartbug.com/6501).
 /**
  * Provide a list of Unicode codepoints for a given string.
diff --git a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
index b58d552..b45a5fa 100644
--- a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
+++ b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
@@ -148,9 +148,11 @@
 
 /// @domName AudioContext
 class AudioContext extends EventTarget native "*AudioContext" {
-  factory AudioContext() => JS('AudioContext',
-      'new (window.AudioContext || window.webkitAudioContext)()');
 
+  ///@docsEditable true
+  factory AudioContext() => AudioContext._create();
+  static AudioContext _create() => JS('AudioContext',
+      'new (window.AudioContext || window.webkitAudioContext)()');
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   AudioContextEvents get on =>
@@ -201,6 +203,9 @@
   /// @domName AudioContext.createMediaElementSource; @docsEditable true
   MediaElementAudioSourceNode createMediaElementSource(MediaElement mediaElement) native;
 
+  /// @domName AudioContext.createMediaStreamDestination; @docsEditable true
+  MediaStreamAudioDestinationNode createMediaStreamDestination() native;
+
   /// @domName AudioContext.createMediaStreamSource; @docsEditable true
   MediaStreamAudioSourceNode createMediaStreamSource(MediaStream mediaStream) native;
 
@@ -413,6 +418,9 @@
   /// @domName BiquadFilterNode.Q; @docsEditable true
   final AudioParam Q;
 
+  /// @domName BiquadFilterNode.detune; @docsEditable true
+  final AudioParam detune;
+
   /// @domName BiquadFilterNode.frequency; @docsEditable true
   final AudioParam frequency;
 
@@ -519,6 +527,17 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
+/// @domName MediaStreamAudioDestinationNode; @docsEditable true
+class MediaStreamAudioDestinationNode extends AudioSourceNode native "*MediaStreamAudioDestinationNode" {
+
+  /// @domName MediaStreamAudioDestinationNode.stream; @docsEditable true
+  final MediaStream stream;
+}
+// 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.
+
+
 /// @domName MediaStreamAudioSourceNode; @docsEditable true
 class MediaStreamAudioSourceNode extends AudioSourceNode native "*MediaStreamAudioSourceNode" {
 
@@ -541,6 +560,18 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
+/// @domName OfflineAudioContext; @docsEditable true
+class OfflineAudioContext extends AudioContext implements EventTarget native "*OfflineAudioContext" {
+
+  ///@docsEditable true
+  factory OfflineAudioContext(int numberOfChannels, int numberOfFrames, num sampleRate) => OfflineAudioContext._create(numberOfChannels, numberOfFrames, sampleRate);
+  static OfflineAudioContext _create(int numberOfChannels, int numberOfFrames, num sampleRate) => JS('OfflineAudioContext', 'new OfflineAudioContext(#,#,#)', numberOfChannels, numberOfFrames, sampleRate);
+}
+// 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.
+
+
 /// @domName OscillatorNode; @docsEditable true
 class OscillatorNode extends AudioSourceNode native "*OscillatorNode" {
 
@@ -603,9 +634,6 @@
 
   static const int SOUNDFIELD = 2;
 
-  /// @domName PannerNode.coneGain; @docsEditable true
-  final AudioGain coneGain;
-
   /// @domName PannerNode.coneInnerAngle; @docsEditable true
   num coneInnerAngle;
 
@@ -615,9 +643,6 @@
   /// @domName PannerNode.coneOuterGain; @docsEditable true
   num coneOuterGain;
 
-  /// @domName PannerNode.distanceGain; @docsEditable true
-  final AudioGain distanceGain;
-
   /// @domName PannerNode.distanceModel; @docsEditable true
   int distanceModel;
 
@@ -650,22 +675,9 @@
 /// @domName ScriptProcessorNode; @docsEditable true
 class ScriptProcessorNode extends AudioNode implements EventTarget native "*ScriptProcessorNode" {
 
-  /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
-  ScriptProcessorNodeEvents get on =>
-    new ScriptProcessorNodeEvents(this);
-
   /// @domName ScriptProcessorNode.bufferSize; @docsEditable true
   final int bufferSize;
 }
-
-/// @docsEditable true
-class ScriptProcessorNodeEvents extends Events {
-  /// @docsEditable true
-  ScriptProcessorNodeEvents(EventTarget _ptr) : super(_ptr);
-
-  /// @docsEditable true
-  EventListenerList get audioProcess => this['audioprocess'];
-}
 // 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/sdk/lib/web_audio/dartium/web_audio_dartium.dart b/sdk/lib/web_audio/dartium/web_audio_dartium.dart
index d0b9b9e..3a591f7 100644
--- a/sdk/lib/web_audio/dartium/web_audio_dartium.dart
+++ b/sdk/lib/web_audio/dartium/web_audio_dartium.dart
@@ -17,7 +17,7 @@
 
 /// @domName AnalyserNode
 class AnalyserNode extends AudioNode {
-  AnalyserNode.internal(): super.internal();
+  AnalyserNode.internal() : super.internal();
 
 
   /** @domName AnalyserNode.fftSize */
@@ -125,7 +125,7 @@
 
 /// @domName AudioBufferSourceNode
 class AudioBufferSourceNode extends AudioSourceNode {
-  AudioBufferSourceNode.internal(): super.internal();
+  AudioBufferSourceNode.internal() : super.internal();
 
   static const int FINISHED_STATE = 3;
 
@@ -184,8 +184,12 @@
       _start_1(when);
       return;
     }
+    if ((when is num || when == null) && (grainOffset is num || grainOffset == null) && !?grainDuration) {
+      _start_2(when, grainOffset);
+      return;
+    }
     if ((when is num || when == null) && (grainOffset is num || grainOffset == null) && (grainDuration is num || grainDuration == null)) {
-      _start_2(when, grainOffset, grainDuration);
+      _start_3(when, grainOffset, grainDuration);
       return;
     }
     throw "Incorrect number or type of arguments";
@@ -197,7 +201,11 @@
 
 
   /** @domName AudioBufferSourceNode.start_2 */
-  void _start_2(when, grainOffset, grainDuration) native "AudioBufferSourceNode_start_2_Callback";
+  void _start_2(when, grainOffset) native "AudioBufferSourceNode_start_2_Callback";
+
+
+  /** @domName AudioBufferSourceNode.start_3 */
+  void _start_3(when, grainOffset, grainDuration) native "AudioBufferSourceNode_start_3_Callback";
 
 
   /** @domName AudioBufferSourceNode.stop */
@@ -211,14 +219,11 @@
 
 /// @domName AudioContext
 class AudioContext extends EventTarget {
-  factory AudioContext() => _createAudioContext();
+  AudioContext.internal() : super.internal();
 
-  static _createAudioContext([int numberOfChannels,
-                              int numberOfFrames,
-                              int sampleRate])
-      native "AudioContext_constructor_Callback";
-
-  AudioContext.internal(): super.internal();
+  ///@docsEditable true
+  factory AudioContext() => AudioContext._create();
+  static AudioContext _create() native "AudioContext_constructor_Callback";
 
   /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
   AudioContextEvents get on =>
@@ -336,6 +341,10 @@
   MediaElementAudioSourceNode createMediaElementSource(MediaElement mediaElement) native "AudioContext_createMediaElementSource_Callback";
 
 
+  /** @domName AudioContext.createMediaStreamDestination */
+  MediaStreamAudioDestinationNode createMediaStreamDestination() native "AudioContext_createMediaStreamDestination_Callback";
+
+
   /** @domName AudioContext.createMediaStreamSource */
   MediaStreamAudioSourceNode createMediaStreamSource(MediaStream mediaStream) native "AudioContext_createMediaStreamSource_Callback";
 
@@ -404,7 +413,7 @@
 
 /// @domName AudioDestinationNode
 class AudioDestinationNode extends AudioNode {
-  AudioDestinationNode.internal(): super.internal();
+  AudioDestinationNode.internal() : super.internal();
 
 
   /** @domName AudioDestinationNode.numberOfChannels */
@@ -420,7 +429,7 @@
 
 /// @domName AudioGain
 class AudioGain extends AudioParam {
-  AudioGain.internal(): super.internal();
+  AudioGain.internal() : super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -584,7 +593,7 @@
 
 /// @domName AudioProcessingEvent
 class AudioProcessingEvent extends Event {
-  AudioProcessingEvent.internal(): super.internal();
+  AudioProcessingEvent.internal() : super.internal();
 
 
   /** @domName AudioProcessingEvent.inputBuffer */
@@ -604,7 +613,7 @@
 
 /// @domName AudioSourceNode
 class AudioSourceNode extends AudioNode {
-  AudioSourceNode.internal(): super.internal();
+  AudioSourceNode.internal() : super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -616,7 +625,7 @@
 
 /// @domName BiquadFilterNode
 class BiquadFilterNode extends AudioNode {
-  BiquadFilterNode.internal(): super.internal();
+  BiquadFilterNode.internal() : super.internal();
 
   static const int ALLPASS = 7;
 
@@ -639,6 +648,10 @@
   AudioParam get Q native "BiquadFilterNode_Q_Getter";
 
 
+  /** @domName BiquadFilterNode.detune */
+  AudioParam get detune native "BiquadFilterNode_detune_Getter";
+
+
   /** @domName BiquadFilterNode.frequency */
   AudioParam get frequency native "BiquadFilterNode_frequency_Getter";
 
@@ -668,7 +681,7 @@
 
 /// @domName ChannelMergerNode
 class ChannelMergerNode extends AudioNode {
-  ChannelMergerNode.internal(): super.internal();
+  ChannelMergerNode.internal() : super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -680,7 +693,7 @@
 
 /// @domName ChannelSplitterNode
 class ChannelSplitterNode extends AudioNode {
-  ChannelSplitterNode.internal(): super.internal();
+  ChannelSplitterNode.internal() : super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -692,7 +705,7 @@
 
 /// @domName ConvolverNode
 class ConvolverNode extends AudioNode {
-  ConvolverNode.internal(): super.internal();
+  ConvolverNode.internal() : super.internal();
 
 
   /** @domName ConvolverNode.buffer */
@@ -720,7 +733,7 @@
 
 /// @domName DelayNode
 class DelayNode extends AudioNode {
-  DelayNode.internal(): super.internal();
+  DelayNode.internal() : super.internal();
 
 
   /** @domName DelayNode.delayTime */
@@ -736,7 +749,7 @@
 
 /// @domName DynamicsCompressorNode
 class DynamicsCompressorNode extends AudioNode {
-  DynamicsCompressorNode.internal(): super.internal();
+  DynamicsCompressorNode.internal() : super.internal();
 
 
   /** @domName DynamicsCompressorNode.attack */
@@ -772,7 +785,7 @@
 
 /// @domName GainNode
 class GainNode extends AudioNode {
-  GainNode.internal(): super.internal();
+  GainNode.internal() : super.internal();
 
 
   /** @domName GainNode.gain */
@@ -788,7 +801,7 @@
 
 /// @domName MediaElementAudioSourceNode
 class MediaElementAudioSourceNode extends AudioSourceNode {
-  MediaElementAudioSourceNode.internal(): super.internal();
+  MediaElementAudioSourceNode.internal() : super.internal();
 
 
   /** @domName MediaElementAudioSourceNode.mediaElement */
@@ -802,9 +815,25 @@
 // WARNING: Do not edit - generated code.
 
 
+/// @domName MediaStreamAudioDestinationNode
+class MediaStreamAudioDestinationNode extends AudioSourceNode {
+  MediaStreamAudioDestinationNode.internal() : super.internal();
+
+
+  /** @domName MediaStreamAudioDestinationNode.stream */
+  MediaStream get stream native "MediaStreamAudioDestinationNode_stream_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.
+
+
 /// @domName MediaStreamAudioSourceNode
 class MediaStreamAudioSourceNode extends AudioSourceNode {
-  MediaStreamAudioSourceNode.internal(): super.internal();
+  MediaStreamAudioSourceNode.internal() : super.internal();
 
 
   /** @domName MediaStreamAudioSourceNode.mediaStream */
@@ -820,7 +849,7 @@
 
 /// @domName OfflineAudioCompletionEvent
 class OfflineAudioCompletionEvent extends Event {
-  OfflineAudioCompletionEvent.internal(): super.internal();
+  OfflineAudioCompletionEvent.internal() : super.internal();
 
 
   /** @domName OfflineAudioCompletionEvent.renderedBuffer */
@@ -834,9 +863,25 @@
 // WARNING: Do not edit - generated code.
 
 
+/// @domName OfflineAudioContext
+class OfflineAudioContext extends AudioContext implements EventTarget {
+  OfflineAudioContext.internal() : super.internal();
+
+  ///@docsEditable true
+  factory OfflineAudioContext(int numberOfChannels, int numberOfFrames, num sampleRate) => OfflineAudioContext._create(numberOfChannels, numberOfFrames, sampleRate);
+  static OfflineAudioContext _create(int numberOfChannels, int numberOfFrames, num sampleRate) native "OfflineAudioContext_constructor_Callback";
+
+}
+// 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.
+
+
 /// @domName OscillatorNode
 class OscillatorNode extends AudioSourceNode {
-  OscillatorNode.internal(): super.internal();
+  OscillatorNode.internal() : super.internal();
 
   static const int CUSTOM = 4;
 
@@ -898,7 +943,7 @@
 
 /// @domName PannerNode
 class PannerNode extends AudioNode {
-  PannerNode.internal(): super.internal();
+  PannerNode.internal() : super.internal();
 
   static const int EQUALPOWER = 0;
 
@@ -913,10 +958,6 @@
   static const int SOUNDFIELD = 2;
 
 
-  /** @domName PannerNode.coneGain */
-  AudioGain get coneGain native "PannerNode_coneGain_Getter";
-
-
   /** @domName PannerNode.coneInnerAngle */
   num get coneInnerAngle native "PannerNode_coneInnerAngle_Getter";
 
@@ -941,10 +982,6 @@
   void set coneOuterGain(num value) native "PannerNode_coneOuterGain_Setter";
 
 
-  /** @domName PannerNode.distanceGain */
-  AudioGain get distanceGain native "PannerNode_distanceGain_Getter";
-
-
   /** @domName PannerNode.distanceModel */
   int get distanceModel native "PannerNode_distanceModel_Getter";
 
@@ -1006,26 +1043,13 @@
 
 /// @domName ScriptProcessorNode
 class ScriptProcessorNode extends AudioNode implements EventTarget {
-  ScriptProcessorNode.internal(): super.internal();
-
-  /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
-  ScriptProcessorNodeEvents get on =>
-    new ScriptProcessorNodeEvents(this);
+  ScriptProcessorNode.internal() : super.internal();
 
 
   /** @domName ScriptProcessorNode.bufferSize */
   int get bufferSize native "ScriptProcessorNode_bufferSize_Getter";
 
 }
-
-/// @docsEditable true
-class ScriptProcessorNodeEvents extends Events {
-  /// @docsEditable true
-  ScriptProcessorNodeEvents(EventTarget _ptr) : super(_ptr);
-
-  /// @docsEditable true
-  EventListenerList get audioProcess => this['audioprocess'];
-}
 // 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.
@@ -1035,7 +1059,7 @@
 
 /// @domName WaveShaperNode
 class WaveShaperNode extends AudioNode {
-  WaveShaperNode.internal(): super.internal();
+  WaveShaperNode.internal() : super.internal();
 
 
   /** @domName WaveShaperNode.curve */
diff --git a/tests/benchmark_smoke/benchmark_smoke.status b/tests/benchmark_smoke/benchmark_smoke.status
index 0616efe..d9eca2f 100644
--- a/tests/benchmark_smoke/benchmark_smoke.status
+++ b/tests/benchmark_smoke/benchmark_smoke.status
@@ -9,7 +9,6 @@
 *: Skip
 
 [ $compiler == dartc ]
-*: Skip
 
 [ $runtime == vm ]
 *: Skip
diff --git a/tests/co19/co19-compiler.status b/tests/co19/co19-compiler.status
index b8c6535..da362cb 100644
--- a/tests/co19/co19-compiler.status
+++ b/tests/co19/co19-compiler.status
@@ -109,11 +109,17 @@
 LibTest/core/StringBuffer/addAll_A02_t01: Fail
 LibTest/core/StringBuffer/clear_A02_t01: Fail
 
-
 # co19 issue 352 (use function expression with return type and name)
 LibTest/isolate/SendPort/send_A01_t01: Fail
 
 
+# co19 issue 354
+Language/07_Classes/6_Constructors/2_Factories_A01_t02: Fail
+
+
+# testing framework or VM issue 7388 (dies on Turkish character)
+Language/11_Expressions/30_Identifier_Reference_A01_t08: Skip
+
 
 Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t02: Fail, OK # deprecated parameter syntax
 
diff --git a/tests/co19/co19-dart2dart.status b/tests/co19/co19-dart2dart.status
index c36a20f..3d66bc6 100644
--- a/tests/co19/co19-dart2dart.status
+++ b/tests/co19/co19-dart2dart.status
@@ -274,8 +274,6 @@
 Language/11_Expressions/11_Instance_Creation/2_Const_A06_t02: Fail # http://dartbug.com/5519
 Language/11_Expressions/11_Instance_Creation/2_Const_A10_t01: Fail # inherited from VM
 Language/11_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A05_t01: Fail # inherited from VM
-Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t02: Fail # inherited from VM
-Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t03: Fail # inherited from VM
 Language/11_Expressions/15_Method_Invocation/3_Static_Invocation_A03_t03: Fail # inherited from VM
 Language/11_Expressions/15_Method_Invocation/3_Static_Invocation_A03_t04: Fail # http://dartbug.com/5519
 Language/11_Expressions/15_Method_Invocation/3_Static_Invocation_A03_t06: Fail # inherited from VM
@@ -325,7 +323,6 @@
 Language/11_Expressions/30_Identifier_Reference_A04_t09: Fail # Inherited from dart2js
 Language/11_Expressions/30_Identifier_Reference_A05_t01: Fail # Inherited from dart2js
 Language/11_Expressions/30_Identifier_Reference_A05_t12: Fail # Inherited from dart2js
-Language/11_Expressions/30_Identifier_Reference_A06_t01: Fail # Inherited from VM (error returning class name).
 Language/11_Expressions/30_Identifier_Reference_A06_t02: Fail # Inherited from VM (error returning typedef).
 Language/11_Expressions/30_Identifier_Reference_A07_t01: Fail # http://dartbug.com/5519
 Language/11_Expressions/30_Identifier_Reference_A08_t02: Fail # Inhertited from VM.
@@ -446,6 +443,12 @@
 LibTest/math/tan_A01_t01: Fail # Issue co19 - 44
 
 
+LibTest/core/StringBuffer/addAll_A02_t01:  Fail, OK # co19 issue 355
+LibTest/core/StringBuffer/add_A02_t01:  Fail, OK # co19 issue 355
+LibTest/core/StringBuffer/isEmpty_A01_t01:  Fail, OK # co19 issue 355
+LibTest/core/StringBuffer/clear_A02_t01: Fail, OK # co19 issue 355
+
+
 [ $compiler == dart2dart && $system == windows ]
 LibTest/core/double/operator_remainder_A01_t04: Fail # Result is NaN
 LibTest/core/double/round_A01_t01: Fail # Result is NaN
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 3ad85ec..43b3c2f 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -143,18 +143,6 @@
 Language/13_Libraries_and_Scripts/5_URIs_A01_t21: Fail # TODO(ahe): Please triage this failure.
 Language/13_Libraries_and_Scripts/5_URIs_A01_t24: Fail # TODO(ahe): Please triage this failure.
 Language/13_Libraries_and_Scripts/5_URIs_A01_t25: Fail # TODO(ahe): Please triage this failure.
-Language/14_Types/5_Function_Types_A01_t04: Fail # TODO(ahe): Please triage this failure.
-Language/14_Types/5_Function_Types_A02_t02: Fail # TODO(ahe): Please triage this failure.
-Language/14_Types/5_Function_Types_A02_t03: Fail # TODO(ahe): Please triage this failure.
-Language/14_Types/5_Function_Types_A02_t04: Fail # TODO(ahe): Please triage this failure.
-Language/14_Types/5_Function_Types_A02_t08: Fail # TODO(ahe): Please triage this failure.
-Language/14_Types/5_Function_Types_A03_t01: Fail # TODO(ahe): Please triage this failure.
-Language/14_Types/5_Function_Types_A03_t02: Fail # TODO(ahe): Please triage this failure.
-Language/14_Types/5_Function_Types_A03_t03: Fail # TODO(ahe): Please triage this failure.
-Language/14_Types/5_Function_Types_A03_t04: Fail # TODO(ahe): Please triage this failure.
-Language/14_Types/5_Function_Types_A03_t09: Fail # TODO(ahe): Please triage this failure.
-Language/14_Types/5_Function_Types_A03_t12: Fail # TODO(ahe): Please triage this failure.
-Language/14_Types/5_Function_Types_A03_t13: Fail # TODO(ahe): Please triage this failure.
 Language/14_Types/5_Function_Types_A04_t01: Fail # TODO(ahe): Please triage this failure.
 Language/15_Reference/1_Lexical_Rules/1_Reserved_Words_A40_t04: Fail # TODO(ahe): Please triage this failure.
 Language/15_Reference/1_Lexical_Rules_A01_t09: Fail # TODO(ahe): Please triage this failure.
@@ -172,6 +160,11 @@
 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/core/StringBuffer/addAll_A02_t01:  Fail, OK # co19 issue 355
+LibTest/core/StringBuffer/add_A02_t01:  Fail, OK # co19 issue 355
+LibTest/core/StringBuffer/isEmpty_A01_t01:  Fail, OK # co19 issue 355
+LibTest/core/StringBuffer/clear_A02_t01: Fail, OK # co19 issue 355
+
 # Partially implemented rediriecting constructors makes this fail.
 Language/07_Classes/6_Constructors/2_Factories_A01_t05: Fail
 
@@ -207,12 +200,6 @@
 Language/11_Expressions/07_Maps_A10_t04: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/07_Maps_A10_t05: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/07_Maps_A11_t01: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/09_Function_Expressions_A03_t03: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/09_Function_Expressions_A04_t03: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/09_Function_Expressions_A05_t02: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/09_Function_Expressions_A05_t04: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/09_Function_Expressions_A06_t02: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/09_Function_Expressions_A06_t04: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/11_Instance_Creation/1_New_A07_t01: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/11_Instance_Creation/1_New_A11_t01: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/11_Instance_Creation/2_Const_A09_t02: Fail # TODO(ahe): Please triage this failure.
@@ -237,7 +224,6 @@
 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.
 LibTest/core/AssertionError/url_A01_t01: Fail # TODO(ahe): Please triage this failure.
-LibTest/core/List/operator_subscript_A03_t01: Fail # TODO(ahe): Please triage this failure.
 LibTest/core/List/operator_subscripted_assignment_A03_t01: Fail # TODO(ahe): Please triage this failure.
 LibTest/core/Map/putIfAbsent_A01_t04: Fail # TODO(ahe): Please triage this failure.
 LibTest/core/Queue/iterator_hasNext_A01_t01: Fail # TODO(ahe): Please triage this failure.
@@ -253,6 +239,10 @@
 
 Language/11_Expressions/11_Instance_Creation/1_New_A12_t02: Fail # http://dartbug.com/3970
 
+Language/13_Libraries_and_Scripts/3_Parts_A02_t03: Fail # http://dartbug.com/5022
+Language/13_Libraries_and_Scripts/3_Parts_A03_t01: Fail # http://dartbug.com/5022
+Language/14_Types/3_Type_Declarations/1_Typedef_A01_t01: Fail # http://dartbug.com/5022
+
 
 [ $compiler == dart2js ]
 LibTest/core/int/operator_GT_A01_t01: Fail, OK # co19 issue 200
@@ -527,6 +517,8 @@
 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.
 
+Language/07_Classes/1_Instance_Methods/2_Operators_A04_t15: Fail # http://dartbug.com/7149
+Language/07_Classes/1_Instance_Methods/2_Operators_A04_t16: Fail # http://dartbug.com/7149
 
 #
 # Unexpected compile-time errors.
@@ -545,24 +537,12 @@
 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/3_Type_Declarations/1_Typedef_A02_t01: Fail # http://dartbug.com/5022
-Language/14_Types/3_Type_Declarations/1_Typedef_A02_t02: Fail # http://dartbug.com/5022
-Language/14_Types/3_Type_Declarations/1_Typedef_A02_t03: Fail # http://dartbug.com/5022
-Language/14_Types/3_Type_Declarations/1_Typedef_A03_t01: Fail # http://dartbug.com/5022
-Language/14_Types/3_Type_Declarations/1_Typedef_A04_t01: Fail # http://dartbug.com/5022
-Language/14_Types/3_Type_Declarations/1_Typedef_A04_t02: Fail # http://dartbug.com/5022
 Language/14_Types/5_Function_Types_A01_t01: Fail # http://dartbug.com/5022
-Language/14_Types/5_Function_Types_A01_t02: Fail # http://dartbug.com/5022
 Language/14_Types/5_Function_Types_A01_t03: Fail # http://dartbug.com/5022
-Language/14_Types/5_Function_Types_A01_t05: Fail # http://dartbug.com/5022
-Language/14_Types/5_Function_Types_A01_t06: Fail # http://dartbug.com/5022
-Language/14_Types/5_Function_Types_A01_t07: 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
 
-Language/13_Libraries_and_Scripts/13_Libraries_and_Scripts_A05_t02: Fail # http://dartbug.com/5713
-
 Language/07_Classes/07_Classes_A03_t10: Fail # http://dartbug.com/6687
 
 
@@ -570,26 +550,33 @@
 # Unexpected runtime errors.
 #
 [ $compiler == dart2js ]
-Language/14_Types/5_Function_Types_A02_t01: Fail # Expect.isTrue(false) fails.
-
 Language/14_Types/4_Interface_Types_A08_t06: Fail # http://dartbug.com/5020
 Language/14_Types/4_Interface_Types_A10_t01: Fail # http://dartbug.com/5020
 Language/14_Types/4_Interface_Types_A10_t02: Fail # http://dartbug.com/5020
-Language/14_Types/4_Interface_Types_A10_t03: Fail # http://dartbug.com/5020
-Language/14_Types/4_Interface_Types_A10_t07: Fail # http://dartbug.com/5020
-Language/14_Types/4_Interface_Types_A11_t02: Fail # http://dartbug.com/5020
 Language/14_Types/4_Interface_Types_A12_t09: Fail # http://dartbug.com/5020
 Language/14_Types/4_Interface_Types_A12_t10: Fail # http://dartbug.com/5020
 Language/14_Types/4_Interface_Types_A12_t14: Fail # http://dartbug.com/5020
-Language/14_Types/4_Interface_Types_A12_t16 :Fail # http://dartbug.com/5020
+Language/14_Types/4_Interface_Types_A12_t16: Fail # http://dartbug.com/5020
 
-Language/03_Overview/1_Scoping_A01_t39: Fail # http://dartbug.com/7202
-Language/14_Types/3_Type_Declarations/1_Typedef_A06_t01: Fail # http://dartbug.com/7202
-Language/14_Types/3_Type_Declarations/1_Typedef_A06_t02: Fail # http://dartbug.com/7202
-Language/14_Types/3_Type_Declarations/1_Typedef_A06_t03: Fail # http://dartbug.com/7202
-Language/14_Types/3_Type_Declarations/1_Typedef_A06_t04: Fail # http://dartbug.com/7202
-Language/14_Types/3_Type_Declarations/1_Typedef_A06_t05: Fail # http://dartbug.com/7202
-Language/14_Types/3_Type_Declarations/1_Typedef_A07_t01: Fail # http://dartbug.com/7202
-Language/14_Types/3_Type_Declarations/1_Typedef_A07_t02: Fail # http://dartbug.com/7202
-Language/14_Types/3_Type_Declarations/1_Typedef_A07_t03: Fail # http://dartbug.com/7202
-Language/14_Types/3_Type_Declarations/1_Typedef_A07_t04: Fail # http://dartbug.com/7202
+Language/03_Overview/1_Scoping_A01_t39: Fail # dartbug.com/7202
+Language/14_Types/3_Type_Declarations/1_Typedef_A06_t01: Fail # dartbug.com/7202
+Language/14_Types/3_Type_Declarations/1_Typedef_A06_t02: Fail # dartbug.com/7202
+Language/14_Types/3_Type_Declarations/1_Typedef_A06_t03: Fail # dartbug.com/7202
+Language/14_Types/3_Type_Declarations/1_Typedef_A06_t04: Fail # dartbug.com/7202
+Language/14_Types/3_Type_Declarations/1_Typedef_A06_t05: Fail # dartbug.com/7202
+Language/14_Types/3_Type_Declarations/1_Typedef_A07_t01: Fail # dartbug.com/7202
+Language/14_Types/3_Type_Declarations/1_Typedef_A07_t02: Fail # dartbug.com/7202
+Language/14_Types/3_Type_Declarations/1_Typedef_A07_t03: Fail # dartbug.com/7202
+Language/14_Types/3_Type_Declarations/1_Typedef_A07_t04: Fail # dartbug.com/7202
+
+Language/14_Types/5_Function_Types_A01_t08: Fail # dartbug.com/7342
+Language/14_Types/5_Function_Types_A01_t09: Fail # dartbug.com/7342
+Language/14_Types/5_Function_Types_A01_t11: Fail # dartbug.com/7342
+Language/14_Types/5_Function_Types_A02_t05: Fail # dartbug.com/7342
+Language/14_Types/5_Function_Types_A02_t07: Fail # dartbug.com/7342
+Language/14_Types/5_Function_Types_A02_t09: Fail # dartbug.com/7342
+Language/14_Types/5_Function_Types_A02_t10: Fail # dartbug.com/7342
+Language/14_Types/5_Function_Types_A03_t06: Fail # dartbug.com/7342
+Language/14_Types/5_Function_Types_A03_t08: Fail # dartbug.com/7342
+Language/14_Types/5_Function_Types_A03_t10: Fail # dartbug.com/7342
+Language/14_Types/5_Function_Types_A03_t11: Fail # dartbug.com/7342
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index ae33a54..3a13029 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -6,7 +6,6 @@
 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
 
-Language/03_Overview/1_Scoping_A02_t32: Fail # Dart issue 6556
 Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A01_t10: Fail # co19 issue 348
 Language/07_Classes/3_Setters_A04_t01: Fail # Dart issue 5840
 Language/07_Classes/3_Setters_A04_t04: Fail # Dart issue 5840
@@ -28,7 +27,6 @@
 Language/11_Expressions/01_Constants_A05_t01: Fail # Dart issue 5832
 Language/11_Expressions/01_Constants_A06_t01: Fail # Dart issue 5214
 Language/11_Expressions/01_Constants_A14_t01: Fail # Dart issue 5214
-Language/11_Expressions/01_Constants_A20_t02: Fail # Dart issue 6556
 Language/11_Expressions/01_Constants_A20_t03: Fail # Dart issue 6556
 Language/11_Expressions/05_Strings/1_String_Interpolation_A01_t04: Fail # Dart issue 7246
 Language/11_Expressions/05_Strings/1_String_Interpolation_A01_t05: Fail # Dart issue 7246
@@ -43,75 +41,40 @@
 Language/11_Expressions/18_Assignment_A05_t02: Fail # Dart issue 6449
 Language/11_Expressions/18_Assignment_A05_t04: Fail, OK # co19 issue 350.
 Language/11_Expressions/18_Assignment_A05_t05: Fail # Dart issue 6449
-Language/11_Expressions/19_Conditional_A01_t10: Fail # Dart issue 7251
-Language/11_Expressions/19_Conditional_A01_t11: Fail # Dart issue 7252
-Language/11_Expressions/19_Conditional_A01_t12: Fail # Dart issue 7251
-Language/11_Expressions/19_Conditional_A01_t13: Fail # Dart issue 7252
 Language/11_Expressions/19_Conditional_A01_t14: Fail # Dart issue 7251
 Language/11_Expressions/19_Conditional_A01_t15: Fail # Dart issue 7252
-Language/11_Expressions/20_Logical_Boolean_Expressions_A01_t10: Fail # Dart issue 7251
-Language/11_Expressions/20_Logical_Boolean_Expressions_A01_t11: Fail # Dart issue 7251
-Language/11_Expressions/20_Logical_Boolean_Expressions_A01_t12: Fail # Dart issue 7251
-Language/11_Expressions/20_Logical_Boolean_Expressions_A01_t13: Fail # Dart issue 7251
 Language/11_Expressions/20_Logical_Boolean_Expressions_A01_t14: Fail # Dart issue 7251
 Language/11_Expressions/20_Logical_Boolean_Expressions_A01_t15: Fail # Dart issue 7251
-Language/11_Expressions/21_Bitwise_Expressions_A01_t12: Fail # Dart issue 7251
-Language/11_Expressions/21_Bitwise_Expressions_A01_t13: Fail # Dart issue 7251
-Language/11_Expressions/21_Bitwise_Expressions_A01_t14: Fail # Dart issue 7251
-Language/11_Expressions/21_Bitwise_Expressions_A01_t15: Fail # Dart issue 7251
 Language/11_Expressions/21_Bitwise_Expressions_A01_t16: Fail # Dart issue 7251
 Language/11_Expressions/21_Bitwise_Expressions_A01_t17: Fail # Dart issue 7251
+Language/11_Expressions/22_Equality_A01_t19: Fail # co19 issue 356
+Language/11_Expressions/22_Equality_A01_t20: Fail # co19 issue 356
 Language/11_Expressions/22_Equality_A01_t23: Fail # Dart issue 7254
 Language/11_Expressions/22_Equality_A01_t24: Fail # Dart issue 7254
-Language/11_Expressions/23_Relational_Expressions_A01_t18: Fail # Dart issue 7256
-Language/11_Expressions/23_Relational_Expressions_A01_t19: Fail # Dart issue 7256
-Language/11_Expressions/23_Relational_Expressions_A01_t20: Fail # Dart issue 7256
-Language/11_Expressions/23_Relational_Expressions_A01_t21: Fail # Dart issue 7256
 Language/11_Expressions/23_Relational_Expressions_A01_t22: Fail # Dart issue 7256
 Language/11_Expressions/23_Relational_Expressions_A01_t23: Fail # Dart issue 7256
-Language/11_Expressions/24_Shift_A01_t09: Fail # Dart issue 7256
-Language/11_Expressions/24_Shift_A01_t10: Fail # Dart issue 7256
-Language/11_Expressions/24_Shift_A01_t11: Fail # Dart issue 7256
-Language/11_Expressions/24_Shift_A01_t12: Fail # Dart issue 7256
 Language/11_Expressions/24_Shift_A01_t13: Fail # Dart issue 7256
 Language/11_Expressions/24_Shift_A01_t14: Fail # Dart issue 7256
-Language/11_Expressions/25_Additive_Expressions_A01_t07: Fail # Dart issue 7256
-Language/11_Expressions/25_Additive_Expressions_A01_t08: Fail # Dart issue 7256
-Language/11_Expressions/25_Additive_Expressions_A01_t11: Fail # Dart issue 7256
-Language/11_Expressions/25_Additive_Expressions_A01_t12: Fail # Dart issue 7256
 Language/11_Expressions/25_Additive_Expressions_A01_t13: Fail # Dart issue 7256
 Language/11_Expressions/25_Additive_Expressions_A01_t14: Fail # Dart issue 7256
-Language/11_Expressions/26_Multiplicative_Expressions_A01_t10: Fail # Dart issue 7256
-Language/11_Expressions/26_Multiplicative_Expressions_A01_t11: Fail # Dart issue 7256
-Language/11_Expressions/26_Multiplicative_Expressions_A01_t14: Fail # Dart issue 7256
-Language/11_Expressions/26_Multiplicative_Expressions_A01_t15: Fail # Dart issue 7256
 Language/11_Expressions/26_Multiplicative_Expressions_A01_t16: Fail # Dart issue 7256
 Language/11_Expressions/26_Multiplicative_Expressions_A01_t17: Fail # Dart issue 7256
 Language/11_Expressions/27_Unary_Expressions_A01_t02: Fail # Dart issue 7256
 Language/11_Expressions/27_Unary_Expressions_A01_t04: Fail # Dart issue 7256
 Language/11_Expressions/27_Unary_Expressions_A01_t05: Fail # Dart issue 7256
-Language/11_Expressions/27_Unary_Expressions_A01_t11: Fail # Dart issue 7256
-Language/11_Expressions/27_Unary_Expressions_A01_t12: Fail # Dart issue 7256
-Language/11_Expressions/27_Unary_Expressions_A01_t13: Fail # Dart issue 7256
-Language/11_Expressions/27_Unary_Expressions_A01_t17: Fail # Dart issue 7256
-Language/11_Expressions/27_Unary_Expressions_A01_t18: Fail # Dart issue 7256
-Language/11_Expressions/27_Unary_Expressions_A01_t19: Fail # Dart issue 7256
 Language/11_Expressions/27_Unary_Expressions_A01_t20: Fail # Dart issue 7256
 Language/11_Expressions/27_Unary_Expressions_A01_t21: Fail # Dart issue 7256
 Language/11_Expressions/27_Unary_Expressions_A01_t22: Fail # Dart issue 7256
 Language/11_Expressions/28_Postfix_Expressions_A01_t02: Fail # Dart issue 7256
 Language/11_Expressions/28_Postfix_Expressions_A01_t03: Fail # Dart issue 7256
 Language/11_Expressions/28_Postfix_Expressions_A01_t05: Fail # Dart issue 7256
-Language/11_Expressions/29_Assignable_Expressions_A01_t06: Fail # Dart issue 7256
 Language/11_Expressions/29_Assignable_Expressions_A01_t08: Fail # Dart issue 7256
-Language/11_Expressions/29_Assignable_Expressions_A01_t09: Fail # Dart issue 7256
 Language/11_Expressions/30_Identifier_Reference_A05_t02: Fail # Dart issue 2492
-Language/11_Expressions/30_Identifier_Reference_A06_t01: Fail # Dart issue 7257
-Language/11_Expressions/30_Identifier_Reference_A06_t02: Fail # Dart issue 7257
 Language/11_Expressions/30_Identifier_Reference_A07_t01: Fail # Dart issue 7257
 Language/11_Expressions/30_Identifier_Reference_A08_t02: Fail # Dart issue 5802
 Language/11_Expressions/31_Type_Test_A01_t02: Fail # Dart issue 7258
 Language/11_Expressions/31_Type_Test_A01_t04: Fail # Dart issue 7258
+Language/11_Expressions/32_Type_Cast_A01_t04: Fail # co19 issue 356
 Language/12_Statements/03_Variable_Declaration_A04_t07: Fail # Dart issue 7305
 Language/12_Statements/04_Local_Function_Declaration_A02_t02: Fail # Dart issue 5773
 Language/12_Statements/06_For_A01_t11: Fail # Dart issue 5675
@@ -302,11 +265,10 @@
 LibTest/isolate/isolate_api/spawnUri_A01_t03: Crash
 LibTest/isolate/isolate_api/spawnUri_A01_t04: Crash
 
-
-# class '?' overrides function '?' of super class '?' with incompatible parameters
-Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t02: Fail
-Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t03: Fail
-
+LibTest/core/StringBuffer/addAll_A02_t01:  Fail, OK # co19 issue 355
+LibTest/core/StringBuffer/add_A02_t01:  Fail, OK # co19 issue 355
+LibTest/core/StringBuffer/isEmpty_A01_t01:  Fail, OK # co19 issue 355
+LibTest/core/StringBuffer/clear_A02_t01: Fail, OK # co19 issue 355
 
 # parameter name or type expected
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A15_t07: Fail
diff --git a/tests/compiler/dart2js/cpa_inference_test.dart b/tests/compiler/dart2js/cpa_inference_test.dart
index 9b9a1ba..99558b7 100644
--- a/tests/compiler/dart2js/cpa_inference_test.dart
+++ b/tests/compiler/dart2js/cpa_inference_test.dart
@@ -91,11 +91,15 @@
     return element.lookupLocalMember(buildSourceString(fieldName));
   }
 
-  static ConcreteType concreteFrom(List<BaseType> baseTypes) {
-    ConcreteType result = new ConcreteType.empty();
+  ConcreteType concreteFrom(List<BaseType> baseTypes) {
+    ConcreteType result = inferrer.emptyConcreteType;
     for (final baseType in baseTypes) {
-      result = result.union(new ConcreteType.singleton(baseType));
+      result = result.union(compiler.maxConcreteTypeSize,
+          inferrer.singletonConcreteType(baseType));
     }
+    // We make sure the concrete types expected by the tests don't default to
+    // dynamic because of widening.
+    assert(!result.isUnkown());
     return result;
   }
 
@@ -162,10 +166,12 @@
   class Dynamic_ {}
   bool identical(Object a, Object b) {}''';
 
-AnalysisResult analyze(String code) {
+AnalysisResult analyze(String code, {int maxConcreteTypeSize: 1000}) {
   Uri uri = new Uri.fromComponents(scheme: 'source');
-  MockCompiler compiler = new MockCompiler(coreSource: CORELIB,
-                                           enableConcreteTypeInference: true);
+  MockCompiler compiler = new MockCompiler(
+      coreSource: CORELIB,
+      enableConcreteTypeInference: true,
+      maxConcreteTypeSize: maxConcreteTypeSize);
   compiler.sourceFiles[uri.toString()] = new SourceFile(uri.toString(), code);
   compiler.typesTask.concreteTypesInferrer.testMode = true;
   compiler.runCompiler(uri);
@@ -786,6 +792,39 @@
   result.checkNodeHasType('w', []);
 }
 
+testBigTypesWidening1() {
+  final String source = r"""
+    small() => true ? 1 : 'abc';
+    big() => true ? 1 : (true ? 'abc' : false);
+    main () {
+      var x = small();
+      var y = big();
+      x; y;
+    }
+    """;
+  AnalysisResult result = analyze(source, maxConcreteTypeSize: 2);
+  result.checkNodeHasType('x', [result.int, result.string]);
+  result.checkNodeHasUnknownType('y');
+}
+
+testBigTypesWidening2() {
+  final String source = r"""
+    class A {
+      var x, y;
+      A(this.x, this.y);
+    }
+    main () {
+      var a = new A(1, 1);
+      a.x = 'abc';
+      a.y = 'abc';
+      a.y = true;
+    }
+    """;
+  AnalysisResult result = analyze(source, maxConcreteTypeSize: 2);
+  result.checkFieldHasType('A', 'x', [result.int, result.string]);
+  result.checkFieldHasUknownType('A', 'y');
+}
+
 testDynamicIsAbsorbing() {
   final String source = r"""
     main () {
@@ -835,5 +874,7 @@
   testInequality();
   // testFieldInitialization(); // TODO(polux)
   testSendWithWrongArity();
+  testBigTypesWidening1();
+  testBigTypesWidening2();
   testDynamicIsAbsorbing();
 }
diff --git a/tests/compiler/dart2js/dart_backend_test.dart b/tests/compiler/dart2js/dart_backend_test.dart
index 30860a8..9959ec4 100644
--- a/tests/compiler/dart2js/dart_backend_test.dart
+++ b/tests/compiler/dart2js/dart_backend_test.dart
@@ -61,6 +61,11 @@
 var JS;
 ''';
 
+const isolateHelperLib = r'''
+class _WorkerStub {
+}
+''';
+
 testDart2Dart(String src, {void continuation(String s), bool minify: false,
     bool stripTypes: false}) {
   // If continuation is not provided, check that source string remains the same.
@@ -88,12 +93,20 @@
     if (uri.toString() == libUri.toString()) {
       return new Future.immediate(srcLibrary);
     }
-    if (uri.path.endsWith('/core.dart')) return new Future.immediate(coreLib);
-    if (uri.path.endsWith('/io.dart')) return new Future.immediate(ioLib);
-    if (uri.path.endsWith('/js_helper.dart')) return new Future.immediate(helperLib);
-    // TODO(smok): The file should change to html_dartium at some point.
-    if (uri.path.endsWith('/html_dart2js.dart')) return new Future.immediate(htmlLib);
-    if (uri.path.endsWith('/foreign_helper.dart')) return new Future.immediate(foreignLib);
+    if (uri.path.endsWith('/core.dart')) {
+      return new Future.immediate(coreLib);
+    } else  if (uri.path.endsWith('/io.dart')) {
+      return new Future.immediate(ioLib);
+    } else if (uri.path.endsWith('/js_helper.dart')) {
+      return new Future.immediate(helperLib);
+    } else if (uri.path.endsWith('/html_dart2js.dart')) {
+      // TODO(smok): The file should change to html_dartium at some point.
+      return new Future.immediate(htmlLib);
+    } else if (uri.path.endsWith('/foreign_helper.dart')) {
+      return new Future.immediate(foreignLib);
+    } else if (uri.path.endsWith('/isolate_helper.dart')) {
+      return new Future.immediate(isolateHelperLib);
+    }
     return new Future.immediate('');
   }
 
diff --git a/tests/compiler/dart2js/mirrors_helper.dart b/tests/compiler/dart2js/mirrors_helper.dart
index 1e9485c..52d9bb9 100644
--- a/tests/compiler/dart2js/mirrors_helper.dart
+++ b/tests/compiler/dart2js/mirrors_helper.dart
@@ -14,11 +14,21 @@
 
 }
 
+@Metadata // This is intentionally the type literal.
+@Metadata(null)
+@Metadata(true)
+@Metadata(false)
+@Metadata(0)
+@Metadata(1.5)
+@Metadata("Foo")
+@Metadata(const ["Foo"])
+@Metadata(const {'foo':"Foo"})
+@metadata
 class Foo {
 
 }
 
-interface Bar<E> {
+abstract class Bar<E> {
 
 }
 
@@ -53,4 +63,11 @@
   void _privateMethod() {}
   _PrivateClass._privateConstructor();
   factory _PrivateClass._privateFactoryConstructor() => new _PrivateClass();
+}
+
+const metadata = const Metadata(null);
+
+class Metadata {
+  final data;
+  const Metadata(this.data);
 }
\ No newline at end of file
diff --git a/tests/compiler/dart2js/mirrors_test.dart b/tests/compiler/dart2js/mirrors_test.dart
index 8b223fa7..0930702 100644
--- a/tests/compiler/dart2js/mirrors_test.dart
+++ b/tests/compiler/dart2js/mirrors_test.dart
@@ -115,6 +115,7 @@
   Expect.equals(fooClass, fooClass.originalDeclaration);
 
   Expect.isTrue(fooClass.isClass, "Class is not class");
+  Expect.isFalse(fooClass.isAbstract);
   Expect.isFalse(fooClass.isInterface, "Class is interface");
   Expect.isFalse(fooClass.isPrivate, "Class is private");
 
@@ -163,65 +164,222 @@
   Expect.isNotNull(fooClass.getters);
   Expect.isNotNull(fooClass.setters);
   Expect.isNotNull(fooClass.variables);
+
+  //////////////////////////////////////////////////////////////////////////////
+  // Metadata tests
+  //////////////////////////////////////////////////////////////////////////////
+
+  var metadata = fooClass.metadata;
+  Expect.isNotNull(metadata);
+  Expect.equals(10, metadata.length);
+
+  // @Metadata // This is intentionally the type literal.
+  var metadata0 = metadata[0];
+  Expect.isTrue(metadata0 is InstanceMirror);
+  Expect.isFalse(metadata0.hasReflectee);
+  Expect.throws(() => metadata0.reflectee, (_) => true);
+  Expect.isTrue(metadata0 is TypeInstanceMirror);
+  var metadataType = metadata0.representedType;
+  Expect.isNotNull(metadataType);
+  Expect.stringEquals('Metadata', metadataType.simpleName);
+
+  // @Metadata(null)
+  var metadata1 = metadata[1];
+  Expect.isTrue(metadata1 is InstanceMirror);
+  Expect.isFalse(metadata1.hasReflectee);
+  Expect.throws(() => metadata1.reflectee, (_) => true);
+  Expect.equals(metadataType.originalDeclaration, metadata1.type);
+  metadata1.getField('data').then((InstanceMirror data) {
+    Expect.isNotNull(data);
+    Expect.isTrue(data.hasReflectee);
+    Expect.isNull(data.reflectee);
+  });
+
+  // @Metadata(true)
+  var metadata2 = metadata[2];
+  Expect.isTrue(metadata2 is InstanceMirror);
+  Expect.isFalse(metadata2.hasReflectee);
+  Expect.throws(() => metadata2.reflectee, (_) => true);
+  Expect.equals(metadataType.originalDeclaration, metadata2.type);
+  metadata2.getField('data').then((InstanceMirror data) {
+    Expect.isNotNull(data);
+    Expect.isTrue(data.hasReflectee);
+    Expect.isTrue(data.reflectee);
+  });
+
+  // @Metadata(false)
+  var metadata3 = metadata[3];
+  Expect.isTrue(metadata3 is InstanceMirror);
+  Expect.isFalse(metadata3.hasReflectee);
+  Expect.throws(() => metadata3.reflectee, (_) => true);
+  Expect.equals(metadataType.originalDeclaration, metadata3.type);
+  metadata3.getField('data').then((InstanceMirror data) {
+    Expect.isNotNull(data);
+    Expect.isTrue(data.hasReflectee);
+    Expect.isFalse(data.reflectee);
+  });
+
+  // @Metadata(0)
+  var metadata4 = metadata[4];
+  Expect.isTrue(metadata4 is InstanceMirror);
+  Expect.isFalse(metadata4.hasReflectee);
+  Expect.throws(() => metadata4.reflectee, (_) => true);
+  Expect.equals(metadataType.originalDeclaration, metadata4.type);
+  metadata4.getField('data').then((InstanceMirror data) {
+    Expect.isNotNull(data);
+    Expect.isTrue(data.hasReflectee);
+    Expect.equals(0, data.reflectee);
+  });
+
+  // @Metadata(1.5)
+  var metadata5 = metadata[5];
+  Expect.isTrue(metadata5 is InstanceMirror);
+  Expect.isFalse(metadata5.hasReflectee);
+  Expect.throws(() => metadata5.reflectee, (_) => true);
+  Expect.equals(metadataType.originalDeclaration, metadata5.type);
+  metadata5.getField('data').then((InstanceMirror data) {
+    Expect.isNotNull(data);
+    Expect.isTrue(data.hasReflectee);
+    Expect.equals(1.5, data.reflectee);
+  });
+
+  // @Metadata("Foo")
+  var metadata6 = metadata[6];
+  Expect.isTrue(metadata6 is InstanceMirror);
+  Expect.isFalse(metadata6.hasReflectee);
+  Expect.throws(() => metadata6.reflectee, (_) => true);
+  Expect.equals(metadataType.originalDeclaration, metadata6.type);
+  metadata6.getField('data').then((InstanceMirror data) {
+    Expect.isNotNull(data);
+    Expect.isTrue(data.hasReflectee);
+    Expect.stringEquals("Foo", data.reflectee);
+  });
+
+  // @Metadata(const ["Foo"])
+  var metadata7 = metadata[7];
+  Expect.isTrue(metadata7 is InstanceMirror);
+  Expect.isFalse(metadata7.hasReflectee);
+  Expect.throws(() => metadata7.reflectee, (_) => true);
+  Expect.equals(metadataType.originalDeclaration, metadata7.type);
+  metadata7.getField('data').then((InstanceMirror data) {
+    Expect.isTrue(data is ListInstanceMirror);
+    Expect.isFalse(data.hasReflectee);
+    Expect.throws(() => data.reflectee, (_) => true);
+    ListInstanceMirror listData = data;
+    Expect.equals(1, listData.length);
+    listData[0].then((InstanceMirror element) {
+      Expect.isNotNull(element);
+      Expect.isTrue(element.hasReflectee);
+      Expect.stringEquals("Foo", element.reflectee);
+    });
+  });
+
+  // @Metadata(const {'foo':"Foo"})
+  var metadata8 = metadata[8];
+  Expect.isTrue(metadata8 is InstanceMirror);
+  Expect.isFalse(metadata8.hasReflectee);
+  Expect.throws(() => metadata8.reflectee, (_) => true);
+  Expect.equals(metadataType.originalDeclaration, metadata8.type);
+  metadata8.getField('data').then((InstanceMirror data) {
+    Expect.isTrue(data is MapInstanceMirror);
+    Expect.isFalse(data.hasReflectee);
+    Expect.throws(() => data.reflectee, (_) => true);
+    MapInstanceMirror mapData = data;
+    Expect.equals(1, mapData.length);
+    Expect.stringEquals('foo', mapData.keys.iterator().next());
+    mapData['foo'].then((InstanceMirror element) {
+      Expect.isNotNull(element);
+      Expect.isTrue(element.hasReflectee);
+      Expect.stringEquals("Foo", element.reflectee);
+    });
+    Expect.isNull(mapData['bar']);
+  });
+
+  // @metadata
+  var metadata9 = metadata[9];
+  Expect.isTrue(metadata9 is InstanceMirror);
+  Expect.isFalse(metadata9.hasReflectee);
+  Expect.throws(() => metadata9.reflectee, (_) => true);
+  Expect.equals(metadataType.originalDeclaration, metadata9.type);
+  metadata9.getField('data').then((InstanceMirror data) {
+    Expect.isNotNull(data);
+    Expect.isTrue(data.hasReflectee);
+    Expect.isNull(data.reflectee);
+  });
+
+  //////////////////////////////////////////////////////////////////////////////
+  // Location test
+  //////////////////////////////////////////////////////////////////////////////
+
+  var fooClassLocation = fooClass.location;
+  Expect.isNotNull(fooClassLocation);
+  // Expect the location to start with the first metadata.
+  Expect.equals(348, fooClassLocation.offset, "Unexpected offset");
+  // Expect the location to end with the class body.
+  Expect.equals(227, fooClassLocation.length, "Unexpected length");
+  Expect.equals(17, fooClassLocation.line, "Unexpected line");
+  Expect.equals(1, fooClassLocation.column, "Unexpected column");
+
 }
 
-// Testing interface Bar:
+// Testing abstract class Bar:
 //
-// interface Bar<E> {
+// abstract class Bar<E> {
 //
 // }
 void testBar(MirrorSystem system, LibraryMirror helperLibrary,
              Map<String,TypeMirror> classes) {
-  var barInterface = classes["Bar"];
-  Expect.isNotNull(barInterface, "Type 'Bar' not found");
-  Expect.isTrue(barInterface is ClassMirror,
+  var barClass = classes["Bar"];
+  Expect.isNotNull(barClass, "Type 'Bar' not found");
+  Expect.isTrue(barClass is ClassMirror,
                "Unexpected mirror type returned");
-  Expect.stringEquals("Bar", barInterface.simpleName,
+  Expect.stringEquals("Bar", barClass.simpleName,
                       "Unexpected type simple name");
-  Expect.stringEquals("mirrors_helper.Bar", barInterface.qualifiedName,
+  Expect.stringEquals("mirrors_helper.Bar", barClass.qualifiedName,
                       "Unexpected type qualified name");
 
-  Expect.equals(helperLibrary, barInterface.library,
+  Expect.equals(helperLibrary, barClass.library,
                 "Unexpected library returned from type");
 
-  Expect.isFalse(barInterface.isObject, "Interface is Object");
-  Expect.isFalse(barInterface.isDynamic, "Interface is Dynamic");
-  Expect.isFalse(barInterface.isVoid, "Interface is void");
-  Expect.isFalse(barInterface.isTypeVariable, "Interface is a type variable");
-  Expect.isFalse(barInterface.isTypedef, "Interface is a typedef");
-  Expect.isFalse(barInterface.isFunction, "Interface is a function");
+  Expect.isFalse(barClass.isObject, "Interface is Object");
+  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");
+  Expect.isFalse(barClass.isFunction, "Interface is a function");
 
-  Expect.isTrue(barInterface.isOriginalDeclaration);
-  Expect.equals(barInterface, barInterface.originalDeclaration);
+  Expect.isTrue(barClass.isOriginalDeclaration);
+  Expect.equals(barClass, barClass.originalDeclaration);
 
-  Expect.isFalse(barInterface.isClass, "Interface is class");
-  Expect.isTrue(barInterface.isInterface, "Interface is not interface");
-  Expect.isFalse(barInterface.isPrivate, "Interface is private");
+  Expect.isTrue(barClass.isClass);
+  Expect.isTrue(barClass.isAbstract);
+  Expect.isFalse(barClass.isInterface);
+  Expect.isFalse(barClass.isPrivate, "Interface is private");
 
-  var objectType = barInterface.superclass;
+  var objectType = barClass.superclass;
   Expect.isNotNull(objectType, "Superclass is null");
   Expect.isTrue(objectType.isObject, "Object is not Object");
   Expect.isFalse(objectType.isOriginalDeclaration);
-  Expect.isTrue(containsType(barInterface,
+  Expect.isTrue(containsType(barClass,
                              computeSubdeclarations(objectType)),
                 "Class is not subclass of superclass");
 
-  var barInterfaces = barInterface.superinterfaces;
+  var barInterfaces = barClass.superinterfaces;
   Expect.isNotNull(barInterfaces, "Interfaces map is null");
   Expect.isTrue(barInterfaces.isEmpty, "Interfaces map is not empty");
 
-  var barSubdeclarations = computeSubdeclarations(barInterface);
+  var barSubdeclarations = computeSubdeclarations(barClass);
   Expect.equals(1, count(barSubdeclarations), "Unexpected subtype count");
   for (var barSubdeclaration in barSubdeclarations) {
-    Expect.isTrue(containsType(barInterface,
+    Expect.isTrue(containsType(barClass,
                                barSubdeclaration.superinterfaces),
                   "Interface is not superinterface of subclass");
   }
 
-  Expect.throws(() => barInterface.typeArguments,
+  Expect.throws(() => barClass.typeArguments,
               (exception) => true,
               "Interface has type arguments");
-  var barInterfaceTypeVariables = barInterface.typeVariables;
+  var barInterfaceTypeVariables = barClass.typeVariables;
   Expect.isNotNull(barInterfaceTypeVariables, "Type variable list is null");
   Expect.isFalse(barInterfaceTypeVariables.isEmpty,
                  "Type variable list is empty");
@@ -232,17 +390,21 @@
   Expect.isNotNull(barE, "Type variable is null");
   Expect.isTrue(barE.isTypeVariable, "Type variable is not type variable");
 
-  Expect.isNull(barInterface.defaultFactory);
+  Expect.isNull(barClass.defaultFactory);
 
-  var barInterfaceMembers = barInterface.members;
+  var barInterfaceMembers = barClass.members;
   Expect.isNotNull(barInterfaceMembers, "Declared members map is null");
   Expect.isTrue(barInterfaceMembers.isEmpty,
                 "Declared members map is unempty");
 
-  var barInterfaceConstructors = barInterface.constructors;
+  var barInterfaceConstructors = barClass.constructors;
   Expect.isNotNull(barInterfaceConstructors, "Constructors map is null");
   Expect.isTrue(barInterfaceConstructors.isEmpty,
                 "Constructors map is unempty");
+
+  var metadata = barClass.metadata;
+  Expect.isNotNull(metadata);
+  Expect.equals(0, metadata.length);
 }
 
 // Testing class Baz:
@@ -284,6 +446,7 @@
   Expect.equals(bazClass, bazClass.originalDeclaration);
 
   Expect.isTrue(bazClass.isClass, "Class is not class");
+  Expect.isFalse(bazClass.isAbstract);
   Expect.isFalse(bazClass.isInterface, "Class is interface");
   Expect.isFalse(bazClass.isPrivate, "Class is private");
 
@@ -721,6 +884,10 @@
 
   // TODO(johnniwinther): Add more tests of constructors.
   // TODO(johnniwinther): Add a test for unnamed factory methods.
+
+  var metadata = bazClass.metadata;
+  Expect.isNotNull(metadata);
+  Expect.equals(0, metadata.length);
 }
 
 // class _PrivateClass {
@@ -737,6 +904,7 @@
   Expect.isNotNull(privateClass);
   Expect.isTrue(privateClass is ClassMirror);
   Expect.isTrue(privateClass.isClass);
+  Expect.isFalse(privateClass.isAbstract);
   Expect.isTrue(privateClass.isPrivate);
 
   var privateField = privateClass.members['_privateField'];
@@ -785,4 +953,8 @@
   Expect.isFalse(privateFactoryConstructor.isRedirectingConstructor);
   Expect.isFalse(privateFactoryConstructor.isGenerativeConstructor);
   Expect.isTrue(privateFactoryConstructor.isFactoryConstructor);
+
+  var metadata = privateClass.metadata;
+  Expect.isNotNull(metadata);
+  Expect.equals(0, metadata.length);
 }
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index 883f02b..1bbb6dd 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -51,6 +51,7 @@
 const String DEFAULT_INTERCEPTORSLIB = r'''
   class JSArray {
     var length;
+    operator[](index) {}
   }
   class JSString {
     var length;
@@ -88,6 +89,9 @@
   class Dynamic_ {}
   bool identical(Object a, Object b) {}''';
 
+const String DEFAULT_ISOLATE_HELPERLIB = r'''
+  class _WorkerBase {}''';
+
 class MockCompiler extends Compiler {
   List<WarningMessage> warnings;
   List<WarningMessage> errors;
@@ -97,15 +101,18 @@
   MockCompiler({String coreSource: DEFAULT_CORELIB,
                 String helperSource: DEFAULT_HELPERLIB,
                 String interceptorsSource: DEFAULT_INTERCEPTORSLIB,
+                String isolateHelperSource: DEFAULT_ISOLATE_HELPERLIB,
                 bool enableTypeAssertions: false,
                 bool enableMinification: false,
                 bool enableConcreteTypeInference: false,
+                int maxConcreteTypeSize: 5,
                 bool analyzeAll: false})
       : warnings = [], errors = [],
         sourceFiles = new Map<String, SourceFile>(),
         super(enableTypeAssertions: enableTypeAssertions,
               enableMinification: enableMinification,
               enableConcreteTypeInference: enableConcreteTypeInference,
+              maxConcreteTypeSize: maxConcreteTypeSize,
               analyzeAll: analyzeAll) {
     coreLibrary = createLibrary("core", coreSource);
     // We need to set the assert method to avoid calls with a 'null'
@@ -116,6 +123,7 @@
 
     assertMethod = jsHelperLibrary.find(buildSourceString('assert'));
     interceptorsLibrary = createLibrary("interceptors", interceptorsSource);
+    isolateHelperLibrary = createLibrary("isolate_helper", isolateHelperSource);
 
     mainApp = mockLibrary(this, "");
     initializeSpecialClasses();
diff --git a/tests/compiler/dart2js/type_inference_test.dart b/tests/compiler/dart2js/type_inference_test.dart
index f82f15b..de15c8f 100644
--- a/tests/compiler/dart2js/type_inference_test.dart
+++ b/tests/compiler/dart2js/type_inference_test.dart
@@ -29,6 +29,7 @@
 
 const String TEST_THREE = r"""
 foo(a) {
+  print([]);
   for (int b = 0; b < 10; b++) print(a[b]);
 }
 """;
@@ -49,6 +50,7 @@
 
 const String TEST_FIVE_WITH_BAILOUT = r"""
 foo(a) {
+  print([]);
   for (int i = 0; i < 1; i++) {
     a[0] = 1;
     print(a[1]);
@@ -58,6 +60,7 @@
 
 const String TEST_SIX = r"""
 foo(a) {
+  print([]);
   print(a[0]);
   while (true) {
     a[0] = a[1];
diff --git a/tests/compiler/dart2js_native/native_class_fields_2_test.dart b/tests/compiler/dart2js_native/native_class_fields_2_test.dart
new file mode 100644
index 0000000..1612371
--- /dev/null
+++ b/tests/compiler/dart2js_native/native_class_fields_2_test.dart
@@ -0,0 +1,111 @@
+// 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.
+
+// Verify that methods are not renamed to clash with native field names
+// that are known from the DOM (like x, y, z).
+class A native "*A" {
+  int x;
+  int y;
+  int z;
+  int gettersCalled;
+}
+
+
+void setup() native r"""
+function getter() {
+  this.gettersCalled++;
+  return 42;
+}
+
+function A(){
+  var a = Object.create(
+      { constructor: { name: 'A'}},
+      { x: { get: getter, configurable: false, writeable: false },
+        y: { get: getter, configurable: false, writeable: false },
+        z: { get: getter, configurable: false, writeable: false }
+      });
+  a.gettersCalled = 0;
+  return a;
+}
+
+makeA = function() { return new A; };
+""";
+
+A makeA() native;
+
+class B {
+  void a() { }
+  void a0() { }
+  void a1() { }
+  void a2() { }
+  void a3() { }
+  void a4() { }
+  void a5() { }
+  void a6() { }
+  void a7() { }
+  void a8() { }
+  void a9() { }
+  void a10() { }
+  void a11() { }
+  void a12() { }
+  void a13() { }
+  void a14() { }
+  void a15() { }
+  void a16() { }
+  void a17() { }
+  void a18() { }
+  void a19() { }
+  void a20() { }
+  void a21() { }
+  void a22() { }
+  void a23() { }
+  void a24() { }
+  void a25() { }
+  void a26() { }
+  int z = 0;
+}
+
+int inscrutable(int x) => x == 0 ? 0 : x | inscrutable(x & (x - 1));
+
+main() {
+  setup();
+  var both = [makeA(), new B()];
+  var x = both[inscrutable(0)];
+  // Each of these will throw, because an instance of A doesn't have any of
+  // these functions.  The important thing is that none of them have been
+  // renamed to be called 'z' by the minifier, because then the getter will be
+  // hit.
+  try { x.a(); } catch(e) { }
+  try { x.a0(); } catch(e) { }
+  try { x.a1(); } catch(e) { }
+  try { x.a2(); } catch(e) { }
+  try { x.a3(); } catch(e) { }
+  try { x.a4(); } catch(e) { }
+  try { x.a5(); } catch(e) { }
+  try { x.a6(); } catch(e) { }
+  try { x.a7(); } catch(e) { }
+  try { x.a8(); } catch(e) { }
+  try { x.a9(); } catch(e) { }
+  try { x.a10(); } catch(e) { }
+  try { x.a11(); } catch(e) { }
+  try { x.a12(); } catch(e) { }
+  try { x.a13(); } catch(e) { }
+  try { x.a14(); } catch(e) { }
+  try { x.a15(); } catch(e) { }
+  try { x.a16(); } catch(e) { }
+  try { x.a17(); } catch(e) { }
+  try { x.a18(); } catch(e) { }
+  try { x.a19(); } catch(e) { }
+  try { x.a20(); } catch(e) { }
+  try { x.a21(); } catch(e) { }
+  try { x.a12(); } catch(e) { }
+  try { x.a23(); } catch(e) { }
+  try { x.a24(); } catch(e) { }
+  try { x.a25(); } catch(e) { }
+  try { x.a26(); } catch(e) { }
+  Expect.equals(0, x.gettersCalled);
+  Expect.equals(42, x.z);
+  Expect.equals(1, x.gettersCalled);
+}
+
diff --git a/tests/compiler/dart2js_native/native_literal_class_frog_test.dart b/tests/compiler/dart2js_native/native_literal_class_frog_test.dart
deleted file mode 100644
index fc6d8a0..0000000
--- a/tests/compiler/dart2js_native/native_literal_class_frog_test.dart
+++ /dev/null
@@ -1,22 +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.
-
-class A native "= {log: function() { return 42 } }" {
-  void log() native;
-}
-
-getA() native """
-  return A;
-""";
-
-bar() {
-  new A();
-}
-
-main() {
-  var a = getA();
-  // Make a call to bar to make sure A gets generated.
-  if (a is int) bar();
-  Expect.equals(42, a.log());
-}
diff --git a/tests/compiler/dart2js_native/native_named_constructors2_frog_test.dart b/tests/compiler/dart2js_native/native_named_constructors2_frog_test.dart
index bd09643..fbdd8fb 100644
--- a/tests/compiler/dart2js_native/native_named_constructors2_frog_test.dart
+++ b/tests/compiler/dart2js_native/native_named_constructors2_frog_test.dart
@@ -11,7 +11,8 @@
 
   factory A.fromString(String s)  => _construct(s.length);
 
-  factory A.nativeConstructor(int a, int b) native r'return makeA(a+b);';
+  // Only functions with zero parameters are allowed with "native r'...'".
+  factory A.nativeConstructor() native r'return makeA(102);';
 
   static A _construct(v) { return makeA(v); }
 
@@ -30,7 +31,7 @@
   setup();
   var a1 = new A(100);
   var a2 = new A.fromString('Hello');
-  var a3 = new A.nativeConstructor(100, 2);
+  var a3 = new A.nativeConstructor();
 
   Expect.equals(100, a1.foo());
   Expect.equals(5, a2.foo());
diff --git a/tests/compiler/dart2js_native/native_named_constructors3_frog_test.dart b/tests/compiler/dart2js_native/native_named_constructors3_frog_test.dart
index 0cf12fa..e13fd46 100644
--- a/tests/compiler/dart2js_native/native_named_constructors3_frog_test.dart
+++ b/tests/compiler/dart2js_native/native_named_constructors3_frog_test.dart
@@ -14,7 +14,8 @@
 
   factory A.fromString(String s)  => makeA(s.length);
 
-  factory A.nativeConstructor(int a, int b) native r'return makeA(a+b);';
+  // Only functions with zero parameters are allowed with "native r'...'".
+  factory A.nativeConstructor() native r'return makeA(102);';
 
   foo() native 'return this._x;';
 }
@@ -31,7 +32,7 @@
   setup();
   var a1 = new A(100);
   var a2 = new A.fromString('Hello');
-  var a3 = new A.nativeConstructor(100, 2);
+  var a3 = new A.nativeConstructor();
 
   Expect.equals(100, a1.foo());
   Expect.equals(5, a2.foo());
diff --git a/tests/compiler/dart2js_native/native_parameter_names_frog_test.dart b/tests/compiler/dart2js_native/native_parameter_names_frog_test.dart
deleted file mode 100644
index bcf6cec..0000000
--- a/tests/compiler/dart2js_native/native_parameter_names_frog_test.dart
+++ /dev/null
@@ -1,26 +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 that parameters in native methods are not mangled. This test is needed
-// until we change all libraries to using the JS foreign element.
-
-class A native "*A" {
-  foo(name) native "return name;";
-  bar(undefined) native "return undefined;";
-}
-
-A makeA() native;
-
-void setup() native """
-function A() {}
-makeA = function(){return new A;};
-""";
-
-
-main() {
-  setup();
-  A a = makeA();
-  Expect.equals(42, a.foo(42));
-  Expect.equals(42, a.bar(42));
-}
diff --git a/tests/compiler/dart2js_native/native_property_frog_test.dart b/tests/compiler/dart2js_native/native_property_frog_test.dart
index 61b4808..ef03e3e 100644
--- a/tests/compiler/dart2js_native/native_property_frog_test.dart
+++ b/tests/compiler/dart2js_native/native_property_frog_test.dart
@@ -7,8 +7,8 @@
 class A native "*A" {
 
   // Setters and getters should be similar to these methods:
-  int getX() native 'return this._x;';
-  void setX(int value) native 'this._x = value;';
+  int getX() => JS('int', '#._x', this);
+  void setX(int value) { JS('void', '#._x = #', this, value); }
 
   int get X() native;
   set X(int value) native;
@@ -16,8 +16,8 @@
   int get Y() native;
   set Y(int value) native;
 
-  int get Z() native 'return this._z;';
-  set Z(int value) native 'this._z = value;';
+  int get Z => JS('int', '#._z', this);
+  set Z(int value) { JS('void', '#._z = #', this, value); }
 }
 
 A makeA() native { return new A(); }
diff --git a/tests/compiler/dart2js_native/native_wrapping_function2_frog_test.dart b/tests/compiler/dart2js_native/native_wrapping_function2_frog_test.dart
deleted file mode 100644
index 004bfca..0000000
--- a/tests/compiler/dart2js_native/native_wrapping_function2_frog_test.dart
+++ /dev/null
@@ -1,40 +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.
-
-typedef void Callback0();
-typedef void Callback1(arg1);
-typedef void Callback2(arg1, arg2);
-
-class A native "*A" {
-  foo0(Callback0 closure) native "return closure();";
-  foo1(Callback1 closure, arg1) native "return closure(arg1);";
-  foo2(Callback2 closure, arg1, arg2) native "return closure(arg1, arg2);";
-  foo3([Callback0 closure]) native
-      "return closure == (void 0) ? 42 : closure();";
-}
-
-makeA() native;
-
-void setup() native """
-function A() {}
-makeA = function(){return new A;};
-""";
-
-
-main() {
-  setup();
-  var a = makeA();
-  Expect.equals(42, a.foo0(() => 42));
-  Expect.equals(43, a.foo1((arg1) => arg1, 43));
-  Expect.equals(44, a.foo2((arg1, arg2) => arg1 + arg2, 21, 23));
-  Expect.equals(42, a.foo3());
-  Expect.equals(43, a.foo3(() => 43));
-
-  A aa = a;
-  Expect.equals(42, aa.foo0(() => 42));
-  Expect.equals(43, aa.foo1((arg1) => arg1, 43));
-  Expect.equals(44, aa.foo2((arg1, arg2) => arg1 + arg2, 21, 23));
-  Expect.equals(42, aa.foo3());
-  Expect.equals(43, aa.foo3(() => 43));
-}
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 2843f20..3ad08b4 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -9,8 +9,6 @@
 *dartc_test: Skip
 compare_to2_test: Fail    # Bug 4018
 null_test: Fail           # Bug 5511
-apply_test: Fail # Bug 5670
-apply2_test: Fail # Bug 5670
 
 [ $runtime == ff || $runtime == ie9 || $runtime == jsshell ]
 unicode_test: Fail
@@ -20,6 +18,7 @@
 
 [ $runtime == opera ]
 core_runtime_types_test: Fail
+null_nosuchmethod_test: Fail # Issue: 7413
 date_time7_test: Fail
 unicode_test: Fail
 
@@ -56,7 +55,7 @@
 *: Fail, Pass # TODO(ahe): Triage these tests.
 
 [ $compiler == dart2js && $runtime == safari ]
-null_nosuchmethod_test: Fail # TODO(ahe): Please triage this failure.
+null_nosuchmethod_test: Fail # Issue: 7414
 core_runtime_types_test: Fail
 
 [ $compiler == dart2js && $runtime == ie9 ]
@@ -65,8 +64,6 @@
 string_base_vm_test: Fail # BUG(3304): Maybe this doesn't time out?
 
 [ $compiler == dart2dart ]
-apply_test: Fail # inherited from VM
-apply2_test: Fail # inherited from VM
 compare_to2_test: Fail # inherited from VM
 null_test: Fail # inherited from VM
 unicode_test: Fail # inherited from VM
diff --git a/tests/corelib/string_buffer_test.dart b/tests/corelib/string_buffer_test.dart
index fac6560..5fcde73 100644
--- a/tests/corelib/string_buffer_test.dart
+++ b/tests/corelib/string_buffer_test.dart
@@ -63,8 +63,6 @@
       bf.add("");
     }
     Expect.equals("", bf.toString());
-
-    Expect.equals(bf, bf.add("foo"));
   }
 
   static testLength() {
@@ -95,8 +93,6 @@
 
     bf.addAll(["", "", ""]);
     Expect.equals("foobarabc", bf.toString());
-
-    Expect.equals(bf, bf.addAll(["foo"]));
   }
 
   static testClear() {
@@ -112,8 +108,6 @@
     bf.clear();
     Expect.equals("", bf.toString());
     Expect.equals(0, bf.length);
-
-    Expect.equals(bf, bf.clear());
   }
 
   static testToString() {
@@ -132,11 +126,11 @@
     StringBuffer bf = new StringBuffer("");
     StringBuffer bf2 = new StringBuffer("");
     bf2.add("bf2");
-    bf.add("foo")
-      .add("bar")
-      .add(bf2)
-      .add(bf2)
-      .add("toto");
+    bf..add("foo")
+      ..add("bar")
+      ..add(bf2)
+      ..add(bf2)
+      ..add("toto");
     Expect.equals("foobarbf2bf2toto", bf.toString());
   }
 
diff --git a/tests/html/callbacks_test.dart b/tests/html/callbacks_test.dart
index b4c55fa..e1aa779 100644
--- a/tests/html/callbacks_test.dart
+++ b/tests/html/callbacks_test.dart
@@ -6,6 +6,6 @@
 main() {
   useHtmlConfiguration();
   test('RequestAnimationFrameCallback', () {
-    window.requestAnimationFrame((int time) => false);
+    window.requestAnimationFrame((num time) => false);
   });
 }
diff --git a/tests/html/canvas_test.dart b/tests/html/canvas_test.dart
index 3f6e700..56994f0 100644
--- a/tests/html/canvas_test.dart
+++ b/tests/html/canvas_test.dart
@@ -27,6 +27,26 @@
     data[100] = 200;
     expect(data[100], equals(200));
   });
+
+  test('toDataUrl', () {
+    var canvas = new CanvasElement(width: 100, height: 100);
+    var context = canvas.context2d;
+    context.fillStyle = 'red';
+    context.fill();
+
+    var url = canvas.toDataUrl('image/png');
+
+    var img = new ImageElement();
+    img.on.load.add(expectAsync1((_) {
+      expect(img.complete, true);
+    }));
+    img.on.error.add((_) {
+      guardAsync(() {
+        expect(true, isFalse, reason: 'URL failed to load.');
+      });
+    });
+    img.src = url;
+  });
 }
 
 void checkPixel(Uint8ClampedArray data, int offset, List<int> rgba)
diff --git a/tests/html/canvasrenderingcontext2d_test.dart b/tests/html/canvasrenderingcontext2d_test.dart
index 4a95b05..1e77f6c 100644
--- a/tests/html/canvasrenderingcontext2d_test.dart
+++ b/tests/html/canvasrenderingcontext2d_test.dart
@@ -7,6 +7,14 @@
 import '../../pkg/unittest/lib/html_config.dart';
 import 'dart:html';
 
+// Some rounding errors in the browsers.
+checkPixel(Uint8ClampedArray pixel, List<int> expected) {
+  expect(pixel[0], closeTo(expected[0], 1));
+  expect(pixel[1], closeTo(expected[1], 1));
+  expect(pixel[2], closeTo(expected[2], 1));
+  expect(pixel[3], closeTo(expected[3], 1));
+}
+
 main() {
   useHtmlConfiguration();
   var canvas = new CanvasElement();
@@ -41,12 +49,7 @@
   test('setFillColorHsl sat', () {
     context.setFillColorHsl(0, 0, 50);
     context.fillRect(0, 0, canvas.width, canvas.height);
-    var pixel = readPixel();
-    // Some rounding errors in the browsers.
-    expect(pixel[0], closeTo(127, 1));
-    expect(pixel[1], closeTo(127, 1));
-    expect(pixel[2], closeTo(127, 1));
-    expect(pixel[3], 255);
+    checkPixel(readPixel(), [127, 127, 127, 255]);
   });
 
   test('setStrokeColorRgb', () {
@@ -74,12 +77,7 @@
     context.setStrokeColorHsl(0, 0, 50);
     context.lineWidth = 10;
     context.strokeRect(0, 0, canvas.width, canvas.height);
-    var pixel = readPixel();
-    // Some rounding errors in the browsers.
-    expect(pixel[0], closeTo(127, 1));
-    expect(pixel[1], closeTo(127, 1));
-    expect(pixel[2], closeTo(127, 1));
-    expect(pixel[3], 255);
+    checkPixel(readPixel(), [127, 127, 127, 255]);
   });
 
   test('fillStyle', () {
diff --git a/tests/html/contentelement_test.dart b/tests/html/contentelement_test.dart
deleted file mode 100644
index b7911eb..0000000
--- a/tests/html/contentelement_test.dart
+++ /dev/null
@@ -1,20 +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 contentelement_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
-import 'dart:html';
-
-main() {
-  useHtmlConfiguration();
-
-  var isContentElement =
-      predicate((x) => x is ContentElement, 'is a ContentElement');
-
-  test('constructor', () {
-      var e = new ContentElement();
-      expect(e, isContentElement);
-    });
-}
diff --git a/tests/html/cross_frame_test.dart b/tests/html/cross_frame_test.dart
index b5d9144..dd5b4be 100644
--- a/tests/html/cross_frame_test.dart
+++ b/tests/html/cross_frame_test.dart
@@ -6,31 +6,31 @@
 main() {
   useHtmlConfiguration();
 
+  var isWindowBase = predicate((x) => x is WindowBase, 'is a WindowBase');
   var isWindow = predicate((x) => x is Window, 'is a Window');
-  var isLocalWindow = predicate((x) => x is LocalWindow, 'is a LocalWindow');
-  var isLocation = predicate((x) => x is Location, 'is a Location');
-  var isLocalLocation =
-      predicate((x) => x is LocalLocation, 'is a LocalLocation');
+  var isLocationBase = predicate((x) => x is LocationBase, 'is a LocationBase');
+  var isLocation =
+      predicate((x) => x is Location, 'is a Location');
+  var isHistoryBase = predicate((x) => x is HistoryBase, 'is a HistoryBase');
   var isHistory = predicate((x) => x is History, 'is a History');
-  var isLocalHistory = predicate((x) => x is LocalHistory, 'is a LocalHistory');
 
   final iframe = new Element.tag('iframe');
   document.body.nodes.add(iframe);
 
   test('window', () {
-      expect(window, isLocalWindow);
+      expect(window, isWindow);
       expect(window.document, document);
     });
 
   test('iframe', () {
       final frameWindow = iframe.contentWindow;
-      expect(frameWindow, isWindow);
+      expect(frameWindow, isWindowBase);
       //TODO(gram) The next test should be written as:
-      //    expect(frameWindow, isNot(isLocalWindow));
+      //    expect(frameWindow, isNot(isWindow));
       // but that will cause problems now until is/is! work
       // properly in dart2js instead of always returning true.
-      expect(frameWindow is! LocalWindow, isTrue);
-      expect(frameWindow.parent, isLocalWindow);
+      expect(frameWindow is! Window, isTrue);
+      expect(frameWindow.parent, isWindow);
 
       // Ensure that the frame's document is inaccessible via window.
       expect(() => frameWindow.document, throws);
@@ -42,27 +42,27 @@
     });
 
   test('location', () {
-      expect(window.location, isLocalLocation);
+      expect(window.location, isLocation);
       final frameLocation = iframe.contentWindow.location;
-      expect(frameLocation, isLocation);
+      expect(frameLocation, isLocationBase);
       // TODO(gram) Similar to the above, the next test should be:
-      //     expect(frameLocation, isNot(isLocalLocation));
-      expect(frameLocation is! LocalLocation, isTrue);
+      //     expect(frameLocation, isNot(isLocation));
+      expect(frameLocation is! Location, isTrue);
 
       expect(() => frameLocation.href, throws);
       expect(() => frameLocation.hash, throws);
 
       final frameParentLocation = iframe.contentWindow.parent.location;
-      expect(frameParentLocation, isLocalLocation);
+      expect(frameParentLocation, isLocation);
     });
 
   test('history', () {
-      expect(window.history, isLocalHistory);
+      expect(window.history, isHistory);
       final frameHistory = iframe.contentWindow.history;
-      expect(frameHistory, isHistory);
+      expect(frameHistory, isHistoryBase);
       // See earlier comments.
-      //expect(frameHistory, isNot(isLocalHistory));
-      expect(frameHistory is! LocalHistory, isTrue);
+      //expect(frameHistory, isNot(isHistory));
+      expect(frameHistory is! History, isTrue);
 
       // Valid methods.
       frameHistory.forward();
@@ -70,6 +70,6 @@
       expect(() => frameHistory.length, throws);
 
       final frameParentHistory = iframe.contentWindow.parent.history;
-      expect(frameParentHistory, isLocalHistory);
+      expect(frameParentHistory, isHistory);
     });
 }
diff --git a/tests/html/datalistelement_test.dart b/tests/html/datalistelement_test.dart
index 7b41aad..b7fe779 100644
--- a/tests/html/datalistelement_test.dart
+++ b/tests/html/datalistelement_test.dart
@@ -34,26 +34,36 @@
       document.body.nodes.removeLast();
     });
 
+  // Support is checked in element_types test.
+  var expectation = DataListElement.supported ? returnsNormally : throws;
 
   test('is', () {
+    expect(() {
       var list = document.query('#browsers');
       expect(list, isDataListElement);
+    }, expectation);
   });
 
   test('list', () {
+    expect(() {
       var list = document.query('#browsers');
       var input = document.query('#input');
       expect(input.list, list);
+    }, expectation);
   });
 
   test('options', () {
+    expect(() {
       var options = document.query('#browsers')
           .queryAll('option');  // Uses DataListElement.
       expect(options.length, 5);
+    }, expectation);
   });
 
   test('create', () {
+    expect(() {
       var list = new DataListElement();
       expect(list, isDataListElement);
-    });
+    }, expectation);
+  });
 }
diff --git a/tests/html/documentfragment_test.dart b/tests/html/documentfragment_test.dart
index 13abe54..257f9c6 100644
--- a/tests/html/documentfragment_test.dart
+++ b/tests/html/documentfragment_test.dart
@@ -5,8 +5,8 @@
 library DocumentFragmentTest;
 import '../../pkg/unittest/lib/unittest.dart';
 import '../../pkg/unittest/lib/html_config.dart';
+import 'util.dart';
 import 'dart:html';
-part 'util.dart';
 
 main() {
   useHtmlConfiguration();
diff --git a/tests/html/element_add_test.dart b/tests/html/element_add_test.dart
index ece267d..2ec51db 100644
--- a/tests/html/element_add_test.dart
+++ b/tests/html/element_add_test.dart
@@ -5,8 +5,8 @@
 library ElementAddTest;
 import '../../pkg/unittest/lib/unittest.dart';
 import '../../pkg/unittest/lib/html_config.dart';
+import 'util.dart';
 import 'dart:html';
-part 'util.dart';
 
 main() {
   useHtmlConfiguration();
diff --git a/tests/html/element_test.dart b/tests/html/element_test.dart
index 6825c91..63b5867 100644
--- a/tests/html/element_test.dart
+++ b/tests/html/element_test.dart
@@ -45,14 +45,6 @@
   }
 }
 
-void testConstructorHelper(String tag, String htmlSnippet,
-    String expectedText, Function isExpectedClass) {
-  expect(isExpectedClass(new Element.tag(tag)), isTrue);
-  final elementFromSnippet = new Element.html(htmlSnippet);
-  expect(isExpectedClass(elementFromSnippet), isTrue);
-  expect(elementFromSnippet.text, expectedText);
-}
-
 main() {
   useHtmlIndividualConfiguration();
 
@@ -104,52 +96,6 @@
     container.remove();
   });
 
-  group('additionalConstructors', () {
-    test('blockquote', () => testConstructorHelper('blockquote',
-        '<blockquote>foo</blockquote>', 'foo',
-        (element) => element is QuoteElement));
-    test('body', () => testConstructorHelper('body',
-        '<body><div>foo</div></body>', 'foo',
-        (element) => element is BodyElement));
-    test('head', () => testConstructorHelper('head',
-        '<head><script>foo;</script></head>', 'foo;',
-        (element) => element is HeadElement));
-    test('optgroup', () => testConstructorHelper('optgroup',
-        '<optgroup>foo</optgroup>', 'foo',
-        (element) => element is OptGroupElement));
-    test('option', () => testConstructorHelper('option',
-        '<option>foo</option>', 'foo',
-        (element) => element is OptionElement));
-    test('output', () => testConstructorHelper('output',
-        '<output>foo</output>', 'foo',
-        (element) => element is OutputElement));
-    test('progress', () => testConstructorHelper('progress',
-        '<progress>foo</progress>', 'foo',
-        (element) => element is ProgressElement));
-    test('caption', () => testConstructorHelper('caption',
-        '<caption>foo</caption>', 'foo',
-        (element) => element is TableCaptionElement));
-    test('td', () => testConstructorHelper('td', '<td>foo</td>', 'foo',
-        (element) => element is TableCellElement));
-    test('colgroup', () => testConstructorHelper('colgroup',
-        '<colgroup></colgroup>', '',
-        (element) => element is TableColElement));
-    test('col', () => testConstructorHelper('col', '<col></col>', '',
-        (element) => element is TableColElement));
-    test('tr', () => testConstructorHelper('tr',
-        '<tr><td>foo</td></tr>', 'foo',
-        (element) => element is TableRowElement));
-    test('tbody', () => testConstructorHelper('tbody',
-        '<tbody><tr><td>foo</td></tr></tbody>', 'foo',
-        (element) => element is TableSectionElement));
-    test('tfoot', () => testConstructorHelper('tfoot',
-        '<tfoot><tr><td>foo</td></tr></tfoot>', 'foo',
-        (element) => element is TableSectionElement));
-    test('thead', () => testConstructorHelper('thead',
-        '<thead><tr><td>foo</td></tr></thead>', 'foo',
-        (element) => element is TableSectionElement));
-  });
-
   group('constructors', () {
     test('error', () {
       expect(() => new Element.html('<br/><br/>'), throwsArgumentError);
@@ -157,131 +103,6 @@
 
     test('.html has no parent', () =>
         expect(new Element.html('<br/>').parent, isNull));
-
-    test('a', () => testConstructorHelper('a', '<a>foo</a>', 'foo',
-        (element) => element is AnchorElement));
-    test('area', () => testConstructorHelper('area', '<area>foo</area>', '',
-        (element) => element is AreaElement));
-    // TODO(jacobr): audio tags cause tests to segfault when using dartium.
-    // b/5522106.
-    // test('audio', () => testConstructorHelper('audio',
-    //     '<audio>foo</audio>', 'foo',
-    //     (element) => element is AudioElement));
-    test('br', () => testConstructorHelper('br', '<br>', '',
-        (element) => element is BRElement));
-    test('base', () => testConstructorHelper('base', '<base>foo</base>', '',
-        (element) => element is BaseElement));
-    test('button', () => testConstructorHelper('button',
-        '<button>foo</button>', 'foo',
-        (element) => element is ButtonElement));
-    test('canvas', () => testConstructorHelper('canvas',
-        '<canvas>foo</canvas>', 'foo',
-        (element) => element is CanvasElement));
-    test('dl', () => testConstructorHelper('dl', '<dl>foo</dl>', 'foo',
-        (element) => element is DListElement));
-    // TODO(jacobr): WebKit doesn't yet support the DataList class.
-    // test('datalist', () => testConstructorHelper('datalist',
-    //     '<datalist>foo</datalist>', 'foo',
-    //     (element) => element is DataListElement));
-    test('div', () => testConstructorHelper('div', '<div>foo</div>', 'foo',
-        (element) => element is DivElement));
-    test('fieldset', () => testConstructorHelper('fieldset',
-        '<fieldset>foo</fieldset>', 'foo',
-        (element) => element is FieldSetElement));
-    test('font', () => testConstructorHelper('font', '<font>foo</font>', 'foo',
-        (element) => element is FontElement));
-    test('form', () => testConstructorHelper('form', '<form>foo</form>', 'foo',
-        (element) => element is FormElement));
-    test('hr', () => testConstructorHelper('hr', '<hr>', '',
-        (element) => element is HRElement));
-    test('h1', () => testConstructorHelper('h1', '<h1>foo</h1>', 'foo',
-        (element) => element is HeadingElement));
-    test('h2', () => testConstructorHelper('h2', '<h2>foo</h2>', 'foo',
-        (element) => element is HeadingElement));
-    test('h3', () => testConstructorHelper('h3', '<h3>foo</h3>', 'foo',
-        (element) => element is HeadingElement));
-    test('h4', () => testConstructorHelper('h4', '<h4>foo</h4>', 'foo',
-        (element) => element is HeadingElement));
-    test('h5', () => testConstructorHelper('h5', '<h5>foo</h5>', 'foo',
-        (element) => element is HeadingElement));
-    test('h6', () => testConstructorHelper('h6', '<h6>foo</h6>', 'foo',
-        (element) => element is HeadingElement));
-    test('iframe', () => testConstructorHelper('iframe',
-        '<iframe>foo</iframe>', 'foo',
-        (element) => element is IFrameElement));
-    test('img', () => testConstructorHelper('img', '<img>', '',
-        (element) => element is ImageElement));
-    test('input', () => testConstructorHelper('input', '<input/>', '',
-        (element) => element is InputElement));
-    test('li', () => testConstructorHelper('li', '<li>foo</li>', 'foo',
-        (element) => element is LIElement));
-    test('label', () => testConstructorHelper('label',
-        '<label>foo</label>', 'foo',
-        (element) => element is LabelElement));
-    test('legend', () => testConstructorHelper('legend',
-        '<legend>foo</legend>', 'foo',
-        (element) => element is LegendElement));
-    test('link', () => testConstructorHelper('link', '<link>', '',
-        (element) => element is LinkElement));
-    test('map', () => testConstructorHelper('map', '<map>foo</map>', 'foo',
-        (element) => element is MapElement));
-    test('menu', () => testConstructorHelper('menu', '<menu>foo</menu>', 'foo',
-        (element) => element is MenuElement));
-    test('meta', () => testConstructorHelper('meta', '<meta>', '',
-        (element) => element is MetaElement));
-    test('del', () => testConstructorHelper('del', '<del>foo</del>', 'foo',
-        (element) => element is ModElement));
-    test('ins', () => testConstructorHelper('ins', '<ins>foo</ins>', 'foo',
-        (element) => element is ModElement));
-    test('ol', () => testConstructorHelper('ol', '<ol>foo</ol>', 'foo',
-        (element) => element is OListElement));
-    test('p', () => testConstructorHelper('p', '<p>foo</p>', 'foo',
-        (element) => element is ParagraphElement));
-    test('param', () => testConstructorHelper('param', '<param>', '',
-        (element) => element is ParamElement));
-    test('pre', () => testConstructorHelper('pre', '<pre>foo</pre>', 'foo',
-        (element) => element is PreElement));
-    test('q', () => testConstructorHelper('q', '<q>foo</q>', 'foo',
-        (element) => element is QuoteElement));
-    test('script', () => testConstructorHelper('script',
-        '<script>foo</script>', 'foo',
-        (element) => element is ScriptElement));
-    test('select', () => testConstructorHelper('select',
-        '<select>foo</select>', 'foo',
-        (element) => element is SelectElement));
-    // TODO(jacobr): audio tags cause tests to segfault when using dartium.
-    // b/5522106.
-    // test('source', () => testConstructorHelper('source', '<source>', '',
-    //                      (element) => element is SourceElement));
-    test('span', () => testConstructorHelper('span', '<span>foo</span>', 'foo',
-        (element) => element is SpanElement));
-    test('style', () => testConstructorHelper('style',
-        '<style>foo</style>', 'foo',
-        (element) => element is StyleElement));
-    test('table', () => testConstructorHelper('table',
-        '<table><caption>foo</caption></table>', 'foo',
-        (element) => element is TableElement));
-    test('textarea', () => testConstructorHelper('textarea',
-        '<textarea>foo</textarea>', 'foo',
-        (element) => element is TextAreaElement));
-    test('title', () => testConstructorHelper('title',
-        '<title>foo</title>', 'foo',
-        (element) => element is TitleElement));
-    // TODO(jacobr): audio tags cause tests to segfault when using dartium.
-    // b/5522106.
-    // test('track', () => testConstructorHelper('track', '<track>', '',
-    //                      (element) => element is TrackElement));
-    test('ul', () => testConstructorHelper('ul', '<ul>foo</ul>', 'foo',
-        (element) => element is UListElement));
-    // TODO(jacobr): video tags cause tests to segfault when using dartium.
-    // b/5522106.
-    // test('video', () => testConstructorHelper('video',
-    //     '<video>foo</video>', 'foo',
-    //     (element) => element is VideoElement));
-    // TODO(jacobr): this test is broken until Dartium fixes b/5521083
-    // test('someunknown', () => testConstructorHelper('someunknown',
-    //     '<someunknown>foo</someunknown>', 'foo',
-    //     (element) => element is UnknownElement));
   });
 
   group('eventListening', () {
@@ -307,9 +128,6 @@
       testEventHelper(on.change, 'change',
           (listener) => Testing.addEventListener(
               element, 'change', listener, true));
-      testEventHelper(on.click, 'click',
-          (listener) => Testing.addEventListener(
-              element, 'click', listener, true));
       testEventHelper(on.contextMenu, 'contextmenu',
           (listener) => Testing.addEventListener(
               element, 'contextmenu', listener, true));
@@ -421,6 +239,23 @@
       testEventHelper(on.touchStart, 'touchstart',
           (listener) => Testing.addEventListener(
               element, 'touchstart', listener, true));
+      testEventHelper(on.transitionEnd, 'webkitTransitionEnd');
+      testEventHelper(on.fullscreenChange, 'webkitfullscreenchange',
+          (listener) => Testing.addEventListener(element,
+             'webkitfullscreenchange', listener, true));
+    });
+  });
+
+  group('click', () {
+    test('clickEvent', () {
+      var e = new DivElement();
+      var firedEvent = false;
+      e.on.click.add((event) {
+        firedEvent = true;
+      });
+      expect(firedEvent, false);
+      e.click();
+      expect(firedEvent, true);
     });
   });
 
@@ -439,7 +274,7 @@
                </div>''');
         final attributes = element.attributes;
         expect(attributes['class'], 'foo');
-        expect(attributes['style'], 'overflow: hidden');
+        expect(attributes['style'], startsWith('overflow: hidden'));
         expect(attributes['data-foo'], 'bar');
         expect(attributes['data-foo2'], 'bar2');
         expect(attributes.length, 5);
@@ -470,7 +305,7 @@
           '''<svg xmlns="http://www.w3.org/2000/svg"
                   xmlns:xlink="http://www.w3.org/1999/xlink">
             <image xlink:href="foo" data-foo="bar"/>
-          </svg>''').elements[0];
+          </svg>''').children[0];
 
         var attributes = element.attributes;
         expect(attributes.length, 1);
diff --git a/tests/html/element_types_test.dart b/tests/html/element_types_test.dart
new file mode 100644
index 0000000..acc20b1
--- /dev/null
+++ b/tests/html/element_types_test.dart
@@ -0,0 +1,310 @@
+// 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 element_types;
+import '../../pkg/unittest/lib/unittest.dart';
+import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'dart:html';
+
+main() {
+  useHtmlIndividualConfiguration();
+
+  group('supported_content', () {
+    test('supported', () {
+      expect(ContentElement.supported, true);
+    });
+  });
+
+  group('supported_datalist', () {
+    test('supported', () {
+      expect(DataListElement.supported, true);
+    });
+  });
+
+  group('supported_details', () {
+    test('supported', () {
+      expect(DetailsElement.supported, true);
+    });
+  });
+
+  group('supported_embed', () {
+    test('supported', () {
+      expect(EmbedElement.supported, true);
+    });
+  });
+
+  group('supported_keygen', () {
+    test('supported', () {
+      expect(KeygenElement.supported, true);
+    });
+  });
+
+  group('supported_meter', () {
+    test('supported', () {
+      expect(MeterElement.supported, true);
+    });
+  });
+
+  group('supported_object', () {
+    test('supported', () {
+      expect(MeterElement.supported, true);
+    });
+  });
+
+  group('supported_output', () {
+    test('supported', () {
+      expect(OutputElement.supported, true);
+    });
+  });
+
+  group('supported_progress', () {
+    test('supported', () {
+      expect(ProgressElement.supported, true);
+    });
+  });
+
+  group('supported_shadow', () {
+    test('supported', () {
+      expect(ShadowElement.supported, true);
+    });
+  });
+
+  group('supported_track', () {
+    test('supported', () {
+      expect(TrackElement.supported, true);
+    });
+  });
+
+  group('constructors', () {
+    test('a', () {
+      expect((new AnchorElement()) is AnchorElement, true);
+    });
+    test('area', () {
+      expect((new AreaElement()) is AreaElement, true);
+    });
+    test('audio', () {
+      expect((new AudioElement()) is AudioElement, true);
+    });
+    test('body', () {
+      expect((new BodyElement()) is BodyElement, true);
+    });
+    test('br', () {
+      expect((new BRElement()) is BRElement, true);
+    });
+    test('base', () {
+      expect((new BaseElement()) is BaseElement, true);
+    });
+    test('button', () {
+      expect((new ButtonElement()) is ButtonElement, true);
+    });
+    test('canvas', () {
+      expect((new CanvasElement()) is CanvasElement, true);
+    });
+    test('caption', () {
+      expect((new TableCaptionElement()) is TableCaptionElement, true);
+    });
+    test('content', () {
+      expect((new ContentElement()) is ContentElement,
+          ContentElement.supported);
+    });
+    test('details', () {
+      expect((new DetailsElement()) is DetailsElement,
+          DetailsElement.supported);
+    });
+    test('dl', () {
+      expect((new DListElement()) is DListElement, true);
+    });
+    test('datalist', () {
+      expect((new DataListElement()) is DataListElement,
+          DataListElement.supported);
+    });
+    test('div', () {
+      expect((new DivElement()) is DivElement, true);
+    });
+    test('embed', () {
+      expect((new EmbedElement()) is EmbedElement, EmbedElement.supported);
+    });
+    test('fieldset', () {
+      expect((new FieldSetElement()) is FieldSetElement, true);
+    });
+    test('font', () {
+      expect((new Element.tag('font')) is FontElement, true);
+    });
+    test('form', () {
+      expect((new FormElement()) is FormElement, true);
+    });
+    test('frame', () {
+      expect((new Element.tag('frame')) is FrameElement, true);
+    });
+    test('frameset', () {
+      expect((new Element.tag('frameset')) is FrameSetElement, true);
+    });
+    test('head', () {
+      expect((new HeadElement()) is HeadElement, true);
+    });
+    test('hr', () {
+      expect((new HRElement()) is HRElement, true);
+    });
+    test('html', () {
+      expect((new HtmlElement()) is HtmlElement, true);
+    });
+    test('h1', () {
+      expect((new HeadingElement.h1()) is HeadingElement, true);
+      expect(new Element.tag('h1') is HeadingElement, true);
+    });
+    test('h2', () {
+      expect((new HeadingElement.h2()) is HeadingElement, true);
+      expect(new Element.tag('h2') is HeadingElement, true);
+    });
+    test('h3', () {
+      expect((new HeadingElement.h3()) is HeadingElement, true);
+      expect(new Element.tag('h3') is HeadingElement, true);
+    });
+    test('h4', () {
+      expect((new HeadingElement.h4()) is HeadingElement, true);
+      expect(new Element.tag('h4') is HeadingElement, true);
+    });
+    test('h5', () {
+      expect((new HeadingElement.h5()) is HeadingElement, true);
+      expect(new Element.tag('h5') is HeadingElement, true);
+    });
+    test('h6', () {
+      expect((new HeadingElement.h6()) is HeadingElement, true);
+      expect(new Element.tag('h6') is HeadingElement, true);
+    });
+    test('iframe', () {
+      expect((new IFrameElement()) is IFrameElement, true);
+    });
+    test('img', () {
+      expect((new ImageElement()) is ImageElement, true);
+    });
+    test('input', () {
+      expect((new InputElement()) is InputElement, true);
+    });
+    test('keygen', () {
+      expect((new KeygenElement()) is KeygenElement, KeygenElement.supported);
+    });
+    test('li', () {
+      expect((new LIElement()) is LIElement, true);
+    });
+    test('label', () {
+      expect((new LabelElement()) is LabelElement, true);
+    });
+    test('legend', () {
+      expect((new LegendElement()) is LegendElement, true);
+    });
+    test('link', () {
+      expect((new LinkElement()) is LinkElement, true);
+    });
+    test('map', () {
+      expect((new MapElement()) is MapElement, true);
+    });
+    test('marquee', () {
+      expect((new Element.tag('marquee')) is MarqueeElement,
+          MarqueeElement.supported);
+    });
+    test('menu', () {
+      expect((new MenuElement()) is MenuElement, true);
+    });
+    test('meta', () {
+      expect((new Element.tag('meta')) is MetaElement, true);
+    });
+    test('meter', () {
+      expect((new Element.tag('meter')) is MeterElement, MeterElement.supported);
+    });
+    test('del', () {
+      expect((new Element.tag('del')) is ModElement, true);
+    });
+    test('ins', () {
+      expect((new Element.tag('ins')) is ModElement, true);
+    });
+    test('object', () {
+      expect((new ObjectElement()) is ObjectElement, ObjectElement.supported);
+    });
+    test('ol', () {
+      expect((new OListElement()) is OListElement, true);
+    });
+    test('optgroup', () {
+      expect((new OptGroupElement()) is OptGroupElement, true);
+    });
+    test('option', () {
+      expect((new OptionElement()) is OptionElement, true);
+    });
+    test('output', () {
+      expect((new OutputElement()) is OutputElement, OutputElement.supported);
+    });
+    test('p', () {
+      expect((new ParagraphElement()) is ParagraphElement, true);
+    });
+    test('param', () {
+      expect((new ParamElement()) is ParamElement, true);
+    });
+    test('pre', () {
+      expect((new PreElement()) is PreElement, true);
+    });
+    test('progress', () {
+      expect((new ProgressElement()) is ProgressElement,
+          ProgressElement.supported);
+    });
+    test('q', () {
+      expect((new Element.tag('q')) is QuoteElement, true);
+    });
+    test('script', () {
+      expect((new ScriptElement()) is ScriptElement, true);
+    });
+    test('select', () {
+      expect((new SelectElement()) is SelectElement, true);
+    });
+    test('shadow', () {
+      expect((new Element.tag('shadow')) is ShadowElement,
+          ShadowElement.supported);
+    });
+    test('source', () {
+      expect((new SourceElement()) is SourceElement, true);
+    });
+    test('span', () {
+      expect((new SpanElement()) is SpanElement, true);
+    });
+    test('style', () {
+      expect((new StyleElement()) is StyleElement, true);
+    });
+    test('table', () {
+      expect((new TableElement()) is TableElement, true);
+    });
+    test('textarea', () {
+      expect((new TextAreaElement()) is TextAreaElement, true);
+    });
+    test('title', () {
+      expect((new TitleElement()) is TitleElement, true);
+    });
+    test('td', () {
+      expect((new TableCellElement()) is TableCellElement, true);
+    });
+    test('col', () {
+      expect((new TableColElement()) is TableColElement, true);
+      expect((new Element.tag('colgroup')) is TableColElement, true);
+    });
+    test('tr', () {
+      expect((new TableRowElement()) is TableRowElement, true);
+    });
+    test('table section', () {
+      expect((new Element.tag('tbody')) is TableSectionElement, true);
+      expect((new Element.tag('tfoot')) is TableSectionElement, true);
+      expect((new Element.tag('thead')) is TableSectionElement, true);
+    });
+    test('track', () {
+      expect((new Element.tag('track')) is TrackElement,
+          TrackElement.supported);
+    });
+    test('ul', () {
+      expect((new UListElement()) is UListElement, true);
+    });
+    test('video', () {
+      expect((new VideoElement()) is VideoElement, true);
+    });
+    test('unknown', () {
+      expect((new Element.tag('someunknown')) is UnknownElement, true);
+    });;
+  });
+}
diff --git a/tests/html/element_webkit_test.dart b/tests/html/element_webkit_test.dart
deleted file mode 100644
index 4933d75..0000000
--- a/tests/html/element_webkit_test.dart
+++ /dev/null
@@ -1,80 +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.
-
-library ElementWebKitTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
-import 'dart:html';
-
-
-// NOTE:
-// These should ALL be webkit-specific items
-// Ideally all of these should be functional on all browsers and moved into
-// element_test.dart.
-
-void testConstructorHelper(String tag, String htmlSnippet,
-    String expectedText, Function isExpectedClass) {
-  expect(isExpectedClass(new Element.tag(tag)), true);
-  final elementFromSnippet = new Element.html(htmlSnippet);
-  expect(isExpectedClass(elementFromSnippet), true);
-  expect(expectedText, elementFromSnippet.text);
-}
-
-void testEventHelper(EventListenerList listenerList, type,
-    [Function registerOnEventListener = null]) {
-  bool firedWhenAddedToListenerList = false;
-  bool firedOnEvent = false;
-  listenerList.add((e) {
-    firedWhenAddedToListenerList = true;
-  });
-  if (registerOnEventListener != null) {
-    registerOnEventListener((e) {
-      firedOnEvent = true;
-    });
-  }
-
-  final event = new Event(type);
-  listenerList.dispatch(event);
-
-  expect(firedWhenAddedToListenerList, isTrue);
-  if (registerOnEventListener != null) {
-    expect(firedOnEvent, isTrue);
-  }
-}
-
-main() {
-  useHtmlConfiguration();
-
-  group('constructors', () {
-    test('details', () => testConstructorHelper('details',
-        '<details>foo</details>', 'foo',
-        (element) => element is DetailsElement));
-    test('embed', () => testConstructorHelper('embed',
-        '<embed>foo</embed>', '',
-        (element) => element is EmbedElement));
-    test('keygen', () => testConstructorHelper('keygen', '<keygen>', '',
-        (element) => element is KeygenElement));
-    test('marquee', () => testConstructorHelper('marquee',
-        '<marquee>foo</marquee>', 'foo',
-        (element) => element is MarqueeElement));
-    test('meter', () => testConstructorHelper('meter',
-        '<meter>foo</meter>', 'foo',
-        (element) => element is MeterElement));
-    test('object', () => testConstructorHelper('object',
-        '<object>foo</object>', 'foo',
-        (element) => element is ObjectElement));
-    });
-
-  group('events', () {
-    final element = new Element.tag('div');
-    final on = element.on;
-    testEventHelper(on.transitionEnd, 'webkitTransitionEnd');
-    testEventHelper(on.fullscreenChange, 'webkitfullscreenchange',
-        (listener) => Testing.addEventListener(element,
-            'webkitfullscreenchange', listener, true));
-  });
-}
-
-
-
diff --git a/tests/html/fileapi_test.dart b/tests/html/fileapi_test.dart
index 2b3b2a3..f7155b6 100644
--- a/tests/html/fileapi_test.dart
+++ b/tests/html/fileapi_test.dart
@@ -14,7 +14,7 @@
 main() {
   useHtmlConfiguration();
   test('getFileSystem', () {
-    window.webkitRequestFileSystem(LocalWindow.TEMPORARY, 100, expectAsync1(
+    window.webkitRequestFileSystem(Window.TEMPORARY, 100, expectAsync1(
       (FileSystem fileSystem) {
         fs = fileSystem;
       }),
diff --git a/tests/html/form_data_test.dart b/tests/html/form_data_test.dart
index 6ea5381..a8b96fd 100644
--- a/tests/html/form_data_test.dart
+++ b/tests/html/form_data_test.dart
@@ -8,6 +8,12 @@
 import '../../pkg/unittest/lib/html_config.dart';
 import 'dart:html';
 
+void fail(message) {
+  guardAsync(() {
+    expect(false, isTrue, reason: message);
+  });
+}
+
 void main() {
   // TODO(efortuna): This is a bad test. Revisit when we have tests that can run
   // both a server and fire up a browser.
@@ -43,4 +49,24 @@
         'text/plain');
     form.append('theBlob', blob, 'theBlob.txt');
   });
+
+  test('send', () {
+    var form = new FormData();
+    var blobString = 'Indescribable... Indestructible! Nothing can stop it!';
+    var blob = new Blob(
+        [blobString],
+        'text/plain');
+    form.append('theBlob', blob, 'theBlob.txt');
+
+    var xhr = new HttpRequest();
+    xhr.open("POST", "http://localhost:9876/echo");
+
+    xhr.on.load.add(expectAsync1((e) {
+      expect(xhr.responseText.contains(blobString), true);
+    }));
+    xhr.on.error.add((e) {
+      fail('$e');
+    });
+    xhr.send(form);
+  });
 }
diff --git a/tests/html/history_test.dart b/tests/html/history_test.dart
index 62dbc9c..462acb3 100644
--- a/tests/html/history_test.dart
+++ b/tests/html/history_test.dart
@@ -1,18 +1,67 @@
 library HistoryTest;
 import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import '../../pkg/unittest/lib/html_individual_config.dart';
 import 'dart:html';
 
-main() {
-  useHtmlConfiguration();
-  test('History', () {
-    window.history.pushState(null, document.title, '?foo=bar');
-    expect(window.history.length, equals(2));
-    window.history.back();
-    expect(window.location.href.endsWith('foo=bar'), isTrue);
+/// Waits for a callback once, then removes the event handler.
+void expectAsync1Once(EventListenerList list, void callback(arg)) {
+  var fn = null;
+  fn = expectAsync1((arg) {
+    list.remove(fn);
+    callback(arg);
+  });
+  list.add(fn);
+}
 
-    window.history.replaceState(null, document.title, '?foo=baz');
-    expect(window.history.length, equals(2));
-    expect(window.location.href.endsWith('foo=baz'), isTrue);
+main() {
+  useHtmlIndividualConfiguration();
+
+  group('supported_state', () {
+    test('supportsState', () {
+      expect(History.supportsState, true);
+    });
+  });
+
+  var expectation = History.supportsState ? returnsNormally : throws;
+
+  group('history', () {
+    test('pushState', () {
+      expect(() {
+        window.history.pushState(null, document.title, '?dummy');
+        var length = window.history.length;
+
+        window.history.pushState(null, document.title, '?foo=bar');
+
+        expect(window.location.href.endsWith('foo=bar'), isTrue);
+
+      }, expectation);
+    });
+
+    test('back', () {
+      expect(() {
+        window.history.pushState(null, document.title, '?dummy1');
+        window.history.pushState(null, document.title, '?dummy2');
+        var length = window.history.length;
+
+        expect(window.location.href.endsWith('dummy2'), isTrue);
+
+        expectAsync1Once(window.on.popState, (_) {
+          expect(window.history.length, length);
+          expect(window.location.href.endsWith('dummy1'), isTrue);
+        });
+
+        window.history.back();
+      }, expectation);
+    });
+
+    test('replaceState', () {
+      expect(() {
+        var length = window.history.length;
+
+        window.history.replaceState(null, document.title, '?foo=baz');
+        expect(window.history.length, length);
+        expect(window.location.href.endsWith('foo=baz'), isTrue);
+      }, expectation);
+    });
   });
 }
diff --git a/tests/html/html.status b/tests/html/html.status
index 8825886..9a8ef67 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -9,16 +9,25 @@
 xmldocument_test: Skip  # XML in dart:html is incomplete
 xmlelement_test: Skip  # XML in dart:html is incomplete
 
+history_test/history: Fail, Pass # Issue 7676.
+
+# Layout tests are only supported on DRT.
+[ $runtime == ie9 || $runtime == ie10 || $runtime == safari || $runtime == ff || $runtime == chrome || $runtime == opera ]
+*layout_test: Skip
+
 [ $runtime == chrome ]
-contentelement_test: Fail   # Issue 5445: not currently supported on chrome stable.
-input_element_test/date: Pass, Fail      # Chrome stable does not support this input type.
-input_element_test/datetime: Fail        # Chrome stable does not support this input type.
-input_element_test/datetime-local: Fail  # Chrome stable does not support this input type.
-input_element_test/month: Fail           # Chrome stable does not support this input type.
-input_element_test/week: Fail            # Chrome stable does not support this input type.
+element_types_test/supported_content: Fail
+element_types_test/supported_shadow: Fail
+input_element_test/supported_date: Pass, Fail      # Chrome stable does not support this input type.
+input_element_test/supported_datetime: Fail
+input_element_test/supported_datetime-local: Fail
+input_element_test/supported_month: Fail
+input_element_test/supported_week: Fail
+shadow_dom_test/supported: Fail
 
 [ $runtime == chrome || $runtime == drt]
 audiobuffersourcenode_test: Pass, Fail  # AudiobufferSourceNode is flaky on Chrome and Dartium.
+audiocontext_test: Skip # Need to adjust to new API.
 
 [ $compiler == none && ($runtime == drt || $runtime == dartium) ]
 request_animation_frame_test: Skip   # drt hangs; requestAnimationFrame not implemented
@@ -51,78 +60,65 @@
 [ $compiler == none && $runtime == drt && $system == linux]
 documentfragment_test: Pass, Timeout
 
-[ $runtime == ie9 || $runtime == ie10 || $runtime == safari || $runtime == ff || $runtime == chrome || $runtime == opera ]
-# TODO(vsm): Triage DOM tests.
-htmloptionscollection_test: Fail # Issue 3813.
-shadow_dom_test: Skip # No ShadowDOM support except on tip dartium.
-shadow_dom_layout_test: Skip
-unknownelement_test: Fail # Issue 4189
-
-[ $runtime == dartium || $runtime == chrome || $runtime == ie9 || $runtime == ie10 || $runtime == safari || $runtime == ff || $runtime == opera ]
-history_test: Fail
-
 [$runtime == ie10 ]
 # TODO(efortuna, blois): Triage.
 audiobuffersourcenode_test: Fail
 audiocontext_test: Fail
-canvasrenderingcontext2d_test: Fail, Pass
-contentelement_test: Fail
 css_test: Fail
 document_test/getCssCanvasContext: Fail # IE does not support this.
 element_test/additionalConstructors: Fail
-element_test/attributes: Fail
-element_test/eventListening: Fail
-element_webkit_test: Fail
+element_test/click: Fail                # IE does not support firing this event.
+element_types_test/supported_content: Fail
+element_types_test/supported_details: Fail
+element_types_test/supported_keygen: Fail
+element_types_test/supported_meter: Fail
+element_types_test/supported_object: Fail
+element_types_test/supported_output: Fail
+element_types_test/supported_shadow: Fail
 exceptions_test: Fail
 fileapi_test: Fail
-indexeddb_1_test: Fail
-indexeddb_2_test: Fail
-indexeddb_3_test: Fail
-indexeddb_4_test: Fail
+indexeddb_1_test/supported: Fail         # IE10 does not support from file://
 inner_frame_test: Skip
-input_element_test/date: Fail            # IE10 does not support this input type.
-input_element_test/datetime: Fail        # IE10 does not support this input type.
-input_element_test/datetime-local: Fail  # IE10 does not support this input type.
-input_element_test/month: Fail           # IE10 does not support this input type.
-input_element_test/time: Fail            # IE10 does not support this input type.
-input_element_test/week: Fail            # IE10 does not support this input type.
+input_element_test/supported_date: Fail
+input_element_test/supported_datetime: Fail
+input_element_test/supported_datetime-local: Fail
+input_element_test/supported_month: Fail
+input_element_test/supported_time: Fail
+input_element_test/supported_week: Fail
 isolates_test: Skip
 localstorage_test: Fail
 measurement_test: Fail, Pass
 messageevent_test: Fail
-mutationobserver_test: Fail
+mutationobserver_test/supported: Fail
 serialized_script_value_test: Fail
+shadow_dom_test/supported: Fail
 storage_test: Fail, Pass
 svgelement_test/additionalConstructors: Fail
-svgelement_test/elementset: Fail
-svgelement_test/innerHtml: Fail
-svgelement_test/outerHtml: Fail
 svgelement2_test: Fail
 svg_3_test: Fail
-typed_arrays_1_test: Fail
-typed_arrays_arraybuffer_test: Fail
-typed_arrays_dataview_test: Fail
-url_test: Fail
+url_test: Fail                           # IE10 does not support from file://
 websql_test: Fail
 window_open_test: Skip
 xhr_test: Fail
 xsltprocessor_test: Fail
 
 [ $runtime == ie9 ]
-contentelement_test: Fail   # ie9 does not support content element.
 document_test/getCssCanvasContext: Fail # IE does not support this.
+element_test/click: Fail                # IE does not support firing this event.
+element_types_test/supported_content: Fail
+element_types_test/supported_datalist: Fail
+element_types_test/supported_details: Fail
+element_types_test/supported_keygen: Fail
+element_types_test/supported_meter: Fail
+element_types_test/supported_object: Fail
+element_types_test/supported_output: Fail
+element_types_test/supported_progress: Fail
+element_types_test/supported_shadow: Fail
+element_types_test/supported_track: Fail
 form_data_test: Fail # Issue 4793.
 form_element_test: Fail # Issue 4793.
 inner_frame_test: Skip # Issue 5727 (timeout)
-typed_arrays_1_test: Skip   # ie9 does not have typed arrays.
-typed_arrays_2_test: Skip
-typed_arrays_3_test: Skip
-typed_arrays_4_test: Skip
-typed_arrays_5_test: Skip
-typed_arrays_arraybuffer_test: Skip
-typed_arrays_dataview_test: Skip
-typed_arrays_range_checks_test: Fail
-element_webkit_test: Fail
+typed_arrays_1_test/supported: Fail
 localstorage_test: Fail
 websql_test: Fail # IE does not support web SQL
 #
@@ -133,39 +129,32 @@
 blob_constructor_test: Fail
 cache_test: fail              # IE9 does not support ApplicationCache, but IE 10 does (and should work).
 css_test: Fail
-datalistelement_test: Fail    # ie9 does not have HTMLDataListElement
 dom_constructors_test: Fail
 element_test/additionalConstructors: Fail
-element_test/attributes: Fail
-element_test/eventListening: Fail
 exceptions_test: Fail
 fileapi_test: Fail          # IE does not support filesystem APIs.
-history_test: Fail
-indexeddb_1_test: Fail
-indexeddb_2_test: Fail
-indexeddb_3_test: Fail
-indexeddb_4_test: Fail
-input_element_test/date: Fail            # IE9 does not support this input type.
-input_element_test/datetime: Fail        # IE9 does not support this input type.
-input_element_test/datetime-local: Fail  # IE9 does not support this input type.
-input_element_test/month: Fail           # IE9 does not support this input type.
-input_element_test/range: Fail           # IE9 does not support this input type.
-input_element_test/time: Fail            # IE9 does not support this input type.
-input_element_test/week: Fail            # IE9 does not support this input type.
-
+history_test/supported_state: Fail
+indexeddb_1_test/supported: Fail
+input_element_test/supported_date: Fail
+input_element_test/supported_datetime-local: Fail
+input_element_test/supported_datetime: Fail
+input_element_test/supported_email: Fail
+input_element_test/supported_month: Fail
+input_element_test/supported_number: Fail
+input_element_test/supported_range: Fail
+input_element_test/supported_search: Fail
+input_element_test/supported_tel: Fail
+input_element_test/supported_time: Fail
+input_element_test/supported_url: Fail
+input_element_test/supported_week: Fail
 messageevent_test: Fail
-mutationobserver_test: Fail
+mutationobserver_test/supported: Fail
 postmessage_structured_test: Skip   # BUG(5685): times out.
 serialized_script_value_test: Fail
-shadow_dom_layout_test: Fail
-shadow_dom_test: Fail
+shadow_dom_test/supported: Fail
 storage_test: Fail
 svg_3_test: Fail
 svgelement_test/additionalConstructors: Fail
-svgelement_test/elementset: Fail
-element_test/eventListening: Fail
-svgelement_test/innerHtml: Fail
-svgelement_test/outerHtml: Fail
 svgelement2_test: Fail
 url_test: Fail              # IE9 does not support createObjectURL (it is supported in IE10)
 websocket_test: Fail
@@ -178,37 +167,23 @@
 [ $runtime == safari ]
 # TODO(ahe, efortuna): These tests need to be retriaged now that we're testing
 # with Safari 6.
-audiocontext_test: Crash, Fail # TODO(ahe): Please triage this failure.
-svgelement_test/innerHtml: Crash, Fail, Pass # TODO(ahe): Please triage this failure.
-svgelement_test/outerHtml: Crash, Fail, Pass # TODO(ahe): Please triage this failure.
-element_test/elements: Crash, Fail # TODO(ahe): Please triage this failure.
-element_test/children: Crash, Fail, Pass # TODO(ahe): Please triage this failure.
-element_test/attributes: Pass, Crash, Fail # TODO(ahe): Please triage this failure.
+audiocontext_test: Crash, Fail # Issue: 7414
+element_test/elements: Crash, Fail # Issue: 7414
+element_types_test/supported_content: Fail
+element_types_test/supported_datalist: Fail
+element_types_test/supported_shadow: Fail
 performance_api_test: Fail # window.performance.timing not in Safari 6.
-indexeddb_1_test: Fail # indexedDB not in Safari 6.
-indexeddb_2_test: Fail # indexedDB not in Safari 6.
-indexeddb_3_test: Fail # indexedDB not in Safari 6.
-indexeddb_4_test: Fail # indexedDB not in Safari 6.
-input_element_test/date: Fail            # Safari does not support this input type.
-input_element_test/datetime: Fail        # Safari does not support this input type.
-input_element_test/datetime-local: Fail  # Safari does not support this input type.
-input_element_test/month: Fail, Crash    # Safari does not support this input type.
-input_element_test/range: Fail, Crash    # TODO(efortuna): Please triage this failure.
-input_element_test/time: Fail, Crash     # Safari does not support this input type.
-input_element_test/week: Fail, Crash     # Safari does not support this input type.
+indexeddb_1_test/supported: Fail
+input_element_test/supported_date: Fail
+input_element_test/supported_datetime: Fail
+input_element_test/supported_datetime-local: Fail
+input_element_test/supported_month: Fail, Crash
+input_element_test/supported_range: Fail, Crash    # TODO(efortuna): Please triage this failure.
+input_element_test/supported_time: Fail, Crash
+input_element_test/supported_week: Fail, Crash
 fileapi_test: Fail # requestFileSystem not supported in Safari 6.
-datalistelement_test: Fail # HTMLDataListElement not yet supported in Safari.
-contentelement_test: Fail # Safari 6 does not support content element.
-# TODO: The following tests need to be triaged to understand why they are
-# failing (They are expected to pass in Safari 6).
-# TODO(efortuna): Make our test framework able to separate tests out by browser
-# version.
-datalistelement_test: Pass,Fail
 node_test: Skip # Issue 6457
-svgelement_test/elementset: Crash, Pass
-svgelement_test/elementget: Crash, Pass
-svgelement_test/css: Crash, Pass
-element_test/eventListening: Crash, Pass
+shadow_dom_test/supported: Fail
 
 [ $runtime == opera && $system == windows ]
 htmlelement_test: Fail, Pass
@@ -218,10 +193,15 @@
 
 
 [ $runtime == opera ]
+document_test/getCssCanvasContext: Fail # Issue: 7413
+form_data_test: Fail # Issue: 7413
+keyboard_event_test: Fail # Issue: 7413
+xmldocument_2_test: Fail # Issue: 7413
+element_test/eventListening: Fail # Issue: 7413
+element_test/children: Fail # Issue: 7413
 audiobuffersourcenode_test: Fail
 cache_test: Fail
 canvas_test: Pass,Fail
-contentelement_test: Fail
 audiocontext_test: Fail
 blob_constructor_test: Fail
 canvas_using_html_test: Fail
@@ -236,17 +216,13 @@
 element_test/queryAll: Fail
 element_webkit_test: Fail
 exceptions_test: Fail
-indexeddb_1_test: Fail
-indexeddb_2_test: Fail
-indexeddb_3_test: Fail
-indexeddb_4_test: Fail
-mutationobserver_test: Fail
+indexeddb_1_test/supported: Fail
+mutationobserver_test/supported: Fail
 performance_api_test: Fail
 serialized_script_value_test: Fail
 svg_3_test: Fail
 svgelement_test/additionalConstructors: Fail
 svgelement2_test: Fail
-typed_arrays_1_test: Fail
 typed_arrays_arraybuffer_test: Fail
 url_test: Fail
 websocket_test: Fail
@@ -261,26 +237,29 @@
 audiobuffersourcenode_test: Fail # FF only has Audio element.
 audiocontext_test: Fail      # FF only has Audio element
 css_test: Fail               # No analog to WebKitCssMatrix
-contentelement_test: Fail    # FF does not support content element.
 dart_object_local_storage_test: Skip  # sessionStorage NS_ERROR_DOM_NOT_SUPPORTED_ERR
 document_test/getCssCanvasContext: Fail # FF does not support this.
 documentfragment_test: Fail
-element_webkit_test: Fail
+element_types_test/supported_content: Fail
+element_types_test/supported_details: Fail
+element_types_test/supported_embed: Fail
+element_types_test/supported_keygen: Fail
+element_types_test/supported_shadow: Fail
+element_types_test/supported_track: Fail
 exceptions_test: Fail      # Uses webkitotifications, no analogue in moz
 fileapi_test: Fail         # FF does not support filesystem APIs.
-indexeddb_1_test: Fail     # FF disables indexedDB from file URLs.
-indexeddb_2_test: Fail     # FF disables indexedDB from file URLs.
-indexeddb_3_test: Fail     # FF disables indexedDB from file URLs.
-indexeddb_4_test: Fail     # FF disables indexedDB from file URLs.
+indexeddb_1_test/supported: Fail  # FF disables indexedDB from file URLs.
 # setup code fails. prepare. (DOM callback has errors) Caught [object Event]
 inner_frame_test: Skip
-input_element_test/date: Fail            # FF does not support this input type.
-input_element_test/datetime: Fail        # FF does not support this input type.
-input_element_test/datetime-local: Fail  # FF does not support this input type.
-input_element_test/month: Fail           # FF does not support this input type.
-input_element_test/time: Fail            # FF does not support this input type.
-input_element_test/week: Fail            # FF does not support this input type.
-input_element_test/range: Fail           # FF does not support this input type.
+input_element_test/supported_date: Fail
+input_element_test/supported_datetime: Fail
+input_element_test/supported_datetime-local: Fail
+input_element_test/supported_month: Fail
+input_element_test/supported_time: Fail
+input_element_test/supported_week: Fail
+input_element_test/supported_number: Fail
+input_element_test/supported_range: Fail
+shadow_dom_test/supported: Fail
 # Interfaces not implemented: SVGTests, SVGLangSpace, SVGExternalResourcesRequired, SVGStylable
 svg_3_test: Fail
 svgelement_test/additionalConstructors: Fail
@@ -300,28 +279,9 @@
 
 # 'html' tests import the HTML library, so they only make sense in
 # a browser environment.
-[ $compiler == dartc ]
-*: Skip
-#documentfragment_test: Fail # test issue 7065
-#element_add_test: Fail      # test issue 7065
-#element_test: Fail          # test issue 7065
-#node_test: Fail             # test issue 7065
-#svgelement_test: Fail       # test issue 7065
-#svgelement2_test: Fail      # test issue 7065
-
 [ $runtime == vm ]
 *: Skip
 
-# TODO(jmesserly): now that we have a bot, we need to set up Opera testing.
-
-[ $compiler == dart2js && $runtime == drt ]
-# Unknown error - should investigate.
-htmloptionscollection_test: Fail # Issue 3813.
-unknownelement_test: Fail # Issue 4189
-
-[ $compiler == dart2js && $runtime == none ]
-*: Fail, Pass # TODO(ahe): Triage these tests.
-
 [ $compiler == dart2js ]
 transferables_test: Skip # until isInstance works in dart2js
 
@@ -330,16 +290,9 @@
 
 [ $compiler == dart2js && ($runtime == drt || $runtime == chrome || $runtime == ff || $runtime == safari) ]
 isolates_test: Skip   # Timeout because leg does not support web workers.
-typed_arrays_1_test: Fail # dart2js doesn't support is checks with generic types.
-
-[ $compiler == dart2js && $runtime == ff && $system == linux]
-indexeddb_3_test: Fail  # Caught Error: DATA_ERR: DOM IDBDatabase Exception 5 Error: The data provided does not meet the requirements of the function.
 
 [ $compiler == dart2js && $runtime == ff ]
 xhr_test: Skip # Timeout
 inner_frame_test: Skip # Timeout
 svg_3_test: Skip # Timeout
 documentfragment_test: Skip # Timeout
-
-[ $compiler == dart2js && $runtime == chrome && $system == windows]
-css_test: Pass, Fail # Issue #2823
diff --git a/tests/html/htmlelement_test.dart b/tests/html/htmlelement_test.dart
index f9455df..7c5e5a0 100644
--- a/tests/html/htmlelement_test.dart
+++ b/tests/html/htmlelement_test.dart
@@ -61,7 +61,7 @@
 
     final keys = <String> [];
     final values = <String> [];
-    div.dataAttributes.forEach(void f(String key, String value) {
+    div.dataAttributes.forEach((String key, String value) {
         keys.add(key);
         values.add(value);
     });
diff --git a/tests/html/htmloptionscollection_test.dart b/tests/html/htmloptionscollection_test.dart
index ccc5da5..8af54c7 100644
--- a/tests/html/htmloptionscollection_test.dart
+++ b/tests/html/htmloptionscollection_test.dart
@@ -32,8 +32,8 @@
     expect(() { optionsCollection[0] = 1; }, throws);
 
     // OPTIONALS optionsCollection[0] = new OptionElement(value: '42', data: 'Option42');
-    optionsCollection[0] = new OptionElement('Option42', '42');
-    expect(optionsCollection[0].value, equals('42'));
-    expect(optionsCollection[0].text, equals('Option42'));
+    expect(() {
+      optionsCollection[0] = new OptionElement('Option42', '42');
+    }, throws);
   });
 }
diff --git a/tests/html/indexeddb_1_test.dart b/tests/html/indexeddb_1_test.dart
index 664a253..c9d7c5f 100644
--- a/tests/html/indexeddb_1_test.dart
+++ b/tests/html/indexeddb_1_test.dart
@@ -1,6 +1,6 @@
 library IndexedDB1Test;
 import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import '../../pkg/unittest/lib/html_individual_config.dart';
 import 'dart:html' as html;
 import 'dart:indexed_db' as idb;
 
@@ -175,8 +175,28 @@
 }
 
 main() {
-  useHtmlConfiguration();
+  useHtmlIndividualConfiguration();
 
-  tests_dynamic();
-  tests_typed();
+  // Test that indexed_db is properly flagged as supported or not.
+  // Note that the rest of the indexed_db tests assume that this has been
+  // checked.
+  group('supported', () {
+    test('supported', () {
+      expect(idb.IdbFactory.supported, true);
+    });
+  });
+
+  test('throws when unsupported', () {
+    var expectation = idb.IdbFactory.supported ? returnsNormally : throws;
+
+    expect(() {
+      var db = window.indexedDB;
+    }, expectation);
+  });
+
+  // Don't bother with these tests if it's unsupported.
+  if (idb.IdbFactory.supported) {
+    tests_dynamic();
+    tests_typed();
+  }
 }
diff --git a/tests/html/indexeddb_2_test.dart b/tests/html/indexeddb_2_test.dart
index e716e6b..ac41b3d 100644
--- a/tests/html/indexeddb_2_test.dart
+++ b/tests/html/indexeddb_2_test.dart
@@ -122,13 +122,17 @@
       verifyGraph(cyclic_list, cyclic_list);
     });
 
-  go('test_simple', obj1);
-  go('test_DAG', obj2);
-  go('test_cycle', obj3);
-  go('test_simple_splay', obj4);
-  go('const_array_1', const [const [1], const [2]]);
-  go('const_array_dag', const [const [1], const [1]]);
-  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);
+  // Don't bother with these tests if it's unsupported.
+  // Support is tested in indexeddb_1_test
+  if (idb.IdbFactory.supported) {
+    go('test_simple', obj1);
+    go('test_DAG', obj2);
+    go('test_cycle', obj3);
+    go('test_simple_splay', obj4);
+    go('const_array_1', const [const [1], const [2]]);
+    go('const_array_dag', const [const [1], const [1]]);
+    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);
+  }
 }
diff --git a/tests/html/indexeddb_3_test.dart b/tests/html/indexeddb_3_test.dart
index 991fce5..5a4f7e5 100644
--- a/tests/html/indexeddb_3_test.dart
+++ b/tests/html/indexeddb_3_test.dart
@@ -22,8 +22,9 @@
       // Nuke object store if it already exists.
       db.deleteObjectStore(STORE_NAME);
     }
-    on DatabaseException catch(e) { }  // Chrome
-    on DomException catch(e) { }          // Firefox
+    // TODO:
+    //on DomException catch(e) { } // Chrome and Firefox
+    catch(e) { } // Chrome and Firefox
     db.createObjectStore(STORE_NAME);
   }
 
@@ -143,8 +144,12 @@
 main() {
   useHtmlConfiguration();
 
-  var test_ = new Test();
-  test('prepare', test_.setupDb);
-  test('readAll1', test_.readAllViaCursor);
-  test('readAll2', test_.readAllReversedViaCursor);
+  // Don't bother with these tests if it's unsupported.
+  // Support is tested in indexeddb_1_test
+  if (IdbFactory.supported) {
+    var test_ = new Test();
+    test('prepare', test_.setupDb);
+    test('readAll1', test_.readAllViaCursor);
+    test('readAll2', test_.readAllReversedViaCursor);
+  }
 }
diff --git a/tests/html/indexeddb_4_test.dart b/tests/html/indexeddb_4_test.dart
index 1a7c484..d8a1341 100644
--- a/tests/html/indexeddb_4_test.dart
+++ b/tests/html/indexeddb_4_test.dart
@@ -22,8 +22,7 @@
       // Nuke object store if it already exists.
       db.deleteObjectStore(STORE_NAME);
     }
-    on DatabaseException catch(e) { }  // Chrome
-    on DomException catch(e) { }          // Firefox
+    catch(e) { } // Chrome and Firefox
     db.createObjectStore(STORE_NAME);
   }
 
@@ -158,24 +157,28 @@
 main() {
   useHtmlConfiguration();
 
-  var test_ = new Test();
-  test('prepare', test_.setupDb);
+  // Don't bother with these tests if it's unsupported.
+  // Support is tested in indexeddb_1_test
+  if (IdbFactory.supported) {
+    var test_ = new Test();
+    test('prepare', test_.setupDb);
 
-  test('only1', test_.only1);
-  test('only2', test_.only2);
-  test('only3', test_.only3);
+    test('only1', test_.only1);
+    test('only2', test_.only2);
+    test('only3', test_.only3);
 
-  test('lower1', test_.lower1);
-  test('lower2', test_.lower2);
-  test('lower3', test_.lower3);
+    test('lower1', test_.lower1);
+    test('lower2', test_.lower2);
+    test('lower3', test_.lower3);
 
-  test('upper1', test_.upper1);
-  test('upper2', test_.upper2);
-  test('upper3', test_.upper3);
+    test('upper1', test_.upper1);
+    test('upper2', test_.upper2);
+    test('upper3', test_.upper3);
 
-  test('bound1', test_.bound1);
-  test('bound2', test_.bound2);
-  test('bound3', test_.bound3);
-  test('bound4', test_.bound4);
-  test('bound5', test_.bound5);
+    test('bound1', test_.bound1);
+    test('bound2', test_.bound2);
+    test('bound3', test_.bound3);
+    test('bound4', test_.bound4);
+    test('bound5', test_.bound5);
+  }
 }
diff --git a/tests/html/input_element_test.dart b/tests/html/input_element_test.dart
index d8c80ce..8f63658 100644
--- a/tests/html/input_element_test.dart
+++ b/tests/html/input_element_test.dart
@@ -3,152 +3,180 @@
 import '../../pkg/unittest/lib/html_individual_config.dart';
 import 'dart:html';
 
+void check(InputElement element, String type, [bool supported = true]) {
+  expect(element is InputElement, true);
+  if (supported) {
+    expect(element.type, type);
+  } else {
+    expect(element.type, 'text');
+  }
+}
+
 main() {
   useHtmlIndividualConfiguration();
 
-  test('hidden', () {
-    var e = new HiddenInputElement();
-    expect(e is InputElement, true);
-    expect(e.type, 'hidden');
-  });
-
-  test('search', () {
-    var e = new SearchInputElement();
-    expect(e is InputElement, true);
-    expect(e.type, 'search');
-  });
-
-  test('text', () {
-    var e = new TextInputElement();
-    expect(e is InputElement, true);
-    expect(e.type, 'text');
-  });
-
-  test('url', () {
-    var e = new UrlInputElement();
-    expect(e is InputElement, true);
-    expect(e.type, 'url');
-  });
-
-  test('telephone', () {
-    var e = new TelephoneInputElement();
-    expect(e is InputElement, true);
-    expect(e.type, 'tel');
-  });
-
-  test('email', () {
-    var e = new EmailInputElement();
-    expect(e is InputElement, true);
-    expect(e.type, 'email');
-  });
-
-  test('password', () {
-    var e = new PasswordInputElement();
-    expect(e is InputElement, true);
-    expect(e.type, 'password');
-  });
-
-  group('datetime', () {
-    test('constructor', () {
-      var e = new DateTimeInputElement();
-      expect(e is InputElement, true);
-      expect(e.type, 'datetime');
+  group('supported_search', () {
+    test('supported', () {
+      expect(SearchInputElement.supported, true);
     });
   });
 
-  group('date', () {
-    test('constructor', () {
-      var e = new DateInputElement();
-      expect(e is InputElement, true);
-      expect(e.type, 'date');
+  group('supported_url', () {
+    test('supported', () {
+      expect(UrlInputElement.supported, true);
     });
   });
 
-  group('month', () {
-    test('constructor', () {
-      var e = new MonthInputElement();
-      expect(e is InputElement, true);
-      expect(e.type, 'month');
+  group('supported_tel', () {
+    test('supported', () {
+      expect(TelephoneInputElement.supported, true);
     });
   });
 
-  group('week', () {
-    test('constructor', () {
-      var e = new WeekInputElement();
-      expect(e is InputElement, true);
-      expect(e.type, 'week');
+  group('supported_email', () {
+    test('supported', () {
+      expect(EmailInputElement.supported, true);
     });
   });
 
-  group('time', () {
-    test('constructor', () {
-      var e = new TimeInputElement();
-      expect(e is InputElement, true);
-      expect(e.type, 'time');
+  group('supported_datetime', () {
+    test('supported', () {
+      expect(DateTimeInputElement.supported, true);
     });
   });
 
-  group('datetime-local', () {
-    test('constructor', () {
-      var e = new LocalDateTimeInputElement();
-      expect(e is InputElement, true);
-      expect(e.type, 'datetime-local');
+  group('supported_date', () {
+    test('supported', () {
+      expect(DateInputElement.supported, true);
     });
   });
 
-  test('number', () {
-    var e = new NumberInputElement();
-    expect(e is InputElement, true);
-    expect(e.type, 'number');
-  });
-
-  group('range', () {
-    test('constructor', () {
-      var e = new RangeInputElement();
-      expect(e is InputElement, true);
-      expect(e.type, 'range');
+  group('supported_month', () {
+    test('supported', () {
+      expect(MonthInputElement.supported, true);
     });
   });
 
-  test('checkbox', () {
-    var e = new CheckboxInputElement();
-    expect(e is InputElement, true);
-    expect(e.type, 'checkbox');
+  group('supported_week', () {
+    test('supported', () {
+      expect(WeekInputElement.supported, true);
+    });
   });
 
-  test('radio', () {
-    var e = new RadioButtonInputElement();
-    expect(e is InputElement, true);
-    expect(e.type, 'radio');
+  group('supported_time', () {
+    test('supported', () {
+      expect(TimeInputElement.supported, true);
+    });
   });
 
-  test('file', () {
-    var e = new FileUploadInputElement();
-    expect(e is InputElement, true);
-    expect(e.type, 'file');
+  group('supported_datetime-local', () {
+    test('supported', () {
+      expect(LocalDateTimeInputElement.supported, true);
+    });
   });
 
-  test('submit', () {
-    var e = new SubmitButtonInputElement();
-    expect(e is InputElement, true);
-    expect(e.type, 'submit');
+  group('supported_number', () {
+    test('supported', () {
+      expect(NumberInputElement.supported, true);
+    });
   });
 
-  test('image', () {
-    var e = new ImageButtonInputElement();
-    expect(e is InputElement, true);
-    expect(e.type, 'image');
+  group('supported_range', () {
+    test('supported', () {
+      expect(RangeInputElement.supported, true);
+    });
   });
 
-  test('reset', () {
-    var e = new ResetButtonInputElement();
-    expect(e is InputElement, true);
-    expect(e.type, 'reset');
-  });
+  group('constructors', () {
+    test('hidden', () {
+      check(new HiddenInputElement(), 'hidden');
+    });
 
-  test('button', () {
-    var e = new ButtonInputElement();
-    expect(e is InputElement, true);
-    expect(e.type, 'button');
+    test('search', () {
+      check(new SearchInputElement(), 'search', SearchInputElement.supported);
+    });
+
+    test('text', () {
+      check(new TextInputElement(), 'text');
+    });
+
+    test('url', () {
+      check(new UrlInputElement(), 'url', UrlInputElement.supported);
+    });
+
+    test('telephone', () {
+      check(new TelephoneInputElement(), 'tel',
+          TelephoneInputElement.supported);
+    });
+
+    test('email', () {
+      check(new EmailInputElement(), 'email', EmailInputElement.supported);
+    });
+
+    test('password', () {
+      check(new PasswordInputElement(), 'password');
+    });
+
+    test('datetime', () {
+      check(new DateTimeInputElement(), 'datetime',
+          DateTimeInputElement.supported);
+    });
+
+    test('date', () {
+      check(new DateInputElement(), 'date', DateInputElement.supported);
+    });
+
+    test('month', () {
+      check(new MonthInputElement(), 'month', MonthInputElement.supported);
+    });
+
+    test('week', () {
+      check(new WeekInputElement(), 'week', WeekInputElement.supported);
+    });
+
+    test('time', () {
+      check(new TimeInputElement(), 'time', TimeInputElement.supported);
+    });
+
+    test('datetime-local', () {
+      check(new LocalDateTimeInputElement(), 'datetime-local',
+          LocalDateTimeInputElement.supported);
+    });
+
+    test('number', () {
+      check(new NumberInputElement(), 'number', NumberInputElement.supported);
+    });
+
+    test('range', () {
+      check(new RangeInputElement(), 'range', RangeInputElement.supported);
+    });
+
+    test('checkbox', () {
+      check(new CheckboxInputElement(), 'checkbox');
+    });
+
+    test('radio', () {
+      check(new RadioButtonInputElement(), 'radio');
+    });
+
+    test('file', () {
+      check(new FileUploadInputElement(), 'file');
+    });
+
+    test('submit', () {
+      check(new SubmitButtonInputElement(), 'submit');
+    });
+
+    test('image', () {
+      check(new ImageButtonInputElement(), 'image');
+    });
+
+    test('reset', () {
+      check(new ResetButtonInputElement(), 'reset');
+    });
+
+    test('button', () {
+      check(new ButtonInputElement(), 'button');
+    });
   });
 }
diff --git a/tests/html/mutationobserver_test.dart b/tests/html/mutationobserver_test.dart
index 6f93d84..e23a04c 100644
--- a/tests/html/mutationobserver_test.dart
+++ b/tests/html/mutationobserver_test.dart
@@ -4,7 +4,7 @@
 
 library mutationobserver_test;
 import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import '../../pkg/unittest/lib/html_individual_config.dart';
 import 'dart:html';
 
 /**
@@ -12,10 +12,17 @@
  * checks, not a complete test suite.
  */
 main() {
-  useHtmlConfiguration();
+  useHtmlIndividualConfiguration();
+
+  group('supported', () {
+    test('supported', () {
+      expect(MutationObserver.supported, true);
+    });
+  });
+
+  var expectation = MutationObserver.supported ? returnsNormally : throws;
 
   group('childList', () {
-
     mutationCallback(count, expectation) {
       var done = false;
       var nodes = [];
@@ -33,18 +40,26 @@
         }
       }
 
+      // If it's not supported, don't block waiting for it.
+      if (!MutationObserver.supported) {
+        return () => done;
+      }
+
       return expectAsyncUntil2(callback, () => done);
     }
 
     test('empty options is syntax error', () {
+      expect(() {
         var mutationObserver = new MutationObserver(
             (mutations, observer) { expect(false, isTrue,
                 reason: 'Should not be reached'); });
         expect(() { mutationObserver.observe(document, {}); },
                throws);
-      });
+      }, expectation);
+    });
 
     test('direct-parallel options-map', () {
+      expect(() {
         var container = new DivElement();
         var div1 = new DivElement();
         var div2 = new DivElement();
@@ -54,9 +69,11 @@
 
         container.nodes.add(div1);
         container.nodes.add(div2);
-      });
+      }, expectation);
+    });
 
     test('direct-parallel options-named', () {
+      expect(() {
         var container = new DivElement();
         var div1 = new DivElement();
         var div2 = new DivElement();
@@ -66,9 +83,11 @@
 
         container.nodes.add(div1);
         container.nodes.add(div2);
-      });
+      }, expectation);
+    });
 
     test('direct-nested options-named', () {
+      expect(() {
         var container = new DivElement();
         var div1 = new DivElement();
         var div2 = new DivElement();
@@ -78,10 +97,12 @@
 
         container.nodes.add(div1);
         div1.nodes.add(div2);
-      });
+      }, expectation);
+    });
 
 
     test('subtree options-map', () {
+      expect(() {
         var container = new DivElement();
         var div1 = new DivElement();
         var div2 = new DivElement();
@@ -92,9 +113,11 @@
 
         container.nodes.add(div1);
         div1.nodes.add(div2);
-      });
+      }, expectation);
+    });
 
     test('subtree options-named', () {
+      expect(() {
         var container = new DivElement();
         var div1 = new DivElement();
         var div2 = new DivElement();
@@ -104,6 +127,7 @@
 
         container.nodes.add(div1);
         div1.nodes.add(div2);
-      });
+      }, expectation);
+    });
   });
 }
diff --git a/tests/html/node_test.dart b/tests/html/node_test.dart
index 01ac3c3..5a406cf 100644
--- a/tests/html/node_test.dart
+++ b/tests/html/node_test.dart
@@ -41,8 +41,7 @@
   test('remove', () {
     final node = makeNodeWithChildren();
     final subnode = node.nodes[1];
-    final out = subnode.remove();
-    expect(out, isNull);
+    subnode.remove();
     expect(node.nodes.length, 2);
     expect(node.nodes[0], isText);
     expect(node.nodes[1], isComment);
diff --git a/tests/html/shadow_dom_layout_test.dart b/tests/html/shadow_dom_layout_test.dart
index ec809ca..5a1d6b8 100644
--- a/tests/html/shadow_dom_layout_test.dart
+++ b/tests/html/shadow_dom_layout_test.dart
@@ -20,7 +20,7 @@
   var greenbox = _colorBox('green', 60, 10);
 
   // assemble DOM
-  var sRoot = new ShadowRoot(div);
+  var sRoot = div.createShadowRoot();
   sRoot.nodes.add(new Element.html('<content select=".foo"></content>'));
   sRoot.nodes.add(redbox);
   sRoot.nodes.add(new Element.tag('content'));
diff --git a/tests/html/shadow_dom_test.dart b/tests/html/shadow_dom_test.dart
index 8e9a932..c6c21ce 100644
--- a/tests/html/shadow_dom_test.dart
+++ b/tests/html/shadow_dom_test.dart
@@ -4,39 +4,53 @@
 
 library ShadowDOMTest;
 import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import '../../pkg/unittest/lib/html_individual_config.dart';
 import 'dart:html';
 
 main() {
-  useHtmlConfiguration();
+  useHtmlIndividualConfiguration();
+
+  group('supported', () {
+    test('supported', () {
+      expect(ShadowRoot.supported, true);
+    });
+  });
 
   group('ShadowDOM tests', () {
 
     var div1, div2, shadowRoot, paragraph1, paragraph2;
 
-    setUp(() {
+    init() {
       paragraph1 = new ParagraphElement();
       paragraph2 = new ParagraphElement();
       [paragraph1, paragraph2].forEach((p) { p.classes.add('foo');});
       div1 = new DivElement();
       div2 = new DivElement();
       div1.classes.add('foo');
-      shadowRoot = new ShadowRoot(div2);
+      shadowRoot = div2.createShadowRoot();
       shadowRoot.nodes.add(paragraph1);
-      // No constructor for ContentElement exists yet.
-      // See http://code.google.com/p/dart/issues/detail?id=3870.
-      shadowRoot.nodes.add(new Element.tag('content'));
+      shadowRoot.nodes.add(new ContentElement());
       div2.nodes.add(paragraph2);
       document.body.nodes.add(div1);
       document.body.nodes.add(div2);
-    });
+    }
+
+    var expectation = ShadowRoot.supported ? returnsNormally : throws;
 
     test("Shadowed nodes aren't visible to queries from outside ShadowDOM", () {
-      expect(queryAll('.foo'), equals([div1, paragraph2]));
+      expect(() {
+        init();
+
+        expect(queryAll('.foo'), equals([div1, paragraph2]));
+      }, expectation);
     });
 
     test('Parent node of a shadow root must be null.', () {
-      expect(shadowRoot.parent, isNull);
+      expect(() {
+        init();
+
+        expect(shadowRoot.parent, isNull);
+      }, expectation);
     });
 
 
@@ -46,7 +60,11 @@
     // rendering tests.
 
     test('Querying in shadowed fragment respects the shadow boundary.', () {
-      expect(shadowRoot.queryAll('.foo'), equals([paragraph1]));
+      expect(() {
+        init();
+
+        expect(shadowRoot.queryAll('.foo'), equals([paragraph1]));
+      }, expectation);
     });
   });
 }
diff --git a/tests/html/shadowroot_test.dart b/tests/html/shadowroot_test.dart
index 4fb6fa0..56cf13b 100644
--- a/tests/html/shadowroot_test.dart
+++ b/tests/html/shadowroot_test.dart
@@ -18,10 +18,10 @@
 
     // If it's supported, then it should work. Otherwise should fail.
     if (isSupported) {
-      var shadowRoot = new ShadowRoot(new DivElement());
+      var shadowRoot = new DivElement().createShadowRoot();
       expect(shadowRoot, isShadowRoot);
     } else {
-      expect(() => new ShadowRoot(new DivElement()), throws);
+      expect(() => new DivElement().createShadowRoot(), throws);
     }
   });
 }
diff --git a/tests/html/svgelement_test.dart b/tests/html/svgelement_test.dart
index 3b3a2f4..333bca8 100644
--- a/tests/html/svgelement_test.dart
+++ b/tests/html/svgelement_test.dart
@@ -154,8 +154,11 @@
       final el = new svg.SvgSvgElement();
       el.children.add(new svg.CircleElement());
       el.children.add(new svg.PathElement());
-      expect(el.outerHtml,
-          '<svg version="1.1"><circle></circle><path></path></svg>');
+      expect([
+        '<svg version="1.1"><circle></circle><path></path></svg>',
+        '<svg xmlns="http://www.w3.org/2000/svg" version="1.1">'
+            '<circle /><path /></svg>',
+        ].contains(el.outerHtml), true);
     });
   });
 
@@ -164,7 +167,12 @@
       final el = new svg.SvgSvgElement();
       el.children.add(new svg.CircleElement());
       el.children.add(new svg.PathElement());
-      expect(el.innerHtml, '<circle></circle><path></path>');
+      // Allow for odd IE serialization.
+      expect([
+        '<circle></circle><path></path>',
+        '<circle xmlns="http://www.w3.org/2000/svg" />'
+            '<path xmlns="http://www.w3.org/2000/svg" />'
+        ].contains(el.innerHtml), true);
     });
 
     test('set', () {
@@ -206,7 +214,9 @@
     test('set', () {
       final el = new svg.SvgSvgElement();
       el.children = [new svg.SvgElement.tag("circle"), new svg.SvgElement.tag("path")];
-      expect(el.innerHtml, '<circle></circle><path></path>');
+      expect(el.nodes.length, 2);
+      expect(el.nodes[0] is svg.CircleElement, true);
+      expect(el.nodes[1] is svg.PathElement, true);
     });
   });
 
diff --git a/tests/html/typed_arrays_1_test.dart b/tests/html/typed_arrays_1_test.dart
index ccd13d0..12bd9f6 100644
--- a/tests/html/typed_arrays_1_test.dart
+++ b/tests/html/typed_arrays_1_test.dart
@@ -4,45 +4,65 @@
 
 library TypedArrays1Test;
 import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import '../../pkg/unittest/lib/html_individual_config.dart';
 import 'dart:html';
 
 main() {
-  useHtmlConfiguration();
+  useHtmlIndividualConfiguration();
 
   var isnumList = predicate((x) => x is List<num>, 'is a List<num>');
   var isStringList = predicate((x) => x is List<String>, 'is a List<String>');
+  var expectation = ArrayBuffer.supported ? returnsNormally : throws;
 
-  test('createByLengthTest', () {
-      var a = new Float32Array(10);
-      expect(a.length, 10);
-      expect(a[4], 0);
-  });
-
-  test('aliasTest', () {
-      var a1 = new Uint8Array.fromList([0,0,1,0x45]);
-      var a2 = new Float32Array.fromBuffer(a1.buffer);
-
-      expect(a2.length, 1);
-
-      // 0x45010000 = 2048+16
-      expect(a2[0], 2048 + 16);
-
-      a1[2] = 0;
-      // 0x45000000 = 2048
-      expect(a2[0], 2048);
-
-      a1[3]--;
-      a1[2] += 128;
-      // 0x44800000 = 1024
-      expect(a2[0], 1024);
-
-  });
-
-  test('typeTests', () {
-      var a = new Float32Array(10);
-      expect(a, isList);
-      expect(a, isnumList);
-      expect(a, isNot(isStringList));
+  group('supported', () {
+    test('supported', () {
+      expect(ArrayBuffer.supported, true);
     });
+  });
+
+  group('arrays', () {
+    test('createByLengthTest', () {
+      expect(() {
+        var a = new Float32Array(10);
+        expect(a.length, 10);
+        expect(a[4], 0);
+      }, expectation);
+    });
+
+    test('aliasTest', () {
+      expect(() {
+        var a1 = new Uint8Array.fromList([0,0,1,0x45]);
+        var a2 = new Float32Array.fromBuffer(a1.buffer);
+
+        expect(a2.length, 1);
+
+        // 0x45010000 = 2048+16
+        expect(a2[0], 2048 + 16);
+
+        a1[2] = 0;
+        // 0x45000000 = 2048
+        expect(a2[0], 2048);
+
+        a1[3]--;
+        a1[2] += 128;
+        // 0x44800000 = 1024
+        expect(a2[0], 1024);
+      }, expectation);
+    });
+
+    // Generic type checking is not available in dart2js, so use this check to
+    // see if we should check for it.
+    var supportsTypeTest = !(new List<String>() is List<int>);
+
+    if (supportsTypeTest) {
+      test('typeTests', () {
+        expect(() {
+          var a = new Float32Array(10);
+          expect(a, isList);
+          expect(a, isnumList);
+          expect(a, isNot(isStringList));
+        }, expectation);
+      });
+    }
+  });
 }
diff --git a/tests/html/typed_arrays_2_test.dart b/tests/html/typed_arrays_2_test.dart
index d109ddc..021de8c 100644
--- a/tests/html/typed_arrays_2_test.dart
+++ b/tests/html/typed_arrays_2_test.dart
@@ -7,9 +7,15 @@
 import '../../pkg/unittest/lib/html_config.dart';
 import 'dart:html';
 
+
 main() {
   useHtmlConfiguration();
 
+  // Only perform tests if ArrayBuffer is supported.
+  if (!ArrayBuffer.supported) {
+    return;
+  }
+
   test('fromBufferTest_dynamic', () {
       var a1 = new Uint8Array(1024);
       for (int i = 0; i < a1.length; i++) {
diff --git a/tests/html/typed_arrays_3_test.dart b/tests/html/typed_arrays_3_test.dart
index 6dcd67b..682b09e 100644
--- a/tests/html/typed_arrays_3_test.dart
+++ b/tests/html/typed_arrays_3_test.dart
@@ -10,6 +10,11 @@
 main() {
   useHtmlConfiguration();
 
+  // Only perform tests if ArrayBuffer is supported.
+  if (!ArrayBuffer.supported) {
+    return;
+  }
+
   test('setElementsTest_dynamic', () {
       var a1 = new Int8Array(1024);
 
diff --git a/tests/html/typed_arrays_4_test.dart b/tests/html/typed_arrays_4_test.dart
index 112e382..45852d0 100644
--- a/tests/html/typed_arrays_4_test.dart
+++ b/tests/html/typed_arrays_4_test.dart
@@ -10,6 +10,11 @@
 main() {
   useHtmlConfiguration();
 
+  // Only perform tests if ArrayBuffer is supported.
+  if (!ArrayBuffer.supported) {
+    return;
+  }
+
   test('indexOf_dynamic', () {
       var a1 = new Uint8Array(1024);
       for (int i = 0; i < a1.length; i++) {
diff --git a/tests/html/typed_arrays_5_test.dart b/tests/html/typed_arrays_5_test.dart
index b1930fe..d4da175 100644
--- a/tests/html/typed_arrays_5_test.dart
+++ b/tests/html/typed_arrays_5_test.dart
@@ -10,6 +10,11 @@
 main() {
   useHtmlConfiguration();
 
+  // Only perform tests if ArrayBuffer is supported.
+  if (!ArrayBuffer.supported) {
+    return;
+  }
+
   test('filter_dynamic', () {
       var a = new Float32Array(1024);
       for (int i = 0; i < a.length; i++) {
diff --git a/tests/html/typed_arrays_arraybuffer_test.dart b/tests/html/typed_arrays_arraybuffer_test.dart
index 69d8d28..21fbc7a 100644
--- a/tests/html/typed_arrays_arraybuffer_test.dart
+++ b/tests/html/typed_arrays_arraybuffer_test.dart
@@ -10,6 +10,11 @@
 main() {
   useHtmlConfiguration();
 
+  // Only perform tests if ArrayBuffer is supported.
+  if (!ArrayBuffer.supported) {
+    return;
+  }
+
   test('constructor', () {
       var a = new ArrayBuffer(100);
       expect(a.byteLength, 100);
diff --git a/tests/html/typed_arrays_dataview_test.dart b/tests/html/typed_arrays_dataview_test.dart
index d73f312..ebadb1a 100644
--- a/tests/html/typed_arrays_dataview_test.dart
+++ b/tests/html/typed_arrays_dataview_test.dart
@@ -10,6 +10,11 @@
 main() {
   useHtmlConfiguration();
 
+  // Only perform tests if ArrayBuffer is supported.
+  if (!ArrayBuffer.supported) {
+    return;
+  }
+
   test('access8', () {
       var a1 = new Uint8Array.fromList([0,0,3,255,0,0,0,0,0,0]);
 
diff --git a/tests/html/typed_arrays_range_checks_test.dart b/tests/html/typed_arrays_range_checks_test.dart
index bb8ee10..7c1debf 100644
--- a/tests/html/typed_arrays_range_checks_test.dart
+++ b/tests/html/typed_arrays_range_checks_test.dart
@@ -10,6 +10,11 @@
 main() {
   useHtmlConfiguration();
 
+  // Only perform tests if ArrayBuffer is supported.
+  if (!ArrayBuffer.supported) {
+    return;
+  }
+
   test('outOfRangeAccess_dynamic', () {
       var a = new Uint8Array(1024);
 
diff --git a/tests/html/unknownelement_test.dart b/tests/html/unknownelement_test.dart
index 5b1a8d2..6632974 100644
--- a/tests/html/unknownelement_test.dart
+++ b/tests/html/unknownelement_test.dart
@@ -31,45 +31,4 @@
       expect(() => foo.field1, throwsNoSuchMethodError);
       expect(() { foo.field1 = 42; }, throwsNoSuchMethodError);
     });
-
-  test('dispatch', () {
-      dispatch(element, name, args) {
-        if (element.xtag == null) {
-          element.xtag = new Map();
-        }
-        var map = element.xtag;
-
-        // FIXME: Remove once VM and Dart2JS converge.
-        name = name.replaceFirst(' ', ':');
-        switch (element.tagName.toLowerCase()) {
-          case 'foo':
-            switch (name) {
-              case 'get:x':
-                return 42;
-              case 'baz':
-                return '${element.id} - ${args[0]}';
-            }
-            break;
-          case 'bar':
-            switch (name) {
-              case 'get:y':
-                return map['y'];
-              case 'set:y=':
-                map['y'] = args[0];
-                return;
-            }
-            break;
-        }
-        throw new NoSuchMethodError(element, name, args, {});
-      }
-      dynamicUnknownElementDispatcher = dispatch;
-
-      expect(foo.x, equals(42));
-      expect(() { foo.x = 7; }, throwsNoSuchMethodError);
-      expect(foo.id, equals('foo'));
-      expect(() => bar.x, throwsNoSuchMethodError);
-      bar.y = 11;
-      expect(bar.y, equals(11));
-      expect(foo.baz('hello'), equals('foo - hello'));
-    });
 }
diff --git a/tests/html/util.dart b/tests/html/util.dart
index 9451581..25bb502 100644
--- a/tests/html/util.dart
+++ b/tests/html/util.dart
@@ -2,6 +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 test.html.util;
+
+import 'dart:html';
+import '../../pkg/unittest/lib/unittest.dart';
+
 void expectUnsupported(f) => expect(f, throwsUnsupportedError);
 
 void expectEmptyRect(ClientRect rect) {
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index e176844..3e6af4a 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -26,7 +26,6 @@
                                # implement timer (currently only in d8)
 
 [ $compiler == dartc ]
-serialization_test: Skip  # tests dart2js-specific serialization code
 isolate_negative_test: Fail    # status change with --check-only
 isolate2_negative_test: Fail   # status change with --check-only
 spawn_function_negative_test: Fail, OK # Fails at runtime.
@@ -41,7 +40,6 @@
 
 [ $compiler == dart2js ]
 serialization_test: Fail # Tries to access class TestingOnly declared in isolate_patch.dart
-port_test: Fail # Issue 6608
 illegal_msg_test: Fail # Issue 6750
 
 [ $runtime == safari ]
diff --git a/tests/isolate/port_test.dart b/tests/isolate/port_test.dart
index d3adfdd..8799af7 100644
--- a/tests/isolate/port_test.dart
+++ b/tests/isolate/port_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS 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.
 
@@ -19,8 +19,8 @@
 void testHashCode() {
   ReceivePort rp0 = new ReceivePort();
   ReceivePort rp1 = new ReceivePort();
-  expect(rp0.toSendPort().hashCode, rp0.toSendPort().hashCode);
-  expect(rp1.toSendPort().hashCode, rp1.toSendPort().hashCode);
+  Expect.equals(rp0.toSendPort().hashCode, rp0.toSendPort().hashCode);
+  Expect.equals(rp1.toSendPort().hashCode, rp1.toSendPort().hashCode);
   rp0.close();
   rp1.close();
 }
@@ -28,9 +28,9 @@
 void testEquals() {
   ReceivePort rp0 = new ReceivePort();
   ReceivePort rp1 = new ReceivePort();
-  expect(rp0.toSendPort(), rp0.toSendPort());
-  expect(rp1.toSendPort(), rp1.toSendPort());
-  expect(rp0.toSendPort() == rp1.toSendPort(), isFalse);
+  Expect.equals(rp0.toSendPort(), rp0.toSendPort());
+  Expect.equals(rp1.toSendPort(), rp1.toSendPort());
+  Expect.isFalse(rp0.toSendPort() == rp1.toSendPort());
   rp0.close();
   rp1.close();
 }
@@ -41,20 +41,20 @@
   final map = new Map<SendPort, int>();
   map[rp0.toSendPort()] = 42;
   map[rp1.toSendPort()] = 87;
-  expect(map[rp0.toSendPort()], 42);
-  expect(map[rp1.toSendPort()], 87);
+  Expect.equals(map[rp0.toSendPort()], 42);
+  Expect.equals(map[rp1.toSendPort()], 87);
 
   map[rp0.toSendPort()] = 99;
-  expect(map[rp0.toSendPort()], 99);
-  expect(map[rp1.toSendPort()], 87);
+  Expect.equals(map[rp0.toSendPort()], 99);
+  Expect.equals(map[rp1.toSendPort()], 87);
 
   map.remove(rp0.toSendPort());
-  expect(map.containsKey(rp0.toSendPort()), isFalse);
-  expect(map[rp1.toSendPort()], 87);
+  Expect.isFalse(map.containsKey(rp0.toSendPort()));
+  Expect.equals(map[rp1.toSendPort()], 87);
 
   map.remove(rp1.toSendPort());
-  expect(map.containsKey(rp0.toSendPort()), isFalse);
-  expect(map.containsKey(rp1.toSendPort()), isFalse);
+  Expect.isFalse(map.containsKey(rp0.toSendPort()));
+  Expect.isFalse(map.containsKey(rp1.toSendPort()));
 
   rp0.close();
   rp1.close();
diff --git a/tests/json/json.status b/tests/json/json.status
index e76252d..0d01775 100644
--- a/tests/json/json.status
+++ b/tests/json/json.status
@@ -8,9 +8,6 @@
 [ $runtime == safari && ($system == linux || $system == windows) ]
 *: Skip
 
-[ $compiler == dartc ]
-*: Skip
-
 [ $runtime == vm ]
 *: Skip
 
diff --git a/tests/language/assign_top_method_test.dart b/tests/language/assign_top_method_test.dart
new file mode 100644
index 0000000..eb85481
--- /dev/null
+++ b/tests/language/assign_top_method_test.dart
@@ -0,0 +1,11 @@
+// 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.
+
+method() { return 0; }
+
+main() {
+  // Illegal, can't change a top level method
+  Expect.throws(() { method = () { return 1; }; },
+                (e) => e is NoSuchMethodError);
+}
diff --git a/tests/language/call_operator_test.dart b/tests/language/call_operator_test.dart
index 386d1f2..2dc7070 100644
--- a/tests/language/call_operator_test.dart
+++ b/tests/language/call_operator_test.dart
@@ -73,4 +73,7 @@
   Expect.equals("foo", e.call("foo"));
   Expect.equals("foo:foo", e.call("foo", count:2));
   Expect.equals("foo:foo:foo", e.call("foo", count:3));
+
+  Expect.isTrue(a1 is Function);
+  Expect.isTrue(e is Function);
 }
diff --git a/tests/language/cascade_2_test.dart b/tests/language/cascade_2_test.dart
new file mode 100644
index 0000000..7ec06f9
--- /dev/null
+++ b/tests/language/cascade_2_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test cascades, issue 7665.
+
+main() {
+  var a = new Element(null);
+  Expect.equals(1, a.path0.length);
+  Expect.equals(a, a.path0[0]);
+
+  Expect.equals(1, a.path1.length);  // 2 instead of 1
+  Expect.equals(a, a.path1[0]);
+
+  Expect.equals(1, a.path2.length);  // NPE.
+
+  var b = new Element(a);
+  Expect.equals(2, b.path0.length);
+  Expect.equals(a, b.path0[0]);
+  Expect.equals(b, b.path0[1]);
+
+  Expect.equals(2, b.path1.length);  // 3 instead of 2.
+  Expect.equals(a, b.path1[0]);
+  Expect.equals(b, b.path1[1]);
+
+  Expect.equals(2, b.path2.length);  // NPE.
+}
+
+
+class Element {
+  final Element parent;
+
+  Element(this.parent);
+
+  List<Element> get path0 {
+    if (parent == null) {
+      return <Element>[this];
+    } else {
+      return parent.path0..add(this);
+    }
+  }
+
+  List<Element> get path1 {
+    return (parent == null) ? <Element>[this] : parent.path1..add(this);
+  }
+
+  List<Element> get path2 {
+    return (parent == null) ? <Element>[this] : (parent.path2..add(this));
+  }
+}
diff --git a/tests/language/class_cycle_test.dart b/tests/language/class_cycle_test.dart
new file mode 100644
index 0000000..dd97174
--- /dev/null
+++ b/tests/language/class_cycle_test.dart
@@ -0,0 +1,23 @@
+// 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.
+// Check fail because of cycles in super class relationship.
+
+class Foo implements Bar {
+}
+
+class C {
+}
+
+class Bar
+    extends Foo  /// 00: compile-time error
+    implements Foo  /// 01: compile-time error
+    implements C, C  /// 02: compile-time error
+    extends C implements C  /// 03: compile-time error
+{
+}
+
+main() {
+  Expect.isTrue(new Foo() is Foo);
+}
+
diff --git a/tests/language/class_literal_test.dart b/tests/language/class_literal_test.dart
index fe4b13c..21bc0fc 100644
--- a/tests/language/class_literal_test.dart
+++ b/tests/language/class_literal_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.
 
-// Test that classes cannot be used as expressions.
+// Test class literal expressions.
 
 class Class {
   static fisk() => 42;
@@ -12,36 +12,53 @@
 
 main() {
   if (false) {
-    Class; /// 01: compile-time error
     Class(); /// 02: compile-time error
-    Class.method(); /// 03: static type warning
-    Class.field; /// 04: static type warning
     Class[0]; /// 05: compile-time error
-    var x = Class; /// 06: compile-time error
     var x = Class(); /// 07: compile-time error
-    var x = Class.method(); /// 08: static type warning
-    var x = Class.field; /// 09: static type warning
     var x = Class[0]; /// 10: compile-time error
     var x = Class[0].field; /// 11: compile-time error
     var x = Class[0].method(); /// 12: compile-time error
-    foo(Class); /// 13: compile-time error
     foo(Class()); /// 14: compile-time error
-    foo(Class.method()); /// 15: static type warning
-    foo(Class.field); /// 16: static type warning
     foo(Class[0]); /// 17: compile-time error
     foo(Class[0].field); /// 18: compile-time error
     foo(Class[0].method()); /// 19: compile-time error
-    Class == null; /// 20: compile-time error
-    null == Class; /// 21: compile-time error
     Class[0] = 91; /// 22: compile-time error
     Class++; /// 23: compile-time error
     ++Class; /// 24: compile-time error
-    Class / 3; /// 25: compile-time error
-    Class += 3; /// 26: compile-time error
     Class[0] += 3; /// 27: compile-time error
     ++Class[0]; /// 28: compile-time error
     Class[0]++; /// 29: compile-time error
   }
   Expect.equals(42, Class.fisk());
   Expect.equals(null, foo(Class.fisk()));
+  
+  // Verify references to a class literal are allowed.
+  Class;
+  var x = Class;
+  foo(Class);
+  Expect.isFalse(Class == null);
+
+  // Verify that dereferencing a class literal is a runtime error.
+  Expect.throws(() { Class.method(); }, (e) => e is NoSuchMethodError);
+  Expect.throws(() { Class.field; }, (e) => e is NoSuchMethodError);
+  Expect.throws(() { var x = Class.method(); }, (e) => e is NoSuchMethodError);
+  Expect.throws(() { var x = Class.field; }, (e) => e is NoSuchMethodError);
+  Expect.throws(() { foo(Class.method()); }, (e) => e is NoSuchMethodError);
+  Expect.throws(() { foo(Class.field); }, (e) => e is NoSuchMethodError);
+  Expect.throws(() { Class / 3; }, (e) => e is NoSuchMethodError);
+  Expect.throws(() { Class += 3; }, (e) => e is NoSuchMethodError);
+
+  // Verify that a class literal is its runtimeType.
+  var obj = new Class();
+  Expect.identical(Class, obj.runtimeType);
+  
+  // Verify that a class literal isn't a string literal.
+  Expect.notEquals(Class, "Class");
+   
+  // Verify toString() works for class literals.
+  Expect.equals((Class).toString(), "Class");
+  var y = Class;
+  Expect.equals(y.toString(), "Class");
+  
+  Expect.throws(() { Class.toString(); }, (e) => e is NoSuchMethodError);
 }
diff --git a/tests/language/identical_closure_test.dart b/tests/language/identical_closure_test.dart
new file mode 100644
index 0000000..6eaf599
--- /dev/null
+++ b/tests/language/identical_closure_test.dart
@@ -0,0 +1,50 @@
+// 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.
+
+var myIdentical = identical;
+
+class Point {
+  num x, y;
+  Point(this.x, this.y);
+}
+
+main() {
+  // Smi.
+  Expect.isTrue(myIdentical(42, 42));
+  Expect.isFalse(myIdentical(42, 41));
+
+  // Double.
+  Expect.isTrue(myIdentical(42.0, 42.0));
+  Expect.isFalse(myIdentical(42.0, 41.0));
+
+  // Mint (2^45).
+  Expect.isTrue(myIdentical(35184372088832,35184372088832));
+  Expect.isFalse(myIdentical(35184372088832,35184372088831));
+
+  // Bigint (2^76).
+  Expect.isTrue(myIdentical(75557863725914323419136,
+                            75557863725914323419136));
+  Expect.isFalse(myIdentical(75557863725914323419136,
+                             75557863725914323419137));
+
+  // Different types.
+  Expect.isFalse(myIdentical(42, 42.0));
+  Expect.isFalse(myIdentical("hello", 41));
+
+  // Points.
+  var p = new Point(1,1);
+  var q = new Point(1,1);
+  Expect.isFalse(myIdentical(p, q));
+
+  // Strings.
+  var a = "hello";
+  var b = "hello";
+  // Identical strings are coalesced into single instances.
+  Expect.isTrue(myIdentical(a, b));
+
+  // Null and NaN handling.
+  Expect.isFalse(myIdentical(42, null));
+  Expect.isTrue(myIdentical(null, null));
+  Expect.isTrue(myIdentical(double.NAN, double.NAN));
+}
\ No newline at end of file
diff --git a/tests/language/invocation_mirror_invoke_on_test.dart b/tests/language/invocation_mirror_invoke_on_test.dart
new file mode 100644
index 0000000..f03726c
--- /dev/null
+++ b/tests/language/invocation_mirror_invoke_on_test.dart
@@ -0,0 +1,37 @@
+// 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.
+
+// Testing InvocationMirror.invokeOn method; test of issue 7227.
+
+var reachedSetX = 0;
+var reachedGetX = 0;
+var reachedM = 0;
+
+class A {
+
+  set x(val) {
+    reachedSetX = val;
+  }
+
+  get x {
+    reachedGetX = 1;
+  }
+
+  m() { reachedM = 1; }
+}
+
+class B {
+  final a = new A();
+  noSuchMethod(mirror) => mirror.invokeOn(a);
+}
+
+main () {
+  var b = new B();
+  b.x = 10;
+  Expect.equals(10, reachedSetX);
+  b.x;
+  Expect.equals(1, reachedGetX);
+  b.m();
+  Expect.equals(1, reachedM);
+}
diff --git a/tests/language/invocation_mirror_test.dart b/tests/language/invocation_mirror_test.dart
index 765fe08..bb573a4 100644
--- a/tests/language/invocation_mirror_test.dart
+++ b/tests/language/invocation_mirror_test.dart
@@ -11,12 +11,11 @@
   var last;
   noSuchMethod(InvocationMirror m) => last = m;
 
-  get wut => this;
-
   flif(int x) { Expect.fail("never get here"); }
   flaf([int x]) { Expect.fail("never get here"); }
   flof({int y}) { Expect.fail("never get here"); }
 
+  get wut => this;
   final int plif = 99;
   int get plaf { Expect.fail("never get here"); return 0; }
 }
@@ -42,8 +41,8 @@
     if (positional == null) {
       Expect.isTrue(im.isGetter, "$name:isGetter");
       Expect.isFalse(im.isSetter, "$name:isSetter");
-      Expect.equals(null, im.positionalArguments, "$name:positional");
-      Expect.equals(null, im.namedArguments, "$name:named");
+      Expect.equals(0, im.positionalArguments.length, "$name:#positional");
+      Expect.equals(0, im.namedArguments.length, "$name:#named");
       return;
     }
     Expect.isTrue(im.isSetter, "$name:isSetter");
@@ -51,7 +50,7 @@
     Expect.equals(1, im.positionalArguments.length, "$name:#positional");
     Expect.equals(positional[0], im.positionalArguments[0],
                   "$name:positional[0]");
-    Expect.equals(null, im.namedArguments, "$name:named");
+    Expect.equals(0, im.namedArguments.length, "$name:#named");
     return;
   }
   Expect.isTrue(im.isMethod, "$name:isMethod");
@@ -134,6 +133,13 @@
   // Trick call to n.call - wut is a getter returning n again.
   testInvocationMirror(n.wut(42), "call", [42], {});
 
+  // Calling noSuchMethod itself, badly.
+  testInvocationMirror(n.noSuchMethod(), "noSuchMethod", [], {});
+  testInvocationMirror(n.noSuchMethod(37, 42), "noSuchMethod", [37, 42], {});
+  testInvocationMirror(n.noSuchMethod(37, x:42),
+                       "noSuchMethod", [37], {"x": 42});
+  testInvocationMirror(n.noSuchMethod(x:42), "noSuchMethod", [], {"x": 42});
+
   // Closurizing a method means that calling it badly will not hit the
   // original receivers noSuchMethod, only the one inherited from Object
   // by the closure object.
@@ -143,6 +149,71 @@
                 (e) => e is NoSuchMethodError);
 }
 
+class M extends N {
+  noSuchMethod(InvocationMirror m) { throw "never get here"; }
+
+  testSuperCalls() {
+    // Missing property/method access.
+    testInvocationMirror(super.bar, 'bar');
+    testInvocationMirror((){super.bar = 42; return last;}(), 'bar=', [42]);
+    testInvocationMirror(super.bar(), 'bar', [], {});
+    testInvocationMirror(super.bar(42), 'bar', [42], {});
+    testInvocationMirror(super.bar(x: 42), 'bar', [], {"x": 42});
+    testInvocationMirror(super.bar(37, x: 42), 'bar', [37], {"x": 42});
+
+    // Missing operator access.
+    testInvocationMirror(super + 4, '+', [4], {});
+    testInvocationMirror(super - 4, '-', [4], {});
+    testInvocationMirror(-super, 'unary-', [], {});
+    testInvocationMirror(super[42], '[]', [42], {});
+    testInvocationMirror((){super[37] = 42; return last;}(), '[]=', [37, 42], {});
+
+    // Wrong arguments to existing function.
+    testInvocationMirror(super.flif(), "flif", [], {});
+    testInvocationMirror(super.flif(37, 42), "flif", [37, 42], {});
+    testInvocationMirror(super.flif(x: 42), "flif", [], {"x": 42});
+    testInvocationMirror(super.flif(37, x: 42), "flif", [37], {"x": 42});
+    testInvocationMirror((){super.flif = 42; return last;}(), "flif=", [42]);
+
+    testInvocationMirror(super.flaf(37, 42), "flaf", [37, 42], {});
+    testInvocationMirror(super.flaf(x: 42), "flaf", [], {"x": 42});
+    testInvocationMirror(super.flaf(37, x: 42), "flaf", [37], {"x": 42});
+    testInvocationMirror((){super.flaf = 42; return last;}(), "flaf=", [42]);
+
+    testInvocationMirror(super.flof(37, 42), "flof", [37, 42], {});
+    testInvocationMirror(super.flof(x: 42), "flof", [], {"x": 42});
+    testInvocationMirror(super.flof(37, y: 42), "flof", [37], {"y": 42});
+    testInvocationMirror((){super.flof = 42; return last;}(), "flof=", [42]);
+
+    // Reading works.
+    Expect.isTrue(super.flif is Function);
+    Expect.isTrue(super.flaf is Function);
+    Expect.isTrue(super.flof is Function);
+
+    // Writing to read-only fields.
+    testInvocationMirror((){super.wut = 42; return last;}(), "wut=", [42]);
+    testInvocationMirror((){super.plif = 42; return last;}(), "plif=", [42]);
+    testInvocationMirror((){super.plaf = 42; return last;}(), "plaf=", [42]);
+
+    // Calling noSuchMethod itself, badly.
+    testInvocationMirror(super.noSuchMethod(), "noSuchMethod", [], {});
+    testInvocationMirror(super.noSuchMethod(37, 42),
+                         "noSuchMethod", [37, 42], {});
+    testInvocationMirror(super.noSuchMethod(37, x:42),
+                         "noSuchMethod", [37], {"x": 42});
+    testInvocationMirror(super.noSuchMethod(x:42),
+                         "noSuchMethod", [], {"x": 42});
+
+    // Closurizing a method means that calling it badly will not hit the
+    // original receivers noSuchMethod, only the one inherited from Object
+    // by the closure object.
+    Expect.throws(() { var x = super.flif; x(37, 42); },
+                  (e) => e is NoSuchMethodError);
+  }
+}
+
+
+
 // Test the NoSuchMethodError thrown by different incorrect calls.
 testNoSuchMethodErrors() {
   test(Function block) {
@@ -163,10 +234,11 @@
   test(() => o.toString(x: 37));
   test(() => o.hashCode = 42);
   test(() => o.hashCode());  // Thrown by int.noSuchMethod.
-  test(n.flif);  // Extracted method has no noSuchMethod.
+  test(() => (n.flif)());  // Extracted method has no noSuchMethod.
 }
 
 main() {
   testInvocationMirrors();
   testNoSuchMethodErrors();
+  new M().testSuperCalls();
 }
diff --git a/tests/language/issue7513_test.dart b/tests/language/issue7513_test.dart
new file mode 100644
index 0000000..4d503c3
--- /dev/null
+++ b/tests/language/issue7513_test.dart
@@ -0,0 +1,20 @@
+// 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.
+
+// Regression test for issue 7513.
+
+foo(a, b) {
+  b[0] = 0.1;
+  return a * b[0];
+}
+
+main() {
+  var a = 0.1;
+  var b = [0.1];
+  for (var i = 0; i < 10000; i++) {
+    foo(a, b);
+  }
+  Expect.approxEquals(0.01, foo(a, b));
+}
+
diff --git a/tests/language/issue7525_test.dart b/tests/language/issue7525_test.dart
new file mode 100644
index 0000000..c2b44d5
--- /dev/null
+++ b/tests/language/issue7525_test.dart
@@ -0,0 +1,19 @@
+// 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.
+
+// Regression test for issue 7525.
+
+foo() {
+  var ol = <int>[2];
+  (ol as List<int>)[0];
+  int x = (ol as List<int>)[0];
+  return x;
+}
+
+main() {
+  for (int i = 0; i < 5000; i++) {
+    foo();
+  }
+  Expect.equals(2, foo());
+}
diff --git a/tests/language/language.status b/tests/language/language.status
index 04878b6..bd0c1fc 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -20,10 +20,10 @@
 library_juxtaposition_test: Fail # Issue 6877
 gc_test: Pass, Fail # Issue 1487
 pseudo_kw_illegal_test/14: Fail  # Issue 356
-first_class_types_constants_test: Fail # Issue 6282
 method_override2_test/00: Fail # Issue 7076.
 method_override2_test/02: Fail # Issue 7076.
 method_override2_test/03: Fail # Issue 7076.
+cascade_2_test: Fail # Issue 7665.
 
 # These bugs refer currently ongoing language discussions.
 constructor5_test: Fail           # (Discussion ongoing)
@@ -49,21 +49,20 @@
 
 compile_time_constant10_test/none: Fail # issue 5214
 
-invocation_mirror_test: Fail # issue 3326.
-invocation_mirror_indirect_test: Fail # Issue 3326
-super_call4_test: Fail # issue 3326.
-
 export_cyclic_test: Fail, Crash # issue 6060
 duplicate_export_negative_test: Fail # issue 6134
 type_annotation_test/04: Fail # Issue 6970
 type_annotation_test/06: Fail # Issue 6973
 type_annotation_test/09: Fail # Issue 6973
 
+type_parameter_literal_test: Fail # Issue 7551
+
 [ $compiler == none && ($system == macos || $system == linux) && $arch == ia32 && $checked ]
 gc_test: Skip  # Issue 1487, flaky.
 
 [ $compiler == none && $mode == debug ]
 gc_test: Skip  # Takes too long.
+issue7513_test: Crash # Issue 7513
 
 [ $compiler == none && $unchecked ]
 
@@ -87,7 +86,8 @@
 default_factory2_test/01: Fail # Issue 7075.
 
 [ $compiler == dartc ]
-built_in_identifier_prefix_test: Fail # http://dartbug.com/6971
+class_literal_test/none : Fail # Issue 7630.
+
 library_juxtaposition_test: Fail # Issue 6881
 new_expression_type_args_test/0*: Fail # Wrongly reports compile-time error.
 redirecting_factory_infinite_steps_test/01: Fail # http://dartbug.com/6560
@@ -241,11 +241,6 @@
 instantiate_type_variable_negative_test: Fail
 type_variable_static_context_negative_test: Fail
 
-
-# test issue 7081 (assignment to top-level method is warning)
-assign_top_method_negative_test: Fail
-
-
 # test issue 7062 (assignment to final variable is a static warning)
 final_for_in_variable_test/01: Fail
 final_param_negative_test: Fail
@@ -277,6 +272,9 @@
 prefix12_negative_test: Fail
 prefix2_negative_test: Fail
 
+# test issue 7523 (const declared without type, so not-a-function warning should not be reported)
+call_through_getter_test: Fail
+
 
 
 #
@@ -323,6 +321,8 @@
 *: Skip
 
 [ $compiler == dart2dart ]
+class_cycle_test/02: Fail # Issue 7468 inherited from dart2js.
+class_cycle_test/03: Fail # Issue 7468 inherited from dart2js.
 built_in_identifier_prefix_test: Fail # Inherited from dart2js.
 const_factory_redirection_test: Fail # http://dartbug.com/6894
 compile_time_constant_h_test: Fail
@@ -479,7 +479,7 @@
 constructor5_test: Fail
 constructor6_test: Fail
 closure_in_initializer_test: Fail
-gc_test: Fail
+gc_test: Pass,Fail
 super_first_constructor_test: Fail
 # VM specific tests.
 disable_privacy_test: Pass, Fail, Ok
@@ -527,13 +527,14 @@
 compile_time_constant_checked3_test/06: Fail, OK
 
 type_error_test: Fail, OK # VM bug: http://dartbug.com/5280
-
-# This is a VM error when the compiled code is run.
-invocation_mirror_test: Fail # issue 3326.
-invocation_mirror_indirect_test: Fail # issue 3326.
-super_call4_test: Fail # issue 3326.
+type_parameter_literal_test: Fail
 
 [ $compiler == dart2dart && $minified ]
+# TODO(tball): Assign proper bug numbers.
+class_literal_test/none: Fail
+
 import_core_prefix_test: Pass
 prefix22_test: Pass
-invocation_mirror2_test: Fail
+invocation_mirror_test: Fail, OK # hardcoded names.
+invocation_mirror2_test: Fail, OK # hardcoded names.
+super_call4_test: Fail, OK # hardcoded names.
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index be05302..12fa00e 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -3,6 +3,7 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dart2js || $compiler == dart2dart ]
+cascade_2_test: Fail # Issue 7689
 class_literal_test/01: Fail # Class literals are expression now; delete this test.
 class_literal_test/02: Fail # Class literals are expression now; delete this test.
 class_literal_test/05: Fail # Class literals are expression now; delete this test.
@@ -32,6 +33,7 @@
 *vm_negative_test: Skip
 
 [ $compiler == dart2js && $checked ]
+prefix16_test: Fail # dartbug.com/7354
 default_factory2_test/01: Pass # For the wrong reasons.
 type_variable_scope_test/none: Fail
 factory_implementation_test/00: Fail
@@ -45,7 +47,7 @@
 type_variable_bounds2_test/03: Fail
 type_variable_bounds2_test/05: Fail
 type_variable_bounds2_test/06: Pass # For the wrong reasons.
-assign_top_method_negative_test: Pass # For the wrong reasons.
+assign_top_method_test: Pass # For the wrong reasons.
 f_bounded_quantification_test/01: Fail
 f_bounded_quantification_test/02: Fail
 closure_type_test: Fail # does not detect type error in checked mode.
@@ -53,7 +55,8 @@
 factory1_test/00: Fail
 factory1_test/01: Fail
 type_annotation_test/09: Fail # Named constructors interpreted as a type.
-callable_test/0*: Fail # Issue 7354
+prefix15_test: Fail # Issue 5022
+local_function2_test: Fail # Issue 5022
 
 [ $compiler == dart2js && $unchecked ]
 default_factory2_test/01: Fail # type arguments on redirecting factory not implemented
@@ -85,6 +88,12 @@
 compile_time_constant_checked3_test/06: Fail, OK
 
 [ $compiler == dart2js ]
+call_operator_test: Fail # Issue 7622.
+class_literal_test: Fail # Issue 7626.
+identical_closure_test: Fail # Fix for identical closure has not been implemented in dart2js yet: https://chromiumcodereview.appspot.com/11612022/
+class_cycle_test/02: Fail # Issue 7468.
+class_cycle_test/03: Fail # Issue 7468.
+invocation_mirror_test: Fail
 built_in_identifier_prefix_test: Fail # http://dartbug.com/6972
 number_identity2_test: Fail # identity of NaN
 new_expression_type_args_test/00: Fail # Wrongly reports compile-time error.
@@ -128,6 +137,7 @@
 
 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
@@ -136,10 +146,6 @@
 positional_parameters_type_test: Fail
 named_parameters_with_object_property_names_test: Fail
 
-# Fail "const EmptyLink<Element>" must be a compile-time constant if unchecked on linux.
-# Crash infinite loop on Mac and dart2js checked mode on linux.
-function_type_alias6_test: Crash, Fail
-
 
 # Compilation errors.
 default_factory3_test: Fail # type arguments on redirecting factory not implemented
@@ -159,7 +165,6 @@
 function_type_alias5_test/00: Fail # visitIs for typedefs not implemented
 function_type_alias5_test/01: Fail # visitIs for typedefs not implemented
 function_type_alias5_test/02: Fail # visitIs for typedefs not implemented
-function_type_alias6_test: 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
@@ -218,7 +223,6 @@
 
 
 # Implementation errors (library or generated code).
-generic_deep_test: Fail # Expect.isTrue(false) fails.
 generic_inheritance_test: Fail # Expect.isTrue(false) fails.
 generic_parameterized_extends_test: Fail # Expect.isTrue(false) fails.
 instanceof2_test: Fail # Expect.equals(expected: <true>, actual: <false>) fails.
@@ -244,7 +248,6 @@
 abstract_static_negative_test: Fail # Negative language test.
 abstract_syntax_test/01: Fail # Negative language test.
 abstract_syntax_test/02: Fail # Negative language test.
-assign_top_method_negative_test: Fail # Negative language test.
 const_constructor_syntax_test/04: Fail # Negative language test.
 const_field_negative_test: Fail # Negative language test.
 const_init4_negative_test: Fail # Negative language test.
@@ -278,7 +281,6 @@
 non_const_super_negative_test: Fail # Negative language test.
 number_identifier_negative_test: Fail # Negative language test.
 operator1_negative_test: Fail # Negative language test.
-prefix16_test: Fail
 prefix23_negative_test: Fail # Negative language test.
 pseudo_kw_illegal_test/03: Fail # Negative language test.
 pseudo_kw_illegal_test/14: Fail # Negative language test.
@@ -326,7 +328,7 @@
 const_factory_negative_test: Crash, Fail
 
 [ $compiler == dart2js && $mode == release ]
-assign_top_method_negative_test: Crash
+assign_top_method_test: Fail
 
 
 [ $compiler == dart2js && $runtime == none ]
@@ -347,11 +349,10 @@
 
 
 [ $compiler == dart2js && $runtime == safari ]
-execute_finally8_test: Fail # TODO(ahe): Please triage this failure.
-execute_finally9_test: Fail # TODO(ahe): Please triage this failure.
-null_access_error_test: Fail # TODO(ahe): Please triage this failure.
-string_interpolate_null_test: Fail # TODO(ahe): Please triage this failure.
-arithmetic_test: Skip # BUG(3492): Times out.
+execute_finally8_test: Fail # Issue: 7414
+execute_finally9_test: Fail # Issue: 7414
+null_access_error_test: Fail # Issue: 7414
+string_interpolate_null_test: Fail # Issue: 7414
 call_through_null_getter_test: Fail # Expected: ObjectNotClosureException got: Instance of 'TypeError'
 closure3_test: Fail # Uncaught error: Instance of 'TypeError'
 method_invocation_test: Fail # Uncaught error: Instance of 'TypeError'
@@ -359,6 +360,8 @@
 string_interpolate_npe_test: Fail # Uncaught error: Instance of 'TypeError'
 
 [ $runtime == opera ]
+null_access_error_test: Fail # Issue: 7413
+string_interpolate_null_test: Fail # Issue: 7413
 call_through_null_getter_test: Fail
 closure3_test: Fail
 execute_finally3_test: Fail
diff --git a/tests/language/string_interpolation_and_buffer.dart b/tests/language/string_interpolation_and_buffer.dart
new file mode 100644
index 0000000..2e25375
--- /dev/null
+++ b/tests/language/string_interpolation_and_buffer.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test to ensure that StringBuffer and string interpolation behaves
+// the same and fail fast.
+
+class ToStringWrapper {
+  final value;
+
+  ToStringWrapper(this.value);
+
+  toString() => value;
+}
+
+wrap(value) => new ToStringWrapper(value);
+
+main() {
+  bool checkedMode = false;
+  assert(checkedMode = true);
+  interpolate(object) {
+    var result;
+    if (checkedMode && object != null) {
+      try {
+        result = '${wrap(object)}';
+      } on TypeError {
+        return 'Error';
+      }
+    } else {
+      try {
+        result = '${wrap(object)}';
+      } on ArgumentError {
+        return 'Error';
+      }
+    }
+    Expect.isTrue(result is String);
+    return 'Success';
+  }
+
+  buffer(object) {
+    var sb;
+    if (checkedMode && object != null) {
+      try {
+        sb = new StringBuffer().add(wrap(object));
+      } on TypeError {
+        return 'Error';
+      }
+    } else {
+      try {
+        sb = new StringBuffer().add(wrap(object));
+      } on ArgumentError {
+        return 'Error';
+      }
+      Expect.isTrue(sb.toString() is String);
+    }
+    return 'Success';
+  }
+
+  Expect.equals('Error', interpolate(null));
+  Expect.equals('Success', interpolate(""));
+  Expect.equals('Success', interpolate("string"));
+  Expect.equals('Error', interpolate([]));
+  Expect.equals('Error', interpolate([1]));
+  Expect.equals('Error', interpolate(new Object()));
+
+  Expect.equals('Error', buffer(null));
+  Expect.equals('Success', buffer(""));
+  Expect.equals('Success', buffer("string"));
+  Expect.equals('Error', buffer([]));
+  Expect.equals('Error', buffer([1]));
+  Expect.equals('Error', buffer(new Object()));
+}
diff --git a/tests/language/assign_top_method_negative_test.dart b/tests/language/type_parameter_literal_test.dart
similarity index 62%
rename from tests/language/assign_top_method_negative_test.dart
rename to tests/language/type_parameter_literal_test.dart
index 265b204..64d95eb 100644
--- a/tests/language/assign_top_method_negative_test.dart
+++ b/tests/language/type_parameter_literal_test.dart
@@ -2,9 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-method() { return 0; }
+// Test type parameter literal expressions.
+
+class D<T> {
+  Type getT() {
+    return T;
+  }
+}
 
 main() {
-  // Illegal, can't change a top level method
-  method = () { return 1; };
+  Expect.equals(int, new D<int>().getT());
 }
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index faa8e36..f34f4b9 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -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.
 
-[ $compiler == dart2js || $compiler == dartc ]
+[ $compiler == dart2js ]
 math/*: Skip
 mirrors/*: Skip
 
@@ -16,6 +16,6 @@
 
 [ $compiler == dartc ]
 # lib issue 6322
-crypto/hmac_sha1_test: Fail, OK
-crypto/hmac_sha256_test: Fail, OK
+crypto/hmac_sha1_test: Fail
+crypto/hmac_sha256_test: Fail
 
diff --git a/tests/standalone/black_listed_test.dart b/tests/standalone/black_listed_test.dart
index 224b1fb..fcb80eb 100644
--- a/tests/standalone/black_listed_test.dart
+++ b/tests/standalone/black_listed_test.dart
@@ -6,7 +6,7 @@
 // Test that certain interfaces/classes are blacklisted from being
 // implemented or extended (VM corelib only).
 
-#library("BlackListedTest.dart");
+library BlackListedTest;
 
 class MyBool extends Bool {}  /// 01: compile-time error
 
diff --git a/tests/standalone/byte_array_test.dart b/tests/standalone/byte_array_test.dart
index 9cb447e..da7ed6e 100644
--- a/tests/standalone/byte_array_test.dart
+++ b/tests/standalone/byte_array_test.dart
@@ -5,9 +5,9 @@
 // Dart test program for testing native byte arrays.
 
 // Library tag to be able to run in html test framework.
-#library("ByteArrayTest.dart");
+library ByteArrayTest;
 
-#import('dart:scalarlist');
+import 'dart:scalarlist';
 
 void testCreateUint8ByteArray() {
   Uint8List byteArray;
diff --git a/tests/standalone/crypto/base64_test.dart b/tests/standalone/crypto/base64_test.dart
index a4a020d..a20fd20 100644
--- a/tests/standalone/crypto/base64_test.dart
+++ b/tests/standalone/crypto/base64_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.
 
-#source("../../../sdk/lib/io/base64.dart");
+part "../../../sdk/lib/io/base64.dart";
 
 void main() {
   String line;
diff --git a/tests/standalone/debugger/basic_debugger_test.dart b/tests/standalone/debugger/basic_debugger_test.dart
new file mode 100644
index 0000000..e2a91be
--- /dev/null
+++ b/tests/standalone/debugger/basic_debugger_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This test forks a second vm process that runs this dart script as
+// a debug target.
+// Run this test with option --wire to see the json messages sent
+// between the processes.
+// Run this test with option --verbose to see the stdout and stderr output
+// of the debug target process.
+
+import "debug_lib.dart";
+
+bar(x) {
+  print(x);
+}
+
+foo(i) {
+  bar("baz");
+  print(i);
+}
+
+main() {
+  if (RunScript(testScript)) return;
+  print("Hello from debuggee");
+  foo(42);
+  print("Hello again");
+}
+
+
+// Expected debugger events and commands.
+var testScript = [
+  Breakpoint(),  // Expect a breakpoint event.
+  MatchFrame(0, "main"),  // Top frame in trace is function "main".
+  Step(),
+  Breakpoint(function: "main"),
+  SetBreakpoint(15),  // Set breakpoint a line 15, in function bar.
+  Resume(),
+  Breakpoint(function: "bar"),
+  MatchFrames(["bar", "foo", "main"]),
+  MatchFrame(1, "foo"),
+  Resume(),
+];
\ No newline at end of file
diff --git a/tests/standalone/debugger/debug_lib.dart b/tests/standalone/debugger/debug_lib.dart
new file mode 100644
index 0000000..82a115b
--- /dev/null
+++ b/tests/standalone/debugger/debug_lib.dart
@@ -0,0 +1,530 @@
+// 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 used by debugger wire protocol tests (standalone VM debugging).
+
+library DartDebugger;
+
+import "dart:io";
+import "dart:utf";
+import "dart:json";
+
+// TODO(hausner): need to select a different port number for each
+// test that runs in parallel.
+var debugPort = 5860;
+
+// Whether or not to print debug target process on the console.
+var showDebuggeeOutput = true;
+
+// Whether or not to print the debugger wire messages on the console.
+var verboseWire = false;
+
+// Class to buffer wire protocol data from debug target and
+// break it down to individual json messages.
+class JsonBuffer {
+  String buffer = null;
+
+  append(String s) {
+    if (buffer == null || buffer.length == 0) {
+      buffer = s;
+    } else {
+      buffer = buffer.concat(s);
+    }
+  }
+
+  String getNextMessage() {
+    if (buffer == null) return null;
+    int msgLen = objectLength();
+    if (msgLen == 0) return null;
+    String msg = null;
+    if (msgLen == buffer.length) {
+      msg = buffer;
+      buffer = null;
+    } else {
+      assert(msgLen < buffer.length);
+      msg = buffer.substring(0, msgLen);
+      buffer = buffer.substring(msgLen);
+    }
+    return msg;
+  }
+
+  // Returns the character length of the newxt json message in the
+  // buffer, or 0 if there is only a partial message in the buffer.
+  // The object value must start with '{' and continues to the
+  // matching '}'. No attempt is made to otherwise validate the contents
+  // as JSON. If it is invalid, a later JSON.parse() will fail.
+  int objectLength() {
+    int skipWhitespace(int index) {
+      while (index < buffer.length) {
+        String char = buffer[index];
+        if (char != " " && char != "\n" && char != "\r" && char != "\t") break;
+        index++;
+      }
+      return index;
+    }
+    int skipString(int index) {
+      assert(buffer[index - 1] == '"');
+      while (index < buffer.length) {
+        String char = buffer[index];
+        if (char == '"') return index + 1;
+        if (char == r'\') index++;
+        if (index == buffer.length) return index;
+        index++;
+      }
+      return index;
+    }
+    int index = 0;
+    index = skipWhitespace(index);
+    // Bail out if the first non-whitespace character isn't '{'.
+    if (index == buffer.length || buffer[index] != '{') return 0;
+    int nesting = 0;
+    while (index < buffer.length) {
+      String char = buffer[index++];
+      if (char == '{') {
+        nesting++;
+      } else if (char == '}') {
+        nesting--;
+        if (nesting == 0) return index;
+      } else if (char == '"') {
+        // Strings can contain braces. Skip their content.
+        index = skipString(index);
+      }
+    }
+    return 0;
+  }
+}
+
+
+getJsonValue(Map jsonMsg, String path) {
+  List properties = path.split(new RegExp(":"));
+  assert(properties.length >= 1);
+  var node = jsonMsg;
+  for (int i = 0; i < properties.length; i++) {
+    if (node == null) return null;
+    String property = properties[i];
+    var index = null;
+    if (property.endsWith("]")) {
+      var bracketPos = property.lastIndexOf("[");
+      if (bracketPos <= 0) return null;
+      var indexStr = property.substring(bracketPos + 1, property.length - 1);
+      try {
+        index = int.parse(indexStr);
+      } on FormatException {
+        print("$indexStr is not a valid array index");
+        return null;
+      }
+      property = property.substring(0, bracketPos);
+    }
+    if (node is Map) {
+      node = node[property];
+    } else {
+      return null;
+    }
+    if (index != null) {
+      if (node is List && node.length > index) {
+        node = node[index];
+      } else {
+        return null;
+      }
+    }
+  }
+  return node;
+}
+
+
+// Returns true if [template] is a subset of [map].
+bool matchMaps(Map template, Map msg) {
+  bool isMatch = true;
+  template.forEach((k, v) {
+    if (msg.containsKey(k)) {
+      var receivedValue = msg[k];
+      if ((v is Map) && (receivedValue is Map)) {
+        if (!matchMaps(v, receivedValue)) isMatch = false;
+      } else if (v == null) {
+        // null in the template matches everything.
+      } else if (v != receivedValue) {
+        isMatch = false;
+      }
+    } else {
+      isMatch = false;
+    }
+  });
+  return isMatch;
+}
+
+
+class BreakpointEvent {
+  String functionName;
+  var template = { "event": "paused", "params": { "reason": "breakpoint" }};
+
+  BreakpointEvent({String function: null}) {
+    functionName = function;
+  }
+
+  void match(Debugger debugger) {
+    var msg = debugger.currentMessage;
+    if (!matchMaps(template, msg)) {
+      debugger.error("message does not match $template");
+    }
+    var name = getJsonValue(msg, "params:callFrames[0]:functionName");
+    if (name == "main") {
+      // Extract script url of debugged script.
+      var scriptUrl = getJsonValue(msg, "params:callFrames[0]:location:url");
+      assert(scriptUrl != null);
+      debugger.scriptUrl = scriptUrl;
+    }
+    if (functionName != null) {
+      var name = getJsonValue(msg, "params:callFrames[0]:functionName");
+      if (functionName != name) {
+        debugger.error("expected function name $functionName but got $name");
+      }
+    }
+  }
+}
+
+Breakpoint({String function}) {
+  return new BreakpointEvent(function: function);
+}
+
+class Matcher {
+  void match(Debugger debugger);
+}
+
+class FrameMatcher extends Matcher {
+  int frameIndex;
+  List<String> functionNames;
+
+  FrameMatcher(this.frameIndex, this.functionNames);
+
+  void match(Debugger debugger) {
+    var msg = debugger.currentMessage;
+    List frames = getJsonValue(msg, "params:callFrames");
+    assert(frames != null);
+    if (frames.length < functionNames.length) {
+      debugger.error("stack trace not long enough "
+                     "to match ${functionNames.length} frames");
+      return;
+    }
+    for (int i = 0; i < functionNames.length; i++) {
+      var idx = i + frameIndex;
+      var property = "params:callFrames[$idx]:functionName";
+      var name = getJsonValue(msg, property);
+      if (name == null) {
+        debugger.error("property '$property' not found");
+        return;
+      }
+      if (name != functionNames[i]) {
+        debugger.error("call frame $idx: "
+          "expected function name '${functionNames[i]}' but found '$name'");
+        return;
+      }
+    }
+  }
+}
+
+
+MatchFrame(int frameIndex, String functionName) {
+  return new FrameMatcher(frameIndex, [ functionName ]);
+}
+
+MatchFrames(List<String> functionNames) {
+  return new FrameMatcher(0, functionNames);
+}
+
+
+class Command {
+  var template;
+  Command();
+  Command.resume() {
+    template = {"id": 0, "command": "resume", "params": {"isolateId": 0}};
+  }
+  Command.step() {
+    template = {"id": 0, "command": "stepOver", "params": {"isolateId": 0}};
+  }
+  Map makeMsg(int cmdId, int isolateId) {
+    template["id"] = cmdId;
+    if ((template["params"] != null)
+        && (template["params"]["isolateId"] != null)) {
+      template["params"]["isolateId"] = isolateId;
+    }
+    return template;
+  }
+
+  void send(Debugger debugger) {
+    template["id"] = debugger.seqNr;
+    template["params"]["isolateId"] = debugger.isolateId;
+    debugger.sendMessage(template);
+  }
+
+  void matchResponse(Debugger debugger) {
+    Map response = debugger.currentMessage;
+    var id = template["id"];
+    assert(id != null && id >= 0);
+    if (response["id"] != id) {
+      debugger.error("Expected messaged id $id but got ${response["id"]}.");
+    }
+  }
+}
+
+Resume() => new Command.resume();
+Step() => new Command.step();
+
+class SetBreakpointCommand extends Command {
+  int line;
+  SetBreakpointCommand(int this.line) {
+    template = {"id": 0,
+                "command": "setBreakpoint",
+                "params": { "isolateId": 0,
+                            "url": null,
+                            "line": null }};
+  }
+  void send(Debugger debugger) {
+    assert(debugger.scriptUrl != null);
+    template["params"]["url"] = debugger.scriptUrl;
+    template["params"]["line"] = line;
+    super.send(debugger);
+  }
+}
+
+SetBreakpoint(int line) => new SetBreakpointCommand(line);
+
+
+// A debug script is a list of Event, Matcher and Command objects.
+class DebugScript {
+  List entries;
+  int currentIndex;
+  DebugScript(List this.entries) : currentIndex = 0;
+  get currentEntry {
+    if (currentIndex < entries.length) return entries[currentIndex];
+    return null;
+  }
+  advance() {
+    currentIndex++;
+  }
+}
+
+
+class Debugger {
+  // Debug target process properties.
+  Process targetProcess;
+  int portNumber;
+  Socket socket;
+  OutputStream to;
+  StringInputStream from;
+  JsonBuffer responses = new JsonBuffer();
+
+  DebugScript script;
+  int seqNr = 0;  // Sequence number of next debugger command message.
+  Command lastCommand = null;  // Most recent command sent to target.
+  List<String> errors = new List();
+
+  // Data collected from debug target.
+  Map currentMessage = null;  // Currently handled message sent by target.
+  String scriptUrl = null;
+  bool shutdownEventSeen = false;
+  int isolateId = 0;
+  
+  Debugger(this.targetProcess, this.portNumber) {
+    var targetStdout = new StringInputStream(targetProcess.stdout);
+    targetStdout.onLine = () {
+      var s = targetStdout.readLine();
+      if (showDebuggeeOutput) {
+        print("TARG: $s");
+      }
+    };
+    var targetStderr = new StringInputStream(targetProcess.stderr);
+    targetStderr.onLine = () {
+      var s = targetStderr.readLine();
+      if (showDebuggeeOutput) {
+        print("TARG: $s");
+      }
+    };
+  }
+
+  // Handle debugger events for which there is no explicit
+  // entry in the debug script, for example isolate create and
+  // shutdown events, breakpoint resolution events, etc.
+  bool handleImplicitEvents(Map<String,dynamic> msg) {
+    if (msg["event"] == "isolate") {
+      if (msg["params"]["reason"] == "created") {
+        isolateId = msg["params"]["id"];
+        assert(isolateId != null);
+        print("Debuggee isolate id $isolateId created.");
+      } else if (msg["params"]["reason"] == "shutdown") {
+        print("Debuggee isolate id ${msg["params"]["id"]} shut down.");
+        shutdownEventSeen = true;
+        if (script.currentEntry != null) {
+          error("Premature isolate shutdown event seen.");
+        }
+      }
+      return true;
+    } else if (msg["event"] == "breakpointResolved") {
+      // Ignore the event. We may want to maintain a table of
+      // breakpoints in the future.
+      return true;
+    }
+    return false;
+  }
+
+  // Handle one JSON message object and match it to the
+  // expected events and responses in the debugging script.
+  void handleMessage(Map<String,dynamic> receivedMsg) {
+    currentMessage = receivedMsg;
+    var isHandled = handleImplicitEvents(receivedMsg);
+    if (isHandled) return;
+
+    if (receivedMsg["id"] != null) {
+      // This is a response to the last command we sent.
+      assert(lastCommand != null);
+      lastCommand.matchResponse(this);
+      lastCommand = null;
+      if (errorsDetected) {
+        error("Error while matching response to debugger command");
+        error("Response received from debug target: $receivedMsg");
+      }
+      return;
+    }
+
+    // This message must be an event that is expected by the script.
+    assert(receivedMsg["event"] != null);
+    if ((script.currentEntry == null) || (script.currentEntry is Command)) {
+      // Error: unexpected event received.
+      error("unexpected event received: $receivedMsg");
+      return;
+    } else {
+      // Match received message with expected event.
+      script.currentEntry.match(this);
+      if (errorsDetected) return;
+      script.advance();
+      while (script.currentEntry is Matcher) {
+        script.currentEntry.match(this);
+        if (errorsDetected) return;
+        script.advance();
+      }
+    }
+  }
+
+  // Send next debugger command in the script, if a response
+  // form the last command has been received and processed.
+  void sendNextCommand() {
+    if (lastCommand == null) {
+      if (script.currentEntry is Command) {
+        script.currentEntry.send(this);
+        lastCommand = script.currentEntry;
+        seqNr++;
+        script.advance();
+      }
+    }
+  }
+
+  // Handle data received over the wire from the debug target
+  // process. Split input from JSON wire format into individual
+  // message objects (maps).
+  void handleMessages() {
+    var msg = responses.getNextMessage();
+    while (msg != null) {
+      if (verboseWire) print("RECV: $msg");
+      var msgObj = JSON.parse(msg);
+      handleMessage(msgObj);
+      if (errorsDetected) {
+        error("Error while handling script entry ${script.currentIndex}");
+        error("Message received from debug target: $msg");
+        close();
+        return;
+      }
+      if (shutdownEventSeen) {
+        close();
+        return;
+      }
+      sendNextCommand();
+      msg = responses.getNextMessage();
+    }
+  }
+
+  runScript(List entries) {
+    script = new DebugScript(entries);
+    openConnection();
+  }
+
+  // Send a debugger command to the target VM.
+  void sendMessage(Map<String,dynamic> msg) {
+    String jsonMsg = JSON.stringify(msg);
+    if (verboseWire) print("SEND: $jsonMsg");
+    to.writeString(jsonMsg, Encoding.UTF_8);
+  }
+
+  bool get errorsDetected => errors.length > 0;
+
+  // Record error message.
+  void error(String s) {
+    errors.add(s);
+  }
+
+  void openConnection() {
+    socket = new Socket("127.0.0.1", portNumber);
+    to = socket.outputStream;
+    from = new StringInputStream(socket.inputStream, Encoding.UTF_8);
+    from.onData = () {
+      try {
+        responses.append(from.read());
+        handleMessages();
+      } catch(e, trace) {
+        print("Unexpected exception:\n$e\n$trace");
+        close();
+      }
+    };
+    from.onClosed = () {
+      print("Connection closed by debug target");
+      close();
+    };
+    from.onError = (e) {
+      print("Error '$e' detected in input stream from debug target");
+      close();
+    };
+  }
+
+  void close() {
+    if (errorsDetected) {
+      for (int i = 0; i < errors.length; i++) print(errors[i]);
+    }
+    to.close();
+    socket.close();
+    targetProcess.kill();
+    print("Target process killed");
+    Expect.isTrue(!errorsDetected);
+    stdin.close();
+    stdout.close();
+    stderr.close();
+  }
+}
+
+
+bool RunScript(List script) {
+  var options = new Options();
+  if (options.arguments.contains("--debuggee")) {
+    return false;
+  }
+  showDebuggeeOutput = options.arguments.contains("--verbose");
+  verboseWire = options.arguments.contains("--wire");
+
+  var targetOpts = [ "--debug:$debugPort" ];
+  if (showDebuggeeOutput) targetOpts.add("--verbose_debug");
+  targetOpts.add(options.script);
+  targetOpts.add("--debuggee");
+
+  Process.start(options.executable, targetOpts).then((Process process) {
+    print("Debug target process started");
+    process.stdin.close();
+    process.stdout.onData = process.stdout.read;
+    process.stderr.onData = process.stderr.read;
+    process.onExit = (int exitCode) {
+      print("Debug target process exited with exit code $exitCode");
+    };
+    var debugger = new Debugger(process, debugPort);
+    stdin.onClosed = () => debugger.close();
+    stdin.onError = (error) => debugger.close();
+    debugger.runScript(script);
+  });
+  return true;
+}
diff --git a/tests/standalone/double_to_int_test.dart b/tests/standalone/double_to_int_test.dart
new file mode 100644
index 0000000..0386644
--- /dev/null
+++ b/tests/standalone/double_to_int_test.dart
@@ -0,0 +1,34 @@
+// 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.
+//
+// Tests optimization: transform double.toInt() to DoubleToSmi
+// unless we encounter a non-Smi result, in which case we deoptimize and
+// optimize it later to DoubleToInt.
+
+
+main() {
+  for (int i = 0; i < 600; i++) {
+    Expect.equals(100, foo(100, 1.2));
+  }
+  // Deoptimize 'foo', d2smi -> d2int.
+  Expect.equals(36507222016 * 2, foo(2, 36507222016.6));
+  for (int i = 0; i < 600; i++) {
+    Expect.equals(100, foo(100, 1.2));
+  }
+  Expect.equals(36507222016 * 2, foo(2, 36507222016.6));
+}
+
+
+foo(n, a) {
+  int k = 0;
+  for (int i = 0; i < n; i++) {
+    k += goo(a);
+  }
+  return k;
+}
+
+
+goo(a) {
+  return a.toInt();
+}
diff --git a/tests/standalone/float_array_test.dart b/tests/standalone/float_array_test.dart
index 6ac8a03..99ffcab 100644
--- a/tests/standalone/float_array_test.dart
+++ b/tests/standalone/float_array_test.dart
@@ -5,9 +5,9 @@
 // Dart test program for testing native float arrays.
 
 // Library tag to be able to run in html test framework.
-#library("FloatArrayTest.dart");
+library FloatArrayTest;
 
-#import('dart:scalarlist');
+import 'dart:scalarlist';
 
 void testCreateFloat32Array() {
   Float32List floatArray;
diff --git a/tests/standalone/int_array_test.dart b/tests/standalone/int_array_test.dart
index dfab86e..e3dfed5 100644
--- a/tests/standalone/int_array_test.dart
+++ b/tests/standalone/int_array_test.dart
@@ -5,9 +5,9 @@
 // Dart test program for testing native int arrays.
 
 // Library tag to be able to run in html test framework.
-#library("IntArrayTest.dart");
+library IntArrayTest;
 
-#import('dart:scalarlist');
+import 'dart:scalarlist';
 
 void testInt32ToSmi() {
   Int32List intArray;
diff --git a/tests/standalone/io/chunked_stream_test.dart b/tests/standalone/io/chunked_stream_test.dart
index 30c9349..9b4d00c 100644
--- a/tests/standalone/io/chunked_stream_test.dart
+++ b/tests/standalone/io/chunked_stream_test.dart
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#import("dart:io");
-#import("dart:isolate");
+import "dart:io";
+import "dart:isolate";
 
 void test1() {
   void testWithChunkSize(var data, int chunkSize, Function testDone) {
diff --git a/tests/standalone/io/compile_all_test.dart b/tests/standalone/io/compile_all_test.dart
index 88e09f8..f82e9af 100644
--- a/tests/standalone/io/compile_all_test.dart
+++ b/tests/standalone/io/compile_all_test.dart
@@ -7,6 +7,6 @@
 //
 // VMOptions=--compile_all
 
-#import("dart:io");
+import "dart:io";
 
 main() => null;
diff --git a/tests/standalone/io/dart_std_io_pipe_test.dart b/tests/standalone/io/dart_std_io_pipe_test.dart
index aa9e89d..e39e65e 100644
--- a/tests/standalone/io/dart_std_io_pipe_test.dart
+++ b/tests/standalone/io/dart_std_io_pipe_test.dart
@@ -10,8 +10,8 @@
 // VMOptions=--short_socket_write
 // VMOptions=--short_socket_read --short_socket_write
 
-#import("dart:io");
-#source("process_test_util.dart");
+import "dart:io";
+import "process_test_util.dart";
 
 void checkFileEmpty(String fileName) {
   RandomAccessFile pipeOut  = new File(fileName).openSync();
diff --git a/tests/standalone/io/directory_error_test.dart b/tests/standalone/io/directory_error_test.dart
index fecb223..3c26749 100644
--- a/tests/standalone/io/directory_error_test.dart
+++ b/tests/standalone/io/directory_error_test.dart
@@ -4,8 +4,8 @@
 //
 // Dart test program for testing error handling in directory I/O.
 
-#import("dart:io");
-#import("dart:isolate");
+import "dart:io";
+import "dart:isolate";
 
 Directory tempDir() {
   return new Directory('').createTempSync();
@@ -139,6 +139,7 @@
 
 void testListNonExistent(Directory temp, Function done) {
   Directory nonExistent = new Directory("${temp.path}/nonExistent");
+  Expect.throws(() => nonExistent.listSync(), (e) => e is DirectoryIOException);
   var lister = nonExistent.list();
   lister.onError = (e) {
     checkListNonExistentFileException(e);
diff --git a/tests/standalone/io/directory_fuzz_test.dart b/tests/standalone/io/directory_fuzz_test.dart
index 625e994..dd6fe0d 100644
--- a/tests/standalone/io/directory_fuzz_test.dart
+++ b/tests/standalone/io/directory_fuzz_test.dart
@@ -5,10 +5,10 @@
 // 'fuzz' test the directory APIs by providing unexpected type
 // arguments. The test passes if the VM does not crash.
 
-#import('dart:io');
-#import('dart:isolate');
+import "dart:io";
+import "dart:isolate";
 
-#import('fuzz_support.dart');
+import "fuzz_support.dart";
 
 fuzzSyncMethods() {
   typeMapping.forEach((k, v) {
@@ -17,6 +17,7 @@
       doItSync(d.existsSync);
       doItSync(d.createSync);
       doItSync(d.deleteSync);
+      doItSync(d.listSync);
       doItSync(() {
         d.createTempSync().deleteSync();
       });
@@ -27,7 +28,8 @@
       });
       typeMapping.forEach((k2, v2) {
         doItSync(() => d.renameSync(v2));
-        doItSync(() => d.list(v2).onError = (e) => null);
+        doItSync(() => d.listSync(recursive: v2));
+        doItSync(() => d.list(recursive: v2).onError = (e) => null);
       });
     });
   });
diff --git a/tests/standalone/io/directory_invalid_arguments_test.dart b/tests/standalone/io/directory_invalid_arguments_test.dart
index 051b0df..029eccd 100644
--- a/tests/standalone/io/directory_invalid_arguments_test.dart
+++ b/tests/standalone/io/directory_invalid_arguments_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.
 
-#import("dart:io");
+import "dart:io";
 
 class DirectoryInvalidArgumentsTest {
   static void testFailingList(Directory d, var recursive) {
@@ -39,8 +39,12 @@
       Expect.isTrue(e is ArgumentError);
     }
     testFailingList(d, false);
+    Expect.throws(() => d.listSync(recursive: true),
+                  (e) => e is ArgumentError);
     d = new Directory(".");
     testFailingList(d, 1);
+    Expect.throws(() => d.listSync(recursive: 1),
+                  (e) => e is ArgumentError);
   }
 
   static void testMain() {
diff --git a/tests/standalone/io/directory_list_nonexistent_test.dart b/tests/standalone/io/directory_list_nonexistent_test.dart
new file mode 100644
index 0000000..81c9ac0
--- /dev/null
+++ b/tests/standalone/io/directory_list_nonexistent_test.dart
@@ -0,0 +1,47 @@
+// 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.
+//
+// Directory listing test that tests listSync on a missing directory.
+//
+// TODO(7157): Merge this test into directory_test.dart testListNonExistent()
+// when it no longer crashes on Windows, when issue 7157 is resolved.
+
+import "dart:io";
+import "dart:isolate";
+
+void testListNonExistent() {
+  new Directory("").createTemp().then((d) {
+    d.delete().then((ignore) {
+      Expect.throws(() => d.listSync(), (e) => e is DirectoryIOException);
+      Expect.throws(() => d.listSync(recursive: true),
+                    (e) => e is DirectoryIOException);
+    });
+  });
+}
+
+void testListTooLongName() {
+  new Directory("").createTemp().then((d) {
+    var subDirName = 'subdir';
+    var subDir = new Directory("${d.path}/$subDirName");
+    subDir.create().then((ignore) {
+      // Construct a long string of the form
+      // 'tempdir/subdir/../subdir/../subdir'.
+      var buffer = new StringBuffer();
+      buffer.add(subDir.path);
+      for (var i = 0; i < 1000; i++) {
+        buffer.add("/../${subDirName}");
+      }
+      var long = new Directory("${buffer.toString()}");
+      Expect.throws(() => long.listSync(),
+                    (e) => e is DirectoryIOException);
+      Expect.throws(() => long.listSync(recursive: true),
+                    (e) => e is DirectoryIOException);
+    });
+  });
+}
+
+void main() {
+  testListNonExistent();
+  testListTooLongName();
+}
diff --git a/tests/standalone/io/directory_test.dart b/tests/standalone/io/directory_test.dart
index f3bd2bd..825cb9c 100644
--- a/tests/standalone/io/directory_test.dart
+++ b/tests/standalone/io/directory_test.dart
@@ -4,8 +4,8 @@
 //
 // Directory listing test.
 
-#import("dart:io");
-#import("dart:isolate");
+import "dart:io";
+import "dart:isolate";
 
 class DirectoryTest {
   static void testListing() {
@@ -14,6 +14,7 @@
 
     Directory directory = new Directory("").createTempSync();
     Directory subDirectory = new Directory("${directory.path}/subdir");
+    Expect.isTrue('$directory'.contains(directory.path));
     Expect.isFalse(subDirectory.existsSync());
     subDirectory.createSync();
     Expect.isTrue(subDirectory.existsSync());
@@ -21,6 +22,31 @@
     Expect.isFalse(f.existsSync());
     f.createSync();
 
+    void testSyncListing(bool recursive) {
+      for (var entry in directory.listSync(recursive: recursive)) {
+        if (entry is File) {
+          Expect.isTrue(entry.name.contains(directory.path));
+          Expect.isTrue(entry.name.contains('subdir'));
+          Expect.isTrue(entry.name.contains('file.txt'));
+          Expect.isFalse(listedFile);
+          listedFile = true;
+        } else {
+          Expect.isTrue(entry is Directory);
+          Expect.isTrue(entry.path.contains(directory.path));
+          Expect.isTrue(entry.path.contains('subdir'));
+          Expect.isFalse(listedDir);
+          listedDir = true;
+        }
+      }
+      Expect.equals(listedFile, recursive);
+      Expect.isTrue(listedDir);
+      listedFile = false;
+      listedDir = false;
+    }
+
+    testSyncListing(true);
+    testSyncListing(false);
+
     var lister = directory.list(recursive: true);
 
     lister.onDir = (dir) {
diff --git a/tests/standalone/io/echo_server_stream_test.dart b/tests/standalone/io/echo_server_stream_test.dart
index 19ffcca..200dfd5 100644
--- a/tests/standalone/io/echo_server_stream_test.dart
+++ b/tests/standalone/io/echo_server_stream_test.dart
@@ -9,9 +9,11 @@
 // VMOptions=--short_socket_write
 // VMOptions=--short_socket_read --short_socket_write
 
-#import("dart:io");
-#import("dart:isolate");
-#source("testing_server.dart");
+library ServerTest;
+
+import "dart:io";
+import "dart:isolate";
+part "testing_server.dart";
 
 class EchoServerGame {
 
diff --git a/tests/standalone/io/echo_server_test.dart b/tests/standalone/io/echo_server_test.dart
index c002971..27c3128 100644
--- a/tests/standalone/io/echo_server_test.dart
+++ b/tests/standalone/io/echo_server_test.dart
@@ -9,10 +9,10 @@
 // VMOptions=--short_socket_write
 // VMOptions=--short_socket_read --short_socket_write
 
-#library("EchoServerTest.dart");
-#import("dart:io");
-#import("dart:isolate");
-#source("testing_server.dart");
+library ServerTest;
+import "dart:io";
+import "dart:isolate";
+part "testing_server.dart";
 
 class EchoServerTest {
 
diff --git a/tests/standalone/io/file_error_test.dart b/tests/standalone/io/file_error_test.dart
index 218879e..4cda95a 100644
--- a/tests/standalone/io/file_error_test.dart
+++ b/tests/standalone/io/file_error_test.dart
@@ -4,8 +4,8 @@
 //
 // Dart test program for testing error handling in file I/O.
 
-#import("dart:io");
-#import("dart:isolate");
+import "dart:io";
+import "dart:isolate";
 
 Directory tempDir() {
   return new Directory('').createTempSync();
diff --git a/tests/standalone/io/file_fuzz_test.dart b/tests/standalone/io/file_fuzz_test.dart
index abb6fc0..313575e 100644
--- a/tests/standalone/io/file_fuzz_test.dart
+++ b/tests/standalone/io/file_fuzz_test.dart
@@ -5,10 +5,10 @@
 // 'fuzz' test the file APIs by providing unexpected type arguments. The test
 // passes if the VM does not crash.
 
-#import('dart:io');
-#import('dart:isolate');
+import "dart:io";
+import "dart:isolate";
 
-#import('fuzz_support.dart');
+import "fuzz_support.dart";
 
 fuzzSyncMethods() {
   typeMapping.forEach((k, v) {
diff --git a/tests/standalone/io/file_input_stream_test.dart b/tests/standalone/io/file_input_stream_test.dart
index 1b7475d..70834fd 100644
--- a/tests/standalone/io/file_input_stream_test.dart
+++ b/tests/standalone/io/file_input_stream_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 // Testing file input stream, VM-only, standalone test.
 
-#import("dart:io");
-#import("dart:isolate");
+import "dart:io";
+import "dart:isolate";
 
 // Helper method to be able to run the test from the runtime
 // directory, or the top directory.
diff --git a/tests/standalone/io/file_invalid_arguments_test.dart b/tests/standalone/io/file_invalid_arguments_test.dart
index fc5c63f..f335ac6 100644
--- a/tests/standalone/io/file_invalid_arguments_test.dart
+++ b/tests/standalone/io/file_invalid_arguments_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.
 
-#import("dart:io");
+import "dart:io";
 
 class FileTest {
   static void testReadListInvalidArgs(buffer, offset, length) {
diff --git a/tests/standalone/io/file_output_stream_test.dart b/tests/standalone/io/file_output_stream_test.dart
index 412ea5c..88b314c 100644
--- a/tests/standalone/io/file_output_stream_test.dart
+++ b/tests/standalone/io/file_output_stream_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 // Testing file input stream, VM-only, standalone test.
 
-#import("dart:io");
-#import("dart:isolate");
+import "dart:io";
+import "dart:isolate";
 
 void testOpenOutputStreamSync() {
   Directory tempDirectory = new Directory('').createTempSync();
diff --git a/tests/standalone/io/file_system_links_test.dart b/tests/standalone/io/file_system_links_test.dart
index 63c6a4d..361f7e6 100644
--- a/tests/standalone/io/file_system_links_test.dart
+++ b/tests/standalone/io/file_system_links_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.
 
-#import('dart:io');
+import "dart:io";
 
 
 createLink(String dst, String link, bool symbolic, void callback()) {
@@ -127,6 +127,21 @@
   createLink(temp2.path, y, true, () {
     var files = [];
     var dirs = [];
+    for (var entry in temp.listSync(recursive:true)) {
+      if (entry is File) {
+        files.add(entry.name);
+      } else {
+        Expect.isTrue(entry is Directory);
+        dirs.add(entry.path);
+      }
+    }
+    Expect.equals(1, files.length);
+    Expect.isTrue(files[0].endsWith(x));
+    Expect.equals(1, dirs.length);
+    Expect.isTrue(dirs[0].endsWith(y));
+
+    files = [];
+    dirs = [];
     var lister = temp.list(recursive: true);
     lister.onFile = (f) => files.add(f);
     lister.onDir = (d) => dirs.add(d);
@@ -150,6 +165,8 @@
   var doesNotExist = 'this_thing_does_not_exist';
   new File(x).createSync();
   createLink(doesNotExist, link, true, () {
+    Expect.throws(() => temp.listSync(recursive: true),
+                  (e) => e is DirectoryIOException);
     var files = [];
     var dirs = [];
     var errors = [];
diff --git a/tests/standalone/io/file_test.dart b/tests/standalone/io/file_test.dart
index 2cfd32d..26ec50a 100644
--- a/tests/standalone/io/file_test.dart
+++ b/tests/standalone/io/file_test.dart
@@ -4,8 +4,8 @@
 //
 // Dart test program for testing file I/O.
 
-#import("dart:io");
-#import("dart:isolate");
+import "dart:io";
+import "dart:isolate";
 
 class MyListOfOneElement implements List {
   int _value;
@@ -44,6 +44,7 @@
     // Read a file and check part of it's contents.
     String filename = getFilename("bin/file_test.cc");
     File file = new File(filename);
+    Expect.isTrue('$file'.contains(file.name));
     InputStream input = file.openInputStream();
     input.onData = () {
       List<int> buffer = new List<int>(42);
diff --git a/tests/standalone/io/file_write_as_test.dart b/tests/standalone/io/file_write_as_test.dart
index 5212b79..466c06b 100644
--- a/tests/standalone/io/file_write_as_test.dart
+++ b/tests/standalone/io/file_write_as_test.dart
@@ -20,7 +20,7 @@
   var data = 'asdf';
   f.writeAsStringSync(data);
   Expect.equals(data, f.readAsStringSync());
-  f.writeAsStringSync(data, FileMode.APPEND);
+  f.writeAsStringSync(data, mode: FileMode.APPEND);
   Expect.equals('$data$data', f.readAsStringSync());
 }
 
@@ -53,7 +53,7 @@
     Expect.equals(f, file);
     f.readAsString().then((str) {
       Expect.equals(data, str);
-      f.writeAsString(data, FileMode.APPEND).then((file) {
+      f.writeAsString(data, mode: FileMode.APPEND).then((file) {
         Expect.equals(f, file);
         f.readAsString().then((str) {
           Expect.equals('$data$data', str);
diff --git a/tests/standalone/io/fuzz_support.dart b/tests/standalone/io/fuzz_support.dart
index 9cd384f..64f96a7 100644
--- a/tests/standalone/io/fuzz_support.dart
+++ b/tests/standalone/io/fuzz_support.dart
@@ -2,9 +2,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.
 
-#library('fuzz_support');
+library fuzz_support;
 
-#import('dart:io');
+import "dart:io";
 
 const typeMapping = const {
   'null': null,
diff --git a/tests/standalone/io/http_advanced_test.dart b/tests/standalone/io/http_advanced_test.dart
index 165af0b..c08916b 100644
--- a/tests/standalone/io/http_advanced_test.dart
+++ b/tests/standalone/io/http_advanced_test.dart
@@ -7,8 +7,8 @@
 // VMOptions=--short_socket_write
 // VMOptions=--short_socket_read --short_socket_write
 
-#import("dart:isolate");
-#import("dart:io");
+import "dart:isolate";
+import "dart:io";
 
 class TestServerMain {
   TestServerMain()
diff --git a/tests/standalone/io/http_auth_test.dart b/tests/standalone/io/http_auth_test.dart
index 07705de..7272658 100644
--- a/tests/standalone/io/http_auth_test.dart
+++ b/tests/standalone/io/http_auth_test.dart
@@ -2,11 +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.
 
-#import("dart:isolate");
-#import("dart:crypto");
-#import("dart:io");
-#import("dart:uri");
-#import("dart:utf");
+import "dart:isolate";
+import "dart:crypto";
+import "dart:io";
+import "dart:uri";
+import "dart:utf";
 
 class Server {
   HttpServer server;
diff --git a/tests/standalone/io/http_basic_test.dart b/tests/standalone/io/http_basic_test.dart
index 0407046..9ec9a6a 100644
--- a/tests/standalone/io/http_basic_test.dart
+++ b/tests/standalone/io/http_basic_test.dart
@@ -7,8 +7,8 @@
 // VMOptions=--short_socket_write
 // VMOptions=--short_socket_read --short_socket_write
 
-#import("dart:isolate");
-#import("dart:io");
+import "dart:isolate";
+import "dart:io";
 
 class TestServerMain {
   TestServerMain()
diff --git a/tests/standalone/io/http_client_test.dart b/tests/standalone/io/http_client_test.dart
index 1dd2b25..ca1daef 100644
--- a/tests/standalone/io/http_client_test.dart
+++ b/tests/standalone/io/http_client_test.dart
@@ -2,9 +2,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.
 
-#import("dart:io");
-#import("dart:uri");
-#import("dart:isolate");
+import "dart:io";
+import "dart:uri";
+import "dart:isolate";
 
 void testGoogle() {
   HttpClient client = new HttpClient();
diff --git a/tests/standalone/io/http_connection_close_test.dart b/tests/standalone/io/http_connection_close_test.dart
index c46dd41..1e10223 100644
--- a/tests/standalone/io/http_connection_close_test.dart
+++ b/tests/standalone/io/http_connection_close_test.dart
@@ -3,9 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 //
 
-#import("dart:isolate");
-#import("dart:io");
-#import("dart:uri");
+import "dart:isolate";
+import "dart:io";
+import "dart:uri";
 
 void testHttp10Close(bool closeRequest) {
   HttpServer server = new HttpServer();
diff --git a/tests/standalone/io/http_connection_header_test.dart b/tests/standalone/io/http_connection_header_test.dart
index ead2067..03c7d93 100644
--- a/tests/standalone/io/http_connection_header_test.dart
+++ b/tests/standalone/io/http_connection_header_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 //
 
-#import("dart:isolate");
-#import("dart:io");
+import "dart:isolate";
+import "dart:io";
 
 void setConnectionHeaders(HttpHeaders headers) {
   headers.add(HttpHeaders.CONNECTION, "my-connection-header1");
diff --git a/tests/standalone/io/http_connection_info_test.dart b/tests/standalone/io/http_connection_info_test.dart
index 0583d60..627d0fc 100644
--- a/tests/standalone/io/http_connection_info_test.dart
+++ b/tests/standalone/io/http_connection_info_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.
 
-#import("dart:io");
+import "dart:io";
 
 void testHttpConnectionInfo() {
   HttpServer server = new HttpServer();
diff --git a/tests/standalone/io/http_content_length_test.dart b/tests/standalone/io/http_content_length_test.dart
index 5a082f2..8cfe934 100644
--- a/tests/standalone/io/http_content_length_test.dart
+++ b/tests/standalone/io/http_content_length_test.dart
@@ -1,17 +1,16 @@
 // 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:isolate");
-#import("dart:io");
+import "dart:isolate";
+import "dart:io";
 
 void testNoBody(int totalConnections, bool explicitContentLength) {
   HttpServer server = new HttpServer();
   server.onError = (e) => Expect.fail("Unexpected error $e");
   server.listen("127.0.0.1", 0, backlog: totalConnections);
   server.defaultRequestHandler = (HttpRequest request, HttpResponse response) {
-    Expect.isNull(request.headers.value('content-length'));
+    Expect.equals("0", request.headers.value('content-length'));
     Expect.equals(0, request.contentLength);
     response.contentLength = 0;
     OutputStream stream = response.outputStream;
@@ -48,21 +47,28 @@
   }
 }
 
-void testBody(int totalConnections) {
+void testBody(int totalConnections, bool useHeader) {
   HttpServer server = new HttpServer();
   server.onError = (e) => Expect.fail("Unexpected error $e");
   server.listen("127.0.0.1", 0, backlog: totalConnections);
   server.defaultRequestHandler = (HttpRequest request, HttpResponse response) {
     Expect.equals("2", request.headers.value('content-length'));
     Expect.equals(2, request.contentLength);
-    response.contentLength = 2;
-    OutputStream stream = response.outputStream;
-    stream.writeString("x");
-    Expect.throws(() => response.contentLength = 3, (e) => e is HttpException);
-    stream.writeString("x");
-    Expect.throws(() => stream.writeString("x"), (e) => e is HttpException);
-    stream.close();
-    Expect.throws(() => stream.writeString("x"), (e) => e is HttpException);
+    if (useHeader) {
+      response.contentLength = 2;
+    } else {
+      response.headers.set("content-length", 2);
+    }
+    request.inputStream.onData = request.inputStream.read;
+    request.inputStream.onClosed = () {
+      OutputStream stream = response.outputStream;
+      stream.writeString("x");
+      Expect.throws(() => response.contentLength = 3, (e) => e is HttpException);
+      stream.writeString("x");
+      Expect.throws(() => stream.writeString("x"), (e) => e is HttpException);
+      stream.close();
+      Expect.throws(() => stream.writeString("x"), (e) => e is HttpException);
+    };
   };
 
   int count = 0;
@@ -71,7 +77,12 @@
     HttpClientConnection conn = client.get("127.0.0.1", server.port, "/");
     conn.onError = (e) => Expect.fail("Unexpected error $e");
     conn.onRequest = (HttpClientRequest request) {
-      request.contentLength = 2;
+      if (useHeader) {
+        request.contentLength = 2;
+      } else {
+        request.headers.add(HttpHeaders.CONTENT_LENGTH, "7");
+        request.headers.add(HttpHeaders.CONTENT_LENGTH, "2");
+      }
       OutputStream stream = request.outputStream;
       stream.writeString("x");
       Expect.throws(() => request.contentLength = 3, (e) => e is HttpException);
@@ -94,13 +105,76 @@
   }
 }
 
+void testBodyChunked(int totalConnections, bool useHeader) {
+  HttpServer server = new HttpServer();
+  server.onError = (e) => Expect.fail("Unexpected error $e");
+  server.listen("127.0.0.1", 0, backlog: totalConnections);
+  server.defaultRequestHandler = (HttpRequest request, HttpResponse response) {
+    Expect.isNull(request.headers.value('content-length'));
+    Expect.equals(-1, request.contentLength);
+    if (useHeader) {
+      response.contentLength = 2;
+      response.headers.chunkedTransferEncoding = true;
+    } else {
+      response.headers.set("content-length", 2);
+      response.headers.set("transfer-encoding", "chunked");
+    }
+    request.inputStream.onData = request.inputStream.read;
+    request.inputStream.onClosed = () {
+      OutputStream stream = response.outputStream;
+      stream.writeString("x");
+      Expect.throws(() => response.headers.chunkedTransferEncoding = false,
+                    (e) => e is HttpException);
+      stream.writeString("x");
+      stream.writeString("x");
+      stream.close();
+      Expect.throws(() => stream.writeString("x"), (e) => e is HttpException);
+    };
+  };
+
+  int count = 0;
+  HttpClient client = new HttpClient();
+  for (int i = 0; i < totalConnections; i++) {
+    HttpClientConnection conn = client.get("127.0.0.1", server.port, "/");
+    conn.onError = (e) => Expect.fail("Unexpected error $e");
+    conn.onRequest = (HttpClientRequest request) {
+      if (useHeader) {
+        request.contentLength = 2;
+        request.headers.chunkedTransferEncoding = true;
+      } else {
+        request.headers.add(HttpHeaders.CONTENT_LENGTH, "2");
+        request.headers.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
+      }
+      OutputStream stream = request.outputStream;
+      stream.writeString("x");
+      Expect.throws(() => request.headers.chunkedTransferEncoding = false,
+                    (e) => e is HttpException);
+      stream.writeString("x");
+      stream.writeString("x");
+      stream.close();
+      Expect.throws(() => stream.writeString("x"), (e) => e is HttpException);
+    };
+    conn.onResponse = (HttpClientResponse response) {
+      Expect.isNull(response.headers.value('content-length'));
+      Expect.equals(-1, response.contentLength);
+      response.inputStream.onData = response.inputStream.read;
+      response.inputStream.onClosed = () {
+        if (++count == totalConnections) {
+          client.shutdown();
+          server.close();
+        }
+      };
+    };
+  }
+}
+
 void testHttp10() {
   HttpServer server = new HttpServer();
   server.onError = (e) => Expect.fail("Unexpected error $e");
   server.listen("127.0.0.1", 0, backlog: 5);
   server.defaultRequestHandler = (HttpRequest request, HttpResponse response) {
     Expect.isNull(request.headers.value('content-length'));
-    Expect.equals(0, request.contentLength);
+    Expect.equals(-1, request.contentLength);
     response.contentLength = 0;
     OutputStream stream = response.outputStream;
     Expect.equals("1.0", request.protocolVersion);
@@ -123,6 +197,9 @@
 void main() {
   testNoBody(5, false);
   testNoBody(5, true);
-  testBody(5);
+  testBody(5, false);
+  testBody(5, true);
+  testBodyChunked(5, false);
+  testBodyChunked(5, true);
   testHttp10();
 }
diff --git a/tests/standalone/io/http_head_test.dart b/tests/standalone/io/http_head_test.dart
index 24efb91..a1f91ec 100644
--- a/tests/standalone/io/http_head_test.dart
+++ b/tests/standalone/io/http_head_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.
 
-#import("dart:io");
+import "dart:io";
 
 void testHEAD(int totalConnections) {
   HttpServer server = new HttpServer();
diff --git a/tests/standalone/io/http_headers_state.dart b/tests/standalone/io/http_headers_state_test.dart
similarity index 68%
rename from tests/standalone/io/http_headers_state.dart
rename to tests/standalone/io/http_headers_state_test.dart
index c84c7fa..72e1ddd 100644
--- a/tests/standalone/io/http_headers_state.dart
+++ b/tests/standalone/io/http_headers_state_test.dart
@@ -3,31 +3,34 @@
 // BSD-style license that can be found in the LICENSE file.
 //
 
-#import("dart:isolate");
-#import("dart:io");
+import "dart:isolate";
+import "dart:io";
 
 void test(int totalConnections, [String body]) {
   HttpServer server = new HttpServer();
   server.onError = (e) => Expect.fail("Unexpected error $e");
-  server.listen("127.0.0.1", 0, totalConnections);
+  server.listen("127.0.0.1", 0, backlog: totalConnections);
   server.defaultRequestHandler = (HttpRequest request, HttpResponse response) {
     // Cannot mutate request headers.
     Expect.throws(() => request.headers.add("X-Request-Header", "value"),
                   (e) => e is HttpException);
     Expect.equals("value", request.headers.value("X-Request-Header"));
-    OutputStream stream = response.outputStream;
-    // Can still mutate response headers as long as no data has been sent.
-    response.headers.add("X-Response-Header", "value");
-    if (body != null) {
-      stream.writeString(body);
+    request.inputStream.onData = request.inputStream.read;
+    request.inputStream.onClosed = () {
+      OutputStream stream = response.outputStream;
+      // Can still mutate response headers as long as no data has been sent.
+      response.headers.add("X-Response-Header", "value");
+      if (body != null) {
+        stream.writeString(body);
+        // Cannot mutate response headers when data has been sent.
+        Expect.throws(() => request.headers.add("X-Request-Header", "value2"),
+                      (e) => e is HttpException);
+      }
+      stream.close();
       // Cannot mutate response headers when data has been sent.
-      Expect.throws(() => request.headers.add("X-Request-Header", "value2"),
+      Expect.throws(() => request.headers.add("X-Request-Header", "value3"),
                     (e) => e is HttpException);
-    }
-    stream.close();
-    // Cannot mutate response headers when data has been sent.
-    Expect.throws(() => request.headers.add("X-Request-Header", "value3"),
-                  (e) => e is HttpException);
+    };
   };
 
   int count = 0;
@@ -58,11 +61,15 @@
       Expect.throws(() => response.headers.add("X-Response-Header", "value"),
                    (e) => e is HttpException);
       Expect.equals("value", response.headers.value("X-Response-Header"));
-      count++;
-      if (count == totalConnections) {
-        client.shutdown();
-        server.close();
-      }
+      response.inputStream.onData = response.inputStream.read;
+      response.inputStream.onClosed = () {
+        // Do not close the connections before we have read the full response
+        // bodies for all connections.
+        if (++count == totalConnections) {
+          client.shutdown();
+          server.close();
+        }
+      };
     };
   }
 }
diff --git a/tests/standalone/io/http_proxy_test.dart b/tests/standalone/io/http_proxy_test.dart
index 5ab12b1..8232769 100644
--- a/tests/standalone/io/http_proxy_test.dart
+++ b/tests/standalone/io/http_proxy_test.dart
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#import("dart:io");
-#import("dart:uri");
+import "dart:io";
+import "dart:uri";
 
 class Server {
   HttpServer server;
diff --git a/tests/standalone/io/http_read_test.dart b/tests/standalone/io/http_read_test.dart
index 15e2606..3a62e6a 100644
--- a/tests/standalone/io/http_read_test.dart
+++ b/tests/standalone/io/http_read_test.dart
@@ -7,8 +7,8 @@
 // VMOptions=--short_socket_write
 // VMOptions=--short_socket_read --short_socket_write
 
-#import("dart:isolate");
-#import("dart:io");
+import "dart:isolate";
+import "dart:io";
 
 class TestServerMain {
   TestServerMain()
diff --git a/tests/standalone/io/http_redirect_test.dart b/tests/standalone/io/http_redirect_test.dart
index 1bad27f..3e8bcb4 100644
--- a/tests/standalone/io/http_redirect_test.dart
+++ b/tests/standalone/io/http_redirect_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 //
 
-#import("dart:io");
-#import("dart:uri");
+import "dart:io";
+import "dart:uri";
 
 HttpServer setupServer() {
   HttpServer server = new HttpServer();
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 5d23fc4..d4d009c 100644
--- a/tests/standalone/io/http_server_early_client_close_test.dart
+++ b/tests/standalone/io/http_server_early_client_close_test.dart
@@ -1,5 +1,9 @@
-#import("dart:io");
-#import("dart:isolate");
+// 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";
+import "dart:isolate";
 
 void sendData(List<int> data, int port) {
   Socket socket = new Socket("127.0.0.1", port);
diff --git a/tests/standalone/io/http_server_early_server_close_test.dart b/tests/standalone/io/http_server_early_server_close_test.dart
index d151fa3..f7f9861 100644
--- a/tests/standalone/io/http_server_early_server_close_test.dart
+++ b/tests/standalone/io/http_server_early_server_close_test.dart
@@ -1,5 +1,9 @@
-#import("dart:io");
-#import("dart:isolate");
+// 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";
+import "dart:isolate";
 
 class Server {
   Server() {
diff --git a/tests/standalone/io/http_server_socket_test.dart b/tests/standalone/io/http_server_socket_test.dart
index 24c9712..6a71fd8 100644
--- a/tests/standalone/io/http_server_socket_test.dart
+++ b/tests/standalone/io/http_server_socket_test.dart
@@ -2,9 +2,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.
 
-#import("dart:io");
-#import("dart:isolate");
-#import("dart:math");
+import "dart:io";
+import "dart:isolate";
+import "dart:math";
 
 class ExpectedDataOutputStream implements OutputStream {
   ExpectedDataOutputStream(List<int> this._data,
diff --git a/tests/standalone/io/http_server_test.dart b/tests/standalone/io/http_server_test.dart
index 7cda6f4..8e7424e 100644
--- a/tests/standalone/io/http_server_test.dart
+++ b/tests/standalone/io/http_server_test.dart
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#import("dart:io");
-#import("dart:isolate");
+import "dart:io";
+import "dart:isolate";
 
 void testListenOn() {
   ServerSocket socket = new ServerSocket("127.0.0.1", 0, 5);
diff --git a/tests/standalone/io/http_session_test.dart b/tests/standalone/io/http_session_test.dart
index 1538c2c..51580097 100644
--- a/tests/standalone/io/http_session_test.dart
+++ b/tests/standalone/io/http_session_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.
 
-#import("dart:io");
+import "dart:io";
 
 const SESSION_ID = "DARTSESSID";
 
diff --git a/tests/standalone/io/http_shutdown_test.dart b/tests/standalone/io/http_shutdown_test.dart
index 1d19e96..077eb83 100644
--- a/tests/standalone/io/http_shutdown_test.dart
+++ b/tests/standalone/io/http_shutdown_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 //
 
-#import("dart:isolate");
-#import("dart:io");
+import "dart:isolate";
+import "dart:io";
 
 void test1(int totalConnections) {
   // Server which just closes immediately.
@@ -34,7 +34,7 @@
 }
 
 
-void test2(int totalConnections) {
+void test2(int totalConnections, int outputStreamWrites) {
   // Server which responds without waiting for request body.
   HttpServer server = new HttpServer();
   server.listen("127.0.0.1", 0, backlog: totalConnections);
@@ -49,7 +49,8 @@
     HttpClientConnection conn = client.get("127.0.0.1", server.port, "/");
     conn.onRequest = (HttpClientRequest request) {
       request.contentLength = -1;
-      request.outputStream.writeString("Hello, world!");
+      for (int i = 0; i < outputStreamWrites; i++)
+        request.outputStream.writeString("Hello, world!");
       request.outputStream.close();
     };
     conn.onResponse = (HttpClientResponse response) {
@@ -62,6 +63,13 @@
         }
       };
     };
+    conn.onError = (e) {
+      count++;
+      if (count == totalConnections) {
+        client.shutdown();
+        server.close();
+      }
+    };
   }
 }
 
@@ -168,8 +176,9 @@
 void main() {
   test1(1);
   test1(10);
-  test2(1);
-  test2(10);
+  test2(1, 10);
+  test2(10, 10);
+  test2(10, 1000);
   test3(1);
   test3(10);
   test4();
diff --git a/tests/standalone/io/https_client_certificate_test.dart b/tests/standalone/io/https_client_certificate_test.dart
new file mode 100644
index 0000000..572b30f
--- /dev/null
+++ b/tests/standalone/io/https_client_certificate_test.dart
@@ -0,0 +1,96 @@
+// 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";
+import "dart:uri";
+import "dart:isolate";
+
+const SERVER_ADDRESS = "127.0.0.1";
+const HOST_NAME = "localhost";
+
+int numClientCertificatesReceived = 0;
+
+Function test(Map options) {
+  Future runTest([var unused]) {
+    var completer = new Completer();
+    HttpsServer server = new HttpsServer();
+    Expect.throws(() => server.port);
+
+    server.defaultRequestHandler =
+        (HttpRequest request, HttpResponse response) {
+      if (request.path == '/true') {
+        // Client certificate sent
+        numClientCertificatesReceived++;
+        Expect.isNotNull(request.certificate);
+        Expect.equals('CN=localhost', request.certificate.subject);
+      } else {
+        Expect.equals('/false', request.path);
+        Expect.isNull(request.certificate);
+      }
+
+      request.inputStream.onClosed = () {
+        response.outputStream.close();
+      };
+    };
+
+    server.listen(SERVER_ADDRESS,
+                  0,
+                  backlog: 5,
+                  certificate_name: 'CN=$HOST_NAME',
+                  requestClientCertificate: true);
+
+    HttpClient client = new HttpClient();
+    Future testConnect(bool sendCertificate) {
+      client.sendClientCertificate = sendCertificate;
+      client.clientCertificate = options['certificateName'];
+      var completer = new Completer();
+      HttpClientConnection conn =
+          client.getUrl(new Uri.fromString(
+              "https://$HOST_NAME:${server.port}/$sendCertificate"));
+      conn.onRequest = (HttpClientRequest request) {
+        request.outputStream.close();
+      };
+      conn.onResponse = (HttpClientResponse response) {
+        Expect.isNotNull(response.certificate);
+        Expect.equals('CN=myauthority', response.certificate.issuer);
+        response.inputStream.onClosed = () {
+          completer.complete(false);  // Chained call will not send cert.
+        };
+      };
+      conn.onError = (Exception e) {
+        Expect.fail("Unexpected error in Https Client: $e");
+      };
+      return completer.future;
+    }
+
+    testConnect(true).chain(testConnect).then((_) {
+        client.shutdown();
+        server.close();
+        Expect.throws(() => server.port);
+        // Run second test with a certificate name.
+        completer.complete(null);
+      });
+    return completer.future;
+  }
+  return runTest;
+}
+
+void InitializeSSL() {
+  var testPkcertDatabase =
+      new Path.fromNative(new Options().script).directoryPath.append('pkcert/');
+  SecureSocket.initialize(database: testPkcertDatabase.toNativePath(),
+                          password: 'dartdart');
+}
+
+void main() {
+  var keepAlive = new ReceivePort();
+  InitializeSSL();
+  // Test two connections in sequence.
+  test({'certificateName': null})()
+      .chain(test({'certificateName': 'localhost_cert'}))
+      .then((_) {
+    Expect.equals(2, numClientCertificatesReceived);
+    keepAlive.close();
+  });
+}
diff --git a/tests/standalone/io/https_client_test.dart b/tests/standalone/io/https_client_test.dart
index 5f230f9..6535e48 100644
--- a/tests/standalone/io/https_client_test.dart
+++ b/tests/standalone/io/https_client_test.dart
@@ -58,7 +58,7 @@
 }
 
 void main() {
-  InitializeSSL();
   testGoogleUrl();
   testBadHostName();
+  Expect.throws(InitializeSSL);
 }
diff --git a/tests/standalone/io/list_input_stream_test.dart b/tests/standalone/io/list_input_stream_test.dart
index 08e2ea0..6826f1b 100644
--- a/tests/standalone/io/list_input_stream_test.dart
+++ b/tests/standalone/io/list_input_stream_test.dart
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#import("dart:io");
-#import("dart:isolate");
+import "dart:io";
+import "dart:isolate";
 
 void testEmptyListInputStream() {
   ListInputStream stream = new ListInputStream();
diff --git a/tests/standalone/io/list_output_stream_test.dart b/tests/standalone/io/list_output_stream_test.dart
index f8e33bb..a9a5b25 100644
--- a/tests/standalone/io/list_output_stream_test.dart
+++ b/tests/standalone/io/list_output_stream_test.dart
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#import("dart:io");
-#import("dart:isolate");
+import "dart:io";
+import "dart:isolate";
 
 void testEmptyListOutputStream1() {
   ListOutputStream stream = new ListOutputStream();
diff --git a/tests/standalone/io/many_directory_operations_test.dart b/tests/standalone/io/many_directory_operations_test.dart
index 4470eaa..7e33403 100644
--- a/tests/standalone/io/many_directory_operations_test.dart
+++ b/tests/standalone/io/many_directory_operations_test.dart
@@ -4,7 +4,7 @@
 //
 // Dart test program for testing using a lot of native port operations.
 
-#import("dart:io");
+import "dart:io";
 
 main() {
   for (var i = 0; i < 10000; i++) {
diff --git a/tests/standalone/io/many_file_operations_test.dart b/tests/standalone/io/many_file_operations_test.dart
index 5829177..294e9c6 100644
--- a/tests/standalone/io/many_file_operations_test.dart
+++ b/tests/standalone/io/many_file_operations_test.dart
@@ -4,7 +4,7 @@
 //
 // Dart test program for testing using a lot of native port operations.
 
-#import("dart:io");
+import "dart:io";
 
 main() {
   for (var i = 0; i < 10000; i++) {
diff --git a/tests/standalone/io/options_test.dart b/tests/standalone/io/options_test.dart
index 59792c7..0c93f03 100644
--- a/tests/standalone/io/options_test.dart
+++ b/tests/standalone/io/options_test.dart
@@ -4,7 +4,7 @@
 // Stress test isolate generation.
 // DartOptions=tests/standalone/io/options_test.dart 10 options_test 20
 
-#import('dart:math');
+import "dart:math";
 
 main() {
   var opts = new Options();
diff --git a/tests/standalone/io/path_test.dart b/tests/standalone/io/path_test.dart
index fbc2ce9..0e20a07 100644
--- a/tests/standalone/io/path_test.dart
+++ b/tests/standalone/io/path_test.dart
@@ -4,7 +4,7 @@
 //
 // Test the Path class in dart:io.
 
-#import("dart:io");
+import "dart:io";
 
 void main() {
   testBaseFunctions();
diff --git a/tests/standalone/io/platform_test.dart b/tests/standalone/io/platform_test.dart
index ada7ff4..96839e3 100644
--- a/tests/standalone/io/platform_test.dart
+++ b/tests/standalone/io/platform_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.
 
-#import("dart:io");
+import "dart:io";
 
 main() {
   Expect.isTrue(Platform.numberOfProcessors > 0);
diff --git a/tests/standalone/io/print_env.dart b/tests/standalone/io/print_env.dart
index 1d29350..997c3a8 100644
--- a/tests/standalone/io/print_env.dart
+++ b/tests/standalone/io/print_env.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.
 
-#import('dart:io');
+import "dart:io";
 
 main() {
   print(Platform.environment[new Options().arguments[0]]);
diff --git a/tests/standalone/io/process_broken_pipe_test.dart b/tests/standalone/io/process_broken_pipe_test.dart
index 611f850..1f42789 100644
--- a/tests/standalone/io/process_broken_pipe_test.dart
+++ b/tests/standalone/io/process_broken_pipe_test.dart
@@ -4,9 +4,9 @@
 //
 // Process test program to test closed stdin from child process.
 
-#import('dart:io');
+import "dart:io";
 
-#source("process_test_util.dart");
+import "process_test_util.dart";
 
 main() {
   // Running dart without arguments makes it close right away.
diff --git a/tests/standalone/io/process_check_arguments_script.dart b/tests/standalone/io/process_check_arguments_script.dart
index 1898356..8a70eda 100644
--- a/tests/standalone/io/process_check_arguments_script.dart
+++ b/tests/standalone/io/process_check_arguments_script.dart
@@ -4,7 +4,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:math";
 
 main() {
   var options = new Options();
diff --git a/tests/standalone/io/process_check_arguments_test.dart b/tests/standalone/io/process_check_arguments_test.dart
index 1e97c8d..23ee444 100644
--- a/tests/standalone/io/process_check_arguments_test.dart
+++ b/tests/standalone/io/process_check_arguments_test.dart
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#import("dart:io");
-#source("process_test_util.dart");
+import "dart:io";
+import "process_test_util.dart";
 
 test(args) {
   var future = Process.start(new Options().executable, args);
diff --git a/tests/standalone/io/process_environment_test.dart b/tests/standalone/io/process_environment_test.dart
index df635ec..c0aaa68 100644
--- a/tests/standalone/io/process_environment_test.dart
+++ b/tests/standalone/io/process_environment_test.dart
@@ -2,9 +2,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.
 
-#import('dart:io');
-#import('dart:isolate');
-#source('process_test_util.dart');
+import "dart:io";
+import "dart:isolate";
+import "process_test_util.dart";
 
 runEnvironmentProcess(Map environment, name, callback) {
   var dartExecutable = new Options().executable;
diff --git a/tests/standalone/io/process_exit_negative_test.dart b/tests/standalone/io/process_exit_negative_test.dart
index caf5cfb..9eede27 100644
--- a/tests/standalone/io/process_exit_negative_test.dart
+++ b/tests/standalone/io/process_exit_negative_test.dart
@@ -3,18 +3,20 @@
 // BSD-style license that can be found in the LICENSE file.
 //
 // Process test program to test that compilation errors in the process
-// exit handler is reported correctly.
+// exit handler are reported correctly.
 
-#import("dart:io");
-#source("process_test_util.dart");
+import "dart:io";
+import "process_test_util.dart";
 
 void main() {
-  Process p = Process.start(getProcessTestFileName(),
+  Future<Process> fp = Process.start(getProcessTestFileName(),
                             const ["0", "0", "0", "0"]);
-  p.onExit = (int s) {
-    print(a.toString());  // Should cause a compilation error here.
-  };
-  // Drain stdout and stderr.
-  p.stdout.onData = p.stdout.read;
-  p.stderr.onData = p.stderr.read;
+  fp.then((p) {
+    p.onExit = (int s) {
+      print(a.toString());  // Should cause a compilation error here.
+    };
+    // Drain stdout and stderr.
+    p.stdout.onData = p.stdout.read;
+    p.stderr.onData = p.stderr.read;
+  });
 }
diff --git a/tests/standalone/io/process_exit_test.dart b/tests/standalone/io/process_exit_test.dart
index a745bfe..f4f9100 100644
--- a/tests/standalone/io/process_exit_test.dart
+++ b/tests/standalone/io/process_exit_test.dart
@@ -4,9 +4,9 @@
 //
 // Process test program to test process communication.
 
-#library("ProcessExitTest");
-#import("dart:io");
-#source("process_test_util.dart");
+library ProcessExitTest;
+import "dart:io";
+import "process_test_util.dart";
 
 testExit() {
   var future = Process.start(getProcessTestFileName(),
diff --git a/tests/standalone/io/process_invalid_arguments_test.dart b/tests/standalone/io/process_invalid_arguments_test.dart
index 35385b4..c58d131 100644
--- a/tests/standalone/io/process_invalid_arguments_test.dart
+++ b/tests/standalone/io/process_invalid_arguments_test.dart
@@ -4,7 +4,7 @@
 //
 // Process test program to test that invalid arguments throw exceptions.
 
-#import("dart:io");
+import "dart:io";
 
 void main() {
   Expect.throws(() => Process.start(["true"], []),
diff --git a/tests/standalone/io/process_kill_test.dart b/tests/standalone/io/process_kill_test.dart
index 400902e..8571952 100644
--- a/tests/standalone/io/process_kill_test.dart
+++ b/tests/standalone/io/process_kill_test.dart
@@ -4,9 +4,9 @@
 //
 // Process test program to test process communication.
 
-#library("ProcessKillTest");
-#import("dart:io");
-#source("process_test_util.dart");
+library ProcessKillTest;
+import "dart:io";
+import "process_test_util.dart";
 
 testKill() {
   // Start a process that will hang waiting for input until killed.
diff --git a/tests/standalone/io/process_path_environment_test.dart b/tests/standalone/io/process_path_environment_test.dart
index 0a29708..3cd4cf6 100644
--- a/tests/standalone/io/process_path_environment_test.dart
+++ b/tests/standalone/io/process_path_environment_test.dart
@@ -5,7 +5,7 @@
 // Test that the executable is looked up on the user's PATH when spawning a
 // process and environment variables are passed in.
 
-#import('dart:io');
+import "dart:io";
 
 main() {
   // Pick an app that we expect to be on the PATH that returns 0 when run with
diff --git a/tests/standalone/io/process_path_test.dart b/tests/standalone/io/process_path_test.dart
index 03debe3..3ce0713 100644
--- a/tests/standalone/io/process_path_test.dart
+++ b/tests/standalone/io/process_path_test.dart
@@ -5,7 +5,7 @@
 // Test that the executable is looked up on the user's PATH when spawning a
 // process.
 
-#import('dart:io');
+import "dart:io";
 
 main() {
   // Pick an app that we expect to be on the PATH that returns 0 when run with
diff --git a/tests/standalone/io/process_run_output_test.dart b/tests/standalone/io/process_run_output_test.dart
index 3111df9..86e833a 100644
--- a/tests/standalone/io/process_run_output_test.dart
+++ b/tests/standalone/io/process_run_output_test.dart
@@ -5,8 +5,8 @@
 // Test script for testing that output is handled correctly for
 // non-interactive processes started with Process.run.
 
-#import("dart:io");
-#source("process_test_util.dart");
+import "dart:io";
+import "process_test_util.dart";
 
 checkOutput(encoding, output) {
   if (encoding == 'ascii') {
diff --git a/tests/standalone/io/process_segfault_test.dart b/tests/standalone/io/process_segfault_test.dart
index e535a69..10d7572 100644
--- a/tests/standalone/io/process_segfault_test.dart
+++ b/tests/standalone/io/process_segfault_test.dart
@@ -4,9 +4,9 @@
 //
 // Process test program to test process communication.
 
-#library("ProcessSegfaultTest");
-#import("dart:io");
-#source("process_test_util.dart");
+library ProcessSegfaultTest;
+import "dart:io";
+import "process_test_util.dart";
 
 testExit() {
   var future = Process.start(getProcessTestFileName(),
diff --git a/sdk/lib/html/templates/dart2js_impl.darttemplate b/tests/standalone/io/process_set_exit_code_script.dart
similarity index 63%
copy from sdk/lib/html/templates/dart2js_impl.darttemplate
copy to tests/standalone/io/process_set_exit_code_script.dart
index 5c62c0e..6a78429 100644
--- a/sdk/lib/html/templates/dart2js_impl.darttemplate
+++ b/tests/standalone/io/process_set_exit_code_script.dart
@@ -2,8 +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.
 
-part of $LIBRARYNAME;
+import "dart:io";
 
-/// @domName $DOMNAME; @docsEditable true
-class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
-$!MEMBERS}
+main() {
+  stdout.writeString("standard out");
+  stderr.writeString("standard error");
+  exitCode = 25;
+}
\ No newline at end of file
diff --git a/tests/standalone/io/process_set_exit_code_test.dart b/tests/standalone/io/process_set_exit_code_test.dart
new file mode 100644
index 0000000..63476ee
--- /dev/null
+++ b/tests/standalone/io/process_set_exit_code_test.dart
@@ -0,0 +1,23 @@
+// 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.
+//
+// Process test program to test process communication.
+
+library ProcessSetExitCodeTest;
+
+import "dart:io";
+
+main() {
+  var options = new Options();
+  var executable = options.executable;
+  var script = options.script;
+  var scriptDirectory = new Path.fromNative(script).directoryPath;
+  var exitCodeScript =
+      scriptDirectory.append('process_set_exit_code_script.dart');
+  Process.run(executable, [exitCodeScript.toNativePath()]).then((result) {
+    Expect.equals("standard out", result.stdout);
+    Expect.equals("standard error", result.stderr);
+    Expect.equals(25, result.exitCode);
+  });
+}
diff --git a/tests/standalone/io/process_start_exception_test.dart b/tests/standalone/io/process_start_exception_test.dart
index d5f6884..4a6d319 100644
--- a/tests/standalone/io/process_start_exception_test.dart
+++ b/tests/standalone/io/process_start_exception_test.dart
@@ -4,7 +4,7 @@
 //
 // Process test program to errors during startup of the process.
 
-#import("dart:io");
+import "dart:io";
 
 testStartError() {
   Future<Process> processFuture =
diff --git a/tests/standalone/io/process_std_io_script.dart b/tests/standalone/io/process_std_io_script.dart
index 2113ac76..bc8b240 100644
--- a/tests/standalone/io/process_std_io_script.dart
+++ b/tests/standalone/io/process_std_io_script.dart
@@ -4,7 +4,7 @@
 //
 // Utility script to echo stdin to stdout or stderr or both.
 
-#import("dart:io");
+import "dart:io";
 
 main() {
   var options = new Options();
diff --git a/tests/standalone/io/process_std_io_script2.dart b/tests/standalone/io/process_std_io_script2.dart
index 7c47150..96d9739 100644
--- a/tests/standalone/io/process_std_io_script2.dart
+++ b/tests/standalone/io/process_std_io_script2.dart
@@ -5,7 +5,7 @@
 // Utility script to echo strings in various formats to stdout or
 // stderr.
 
-#import("dart:io");
+import "dart:io";
 
 writeData(data, encoding, stream) {
   if (stream == "stdout") {
diff --git a/tests/standalone/io/process_stderr_test.dart b/tests/standalone/io/process_stderr_test.dart
index 34cc672..53f9358 100644
--- a/tests/standalone/io/process_stderr_test.dart
+++ b/tests/standalone/io/process_stderr_test.dart
@@ -9,10 +9,10 @@
 // VMOptions=--short_socket_write
 // VMOptions=--short_socket_read --short_socket_write
 
-#import('dart:io');
-#import('dart:math');
+import "dart:io";
+import "dart:math";
 
-#source('process_test_util.dart');
+import "process_test_util.dart";
 
 void test(Future<Process> future, int expectedExitCode) {
   future.then((process) {
diff --git a/tests/standalone/io/process_stdout_test.dart b/tests/standalone/io/process_stdout_test.dart
index 79b3fed..ddf8037 100644
--- a/tests/standalone/io/process_stdout_test.dart
+++ b/tests/standalone/io/process_stdout_test.dart
@@ -9,10 +9,10 @@
 // VMOptions=--short_socket_write
 // VMOptions=--short_socket_read --short_socket_write
 
-#import("dart:io");
-#import("dart:math");
+import "dart:io";
+import "dart:math";
 
-#source("process_test_util.dart");
+import "process_test_util.dart";
 
 void test(Future<Process> future, int expectedExitCode) {
   future.then((process) {
diff --git a/tests/standalone/io/process_test_util.dart b/tests/standalone/io/process_test_util.dart
index 61ad729..6abf0c6 100644
--- a/tests/standalone/io/process_test_util.dart
+++ b/tests/standalone/io/process_test_util.dart
@@ -2,6 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+library process_test_util;
+
+import "dart:io";
+
 String getPlatformExecutableExtension() {
   var os = Platform.operatingSystem;
   if (os == 'windows') return '.exe';
diff --git a/tests/standalone/io/process_working_directory_test.dart b/tests/standalone/io/process_working_directory_test.dart
index 6040b53..b5fe0ee 100644
--- a/tests/standalone/io/process_working_directory_test.dart
+++ b/tests/standalone/io/process_working_directory_test.dart
@@ -4,9 +4,9 @@
 //
 // Process working directory test.
 
-#library("ProcessWorkingDirectoryTest");
-#import("dart:io");
-#source("process_test_util.dart");
+library ProcessWorkingDirectoryTest;
+import "dart:io";
+import "process_test_util.dart";
 
 class ProcessWorkingDirectoryTest {
   static String get fullTestFilePath {
@@ -34,7 +34,7 @@
     });
     processFuture.handleException((error) {
       directory.deleteSync();
-      Expect.fails("Couldn't start process");
+      Expect.fail("Couldn't start process");
     });
   }
 
diff --git a/tests/standalone/io/read_into_const_list_test.dart b/tests/standalone/io/read_into_const_list_test.dart
index c7d1da1..0362f3c 100644
--- a/tests/standalone/io/read_into_const_list_test.dart
+++ b/tests/standalone/io/read_into_const_list_test.dart
@@ -5,7 +5,7 @@
 // Regression test for missing immutability check in the ListSet
 // methods in the API. This allowed overwriting const Lists.
 
-#import("dart:io");
+import "dart:io";
 
 String getFilename(String path) =>
     new File(path).existsSync() ? path : 'runtime/$path';
@@ -13,7 +13,7 @@
 void main() {
   var a = const [0];
   var b = const [0];
-  Expect.isTrue(a === b);
+  Expect.identical(a, b);
 
   String filename = getFilename("bin/file_test.cc");
   File file = new File(filename);
diff --git a/tests/standalone/io/regress-1925.dart b/tests/standalone/io/regress-1925.dart
deleted file mode 100644
index 6e68160..0000000
--- a/tests/standalone/io/regress-1925.dart
+++ /dev/null
@@ -1,58 +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.
-//
-// Regression test for http://code.google.com/p/dart/issues/detail?id=1925.
-//
-// VMOptions=
-// VMOptions=--short_socket_read
-// VMOptions=--short_socket_write
-// VMOptions=--short_socket_read --short_socket_write
-
-#import("dart:io");
-#import("dart:isolate");
-#source("testing_server.dart");
-
-class Regress1925TestServer extends TestingServer {
-
-  void onConnection(Socket socket) {
-    socket.onError = (e) => Expect.fail("Server socket error $e");
-    socket.inputStream.onClosed = () => socket.outputStream.close();
-    socket.inputStream.onData = () {
-      var buffer = new List(1);
-      var read = socket.inputStream.readInto(buffer);
-      Expect.equals(1, read);
-      socket.outputStream.writeFrom(buffer, 0, read);
-    };
-  }
-
-  int _connections = 0;
-}
-
-
-class Regress1925Test extends TestingServerTest {
-  Regress1925Test.start() : super.start(new Regress1925TestServer());
-
-  void run() {
-
-    var count = 0;
-    var buffer = new List(5);
-    Socket socket = new Socket(TestingServer.HOST, _port);
-    socket.onConnect = () {
-      socket.outputStream.write("12345".charCodes);
-      socket.outputStream.close();
-      socket.inputStream.onData = () {
-        count += socket.inputStream.readInto(buffer, count);
-      };
-      socket.inputStream.onClosed = () {
-        Expect.equals(5, count);
-        shutdown();
-      };
-      socket.inputStream.onError = (e) => Expect.fail("Socket error $e");
-    };
-  }
-}
-
-main() {
-  Regress1925Test test = new Regress1925Test.start();
-}
diff --git a/tests/standalone/io/regress-6521.dart b/tests/standalone/io/regress_6521_test.dart
similarity index 96%
rename from tests/standalone/io/regress-6521.dart
rename to tests/standalone/io/regress_6521_test.dart
index a02025d..9d393b7 100644
--- a/tests/standalone/io/regress-6521.dart
+++ b/tests/standalone/io/regress_6521_test.dart
@@ -18,10 +18,6 @@
       req.inputStream.read();
       rsp.outputStream.close();
     };
-    req.inputStream.onClosed = () {
-      client.shutdown();
-      server.close();
-    };
   };
 
   var connection = client.openUrl(
@@ -36,6 +32,8 @@
     response.inputStream.onClosed = () {
       // Wait with closing the client request until the response is done.
       clientRequest.outputStream.close();
+      client.shutdown();
+      server.close();
     };
   };
 }
diff --git a/tests/standalone/io/regress_7679_test.dart b/tests/standalone/io/regress_7679_test.dart
new file mode 100644
index 0000000..b13c249
--- /dev/null
+++ b/tests/standalone/io/regress_7679_test.dart
@@ -0,0 +1,35 @@
+// 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';
+
+main() {
+  Directory temp = new Directory('').createTempSync();
+  File script = new File('${temp.path}/script.dart');
+  script.writeAsStringSync("""
+import 'dart:io';
+
+main() {
+  Directory d = new Directory('a');
+  d.create(recursive: true).then((_) {
+    d.exists().then((result) {
+      Expect.isTrue(result);
+      d = new Directory('b/c/d');
+      d.create(recursive: true).then((_) {
+        d.exists().then((result) {
+          Expect.isTrue(result);
+        });
+      });
+    });
+  });
+}
+""");
+  ProcessOptions options = new ProcessOptions();
+  options.workingDirectory = temp.path;
+  String executable = new File(new Options().executable).fullPathSync();
+  Process.run(executable, ['script.dart'], options).then((result) {
+    temp.deleteSync(recursive: true);
+    Expect.equals(0, result.exitCode);
+  });
+}
diff --git a/tests/standalone/io/secure_socket_bad_certificate_test.dart b/tests/standalone/io/secure_socket_bad_certificate_test.dart
index 43c055b..2f27d9b 100644
--- a/tests/standalone/io/secure_socket_bad_certificate_test.dart
+++ b/tests/standalone/io/secure_socket_bad_certificate_test.dart
@@ -8,8 +8,8 @@
 // www.google.dk.  Add this to the test when we have secure server sockets.
 // See TODO below.
 
-#import("dart:isolate");
-#import("dart:io");
+import "dart:isolate";
+import "dart:io";
 
 void WriteAndClose(Socket socket, String message) {
   var data = message.charCodes;
diff --git a/tests/standalone/io/secure_socket_test.dart b/tests/standalone/io/secure_socket_test.dart
index ed7abf1..b520c22 100644
--- a/tests/standalone/io/secure_socket_test.dart
+++ b/tests/standalone/io/secure_socket_test.dart
@@ -8,8 +8,8 @@
 // www.google.dk.  Add this to the test when we have secure server sockets.
 // See TODO below.
 
-#import("dart:isolate");
-#import("dart:io");
+import "dart:isolate";
+import "dart:io";
 
 void WriteAndClose(Socket socket, String message) {
   var data = message.charCodes;
diff --git a/tests/standalone/io/secure_stream_test.dart b/tests/standalone/io/secure_stream_test.dart
index 8d514e6..63c0fce 100644
--- a/tests/standalone/io/secure_stream_test.dart
+++ b/tests/standalone/io/secure_stream_test.dart
@@ -8,8 +8,8 @@
 // www.google.dk.  Add this to the test when we have secure server sockets.
 // See TODO below.
 
-#import("dart:isolate");
-#import("dart:io");
+import "dart:isolate";
+import "dart:io";
 
 void main() {
   ReceivePort keepAlive = new ReceivePort();
diff --git a/sdk/lib/html/templates/html/dartium/dart_implementation.darttemplate b/tests/standalone/io/skipping_dart2js_compilations_helper.dart
similarity index 62%
copy from sdk/lib/html/templates/html/dartium/dart_implementation.darttemplate
copy to tests/standalone/io/skipping_dart2js_compilations_helper.dart
index 015ae9f..1728e3a 100644
--- a/sdk/lib/html/templates/html/dartium/dart_implementation.darttemplate
+++ b/tests/standalone/io/skipping_dart2js_compilations_helper.dart
@@ -2,11 +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.
 
-// WARNING: Do not edit - generated code.
+import 'dart:io';
 
-part of html;
-
-/// @domName $DOMNAME
-class $CLASSNAME$EXTENDS$IMPLEMENTS {
-$!MEMBERS
+main() {
+  var outputFile = new Options().arguments[0];
+  var file = new File(outputFile);
+  file.createSync();
 }
diff --git a/tests/standalone/io/skipping_dart2js_compilations_test.dart b/tests/standalone/io/skipping_dart2js_compilations_test.dart
new file mode 100644
index 0000000..b74103e
--- /dev/null
+++ b/tests/standalone/io/skipping_dart2js_compilations_test.dart
@@ -0,0 +1,225 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*
+ * This test makes sure that the "skipping Dart2Js compilations if the output is
+ * already up to date" feature does work as it should.
+ * Therefore this test ensures that compilations are only skipped if the last
+ * modified date of the output of a dart2js compilation is newer than
+ *   - the the dart application to compile (including it's dependencies)
+ *   - the dart2js snapshot
+ * Furtheremore it ensure that a compilations is not skipped if any of the
+ * necessary files could not be found (dart2js snapshots, previous dart2js
+ * output (+deps file), dart application)
+ */
+
+import 'dart:io';
+import 'dart:isolate';
+import 'dart:uri';
+import '../../../tools/testing/dart/test_suite.dart' as suite;
+import '../../../tools/testing/dart/test_runner.dart' as runner;
+import '../../../tools/testing/dart/test_options.dart' as options;
+import '../../../tools/testing/dart/status_file_parser.dart' as status;
+
+/**
+ * This class is reponsible for setting up the files necessary for this test
+ * as well as touching a file.
+ */
+class FileUtils {
+  Directory tempDir;
+  File testJs;
+  File testJsDeps;
+  File testDart;
+  File testSnapshot;
+
+  FileUtils({bool createJs,
+             bool createJsDeps,
+             bool createDart,
+             bool createSnapshot}) {
+    tempDir = new Directory('').createTempSync();
+    if (createJs) {
+      testJs = _createFile(testJsFilePath);
+      _writeToFile(testJs, "test.js content");
+    }
+    if (createSnapshot) {
+      testSnapshot = _createFile(testSnapshotFilePath);
+      _writeToFile(testSnapshot, "dart2js snapshot");
+    }
+    if (createDart) {
+      testDart = _createFile(testDartFilePath);
+      _writeToFile(testDart, "dart code");
+    }
+    if (createJsDeps) {
+      testJsDeps = _createFile(testJsDepsFilePath);
+      var path = suite.TestUtils.absolutePath(new Path.fromNative(tempDir.path))
+          .append("test.dart");
+      _writeToFile(testJsDeps, "file://$path");
+    }
+  }
+
+  void cleanup() {
+    if (testJs != null) testJs.deleteSync();
+    if (testJsDeps != null) testJsDeps.deleteSync();
+    if (testDart != null) testDart.deleteSync();
+    if (testSnapshot != null) testSnapshot.deleteSync();
+
+    // if the script did run, it created this file, so we need to delete it
+    File file = new File(scriptOutputPath.toNativePath());
+    if (file.existsSync()) {
+      file.deleteSync();
+    }
+
+    tempDir.deleteSync();
+  }
+
+  Path get scriptOutputPath {
+    return suite.TestUtils.absolutePath(new Path.fromNative(tempDir.path)
+        .append('created_if_command_did_run.txt'));
+  }
+
+  Path get testDartFilePath {
+    return suite.TestUtils.absolutePath(new Path.fromNative(tempDir.path)
+        .append('test.dart'));
+  }
+
+  Path get testJsFilePath {
+    return suite.TestUtils.absolutePath(new Path.fromNative(tempDir.path)
+        .append('test.js'));
+  }
+
+  Path get testJsDepsFilePath {
+    return suite.TestUtils.absolutePath(new Path.fromNative(tempDir.path)
+        .append('test.js.deps'));
+  }
+
+  Path get testSnapshotFilePath {
+    return suite.TestUtils.absolutePath(new Path.fromNative(tempDir.path)
+        .append('test_dart2js.snapshot'));
+  }
+
+  void touchFile(File file) {
+    _writeToFile(file, _readFile(file));
+  }
+
+  void _writeToFile(File file, String content) {
+    if (content != null) {
+      var fd = new File(file.fullPathSync()).openSync(FileMode.WRITE);
+      fd.writeStringSync(content);
+      fd.closeSync();
+    }
+  }
+
+  String _readFile(File file) {
+    return file.readAsStringSync();
+  }
+
+  File _createFile(Path path) {
+    var file = new File(path.toNativePath());
+    file.createSync();
+    return file;
+  }
+}
+
+class TestCompletedHandler {
+  FileUtils fileUtils;
+  Date _expectedTimestamp;
+  bool _shouldHaveRun;
+
+  TestCompletedHandler(FileUtils this.fileUtils, bool this._shouldHaveRun);
+
+  void processCompletedTest(runner.TestCase testCase) {
+    var output = testCase.lastCommandOutput;
+
+    Expect.isFalse(output.unexpectedOutput);
+    Expect.isTrue(output.stderr.length == 0);
+    if (_shouldHaveRun) {
+      Expect.isTrue(output.stdout.length == 0);
+      Expect.isTrue(new File(fileUtils.scriptOutputPath.toNativePath())
+          .existsSync());
+    } else {
+      Expect.isFalse(new File(fileUtils.scriptOutputPath.toNativePath())
+          .existsSync());
+    }
+    fileUtils.cleanup();
+  }
+}
+
+runner.TestCase makeTestCase(String testName,
+                             TestCompletedHandler completedHandler) {
+  var fileUtils = completedHandler.fileUtils;
+  var config = new options.TestOptionsParser().parse(['--timeout', '2'])[0];
+  var scriptDirPath = new Path.fromNative(new Options().script).directoryPath;
+  var createFileScript = scriptDirPath.
+      append('skipping_dart2js_compilations_helper.dart').toNativePath();
+  var executable = new Options().executable;
+  var arguments = [createFileScript, fileUtils.scriptOutputPath.toNativePath()];
+  var bootstrapDeps = [
+      new Uri("file://${fileUtils.testSnapshotFilePath}")];
+  var commands = [new runner.CompilationCommand(
+      fileUtils.testJsFilePath.toNativePath(),
+      false,
+      bootstrapDeps,
+      executable,
+      arguments)];
+  return new runner.TestCase(
+      testName,
+      commands,
+      config,
+      completedHandler.processCompletedTest,
+      new Set<String>.from([status.PASS]));
+}
+
+void main() {
+  var fs_noTestJs = new FileUtils(createJs: false,
+                                  createJsDeps: true,
+                                  createDart: true,
+                                  createSnapshot: true);
+  var fs_noTestJsDeps = new FileUtils(createJs: true,
+                                      createJsDeps: false,
+                                      createDart: true,
+                                      createSnapshot: true);
+  var fs_noTestDart = new FileUtils(createJs: true,
+                                    createJsDeps: true,
+                                    createDart: false,
+                                    createSnapshot: true);
+  var fs_noTestSnapshot = new FileUtils(createJs: true,
+                                        createJsDeps: true,
+                                        createDart: true,
+                                        createSnapshot: false);
+  var fs_notUpToDate_snapshot = new FileUtils(createJs: true,
+                                              createJsDeps: true,
+                                              createDart: true,
+                                              createSnapshot: true);
+  var fs_notUpToDate_dart = new FileUtils(createJs: true,
+                                          createJsDeps: true,
+                                          createDart: true,
+                                          createSnapshot: true);
+  var fs_upToDate = new FileUtils(createJs: true,
+                                  createJsDeps: true,
+                                  createDart: true,
+                                  createSnapshot: true);
+
+  void touchFilesAndRunTests(Timer unused) {
+    fs_notUpToDate_snapshot.touchFile(fs_notUpToDate_snapshot.testSnapshot);
+    fs_notUpToDate_dart.touchFile(fs_notUpToDate_dart.testDart);
+    fs_upToDate.touchFile(fs_upToDate.testJs);
+
+    void runTest(String name, FileUtils fileUtils, bool shouldRun) {
+      new runner.RunningProcess(makeTestCase(name,
+          new TestCompletedHandler(fileUtils, shouldRun))).start();
+    }
+    runTest("fs_noTestJs", fs_noTestJs, true);
+    runTest("fs_noTestJsDeps", fs_noTestJsDeps, true);
+    runTest("fs_noTestDart", fs_noTestDart, true);
+    runTest("fs_noTestSnapshot", fs_noTestSnapshot, true);
+    runTest("fs_notUpToDate_snapshot", fs_notUpToDate_snapshot, true);
+    runTest("fs_notUpToDate_dart", fs_notUpToDate_dart, true);
+    // This is the only test where all dependencies are present and the test.js
+    // file is newer than all the others. So we pass 'false' for shouldRun.
+    runTest("fs_upToDate", fs_upToDate, false);
+  }
+  // We need to wait some time to make sure that the files we 'touch' get a
+  // bigger timestamp than the old ones
+  new Timer(1000, touchFilesAndRunTests);
+}
diff --git a/tests/standalone/io/socket_close_test.dart b/tests/standalone/io/socket_close_test.dart
index 21f4fb7..efb6f20 100644
--- a/tests/standalone/io/socket_close_test.dart
+++ b/tests/standalone/io/socket_close_test.dart
@@ -9,8 +9,8 @@
 //
 // Test socket close events.
 
-#import("dart:io");
-#import("dart:isolate");
+import "dart:io";
+import "dart:isolate";
 
 const SERVERSHUTDOWN = -1;
 const ITERATIONS = 10;
diff --git a/tests/standalone/io/socket_exception_test.dart b/tests/standalone/io/socket_exception_test.dart
index 6323217..8708a4c 100644
--- a/tests/standalone/io/socket_exception_test.dart
+++ b/tests/standalone/io/socket_exception_test.dart
@@ -4,8 +4,8 @@
 //
 // Tests socket exceptions.
 
-#import("dart:isolate");
-#import("dart:io");
+import "dart:isolate";
+import "dart:io";
 
 class SocketExceptionTest {
 
diff --git a/tests/standalone/io/socket_info_test.dart b/tests/standalone/io/socket_info_test.dart
index 0d36140..e35eab6 100644
--- a/tests/standalone/io/socket_info_test.dart
+++ b/tests/standalone/io/socket_info_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.
 
-#import("dart:io");
+import "dart:io";
 
 void testHostAndPort() {
   ServerSocket server = new ServerSocket("127.0.0.1", 0, 5);
diff --git a/tests/standalone/io/socket_invalid_arguments_test.dart b/tests/standalone/io/socket_invalid_arguments_test.dart
index 239ee06..91108b4 100644
--- a/tests/standalone/io/socket_invalid_arguments_test.dart
+++ b/tests/standalone/io/socket_invalid_arguments_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.
 
-#import("dart:io");
+import "dart:io";
 
 class NotAnInteger {
   operator==(other) => other == 1;
diff --git a/tests/standalone/io/socket_many_connections_test.dart b/tests/standalone/io/socket_many_connections_test.dart
index 7c3fd6a..6e718f9 100644
--- a/tests/standalone/io/socket_many_connections_test.dart
+++ b/tests/standalone/io/socket_many_connections_test.dart
@@ -3,10 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 //
 // Test creating a large number of socket connections.
+library ServerTest;
 
-#import("dart:io");
-#import("dart:isolate");
-#source("testing_server.dart");
+import "dart:io";
+import "dart:isolate";
+part "testing_server.dart";
 
 const CONNECTIONS = 200;
 
diff --git a/tests/standalone/io/socket_port_test.dart b/tests/standalone/io/socket_port_test.dart
index 94f3669..841e1444 100644
--- a/tests/standalone/io/socket_port_test.dart
+++ b/tests/standalone/io/socket_port_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.
 
-#import("dart:io");
+import "dart:io";
 
 void testPort() {
   ServerSocket server = new ServerSocket("127.0.0.1", 0, 5);
diff --git a/tests/standalone/io/socket_stream_close_test.dart b/tests/standalone/io/socket_stream_close_test.dart
index ad68f2d..b6fa345 100644
--- a/tests/standalone/io/socket_stream_close_test.dart
+++ b/tests/standalone/io/socket_stream_close_test.dart
@@ -9,8 +9,8 @@
 //
 // Test socket close events.
 
-#import("dart:io");
-#import("dart:isolate");
+import "dart:io";
+import "dart:isolate";
 
 const SERVERSHUTDOWN = -1;
 const ITERATIONS = 10;
diff --git a/tests/standalone/io/status_file_parser_test.dart b/tests/standalone/io/status_file_parser_test.dart
index 700277c..3769682 100644
--- a/tests/standalone/io/status_file_parser_test.dart
+++ b/tests/standalone/io/status_file_parser_test.dart
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#library("StatusFileParserTest");
+library StatusFileParserTest;
 
-#import("dart:io");
-#import("../../../tools/testing/dart/status_file_parser.dart");
+import "dart:io";
+import "../../../tools/testing/dart/status_file_parser.dart";
 
 
 void main() {
diff --git a/tests/standalone/io/stream_pipe_test.dart b/tests/standalone/io/stream_pipe_test.dart
index 8775b86..3468aae 100644
--- a/tests/standalone/io/stream_pipe_test.dart
+++ b/tests/standalone/io/stream_pipe_test.dart
@@ -6,10 +6,11 @@
 // VMOptions=--short_socket_read
 // VMOptions=--short_socket_write
 // VMOptions=--short_socket_read --short_socket_write
+library ServerTest;
 
-#import("dart:io");
-#import("dart:isolate");
-#source("testing_server.dart");
+import "dart:io";
+import "dart:isolate";
+part "testing_server.dart";
 
 // Helper method to be able to run the test from the runtime
 // directory, or the top directory.
diff --git a/tests/standalone/io/string_decoder_test.dart b/tests/standalone/io/string_decoder_test.dart
new file mode 100644
index 0000000..879cf8c
--- /dev/null
+++ b/tests/standalone/io/string_decoder_test.dart
@@ -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.
+
+import "dart:io";
+
+void test() {
+  // Code point U+10FFFF is the largest code point supported by Dart.
+  //var decoder = _StringDecoders.decoder(Encoding.UTF_8);
+  ListInputStream lis = new ListInputStream();
+  lis.write([0xf0, 0x90, 0x80, 0x80]);  // U+10000
+  lis.write([0xf4, 0x8f, 0xbf, 0xbf]);  // U+10FFFF
+  lis.write([0xf4, 0x90, 0x80, 0x80]);  // U+110000
+  lis.write([0xfa, 0x80, 0x80, 0x80, 0x80]);  //  U+2000000
+  lis.write([0xfd, 0x80, 0x80, 0x80, 0x80, 0x80]);  // U+40000000
+  lis.markEndOfStream();
+
+  var sis = new StringInputStream(lis);
+  sis.onData = () {
+    var decoded = sis.read();
+    Expect.equals(7, decoded.length);
+
+    var replacementChar = '?'.charCodeAt(0);
+    Expect.equals(0xd800, decoded.charCodeAt(0));
+    Expect.equals(0xdc00, decoded.charCodeAt(1));
+    Expect.equals(0xdbff, decoded.charCodeAt(2));
+    Expect.equals(0xdfff, decoded.charCodeAt(3));
+    Expect.equals(replacementChar, decoded.charCodeAt(4));
+    Expect.equals(replacementChar, decoded.charCodeAt(5));
+    Expect.equals(replacementChar, decoded.charCodeAt(6));
+  };
+}
+
+void testInvalid() {
+  void invalid(var bytes) {
+    ListInputStream lis = new ListInputStream();
+    lis.write(bytes);
+    lis.markEndOfStream();
+    var sis = new StringInputStream(lis);
+    sis.onData = () { throw "onData not expected"; };
+    sis.onError = (e) { Expect.isTrue(e is DecoderException); };
+    sis.onClosed = () { throw "onClosed not expected"; };
+  }
+
+  invalid([0x80]);
+  invalid([0xff]);
+  invalid([0xf0, 0xc0]);
+}
+
+void main() {
+  test();
+  testInvalid();
+}
diff --git a/tests/standalone/io/string_stream_test.dart b/tests/standalone/io/string_stream_test.dart
index d1369dc..4ef0534 100644
--- a/tests/standalone/io/string_stream_test.dart
+++ b/tests/standalone/io/string_stream_test.dart
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#import("dart:io");
-#import("dart:isolate");
+import "dart:io";
+import "dart:isolate";
 
 void testUtf8() {
   List<int> data = [0x01,
diff --git a/tests/standalone/io/test_extension.dart b/tests/standalone/io/test_extension.dart
index ad86b91..beed87c 100644
--- a/tests/standalone/io/test_extension.dart
+++ b/tests/standalone/io/test_extension.dart
@@ -2,9 +2,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.
 
-#library("test_extension");
+library test_extension;
 
-#import("dart-ext:test_extension");
+import "dart-ext:test_extension";
 
 class Cat {
   Cat(this.x);
diff --git a/tests/standalone/io/test_extension_fail_test.dart b/tests/standalone/io/test_extension_fail_test.dart
index fbb530f..ee379ba 100644
--- a/tests/standalone/io/test_extension_fail_test.dart
+++ b/tests/standalone/io/test_extension_fail_test.dart
@@ -4,7 +4,7 @@
 //
 // Dart test program for testing native extensions.
 
-#import('dart:io');
+import "dart:io";
 
 Future copyFileToDirectory(Path file, Path directory) {
   String src = file.toNativePath();
diff --git a/tests/standalone/io/test_extension_fail_tester.dart b/tests/standalone/io/test_extension_fail_tester.dart
index 8406c0a..628d804 100644
--- a/tests/standalone/io/test_extension_fail_tester.dart
+++ b/tests/standalone/io/test_extension_fail_tester.dart
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#library("test_extension_test");
+library test_extension_test;
 
-#import("dart:isolate");
-#import('test_extension.dart');
+import "dart:isolate";
+import "test_extension.dart";
 
 main() {
   try {
diff --git a/tests/standalone/io/test_extension_test.dart b/tests/standalone/io/test_extension_test.dart
index 276cbc9..88b58f7 100644
--- a/tests/standalone/io/test_extension_test.dart
+++ b/tests/standalone/io/test_extension_test.dart
@@ -4,7 +4,7 @@
 //
 // Dart test program for testing native extensions.
 
-#import('dart:io');
+import "dart:io";
 
 Future copyFileToDirectory(Path file, Path directory) {
   String src = file.toNativePath();
diff --git a/tests/standalone/io/test_extension_tester.dart b/tests/standalone/io/test_extension_tester.dart
index 03991cd..deacbaa 100644
--- a/tests/standalone/io/test_extension_tester.dart
+++ b/tests/standalone/io/test_extension_tester.dart
@@ -2,9 +2,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.
 
-#library("test_extension_test");
+library test_extension_test;
 
-#import('test_extension.dart');
+import "test_extension.dart";
 
 main() {
   Expect.equals('cat 13', new Cat(13).toString(), 'new Cat(13).toString()');
diff --git a/tests/standalone/io/test_runner_exit_code_script.dart b/tests/standalone/io/test_runner_exit_code_script.dart
index 37fbc8e..3bdbb9a 100644
--- a/tests/standalone/io/test_runner_exit_code_script.dart
+++ b/tests/standalone/io/test_runner_exit_code_script.dart
@@ -4,9 +4,9 @@
 
 // Simulates a use of test_progress during a failing run of test.dart.
 
-#import("../../../tools/testing/dart/test_progress.dart");
-#import("../../../tools/testing/dart/test_runner.dart");
-#import("../../../tools/testing/dart/test_options.dart");
+import "../../../tools/testing/dart/test_progress.dart";
+import "../../../tools/testing/dart/test_runner.dart";
+import "../../../tools/testing/dart/test_options.dart";
 
 main() {
   var progressType = new Options().arguments[0];
@@ -31,7 +31,7 @@
   progress.allTestsKnown();
   progress.start(testCase);
   new CommandOutput.fromCase(testCase, dummyCommand, 1, false, false, [], [],
-                             new Date.now().difference(startTime));
+                             new Date.now().difference(startTime), false);
   progress.done(testCase);
   progress.allDone();
 }
diff --git a/tests/standalone/io/test_runner_exit_code_test.dart b/tests/standalone/io/test_runner_exit_code_test.dart
index ced3acc..34e9d0b 100644
--- a/tests/standalone/io/test_runner_exit_code_test.dart
+++ b/tests/standalone/io/test_runner_exit_code_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.
 
-#import('dart:io');
+import "dart:io";
 
 void runTests(String executable, String script, Iterator iterator) {
   if (iterator.hasNext) {
diff --git a/tests/standalone/io/test_runner_test.dart b/tests/standalone/io/test_runner_test.dart
index 044f559..af2fe52 100644
--- a/tests/standalone/io/test_runner_test.dart
+++ b/tests/standalone/io/test_runner_test.dart
@@ -2,12 +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("dart:io");
-#import("dart:isolate");
-#import("../../../tools/testing/dart/test_runner.dart");
-#import("../../../tools/testing/dart/status_file_parser.dart");
-#import("../../../tools/testing/dart/test_options.dart");
-#source("process_test_util.dart");
+import "dart:io";
+import "dart:isolate";
+import "../../../tools/testing/dart/test_runner.dart";
+import "../../../tools/testing/dart/status_file_parser.dart";
+import "../../../tools/testing/dart/test_options.dart";
+import "process_test_util.dart";
 
 class TestController {
   static const int numTests = 4;
diff --git a/tests/standalone/io/testing_server.dart b/tests/standalone/io/testing_server.dart
index 59a0c9e..e37a989 100644
--- a/tests/standalone/io/testing_server.dart
+++ b/tests/standalone/io/testing_server.dart
@@ -2,7 +2,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.
 
-class TestingServer {
+part of ServerTest;
+
+abstract class TestingServer {
 
   static const HOST = "127.0.0.1";
   static const INIT = 0;
@@ -30,7 +32,7 @@
   ServerSocket _server;
 }
 
-class TestingServerTest {
+abstract class TestingServerTest {
 
   TestingServerTest.start(SendPort port)
       : _receivePort = new ReceivePort(),
diff --git a/tests/standalone/io/url_encoding_test.dart b/tests/standalone/io/url_encoding_test.dart
index f491d5c..83765bb 100644
--- a/tests/standalone/io/url_encoding_test.dart
+++ b/tests/standalone/io/url_encoding_test.dart
@@ -17,6 +17,9 @@
   String encodedString = 'foo+bar%20foobar%25%26';
   Expect.equals(_HttpUtils.decodeUrlEncodedString(encodedString),
                 'foo bar foobar%&');
+  encodedString = 'A+%2B+B';
+  Expect.equals(_HttpUtils.decodeUrlEncodedString(encodedString),
+                'A + B');
 }
 
 void testParseQueryString() {
diff --git a/tests/standalone/io/web_socket_test.dart b/tests/standalone/io/web_socket_test.dart
index 5bede0a..87a3223 100644
--- a/tests/standalone/io/web_socket_test.dart
+++ b/tests/standalone/io/web_socket_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 //
 
-#import("dart:io");
-#import("dart:scalarlist");
+import "dart:io";
+import "dart:scalarlist";
 
 void testRequestResponseClientCloses(
     int totalConnections, int closeStatus, String closeReason) {
diff --git a/tests/standalone/io/windows_environment_script.dart b/tests/standalone/io/windows_environment_script.dart
index d94a52c..d0fce49 100644
--- a/tests/standalone/io/windows_environment_script.dart
+++ b/tests/standalone/io/windows_environment_script.dart
@@ -2,11 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#import("dart:io");
+import "dart:io";
 
 main() {
   var scriptDir = Platform.environment['SCRIPTDIR'];
   Expect.isTrue(scriptDir.contains('å'));
+  scriptDir = Platform.environment['ScriptDir'];
+  Expect.isTrue(scriptDir.contains('å'));
   var str = new File('$scriptDir/funky.bat').readAsStringSync();
   Expect.isTrue(str.contains('%~dp0'));
 }
diff --git a/tests/standalone/io/windows_environment_test.dart b/tests/standalone/io/windows_environment_test.dart
index 34dc2a2..2224432 100644
--- a/tests/standalone/io/windows_environment_test.dart
+++ b/tests/standalone/io/windows_environment_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.
 
-#import("dart:io");
+import "dart:io";
 
 main() {
   if (Platform.operatingSystem != 'windows') return;
diff --git a/tests/standalone/medium_integer_test.dart b/tests/standalone/medium_integer_test.dart
index 8abdaee..579f721 100644
--- a/tests/standalone/medium_integer_test.dart
+++ b/tests/standalone/medium_integer_test.dart
@@ -4,7 +4,7 @@
 // Testing Mints. Note that the tests may not work on 64-bit machines,
 // as Smi's would be used to represent many of the numbers.
 
-#library("MediumIntegerTest.dart");
+library MediumIntegerTest;
 
 
 class MediumIntegerTest {
diff --git a/tests/standalone/package/invalid_uri_test.dart b/tests/standalone/package/invalid_uri_test.dart
index 766dc76..7015343 100644
--- a/tests/standalone/package/invalid_uri_test.dart
+++ b/tests/standalone/package/invalid_uri_test.dart
@@ -2,9 +2,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.
 
-#library('invalid_uri_test');
+library invalid_uri_test;
 
-#import('package://lib1.dart'); // Should not contain "//".
+import 'package://lib1.dart'; // Should not contain "//".
 
 void main() {
 }
diff --git a/tests/standalone/package/package1_test.dart b/tests/standalone/package/package1_test.dart
index b331d1c..0640511 100644
--- a/tests/standalone/package/package1_test.dart
+++ b/tests/standalone/package/package1_test.dart
@@ -4,5 +4,5 @@
 
 // PackageRoot=none
 
-#library('package1_test.dart');
-#import('package:package1.dart');
+library package1_test;
+import 'package:package1.dart';
diff --git a/tests/standalone/package/package_isolate_test.dart b/tests/standalone/package/package_isolate_test.dart
index fad10c8..f826c5f 100644
--- a/tests/standalone/package/package_isolate_test.dart
+++ b/tests/standalone/package/package_isolate_test.dart
@@ -10,33 +10,35 @@
 import '../../../pkg/unittest/lib/unittest.dart';
 
 expectResponse() {
-  port.receive(expectAsync2((msg, r) {
+  var receivePort = new ReceivePort();
+  receivePort.receive(expectAsync2((msg, r) {
     expect('isolate', msg);
     expect('main', shared.output);
-    port.close();
+    receivePort.close();
   }));
+  return receivePort;
 }
 
 void main() {
   test("package in spawnFunction()", () {
-    expectResponse();
+    var replyPort = expectResponse().toSendPort();
     shared.output = 'main';
     var sendPort = spawnFunction(isolate_main);
-    sendPort.send("sendPort", port.toSendPort());
+    sendPort.send("sendPort", replyPort);
   });
   
   test("package in spawnUri() of sibling file", () {
-    expectResponse();
+    var replyPort = expectResponse().toSendPort();
     shared.output = 'main';
     var sendPort = spawnUri('sibling_isolate.dart');
-    sendPort.send('sendPort', port.toSendPort());
+    sendPort.send('sendPort', replyPort);
   });
 
   test("package in spawnUri() of file in folder", () {
-    expectResponse();
+    var replyPort = expectResponse().toSendPort();
     shared.output = 'main';
     var sendPort = spawnUri('test_folder/folder_isolate.dart');
-    sendPort.send('sendPort', port.toSendPort());
+    sendPort.send('sendPort', replyPort);
   });
 }
 
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index fa225d4..a0b5abb 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -4,6 +4,9 @@
 
 package/invalid_uri_test: Fail, OK # Fails intentionally
 
+[ $runtime == vm ]
+package/package_isolate_test: Fail # Issue 7520.
+
 [ $runtime == vm && $checked ]
 # These tests have type errors on purpose.
 io/process_invalid_arguments_test: Fail, OK
@@ -42,15 +45,35 @@
 io/secure_server_test: Pass, Crash, Fail, Timeout  # Issue 6893
 io/secure_no_builtin_roots_test: Pass, Crash  # Issue 7157
 io/secure_socket_bad_certificate_test: Pass, Crash, Fail, Timeout  # Issue 7157
-io/http_shutdown_test: Pass, Fail, Timeout  # Issue 7294
+io/directory_list_nonexistent_test: Skip # Issue 7157
 
 [ $compiler == none && $runtime == drt ]
 io/*: Skip # Don't run tests using dart:io in the browser
 crypto/*: Skip # Don't run tests using dart:io in the browser
 package/*: Skip # Do not run those in Dartium.
+debugger/*: Skip # Do not run standalone debugger tests in browser.
 
 [ $compiler == dartc ]
-*: Skip
+
+# package test issue 7392
+package/package1_test: Fail
+package/package_isolate_test: Fail
+package/package_test: Fail
+
+
+# The dart:io library is created at build time from separate files, and
+# there is no language-spec compatible way to run unit tests on the private
+# members and methods of dart:io.
+# Dartc spots the misuse of 'part' directives in these unit tests.
+crypto/*: Skip  # dartc cannot parse dart:io unit tests.
+io/mime_multipart_parser_test: Skip  # dartc cannot parse dart:io unit tests.
+io/http_headers_test: Skip  # dartc cannot parse dart:io unit tests.
+io/http_date_test: Skip  # dartc cannot parse dart:io unit tests.
+io/url_encoding_test: Skip  # dartc cannot parse dart:io unit tests.
+io/http_parser_test: Skip  # dartc cannot parse dart:io unit tests.
+io/web_socket_protocol_processor_test: Skip  # dart:io unit test.
+
+io/process_exit_negative_test: Fail  # This is a compilation-time negative test.
 
 [ $compiler == frog ]
 *: Skip
@@ -70,6 +93,7 @@
 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.
 package/package_isolate_test: Skip # spawnUri does not work in dart2js. See issue 3051
+debugger/*: Skip # Do not run standalone vm debugger tests with dart2js.
 
 [ $compiler == dart2js && $jscl ]
 assert_test: Fail, OK # Assumes unspecified fields on the AssertionError.
diff --git a/tests/standalone/status_expression_test.dart b/tests/standalone/status_expression_test.dart
index 65ad579..2c6da43 100644
--- a/tests/standalone/status_expression_test.dart
+++ b/tests/standalone/status_expression_test.dart
@@ -2,9 +2,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.
 
-#library("StatusExpressionTest");
+library StatusExpressionTest;
 
-#import("../../tools/testing/dart/status_expression.dart");
+import "../../tools/testing/dart/status_expression.dart";
 
 
 class StatusExpressionTest {
diff --git a/tests/standalone/typed_array_test.dart b/tests/standalone/typed_array_test.dart
index 993b232..ac4d57f 100644
--- a/tests/standalone/typed_array_test.dart
+++ b/tests/standalone/typed_array_test.dart
@@ -5,9 +5,9 @@
 // Dart test program for testing native float arrays.
 
 // Library tag to be able to run in html test framework.
-#library('TypedArray');
-#import('dart:isolate');
-#import('dart:scalarlist');
+library TypedArray;
+import 'dart:isolate';
+import 'dart:scalarlist';
 
 void main() {
   int8_receiver();
diff --git a/tests/utils/dummy_compiler_test.dart b/tests/utils/dummy_compiler_test.dart
index cd329ca..b5b8993 100644
--- a/tests/utils/dummy_compiler_test.dart
+++ b/tests/utils/dummy_compiler_test.dart
@@ -49,6 +49,8 @@
                   var getInterceptor;""";
     } else if (uri.path.endsWith('js_helper.dart')) {
       source = 'library jshelper; class JSInvocationMirror {}';
+    } else if (uri.path.endsWith('isolate_helper.dart')) {
+      source = 'library isolatehelper; class _WorkerStub {}';
     } else {
       source = "library lib;";
     }
diff --git a/tests/utils/recursive_import_test.dart b/tests/utils/recursive_import_test.dart
index 0ad898c..ef53e69 100644
--- a/tests/utils/recursive_import_test.dart
+++ b/tests/utils/recursive_import_test.dart
@@ -52,6 +52,8 @@
         source = CORE_LIB;
       } else if (uri.path.endsWith('_patch.dart')) {
         source = '';
+      } else if (uri.path.endsWith('isolate_helper.dart')) {
+        source = 'class _WorkerStub {}';
       } else {
         source = "library lib${uri.path.replaceAll('/', '.')};";
       }
diff --git a/tests/utils/uri_test.dart b/tests/utils/uri_test.dart
index 66820dc..202304e 100644
--- a/tests/utils/uri_test.dart
+++ b/tests/utils/uri_test.dart
@@ -192,6 +192,7 @@
 
   Expect.stringEquals("\u{10000}", s);
 
+  testEncodeDecode("A + B", "A+%2B+B");
   testEncodeDecode("\uFFFE", "%EF%BF%BE");
   testEncodeDecode("\uFFFF", "%EF%BF%BF");
   testEncodeDecode("\uFFFE", "%EF%BF%BE");
@@ -199,7 +200,7 @@
   testEncodeDecode("\x7f", "%7F");
   testEncodeDecode("\x80", "%C2%80");
   testEncodeDecode("\u0800", "%E0%A0%80");
-  testEncodeDecode(":/@',;?&=+\$", ":/@',;?&=+\$");
+  testEncodeDecode(":/@',;?&=+\$", ":/@',;?&=%2B\$");
   testEncodeDecode(s, "%F0%90%80%80");
   testEncodeDecodeComponent("\uFFFE", "%EF%BF%BE");
   testEncodeDecodeComponent("\uFFFF", "%EF%BF%BF");
diff --git a/tools/VERSION b/tools/VERSION
index 1502503..a9561a1 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
 MAJOR 0
 MINOR 2
-BUILD 9
-PATCH 9
+BUILD 10
+PATCH 0
diff --git a/tools/create_sdk.py b/tools/create_sdk.py
index 1f1ef12..321ab21 100755
--- a/tools/create_sdk.py
+++ b/tools/create_sdk.py
@@ -84,11 +84,6 @@
   copyfile(src, dest)
   copymode(src, dest)
 
-# TODO(zundel): this excludes the analyzer from the sdk build until builders
-# have all prerequisite software installed.  Also update dart.gyp.
-def ShouldCopyAnalyzer():
-  return HOST_OS == 'linux' or HOST_OS == 'macos'
-
 
 def CopyShellScript(src_file, dest_dir):
   '''Copies a shell/batch script to the given destination directory. Handles
@@ -152,7 +147,7 @@
   analyzer_file_extension = ''
   if HOST_OS == 'win32':
     dart_file_extension = '.exe'
-    analyzer_file_extension = '.bat'  # TODO(zundel): test on Windows
+    analyzer_file_extension = '.bat'
     dart_import_lib_src = join(HOME, build_dir, 'dart.lib')
     dart_import_lib_dest = join(BIN, 'dart.lib')
     copyfile(dart_import_lib_src, dart_import_lib_dest)
@@ -166,14 +161,14 @@
   elif HOST_OS == 'macos':
     subprocess.call(['strip', '-x', dart_dest_binary])
 
-  if ShouldCopyAnalyzer():
-    # Copy analyzer into sdk/bin
-    ANALYZER_HOME = join(HOME, build_dir, 'analyzer')
-    dart_analyzer_src_binary = join(ANALYZER_HOME, 'bin', 'dart_analyzer')
-    dart_analyzer_dest_binary = join(BIN,
-        'dart_analyzer' + analyzer_file_extension)
-    copyfile(dart_analyzer_src_binary, dart_analyzer_dest_binary)
-    copymode(dart_analyzer_src_binary, dart_analyzer_dest_binary)
+  # Copy analyzer into sdk/bin
+  ANALYZER_HOME = join(HOME, build_dir, 'analyzer')
+  dart_analyzer_src_binary = join(ANALYZER_HOME, 'bin',
+      'dart_analyzer' + analyzer_file_extension)
+  dart_analyzer_dest_binary = join(BIN,
+      'dart_analyzer' + analyzer_file_extension)
+  copyfile(dart_analyzer_src_binary, dart_analyzer_dest_binary)
+  copymode(dart_analyzer_src_binary, dart_analyzer_dest_binary)
 
   # Create pub shell script.
   # TODO(dgrove) - delete this once issue 6619 is fixed
@@ -222,7 +217,7 @@
   #
 
   for library in ['args', 'http', 'intl', 'logging',
-                  'meta', 'oauth2', 'serialization', 'unittest']:
+                  'meta', 'oauth2', 'path', 'serialization', 'unittest']:
 
     copytree(join(HOME, 'pkg', library), join(PKG, library),
              ignore=ignore_patterns('*.svn', 'doc', 'docs',
@@ -232,25 +227,24 @@
   UTIL = join(SDK_tmp, 'util')
   os.makedirs(UTIL)
 
-  if ShouldCopyAnalyzer():
-    # Create and copy Analyzer library into 'util'
-    ANALYZER_DEST = join(UTIL, 'analyzer')
-    os.makedirs(ANALYZER_DEST)
+  # Create and copy Analyzer library into 'util'
+  ANALYZER_DEST = join(UTIL, 'analyzer')
+  os.makedirs(ANALYZER_DEST)
 
-    analyzer_src_jar = join(ANALYZER_HOME, 'util', 'analyzer',
-                            'dart_analyzer.jar')
-    analyzer_dest_jar = join(ANALYZER_DEST, 'dart_analyzer.jar')
-    copyfile(analyzer_src_jar, analyzer_dest_jar)
+  analyzer_src_jar = join(ANALYZER_HOME, 'util', 'analyzer',
+                          'dart_analyzer.jar')
+  analyzer_dest_jar = join(ANALYZER_DEST, 'dart_analyzer.jar')
+  copyfile(analyzer_src_jar, analyzer_dest_jar)
 
-    jarsToCopy = [ join("args4j", "2.0.12", "args4j-2.0.12.jar"),
-                   join("guava", "r09", "guava-r09.jar"),
-                   join("json", "r2_20080312", "json.jar") ]
-    for jarToCopy in jarsToCopy:
-      dest_dir = join (ANALYZER_DEST, os.path.dirname(jarToCopy))
-      os.makedirs(dest_dir)
-      dest_file = join (ANALYZER_DEST, jarToCopy)
-      src_file = join(ANALYZER_HOME, 'util', 'analyzer', jarToCopy)
-      copyfile(src_file, dest_file)
+  jarsToCopy = [ join("args4j", "2.0.12", "args4j-2.0.12.jar"),
+                 join("guava", "r09", "guava-r09.jar"),
+                 join("json", "r2_20080312", "json.jar") ]
+  for jarToCopy in jarsToCopy:
+    dest_dir = join (ANALYZER_DEST, os.path.dirname(jarToCopy))
+    os.makedirs(dest_dir)
+    dest_file = join (ANALYZER_DEST, jarToCopy)
+    src_file = join(ANALYZER_HOME, 'util', 'analyzer', jarToCopy)
+    copyfile(src_file, dest_file)
 
   # Create and populate util/pub.
   copytree(join(HOME, 'utils', 'pub'), join(UTIL, 'pub'),
diff --git a/sdk/lib/html/.gitignore b/tools/dom/.gitignore
similarity index 100%
rename from sdk/lib/html/.gitignore
rename to tools/dom/.gitignore
diff --git a/tools/dom/doc/html.dartdoc b/tools/dom/doc/html.dartdoc
new file mode 100644
index 0000000..069ed46
--- /dev/null
+++ b/tools/dom/doc/html.dartdoc
@@ -0,0 +1,37 @@
+// 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.
+
+// Fake dart:html library for documentation.
+
+/// The Dart HTML5 Library.
+library dart.html;
+
+part 'interface/AbstractWorker.dartdoc';
+part 'interface/Element.dartdoc';
+part 'interface/Event.dartdoc';
+part 'interface/EventTarget.dartdoc';
+part 'interface/HttpRequest.dartdoc';
+part 'interface/MouseEvent.dartdoc';
+part 'interface/Storage.dartdoc';
+part 'interface/Node.dartdoc';
+part 'interface/UIEvent.dartdoc';
+part 'interface/WebSocket.dartdoc';
+
+// Implementation files that appear to be necessary to load the sources.
+
+//part 'nodoc-src/SomeFile.dart';
+
+// Global definitions.
+
+/**
+ * The top-level Window object.
+ */
+Window get window() => null;
+
+/**
+ * The top-level Document object.
+ */
+Document get document() => null;
+
+typedef void EventListener(Event event);
diff --git a/sdk/lib/html/doc/interface/AbstractWorker.dartdoc b/tools/dom/doc/interface/AbstractWorker.dartdoc
similarity index 100%
rename from sdk/lib/html/doc/interface/AbstractWorker.dartdoc
rename to tools/dom/doc/interface/AbstractWorker.dartdoc
diff --git a/sdk/lib/html/doc/interface/Element.dartdoc b/tools/dom/doc/interface/Element.dartdoc
similarity index 100%
rename from sdk/lib/html/doc/interface/Element.dartdoc
rename to tools/dom/doc/interface/Element.dartdoc
diff --git a/sdk/lib/html/doc/interface/Event.dartdoc b/tools/dom/doc/interface/Event.dartdoc
similarity index 100%
rename from sdk/lib/html/doc/interface/Event.dartdoc
rename to tools/dom/doc/interface/Event.dartdoc
diff --git a/sdk/lib/html/doc/interface/EventTarget.dartdoc b/tools/dom/doc/interface/EventTarget.dartdoc
similarity index 100%
rename from sdk/lib/html/doc/interface/EventTarget.dartdoc
rename to tools/dom/doc/interface/EventTarget.dartdoc
diff --git a/sdk/lib/html/doc/interface/HttpRequest.dartdoc b/tools/dom/doc/interface/HttpRequest.dartdoc
similarity index 100%
rename from sdk/lib/html/doc/interface/HttpRequest.dartdoc
rename to tools/dom/doc/interface/HttpRequest.dartdoc
diff --git a/sdk/lib/html/doc/interface/MouseEvent.dartdoc b/tools/dom/doc/interface/MouseEvent.dartdoc
similarity index 100%
rename from sdk/lib/html/doc/interface/MouseEvent.dartdoc
rename to tools/dom/doc/interface/MouseEvent.dartdoc
diff --git a/sdk/lib/html/doc/interface/Node.dartdoc b/tools/dom/doc/interface/Node.dartdoc
similarity index 100%
rename from sdk/lib/html/doc/interface/Node.dartdoc
rename to tools/dom/doc/interface/Node.dartdoc
diff --git a/sdk/lib/html/doc/interface/Storage.dartdoc b/tools/dom/doc/interface/Storage.dartdoc
similarity index 100%
rename from sdk/lib/html/doc/interface/Storage.dartdoc
rename to tools/dom/doc/interface/Storage.dartdoc
diff --git a/sdk/lib/html/doc/interface/UIEvent.dartdoc b/tools/dom/doc/interface/UIEvent.dartdoc
similarity index 100%
rename from sdk/lib/html/doc/interface/UIEvent.dartdoc
rename to tools/dom/doc/interface/UIEvent.dartdoc
diff --git a/sdk/lib/html/doc/interface/WebSocket.dartdoc b/tools/dom/doc/interface/WebSocket.dartdoc
similarity index 100%
rename from sdk/lib/html/doc/interface/WebSocket.dartdoc
rename to tools/dom/doc/interface/WebSocket.dartdoc
diff --git a/sdk/lib/html/docs/html_docs.json b/tools/dom/docs/html_docs.json
similarity index 94%
rename from sdk/lib/html/docs/html_docs.json
rename to tools/dom/docs/html_docs.json
index de93b4a..8f23289 100644
--- a/sdk/lib/html/docs/html_docs.json
+++ b/tools/dom/docs/html_docs.json
@@ -642,14 +642,22 @@
   },
 "Document.dart":
   {
-  "  @JSName('querySelectorAll')":
+  "  @JSName('body')":
     [
-      "  /// Deprecated: use query(\"#$elementId\") instead."
+      "  /// Moved to [HtmlDocument]."
+    ],
+  "  @JSName('caretRangeFromPoint')":
+    [
+      "  /// Use the [Range] constructor instead."
     ],
   "  @JSName('createElement')":
     [
       "  /// Deprecated: use new Element.tag(tagName) instead."
     ],
+  "  @JSName('createTouchList')":
+    [
+      "  /// Use the [TouchList] constructor isntead."
+    ],
   "  @JSName('elementFromPoint')":
     [
       "  /// Moved to [HtmlDocument]."
@@ -658,19 +666,23 @@
     [
       "  /// Deprecated: use query(\"#$elementId\") instead."
     ],
+  "  @JSName('head')":
+    [
+      "  /// Moved to [HtmlDocument]."
+    ],
+  "  @JSName('lastModified')":
+    [
+      "  /// Moved to [HtmlDocument]."
+    ],
   "  @JSName('querySelector')":
     [
       "  /// Deprecated: renamed to the shorter name [query]."
     ],
-  "  @JSName('webkitFullscreenElement')":
+  "  @JSName('querySelectorAll')":
     [
-      "  /// Moved to [HtmlDocument]."
+      "  /// Deprecated: use query(\"#$elementId\") instead."
     ],
-  "  @JSName('webkitPointerLockElement')":
-    [
-      "  /// Moved to [HtmlDocument]."
-    ],
-  "  @JSName('head')":
+  "  @JSName('referrer')":
     [
       "  /// Moved to [HtmlDocument]."
     ],
@@ -678,46 +690,10 @@
     [
       "  /// Moved to [HtmlDocument]."
     ],
-  "  @JSName('caretRangeFromPoint')":
-    [
-      "  /// Use the [Range] constructor instead."
-    ],
-  "  @JSName('lastModified')":
-    [
-      "  /// Moved to [HtmlDocument]."
-    ],
-  "  @JSName('referrer')":
-    [
-      "  /// Moved to [HtmlDocument]."
-    ],
   "  @JSName('title')":
     [
       "  /// Moved to [HtmlDocument]."
     ],
-  "  @JSName('webkitVisibilityState')":
-    [
-      "  /// Moved to [HtmlDocument]."
-    ],
-  "  @JSName('createTouchList')":
-    [
-      "  /// Use the [TouchList] constructor isntead."
-    ],
-  "  Window get window => _convertNativeToDart_Window(this._window);":
-    [
-      "  /// Returns the [Window] associated with the document."
-    ],
-  "  @JSName('webkitFullscreenEnabled')":
-    [
-      "  /// Moved to [HtmlDocument]."
-    ],
-  "  @JSName('webkitHidden')":
-    [
-      "  /// Moved to [HtmlDocument]."
-    ],
-  "  @JSName('webkitIsFullScreen')":
-    [
-      "  /// Moved to [HtmlDocument]."
-    ],
   "  @JSName('webkitCancelFullScreen')":
     [
       "  /// Moved to [HtmlDocument]."
@@ -730,13 +706,33 @@
     [
       "  /// Moved to [HtmlDocument]."
     ],
-  "  @JSName('body')":
+  "  @JSName('webkitFullscreenElement')":
     [
       "  /// Moved to [HtmlDocument]."
     ],
-  "  @JSName('title')":
+  "  @JSName('webkitFullscreenEnabled')":
     [
       "  /// Moved to [HtmlDocument]."
+    ],
+  "  @JSName('webkitHidden')":
+    [
+      "  /// Moved to [HtmlDocument]."
+    ],
+  "  @JSName('webkitIsFullScreen')":
+    [
+      "  /// Moved to [HtmlDocument]."
+    ],
+  "  @JSName('webkitPointerLockElement')":
+    [
+      "  /// Moved to [HtmlDocument]."
+    ],
+  "  @JSName('webkitVisibilityState')":
+    [
+      "  /// Moved to [HtmlDocument]."
+    ],
+  "  Window get window => _convertNativeToDart_Window(this._window);":
+    [
+      "  /// Returns the [Window] associated with the document."
     ]
   },
 "DocumentFragment.dart":
@@ -1039,6 +1035,16 @@
       "   * [String]). `null` indicates request failure.",
       "   */"
     ],
+  "  @JSName('responseXML')":
+    [
+      "  /**",
+      "   * The request response, or null on failure.",
+      "   * ",
+      "   * The response is processed as",
+      "   * `text/xml` stream, unless responseType = 'document' and the request is",
+      "   * synchronous.",
+      "   */"
+    ],
   "  EventListenerList get abort => this['abort'];":
     [
       "  /**",
@@ -1128,7 +1134,7 @@
       "   *",
       "   * Default is `String`.",
       "   * Other options are one of 'arraybuffer', 'blob', 'document', 'json',",
-      "   * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if",
+      "   * 'text'. Some newer browsers will throw `NS_ERROR_DOM_INVALID_ACCESS_ERR` if",
       "   * `responseType` is set while performing a synchronous request.",
       "   *",
       "   * See also: [MDN responseType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType)",
@@ -1156,7 +1162,8 @@
       "   * ",
       "   * is the (more verbose) equivalent of",
       "   * ",
-      "   *     var request = new HttpRequest.get('http://dartlang.org', (event) => print('Request complete'));",
+      "   *     var request = new HttpRequest.get('http://dartlang.org',",
+      "   *         (event) => print('Request complete'));",
       "   */"
     ],
   "  final HttpRequestUpload upload;":
@@ -1169,7 +1176,7 @@
   "  final String responseText;":
     [
       "  /**",
-      "   * The response in string form or `null` on failure.",
+      "   * The response in string form or null on failure.",
       "   */"
     ],
   "  final String statusText;":
@@ -1181,7 +1188,38 @@
     ],
   "  final int readyState;":
     [
-      "  /** @domName XMLHttpRequest.readyState */"
+      "  /**",
+      "   * Indicator of the current state of the request:",
+      "   *",
+      "   * <table>",
+      "   *   <tr>",
+      "   *     <td>Value</td>",
+      "   *     <td>State</td>",
+      "   *     <td>Meaning</td>",
+      "   *   </tr>",
+      "   *   <tr>",
+      "   *     <td>0</td>",
+      "   *     <td>unsent</td>",
+      "   *     <td><code>open()</code> has not yet been called</td>",
+      "   *   </tr>",
+      "   *   <tr>",
+      "   *     <td>1</td>",
+      "   *     <td>opened</td>",
+      "   *     <td><code>send()</code> has not yet been called</td>",
+      "   *   </tr>",
+      "   *   <tr>",
+      "   *     <td>2</td>",
+      "   *     <td>headers received</td>",
+      "   *     <td><code>sent()</code> has been called; response headers and <code>status</code> are available</td>",
+      "   *   </tr>",
+      "   *   <tr>",
+      "   *     <td>3</td> <td>loading</td> <td><code>responseText</code> holds some data</td>",
+      "   *   </tr>",
+      "   *   <tr>",
+      "   *     <td>4</td> <td>done</td> <td>request is complete</td>",
+      "   *   </tr>",
+      "   * </table>",
+      "   */"
     ],
   "  final int status;":
     [
diff --git a/sdk/lib/html/docs/svg_docs.json b/tools/dom/docs/svg_docs.json
similarity index 100%
rename from sdk/lib/html/docs/svg_docs.json
rename to tools/dom/docs/svg_docs.json
diff --git a/tools/dom/idl/dart/dart.idl b/tools/dom/idl/dart/dart.idl
new file mode 100644
index 0000000..cbf08c0
--- /dev/null
+++ b/tools/dom/idl/dart/dart.idl
@@ -0,0 +1,331 @@
+// This file introduces / supplements and forces Dart declarations.
+
+[Supplemental,
+ Constructor]
+interface AudioContext {};
+
+[Supplemental]
+interface Document {
+  [Suppressed] DOMObject getCSSCanvasContext(in DOMString contextId, in DOMString name, in long width, in long height);
+  CanvasRenderingContext getCSSCanvasContext(in DOMString contextId, in DOMString name, in long width, in long height);
+};
+
+[Supplemental]
+interface ScriptProcessorNode {
+  // FIXME(antonm): provide proper support.
+  [Suppressed] attribute EventListener onaudioprocess;
+};
+
+// Force ElementTraversal. WebKit defines these directly.
+interface ElementTraversal {
+  readonly attribute unsigned long childElementCount;
+  readonly attribute Element firstElementChild;
+  readonly attribute Element lastElementChild;
+  readonly attribute Element nextElementSibling;
+  readonly attribute Element previousElementSibling;
+};
+Element implements ElementTraversal;
+
+[Callback]
+interface TimeoutHandler {
+  void handleEvent();
+};
+
+[Supplemental]
+interface Console {
+  [Suppressed] void assert(in boolean condition);
+  [CallWith=ScriptArguments|ScriptState] void assertCondition(boolean condition);
+};
+
+interface HTMLCanvasElement {
+  [Suppressed] DOMString toDataURL([TreatNullAs=NullString, TreatUndefinedAs=NullString,Optional=DefaultIsUndefined] in DOMString type) raises(DOMException);
+  [Custom] DOMString toDataURL([TreatNullAs=NullString, TreatUndefinedAs=NullString,Optional=DefaultIsUndefined] in DOMString type, [Optional] in float quality) raises(DOMException);
+};
+
+[Supplemental]
+interface HTMLOptionsCollection {
+  [Suppressed] void add([Optional] in HTMLOptionElement element, [Optional] in long before);
+};
+
+[Supplemental]
+interface HTMLSelectElement {
+  [Suppressed] void add([Optional=DefaultIsUndefined] in HTMLElement element, [Optional=DefaultIsUndefined] in HTMLElement before);
+  [Suppressed, Custom] void remove();
+  [Custom] void remove(in long index);
+  [Custom] void remove(in HTMLOptionElement option);
+};
+
+[Supplemental]
+interface ImageData {
+  readonly attribute Uint8ClampedArray data;
+};
+
+[Supplemental]
+interface HTMLMediaElement {
+  // Adding media events.
+  attribute EventListener oncanplay;
+  attribute EventListener oncanplaythrough;
+  attribute EventListener ondurationchange;
+  attribute EventListener onemptied;
+  attribute EventListener onended;
+  attribute EventListener onloadeddata;
+  attribute EventListener onloadedmetadata;
+  attribute EventListener onloadstart;
+  attribute EventListener onpause;
+  attribute EventListener onplay;
+  attribute EventListener onplaying;
+  attribute EventListener onprogress;
+  attribute EventListener onratechange;
+  attribute EventListener onseeked;
+  attribute EventListener onseeking;
+  attribute EventListener onshow;
+  attribute EventListener onstalled;
+  attribute EventListener onsuspend;
+  attribute EventListener ontimeupdate;
+  attribute EventListener onvolumechange;
+  attribute EventListener onwaiting;
+};
+
+[Supplemental]
+interface WebGLContextEvent {
+  [Suppressed] void initEvent([Optional] in DOMString eventTypeArg,
+                              [Optional] in boolean canBubbleArg,
+                              [Optional] in boolean cancelableArg,
+                              [Optional] in DOMString statusMessageArg);
+};
+
+[Supplemental]
+interface WebGLRenderingContext {
+
+  //void         compressedTexImage2D(in unsigned long target, in long level, in unsigned long internalformat, in unsigned long width, in unsigned long height, in long border, in unsigned long imageSize, const void* data);
+  //void         compressedTexSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset, in unsigned long width, in unsigned long height, in unsigned long format, in unsigned long imageSize, const void* data);
+
+  [Custom] any getBufferParameter(in unsigned long target, in unsigned long pname) raises(DOMException);
+  [Suppressed, StrictTypeChecking, Custom] void getBufferParameter();
+
+  [Custom] any getFramebufferAttachmentParameter(in unsigned long target, in unsigned long attachment, in unsigned long pname) raises(DOMException);
+  [Suppressed, StrictTypeChecking, Custom] void getFramebufferAttachmentParameter();
+
+  [Custom] any getParameter(in unsigned long pname) raises(DOMException);
+  [Suppressed, StrictTypeChecking, Custom] void getParameter();
+
+  [Custom] any getProgramParameter(in WebGLProgram program, in unsigned long pname) raises(DOMException);
+  [Suppressed, StrictTypeChecking, Custom] void getProgramParameter();
+
+  [Custom] any getRenderbufferParameter(in unsigned long target, in unsigned long pname) raises(DOMException);
+  [Suppressed, StrictTypeChecking, Custom] void getRenderbufferParameter();
+
+  [Custom] any getShaderParameter(in WebGLShader shader, in unsigned long pname) raises(DOMException);
+  [Suppressed, StrictTypeChecking, Custom] void getShaderParameter() raises(DOMException);
+
+  // TBD
+  // void glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+
+  [Custom] any getExtension(DOMString name);
+  [Suppressed, StrictTypeChecking, Custom] void getExtension(DOMString name);
+  [Custom] DOMString[] getSupportedExtensions();
+  [Suppressed, StrictTypeChecking, Custom] void getSupportedExtensions();
+
+  [Custom] any getTexParameter(in unsigned long target, in unsigned long pname) raises(DOMException);
+  [Suppressed, StrictTypeChecking, Custom] void getTexParameter();
+
+  [Custom] any getUniform(in WebGLProgram program, in WebGLUniformLocation location) raises(DOMException);
+  [Suppressed, StrictTypeChecking, Custom] void getUniform();
+
+  [Custom] any getVertexAttrib(in unsigned long index, in unsigned long pname) raises(DOMException);
+  [Suppressed, StrictTypeChecking, Custom] void getVertexAttrib();
+};
+
+[Supplemental]
+interface CSSStyleDeclaration {
+  void setProperty(in DOMString propertyName, in DOMString value, [Optional] in DOMString priority);
+  [DartName=_getPropertyValue] DOMString getPropertyValue(in DOMString propertyName);
+};
+
+[Supplemental,
+  Constructor(in long length)]  // Add constructor signature.
+interface ArrayBuffer {
+};
+[Supplemental]
+interface Float32Array {
+  [Suppressed] void set();
+  [DartName=setElements, Custom] void set(in any array, [Optional] in unsigned long offset);
+};
+[Supplemental]
+interface Float64Array {
+  [Suppressed] void set();
+  [DartName=setElements, Custom] void set(in any array, [Optional] in unsigned long offset);
+};
+[Supplemental]
+interface Int16Array {
+  [Suppressed] void set();
+  [DartName=setElements, Custom] void set(in any array, [Optional] in unsigned long offset);
+};
+[Supplemental]
+interface Int32Array {
+  [Suppressed] void set();
+  [DartName=setElements, Custom] void set(in any array, [Optional] in unsigned long offset);
+};
+[Supplemental]
+interface Int8Array {
+  [Suppressed] void set();
+  [DartName=setElements, Custom] void set(in any array, [Optional] in unsigned long offset);
+};
+[Supplemental]
+interface Uint16Array {
+  [Suppressed] void set();
+  [DartName=setElements, Custom] void set(in any array, [Optional] in unsigned long offset);
+};
+[Supplemental]
+interface Uint32Array {
+  [Suppressed] void set();
+  [DartName=setElements, Custom] void set(in any array, [Optional] in unsigned long offset);
+};
+[Supplemental]
+interface Uint8Array {
+  [Suppressed] void set();
+  [DartName=setElements, Custom] void set(in any array, [Optional] in unsigned long offset);
+};
+
+[Supplemental]
+interface Uint8ClampedArray {
+  // Avoid 'overriding static member BYTES_PER_ELEMENT'.
+  [Suppressed] const long BYTES_PER_ELEMENT = 1;
+
+  [Suppressed] void set();
+  [DartName=setElements, Custom] void set(in any array, [Optional] in unsigned long offset);
+};
+
+[Supplemental,
+  Constructor(in ArrayBuffer buffer,
+              [Optional] in unsigned long byteOffset,
+              [Optional] in unsigned long byteLength)
+  ]
+interface DataView {
+  // Undo this:
+  // We have to use custom code because our code generator does not support int8_t type.
+  // int8_t getInt8(in unsigned long byteOffset);
+  // uint8_t getUint8(in unsigned long byteOffset);
+  [Suppressed] DOMObject getInt8();
+  [Suppressed] DOMObject getUint8();
+  byte getInt8(in unsigned long byteOffset)
+      raises (DOMException);
+  octet getUint8(in unsigned long byteOffset)
+      raises (DOMException);
+
+  // We have to use custom code because our code generator does not support uint8_t type.
+  // void setInt8(in unsigned long byteOffset, in int8_t value);
+  // void setUint8(in unsigned long byteOffset, in uint8_t value);
+  [Suppressed] void setInt8();
+  [Suppressed] void setUint8();
+  void setInt8(in unsigned long byteOffset, in byte value)
+      raises (DOMException);
+  void setUint8(in unsigned long byteOffset, in octet value)
+      raises (DOMException);
+};
+
+// TODO(vsm): Define new names for these (see b/4436830).
+[Supplemental]
+interface IDBCursor {
+  [DartName=continueFunction] void continue([Optional] in IDBKey key);
+};
+[Supplemental]
+interface IDBDatabase {
+  // These variants are slated for removal from WebKit.  Suppress to bring our
+  // API in line with the most recent spec.
+  [Suppressed, CallWith=ScriptExecutionContext] IDBTransaction transaction(in DOMStringList storeNames, in unsigned short mode)
+      raises (IDBDatabaseException);
+  [Suppressed, CallWith=ScriptExecutionContext] IDBTransaction transaction(in DOMString[] storeNames, in unsigned short mode)
+      raises (IDBDatabaseException);
+  [Suppressed, CallWith=ScriptExecutionContext] IDBTransaction transaction(in DOMString storeName, in unsigned short mode)
+      raises (IDBDatabaseException);
+};
+[Supplemental]
+interface IDBIndex {
+  [DartName=getObject] IDBRequest get(in IDBKey key);
+};
+[Supplemental]
+interface IDBObjectStore {
+  [DartName=getObject] IDBRequest get(in IDBKey key);
+  [DartName=getObject] IDBRequest get(in IDBKeyRange key);
+};
+
+[Supplemental]
+interface IDBKeyRange {
+  [DartName=only_] static IDBKeyRange only(in IDBKey value) raises (IDBDatabaseException);
+  [DartName=lowerBound_] static IDBKeyRange lowerBound(in IDBKey bound, [Optional] in boolean open) raises (IDBDatabaseException);
+  [DartName=upperBound_] static IDBKeyRange upperBound(in IDBKey bound, [Optional] in boolean open) raises (IDBDatabaseException);
+  [DartName=bound_] static IDBKeyRange bound(in IDBKey lower, in IDBKey upper, [Optional] in boolean lowerOpen, [Optional] in boolean upperOpen) raises (IDBDatabaseException);
+};
+
+interface EntrySync {
+  // Native implementation is declared to return EntrySync.
+  [Suppressed] DirectoryEntrySync getParent();
+  EntrySync getParent();
+};
+
+
+[Supplemental,
+  CustomConstructor,
+  Constructor(in Array blobParts,
+              [Optional] in DOMString type, [Optional] in DOMString endings)
+  ]
+interface Blob {
+};
+
+[Supplemental,
+  Constructor(float x, float y)
+]
+interface WebKitPoint {
+};
+
+[Supplemental, Callback] // Add missing Callback attribute.
+interface VoidCallback {
+};
+
+interface SVGNumber {
+  [StrictTypeChecking, Custom] attribute float value;
+};
+
+[Supplemental,
+  CustomConstructor,
+  // Provide missing constructor signature.
+  Constructor(MutationCallback callback)]
+interface MutationObserver {
+  // Rename 'observe' so we can define a new 'observe' API that calls the
+  // original.
+  [DartName=_observe] void observe(in Node target, in Dictionary options)
+      raises(DOMException);
+};
+
+  [Supplemental,
+    CustomConstructor,
+    // Provide missing constructor signature.
+    Constructor([Optional] in HTMLFormElement form)]
+  interface DOMFormData {
+    [Suppressed] void append(in DOMString name, in DOMString value, in DOMString filename);
+    [Custom] void append(in DOMString name, in DOMString value);
+    [Custom] void append(in DOMString name, in Blob value, [Optional] in DOMString filename);
+  };
+
+[Supplemental]
+interface SQLResultSetRowList {
+  // Change the return type to Dictionary so that rows are exposed in the Dart
+  // API as a Maps, with the appropriate conversion in JavaScript.
+  [Suppressed] DOMObject item(in unsigned long index);
+  [Custom] Dictionary item(in unsigned long index);
+};
+
+[Supplemental]
+interface WebSocket {
+  // Suppress the default since it has non-standard return type and add
+  // overrides.
+  [Suppressed] boolean send(in DOMString data) raises(DOMException);
+  [Custom] void send(DOMString data) raises(DOMException);
+  [Custom] void send(Blob data) raises(DOMException);
+  [Custom] void send(ArrayBuffer data) raises(DOMException);
+  [Custom] void send(ArrayBufferView data) raises(DOMException);
+};
+
+[Suppressed]
+interface Entity {};
diff --git a/sdk/lib/html/scripts/all_tests.py b/tools/dom/scripts/all_tests.py
similarity index 100%
rename from sdk/lib/html/scripts/all_tests.py
rename to tools/dom/scripts/all_tests.py
diff --git a/sdk/lib/html/scripts/css_code_generator.py b/tools/dom/scripts/css_code_generator.py
similarity index 100%
rename from sdk/lib/html/scripts/css_code_generator.py
rename to tools/dom/scripts/css_code_generator.py
diff --git a/sdk/lib/html/scripts/dartdomgenerator.py b/tools/dom/scripts/dartdomgenerator.py
similarity index 90%
rename from sdk/lib/html/scripts/dartdomgenerator.py
rename to tools/dom/scripts/dartdomgenerator.py
index dea8fac..879df28 100755
--- a/sdk/lib/html/scripts/dartdomgenerator.py
+++ b/tools/dom/scripts/dartdomgenerator.py
@@ -23,6 +23,9 @@
 from systemnative import CPPLibraryEmitter, DartiumBackend
 from templateloader import TemplateLoader
 
+sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..'))
+import utils
+
 _logger = logging.getLogger('dartdomgenerator')
 
 _libraries = ['html', 'indexed_db', 'svg', 'web_audio']
@@ -138,7 +141,7 @@
 def GenerateSingleFile(library_path, output_dir, generated_output_dir=None):
   library_dir = os.path.dirname(library_path)
   library_filename = os.path.basename(library_path)
-  copy_dart_script = os.path.relpath('../../../../tools/copy_dart.py',
+  copy_dart_script = os.path.relpath('../../copy_dart.py',
       library_dir)
   output_dir = os.path.relpath(output_dir, library_dir)
   command = ' '.join(['cd', library_dir, ';',
@@ -173,7 +176,9 @@
   logging.config.fileConfig(os.path.join(current_dir, 'logging.conf'))
   systems = options.systems.split(',')
 
-  output_dir = options.output_dir or os.path.join(current_dir, '../generated')
+  output_dir = options.output_dir or os.path.join(
+      current_dir, '..', '..', utils.GetBuildDir(utils.GuessOS(), None),
+      'generated')
 
   dart2js_output_dir = None
   if 'htmldart2js' in systems:
@@ -192,16 +197,19 @@
 
   _logger.info('Add documentation to generated classes.')
   html_to_json_script = os.path.relpath(
-      '../../../../tools/html_json_doc/bin/html_json_doc.dart',
+      '../../html_json_doc/bin/html_json_doc.dart',
       current_dir)
   html_output_dir = os.path.join(output_dir, 'dart2js/dart/html/')
   svg_output_dir = os.path.join(output_dir, 'dart2js/dart/svg/')
   html_json_path = os.path.relpath('../docs/html_docs.json')
   svg_json_path = os.path.relpath('../docs/svg_docs.json')
-  html_command = ' '.join(['dart', html_to_json_script, '--mode=json-to-html',
-                      html_output_dir, html_json_path])
-  svg_command = ' '.join(['dart', html_to_json_script, '--mode=json-to-html',
-                      svg_output_dir, svg_json_path])
+
+  path_to_dart = utils.DartBinary()
+  html_command = ' '.join([path_to_dart, html_to_json_script,
+                           '--mode=json-to-html', html_output_dir,
+                           html_json_path])
+  svg_command = ' '.join([path_to_dart, html_to_json_script,
+                          '--mode=json-to-html', svg_output_dir, svg_json_path])
   subprocess.call([html_command], shell=True)
   subprocess.call([svg_command], shell=True)
 
@@ -210,13 +218,13 @@
     for library_name in _libraries:
       GenerateSingleFile(
           os.path.join(dart2js_output_dir, '%s_dart2js.dart' % library_name),
-          '../../%s/dart2js' % library_name)
+          os.path.join('..', '..', '..', 'sdk', 'lib', library_name, 'dart2js'))
   if 'htmldartium' in systems:
     _logger.info('Generating dartium single files.')
     for library_name in _libraries:
       GenerateSingleFile(
           os.path.join(dartium_output_dir, '%s_dartium.dart' % library_name),
-          '../../%s/dartium' % library_name)
+          os.path.join('..', '..', '..', 'sdk', 'lib', library_name, 'dartium'))
 
 if __name__ == '__main__':
   sys.exit(main())
diff --git a/sdk/lib/html/scripts/dartgenerator.py b/tools/dom/scripts/dartgenerator.py
similarity index 94%
rename from sdk/lib/html/scripts/dartgenerator.py
rename to tools/dom/scripts/dartgenerator.py
index 6893df9..ac399eb 100755
--- a/sdk/lib/html/scripts/dartgenerator.py
+++ b/tools/dom/scripts/dartgenerator.py
@@ -148,6 +148,17 @@
       else:
         database.DeleteInterface(interface.id)
 
+      # Ugly temporary hack
+      websocket_interface = database.GetInterface('WebSocket')
+      def make_object(**fields):
+        o = type('Anon', (object,), {})()
+        for k, v in fields.items(): setattr(o, k, v)
+        o.ext_attrs = {}
+        return o
+      arg = make_object(id = 'url', type = make_object(id = 'DOMString'))
+      websocket_interface.ext_attrs['Constructor'] = make_object(arguments = [arg])
+      websocket_interface.ext_attrs['CustomConstructor'] = True
+
     self.FilterMembersWithUnidentifiedTypes(database)
 
   def Generate(self, database, super_database, generate_interface):
@@ -226,5 +237,5 @@
     ARG = idlnode.IDLArgument([('Type', ('ScopedName', 'object')), ('Id', 'arg')])
     for interface in database.GetInterfaces():
       for operation in interface.operations:
-        if operation.ext_attrs.get('CallWith') == 'ScriptArguments|CallStack':
+        if operation.ext_attrs.get('CallWith') == 'ScriptArguments|ScriptState':
           operation.arguments.append(ARG)
diff --git a/sdk/lib/html/scripts/dartgenerator_test.py b/tools/dom/scripts/dartgenerator_test.py
similarity index 100%
rename from sdk/lib/html/scripts/dartgenerator_test.py
rename to tools/dom/scripts/dartgenerator_test.py
diff --git a/sdk/lib/html/scripts/database.py b/tools/dom/scripts/database.py
similarity index 100%
rename from sdk/lib/html/scripts/database.py
rename to tools/dom/scripts/database.py
diff --git a/sdk/lib/html/scripts/database_test.py b/tools/dom/scripts/database_test.py
similarity index 100%
rename from sdk/lib/html/scripts/database_test.py
rename to tools/dom/scripts/database_test.py
diff --git a/sdk/lib/html/scripts/databasebuilder.py b/tools/dom/scripts/databasebuilder.py
similarity index 100%
rename from sdk/lib/html/scripts/databasebuilder.py
rename to tools/dom/scripts/databasebuilder.py
diff --git a/sdk/lib/html/scripts/databasebuilder_test.py b/tools/dom/scripts/databasebuilder_test.py
similarity index 100%
rename from sdk/lib/html/scripts/databasebuilder_test.py
rename to tools/dom/scripts/databasebuilder_test.py
diff --git a/sdk/lib/html/scripts/emitter.py b/tools/dom/scripts/emitter.py
similarity index 100%
rename from sdk/lib/html/scripts/emitter.py
rename to tools/dom/scripts/emitter.py
diff --git a/sdk/lib/html/scripts/emitter_test.py b/tools/dom/scripts/emitter_test.py
similarity index 100%
rename from sdk/lib/html/scripts/emitter_test.py
rename to tools/dom/scripts/emitter_test.py
diff --git a/sdk/lib/html/scripts/fremontcutbuilder.py b/tools/dom/scripts/fremontcutbuilder.py
similarity index 97%
rename from sdk/lib/html/scripts/fremontcutbuilder.py
rename to tools/dom/scripts/fremontcutbuilder.py
index 19181a0..220f565 100755
--- a/sdk/lib/html/scripts/fremontcutbuilder.py
+++ b/tools/dom/scripts/fremontcutbuilder.py
@@ -185,8 +185,8 @@
 
   idl_files = []
 
-  webcore_dir = os.path.join(current_dir, '..', '..', '..', '..',
-                             'third_party', 'WebCore')
+  webcore_dir = os.path.join(current_dir, '..', '..', '..', 'third_party',
+                             'WebCore')
   if not os.path.exists(webcore_dir):
     raise RuntimeError('directory not found: %s' % webcore_dir)
 
diff --git a/sdk/lib/html/scripts/generator.py b/tools/dom/scripts/generator.py
similarity index 90%
rename from sdk/lib/html/scripts/generator.py
rename to tools/dom/scripts/generator.py
index 7078147..ceac4e2 100644
--- a/sdk/lib/html/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -238,6 +238,7 @@
   info.type_name = interface.id
   info.param_infos = args
   info.requires_named_arguments = False
+  info.pure_dart_constructor = False
   return info
 
 def IsDartListType(type):
@@ -358,96 +359,9 @@
     else:
       return rename_type(self.type_name)
 
-  def ConstructorFactoryName(self, rename_type):
-    return 'create' + self._ConstructorFullName(rename_type).replace('.', '_')
-
-  def GenerateFactoryInvocation(self, rename_type, emitter, factory_name,
-      factory_constructor_name=None, factory_parameters=None):
-    has_optional = any(param_info.is_optional
-        for param_info in self.param_infos)
-
-    if not factory_constructor_name:
-      factory_constructor_name = self.ConstructorFactoryName(rename_type)
-      factory_parameters = self.ParametersAsArgumentList()
-      has_factory_provider = True
-    else:
-      factory_parameters = ', '.join(factory_parameters)
-      has_factory_provider = False
-    if not has_optional:
-      emitter.Emit(
-          '\n'
-          '  factory $CTOR($PARAMS) => '
-          '$FACTORY.$CTOR_FACTORY_NAME($FACTORY_PARAMS);\n',
-          CTOR=self._ConstructorFullName(rename_type),
-          PARAMS=self.ParametersDeclaration(rename_type),
-          FACTORY=factory_name,
-          CTOR_FACTORY_NAME=factory_constructor_name,
-          FACTORY_PARAMS=factory_parameters)
-      return
-    if has_factory_provider:
-      self._GenerateFactoryOptParams(rename_type, emitter, factory_name)
-    else:
-      self._GenerateFactoryOptParamsWithoutFactoryProvider(rename_type, emitter,
-          factory_name, factory_constructor_name, factory_parameters)
-
-  def _GenerateFactoryOptParams(self, rename_type, emitter, factory_provider):
-    """Helper method for creating generic factory constructors with optional
-    parameters that use factory providers."""
-    dispatcher_emitter = emitter.Emit(
-        '\n'
-        '  factory $CTOR($PARAMS) {\n'
-        '$!DISPATCHER'
-        '    return $FACTORY.$CTOR_FACTORY_NAME($FACTORY_PARAMS);\n'
-        '  }\n',
-        CTOR=self._ConstructorFullName(rename_type),
-        PARAMS=self.ParametersDeclaration(rename_type),
-        FACTORY=factory_provider,
-        CTOR_FACTORY_NAME=self.ConstructorFactoryName(rename_type),
-        FACTORY_PARAMS=self.ParametersAsArgumentList())
-
-    # If we have optional parameters, check to see if they are set
-    # and call the appropriate factory method.
-    def EmitOptionalParameterInvocation(index):
-      dispatcher_emitter.Emit(
-        '    if (!?$OPT_PARAM_NAME) {\n'
-        '      return $FACTORY.$CTOR_FACTORY_NAME($FACTORY_PARAMS);\n'
-        '    }\n',
-        OPT_PARAM_NAME=self.param_infos[index].name,
-        FACTORY=factory_provider,
-        CTOR_FACTORY_NAME=self.ConstructorFactoryName(rename_type),
-        FACTORY_PARAMS=self.ParametersAsArgumentList(index))
-
-    for index, param_info in enumerate(self.param_infos):
-      if param_info.is_optional:
-        EmitOptionalParameterInvocation(index)
-
-  def _GenerateFactoryOptParamsWithoutFactoryProvider(self, rename_type,
-      emitter, factory_name, factory_constructor_name, factory_parameters):
-    """Helper method for creating a factory constructor with optional
-    parameters that does not call a factory provider, it simply creates the
-    object itself. This is currently used for SVGElements and HTMLElements."""
-    inits = emitter.Emit(
-        '\n'
-        '  factory $CONSTRUCTOR($PARAMS) {\n'
-        '    var e = $FACTORY.$CTOR_FACTORY_NAME($FACTORY_PARAMS);\n'
-        '$!INITS'
-        '    return e;\n'
-        '  }\n',
-        CONSTRUCTOR=self._ConstructorFullName(rename_type),
-        FACTORY=factory_name,
-        CTOR_FACTORY_NAME=factory_constructor_name,
-        PARAMS=self.ParametersDeclaration(rename_type),
-        FACTORY_PARAMS=factory_parameters)
-    for index, param_info in enumerate(self.param_infos):
-      if param_info.is_optional:
-        inits.Emit('    if ($E != null) e.$E = $E;\n',
-            E=self.param_infos[index].name)
-
 def ConstantOutputOrder(a, b):
   """Canonical output ordering for constants."""
-  if a.id < b.id: return -1
-  if a.id > b.id: return 1
-  return 0
+  return cmp(a.id, b.id)
 
 
 def _FormatNameList(names):
@@ -508,7 +422,7 @@
     # as well.  Note, there are no functions that take a non-local Window
     # as a parameter / setter.
     'DOMWindow get':
-      Conversion('_convertNativeToDart_Window', 'dynamic', 'Window'),
+      Conversion('_convertNativeToDart_Window', 'dynamic', 'WindowBase'),
     'EventTarget get':
       Conversion('_convertNativeToDart_EventTarget', 'dynamic',
                  'EventTarget'),
@@ -619,7 +533,7 @@
     # Methods returning Window can return a local window, or a cross-frame
     # window (=Object) that needs wrapping.
     'DOMWindow':
-      "@Creates('LocalWindow|=Object') @Returns('LocalWindow|=Object')",
+      "@Creates('Window|=Object') @Returns('Window|=Object')",
 
     'DOMWindow.openDatabase': "@Creates('Database') @Creates('DatabaseSync')",
 
@@ -701,7 +615,136 @@
       "@Creates('ArrayBuffer|Blob|Document|=Object|=List|String|num')",
 }
 
-def FindAnnotations(idl_type, interface_name, member_name):
+_indexed_db_annotations = [
+  "@SupportedBrowser(SupportedBrowser.CHROME)",
+  "@SupportedBrowser(SupportedBrowser.FIREFOX, '15')",
+  "@SupportedBrowser(SupportedBrowser.IE, '10')",
+  "@Experimental()",
+]
+
+_history_annotations = [
+  "@SupportedBrowser(SupportedBrowser.CHROME)",
+  "@SupportedBrowser(SupportedBrowser.FIREFOX)",
+  "@SupportedBrowser(SupportedBrowser.IE, '10')",
+  "@SupportedBrowser(SupportedBrowser.SAFARI)",
+]
+
+# Annotations to be placed on generated members.
+# The table is indexed as:
+#   INTERFACE:     annotations to be added to the interface declaration
+#   INTERFACE.MEMBER: annotation to be added to the member declaration
+dart_annotations = {
+  'ArrayBuffer': [
+    "@SupportedBrowser(SupportedBrowser.CHROME)",
+    "@SupportedBrowser(SupportedBrowser.FIREFOX)",
+    "@SupportedBrowser(SupportedBrowser.IE, '10')",
+    "@SupportedBrowser(SupportedBrowser.SAFARI)",
+  ],
+  'ArrayBufferView': [
+    "@SupportedBrowser(SupportedBrowser.CHROME)",
+    "@SupportedBrowser(SupportedBrowser.FIREFOX)",
+    "@SupportedBrowser(SupportedBrowser.IE, '10')",
+    "@SupportedBrowser(SupportedBrowser.SAFARI)",
+  ],
+  'DOMWindow.indexedDB': _indexed_db_annotations,
+  'Element.webkitCreateShadowRoot': [
+    "@SupportedBrowser(SupportedBrowser.CHROME, '25')",
+    "@Experimental()",
+  ],
+  'History.pushState': _history_annotations,
+  'History.replaceState': _history_annotations,
+  'HTMLContentElement': [
+    "@SupportedBrowser(SupportedBrowser.CHROME, '25')",
+    "@Experimental()",
+  ],
+  'HTMLDataListElement': [
+    "@SupportedBrowser(SupportedBrowser.CHROME)",
+    "@SupportedBrowser(SupportedBrowser.FIREFOX)",
+    "@SupportedBrowser(SupportedBrowser.IE, '10')",
+    "@SupportedBrowser(SupportedBrowser.SAFARI)",
+  ],
+  'HTMLDetailsElement': [
+    "@SupportedBrowser(SupportedBrowser.CHROME)",
+    "@SupportedBrowser(SupportedBrowser.SAFARI)",
+    "@Experimental()",
+  ],
+  'HTMLEmbedElement': [
+    "@SupportedBrowser(SupportedBrowser.CHROME)",
+    "@SupportedBrowser(SupportedBrowser.IE)",
+    "@SupportedBrowser(SupportedBrowser.SAFARI)",
+  ],
+  'HTMLKeygenElement': [
+    "@SupportedBrowser(SupportedBrowser.CHROME)",
+    "@SupportedBrowser(SupportedBrowser.SAFARI)",
+    "@Experimental()",
+  ],
+  'HTMLMeterElement': [
+    "@SupportedBrowser(SupportedBrowser.CHROME)",
+    "@SupportedBrowser(SupportedBrowser.FIREFOX)",
+    "@SupportedBrowser(SupportedBrowser.SAFARI)",
+  ],
+  'HTMLObjectElement': [
+    "@SupportedBrowser(SupportedBrowser.CHROME)",
+    "@SupportedBrowser(SupportedBrowser.FIREFOX)",
+    "@SupportedBrowser(SupportedBrowser.SAFARI)",
+  ],
+  'HTMLOutputElement': [
+    "@SupportedBrowser(SupportedBrowser.CHROME)",
+    "@SupportedBrowser(SupportedBrowser.FIREFOX)",
+    "@SupportedBrowser(SupportedBrowser.SAFARI)",
+  ],
+  'HTMLProgressElement': [
+    "@SupportedBrowser(SupportedBrowser.CHROME)",
+    "@SupportedBrowser(SupportedBrowser.FIREFOX)",
+    "@SupportedBrowser(SupportedBrowser.IE, '10')",
+    "@SupportedBrowser(SupportedBrowser.SAFARI)",
+  ],
+  'HTMLShadowElement': [
+    "@SupportedBrowser(SupportedBrowser.CHROME, '25')",
+    "@Experimental()",
+  ],
+  'HTMLTrackElement': [
+    "@SupportedBrowser(SupportedBrowser.CHROME)",
+    "@SupportedBrowser(SupportedBrowser.IE, '10')",
+    "@SupportedBrowser(SupportedBrowser.SAFARI)",
+  ],
+  'IDBFactory': _indexed_db_annotations,
+  'IDBDatabase': _indexed_db_annotations,
+  'ShadowRoot': [
+    "@SupportedBrowser(SupportedBrowser.CHROME, '25')",
+    "@Experimental()",
+  ],
+  'WorkerContext.indexedDB': _indexed_db_annotations,
+}
+
+def FindCommonAnnotations(interface_name, member_name=None):
+  """ Finds annotations common between dart2js and dartium.
+  """
+  if member_name:
+    return dart_annotations.get('%s.%s' % (interface_name, member_name))
+  else:
+    return dart_annotations.get(interface_name)
+
+def FindDart2JSAnnotations(idl_type, interface_name, member_name):
+  """ Finds all annotations for Dart2JS members- including annotations for
+  both dart2js and dartium.
+  """
+  annotations = FindCommonAnnotations(interface_name, member_name)
+  if annotations:
+    annotations = ' '.join(annotations)
+
+  ann2 = _FindDart2JSSpecificAnnotations(idl_type, interface_name, member_name)
+  if ann2:
+    if annotations:
+      annotations = annotations + ' ' + ann2
+    else:
+      annotations = ann2
+  return annotations
+
+def _FindDart2JSSpecificAnnotations(idl_type, interface_name, member_name):
+  """ Finds dart2js-specific annotations. This does not include ones shared with
+  dartium.
+  """
   ann1 = dart2js_annotations.get("%s.%s" % (interface_name, member_name))
   if ann1:
     ann2 = dart2js_annotations.get('+' + idl_type)
diff --git a/sdk/lib/html/scripts/go.sh b/tools/dom/scripts/go.sh
similarity index 100%
rename from sdk/lib/html/scripts/go.sh
rename to tools/dom/scripts/go.sh
diff --git a/sdk/lib/html/scripts/htmldartgenerator.py b/tools/dom/scripts/htmldartgenerator.py
similarity index 70%
rename from sdk/lib/html/scripts/htmldartgenerator.py
rename to tools/dom/scripts/htmldartgenerator.py
index d5d5630..46ba4ba 100644
--- a/sdk/lib/html/scripts/htmldartgenerator.py
+++ b/tools/dom/scripts/htmldartgenerator.py
@@ -8,18 +8,19 @@
 
 from generator import AnalyzeOperation, ConstantOutputOrder, \
     DartDomNameOfAttribute, FindMatchingAttribute, IsDartCollectionType, \
-    IsPureInterface
+    IsPureInterface, TypeOrNothing
 
 # Types that are accessible cross-frame in a limited fashion.
-# In these cases, the base type (e.g., Window) provides restricted access
-# while the subtype (e.g., LocalWindow) provides full access to the
+# In these cases, the base type (e.g., WindowBase) provides restricted access
+# while the subtype (e.g., Window) provides full access to the
 # corresponding objects if there are from the same frame.
 _secure_base_types = {
-  'LocalWindow': 'Window',
-  'LocalLocation': 'Location',
-  'LocalHistory': 'History',
+  'Window': 'WindowBase',
+  'Location': 'LocationBase',
+  'History': 'HistoryBase',
 }
 
+
 class HtmlDartGenerator(object):
   def __init__(self, interface, options):
     self._database = options.database
@@ -28,6 +29,16 @@
     self._interface_type_info = self._type_registry.TypeInfo(self._interface.id)
     self._renamer = options.renamer
 
+  def EmitSupportCheck(self):
+    if self.HasSupportCheck():
+      support_check = self.GetSupportCheck()
+      self._members_emitter.Emit('\n'
+          '  /**\n'
+          '   * Checks if this type is supported on the current platform\n'
+          '   */\n'
+          '  static bool get supported => $SUPPORT_CHECK;\n',
+          SUPPORT_CHECK=support_check)
+
   def EmitAttributeDocumentation(self, attribute):
     """ Emits the MDN dartdoc comment for an attribute.
     """
@@ -118,6 +129,17 @@
           self.SecondaryContext(parent_interface)
           self.AddOperation(info)
 
+  def AddConstant(self, constant):
+    const_name = self._renamer.RenameMember(
+        self._interface.id, constant, constant.id, dartify_name=False)
+    if not const_name:
+      return
+    type = TypeOrNothing(self._DartType(constant.type.id), constant.type.id)
+    self._members_emitter.Emit('\n  static const $TYPE$NAME = $VALUE;\n',
+        NAME=const_name,
+        TYPE=type,
+        VALUE=constant.value)
+
   def AddAttribute(self, attribute, declare_only=False):
     """ Adds an attribute to the generated class.
     Arguments:
@@ -171,6 +193,26 @@
     else:
       self.EmitOperation(info, method_name)
 
+  def _OverloadChecks(self,
+      operation,
+      parameter_names,
+      argument_count,
+      can_omit_type_check=lambda type, pos: False):
+    checks = []
+    for i in range(0, argument_count):
+      argument = operation.arguments[i]
+      parameter_name = parameter_names[i]
+      test_type = self._DartType(argument.type.id)
+      if test_type in ['dynamic', 'Object']:
+        checks.append('?%s' % parameter_name)
+      elif not can_omit_type_check(test_type, i):
+        checks.append('(%s is %s || %s == null)' % (
+            parameter_name, test_type, parameter_name))
+    # There can be multiple presence checks.  We need them all since a later
+    # optional argument could have been passed by name, leaving 'holes'.
+    checks.extend(['!?%s' % name for name in parameter_names[argument_count:]])
+    return checks
+
   def AdditionalImplementedInterfaces(self):
     # TODO: Include all implemented interfaces, including other Lists.
     implements = []
@@ -183,21 +225,19 @@
       implements.append('List<%s>' % item_type_info.dart_type())
     return implements
 
-  def AddConstructors(self, constructors, factory_name, class_name,
-      base_class, factory_constructor_name=None):
+  def AddConstructors(self,
+      constructors, factory_name, factory_constructor_name):
     """ Adds all of the constructors.
     Arguments:
       constructors - List of the constructors to be added.
       factory_name - Name of the factory for this class.
-      class_name - The name of this class.
-      base_class - The name of the base class which this extends.
       factory_constructor_name - The name of the constructor on the
           factory_name to call (calls an autogenerated FactoryProvider
           if unspecified)
     """
     for constructor_info in constructors:
-      self._AddConstructor(constructor_info, factory_name,
-          factory_constructor_name, constructor_info.factory_parameters)
+      self._AddConstructor(
+          constructor_info, factory_name, factory_constructor_name)
 
     typed_array_type = None
     for interface in self._database.Hierarchy(self._interface):
@@ -221,13 +261,83 @@
         TYPE=self._DartType(typed_array_type),
         FACTORY=factory_name)
 
-  def _AddConstructor(self, constructor_info, factory_name,
-      factory_constructor_name, factory_constructor_params):
+  def _AddConstructor(self,
+      constructor_info, factory_name, factory_constructor_name):
     self._members_emitter.Emit('\n  ///@docsEditable true');
-    constructor_info.GenerateFactoryInvocation(
-        self._DartType, self._members_emitter, factory_name,
-        factory_constructor_name=factory_constructor_name,
-        factory_parameters=factory_constructor_params)
+
+    if not factory_constructor_name:
+      factory_constructor_name = '_create'
+      factory_parameters = constructor_info.ParametersAsArgumentList()
+      has_factory_provider = True
+    else:
+      factory_parameters = ', '.join(constructor_info.factory_parameters)
+      has_factory_provider = False
+
+    has_optional = any(param_info.is_optional
+        for param_info in constructor_info.param_infos)
+
+    if not has_optional:
+      self._members_emitter.Emit(
+          '\n'
+          '  factory $CTOR($PARAMS) => '
+          '$FACTORY.$CTOR_FACTORY_NAME($FACTORY_PARAMS);\n',
+          CTOR=constructor_info._ConstructorFullName(self._DartType),
+          PARAMS=constructor_info.ParametersDeclaration(self._DartType),
+          FACTORY=factory_name,
+          CTOR_FACTORY_NAME=factory_constructor_name,
+          FACTORY_PARAMS=factory_parameters)
+    else:
+      if has_factory_provider:
+        dispatcher_emitter = self._members_emitter.Emit(
+            '\n'
+            '  factory $CTOR($PARAMS) {\n'
+            '$!DISPATCHER'
+            '    return $FACTORY._create($FACTORY_PARAMS);\n'
+            '  }\n',
+            CTOR=constructor_info._ConstructorFullName(self._DartType),
+            PARAMS=constructor_info.ParametersDeclaration(self._DartType),
+            FACTORY=factory_name,
+            FACTORY_PARAMS=constructor_info.ParametersAsArgumentList())
+
+        for index, param_info in enumerate(constructor_info.param_infos):
+          if param_info.is_optional:
+            dispatcher_emitter.Emit(
+              '    if (!?$OPT_PARAM_NAME) {\n'
+              '      return $FACTORY._create($FACTORY_PARAMS);\n'
+              '    }\n',
+              OPT_PARAM_NAME=param_info.name,
+              FACTORY=factory_name,
+              FACTORY_PARAMS=constructor_info.ParametersAsArgumentList(index))
+      else:
+        inits = self._members_emitter.Emit(
+            '\n'
+            '  factory $CONSTRUCTOR($PARAMS) {\n'
+            '    var e = $FACTORY.$CTOR_FACTORY_NAME($FACTORY_PARAMS);\n'
+            '$!INITS'
+            '    return e;\n'
+            '  }\n',
+            CONSTRUCTOR=constructor_info._ConstructorFullName(self._DartType),
+            FACTORY=factory_name,
+            CTOR_FACTORY_NAME=factory_constructor_name,
+            PARAMS=constructor_info.ParametersDeclaration(self._DartType),
+            FACTORY_PARAMS=factory_parameters)
+
+        for index, param_info in enumerate(constructor_info.param_infos):
+          if param_info.is_optional:
+            inits.Emit('    if ($E != null) e.$E = $E;\n', E=param_info.name)
+
+    if not constructor_info.pure_dart_constructor:
+      template_file = ('factoryprovider_%s.darttemplate' % self._interface.doc_js_name)
+      template = self._template_loader.TryLoad(template_file)
+      if template:
+        # There is a class specific factory.
+        # TODO(antonm): should move into the class template.
+        self._members_emitter.Emit(template)
+      else:
+        self.EmitStaticFactory(constructor_info)
+
+  def EmitHelpers(self, base_class):
+    pass
 
   def DeclareAttribute(self, attribute, type_name, attr_name, read_only):
     """ Declares an attribute but does not include the code to invoke it.
@@ -292,8 +402,8 @@
       dart_name = self._DartType(type_name)
     # We only need to secure Window.  Only local History and Location are
     # returned in generated code.
-    assert(dart_name != 'History' and dart_name != 'Location')
-    if dart_name == 'LocalWindow':
+    assert(dart_name != 'HistoryBase' and dart_name != 'LocationBase')
+    if dart_name == 'Window':
       return _secure_base_types[dart_name]
     return dart_name
 
diff --git a/sdk/lib/html/scripts/htmleventgenerator.py b/tools/dom/scripts/htmleventgenerator.py
similarity index 100%
rename from sdk/lib/html/scripts/htmleventgenerator.py
rename to tools/dom/scripts/htmleventgenerator.py
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py
new file mode 100644
index 0000000..6761de4
--- /dev/null
+++ b/tools/dom/scripts/htmlrenamer.py
@@ -0,0 +1,510 @@
+#!/usr/bin/python
+# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+import re
+
+html_interface_renames = {
+    'CDATASection': 'CDataSection',
+    'DOMApplicationCache': 'ApplicationCache',
+    'DOMCoreException': 'DomException',
+    'DOMFileSystem': 'FileSystem',
+    'DOMFileSystemSync': 'FileSystemSync',
+    'DOMFormData': 'FormData',
+    'DOMURL': 'Url',
+    'DOMWindow': 'Window',
+    'HTMLDocument' : 'HtmlDocument',
+    'IDBAny': '_Any', # Suppressed, but needs to exist for Dartium.
+    'IDBFactory': 'IdbFactory', # Manual to avoid name conflicts.
+    'SVGDocument': 'SvgDocument', # Manual to avoid name conflicts.
+    'SVGElement': 'SvgElement', # Manual to avoid name conflicts.
+    'SVGException': 'SvgException', # Manual of avoid conflict with Exception.
+    'SVGSVGElement': 'SvgSvgElement', # Manual to avoid name conflicts.
+    'WebGLVertexArrayObjectOES': 'WebGLVertexArrayObject',
+    'WebKitAnimation': 'Animation',
+    'WebKitAnimationEvent': 'AnimationEvent',
+    'WebKitBlobBuilder': 'BlobBuilder',
+    'WebKitCSSKeyframeRule': 'CssKeyframeRule',
+    'WebKitCSSKeyframesRule': 'CssKeyframesRule',
+    'WebKitCSSMatrix': 'CssMatrix',
+    'WebKitCSSTransformValue': 'CssTransformValue',
+    'WebKitFlags': 'Flags',
+    'WebKitLoseContext': 'LoseContext',
+    'WebKitPoint': 'Point',
+    'WebKitTransitionEvent': 'TransitionEvent',
+    'XMLHttpRequest': 'HttpRequest',
+    'XMLHttpRequestException': 'HttpRequestException',
+    'XMLHttpRequestProgressEvent': 'HttpRequestProgressEvent',
+    'XMLHttpRequestUpload': 'HttpRequestUpload',
+}
+
+# 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 = set([
+  'CustomEvent.initCustomEvent',
+  'Document.createElement',
+  'Document.createElementNS',
+  'Document.createEvent',
+  'Document.createRange',
+  'Document.createTextNode',
+  'Document.createTouch',
+  'Document.createTouchList',
+  'Document.getElementById',
+  'Document.getElementsByClassName',
+  'Document.getElementsByName',
+  'Document.getElementsByTagName',
+  'Document.querySelector',
+  'Document.querySelectorAll',
+
+  # Moved to HTMLDocument.
+  'Document.body',
+  'Document.caretRangeFromPoint',
+  'Document.elementFromPoint',
+  'Document.getCSSCanvasContext',
+  'Document.head',
+  'Document.lastModified',
+  'Document.preferredStylesheetSet',
+  'Document.referrer',
+  'Document.selectedStylesheetSet',
+  'Document.styleSheets',
+  'Document.title',
+  'Document.webkitCancelFullScreen',
+  'Document.webkitExitFullscreen',
+  'Document.webkitExitPointerLock',
+  'Document.webkitFullscreenElement',
+  'Document.webkitFullscreenEnabled',
+  'Document.webkitHidden',
+  'Document.webkitIsFullScreen',
+  'Document.webkitPointerLockElement',
+  'Document.webkitVisibilityState',
+
+  'DocumentFragment.querySelector',
+  'DocumentFragment.querySelectorAll',
+  'Element.childElementCount',
+  'Element.children',
+  'Element.className',
+  'Element.firstElementChild',
+  'Element.getAttribute',
+  'Element.getAttributeNS',
+  'Element.getElementsByClassName',
+  'Element.getElementsByTagName',
+  'Element.hasAttribute',
+  'Element.hasAttributeNS',
+  'Element.lastElementChild',
+  'Element.querySelector',
+  'Element.querySelectorAll',
+  'Element.removeAttribute',
+  'Element.removeAttributeNS',
+  'Element.setAttribute',
+  'Element.setAttributeNS',
+  'ElementTraversal.childElementCount',
+  'ElementTraversal.firstElementChild',
+  'ElementTraversal.lastElementChild',
+  'Event.initEvent',
+  'EventTarget.addEventListener',
+  'EventTarget.dispatchEvent',
+  'EventTarget.removeEventListener',
+  'KeyboardEvent.initKeyboardEvent',
+  'KeyboardEvent.keyIdentifier',
+  'MouseEvent.initMouseEvent',
+  'Node.appendChild',
+  'Node.attributes',
+  'Node.childNodes',
+  'Node.firstChild',
+  'Node.lastChild',
+  'Node.localName',
+  'Node.namespaceURI',
+  'Node.removeChild',
+  'Node.replaceChild',
+  'ShadowRoot.getElementById',
+  'ShadowRoot.getElementsByClassName',
+  'ShadowRoot.getElementsByTagName',
+  'Storage.clear',
+  'Storage.getItem',
+  'Storage.key',
+  'Storage.length',
+  'Storage.removeItem',
+  'Storage.setItem',
+  'UIEvent.charCode',
+  'UIEvent.initUIEvent',
+  'UIEvent.keyCode',
+  'WheelEvent.wheelDeltaX',
+  'WheelEvent.wheelDeltaY',
+  'Window.getComputedStyle',
+])
+
+# Members from the standard dom that exist in the dart:html library with
+# identical functionality but with cleaner names.
+_renamed_html_members = {
+    'AnimatedString.className': '$dom_svgClassName',
+    'Document.createCDATASection': 'createCDataSection',
+    'Document.defaultView': 'window',
+    'Element.scrollIntoViewIfNeeded': 'scrollIntoView',
+    'Element.webkitCreateShadowRoot': 'createShadowRoot',
+    'Element.webkitMatchesSelector' : 'matchesSelector',
+    'Node.cloneNode': 'clone',
+    'Node.nextSibling': 'nextNode',
+    'Node.ownerDocument': 'document',
+    'Node.parentElement': 'parent',
+    'Node.previousSibling': 'previousNode',
+    'Node.textContent': 'text',
+    'Stylable.className': '$dom_svgClassName',
+    'SvgElement.className': '$dom_svgClassName',
+    'Url.createObjectURL': 'createObjectUrl',
+    'Url.revokeObjectURL': 'revokeObjectUrl',
+}
+
+# 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.
+# Syntax is: ClassName.(get\.|set\.)?MemberName
+# Using get: and set: is optional and should only be used when a getter needs
+# to be suppressed but not the setter, etc.
+# TODO(jacobr): cleanup and augment this list.
+_removed_html_members = set([
+    'AnchorElement.charset',
+    'AnchorElement.coords',
+    'AnchorElement.rev',
+    'AnchorElement.shape',
+    'AnchorElement.text',
+    'AreaElement.noHref',
+    'Attr.*',
+    'BRElement.clear',
+    'BodyElement.aLink',
+    'BodyElement.background',
+    'BodyElement.bgColor',
+    'BodyElement.bgColor',
+    'BodyElement.link',
+    'BodyElement.text',
+    'BodyElement.text',
+    'BodyElement.vlink',
+    'CanvasRenderingContext2D.clearShadow',
+    'CanvasRenderingContext2D.drawImageFromRect',
+    'CanvasRenderingContext2D.setAlpha',
+    'CanvasRenderingContext2D.setCompositeOperation',
+    'CanvasRenderingContext2D.setFillColor',
+    'CanvasRenderingContext2D.setLineCap',
+    'CanvasRenderingContext2D.setLineJoin',
+    'CanvasRenderingContext2D.setLineWidth',
+    'CanvasRenderingContext2D.setMiterLimit',
+    'CanvasRenderingContext2D.setShadow',
+    'CanvasRenderingContext2D.setStrokeColor',
+    'Cursor.NEXT',
+    'Cursor.NEXT_NO_DUPLICATE',
+    'Cursor.PREV',
+    'Cursor.PREV_NO_DUPLICATE',
+    'DListElement.compact',
+    'DivElement.align',
+    'Document.adoptNode',
+    'Document.alinkColor',
+    'Document.all',
+    'Document.applets',
+    'Document.bgColor',
+    'Document.captureEvents',
+    'Document.clear',
+    'Document.createAttribute',
+    'Document.createAttributeNS',
+    'Document.createComment',
+    'Document.createEntityReference',
+    'Document.createExpression',
+    'Document.createNSResolver',
+    'Document.createNodeIterator',
+    'Document.createProcessingInstruction',
+    'Document.createTreeWalker',
+    'Document.designMode',
+    'Document.dir',
+    'Document.evaluate',
+    'Document.fgColor',
+    'Document.get:URL',
+    'Document.get:anchors',
+    'Document.get:applets',
+    'Document.get:characterSet',
+    'Document.get:compatMode',
+    'Document.get:compatMode',
+    'Document.get:defaultCharset',
+    'Document.get:doctype',
+    'Document.get:documentURI',
+    'Document.get:embeds',
+    'Document.get:forms',
+    'Document.get:height',
+    'Document.get:images',
+    'Document.get:inputEncoding',
+    'Document.get:links',
+    'Document.get:plugins',
+    'Document.get:scripts',
+    'Document.get:width',
+    'Document.get:xmlEncoding',
+    'Document.getElementsByTagNameNS',
+    'Document.getOverrideStyle',
+    'Document.getSelection',
+    'Document.images',
+    'Document.importNode',
+    'Document.linkColor',
+    'Document.location',
+    'Document.manifest',
+    'Document.open',
+    'Document.releaseEvents',
+    'Document.set:documentURI',
+    'Document.set:domain',
+    'Document.version',
+    'Document.vlinkColor',
+    'Document.webkitCurrentFullScreenElement',
+    'Document.webkitFullScreenKeyboardInputAllowed',
+    'Document.write',
+    'Document.writeln',
+    'Document.xmlStandalone',
+    'Document.xmlVersion',
+    'DocumentType.*',
+    'Element.accessKey',
+    'Element.get:classList',
+    'Element.get:itemProp',
+    'Element.get:itemRef',
+    'Element.get:itemType',
+    'Element.getAttributeNode',
+    'Element.getAttributeNodeNS',
+    'Element.getElementsByTagNameNS',
+    'Element.innerText',
+    'Element.itemId',
+    'Element.itemScope',
+    'Element.itemValue',
+    'Element.outerText',
+    'Element.removeAttributeNode',
+    'Element.scrollIntoView',
+    'Element.set:outerHTML',
+    'Element.setAttributeNode',
+    'Element.setAttributeNodeNS',
+    'Event.srcElement',
+    'EventSource.URL',
+    'FormElement.get:elements',
+    'HRElement.align',
+    'HRElement.noShade',
+    'HRElement.size',
+    'HRElement.width',
+    'HTMLFrameElement.*',
+    'HTMLFrameSetElement.*',
+    'HTMLIsIndexElement.*',
+    'HTMLOptionsCollection.*',
+    'HTMLPropertiesCollection.*',
+    'HeadElement.profile',
+    'HeadingElement.align',
+    'HtmlElement.manifest',
+    'HtmlElement.version',
+    'HtmlElement.version',
+    'IFrameElement.align',
+    'IFrameElement.frameBorder',
+    'IFrameElement.longDesc',
+    'IFrameElement.marginHeight',
+    'IFrameElement.marginWidth',
+    'IFrameElement.scrolling',
+    'ImageElement.align',
+    'ImageElement.hspace',
+    'ImageElement.longDesc',
+    'ImageElement.name',
+    'ImageElement.vspace',
+    'InputElement.align',
+    'Legend.align',
+    'LinkElement.charset',
+    'LinkElement.rev',
+    'LinkElement.target',
+    'Menu.compact',
+    'MenuElement.compact',
+    'MetaElement.scheme',
+    'NamedNodeMap.*',
+    'Node.compareDocumentPosition',
+    'Node.get:ATTRIBUTE_NODE',
+    'Node.get:CDATA_SECTION_NODE',
+    'Node.get:COMMENT_NODE',
+    'Node.get:DOCUMENT_FRAGMENT_NODE',
+    'Node.get:DOCUMENT_NODE',
+    'Node.get:DOCUMENT_POSITION_CONTAINED_BY',
+    'Node.get:DOCUMENT_POSITION_CONTAINS',
+    'Node.get:DOCUMENT_POSITION_DISCONNECTED',
+    'Node.get:DOCUMENT_POSITION_FOLLOWING',
+    'Node.get:DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC',
+    'Node.get:DOCUMENT_POSITION_PRECEDING',
+    'Node.get:DOCUMENT_TYPE_NODE',
+    'Node.get:ELEMENT_NODE',
+    'Node.get:ENTITY_NODE',
+    'Node.get:ENTITY_REFERENCE_NODE',
+    'Node.get:NOTATION_NODE',
+    'Node.get:PROCESSING_INSTRUCTION_NODE',
+    'Node.get:TEXT_NODE',
+    'Node.get:baseURI',
+    'Node.get:nodeName',
+    'Node.get:nodeValue',
+    'Node.get:prefix',
+    'Node.hasAttributes',
+    'Node.isDefaultNamespace',
+    'Node.isEqualNode',
+    'Node.isSameNode',
+    'Node.isSupported',
+    'Node.lookupNamespaceURI',
+    'Node.lookupPrefix',
+    'Node.normalize',
+    'Node.set:nodeValue',
+    'Node.set:prefix',
+    'NodeList.item',
+    'OListElement.compact',
+    'ObjectElement.align',
+    'ObjectElement.archive',
+    'ObjectElement.border',
+    'ObjectElement.codeBase',
+    'ObjectElement.codeType',
+    'ObjectElement.declare',
+    'ObjectElement.hspace',
+    'ObjectElement.standby',
+    'ObjectElement.vspace',
+    'OptionElement.text',
+    'ParagraphElement.align',
+    'ParamElement.type',
+    'ParamElement.valueType',
+    'PreElement.width',
+    'ScriptElement.text',
+    'SelectElement.options',
+    'SelectElement.remove',
+    'SelectElement.selectedOptions',
+    'ShadowRoot.getElementsByTagNameNS',
+    'TableCaptionElement.align',
+    'TableCellElement.abbr',
+    'TableCellElement.align',
+    'TableCellElement.axis',
+    'TableCellElement.bgColor',
+    'TableCellElement.ch',
+    'TableCellElement.chOff',
+    'TableCellElement.height',
+    'TableCellElement.noWrap',
+    'TableCellElement.scope',
+    'TableCellElement.vAlign',
+    'TableCellElement.width',
+    'TableColElement.align',
+    'TableColElement.ch',
+    'TableColElement.chOff',
+    'TableColElement.vAlign',
+    'TableColElement.width',
+    'TableElement.align',
+    'TableElement.bgColor',
+    'TableElement.cellPadding',
+    'TableElement.cellSpacing',
+    'TableElement.frame',
+    'TableElement.rules',
+    'TableElement.summary',
+    'TableElement.width',
+    'TableRowElement.align',
+    'TableRowElement.bgColor',
+    'TableRowElement.ch',
+    'TableRowElement.chOff',
+    'TableRowElement.vAlign',
+    'TableSectionElement.align',
+    'TableSectionElement.ch',
+    'TableSectionElement.choff',
+    'TableSectionElement.vAlign',
+    'TitleElement.text',
+    'Transaction.READ_ONLY',
+    'Transaction.READ_WRITE',
+    'UListElement.compact',
+    'UListElement.type',
+    'WheelEvent.wheelDelta',
+    'Window.blur',
+    'Window.clientInformation',
+    'Window.focus',
+    'Window.get:frames',
+    'Window.get:length',
+    'Window.prompt',
+    'Window.webkitCancelRequestAnimationFrame',
+    'Window.webkitIndexedDB',
+    'WorkerContext.webkitIndexedDB',
+# TODO(jacobr): should these be removed?
+    'Document.close',
+    'Document.hasFocus',
+    ])
+
+class HtmlRenamer(object):
+  def __init__(self, database):
+    self._database = database
+
+  def RenameInterface(self, interface):
+    if interface.id in html_interface_renames:
+      return html_interface_renames[interface.id]
+    elif interface.id.startswith('HTML'):
+      if any(interface.id in ['Element', 'Document']
+             for interface in self._database.Hierarchy(interface)):
+        return interface.id[len('HTML'):]
+    return self.DartifyTypeName(interface.id)
+
+
+  def RenameMember(self, interface_name, member_node, member, member_prefix='',
+      dartify_name=True):
+    """
+    Returns the name of the member in the HTML library or None if the member is
+    suppressed in the HTML library
+    """
+    interface = self._database.GetInterface(interface_name)
+
+    if self._FindMatch(interface, member, member_prefix, _removed_html_members):
+      return None
+
+    if 'CheckSecurityForNode' in member_node.ext_attrs:
+      return None
+
+    name = self._FindMatch(interface, member, member_prefix,
+                           _renamed_html_members)
+
+    target_name = _renamed_html_members[name] if name else member
+    if self._FindMatch(interface, member, member_prefix, _private_html_members):
+      if not target_name.startswith('$dom_'):  # e.g. $dom_svgClassName
+        target_name = '$dom_' + target_name
+
+    if dartify_name:
+      target_name = self._DartifyMemberName(target_name)
+    return target_name
+
+  def _FindMatch(self, interface, member, member_prefix, candidates):
+    for interface in self._database.Hierarchy(interface):
+      html_interface_name = self.RenameInterface(interface)
+      member_name = html_interface_name + '.' + member
+      if member_name in candidates:
+        return member_name
+      member_name = html_interface_name + '.' + member_prefix + member
+      if member_name in candidates:
+        return member_name
+
+  def GetLibraryName(self, interface):
+    if 'Conditional' in interface.ext_attrs:
+      if 'WEB_AUDIO' in interface.ext_attrs['Conditional']:
+        return 'web_audio'
+      if 'SVG' in interface.ext_attrs['Conditional']:
+        return 'svg'
+      if 'INDEXED_DATABASE' in interface.ext_attrs['Conditional']:
+        return 'indexed_db'
+
+    return 'html'
+
+  def DartifyTypeName(self, type_name):
+    """Converts a DOM name to a Dart-friendly class name. """
+
+    # Strip off any standard prefixes.
+    name = re.sub(r'^SVG', '', type_name)
+    name = re.sub(r'^IDB', '', name)
+
+    return self._CamelCaseName(name)
+
+  def _DartifyMemberName(self, member_name):
+    # Strip off any OpenGL ES suffixes.
+    name = re.sub(r'OES$', '', member_name)
+    return self._CamelCaseName(name)
+
+  def _CamelCaseName(self, name):
+
+    def toLower(match):
+      return match.group(1) + match.group(2).lower() + match.group(3)
+
+    # We're looking for a sequence of letters which start with capital letter
+    # then a series of caps and finishes with either the end of the string or
+    # a capital letter.
+    # The [0-9] check is for names such as 2D or 3D
+    # The following test cases should match as:
+    #   WebKitCSSFilterValue: WebKit(C)(SS)(F)ilterValue
+    #   XPathNSResolver: (X)()(P)ath(N)(S)(R)esolver (no change)
+    #   IFrameElement: (I)()(F)rameElement (no change)
+    return re.sub(r'([A-Z])([A-Z]{2,})([A-Z]|$)', toLower, name)
diff --git a/sdk/lib/html/scripts/idlnode.py b/tools/dom/scripts/idlnode.py
similarity index 100%
rename from sdk/lib/html/scripts/idlnode.py
rename to tools/dom/scripts/idlnode.py
diff --git a/sdk/lib/html/scripts/idlnode_test.py b/tools/dom/scripts/idlnode_test.py
similarity index 100%
rename from sdk/lib/html/scripts/idlnode_test.py
rename to tools/dom/scripts/idlnode_test.py
diff --git a/sdk/lib/html/scripts/idlparser.dart b/tools/dom/scripts/idlparser.dart
similarity index 100%
rename from sdk/lib/html/scripts/idlparser.dart
rename to tools/dom/scripts/idlparser.dart
diff --git a/sdk/lib/html/scripts/idlparser.py b/tools/dom/scripts/idlparser.py
similarity index 100%
rename from sdk/lib/html/scripts/idlparser.py
rename to tools/dom/scripts/idlparser.py
diff --git a/sdk/lib/html/scripts/idlparser_test.dart b/tools/dom/scripts/idlparser_test.dart
similarity index 100%
rename from sdk/lib/html/scripts/idlparser_test.dart
rename to tools/dom/scripts/idlparser_test.dart
diff --git a/sdk/lib/html/scripts/idlparser_test.py b/tools/dom/scripts/idlparser_test.py
similarity index 100%
rename from sdk/lib/html/scripts/idlparser_test.py
rename to tools/dom/scripts/idlparser_test.py
diff --git a/sdk/lib/html/scripts/idlrenderer.dart b/tools/dom/scripts/idlrenderer.dart
similarity index 100%
rename from sdk/lib/html/scripts/idlrenderer.dart
rename to tools/dom/scripts/idlrenderer.dart
diff --git a/sdk/lib/html/scripts/idlrenderer.py b/tools/dom/scripts/idlrenderer.py
similarity index 100%
rename from sdk/lib/html/scripts/idlrenderer.py
rename to tools/dom/scripts/idlrenderer.py
diff --git a/sdk/lib/html/scripts/idlrenderer_test.py b/tools/dom/scripts/idlrenderer_test.py
similarity index 100%
rename from sdk/lib/html/scripts/idlrenderer_test.py
rename to tools/dom/scripts/idlrenderer_test.py
diff --git a/sdk/lib/html/scripts/idlsync.py b/tools/dom/scripts/idlsync.py
similarity index 97%
rename from sdk/lib/html/scripts/idlsync.py
rename to tools/dom/scripts/idlsync.py
index 930698f..ba4c4ee 100755
--- a/sdk/lib/html/scripts/idlsync.py
+++ b/tools/dom/scripts/idlsync.py
@@ -12,7 +12,7 @@
 import sys
 
 SCRIPT_PATH = os.path.abspath(os.path.dirname(__file__))
-DART_PATH = os.path.abspath(os.path.join(SCRIPT_PATH, '..', '..', '..'))
+DART_PATH = os.path.abspath(os.path.join(SCRIPT_PATH, '..', '..', '..', '..'))
 
 # Path to install latest IDL.
 IDL_PATH = os.path.join(DART_PATH, 'third_party', 'WebCore')
@@ -91,7 +91,7 @@
 See the attached LICENSE-* files in this directory.
 
 Please do not modify the files here.  They are periodically copied
-using the script: $DART_ROOT/lib/dom/scripts/%(script)s
+using the script: $DART_ROOT/sdk/lib/html/scripts/%(script)s
 
 The current version corresponds to:
 URL: %(url)s
diff --git a/sdk/lib/html/scripts/logging.conf b/tools/dom/scripts/logging.conf
similarity index 100%
rename from sdk/lib/html/scripts/logging.conf
rename to tools/dom/scripts/logging.conf
diff --git a/sdk/lib/html/scripts/multiemitter.py b/tools/dom/scripts/multiemitter.py
similarity index 100%
rename from sdk/lib/html/scripts/multiemitter.py
rename to tools/dom/scripts/multiemitter.py
diff --git a/sdk/lib/html/scripts/multiemitter_test.py b/tools/dom/scripts/multiemitter_test.py
similarity index 100%
rename from sdk/lib/html/scripts/multiemitter_test.py
rename to tools/dom/scripts/multiemitter_test.py
diff --git a/sdk/lib/html/scripts/pegparser.py b/tools/dom/scripts/pegparser.py
similarity index 100%
rename from sdk/lib/html/scripts/pegparser.py
rename to tools/dom/scripts/pegparser.py
diff --git a/sdk/lib/html/scripts/pegparser_test.py b/tools/dom/scripts/pegparser_test.py
similarity index 100%
rename from sdk/lib/html/scripts/pegparser_test.py
rename to tools/dom/scripts/pegparser_test.py
diff --git a/sdk/lib/html/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
similarity index 90%
rename from sdk/lib/html/scripts/systemhtml.py
rename to tools/dom/scripts/systemhtml.py
index 3a7abb5..02a4f5b 100644
--- a/sdk/lib/html/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -12,6 +12,7 @@
 from htmldartgenerator import *
 
 _js_custom_members = set([
+    'ArrayBuffer.slice',
     'AudioBufferSourceNode.start',
     'AudioBufferSourceNode.stop',
     'AudioContext.createGain',
@@ -44,8 +45,6 @@
     'Element.remove',
     'ElementEvents.mouseWheel',
     'HTMLCanvasElement.getContext',
-    'HTMLSelectElement.options',
-    'HTMLSelectElement.selectedOptions',
     'HTMLTableElement.createTBody',
     'IDBDatabase.transaction',
     'KeyboardEvent.initKeyboardEvent',
@@ -68,6 +67,24 @@
     'WorkerContext.indexedDB',
     ])
 
+js_support_checks = {
+  'ArrayBuffer': "JS('bool', 'typeof window.ArrayBuffer != \"undefined\"')",
+  'HTMLContentElement': "Element.isTagSupported('content')",
+  'HTMLDataListElement': "Element.isTagSupported('datalist')",
+  'HTMLDetailsElement': "Element.isTagSupported('details')",
+  'HTMLEmbedElement': "Element.isTagSupported('embed')",
+  # IE creates keygen as Block elements
+  'HTMLKeygenElement': "Element.isTagSupported('keygen') "
+      "&& (new Element.tag('keygen') is KeygenElement)",
+  'HTMLMarqueeElement': "Element.isTagSupported('marquee')"
+      "&& (new Element.tag('marquee') is MarqueeElement)",
+  'HTMLMeterElement': "Element.isTagSupported('meter')",
+  'HTMLObjectElement': "Element.isTagSupported('object')",
+  'HTMLOutputElement': "Element.isTagSupported('output')",
+  'HTMLProgressElement': "Element.isTagSupported('progress')",
+  'HTMLShadowElement': "Element.isTagSupported('shadow')",
+  'HTMLTrackElement': "Element.isTagSupported('track')",
+}
 
 # Classes that offer only static methods, and therefore we should suppress
 # constructor creation.
@@ -102,6 +119,7 @@
                            self.opt_params)
     info.requires_named_arguments = True
     info.factory_parameters = ['"%s"' % self.tag]
+    info.pure_dart_constructor = True
     return info
 
 _html_element_constructors = {
@@ -138,8 +156,6 @@
     ElementConstructorInfo(tag='img',
                            opt_params=[('DOMString', 'src'),
                                        ('int', 'width'), ('int', 'height')]),
-  'InputElement':
-    ElementConstructorInfo(tag='input', opt_params=[('DOMString', 'type')]),
   'KeygenElement': 'keygen',
   'LIElement': 'li',
   'LabelElement': 'label',
@@ -321,11 +337,8 @@
       constructor_info = AnalyzeConstructor(self._interface)
     if constructor_info:
       constructors.append(constructor_info)
-      factory_provider = '_' + interface_name + 'FactoryProvider'
-      factory_provider_emitter = self._library_emitter.FileEmitter(
-          '_%sFactoryProvider' % interface_name, self._library_name)
-      self._backend.EmitFactoryProvider(
-          constructor_info, factory_provider, factory_provider_emitter)
+      # TODO(antonm): consider removing it later.
+      factory_provider = interface_name
 
     # HTML Elements and SVG Elements have convenience constructors.
     infos = ElementConstructorInfos(interface_name,
@@ -375,19 +388,26 @@
     if implements:
       implements_str = ' implements ' + ', '.join(set(implements))
 
+    annotations = FindCommonAnnotations(self._interface.doc_js_name)
+    annotations_str = ''
+    if annotations:
+      annotations_str = '\n' + '\n'.join(annotations)
+
     self._implementation_members_emitter = implementation_emitter.Emit(
         self._backend.ImplementationTemplate(),
         LIBRARYNAME=self._library_name,
+        ANNOTATIONS=annotations_str,
         CLASSNAME=self._interface_type_info.implementation_name(),
         EXTENDS=' extends %s' % base_class if base_class else '',
         IMPLEMENTS=implements_str,
         DOMNAME=self._interface.doc_js_name,
         NATIVESPEC=self._backend.NativeSpec())
     self._backend.StartInterface(self._implementation_members_emitter)
+    self._backend.EmitHelpers(base_class)
+    self._backend.AddConstructors(
+        constructors, factory_provider, factory_constructor_name)
 
-    self._backend.AddConstructors(constructors, factory_provider,
-        self._interface_type_info.implementation_name(),
-        base_class, factory_constructor_name=factory_constructor_name)
+    self._backend.EmitSupportCheck()
 
     events_class_name = self._event_generator.ProcessInterface(
         self._interface, interface_name,
@@ -462,31 +482,58 @@
     return (self._template_loader.TryLoad(template_file) or
             self._template_loader.Load('dart2js_impl.darttemplate'))
 
-  def StartInterface(self, emitter):
-    self._members_emitter = emitter
+  def StartInterface(self, members_emitter):
+    self._members_emitter = members_emitter
 
   def FinishInterface(self):
     pass
 
-  def EmitFactoryProvider(self, constructor_info, factory_provider, emitter):
-    template_file = ('factoryprovider_%s.darttemplate' %
-                     self._interface.doc_js_name)
-    template = self._template_loader.TryLoad(template_file)
-    if not template:
-      template = self._template_loader.Load('factoryprovider.darttemplate')
+  def HasSupportCheck(self):
+    return self._interface.doc_js_name in js_support_checks
 
-    interface_name = self._interface_type_info.interface_name()
-    arguments = constructor_info.ParametersAsArgumentList()
-    comma = ',' if arguments else ''
-    emitter.Emit(
-        template,
-        FACTORYPROVIDER=factory_provider,
-        CONSTRUCTOR=interface_name,
-        PARAMETERS=constructor_info.ParametersDeclaration(self._DartType),
-        NAMED_CONSTRUCTOR=constructor_info.name or self._interface.doc_js_name,
-        ARGUMENTS=arguments,
-        PRE_ARGUMENTS_COMMA=comma,
-        ARGUMENTS_PATTERN=','.join(['#'] * len(constructor_info.param_infos)))
+  def GetSupportCheck(self):
+    return js_support_checks.get(self._interface.doc_js_name)
+
+  def EmitStaticFactory(self, constructor_info):
+    has_optional = any(param_info.is_optional
+        for param_info in constructor_info.param_infos)
+
+    def FormatJS(index):
+      arguments = constructor_info.ParametersAsArgumentList(index)
+      if arguments:
+        arguments = ', ' + arguments
+      return "JS('%s', 'new %s(%s)'%s)" % (
+          self._interface_type_info.interface_name(),
+          constructor_info.name or self._interface.doc_js_name,
+          ','.join(['#'] * index),
+          arguments)
+
+    if not has_optional:
+      self._members_emitter.Emit(
+          "  static $INTERFACE_NAME _create($PARAMETERS_DECLARATION) => $JS;\n",
+          INTERFACE_NAME=self._interface_type_info.interface_name(),
+          PARAMETERS_DECLARATION=constructor_info.ParametersDeclaration(
+              self._DartType),
+          JS=FormatJS(len(constructor_info.param_infos)))
+    else:
+      dispatcher_emitter = self._members_emitter.Emit(
+          "  static $INTERFACE_NAME _create($PARAMETERS_DECLARATION) {\n"
+          "$!DISPATCHER"
+          "    return $JS;\n"
+          "  }\n",
+          INTERFACE_NAME=self._interface_type_info.interface_name(),
+          PARAMETERS_DECLARATION=constructor_info.ParametersDeclaration(
+              self._DartType),
+          JS=FormatJS(len(constructor_info.param_infos)))
+
+      for index, param_info in enumerate(constructor_info.param_infos):
+        if param_info.is_optional:
+          dispatcher_emitter.Emit(
+            "    if (!?$OPT_PARAM_NAME) {\n"
+            "      return $JS;\n"
+            "    }\n",
+            OPT_PARAM_NAME=constructor_info.param_infos[index].name,
+            JS=FormatJS(index))
 
   def SecondaryContext(self, interface):
     if interface is not self._current_secondary_parent:
@@ -812,21 +859,12 @@
           PARAMS=', '.join(target_parameters))
 
     def GenerateChecksAndCall(operation, argument_count):
-      checks = []
-      for i in range(0, argument_count):
-        argument = operation.arguments[i]
-        parameter_name = parameter_names[i]
-        test_type = self._DartType(argument.type.id)
-        if test_type in ['dynamic', 'Object']:
-          checks.append('?%s' % parameter_name)
-        elif test_type != parameter_types[i]:
-          checks.append('(?%s && (%s is %s || %s == null))' % (
-              parameter_name, parameter_name, test_type, parameter_name))
-
-      checks.extend(['!?%s' % name for name in parameter_names[argument_count:]])
-      # There can be multiple presence checks.  We need them all since a later
-      # optional argument could have been passed by name, leaving 'holes'.
-      GenerateCall(operation, argument_count, checks)
+      GenerateCall(operation, argument_count,
+          self._OverloadChecks(
+            operation,
+            parameter_names,
+            argument_count,
+            can_omit_type_check=lambda type, pos: type == parameter_types[pos]))
 
     # TODO: Optimize the dispatch to avoid repeated checks.
     if len(operations) > 1:
@@ -856,13 +894,6 @@
         NAME=info.name,
         PARAMS=info.ParametersDeclaration(self._NarrowInputType))
 
-  def AddConstant(self, constant):
-    type = TypeOrNothing(self._DartType(constant.type.id), constant.type.id)
-    self._members_emitter.Emit('\n  static const $TYPE$NAME = $VALUE;\n',
-        NAME=constant.id,
-        TYPE=type,
-        VALUE=constant.value)
-
   def _IsOptional(self, operation, argument):
     return IsOptional(argument)
 
@@ -894,7 +925,8 @@
     return ''
 
   def _Annotations(self, idl_type, idl_member_name):
-    annotations = FindAnnotations(idl_type, self._interface.id, idl_member_name)
+    annotations = FindDart2JSAnnotations(idl_type, self._interface.id,
+        idl_member_name)
     if annotations:
       return '%s\n  ' % annotations
     return_type = self.SecureOutputType(idl_type)
diff --git a/sdk/lib/html/scripts/systemnative.py b/tools/dom/scripts/systemnative.py
similarity index 87%
rename from sdk/lib/html/scripts/systemnative.py
rename to tools/dom/scripts/systemnative.py
index 6e20379..ca6789f 100644
--- a/sdk/lib/html/scripts/systemnative.py
+++ b/tools/dom/scripts/systemnative.py
@@ -10,6 +10,7 @@
 import os
 from generator import *
 from htmldartgenerator import *
+from systemhtml import js_support_checks
 
 class DartiumBackend(HtmlDartGenerator):
   """Generates Dart implementation for one DOM IDL interface."""
@@ -130,32 +131,14 @@
     self._cpp_definitions_emitter = emitter.Emitter()
     self._cpp_resolver_emitter = emitter.Emitter()
 
-    self._GenerateConstructors()
+    # We need to revisit our treatment of typed arrays, right now
+    # it is full of hacks.
+    if self._interface.ext_attrs.get('ConstructorTemplate') == 'TypedArray':
+      self._cpp_resolver_emitter.Emit(
+          '    if (name == "$(INTERFACE_NAME)_constructor_Callback")\n'
+          '        return Dart$(INTERFACE_NAME)Internal::constructorCallback;\n',
+          INTERFACE_NAME=self._interface.id)
 
-  def _GenerateConstructors(self):
-    if not self._IsConstructable():
-      return
-
-    # TODO(antonm): currently we don't have information about number of arguments expected by
-    # the constructor, so name only dispatch.
-    self._cpp_resolver_emitter.Emit(
-        '    if (name == "$(INTERFACE_NAME)_constructor_Callback")\n'
-        '        return Dart$(INTERFACE_NAME)Internal::constructorCallback;\n',
-        INTERFACE_NAME=self._interface.id)
-
-
-    constructor_info = AnalyzeConstructor(self._interface)
-
-    ext_attrs = self._interface.ext_attrs
-
-    if 'CustomConstructor' in ext_attrs:
-      # We have a custom implementation for it.
-      self._cpp_declarations_emitter.Emit(
-          '\n'
-          'void constructorCallback(Dart_NativeArguments);\n')
-      return
-
-    if ext_attrs.get('ConstructorTemplate') == 'TypedArray':
       self._cpp_impl_includes.add('"DartArrayBufferViewCustom.h"');
       self._cpp_definitions_emitter.Emit(
         '\n'
@@ -164,6 +147,45 @@
         '    WebCore::DartArrayBufferViewInternal::constructWebGLArray<Dart$(INTERFACE_NAME)>(args);\n'
         '}\n',
         INTERFACE_NAME=self._interface.id);
+
+  def EmitHelpers(self, base_class):
+    # Emit internal constructor which is necessary for Dartium bindings
+    # to construct wrappers from C++.  Eventually it should go away
+    # once it is possible to construct such an instance directly.
+    super_constructor = ''
+    if base_class and base_class != 'NativeFieldWrapperClass1':
+      super_constructor = ' : super.internal()'
+    self._members_emitter.Emit(
+        '  $CLASSNAME.internal()$SUPERCONSTRUCTOR;\n',
+        CLASSNAME=self._interface_type_info.implementation_name(),
+        SUPERCONSTRUCTOR=super_constructor)
+
+  def EmitStaticFactory(self, constructor_info):
+    constructor_callback_id = self._interface.id + '_constructor_Callback'
+
+    self._members_emitter.Emit(
+        '  static $INTERFACE_NAME _create($PARAMETERS_DECLARATION) '
+          'native "$CONSTRUCTOR_CALLBACK_ID";\n',
+        INTERFACE_NAME=self._interface_type_info.interface_name(),
+        PARAMETERS_DECLARATION=constructor_info.ParametersDeclaration(
+            self._DartType),
+        CONSTRUCTOR_CALLBACK_ID=constructor_callback_id)
+
+    # TODO(antonm): currently we don't have information about number of arguments expected by
+    # the constructor, so name only dispatch.
+    self._cpp_resolver_emitter.Emit(
+        '    if (name == "$CONSTRUCTOR_CALLBACK_ID")\n'
+        '        return Dart$(WEBKIT_INTERFACE_NAME)Internal::constructorCallback;\n',
+        CONSTRUCTOR_CALLBACK_ID=constructor_callback_id,
+        WEBKIT_INTERFACE_NAME=self._interface.id)
+
+    ext_attrs = self._interface.ext_attrs
+
+    if 'CustomConstructor' in ext_attrs:
+      # We have a custom implementation for it.
+      self._cpp_declarations_emitter.Emit(
+          '\n'
+          'void constructorCallback(Dart_NativeArguments);\n')
       return
 
     create_function = 'create'
@@ -179,54 +201,13 @@
         self._interface.id,
         'ConstructorRaisesException' in ext_attrs)
 
-  ATTRIBUTES_OF_CONSTRUCTABLE = set([
-    'CustomConstructor',
-    'V8CustomConstructor',
-    'Constructor',
-    'NamedConstructor'])
+  def HasSupportCheck(self):
+    # Need to omit a support check if it is conditional in JS.
+    return self._interface.doc_js_name in js_support_checks
 
-  def _IsConstructable(self):
-    ext_attrs = self._interface.ext_attrs
-
-    if self.ATTRIBUTES_OF_CONSTRUCTABLE & set(ext_attrs):
-      return True
-
-    # FIXME: support other types of ConstructorTemplate.
-    if ext_attrs.get('ConstructorTemplate') == 'TypedArray':
-      return True
-
-    return False
-
-  def EmitFactoryProvider(self, constructor_info, factory_provider, emitter):
-    interface_name = self._interface_type_info.interface_name()
-    template_file = ('factoryprovider_%s.darttemplate' %
-                     self._interface.doc_js_name)
-    template = self._template_loader.TryLoad(template_file)
-    if not template:
-      template = self._template_loader.Load('factoryprovider.darttemplate')
-
-    native_binding = '%s_constructor_Callback' % self._interface.id
-    emitter.Emit(
-        template,
-        FACTORYPROVIDER=factory_provider,
-        INTERFACE=interface_name,
-        PARAMETERS=constructor_info.ParametersDeclaration(self._DartType),
-        ARGUMENTS=constructor_info.ParametersAsArgumentList(),
-        NATIVE_NAME=native_binding)
-
-  def AddConstructors(self, constructors, factory_name, class_name,
-      base_class, factory_constructor_name=None):
-    super(DartiumBackend, self).AddConstructors(constructors, factory_name,
-        class_name, base_class, factory_constructor_name)
-
-    super_constructor = ''
-    if base_class and base_class != 'NativeFieldWrapperClass1':
-      super_constructor = ': super.internal()'
-
-    self._members_emitter.Emit(
-        '  $CLASSNAME.internal()$SUPERCONSTRUCTOR;\n',
-        CLASSNAME=class_name,
-        SUPERCONSTRUCTOR=super_constructor)
+  def GetSupportCheck(self):
+    # Assume that everything is supported on Dartium.
+    return 'true'
 
   def FinishInterface(self):
     self._GenerateCPPHeader()
@@ -470,14 +451,7 @@
     else:
       self._GenerateDispatcher(info.operations, dart_declaration, [info.name for info in info.param_infos])
 
-  def AddConstant(self, constant):
-    type = TypeOrNothing(self._DartType(constant.type.id), constant.type.id)
-    self._members_emitter.Emit('\n  static const $TYPE$NAME = $VALUE;\n',
-        NAME=constant.id,
-        TYPE=type,
-        VALUE=constant.value)
-
-  def _GenerateDispatcher(self, operations, dart_declaration, argument_names):
+  def _GenerateDispatcher(self, operations, dart_declaration, parameter_names):
 
     body = self._members_emitter.Emit(
         '\n'
@@ -501,7 +475,7 @@
 
       overload_name = '%s_%s' % (operation.id, version[0])
       version[0] += 1
-      argument_list = ', '.join(argument_names[:argument_count])
+      argument_list = ', '.join(parameter_names[:argument_count])
       call = '_%s(%s)' % (overload_name, argument_list)
       body.Emit(template, CHECKS=' && '.join(checks), CALL=call)
 
@@ -515,15 +489,8 @@
       self._GenerateOperationNativeCallback(operation, operation.arguments[:argument_count], cpp_callback_name)
 
     def GenerateChecksAndCall(operation, argument_count):
-      checks = []
-      for i in range(0, argument_count):
-        argument = operation.arguments[i]
-        argument_name = argument_names[i]
-        type = self._DartType(argument.type.id)
-        if type not in ['dynamic', 'Object']:
-          checks.append('(%s is %s || %s == null)' % (argument_name, type, argument_name))
-      checks.extend(['!?%s' % name for name in argument_names[argument_count:]])
-      GenerateCall(operation, argument_count, checks)
+      GenerateCall(operation, argument_count,
+          self._OverloadChecks(operation, parameter_names, argument_count))
 
     # TODO: Optimize the dispatch to avoid repeated checks.
     if len(operations) > 1:
@@ -538,7 +505,7 @@
       argument_count = len(operation.arguments)
       for position, argument in list(enumerate(operation.arguments))[::-1]:
         if self._IsArgumentOptionalInWebCore(operation, argument):
-          check = '?%s' % argument_names[position]
+          check = '?%s' % parameter_names[position]
           # argument_count instead of position + 1 is used here to cover one
           # complicated case with the effectively optional argument in the middle.
           # Consider foo(x, [Optional] y, [Optional=DefaultIsNullString] z)
@@ -577,15 +544,27 @@
 
     cpp_arguments = []
     requires_v8_scope = \
-        any((self._TypeInfo(argument.type.id).requires_v8_scope() for argument in arguments))
+        any((self._TypeInfo(argument.type.id).requires_v8_scope() for argument in arguments)) or\
+        self._interface.id.startswith('IDB')
     runtime_check = None
     raises_exceptions = raises_dom_exception or arguments
 
-    requires_stack_info = ext_attrs.get('CallWith') == 'ScriptArguments|CallStack'
+    # TODO(antonm): unify with ScriptState below.
+    requires_stack_info = ext_attrs.get('CallWith') == 'ScriptArguments|ScriptState'
     if requires_stack_info:
       raises_exceptions = True
       requires_v8_scope = True
-      cpp_arguments = ['scriptArguments', 'scriptCallStack']
+      cpp_arguments = ['&state', 'scriptArguments.release()']
+      # WebKit uses scriptArguments to reconstruct last argument, so
+      # it's not needed and should be just removed.
+      arguments = arguments[:-1]
+
+    # TODO(antonm): unify with ScriptState below.
+    requires_script_arguments = ext_attrs.get('CallWith') == 'ScriptArguments'
+    if requires_script_arguments:
+      raises_exceptions = True
+      requires_v8_scope = True
+      cpp_arguments = ['scriptArguments.release()']
       # WebKit uses scriptArguments to reconstruct last argument, so
       # it's not needed and should be just removed.
       arguments = arguments[:-1]
@@ -595,6 +574,11 @@
       raises_exceptions = True
       cpp_arguments = ['context']
 
+    requires_script_state = ext_attrs.get('CallWith') == 'ScriptState'
+    if requires_script_state:
+      raises_exceptions = True
+      cpp_arguments = ['&state']
+
     requires_dom_window = 'NamedConstructor' in ext_attrs
     if requires_dom_window:
       raises_exceptions = True
@@ -674,6 +658,15 @@
           '            goto fail;\n'
           '        }\n\n')
 
+    if requires_script_state:
+      body_emitter.Emit(
+          '        ScriptState* currentState = ScriptState::current();\n'
+          '        if (!currentState) {\n'
+          '            exception = Dart_NewStringFromCString("Failed to retrieve a script state");\n'
+          '            goto fail;\n'
+          '        }\n'
+          '        ScriptState& state = *currentState;\n\n')
+
     if requires_dom_window:
       self._cpp_impl_includes.add('"DOMWindow.h"')
       body_emitter.Emit(
@@ -691,7 +684,26 @@
 
     if requires_stack_info:
       self._cpp_impl_includes.add('"ScriptArguments.h"')
-      self._cpp_impl_includes.add('"ScriptCallStack.h"')
+      body_emitter.Emit(
+          '\n'
+          '        ScriptState* currentState = ScriptState::current();\n'
+          '        if (!currentState) {\n'
+          '            exception = Dart_NewStringFromCString("Failed to retrieve a script state");\n'
+          '            goto fail;\n'
+          '        }\n'
+          '        ScriptState& state = *currentState;\n'
+          '\n'
+          '        Dart_Handle customArgument = Dart_GetNativeArgument(args, $INDEX);\n'
+          '        RefPtr<ScriptArguments> scriptArguments(DartUtilities::createScriptArguments(customArgument, exception));\n'
+          '        if (!scriptArguments)\n'
+          '            goto fail;\n'
+          '        RefPtr<ScriptCallStack> scriptCallStack(DartUtilities::createScriptCallStack());\n'
+          '        if (!scriptCallStack->size())\n'
+          '            return;\n',
+          INDEX=len(arguments) + 1)
+
+    if requires_script_arguments:
+      self._cpp_impl_includes.add('"ScriptArguments.h"')
       body_emitter.Emit(
           '\n'
           '        Dart_Handle customArgument = Dart_GetNativeArgument(args, $INDEX);\n'
@@ -770,13 +782,21 @@
 
   def _GenerateNativeBinding(self, idl_name, argument_count, dart_declaration,
       native_suffix, is_custom):
+    annotations = FindCommonAnnotations(self._interface.id, idl_name)
+    if annotations:
+      annotation_str = '\n  ' + '\n  '.join(annotations)
+    else:
+      annotation_str = ''
+
     native_binding = '%s_%s_%s' % (self._interface.id, idl_name, native_suffix)
     self._members_emitter.Emit(
         '\n'
         '\n  /** @domName $DOMINTERFACE.$DOMNAME */'
+        '$ANNOTATIONS'
         '\n  $DART_DECLARATION native "$NATIVE_BINDING";\n',
         DOMINTERFACE=self._interface.id,
         DOMNAME=idl_name,
+        ANNOTATIONS=annotation_str,
         DART_DECLARATION=dart_declaration,
         NATIVE_BINDING=native_binding)
 
diff --git a/sdk/lib/html/scripts/templateloader.py b/tools/dom/scripts/templateloader.py
similarity index 100%
rename from sdk/lib/html/scripts/templateloader.py
rename to tools/dom/scripts/templateloader.py
diff --git a/sdk/lib/html/scripts/templateloader_test.py b/tools/dom/scripts/templateloader_test.py
similarity index 100%
rename from sdk/lib/html/scripts/templateloader_test.py
rename to tools/dom/scripts/templateloader_test.py
diff --git a/sdk/lib/html/src/AttributeMap.dart b/tools/dom/src/AttributeMap.dart
similarity index 100%
rename from sdk/lib/html/src/AttributeMap.dart
rename to tools/dom/src/AttributeMap.dart
diff --git a/sdk/lib/html/src/CrossFrameTypes.dart b/tools/dom/src/CrossFrameTypes.dart
similarity index 83%
rename from sdk/lib/html/src/CrossFrameTypes.dart
rename to tools/dom/src/CrossFrameTypes.dart
index 5677eea..7034d24 100644
--- a/sdk/lib/html/src/CrossFrameTypes.dart
+++ b/tools/dom/src/CrossFrameTypes.dart
@@ -12,7 +12,7 @@
  * is the container that displays a [Document]'s content. All web scripting
  * happens within the context of a [Window] object.
  *
- * **Note:** This class represents any window, whereas [LocalWindow] is
+ * **Note:** This class represents any window, whereas [Window] is
  * used to access the properties and content of the current window.
  *
  * See also:
@@ -20,7 +20,7 @@
  * * [DOM Window](https://developer.mozilla.org/en-US/docs/DOM/window) from MDN.
  * * [Window](http://www.w3.org/TR/Window/) from the W3C.
  */
-abstract class Window {
+abstract class WindowBase {
   // Fields.
 
   /**
@@ -29,8 +29,8 @@
    *     Location currentLocation = window.location;
    *     print(currentLocation.href); // 'http://www.example.com:80/'
    */
-  Location get location;
-  History get history;
+  LocationBase get location;
+  HistoryBase get history;
 
   /**
    * Indicates whether this window has been closed.
@@ -45,16 +45,16 @@
    * A reference to the window that opened this one.
    *
    *     Window thisWindow = window;
-   *     Window otherWindow = thisWindow.open('http://www.example.com/', 'foo');
+   *     WindowBase otherWindow = thisWindow.open('http://www.example.com/', 'foo');
    *     print(otherWindow.opener == thisWindow); // 'true'
    */
-  Window get opener;
+  WindowBase get opener;
 
   /**
    * A reference to the parent of this window.
    *
-   * If this [Window] has no parent, [parent] will return a reference to
-   * the [Window] itself.
+   * If this [WindowBase] has no parent, [parent] will return a reference to
+   * the [WindowBase] itself.
    *
    *     IFrameElement myIFrame = new IFrameElement();
    *     window.document.body.elements.add(myIFrame);
@@ -62,13 +62,13 @@
    *
    *     print(window.parent == window) // 'true'
    */
-  Window get parent;
+  WindowBase get parent;
 
   /**
    * A reference to the topmost window in the window hierarchy.
    *
-   * If this [Window] is the topmost [Window], [top] will return a reference to
-   * the [Window] itself.
+   * If this [WindowBase] is the topmost [WindowBase], [top] will return a
+   * reference to the [WindowBase] itself.
    *
    *     // Add an IFrame to the current window.
    *     IFrameElement myIFrame = new IFrameElement();
@@ -83,13 +83,13 @@
    *
    *     print(window.top == window) // 'true'
    */
-  Window get top;
+  WindowBase get top;
 
   // Methods.
   /**
    * Closes the window.
    *
-   * This method should only succeed if the [Window] object is
+   * This method should only succeed if the [WindowBase] object is
    * **script-closeable** and the window calling [close] is allowed to navigate
    * the window.
    *
@@ -118,11 +118,11 @@
   void postMessage(var message, String targetOrigin, [List messagePorts]);
 }
 
-abstract class Location {
+abstract class LocationBase {
   void set href(String val);
 }
 
-abstract class History {
+abstract class HistoryBase {
   void back();
   void forward();
   void go(int distance);
diff --git a/sdk/lib/html/src/CssClassSet.dart b/tools/dom/src/CssClassSet.dart
similarity index 100%
rename from sdk/lib/html/src/CssClassSet.dart
rename to tools/dom/src/CssClassSet.dart
diff --git a/sdk/lib/html/src/Device.dart b/tools/dom/src/Device.dart
similarity index 100%
rename from sdk/lib/html/src/Device.dart
rename to tools/dom/src/Device.dart
diff --git a/sdk/lib/html/src/EventListener.dart b/tools/dom/src/EventListener.dart
similarity index 100%
rename from sdk/lib/html/src/EventListener.dart
rename to tools/dom/src/EventListener.dart
diff --git a/sdk/lib/html/src/Isolates.dart b/tools/dom/src/Isolates.dart
similarity index 100%
rename from sdk/lib/html/src/Isolates.dart
rename to tools/dom/src/Isolates.dart
diff --git a/sdk/lib/html/src/KeyCode.dart b/tools/dom/src/KeyCode.dart
similarity index 100%
rename from sdk/lib/html/src/KeyCode.dart
rename to tools/dom/src/KeyCode.dart
diff --git a/sdk/lib/html/src/KeyLocation.dart b/tools/dom/src/KeyLocation.dart
similarity index 100%
rename from sdk/lib/html/src/KeyLocation.dart
rename to tools/dom/src/KeyLocation.dart
diff --git a/sdk/lib/html/src/KeyName.dart b/tools/dom/src/KeyName.dart
similarity index 100%
rename from sdk/lib/html/src/KeyName.dart
rename to tools/dom/src/KeyName.dart
diff --git a/sdk/lib/html/src/KeyboardEventController.dart b/tools/dom/src/KeyboardEventController.dart
similarity index 100%
rename from sdk/lib/html/src/KeyboardEventController.dart
rename to tools/dom/src/KeyboardEventController.dart
diff --git a/sdk/lib/html/src/Measurement.dart b/tools/dom/src/Measurement.dart
similarity index 98%
rename from sdk/lib/html/src/Measurement.dart
rename to tools/dom/src/Measurement.dart
index 7b72c93..7d34e7b 100644
--- a/sdk/lib/html/src/Measurement.dart
+++ b/tools/dom/src/Measurement.dart
@@ -16,7 +16,6 @@
 
 typedef void _MeasurementCallback();
 
-
 /**
  * This class attempts to invoke a callback as soon as the current event stack
  * unwinds, but before the browser repaints.
@@ -31,7 +30,7 @@
    * Creates the best possible measurement scheduler for the current platform.
    */
   factory _MeasurementScheduler.best(_MeasurementCallback callback) {
-    if (_isMutationObserverSupported()) {
+    if (MutationObserver.supported) {
       return new _MutationObserverScheduler(callback);
     }
     return new _PostMessageScheduler(callback);
diff --git a/sdk/lib/html/src/ReadyState.dart b/tools/dom/src/ReadyState.dart
similarity index 100%
rename from sdk/lib/html/src/ReadyState.dart
rename to tools/dom/src/ReadyState.dart
diff --git a/sdk/lib/html/src/Serialization.dart b/tools/dom/src/Serialization.dart
similarity index 100%
rename from sdk/lib/html/src/Serialization.dart
rename to tools/dom/src/Serialization.dart
diff --git a/sdk/lib/html/src/Timer.dart b/tools/dom/src/Timer.dart
similarity index 100%
rename from sdk/lib/html/src/Timer.dart
rename to tools/dom/src/Timer.dart
diff --git a/sdk/lib/html/src/_HttpRequestUtils.dart b/tools/dom/src/_HttpRequestUtils.dart
similarity index 100%
rename from sdk/lib/html/src/_HttpRequestUtils.dart
rename to tools/dom/src/_HttpRequestUtils.dart
diff --git a/sdk/lib/html/src/_ListIterators.dart b/tools/dom/src/_ListIterators.dart
similarity index 100%
rename from sdk/lib/html/src/_ListIterators.dart
rename to tools/dom/src/_ListIterators.dart
diff --git a/sdk/lib/html/src/_Testing.dart b/tools/dom/src/_Testing.dart
similarity index 100%
rename from sdk/lib/html/src/_Testing.dart
rename to tools/dom/src/_Testing.dart
diff --git a/sdk/lib/html/src/dart2js_Conversions.dart b/tools/dom/src/dart2js_Conversions.dart
similarity index 97%
rename from sdk/lib/html/src/dart2js_Conversions.dart
rename to tools/dom/src/dart2js_Conversions.dart
index a3e35cc..8b75d71 100644
--- a/sdk/lib/html/src/dart2js_Conversions.dart
+++ b/tools/dom/src/dart2js_Conversions.dart
@@ -11,7 +11,7 @@
 
 part of html;
 
-Window _convertNativeToDart_Window(win) {
+WindowBase _convertNativeToDart_Window(win) {
   return _DOMWindowCrossFrame._createSafe(win);
 }
 
diff --git a/sdk/lib/html/src/dart2js_DOMImplementation.dart b/tools/dom/src/dart2js_DOMImplementation.dart
similarity index 77%
rename from sdk/lib/html/src/dart2js_DOMImplementation.dart
rename to tools/dom/src/dart2js_DOMImplementation.dart
index 9056a14..adb5f27 100644
--- a/sdk/lib/html/src/dart2js_DOMImplementation.dart
+++ b/tools/dom/src/dart2js_DOMImplementation.dart
@@ -5,27 +5,27 @@
 part of html;
 
 // TODO(vsm): Unify with Dartium version.
-class _DOMWindowCrossFrame implements Window {
+class _DOMWindowCrossFrame implements WindowBase {
   // Private window.  Note, this is a window in another frame, so it
   // cannot be typed as "Window" as its prototype is not patched
   // properly.  Its fields and methods can only be accessed via JavaScript.
   var _window;
 
   // Fields.
-  History get history =>
-    _HistoryCrossFrame._createSafe(JS('History', '#.history', _window));
-  Location get location =>
-    _LocationCrossFrame._createSafe(JS('Location', '#.location', _window));
+  HistoryBase get history =>
+    _HistoryCrossFrame._createSafe(JS('HistoryBase', '#.history', _window));
+  LocationBase get location =>
+    _LocationCrossFrame._createSafe(JS('LocationBase', '#.location', _window));
 
   // TODO(vsm): Add frames to navigate subframes.  See 2312.
 
   bool get closed => JS('bool', '#.closed', _window);
 
-  Window get opener => _createSafe(JS('Window', '#.opener', _window));
+  WindowBase get opener => _createSafe(JS('WindowBase', '#.opener', _window));
 
-  Window get parent => _createSafe(JS('Window', '#.parent', _window));
+  WindowBase get parent => _createSafe(JS('WindowBase', '#.parent', _window));
 
-  Window get top => _createSafe(JS('Window', '#.top', _window));
+  WindowBase get top => _createSafe(JS('WindowBase', '#.top', _window));
 
   // Methods.
   void close() => JS('void', '#.close()', _window);
@@ -41,7 +41,7 @@
   // Implementation support.
   _DOMWindowCrossFrame(this._window);
 
-  static Window _createSafe(w) {
+  static WindowBase _createSafe(w) {
     if (identical(w, window)) {
       return w;
     } else {
@@ -51,7 +51,7 @@
   }
 }
 
-class _LocationCrossFrame implements Location {
+class _LocationCrossFrame implements LocationBase {
   // Private location.  Note, this is a location object in another frame, so it
   // cannot be typed as "Location" as its prototype is not patched
   // properly.  Its fields and methods can only be accessed via JavaScript.
@@ -65,7 +65,7 @@
   // Implementation support.
   _LocationCrossFrame(this._location);
 
-  static Location _createSafe(location) {
+  static LocationBase _createSafe(location) {
     if (identical(location, window.location)) {
       return location;
     } else {
@@ -75,7 +75,7 @@
   }
 }
 
-class _HistoryCrossFrame implements History {
+class _HistoryCrossFrame implements HistoryBase {
   // Private history.  Note, this is a history object in another frame, so it
   // cannot be typed as "History" as its prototype is not patched
   // properly.  Its fields and methods can only be accessed via JavaScript.
@@ -90,7 +90,7 @@
   // Implementation support.
   _HistoryCrossFrame(this._history);
 
-  static History _createSafe(h) {
+  static HistoryBase _createSafe(h) {
     if (identical(h, window.history)) {
       return h;
     } else {
diff --git a/sdk/lib/html/templates/html/dartium/dart_implementation.darttemplate b/tools/dom/src/dart2js_FactoryProviders.dart
similarity index 64%
copy from sdk/lib/html/templates/html/dartium/dart_implementation.darttemplate
copy to tools/dom/src/dart2js_FactoryProviders.dart
index 015ae9f..03edac9 100644
--- a/sdk/lib/html/templates/html/dartium/dart_implementation.darttemplate
+++ b/tools/dom/src/dart2js_FactoryProviders.dart
@@ -2,11 +2,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.
-
 part of html;
 
-/// @domName $DOMNAME
-class $CLASSNAME$EXTENDS$IMPLEMENTS {
-$!MEMBERS
+class _TextFactoryProvider {
+  static Text createText(String data) =>
+      JS('Text', 'document.createTextNode(#)', data);
 }
diff --git a/sdk/lib/html/src/dart2js_KeyEvent.dart b/tools/dom/src/dart2js_KeyEvent.dart
similarity index 97%
rename from sdk/lib/html/src/dart2js_KeyEvent.dart
rename to tools/dom/src/dart2js_KeyEvent.dart
index 83f73ff..332ce8d 100644
--- a/sdk/lib/html/src/dart2js_KeyEvent.dart
+++ b/tools/dom/src/dart2js_KeyEvent.dart
@@ -96,7 +96,7 @@
   void stopImmediatePropagation() => _parent.stopImmediatePropagation();
   void stopPropagation() => _parent.stopPropagation();
   void $dom_initUIEvent(String type, bool canBubble, bool cancelable,
-      LocalWindow view, int detail) {
+      Window view, int detail) {
     throw new UnsupportedError("Cannot initialize a UI Event from a KeyEvent.");
   }
   void $dom_initEvent(String eventTypeArg, bool canBubbleArg,
@@ -112,7 +112,7 @@
     throw new UnsupportedError("keyIdentifier is unsupported.");
   }
   void $dom_initKeyboardEvent(String type, bool canBubble, bool cancelable,
-      LocalWindow view, String keyIdentifier, int keyLocation, bool ctrlKey,
+      Window view, String keyIdentifier, int keyLocation, bool ctrlKey,
       bool altKey, bool shiftKey, bool metaKey,
       bool altGraphKey) {
     throw new UnsupportedError(
diff --git a/sdk/lib/html/src/dart2js_LocationWrapper.dart b/tools/dom/src/dart2js_LocationWrapper.dart
similarity index 97%
rename from sdk/lib/html/src/dart2js_LocationWrapper.dart
rename to tools/dom/src/dart2js_LocationWrapper.dart
index d0c9539..f430534 100644
--- a/sdk/lib/html/src/dart2js_LocationWrapper.dart
+++ b/tools/dom/src/dart2js_LocationWrapper.dart
@@ -8,7 +8,7 @@
 // It can't be monkey-patched and seems immune to putting methods on
 // Object.prototype.  We are forced to wrap the object.
 
-class _LocationWrapper implements LocalLocation {
+class _LocationWrapper implements Location {
 
   final _ptr;  // Opaque reference to real location.
 
diff --git a/sdk/lib/html/src/dart2js_TypedArrayFactoryProvider.dart b/tools/dom/src/dart2js_TypedArrayFactoryProvider.dart
similarity index 100%
rename from sdk/lib/html/src/dart2js_TypedArrayFactoryProvider.dart
rename to tools/dom/src/dart2js_TypedArrayFactoryProvider.dart
diff --git a/sdk/lib/html/src/dartium_FactoryProviders.dart b/tools/dom/src/dartium_FactoryProviders.dart
similarity index 91%
rename from sdk/lib/html/src/dartium_FactoryProviders.dart
rename to tools/dom/src/dartium_FactoryProviders.dart
index e76e7d7..ade562c 100644
--- a/sdk/lib/html/src/dartium_FactoryProviders.dart
+++ b/tools/dom/src/dartium_FactoryProviders.dart
@@ -72,16 +72,6 @@
   static ensureNative(List list) => list;  // TODO: make sure.
 }
 
-class _PointFactoryProvider {
-  static Point createPoint(num x, num y) => _createWebKitPoint(x, y);
-  static _createWebKitPoint(num x, num y) native "WebKitPoint_constructor_Callback";
-}
-
-class _WebSocketFactoryProvider {
-  static WebSocket createWebSocket(String url) => _createWebSocket(url);
-  static _createWebSocket(String url) native "WebSocket_constructor_Callback";
-}
-
 class _TextFactoryProvider {
   static Text createText(String data) => document.$dom_createTextNode(data);
 }
diff --git a/sdk/lib/html/src/dartium_KeyEvent.dart b/tools/dom/src/dartium_KeyEvent.dart
similarity index 97%
rename from sdk/lib/html/src/dartium_KeyEvent.dart
rename to tools/dom/src/dartium_KeyEvent.dart
index eeddc02..c610b8e 100644
--- a/sdk/lib/html/src/dartium_KeyEvent.dart
+++ b/tools/dom/src/dartium_KeyEvent.dart
@@ -96,7 +96,7 @@
   void stopImmediatePropagation() => _parent.stopImmediatePropagation();
   void stopPropagation() => _parent.stopPropagation();
   void $dom_initUIEvent(String type, bool canBubble, bool cancelable,
-      LocalWindow view, int detail) {
+      Window view, int detail) {
     throw new UnsupportedError("Cannot initialize a UI Event from a KeyEvent.");
   }
   void $dom_initEvent(String eventTypeArg, bool canBubbleArg,
@@ -112,7 +112,7 @@
     throw new UnsupportedError("keyIdentifier is unsupported.");
   }
   void $dom_initKeyboardEvent(String type, bool canBubble, bool cancelable,
-      LocalWindow view, String keyIdentifier, int keyLocation, bool ctrlKey,
+      Window view, String keyIdentifier, int keyLocation, bool ctrlKey,
       bool altKey, bool shiftKey, bool metaKey,
       bool altGraphKey) {
     throw new UnsupportedError(
diff --git a/sdk/lib/html/src/native_DOMImplementation.dart b/tools/dom/src/native_DOMImplementation.dart
similarity index 90%
rename from sdk/lib/html/src/native_DOMImplementation.dart
rename to tools/dom/src/native_DOMImplementation.dart
index 4b8b72a..84d9af8 100644
--- a/sdk/lib/html/src/native_DOMImplementation.dart
+++ b/tools/dom/src/native_DOMImplementation.dart
@@ -47,17 +47,18 @@
   invoke(String methodName, [List args = null]) native "NPObject_invoke";
 }
 
-class _DOMWindowCrossFrame extends NativeFieldWrapperClass1 implements Window {
+class _DOMWindowCrossFrame extends NativeFieldWrapperClass1 implements
+    WindowBase {
   _DOMWindowCrossFrame.internal();
 
   // Fields.
-  History get history native "DOMWindow_history_cross_frame_Getter";
-  Location get location native "DOMWindow_location_cross_frame_Getter";
+  HistoryBase get history native "DOMWindow_history_cross_frame_Getter";
+  LocationBase get location native "DOMWindow_location_cross_frame_Getter";
   bool get closed native "DOMWindow_closed_Getter";
   int get length native "DOMWindow_length_Getter";
-  Window get opener native "DOMWindow_opener_Getter";
-  Window get parent native "DOMWindow_parent_Getter";
-  Window get top native "DOMWindow_top_Getter";
+  WindowBase get opener native "DOMWindow_opener_Getter";
+  WindowBase get parent native "DOMWindow_parent_Getter";
+  WindowBase get top native "DOMWindow_top_Getter";
 
   // Methods.
   void close() native "DOMWindow_close_Callback";
@@ -67,7 +68,7 @@
   String get typeName => "DOMWindow";
 }
 
-class _HistoryCrossFrame extends NativeFieldWrapperClass1 implements History {
+class _HistoryCrossFrame extends NativeFieldWrapperClass1 implements HistoryBase {
   _HistoryCrossFrame.internal();
 
   // Methods.
@@ -79,7 +80,7 @@
   String get typeName => "History";
 }
 
-class _LocationCrossFrame extends NativeFieldWrapperClass1 implements Location {
+class _LocationCrossFrame extends NativeFieldWrapperClass1 implements LocationBase {
   _LocationCrossFrame.internal();
 
   // Fields.
diff --git a/sdk/lib/html/src/native_DOMPublic.dart b/tools/dom/src/native_DOMPublic.dart
similarity index 100%
rename from sdk/lib/html/src/native_DOMPublic.dart
rename to tools/dom/src/native_DOMPublic.dart
diff --git a/sdk/lib/html/src/shared_FactoryProviders.dart b/tools/dom/src/shared_FactoryProviders.dart
similarity index 100%
rename from sdk/lib/html/src/shared_FactoryProviders.dart
rename to tools/dom/src/shared_FactoryProviders.dart
diff --git a/sdk/lib/html/src/shared_SVGFactoryProviders.dart b/tools/dom/src/shared_SVGFactoryProviders.dart
similarity index 100%
rename from sdk/lib/html/src/shared_SVGFactoryProviders.dart
rename to tools/dom/src/shared_SVGFactoryProviders.dart
diff --git a/sdk/lib/html/templates/callback.darttemplate b/tools/dom/templates/callback.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/callback.darttemplate
rename to tools/dom/templates/callback.darttemplate
diff --git a/sdk/lib/html/templates/dart2js_impl.darttemplate b/tools/dom/templates/dart2js_impl.darttemplate
similarity index 84%
rename from sdk/lib/html/templates/dart2js_impl.darttemplate
rename to tools/dom/templates/dart2js_impl.darttemplate
index 5c62c0e..35ea8d4 100644
--- a/sdk/lib/html/templates/dart2js_impl.darttemplate
+++ b/tools/dom/templates/dart2js_impl.darttemplate
@@ -4,6 +4,6 @@
 
 part of $LIBRARYNAME;
 
-/// @domName $DOMNAME; @docsEditable true
+/// @domName $DOMNAME; @docsEditable true$ANNOTATIONS
 class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 $!MEMBERS}
diff --git a/tools/dom/templates/html/dart2js/factoryprovider_AudioContext.darttemplate b/tools/dom/templates/html/dart2js/factoryprovider_AudioContext.darttemplate
new file mode 100644
index 0000000..add4ae5
--- /dev/null
+++ b/tools/dom/templates/html/dart2js/factoryprovider_AudioContext.darttemplate
@@ -0,0 +1,2 @@
+  static AudioContext _create() => JS('AudioContext',
+      'new (window.AudioContext || window.webkitAudioContext)()');
diff --git a/sdk/lib/html/templates/html/dart2js/factoryprovider_Blob.darttemplate b/tools/dom/templates/html/dart2js/factoryprovider_Blob.darttemplate
similarity index 68%
rename from sdk/lib/html/templates/html/dart2js/factoryprovider_Blob.darttemplate
rename to tools/dom/templates/html/dart2js/factoryprovider_Blob.darttemplate
index 51f20d4..620d195 100644
--- a/sdk/lib/html/templates/html/dart2js/factoryprovider_Blob.darttemplate
+++ b/tools/dom/templates/html/dart2js/factoryprovider_Blob.darttemplate
@@ -1,11 +1,4 @@
-// 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;
-
-class $FACTORYPROVIDER {
-  static Blob createBlob([List blobParts = null, String type, String endings]) {
+  static Blob _create([List blobParts = null, String type, String endings]) {
     // TODO: validate that blobParts is a JS Array and convert if not.
     // TODO: any coercions on the elements of blobParts, e.g. coerce a typed
     // array to ArrayBuffer if it is a total view.
@@ -23,4 +16,3 @@
 
   static _create_bag() => JS('var', '{}');
   static _bag_set(bag, key, value) { JS('void', '#[#] = #', bag, key, value); }
-}
diff --git a/tools/dom/templates/html/dart2js/factoryprovider_MutationObserver.darttemplate b/tools/dom/templates/html/dart2js/factoryprovider_MutationObserver.darttemplate
new file mode 100644
index 0000000..88615a9
--- /dev/null
+++ b/tools/dom/templates/html/dart2js/factoryprovider_MutationObserver.darttemplate
@@ -0,0 +1,9 @@
+  static MutationObserver _create(MutationCallback callback) {
+    // Dummy statement to mark types as instantiated.
+    JS('MutationObserver|MutationRecord', '0');
+
+    return JS('MutationObserver',
+        'new(window.MutationObserver||window.WebKitMutationObserver||'
+        'window.MozMutationObserver)(#)',
+        convertDartClosureToJS(callback, 2));
+  }
diff --git a/sdk/lib/html/templates/html/dart2js/html_dart2js.darttemplate b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
similarity index 95%
rename from sdk/lib/html/templates/html/dart2js/html_dart2js.darttemplate
rename to tools/dom/templates/html/dart2js/html_dart2js.darttemplate
index da85734..c0d59d3 100644
--- a/sdk/lib/html/templates/html/dart2js/html_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
@@ -12,6 +12,7 @@
 import 'dart:indexed_db';
 import 'dart:isolate';
 import 'dart:json';
+import 'dart:math';
 // Not actually used, but imported since dart:html can generate these objects.
 import 'dart:svg' as svg;
 import 'dart:web_audio' as web_audio;
@@ -39,13 +40,12 @@
 part '$AUXILIARY_DIR/dart2js_KeyEvent.dart';
 part '$AUXILIARY_DIR/dart2js_FactoryProviders.dart';
 part '$AUXILIARY_DIR/dart2js_LocationWrapper.dart';
-part '$AUXILIARY_DIR/dart2js_MutationObserverSupported.dart';
 part '$AUXILIARY_DIR/dart2js_TypedArrayFactoryProvider.dart';
 part '$AUXILIARY_DIR/_Testing.dart';
 part '$AUXILIARY_DIR/_ListIterators.dart';
 
 
-LocalWindow get window => JS('LocalWindow', 'window');
+Window get window => JS('Window', 'window');
 
 HtmlDocument get document => JS('Document', 'document');
 
diff --git a/tools/dom/templates/html/dart2js/impl_ArrayBuffer.darttemplate b/tools/dom/templates/html/dart2js/impl_ArrayBuffer.darttemplate
new file mode 100644
index 0000000..ab440b0
--- /dev/null
+++ b/tools/dom/templates/html/dart2js/impl_ArrayBuffer.darttemplate
@@ -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.
+
+part of $LIBRARYNAME;
+
+/// @domName $DOMNAME$ANNOTATIONS
+class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
+$!MEMBERS
+  /// @domName ArrayBuffer.slice;
+  ArrayBuffer slice(int begin, [int end]) {
+    // IE10 supports ArrayBuffers but does not have the slice method.
+    if (JS('bool', '!!#.slice', this)) {
+      if (?end) {
+        return JS('ArrayBuffer', '#.slice(#, #)', this, begin, end);
+      }
+      return JS('ArrayBuffer', '#.slice(#)', this, begin);
+    } else {
+      var start = begin;
+      // Negative values go from end.
+      if (start < 0) {
+        start = this.byteLength + start;
+      }
+      var finish = ?end ? min(end, byteLength) : byteLength;
+      if (finish < 0) {
+        finish = this.byteLength + finish;
+      }
+      var length = max(finish - start, 0);
+
+      var clone = new Int8Array(length);
+      var source = new Int8Array.fromBuffer(this, start);
+      for (var i = 0; i < length; ++i) {
+        clone[i] = source[i];
+      }
+      return clone.buffer;
+    }
+  }
+}
diff --git a/sdk/lib/html/templates/html/dart2js/impl_AudioBufferSourceNode.darttemplate b/tools/dom/templates/html/dart2js/impl_AudioBufferSourceNode.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/dart2js/impl_AudioBufferSourceNode.darttemplate
rename to tools/dom/templates/html/dart2js/impl_AudioBufferSourceNode.darttemplate
diff --git a/sdk/lib/html/templates/html/dart2js/impl_Console.darttemplate b/tools/dom/templates/html/dart2js/impl_Console.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/dart2js/impl_Console.darttemplate
rename to tools/dom/templates/html/dart2js/impl_Console.darttemplate
diff --git a/sdk/lib/html/templates/html/dart2js/impl_ElementEvents.darttemplate b/tools/dom/templates/html/dart2js/impl_ElementEvents.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/dart2js/impl_ElementEvents.darttemplate
rename to tools/dom/templates/html/dart2js/impl_ElementEvents.darttemplate
diff --git a/sdk/lib/html/templates/html/dart2js/impl_HTMLTableElement.darttemplate b/tools/dom/templates/html/dart2js/impl_HTMLTableElement.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/dart2js/impl_HTMLTableElement.darttemplate
rename to tools/dom/templates/html/dart2js/impl_HTMLTableElement.darttemplate
diff --git a/tools/dom/templates/html/dart2js/impl_IDBDatabase.darttemplate b/tools/dom/templates/html/dart2js/impl_IDBDatabase.darttemplate
new file mode 100644
index 0000000..5629a9f
--- /dev/null
+++ b/tools/dom/templates/html/dart2js/impl_IDBDatabase.darttemplate
@@ -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 indexed_db;
+
+/// @domName $DOMNAME
+class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
+
+  Transaction transaction(storeName_OR_storeNames, String mode) {
+    if (mode != 'readonly' && mode != 'readwrite') {
+      throw new ArgumentError(mode);
+    }
+
+    // TODO(sra): Ensure storeName_OR_storeNames is a string or List<String>,
+    // and copy to JavaScript array if necessary.
+
+    // Try and create a transaction with a string mode.  Browsers that expect a
+    // numeric mode tend to convert the string into a number.  This fails
+    // silently, resulting in zero ('readonly').
+    return _transaction(storeName_OR_storeNames, mode);
+  }
+
+  @JSName('transaction')
+  Transaction _transaction(stores, mode) native;
+
+$!MEMBERS}
diff --git a/sdk/lib/html/templates/html/dart2js/impl_KeyboardEvent.darttemplate b/tools/dom/templates/html/dart2js/impl_KeyboardEvent.darttemplate
similarity index 91%
rename from sdk/lib/html/templates/html/dart2js/impl_KeyboardEvent.darttemplate
rename to tools/dom/templates/html/dart2js/impl_KeyboardEvent.darttemplate
index 4a555d9..d6213e4 100644
--- a/sdk/lib/html/templates/html/dart2js/impl_KeyboardEvent.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_KeyboardEvent.darttemplate
@@ -7,7 +7,7 @@
 class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 
   factory $CLASSNAME(String type, Window view,
-      [bool canBubble = true, bool cancelable = true, 
+      [bool canBubble = true, bool cancelable = true,
       String keyIdentifier = "", int keyLocation = 1, bool ctrlKey = false,
       bool altKey = false, bool shiftKey = false, bool metaKey = false,
       bool altGraphKey = false]) {
@@ -19,7 +19,7 @@
 
   /** @domName KeyboardEvent.initKeyboardEvent */
   void $dom_initKeyboardEvent(String type, bool canBubble, bool cancelable,
-      LocalWindow view, String keyIdentifier, int keyLocation, bool ctrlKey,
+      Window view, String keyIdentifier, int keyLocation, bool ctrlKey,
       bool altKey, bool shiftKey, bool metaKey, bool altGraphKey) {
     if (JS('bool', 'typeof(#.initKeyEvent) == "function"', this)) {
       // initKeyEvent is only in Firefox (instead of initKeyboardEvent). It has
@@ -27,7 +27,7 @@
       // charCode as the last two arguments, but we just set them as the default
       // since they can't be specified in other browsers.
       JS('void', '#.initKeyEvent(#, #, #, #, #, #, #, #, 0, 0)', this,
-          type, canBubble, cancelable, view, 
+          type, canBubble, cancelable, view,
           ctrlKey, altKey, shiftKey, metaKey);
     } else {
       // initKeyboardEvent is for all other browsers.
diff --git a/sdk/lib/html/templates/html/dart2js/impl_MouseEvent.darttemplate b/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/dart2js/impl_MouseEvent.darttemplate
rename to tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate
diff --git a/sdk/lib/html/templates/html/dart2js/impl_Navigator.darttemplate b/tools/dom/templates/html/dart2js/impl_Navigator.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/dart2js/impl_Navigator.darttemplate
rename to tools/dom/templates/html/dart2js/impl_Navigator.darttemplate
diff --git a/sdk/lib/html/templates/html/dart2js/impl_URL.darttemplate b/tools/dom/templates/html/dart2js/impl_URL.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/dart2js/impl_URL.darttemplate
rename to tools/dom/templates/html/dart2js/impl_URL.darttemplate
diff --git a/sdk/lib/html/templates/html/dart2js/impl_Window.darttemplate b/tools/dom/templates/html/dart2js/impl_Window.darttemplate
similarity index 87%
rename from sdk/lib/html/templates/html/dart2js/impl_Window.darttemplate
rename to tools/dom/templates/html/dart2js/impl_Window.darttemplate
index 892db5b..dbe3849 100644
--- a/sdk/lib/html/templates/html/dart2js/impl_Window.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_Window.darttemplate
@@ -9,12 +9,12 @@
 
   Document get document => JS('Document', '#.document', this);
 
-  Window _open2(url, name) => JS('Window', '#.open(#,#)', this, url, name);
+  WindowBase _open2(url, name) => JS('Window', '#.open(#,#)', this, url, name);
 
-  Window _open3(url, name, options) =>
+  WindowBase _open3(url, name, options) =>
       JS('Window', '#.open(#,#,#)', this, url, name, options);
 
-  Window open(String url, String name, [String options]) {
+  WindowBase open(String url, String name, [String options]) {
     if (options == null) {
       return _DOMWindowCrossFrame._createSafe(_open2(url, name));
     } else {
@@ -25,7 +25,7 @@
   // API level getter and setter for Location.
   // TODO: The cross domain safe wrapper can be inserted here or folded into
   // _LocationWrapper.
-  LocalLocation get location {
+  Location get location {
     // Firefox work-around for Location.  The Firefox location object cannot be
     // made to behave like a Dart object so must be wrapped.
     var result = _location;
@@ -52,8 +52,8 @@
   _LocationWrapper _location_wrapper;  // Cached wrapped Location object.
 
   // Native getter and setter to access raw Location object.
-  Location get _location => JS('Location', '#.location', this);
-  void set _location(Location value) {
+  dynamic get _location => JS('Location|=Object', '#.location', this);
+  void set _location(value) {
     JS('void', '#.location = #', this, value);
   }
   // Prevent compiled from thinking 'location' property is available for a Dart
@@ -123,6 +123,16 @@
        this);
   }
 
+  /**
+   * Gets an instance of the Indexed DB factory to being using Indexed DB.
+   *
+   * Use [IdbFactory.supported] to check if Indexed DB is supported on the
+   * current platform.
+   */
+  @SupportedBrowser(SupportedBrowser.CHROME, '23.0')
+  @SupportedBrowser(SupportedBrowser.FIREFOX, '15.0')
+  @SupportedBrowser(SupportedBrowser.IE, '10.0')
+  @Experimental()
   IdbFactory get indexedDB =>
       JS('IdbFactory',
          '#.indexedDB || #.webkitIndexedDB || #.mozIndexedDB',
@@ -146,7 +156,7 @@
     var serialized = _serialize(port);
     document.documentElement.attributes['dart-port:$name'] = JSON.stringify(serialized);
   }
-  
+
   /// @domName Window.console; @docsEditable true
   Console get console => Console.safeConsole;
 
diff --git a/tools/dom/templates/html/dart2js/impl_WorkerContext.darttemplate b/tools/dom/templates/html/dart2js/impl_WorkerContext.darttemplate
new file mode 100644
index 0000000..62b1693
--- /dev/null
+++ b/tools/dom/templates/html/dart2js/impl_WorkerContext.darttemplate
@@ -0,0 +1,25 @@
+// 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;
+
+/// @domName $DOMNAME
+class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
+$!MEMBERS
+
+  /**
+   * Gets an instance of the Indexed DB factory to being using Indexed DB.
+   *
+   * Use [IdbFactory.supported] to check if Indexed DB is supported on the
+   * current platform.
+   */
+  @SupportedBrowser(SupportedBrowser.CHROME, '23.0')
+  @SupportedBrowser(SupportedBrowser.FIREFOX, '15.0')
+  @SupportedBrowser(SupportedBrowser.IE, '10.0')
+  @Experimental()
+  IdbFactory get indexedDB =>
+      JS('IdbFactory',
+         '#.indexedDB || #.webkitIndexedDB || #.mozIndexedDB',
+         this, this, this);
+}
diff --git a/sdk/lib/html/templates/html/dart2js/indexed_db_dart2js.darttemplate b/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/dart2js/indexed_db_dart2js.darttemplate
rename to tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate
diff --git a/sdk/lib/html/templates/html/dart2js/svg_dart2js.darttemplate b/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/dart2js/svg_dart2js.darttemplate
rename to tools/dom/templates/html/dart2js/svg_dart2js.darttemplate
diff --git a/sdk/lib/html/templates/html/dart2js/web_audio_dart2js.darttemplate b/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/dart2js/web_audio_dart2js.darttemplate
rename to tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate
diff --git a/sdk/lib/html/templates/html/dartium/cpp_callback_header.template b/tools/dom/templates/html/dartium/cpp_callback_header.template
similarity index 100%
rename from sdk/lib/html/templates/html/dartium/cpp_callback_header.template
rename to tools/dom/templates/html/dartium/cpp_callback_header.template
diff --git a/sdk/lib/html/templates/html/dartium/cpp_callback_implementation.template b/tools/dom/templates/html/dartium/cpp_callback_implementation.template
similarity index 100%
rename from sdk/lib/html/templates/html/dartium/cpp_callback_implementation.template
rename to tools/dom/templates/html/dartium/cpp_callback_implementation.template
diff --git a/sdk/lib/html/templates/html/dartium/cpp_derived_sources.template b/tools/dom/templates/html/dartium/cpp_derived_sources.template
similarity index 100%
rename from sdk/lib/html/templates/html/dartium/cpp_derived_sources.template
rename to tools/dom/templates/html/dartium/cpp_derived_sources.template
diff --git a/sdk/lib/html/templates/html/dartium/cpp_header.template b/tools/dom/templates/html/dartium/cpp_header.template
similarity index 100%
rename from sdk/lib/html/templates/html/dartium/cpp_header.template
rename to tools/dom/templates/html/dartium/cpp_header.template
diff --git a/sdk/lib/html/templates/html/dartium/cpp_implementation.template b/tools/dom/templates/html/dartium/cpp_implementation.template
similarity index 100%
rename from sdk/lib/html/templates/html/dartium/cpp_implementation.template
rename to tools/dom/templates/html/dartium/cpp_implementation.template
diff --git a/sdk/lib/html/templates/html/dartium/cpp_resolver.template b/tools/dom/templates/html/dartium/cpp_resolver.template
similarity index 100%
rename from sdk/lib/html/templates/html/dartium/cpp_resolver.template
rename to tools/dom/templates/html/dartium/cpp_resolver.template
diff --git a/sdk/lib/html/templates/html/dartium/dart_implementation.darttemplate b/tools/dom/templates/html/dartium/dart_implementation.darttemplate
similarity index 84%
rename from sdk/lib/html/templates/html/dartium/dart_implementation.darttemplate
rename to tools/dom/templates/html/dartium/dart_implementation.darttemplate
index 015ae9f..8377e83 100644
--- a/sdk/lib/html/templates/html/dartium/dart_implementation.darttemplate
+++ b/tools/dom/templates/html/dartium/dart_implementation.darttemplate
@@ -4,9 +4,9 @@
 
 // WARNING: Do not edit - generated code.
 
-part of html;
+part of $LIBRARYNAME;
 
-/// @domName $DOMNAME
+/// @domName $DOMNAME$ANNOTATIONS
 class $CLASSNAME$EXTENDS$IMPLEMENTS {
 $!MEMBERS
 }
diff --git a/sdk/lib/html/templates/html/dartium/html_dartium.darttemplate b/tools/dom/templates/html/dartium/html_dartium.darttemplate
similarity index 95%
rename from sdk/lib/html/templates/html/dartium/html_dartium.darttemplate
rename to tools/dom/templates/html/dartium/html_dartium.darttemplate
index 894e023..2d1d6cf 100644
--- a/sdk/lib/html/templates/html/dartium/html_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/html_dartium.darttemplate
@@ -37,16 +37,15 @@
 part '$AUXILIARY_DIR/Isolates.dart';
 part '$AUXILIARY_DIR/Measurement.dart';
 part '$AUXILIARY_DIR/Serialization.dart';
-part '$AUXILIARY_DIR/dartium_MutationObserverSupported.dart';
 part '$AUXILIARY_DIR/_Testing.dart';
 part '$AUXILIARY_DIR/_ListIterators.dart';
 
 part '$AUXILIARY_DIR/native_DOMPublic.dart';
 part '$AUXILIARY_DIR/native_DOMImplementation.dart';
 
-LocalWindow _window;
+Window _window;
 
-LocalWindow get window {
+Window get window {
   if (_window != null) {
     return _window;
   }
diff --git a/sdk/lib/html/templates/html/dartium/impl_KeyboardEvent.darttemplate b/tools/dom/templates/html/dartium/impl_KeyboardEvent.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/dartium/impl_KeyboardEvent.darttemplate
rename to tools/dom/templates/html/dartium/impl_KeyboardEvent.darttemplate
diff --git a/sdk/lib/html/templates/html/dartium/impl_MouseEvent.darttemplate b/tools/dom/templates/html/dartium/impl_MouseEvent.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/dartium/impl_MouseEvent.darttemplate
rename to tools/dom/templates/html/dartium/impl_MouseEvent.darttemplate
diff --git a/sdk/lib/html/templates/html/dartium/impl_Window.darttemplate b/tools/dom/templates/html/dartium/impl_Window.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/dartium/impl_Window.darttemplate
rename to tools/dom/templates/html/dartium/impl_Window.darttemplate
diff --git a/sdk/lib/html/templates/html/dartium/indexed_db_dartium.darttemplate b/tools/dom/templates/html/dartium/indexed_db_dartium.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/dartium/indexed_db_dartium.darttemplate
rename to tools/dom/templates/html/dartium/indexed_db_dartium.darttemplate
diff --git a/sdk/lib/html/templates/html/dartium/svg_dartium.darttemplate b/tools/dom/templates/html/dartium/svg_dartium.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/dartium/svg_dartium.darttemplate
rename to tools/dom/templates/html/dartium/svg_dartium.darttemplate
diff --git a/sdk/lib/html/templates/html/dartium/web_audio_dartium.darttemplate b/tools/dom/templates/html/dartium/web_audio_dartium.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/dartium/web_audio_dartium.darttemplate
rename to tools/dom/templates/html/dartium/web_audio_dartium.darttemplate
diff --git a/sdk/lib/html/templates/html/impl/factoryprovider_Elements.darttemplate b/tools/dom/templates/html/impl/factoryprovider_Elements.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/impl/factoryprovider_Elements.darttemplate
rename to tools/dom/templates/html/impl/factoryprovider_Elements.darttemplate
diff --git a/sdk/lib/html/templates/html/impl/impl_AudioContext.darttemplate b/tools/dom/templates/html/impl/impl_AudioContext.darttemplate
similarity index 76%
rename from sdk/lib/html/templates/html/impl/impl_AudioContext.darttemplate
rename to tools/dom/templates/html/impl/impl_AudioContext.darttemplate
index 0b872b4..47b17e7 100644
--- a/sdk/lib/html/templates/html/impl/impl_AudioContext.darttemplate
+++ b/tools/dom/templates/html/impl/impl_AudioContext.darttemplate
@@ -6,18 +6,6 @@
 
 /// @domName $DOMNAME
 class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
-$if DART2JS
-  factory AudioContext() => JS('AudioContext',
-      'new (window.AudioContext || window.webkitAudioContext)()');
-$else
-  factory AudioContext() => _createAudioContext();
-
-  static _createAudioContext([int numberOfChannels,
-                              int numberOfFrames,
-                              int sampleRate])
-      native "AudioContext_constructor_Callback";
-$endif
-
 $!MEMBERS
 $if DART2JS
   GainNode createGain() {
diff --git a/sdk/lib/html/templates/html/impl/impl_CSSStyleDeclaration.darttemplate b/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
rename to tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
diff --git a/sdk/lib/html/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate b/tools/dom/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate
rename to tools/dom/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate
diff --git a/sdk/lib/html/templates/html/impl/impl_CustomEvent.darttemplate b/tools/dom/templates/html/impl/impl_CustomEvent.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/impl/impl_CustomEvent.darttemplate
rename to tools/dom/templates/html/impl/impl_CustomEvent.darttemplate
diff --git a/sdk/lib/html/templates/html/impl/impl_Document.darttemplate b/tools/dom/templates/html/impl/impl_Document.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/impl/impl_Document.darttemplate
rename to tools/dom/templates/html/impl/impl_Document.darttemplate
diff --git a/sdk/lib/html/templates/html/impl/impl_DocumentFragment.darttemplate b/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/impl/impl_DocumentFragment.darttemplate
rename to tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate
diff --git a/sdk/lib/html/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
similarity index 95%
rename from sdk/lib/html/templates/html/impl/impl_Element.darttemplate
rename to tools/dom/templates/html/impl/impl_Element.darttemplate
index fc2bcfb..1ef1b73 100644
--- a/sdk/lib/html/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -385,6 +385,10 @@
    *
    * For standard elements it is more preferable to use the type constructors:
    *     var element = new DivElement();
+   *
+   * See also:
+   *
+   * * [isTagSupported]
    */
   factory $CLASSNAME.tag(String tag) =>
       _$(CLASSNAME)FactoryProvider.createElement_tag(tag);
@@ -598,6 +602,16 @@
     this.insertAdjacentHtml('beforeend', text);
   }
 
+  /**
+   * Checks to see if the tag name is supported by the current platform.
+   *
+   * The tag should be a valid HTML tag name.
+   */
+  static bool isTagSupported(String tag) {
+    var e = _ElementFactoryProvider.createElement_tag(tag);
+    return e is Element && !(e is UnknownElement);
+  }
+
   // Hooks to support custom WebComponents.
   /**
    * Experimental support for [web components][wc]. This field stores a
@@ -614,25 +628,6 @@
 $endif
   var xtag;
 
-$if DARTIUM
-  noSuchMethod(InvocationMirror invocation) {
-    if (dynamicUnknownElementDispatcher == null) {
-      throw new NoSuchMethodError(this, invocation.memberName,
-                                        invocation.positionalArguments,
-                                        invocation.namedArguments);
-    } else {
-      String hackedName = invocation.memberName;
-      if (invocation.isGetter) hackedName = "get:$hackedName";
-      if (invocation.isSetter) hackedName = "set:$hackedName";
-      return dynamicUnknownElementDispatcher(this,
-                                             hackedName,
-                                             invocation.positionalArguments);
-    }
-  }
-$else
-  // TODO(vsm): Implement noSuchMethod or similar for dart2js.
-$endif
-
 $if DART2JS
   /**
    * Creates a text node and inserts it into the DOM at the specified location.
@@ -735,9 +730,6 @@
 $!MEMBERS
 }
 
-// Temporary dispatch hook to support WebComponents.
-Function dynamicUnknownElementDispatcher;
-
 final _START_TAG_REGEXP = new RegExp('<(\\w+)');
 class _ElementFactoryProvider {
   static final _CUSTOM_PARENT_TAG_MAP = const {
@@ -794,7 +786,7 @@
 $if DART2JS
   // Optimization to improve performance until the dart2js compiler inlines this
   // method.
-  static Element createElement_tag(String tag) =>
+  static dynamic createElement_tag(String tag) =>
       JS('Element', 'document.createElement(#)', tag);
 $else
   static Element createElement_tag(String tag) =>
diff --git a/sdk/lib/html/templates/html/impl/impl_Event.darttemplate b/tools/dom/templates/html/impl/impl_Event.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/impl/impl_Event.darttemplate
rename to tools/dom/templates/html/impl/impl_Event.darttemplate
diff --git a/sdk/lib/html/templates/html/impl/impl_EventTarget.darttemplate b/tools/dom/templates/html/impl/impl_EventTarget.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/impl/impl_EventTarget.darttemplate
rename to tools/dom/templates/html/impl/impl_EventTarget.darttemplate
diff --git a/sdk/lib/html/templates/html/impl/impl_HTMLCanvasElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/impl/impl_HTMLCanvasElement.darttemplate
rename to tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate
diff --git a/sdk/lib/html/templates/html/impl/impl_HTMLDocument.darttemplate b/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/impl/impl_HTMLDocument.darttemplate
rename to tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
diff --git a/sdk/lib/html/templates/html/impl/impl_HTMLInputElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLInputElement.darttemplate
similarity index 72%
rename from sdk/lib/html/templates/html/impl/impl_HTMLInputElement.darttemplate
rename to tools/dom/templates/html/impl/impl_HTMLInputElement.darttemplate
index a4c4e9a..45da9bc 100644
--- a/sdk/lib/html/templates/html/impl/impl_HTMLInputElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLInputElement.darttemplate
@@ -29,6 +29,18 @@
     ResetButtonInputElement,
     ButtonInputElement
     $NATIVESPEC {
+
+  ///@docsEditable true
+  factory InputElement({String type}) {
+    var e = document.$dom_createElement("input");
+    if (type != null) {
+      try {
+        // IE throws an exception for unknown types.
+        e.type = type;
+      } catch(_) {}
+    }
+    return e;
+  }
 $!MEMBERS
 }
 
@@ -130,7 +142,13 @@
 /**
  * Similar to [TextInputElement], but on platforms where search is styled
  * differently this will get the search style.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 abstract class SearchInputElement implements TextInputElementBase {
   factory SearchInputElement() => new InputElement(type: 'search');
 
@@ -139,6 +157,11 @@
 
   /// @domName HTMLInputElement.list;
   Element get list;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'search')).type == 'search';
+  }
 }
 
 /**
@@ -156,12 +179,23 @@
 
 /**
  * A control for editing an absolute URL.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 abstract class UrlInputElement implements TextInputElementBase {
   factory UrlInputElement() => new InputElement(type: 'url');
 
   /// @domName HTMLInputElement.list;
   Element get list;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'url')).type == 'url';
+  }
 }
 
 /**
@@ -169,17 +203,34 @@
  *
  * This provides a single line of text with minimal formatting help since
  * there is a wide variety of telephone numbers.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 abstract class TelephoneInputElement implements TextInputElementBase {
   factory TelephoneInputElement() => new InputElement(type: 'tel');
 
   /// @domName HTMLInputElement.list;
   Element get list;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'tel')).type == 'tel';
+  }
 }
 
 /**
  * An e-mail address or list of e-mail addresses.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 abstract class EmailInputElement implements TextInputElementBase {
   factory EmailInputElement() => new InputElement(type: 'email');
 
@@ -212,6 +263,11 @@
 
   /// @domName HTMLInputElement.size
   int size;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'email')).type == 'email';
+  }
 }
 
 /**
@@ -251,7 +307,11 @@
 /**
  * A date and time (year, month, day, hour, minute, second, fraction of a
  * second) with the time zone set to UTC.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Experimental()
 abstract class DateTimeInputElement implements RangeInputElementBase {
   factory DateTimeInputElement() => new InputElement(type: 'datetime');
 
@@ -263,11 +323,20 @@
 
   /// @domName HTMLInputElement.required
   bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'datetime')).type == 'datetime';
+  }
 }
 
 /**
  * A date (year, month, day) with no time zone.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Experimental()
 abstract class DateInputElement implements RangeInputElementBase {
   factory DateInputElement() => new InputElement(type: 'date');
 
@@ -279,11 +348,20 @@
 
   /// @domName HTMLInputElement.required
   bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'date')).type == 'date';
+  }
 }
 
 /**
  * A date consisting of a year and a month with no time zone.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Experimental()
 abstract class MonthInputElement implements RangeInputElementBase {
   factory MonthInputElement() => new InputElement(type: 'month');
 
@@ -295,11 +373,20 @@
 
   /// @domName HTMLInputElement.required
   bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'month')).type == 'month';
+  }
 }
 
 /**
  * A date consisting of a week-year number and a week number with no time zone.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Experimental()
 abstract class WeekInputElement implements RangeInputElementBase {
   factory WeekInputElement() => new InputElement(type: 'week');
 
@@ -311,11 +398,20 @@
 
   /// @domName HTMLInputElement.required
   bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'week')).type == 'week';
+  }
 }
 
 /**
  * A time (hour, minute, seconds, fractional seconds) with no time zone.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@Experimental()
 abstract class TimeInputElement implements RangeInputElementBase {
   factory TimeInputElement() => new InputElement(type: 'time');
 
@@ -327,12 +423,21 @@
 
   /// @domName HTMLInputElement.required
   bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'time')).type == 'time';
+  }
 }
 
 /**
  * A date and time (year, month, day, hour, minute, second, fraction of a
  * second) with no time zone.
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Experimental()
 abstract class LocalDateTimeInputElement implements RangeInputElementBase {
   factory LocalDateTimeInputElement() =>
       new InputElement(type: 'datetime-local');
@@ -342,11 +447,20 @@
 
   /// @domName HTMLInputElement.required
   bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'datetime-local')).type == 'datetime-local';
+  }
 }
 
 /**
  * A numeric editor control.
  */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.IE)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental()
 abstract class NumberInputElement implements RangeInputElementBase {
   factory NumberInputElement() => new InputElement(type: 'number');
 
@@ -358,14 +472,29 @@
 
   /// @domName HTMLInputElement.required
   bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'number')).type == 'number';
+  }
 }
 
 /**
  * Similar to [NumberInputElement] but the browser may provide more optimal
  * styling (such as a slider control).
+ *
+ * Use [supported] to check if this is supported on the current platform.
  */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@Experimental()
 abstract class RangeInputElement implements RangeInputElementBase {
   factory RangeInputElement() => new InputElement(type: 'range');
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'range')).type == 'range';
+  }
 }
 
 /**
diff --git a/sdk/lib/html/templates/html/dart2js/impl_HTMLSelectElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLSelectElement.darttemplate
similarity index 91%
rename from sdk/lib/html/templates/html/dart2js/impl_HTMLSelectElement.darttemplate
rename to tools/dom/templates/html/impl/impl_HTMLSelectElement.darttemplate
index f424a19..ad44ea6 100644
--- a/sdk/lib/html/templates/html/dart2js/impl_HTMLSelectElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLSelectElement.darttemplate
@@ -11,7 +11,7 @@
   // Override default options, since IE returns SelectElement itself and it
   // does not operate as a List.
   List<OptionElement> get options {
-    return this.elements.filter((e) => e is OptionElement);
+    return this.children.filter((e) => e is OptionElement);
   }
 
   List<OptionElement> get selectedOptions {
diff --git a/tools/dom/templates/html/impl/impl_History.darttemplate b/tools/dom/templates/html/impl/impl_History.darttemplate
new file mode 100644
index 0000000..943d831
--- /dev/null
+++ b/tools/dom/templates/html/impl/impl_History.darttemplate
@@ -0,0 +1,24 @@
+// 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;
+
+/// @domName $DOMNAME; @docsEditable true$ANNOTATIONS
+class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
+
+  /**
+   * Checks if the State APIs are supported on the current platform.
+   *
+   * See also:
+   *
+   * * [pushState]
+   * * [replaceState]
+   * * [state]
+   */
+$if DART2JS
+  static bool get supportsState => JS('bool', '!!window.history.pushState');
+$else
+  static bool get supportsState => true;
+$endif
+$!MEMBERS}
diff --git a/tools/dom/templates/html/impl/impl_IDBFactory.darttemplate b/tools/dom/templates/html/impl/impl_IDBFactory.darttemplate
new file mode 100644
index 0000000..ce1b889
--- /dev/null
+++ b/tools/dom/templates/html/impl/impl_IDBFactory.darttemplate
@@ -0,0 +1,24 @@
+// 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;
+
+/// @domName $DOMNAME$ANNOTATIONS
+class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
+  /**
+   * Checks to see if Indexed DB is supported on the current platform.
+   */
+  static bool get supported {
+$if DARTIUM
+    return true;
+$else
+    return JS('bool',
+        '!!(window.indexedDB || '
+        'window.webkitIndexedDB || '
+        'window.mozIndexedDB)');
+$endif
+  }
+
+$!MEMBERS
+}
diff --git a/sdk/lib/html/templates/html/impl/impl_IDBKeyRange.darttemplate b/tools/dom/templates/html/impl/impl_IDBKeyRange.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/impl/impl_IDBKeyRange.darttemplate
rename to tools/dom/templates/html/impl/impl_IDBKeyRange.darttemplate
diff --git a/sdk/lib/html/templates/html/impl/impl_MutationObserver.darttemplate b/tools/dom/templates/html/impl/impl_MutationObserver.darttemplate
similarity index 85%
rename from sdk/lib/html/templates/html/impl/impl_MutationObserver.darttemplate
rename to tools/dom/templates/html/impl/impl_MutationObserver.darttemplate
index dda5aee..e989a5e 100644
--- a/sdk/lib/html/templates/html/impl/impl_MutationObserver.darttemplate
+++ b/tools/dom/templates/html/impl/impl_MutationObserver.darttemplate
@@ -5,8 +5,25 @@
 part of html;
 
 /// @domName $DOMNAME
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental()
 class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 $!MEMBERS
+  /**
+   * Checks to see if the mutation observer API is supported on the current
+   * platform.
+   */
+  static bool get supported {
+$if DARTIUM
+    return true;
+$else
+    return JS('bool',
+        '!!(window.MutationObserver || window.WebKitMutationObserver)');
+$endif
+  }
+
   void observe(Node target,
                {Map options,
                 bool childList,
diff --git a/sdk/lib/html/templates/html/impl/impl_Node.darttemplate b/tools/dom/templates/html/impl/impl_Node.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/impl/impl_Node.darttemplate
rename to tools/dom/templates/html/impl/impl_Node.darttemplate
diff --git a/sdk/lib/html/templates/html/impl/impl_Range.darttemplate b/tools/dom/templates/html/impl/impl_Range.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/impl/impl_Range.darttemplate
rename to tools/dom/templates/html/impl/impl_Range.darttemplate
diff --git a/sdk/lib/html/templates/html/impl/impl_SVGElement.darttemplate b/tools/dom/templates/html/impl/impl_SVGElement.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/impl/impl_SVGElement.darttemplate
rename to tools/dom/templates/html/impl/impl_SVGElement.darttemplate
diff --git a/sdk/lib/html/templates/html/impl/impl_SVGSVGElement.darttemplate b/tools/dom/templates/html/impl/impl_SVGSVGElement.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/impl/impl_SVGSVGElement.darttemplate
rename to tools/dom/templates/html/impl/impl_SVGSVGElement.darttemplate
diff --git a/sdk/lib/html/templates/html/impl/impl_ShadowRoot.darttemplate b/tools/dom/templates/html/impl/impl_ShadowRoot.darttemplate
similarity index 82%
rename from sdk/lib/html/templates/html/impl/impl_ShadowRoot.darttemplate
rename to tools/dom/templates/html/impl/impl_ShadowRoot.darttemplate
index 9f0649b..2f87efe 100644
--- a/sdk/lib/html/templates/html/impl/impl_ShadowRoot.darttemplate
+++ b/tools/dom/templates/html/impl/impl_ShadowRoot.darttemplate
@@ -6,12 +6,12 @@
 
 part of html;
 
-/// @domName $DOMNAME
+/// @domName $DOMNAME$ANNOTATIONS
 class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 $!MEMBERS
 $if DART2JS
   static bool get supported =>
-      JS('bool', '!!(window.ShadowRoot || window.WebKitShadowRoot)');
+      JS('bool', '!!(Element.prototype.webkitCreateShadowRoot)');
 $else
   static bool get supported => _Utils.shadowRootSupported(window.document);
 $endif
diff --git a/sdk/lib/html/templates/html/impl/impl_Storage.darttemplate b/tools/dom/templates/html/impl/impl_Storage.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/impl/impl_Storage.darttemplate
rename to tools/dom/templates/html/impl/impl_Storage.darttemplate
diff --git a/sdk/lib/html/templates/html/impl/impl_Text.darttemplate b/tools/dom/templates/html/impl/impl_Text.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/impl/impl_Text.darttemplate
rename to tools/dom/templates/html/impl/impl_Text.darttemplate
diff --git a/sdk/lib/html/templates/html/impl/impl_UIEvent.darttemplate b/tools/dom/templates/html/impl/impl_UIEvent.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/impl/impl_UIEvent.darttemplate
rename to tools/dom/templates/html/impl/impl_UIEvent.darttemplate
diff --git a/sdk/lib/html/templates/html/impl/impl_WheelEvent.darttemplate b/tools/dom/templates/html/impl/impl_WheelEvent.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/impl/impl_WheelEvent.darttemplate
rename to tools/dom/templates/html/impl/impl_WheelEvent.darttemplate
diff --git a/sdk/lib/html/templates/html/impl/impl_XMLHttpRequest.darttemplate b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
similarity index 71%
rename from sdk/lib/html/templates/html/impl/impl_XMLHttpRequest.darttemplate
rename to tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
index a2b4be2..ea113b6 100644
--- a/sdk/lib/html/templates/html/impl/impl_XMLHttpRequest.darttemplate
+++ b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
@@ -38,22 +38,29 @@
    * [onComplete] callback.
    */
   factory $CLASSNAME.get(String url, onComplete($CLASSNAME request)) =>
-      _$(CLASSNAME)FactoryProvider.create$(CLASSNAME)_get(url, onComplete);
+      _HttpRequestUtils.get(url, onComplete, false);
 
+  // 80 char issue for comments in lists: dartbug.com/7588.
   /**
    * Creates a URL GET request for the specified `url` with
    * credentials such a cookie (already) set in the header or
-   * (authorization headers)[http://tools.ietf.org/html/rfc1945#section-10.2].
+   * [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2).
    * 
    * After completing the request, the object will call the user-provided 
    * [onComplete] callback.
+   *
+   * A few other details to keep in mind when using credentials:
+   *
+   * * Using credentials is only useful for cross-origin requests.
+   * * The `Access-Control-Allow-Origin` header of `url` cannot contain a wildcard (*).
+   * * The `Access-Control-Allow-Credentials` header of `url` must be set to true.
+   * * If `Access-Control-Expose-Headers` has not been set to true, only a subset of all the response headers will be returned when calling [getAllRequestHeaders].
    * 
-   * See also: (authorization headers)[http://en.wikipedia.org/wiki/Basic_access_authentication].
+   * See also: [authorization headers](http://en.wikipedia.org/wiki/Basic_access_authentication).
    */
   factory $CLASSNAME.getWithCredentials(String url,
       onComplete($CLASSNAME request)) =>
-      _$(CLASSNAME)FactoryProvider.create$(CLASSNAME)_getWithCredentials(url,
-      onComplete);
+      _HttpRequestUtils.get(url, onComplete, true);
 
 $!MEMBERS
 }
diff --git a/sdk/lib/html/templates/html/impl/pure_interface.darttemplate b/tools/dom/templates/html/impl/pure_interface.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/html/impl/pure_interface.darttemplate
rename to tools/dom/templates/html/impl/pure_interface.darttemplate
diff --git a/sdk/lib/html/templates/immutable_list_mixin.darttemplate b/tools/dom/templates/immutable_list_mixin.darttemplate
similarity index 100%
rename from sdk/lib/html/templates/immutable_list_mixin.darttemplate
rename to tools/dom/templates/immutable_list_mixin.darttemplate
diff --git a/tools/get_archive.py b/tools/get_archive.py
index 8585703..e919267 100755
--- a/tools/get_archive.py
+++ b/tools/get_archive.py
@@ -200,12 +200,15 @@
   def FindPermanentUrl(out, osname, not_used):
     rev_num = revision_num
     if not rev_num:
-      temp_file = tempfile.NamedTemporaryFile()
+      temp_file = tempfile.NamedTemporaryFile(delete=False)
+      temp_file.close()
       temp_file_url = 'file://' + temp_file.name
       Gsutil('cp', latest_pattern % {'osname' : osname }, temp_file_url)
+      temp_file = open(temp_file.name)
       temp_file.seek(0)
       version_info = temp_file.read()
       temp_file.close()
+      os.unlink(temp_file.name)
       if version_info != '':
         rev_num = json.loads(version_info)['revision']
       else:
diff --git a/tools/line_doc_comments.dart b/tools/line_doc_comments.dart
new file mode 100755
index 0000000..aa7627c
--- /dev/null
+++ b/tools/line_doc_comments.dart
@@ -0,0 +1,87 @@
+#!/usr/bin/env dart
+
+/// Converts block-style Doc comments in Dart code to line style.
+library line_doc_comments;
+import 'dart:io';
+
+import '../pkg/path/lib/path.dart' as path;
+
+final oneLineBlock = new RegExp(r'^(\s*)/\*\*\s?(.*)\*/\s*$');
+final startBlock = new RegExp(r'^(\s*)/\*\*(.*)$');
+final blockLine = new RegExp(r'^\s*\*\s?(.*)$');
+final endBlock = new RegExp(r'^\s*\*/\s*$');
+
+main() {
+  var args = new Options().arguments;
+  if (args.length != 1) {
+    print('Converts "/**"-style block doc comments in a directory ');
+    print('containing Dart code to "///"-style line doc comments.');
+    print('');
+    print('Usage: line_doc_coments.dart <dir>');
+    return;
+  }
+
+  var dir = new Directory(args[0]);
+  var lister = dir.list(recursive: true);
+  lister.onFile = (file) {
+    if (path.extension(file) != '.dart') return;
+    fixFile(file);
+  };
+}
+
+void fixFile(String path) {
+  var file = new File(path);
+  file.readAsLines().transform(fixContents).chain((fixed) {
+    return new File(path).writeAsString(fixed);
+  }).then((file) {
+    print(file.name);
+  });
+}
+
+String fixContents(List<String> lines) {
+  var buffer = new StringBuffer();
+  var inBlock = false;
+  var indent;
+  for (var line in lines) {
+    if (inBlock) {
+      // See if it's the end of the comment.
+      if (endBlock.hasMatch(line)) {
+        inBlock = false;
+
+        // Just a pointless line, delete it!
+        line = null;
+      } else {
+        var match = blockLine.firstMatch(line);
+        line = '$indent/// ${match[1]}';
+      }
+    } else {
+      // See if it's a one-line block comment like: /** Blah. */
+      var match = oneLineBlock.firstMatch(line);
+      if (match != null) {
+        if (match[2] != '') {
+          line = '${match[1]}/// ${match[2]}';
+        } else {
+          line = '${match[1]}///';
+        }
+      } else {
+        // See if it's the start of a block doc comment.
+        match = startBlock.firstMatch(line);
+        if (match != null) {
+          inBlock = true;
+          indent = match[1];
+          if (match[2] != '') {
+            // Got comment on /** line.
+            line = match[2];
+          } else {
+            // Just a pointless line, delete it!
+            line = null;
+          }
+        }
+      }
+    }
+
+    if (line != null) buffer.add('$line\n');
+  }
+
+  return buffer.toString();
+}
diff --git a/tools/publish_pkg.py b/tools/publish_pkg.py
index 82e07df..9e2fa0a 100755
--- a/tools/publish_pkg.py
+++ b/tools/publish_pkg.py
@@ -4,7 +4,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.
 #
-# Script to push a package to pub. 
+# Script to push a package to pub.
 #
 # Usage: publish_pkg.py pkg_dir
 #
@@ -31,13 +31,12 @@
     dest.write(contents)
     dest.close()
 
-
 def ReadVersion(file, field):
   for line in open(file).read().split('\n'):
     [k, v] = re.split('\s+', line)
     if field == k:
       return int(v)
-  
+
 def Main(argv):
   HOME = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
 
@@ -46,7 +45,7 @@
   minor = ReadVersion(versionFile, 'MINOR')
   build = ReadVersion(versionFile, 'BUILD')
   patch = ReadVersion(versionFile, 'PATCH')
-  
+
   # bleeding_edge has a fixed version number of 0.1.x.y . Don't allow users
   # to publish packages from bleeding_edge.
   if major == 0 and minor <= 1:
@@ -63,12 +62,14 @@
 
   pubspec = os.path.join(tmpDir, pkgName, 'pubspec.yaml')
 
+  replaceInFiles = []
+
   if os.path.exists(os.path.join(HOME, argv[1], 'pubspec.yaml')):
     #
     # If pubspec.yaml exists, add the SDK's version number if
     # no version number is present.
     #
-    shutil.copytree(os.path.join(HOME, argv[1]), 
+    shutil.copytree(os.path.join(HOME, argv[1]),
                     os.path.join(tmpDir, pkgName))
     with open(pubspec) as pubspecFile:
       lines = pubspecFile.readlines()
@@ -100,7 +101,7 @@
     # Otherwise, move the package's contents to lib/.
     #
     if os.path.exists(os.path.join(HOME, argv[1], 'lib')):
-      shutil.copytree(os.path.join(HOME, argv[1]), 
+      shutil.copytree(os.path.join(HOME, argv[1]),
                       os.path.join(tmpDir, pkgName))
     else:
       os.makedirs(os.path.join(tmpDir, pkgName))
@@ -110,6 +111,8 @@
     # Create pubspec.yaml .
     with open(pubspec, 'w') as pubspecFile:
       pubspecFile.write('name: ' + pkgName + '_unsupported\n')
+      pubspecFile.write('author: None\n')
+      pubspecFile.write('homepage: http://None\n')
       pubspecFile.write('version: ' + version + '\n')
       pubspecFile.write("description: >\n")
       pubspecFile.write('  A completely unsupported clone of Dart SDK library\n')
@@ -117,13 +120,57 @@
       pubspecFile.write('  unpredictable/incompatible ways without warning.\n')
       pubspecFile.write('dependencies:\n')
 
+    libpath = os.path.join(HOME, argv[1], '../libraries.dart')
+    if os.path.exists(libpath):
+      # Copy libraries.dart into the package source code
+      shutil.copy(libpath, os.path.join(tmpDir, pkgName, 'lib/libraries.dart'))
+
+      # Replace '../../libraries.dart' with '../libraries.dart'
+      replaceInFiles.append(
+        (r'(import|part)(\s+)(\'|")\.\./(\.\./)*libraries.dart',
+         r'\1\2\3\4libraries.dart'))
+
+  if not os.path.exists(os.path.join(tmpDir, pkgName, 'LICENSE')):
+    with open(os.path.join(tmpDir, pkgName, 'LICENSE'), 'w') as licenseFile:
+      licenseFile.write('''
+Copyright 2012, the Dart project authors. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Google Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+''');
+
+  replaceInFiles.append(
+    (r'(import|part)(\s+)(\'|")(\.\./)+pkg/', r'\1\2\3package:'))
+
   # Replace '../*/pkg' imports and parts.
   for root, dirs, files in os.walk(os.path.join(tmpDir, pkgName)):
+    # TODO(dgrove): Remove this when dartbug.com/7487 is fixed.
+    if '.svn' in dirs:
+      shutil.rmtree(os.path.join(root, '.svn'))
     for name in files:
       if name.endswith('.dart'):
-        ReplaceInFiles([os.path.join(root, name)], 
-            [(r'(import|part)(\s+)(\'|")(\.\./)+pkg/', r'\1\2\3package:')])
-  
+        ReplaceInFiles([os.path.join(root, name)], replaceInFiles)
+
   print 'publishing version ' + version + ' of ' + argv[1] + ' to pub.\n'
   subprocess.call(['pub', 'publish'], cwd=os.path.join(tmpDir, pkgName))
   shutil.rmtree(tmpDir)
diff --git a/tools/test.dart b/tools/test.dart
index 1fa5b0f..8d7388c 100755
--- a/tools/test.dart
+++ b/tools/test.dart
@@ -22,19 +22,19 @@
  *
  */
 
-#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/test_progress.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/test_progress.dart";
+import "testing/dart/http_server.dart";
 
-#import("../compiler/tests/dartc/test_config.dart");
-#import("../runtime/tests/vm/test_config.dart");
-#import("../samples/tests/dartc/test_config.dart");
-#import("../tests/co19/test_config.dart");
+import "../compiler/tests/dartc/test_config.dart";
+import "../runtime/tests/vm/test_config.dart";
+import "../samples/tests/dartc/test_config.dart";
+import "../tests/co19/test_config.dart";
 
 /**
  * The directories that contain test suites which follow the conventions
diff --git a/tools/testing/dart/browser_test.dart b/tools/testing/dart/browser_test.dart
index ec6d9a8..b47bbf8 100644
--- a/tools/testing/dart/browser_test.dart
+++ b/tools/testing/dart/browser_test.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 test_suite;
+
 String getHtmlContents(String title,
                        Path controllerScript,
                        Path dartJsScript,
@@ -23,7 +25,8 @@
 <body>
   <h1> Running $title </h1>
   <script type="text/javascript" src="$controllerScript"></script>
-  <script type="$scriptType" src="$sourceScript"></script>
+  <script type="$scriptType" src="$sourceScript" onerror="externalError(null)">
+  </script>
   <script type="text/javascript" src="$dartJsScript"></script>
 </body>
 </html>
@@ -51,12 +54,24 @@
 part '$test';
 """;
 
-String dartTestWrapper(Path dartHome, Path library) =>
-"""
+String dartTestWrapper(Path dartHome, Path library) {
+  // Tests inside "pkg" import unittest using "package:". All others use a
+  // relative path. The imports need to agree, so use a matching form here.
+  var unitTest = dartHome.append("pkg/unittest/lib").toString();
+
+  // TODO(rnystrom): Looking in the entire path here is wrong. It should only
+  // consider the relative path within dartHome. Unfortunately,
+  // Path.relativeTo() does not handle cases where library is already a relative
+  // path, and Path.isAbsolute does not work on Windows.
+  if (library.segments().contains("pkg")) {
+    unitTest = 'package:unittest';
+  }
+
+  return """
 library test;
 
-import '${dartHome.append('pkg/unittest/lib/unittest.dart')}' as unittest;
-import '${dartHome.append('pkg/unittest/lib/html_config.dart')}' as config;
+import '$unitTest/unittest.dart' as unittest;
+import '$unitTest/html_config.dart' as config;
 import '${library}' as Test;
 
 main() {
@@ -64,4 +79,4 @@
   unittest.group('', Test.main);
 }
 """;
-
+}
diff --git a/tools/testing/dart/co19_test.dart b/tools/testing/dart/co19_test.dart
index 9c6de09..4de996c 100644
--- a/tools/testing/dart/co19_test.dart
+++ b/tools/testing/dart/co19_test.dart
@@ -14,15 +14,15 @@
  * [: ./tools/testing/bin/$OS/dart tools/testing/dart/co19_test.dart :]
  */
 
-#library("co19_test");
+library co19_test;
 
-#import("dart:io");
-#import("test_runner.dart");
-#import("test_options.dart");
-#import("test_suite.dart");
-#import("test_progress.dart");
+import "dart:io";
+import "test_runner.dart";
+import "test_options.dart";
+import "test_suite.dart";
+import "test_progress.dart";
 
-#import("../../../tests/co19/test_config.dart");
+import "../../../tests/co19/test_config.dart";
 
 const List<String> COMMON_ARGUMENTS = const <String>['--report'];
 
diff --git a/tools/testing/dart/drt_updater.dart b/tools/testing/dart/drt_updater.dart
index c048263..e6645df 100644
--- a/tools/testing/dart/drt_updater.dart
+++ b/tools/testing/dart/drt_updater.dart
@@ -2,11 +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("drt_updater");
+library drt_updater;
 
-#import("dart:io");
+import "dart:io";
 
-#import("test_suite.dart");
+import "test_suite.dart";
 
 class _DartiumUpdater {
   String name;
diff --git a/tools/testing/dart/http_server.dart b/tools/testing/dart/http_server.dart
index ad542d7..8d233a8 100644
--- a/tools/testing/dart/http_server.dart
+++ b/tools/testing/dart/http_server.dart
@@ -2,11 +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('http_server');
+library http_server;
 
-#import('dart:io');
-#import('dart:isolate');
-#import('test_suite.dart');  // For TestUtils.
+import 'dart:io';
+import 'dart:isolate';
+import 'test_suite.dart';  // For TestUtils.
 
 HttpServer _httpServer;
 
@@ -42,6 +42,13 @@
     }
   };
 
+  // Echos back the contents of the request as the response data.
+  _httpServer.addRequestHandler((req) => req.path == "/echo", (request, resp) {
+    resp.headers.set("Access-Control-Allow-Origin", "*");
+
+    request.inputStream.pipe(resp.outputStream);
+  });
+
   _httpServer.listen(host, port);
 }
 
diff --git a/tools/testing/dart/multitest.dart b/tools/testing/dart/multitest.dart
index 10ad84a..ca62175 100644
--- a/tools/testing/dart/multitest.dart
+++ b/tools/testing/dart/multitest.dart
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#library("multitest");
+library multitest;
 
-#import("dart:io");
-#import("test_suite.dart");
+import "dart:io";
+import "test_suite.dart";
 
 // Multitests are Dart test scripts containing lines of the form
 // " [some dart code] /// [key]: [error type]"
diff --git a/tools/testing/dart/scrub_status_file.dart b/tools/testing/dart/scrub_status_file.dart
index 2afd4cf..4aced43 100644
--- a/tools/testing/dart/scrub_status_file.dart
+++ b/tools/testing/dart/scrub_status_file.dart
@@ -11,9 +11,9 @@
 
 // TODO(ahe): Consider generalizing this.
 
-#import('dart:io');
+import 'dart:io';
 
-#import('status_file_parser.dart');
+import 'status_file_parser.dart';
 
 const List<String> CO19_STATUS_FILES = const <String>[
     'tests/co19/co19-compiler.status',
diff --git a/tools/testing/dart/status_expression.dart b/tools/testing/dart/status_expression.dart
index f5191fb..a5e919a 100644
--- a/tools/testing/dart/status_expression.dart
+++ b/tools/testing/dart/status_expression.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#library("status_expression");
+library status_expression;
 
 /**
  * Parse and evaluate expressions in a .status file for Dart and V8.
diff --git a/tools/testing/dart/status_file_parser.dart b/tools/testing/dart/status_file_parser.dart
index 5d3cee6..d314581 100644
--- a/tools/testing/dart/status_file_parser.dart
+++ b/tools/testing/dart/status_file_parser.dart
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#library("status_file_parser");
+library status_file_parser;
 
-#import("dart:io");
-#import("status_expression.dart");
+import "dart:io";
+import "status_expression.dart";
 
 /** Possible outcomes of running a test. */
 const CRASH = "crash";
diff --git a/tools/testing/dart/test_options.dart b/tools/testing/dart/test_options.dart
index fc9adac..8f9232b 100644
--- a/tools/testing/dart/test_options.dart
+++ b/tools/testing/dart/test_options.dart
@@ -2,12 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#library("test_options_parser");
+library test_options_parser;
 
-#import("dart:io");
-#import("dart:math");
-#import("drt_updater.dart");
-#import("test_suite.dart");
+import "dart:io";
+import "dart:math";
+import "drt_updater.dart";
+import "test_suite.dart";
 
 List<String> defaultTestSelectors =
     const ['dartc', 'samples', 'standalone', 'corelib', 'co19', 'language',
diff --git a/tools/testing/dart/test_progress.dart b/tools/testing/dart/test_progress.dart
index 33e0765..203edbd 100644
--- a/tools/testing/dart/test_progress.dart
+++ b/tools/testing/dart/test_progress.dart
@@ -2,12 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#library("test_progress");
+library test_progress;
 
-#import("dart:io");
-#import("test_runner.dart");
-#import("test_suite.dart");
-#import("status_file_parser.dart");
+import "dart:io";
+import "test_runner.dart";
+import "test_suite.dart";
+import "status_file_parser.dart";
 
 class ProgressIndicator {
   ProgressIndicator(this._startTime, this._printTiming)
@@ -53,6 +53,10 @@
       }
       _appendToFlakyFile(buf.toString());
     }
+    for (var commandOutput in test.commandOutputs.values) {
+      if (commandOutput.compilationSkipped)
+        _skippedCompilations++;
+    }
 
     if (test.lastCommandOutput.unexpectedOutput) {
       _failedTests++;
@@ -71,6 +75,13 @@
     _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
@@ -93,6 +104,7 @@
   void allDone() {
     _printFailureSummary();
     _printStatus();
+    _printSkippedCompilationInfo();
     _printTimingInformation();
     stdout.close();
     stderr.close();
@@ -136,7 +148,7 @@
     }
     _failureSummary.addAll(failureOutput);
   }
-  
+
   List<String> _buildFailureOutput(TestCase test) {
     List<String> output = new List<String>();
     output.add('');
@@ -171,16 +183,17 @@
     if (!test.lastCommandOutput.stdout.isEmpty) {
       output.add('');
       output.add('stdout:');
-      for (var s in test.lastCommandOutput.stdout) {
-        output.add(s);
+      if (test.lastCommandOutput.command.isPixelTest) {
+        output.add('DRT pixel test failed! stdout is not printed because it '
+                   'contains binary data!');
+      } else {
+        output.add(new String.fromCharCodes(test.lastCommandOutput.stdout));
       }
     }
     if (!test.lastCommandOutput.stderr.isEmpty) {
       output.add('');
       output.add('stderr:');
-      for (var s in test.lastCommandOutput.stderr) {
-        output.add(s);
-      }
+      output.add(new String.fromCharCodes(test.lastCommandOutput.stderr));
     }
     for (Command c in test.commands) {
       output.add('');
@@ -225,6 +238,7 @@
   int _foundTests = 0;
   int _passedTests = 0;
   int _failedTests = 0;
+  int _skippedCompilations = 0;
   bool _allTestsKnown = false;
   Date _startTime;
   bool _printTiming;
@@ -252,6 +266,7 @@
   void allDone() {
     stdout.write('\n'.charCodes);
     _printFailureSummary();
+    _printSkippedCompilationInfo();
     _printTimingInformation();
     if (_failedTests > 0) {
       // We may have printed many failure logs, so reprint the summary data.
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index 4c7498d..3ccc3ee 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -9,13 +9,14 @@
  * - Managing parallel execution of tests, including timeout checks.
  * - Evaluating the output of each test as pass/fail/crash/timeout.
  */
-#library("test_runner");
+library test_runner;
 
-#import("dart:io");
-#import("dart:isolate");
-#import("status_file_parser.dart");
-#import("test_progress.dart");
-#import("test_suite.dart");
+import "dart:io";
+import "dart:isolate";
+import "dart:uri";
+import "status_file_parser.dart";
+import "test_progress.dart";
+import "test_suite.dart";
 
 const int NO_TIMEOUT = 0;
 const int SLOW_TIMEOUT_MULTIPLIER = 4;
@@ -24,6 +25,55 @@
 typedef void ExitCodeEvent(int exitCode);
 typedef void EnqueueMoreWork(ProcessQueue queue);
 
+
+/**
+ * [areByteArraysEqual] compares a range of bytes from [buffer1] with a
+ * range of bytes from [buffer2].
+ *
+ * Returns [true] if the [count] bytes in [buffer1] (starting at
+ * [offset1]) match the [count] bytes in [buffer2] (starting at
+ * [offset2]).
+ * Otherwise [false] is returned.
+ */
+bool areByteArraysEqual(List<int> buffer1, int offset1,
+                        List<int> buffer2, int offset2,
+                        int count) {
+  if ((offset1 + count) > buffer1.length ||
+      (offset2 + count) > buffer2.length) {
+    return false;
+  }
+
+  for (var i = 0; i < count; i++) {
+    if (buffer1[offset1 + i] != buffer2[offset2 + i]) {
+      return false;
+    }
+  }
+  return true;
+}
+
+/**
+ * [findBytes] searches for [pattern] in [data] beginning at [startPos].
+ *
+ * Returns [true] if [pattern] was found in [data].
+ * Otherwise [false] is returned.
+ */
+int findBytes(List<int> data, List<int> pattern, [int startPos=0]) {
+  // TODO(kustermann): Use one of the fast string-matching algorithms!
+  for (int i=startPos; i < (data.length-pattern.length); i++) {
+    bool found = true;
+    for (int j=0; j<pattern.length; j++) {
+      if (data[i+j] != pattern[j]) {
+        found = false;
+      }
+    }
+    if (found) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+
 /** A command executed as a step in a test case. */
 class Command {
   /** Path to the executable of this command. */
@@ -32,10 +82,13 @@
   /** Command line arguments to the executable. */
   List<String> arguments;
 
+  /** Environment for the command */
+  Map<String,String> environment;
+
   /** The actual command line that will be executed. */
   String commandLine;
 
-  Command(this.executable, this.arguments) {
+  Command(this.executable, this.arguments, [this.environment = null]) {
     if (Platform.operatingSystem == 'windows') {
       // Windows can't handle the first command if it is a .bat file or the like
       // with the slashes going the other direction.
@@ -46,8 +99,115 @@
   }
 
   String toString() => commandLine;
+
+  Future<bool> get outputIsUpToDate => new Future.immediate(false);
+  Path get expectedOutputFile => null;
+  bool get isPixelTest => false;
 }
 
+class CompilationCommand extends Command {
+  String _outputFile;
+  bool _neverSkipCompilation;
+  List<Uri> _bootstrapDependencies;
+
+  CompilationCommand(this._outputFile,
+                     this._neverSkipCompilation,
+                     this._bootstrapDependencies,
+                     String executable,
+                     List<String> arguments)
+      : super(executable, arguments);
+
+  Future<bool> get outputIsUpToDate {
+    if (_neverSkipCompilation) return new Future.immediate(false);
+
+    Future<List<Uri>> readDepsFile(String path) {
+      var file = new File(new Path(path).toNativePath());
+      if (!file.existsSync()) {
+        return new Future.immediate(null);
+      }
+      return file.readAsLines().transform((List<String> lines) {
+        var dependencies = new List<Uri>();
+        for (var line in lines) {
+          line = line.trim();
+          if (line.length > 0) {
+            dependencies.add(new Uri(line));
+          }
+        }
+        return dependencies;
+      });
+    }
+
+    return readDepsFile("$_outputFile.deps").transform((dependencies) {
+      if (dependencies != null) {
+        dependencies.addAll(_bootstrapDependencies);
+        var jsOutputLastModified = TestUtils.lastModifiedCache.getLastModified(
+            new Uri.fromComponents(scheme: 'file', path: _outputFile));
+        if (jsOutputLastModified != null) {
+          for (var dependency in dependencies) {
+            var dependencyLastModified =
+                TestUtils.lastModifiedCache.getLastModified(dependency);
+            if (dependencyLastModified == null ||
+                dependencyLastModified > jsOutputLastModified) {
+              return false;
+            }
+          }
+          return true;
+        }
+      }
+      return false;
+    });
+  }
+}
+
+class DumpRenderTreeCommand extends Command {
+  /**
+   * If [expectedOutputPath] is set, the output of DumpRenderTree is compared
+   * with the content of [expectedOutputPath].
+   * This is used for example for pixel tests, where [expectedOutputPath] points
+   * to a *png file.
+   */
+  Path expectedOutputPath;
+
+  DumpRenderTreeCommand(String executable,
+                        String htmlFile,
+                        List<String> options,
+                        List<String> dartFlags,
+                        Uri packageRootUri,
+                        Path this.expectedOutputPath)
+      : super(executable,
+              _getArguments(options, htmlFile),
+              _getEnvironment(dartFlags, packageRootUri));
+
+  static Map _getEnvironment(List<String> dartFlags, Uri packageRootUri) {
+    var needDartFlags = dartFlags != null && dartFlags.length > 0;
+    var needDartPackageRoot = packageRootUri != null;
+
+    var env = null;
+    if (needDartFlags || needDartPackageRoot) {
+      env = new Map.from(Platform.environment);
+      if (needDartFlags) {
+        env['DART_FLAGS'] = Strings.join(dartFlags, " ");
+      }
+      if (needDartPackageRoot) {
+        env['DART_PACKAGE_ROOT'] = packageRootUri.toString();
+      }
+    }
+
+    return env;
+  }
+
+  static List<String> _getArguments(List<String> options, String htmlFile) {
+    var arguments = new List.from(options);
+    arguments.add(htmlFile);
+    return arguments;
+  }
+
+  Path get expectedOutputFile => expectedOutputPath;
+  bool get isPixelTest => (expectedOutputFile != null &&
+                           expectedOutputFile.filename.endsWith(".png"));
+}
+
+
 /**
  * TestCase contains all the information needed to run a test and evaluate
  * its output.  Running a test involves starting a separate process, with
@@ -67,7 +227,7 @@
  */
 class TestCase {
   /**
-   * A list of commands to execute. Most test cases have a single command. 
+   * A list of commands to execute. Most test cases have a single command.
    * Dart2js tests have two commands, one to compile the source and another
    * to execute it. Some isolate tests might even have three, if they require
    * compiling multiple sources that are run in isolation.
@@ -209,7 +369,7 @@
    * first).
    */
   bool waitingForOtherTest;
-  
+
   /**
    * The set of test cases that wish to be notified when this test has
    * completed.
@@ -249,7 +409,7 @@
 
 
 /**
- * CommandOutput records the output of a completed command: the process's exit 
+ * CommandOutput records the output of a completed command: the process's exit
  * code, the standard output and standard error, whether the process timed out,
  * and the time the process took to run.  It also contains a pointer to the
  * [TestCase] this is the output of.
@@ -260,19 +420,23 @@
                                  int exitCode,
                                  bool incomplete,
                                  bool timedOut,
-                                 List<String> stdout,
-                                 List<String> stderr,
-                                 Duration time) {
-    return new CommandOutputImpl.fromCase(testCase, 
+                                 List<int> stdout,
+                                 List<int> stderr,
+                                 Duration time,
+                                 bool compilationSkipped) {
+    return new CommandOutputImpl.fromCase(testCase,
                                           command,
                                           exitCode,
                                           incomplete,
                                           timedOut,
                                           stdout,
                                           stderr,
-                                          time);
+                                          time,
+                                          compilationSkipped);
   }
 
+  Command get command;
+
   bool get incomplete;
 
   String get result;
@@ -291,14 +455,17 @@
 
   int get exitCode;
 
-  List<String> get stdout;
+  List<int> get stdout;
 
-  List<String> get stderr;
+  List<int> get stderr;
 
   List<String> get diagnostics;
+
+  bool get compilationSkipped;
 }
 
 class CommandOutputImpl implements CommandOutput {
+  Command command;
   TestCase testCase;
   int exitCode;
 
@@ -307,10 +474,11 @@
 
   bool timedOut;
   bool failed = false;
-  List<String> stdout;
-  List<String> stderr;
+  List<int> stdout;
+  List<int> stderr;
   Duration time;
   List<String> diagnostics;
+  bool compilationSkipped;
 
   /**
    * A flag to indicate we have already printed a warning about ignoring the VM
@@ -327,13 +495,14 @@
   // Don't call this constructor, call CommandOutput.fromCase() to
   // get a new TestOutput instance.
   CommandOutputImpl(TestCase this.testCase,
-                    Command command,
+                    Command this.command,
                     int this.exitCode,
                     bool this.incomplete,
                     bool this.timedOut,
-                    List<String> this.stdout,
-                    List<String> this.stderr,
-                    Duration this.time) {
+                    List<int> this.stdout,
+                    List<int> this.stderr,
+                    Duration this.time,
+                    bool this.compilationSkipped) {
     testCase.commandOutputs[command] = this;
     diagnostics = [];
   }
@@ -342,18 +511,20 @@
                                      int exitCode,
                                      bool incomplete,
                                      bool timedOut,
-                                     List<String> stdout,
-                                     List<String> stderr,
-                                     Duration time) {
+                                     List<int> stdout,
+                                     List<int> stderr,
+                                     Duration time,
+                                     bool compilationSkipped) {
     if (testCase is BrowserTestCase) {
       return new BrowserCommandOutputImpl(testCase,
                                           command,
-                                          exitCode, 
+                                          exitCode,
                                           incomplete,
                                           timedOut,
                                           stdout,
                                           stderr,
-                                          time);
+                                          time,
+                                          compilationSkipped);
     } else if (testCase.configuration['compiler'] == 'dartc') {
       return new AnalysisCommandOutputImpl(testCase,
                                            command,
@@ -361,16 +532,18 @@
                                            timedOut,
                                            stdout,
                                            stderr,
-                                           time);
+                                           time,
+                                           compilationSkipped);
     }
     return new CommandOutputImpl(testCase,
                                  command,
                                  exitCode,
-                                 incomplete, 
+                                 incomplete,
                                  timedOut,
                                  stdout,
                                  stderr,
-                                 time);
+                                 time,
+                                 compilationSkipped);
   }
 
   String get result =>
@@ -419,7 +592,8 @@
       timedOut,
       stdout,
       stderr,
-      time) :
+      time,
+      compilationSkipped) :
     super(testCase,
           command,
           exitCode,
@@ -427,38 +601,121 @@
           timedOut,
           stdout,
           stderr,
-          time);
+          time,
+          compilationSkipped);
 
   bool get didFail {
+    if (_failedBecauseOfMissingXDisplay) {
+      return true;
+    }
+
+    if (command.expectedOutputFile != null) {
+      // We are either doing a pixel test or a layout test with DumpRenderTree
+      return _failedBecauseOfUnexpectedDRTOutput;
+    }
+    return _browserTestFailure;
+  }
+
+  bool get _failedBecauseOfMissingXDisplay {
     // Browser case:
     // If the browser test failed, it may have been because DumpRenderTree
     // and the virtual framebuffer X server didn't hook up, or DRT crashed with
     // a core dump. Sometimes DRT crashes after it has set the stdout to PASS,
     // so we have to do this check first.
-    for (String line in super.stderr) {
-      if (line.contains('Gtk-WARNING **: cannot open display: :99') ||
-        line.contains('Failed to run command. return code=1')) {
+    var stderrLines = new String.fromCharCodes(super.stderr).split("\n");
+    for (String line in stderrLines) {
+      // TODO(kustermann,ricow): Issue: 7564
+      // This seems to happen quite frequently, we need to figure out why.
+      if (line.contains('Gtk-WARNING **: cannot open display') ||
+          line.contains('Failed to run command. return code=1')) {
         // If we get the X server error, or DRT crashes with a core dump, retry
         // the test.
         if ((testCase as BrowserTestCase).numRetries > 0) {
           requestRetry = true;
         }
+        print("Warning: Test failure because of missing XDisplay");
         return true;
       }
     }
+    return false;
+  }
 
+  bool get _failedBecauseOfUnexpectedDRTOutput {
+    /*
+     * The output of DumpRenderTree is different for pixel tests than for
+     * layout tests.
+     *
+     * On a pixel test, the DRT output has the following format
+     *     ......
+     *     ......
+     *     Content-Length: ...\n
+     *     <*png data>
+     *     #EOF\n
+     * So we need to get the byte-range of the png data first, before
+     * comparing it with the content of the expected output file.
+     *
+     * On a layout tests, the DRT output is directly compared with the
+     * content of the expected output.
+     */
+    var stdout = testCase.commandOutputs[command].stdout;
+    var file = new File.fromPath(command.expectedOutputFile);
+    if (file.existsSync()) {
+      var bytesContentLength = "Content-Length:".charCodes;
+      var bytesNewLine = "\n".charCodes;
+      var bytesEOF = "#EOF\n".charCodes;
+
+      var expectedContent = file.readAsBytesSync();
+      if (command.isPixelTest) {
+        var startOfContentLength = findBytes(stdout, bytesContentLength);
+        if (startOfContentLength >= 0) {
+          var newLineAfterContentLength = findBytes(stdout,
+                                                    bytesNewLine,
+                                                    startOfContentLength);
+          if (newLineAfterContentLength > 0) {
+            var startPosition = newLineAfterContentLength +
+                bytesNewLine.length;
+            var endPosition = stdout.length - bytesEOF.length;
+
+            return !areByteArraysEqual(expectedContent,
+                                       0,
+                                       stdout,
+                                       startPosition,
+                                       endPosition - startPosition);
+          }
+        }
+        return true;
+      } else {
+        return !areByteArraysEqual(expectedContent, 0,
+                                   stdout, 0,
+                                   stdout.length);
+      }
+    }
+    return true;
+  }
+
+  bool get _browserTestFailure {
     // Browser tests fail unless stdout contains
     // 'Content-Type: text/plain' followed by 'PASS'.
     bool has_content_type = false;
-    for (String line in super.stdout) {
+    var stdoutLines = new String.fromCharCodes(super.stdout).split("\n");
+    for (String line in stdoutLines) {
       switch (line) {
         case 'Content-Type: text/plain':
           has_content_type = true;
           break;
-
         case 'PASS':
           if (has_content_type) {
-            return (exitCode != 0 && !hasCrashed);
+            if (exitCode != 0) {
+              print("Warning: All tests passed, but exitCode != 0 "
+                    "(${testCase.displayName})");
+            }
+            if (testCase.configuration['runtime'] == 'drt') {
+              // TODO(kustermann/ricow): Issue: 7563
+              // We should eventually get rid of this hack.
+              return false;
+            } else {
+              return (exitCode != 0 && !hasCrashed);
+            }
           }
           break;
       }
@@ -479,14 +736,24 @@
 
   bool alreadyComputed = false;
   bool failResult;
+
   AnalysisCommandOutputImpl(testCase,
                             command,
                             exitCode,
                             timedOut,
-                            stdout, 
+                            stdout,
                             stderr,
-                            time) :
-    super(testCase, command, exitCode, false, timedOut, stdout, stderr, time);
+                            time,
+                            compilationSkipped) :
+    super(testCase,
+          command,
+          exitCode,
+          false,
+          timedOut,
+          stdout,
+          stderr,
+          time,
+          compilationSkipped);
 
   bool get didFail {
     if (!alreadyComputed) {
@@ -503,7 +770,8 @@
     List<String> staticWarnings = [];
 
     // Read the returned list of errors and stuff them away.
-    for (String line in super.stderr) {
+    var stderrLines = new String.fromCharCodes(super.stderr).split("\n");
+    for (String line in stderrLines) {
       if (line.length == 0) continue;
       List<String> fields = splitMachineError(line);
       if (fields[ERROR_LEVEL] == 'ERROR') {
@@ -652,8 +920,10 @@
   bool timedOut = false;
   Date startTime;
   Timer timeoutTimer;
-  List<String> stdout;
-  List<String> stderr;
+  List<int> stdout;
+  List<int> stderr;
+  List<String> notifications;
+  bool compilationSkipped;
   bool allowRetries;
 
   /** Which command of [testCase.commands] is currently being executed. */
@@ -663,16 +933,34 @@
       [this.allowRetries = false, this.processQueue]);
 
   /**
-   * Called when all commands are executed. 
+   * Called when all commands are executed.
    */
   void testComplete(CommandOutput lastCommandOutput) {
-    timeoutTimer.cancel();
+    var command = lastCommandOutput.command;
+
+    if (timeoutTimer != null) {
+      timeoutTimer.cancel();
+    }
     if (lastCommandOutput.unexpectedOutput
         && testCase.configuration['verbose'] != null
         && testCase.configuration['verbose']) {
       print(testCase.displayName);
-      for (var line in lastCommandOutput.stderr) print(line);
-      for (var line in lastCommandOutput.stdout) print(line);
+
+      print(new String.fromCharCodes(lastCommandOutput.stderr));
+      if (!lastCommandOutput.command.isPixelTest) {
+        print(new String.fromCharCodes(lastCommandOutput.stdout));
+      } else {
+        print("DRT pixel test failed! stdout is not printed because it "
+              "contains binary data!");
+      }
+      print('');
+      if (notifications.length > 0) {
+        print("Notifications:");
+        for (var line in notifications) {
+          print(notifications);
+        }
+        print('');
+      }
     }
     if (allowRetries && testCase.usesWebDriver
         && lastCommandOutput.unexpectedOutput
@@ -714,21 +1002,23 @@
       testComplete(createCommandOutput(command, exitCode, false));
     } else if (exitCode != 0) {
       // One of the steps failed.
-      stderr.add('test.dart: Compilation failed$suffix, exit code $exitCode\n');
+      notifications.add('test.dart: Compilation failed$suffix, '
+                        'exit code $exitCode\n');
       testComplete(createCommandOutput(command, exitCode, true));
     } else {
       createCommandOutput(command, exitCode, true);
       // One compilation step successfully completed, move on to the
       // next step.
-      stderr.add('test.dart: Compilation finished $suffix\n');
-      stdout.add('test.dart: Compilation finished $suffix\n');
+      notifications.add('test.dart: Compilation finished $suffix\n\n');
       if (currentStep == totalSteps - 1 && testCase.usesWebDriver &&
           !testCase.configuration['noBatch']) {
         // Note: processQueue will always be non-null for runtime == ie9, ie10,
         // ff, safari, chrome, opera. (It is only null for runtime == vm)
         // This RunningProcess object is done, and hands over control to
         // BatchRunner.startTest(), which handles reporting, etc.
-        timeoutTimer.cancel();
+        if (timeoutTimer != null) {
+          timeoutTimer.cancel();
+        }
         processQueue._getBatchRunner(testCase).startTest(testCase);
       } else {
         runCommand(testCase.commands[currentStep++], commandComplete);
@@ -750,27 +1040,32 @@
         timedOut,
         stdout,
         stderr,
-        new Date.now().difference(startTime));
+        new Date.now().difference(startTime),
+        compilationSkipped);
     resetLocalOutputInformation();
     return commandOutput;
   }
 
   void resetLocalOutputInformation() {
-    stdout = new List<String>();
-    stderr = new List<String>();
+    stdout = new List<int>();
+    stderr = new List<int>();
+    notifications = new List<String>();
+    compilationSkipped = false;
   }
-  
-  VoidFunction makeReadHandler(StringInputStream source,
-                               List<String> destination) {
-    void handler () {
-      if (source.closed) return;  // TODO(whesse): Remove when bug is fixed.
-      var line = source.readLine();
-      while (null != line) {
-        destination.add(line);
-        line = source.readLine();
+
+  void drainStream(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();
       }
     }
-    return handler;
+    source.onData = onDataHandler;
+    source.onClosed = onDataHandler;
   }
 
   void start() {
@@ -785,36 +1080,50 @@
     void processExitHandler(int returnCode) {
       commandCompleteHandler(command, returnCode);
     }
-    ProcessOptions options = new ProcessOptions();
-    options.environment = new Map<String, String>.from(Platform.environment);
-    options.environment['DART_CONFIGURATION'] =
-        TestUtils.configurationDir(testCase.configuration);
-    Future processFuture = Process.start(command.executable,
-                                         command.arguments,
-                                         options);
-    processFuture.then((Process p) {
-      process = p;
-      process.onExit = processExitHandler;
-      var stdoutStringStream = new StringInputStream(process.stdout);
-      var stderrStringStream = new StringInputStream(process.stderr);
-      stdoutStringStream.onLine =
-          makeReadHandler(stdoutStringStream, stdout);
-      stderrStringStream.onLine =
-          makeReadHandler(stderrStringStream, stderr);
-      if (timeoutTimer == null) {
-        // Create one timeout timer when starting test case, remove it at end.
-        timeoutTimer = new Timer(1000 * testCase.timeout, timeoutHandler);
+
+    command.outputIsUpToDate.then((bool isUpToDate) {
+      if (isUpToDate) {
+        notifications.add("Skipped compilation because the old output is "
+                          "still up to date!");
+        compilationSkipped = true;
+        commandComplete(command, 0);
+      } else {
+        ProcessOptions options = new ProcessOptions();
+        if (command.environment != null) {
+          options.environment =
+              new Map<String, String>.from(command.environment);
+        } else {
+          options.environment =
+              new Map<String, String>.from(Platform.environment);
+        }
+
+        options.environment['DART_CONFIGURATION'] =
+            TestUtils.configurationDir(testCase.configuration);
+        Future processFuture = Process.start(command.executable,
+                                             command.arguments,
+                                             options);
+        processFuture.then((Process p) {
+          process = p;
+          process.onExit = processExitHandler;
+          drainStream(process.stdout, stdout);
+          drainStream(process.stderr, stderr);
+          if (timeoutTimer == null) {
+            // Create one timeout timer when starting test case, remove it at
+            // the end.
+            timeoutTimer = new Timer(1000 * testCase.timeout, timeoutHandler);
+          }
+          // If the timeout fired in between two commands, kill the just
+          // started process immediately.
+          if (timedOut) safeKill(process);
+        });
+        processFuture.handleException((e) {
+          print("Process error:");
+          print("  Command: $command");
+          print("  Error: $e");
+          testComplete(createCommandOutput(command, -1, false));
+          return true;
+        });
       }
-      // If the timeout fired in between two commands, kill the just
-      // started process immediately.
-      if (timedOut) safeKill(process);
-    });
-    processFuture.handleException((e) {
-      print("Process error:");
-      print("  Command: $command");
-      print("  Error: $e");
-      testComplete(createCommandOutput(command, -1, false));
-      return true;
     });
   }
 
@@ -853,8 +1162,8 @@
   StringInputStream _stderrStream;
 
   TestCase _currentTest;
-  List<String> _testStdout;
-  List<String> _testStderr;
+  List<int> _testStdout;
+  List<int> _testStderr;
   String _status;
   bool _stdoutDrained = false;
   bool _stderrDrained = false;
@@ -931,9 +1240,15 @@
     _stdoutDrained = false;
     _stderrDrained = false;
     _ignoreStreams = new MutableValue<bool>(false);  // Captured by closures.
-    _stdoutStream.onLine = _readStdout(_stdoutStream, _testStdout);
-    _stderrStream.onLine = _readStderr(_stderrStream, _testStderr);
+    _readStdout(_stdoutStream, _testStdout);
+    _readStderr(_stderrStream, _testStderr);
     _timer = new Timer(testCase.timeout * 1000, _timeoutHandler);
+
+    if (testCase.commands.last.environment != null) {
+      print("Warning: command.environment != null, but we don't support custom "
+            "environments for batch runner tests!");
+    }
+
     var line = _createArgumentsLine(testCase.batchTestArguments);
     _process.stdin.onError = (err) {
       print('Error on batch runner input stream stdin');
@@ -964,7 +1279,8 @@
                                (outcome == "TIMEOUT"),
                                _testStdout,
                                _testStderr,
-                               new Date.now().difference(_startTime));
+                               new Date.now().difference(_startTime),
+                               false);
     var test = _currentTest;
     _currentTest = null;
     test.completed();
@@ -982,9 +1298,9 @@
     if (_stderrDrained) _reportResult();
   }
 
-  VoidFunction _readStdout(StringInputStream stream, List<String> buffer) {
+  void _readStdout(StringInputStream stream, List<int> buffer) {
     var ignoreStreams = _ignoreStreams;  // Capture this mutable object.
-    void reader() {
+    void onLineHandler() {
       if (ignoreStreams.value) {
          while (stream.readLine() != null) {
           // Do nothing.
@@ -1001,7 +1317,7 @@
         } else if (line.startsWith('>>> ')) {
           throw new Exception('Unexpected command from dartc batch runner.');
         } else {
-          buffer.add(line);
+          buffer.addAll("$line\n".charCodes);
         }
         line = stream.readLine();
       }
@@ -1010,12 +1326,12 @@
         _stdoutDone();
       }
     }
-    return reader;
+    stream.onLine = onLineHandler;
   }
 
-  VoidFunction _readStderr(StringInputStream stream, List<String> buffer) {
+  void _readStderr(StringInputStream stream, List<int> buffer) {
     var ignoreStreams = _ignoreStreams;  // Capture this mutable object.
-    void reader() {
+    void onLineHandler() {
       if (ignoreStreams.value) {
         while (stream.readLine() != null) {
           // Do nothing.
@@ -1028,12 +1344,12 @@
         if (line.startsWith('>>> EOF STDERR')) {
           _stderrDone();
         } else {
-          buffer.add(line);
+          buffer.addAll("$line\n".charCodes);
         }
         line = stream.readLine();
       }
     }
-    return reader;
+    stream.onLine = onLineHandler;
   }
 
   ExitCodeEvent makeExitHandler(String status) {
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index ee4023a..4d04472 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -12,16 +12,17 @@
  * - Preparing tests, including copying files and frameworks to temporary
  *   directories, and computing the command line and arguments to be run.
  */
-#library("test_suite");
+library test_suite;
 
-#import("dart:io");
-#import("dart:isolate");
-#import("status_file_parser.dart");
-#import("test_runner.dart");
-#import("multitest.dart");
-#import("drt_updater.dart");
+import "dart:io";
+import "dart:isolate";
+import "status_file_parser.dart";
+import "test_runner.dart";
+import "multitest.dart";
+import "drt_updater.dart";
+import "dart:uri";
 
-#source("browser_test.dart");
+part "browser_test.dart";
 
 
 // TODO(rnystrom): Add to dart:core?
@@ -433,6 +434,19 @@
         recursive: true);
   }
 
+  Collection<Uri> get dart2JsBootstrapDependencies {
+    if (!useDart2JsFromSdk) return [];
+
+    var snapshotPath = TestUtils.absolutePath(new Path(buildDir).join(
+        new Path('dart-sdk/lib/_internal/compiler/'
+                 'implementation/dart2js.dart.snapshot'))).toString();
+    return [new Uri.fromComponents(scheme: 'file', path: snapshotPath)];
+  }
+
+  bool get useDart2JsFromSdk {
+    return configuration['use_sdk'];
+  }
+
   /**
    * The default implementation assumes a file is a test if
    * it ends in "Test.dart".
@@ -689,7 +703,13 @@
       args = new List.from(args);
       String tempDir = createOutputDirectory(info.filePath, '');
       args.add('--out=$tempDir/out.js');
-      List<Command> commands = <Command>[new Command(compilerPath, args)];
+
+       List<Command> commands = 
+           <Command>[new CompilationCommand("$tempDir/out.js",
+                                            !useDart2JsFromSdk,
+                                            dart2JsBootstrapDependencies,
+                                            compilerPath,
+                                            args)];
       if (info.hasCompileError) {
         // Do not attempt to run the compiled result. A compilation
         // error should be reported by the compilation command.
@@ -701,12 +721,17 @@
       return commands;
 
     case 'dart2dart':
-      var compilerArguments = new List.from(args);
-      compilerArguments.add('--output-type=dart');
+      args = new List.from(args);
+      args.add('--output-type=dart');
       String tempDir = createOutputDirectory(info.filePath, '');
-      compilerArguments.add('--out=$tempDir/out.dart');
+      args.add('--out=$tempDir/out.dart');
+
       List<Command> commands =
-          <Command>[new Command(compilerPath, compilerArguments)];
+          <Command>[new CompilationCommand("$tempDir/out.dart",
+                                           !useDart2JsFromSdk,
+                                           dart2JsBootstrapDependencies,
+                                           compilerPath,
+                                           args)];
       if (info.hasCompileError) {
         // Do not attempt to run the compiled result. A compilation
         // error should be reported by the compilation command.
@@ -769,6 +794,7 @@
                           String testName,
                           Object expectations,
                           bool isWrappingRequired) {
+    // TODO(kustermann/ricow): This method should be refactored.
     Map optionsFromFile = info.optionsFromFile;
     Path filePath = info.filePath;
     String filename = filePath.toString();
@@ -894,6 +920,14 @@
       int subtestIndex = 0;
       // Construct the command that executes the browser test
       do {
+        List<Command> commandSet = new List<Command>.from(commands);
+        if (subtestIndex != 0) {
+          // NOTE: The first time we enter this loop, all the compilation 
+          // commands will be executed. On subsequent loop iterations, we 
+          // don't need to do any compilations. Thus we set "commandSet = []".
+          commandSet = [];
+        }
+
         List<String> args = <String>[];
         String fullHtmlPath = htmlPath.startsWith('http:') ? htmlPath :
             (htmlPath.startsWith('/') ?
@@ -903,6 +937,7 @@
             && subtestNames.length > 0) {
           fullHtmlPath = '${fullHtmlPath}#${subtestNames[subtestIndex]}';
         }
+
         if (TestUtils.usesWebDriver(runtime)) {
           args = [
               dartDir.append('tools/testing/run_selenium.py').toNativePath(),
@@ -912,40 +947,52 @@
           if (runtime == 'dartium') {
             args.add('--executable=$dartiumFilename');
           }
-        } else {
-          args = [
-              dartDir.append('tools/testing/drt-trampoline.py').toNativePath(),
-              dumpRenderTreeFilename,
-              '--no-timeout'
-          ];
-          if (compiler == 'none') {
-            String packageRoot =
-                packageRootArgument(optionsFromFile['packageRoot']);
-            if (packageRoot != null) {
-              args.add(packageRoot);
-            }
+          if (subtestIndex != 0) {
+            args.add('--force-refresh');
           }
-          if (runtime == 'drt' &&
-              (compiler == 'none' || compiler == 'dart2dart')) {
-            var dartFlags = ['--ignore-unrecognized-flags'];
+          commandSet.add(new Command('python', args));
+        } else {
+          Expect.isTrue(runtime == "drt");
+
+          var dartFlags = [];
+          var dumpRenderTreeOptions = [];
+          var packageRootUri;
+
+          dumpRenderTreeOptions.add('--no-timeout');
+
+          if (compiler == 'none' || compiler == 'dart2dart') {
+            dartFlags.add('--ignore-unrecognized-flags');
             if (configuration["checked"]) {
               dartFlags.add('--enable_asserts');
               dartFlags.add("--enable_type_checks");
             }
             dartFlags.addAll(vmOptions);
-            args.add('--dart-flags=${Strings.join(dartFlags, " ")}');
           }
-          args.add(fullHtmlPath);
+          if (compiler == 'none') {
+            var packageRootPath = packageRoot(optionsFromFile['packageRoot']);
+            if (packageRootPath != null) {
+              var absolutePath = 
+                  TestUtils.absolutePath(new Path(packageRootPath));
+              packageRootUri = new Uri.fromComponents(
+                  scheme: 'file',
+                  path: absolutePath.toString());
+            }
+          }
+
           if (expectedOutput != null) {
-            args.add('--out-expectation=${expectedOutput.toNativePath()}');
+            if (expectedOutput.toNativePath().endsWith('.png')) {
+              // pixel tests are specified by running DRT "foo.html'-p"
+              dumpRenderTreeOptions.add('--notree');
+              fullHtmlPath = "${fullHtmlPath}'-p";
+            }
           }
+          commandSet.add(new DumpRenderTreeCommand(dumpRenderTreeFilename,
+                                                   fullHtmlPath,
+                                                   dumpRenderTreeOptions,
+                                                   dartFlags,
+                                                   packageRootUri,
+                                                   expectedOutput));
         }
-        List<Command> commandSet = new List<Command>.from(commands);
-        if (subtestIndex != 0) {
-         commandSet = [];
-         if(TestUtils.usesWebDriver(runtime)) args.add('--force-refresh');
-        }
-        commandSet.add(new Command('python', args));
 
         // Create BrowserTestCase and queue it.
         String testDisplayName = '$suiteName/$testName';
@@ -998,6 +1045,13 @@
       args.insertRange(0, 1, executable);
       executable = dartShellFileName;
     }
+    if (['dart2js', 'dart2dart'].contains(configuration['compiler'])) {
+      return new CompilationCommand(outputFile,
+                                   !useDart2JsFromSdk,
+                                   dart2JsBootstrapDependencies,
+                                   compilerPath,
+                                   args);
+    }
     return new Command(executable, args);
   }
 
@@ -1132,13 +1186,23 @@
     return args;
   }
 
-  String packageRootArgument(String packageRootFromFile) {
-    if (packageRootFromFile == "none") return null;
+  String packageRoot(String packageRootFromFile) {
+    if (packageRootFromFile == "none") {
+      return null;
+    }
     String packageRoot = packageRootFromFile;
     if (packageRootFromFile == null) {
       packageRoot = "$buildDir/packages/";
     }
-    return "--package-root=$packageRoot";
+    return packageRoot;
+  }
+
+  String packageRootArgument(String packageRootFromFile) {
+    var packageRootPath = packageRoot(packageRootFromFile);
+    if (packageRootPath == null) {
+      return null;
+    }
+    return "--package-root=$packageRootPath";
   }
 
   /**
@@ -1494,6 +1558,31 @@
   }
 }
 
+class LastModifiedCache {
+  Map<String, Date> _cache = <String, Date>{};
+
+  /**
+   * Returns the last modified date of the given [uri].
+   *
+   * The return value will be cached for future queries. If [uri] is a local
+   * file, it's last modified [Date] will be returned. If the file does not
+   * exist, null will be returned instead.
+   * In case [uri] is not a local file, this method will always return
+   * the current date.
+   */
+  Date getLastModified(Uri uri) {
+    if (uri.scheme == "file") {
+      if (_cache.containsKey(uri.path)) {
+        return _cache[uri.path];
+      }
+      var file = new File(new Path(uri.path).toNativePath());
+      _cache[uri.path] = file.existsSync() ? file.lastModifiedSync() : null;
+      return _cache[uri.path];
+    }
+    return new Date.now();
+  }
+}
+
 class TestUtils {
   /**
    * The libraries in this directory relies on finding various files
@@ -1502,7 +1591,9 @@
    * script must set this to '.../dart/tools/test.dart'.
    */
   static String testScriptPath = new Options().script;
-
+  static LastModifiedCache lastModifiedCache = new LastModifiedCache();
+  static Path currentWorkingDirectory =
+      new Path.fromNative(new Directory.current().path);
   /**
    * Creates a directory using a [relativePath] to an existing
    * [base] directory if that [relativePath] does not already exist.
@@ -1548,7 +1639,7 @@
     // If a flaky test did fail, infos about it (i.e. test name, stdin, stdout)
     // will be written to this file. This is useful for the debugging of
     // flaky tests.
-    // When running on a built bot, the file can be made visible in the 
+    // When running on a built bot, the file can be made visible in the
     // waterfall UI.
     return ".flaky.log";
   }
@@ -1559,6 +1650,26 @@
     }
   }
 
+  static Path absolutePath(Path path) {
+    if (!path.isAbsolute) {
+      return currentWorkingDirectory.join(path);
+    }
+    return path;
+  }
+
+  static String outputDir(Map configuration) {
+    var result = '';
+    var system = configuration['system'];
+    if (system == 'linux') {
+      result = 'out/';
+    } else if (system == 'macos') {
+      result = 'xcodebuild/';
+    } else if (system == 'windows') {
+      result = 'build/';
+    }
+    return result;
+  }
+
   static Path dartDir() {
     File scriptFile = new File(testScriptPath);
     Path scriptPath = new Path.fromNative(scriptFile.fullPathSync());
diff --git a/utils/apidoc/apidoc.dart b/utils/apidoc/apidoc.dart
index 742e519..019812a 100644
--- a/utils/apidoc/apidoc.dart
+++ b/utils/apidoc/apidoc.dart
@@ -34,6 +34,7 @@
 
   List<String> excludedLibraries = <String>[];
   List<String> includedLibraries = <String>[];
+  var pkgPath;
 
 
   // Parse the command-line arguments.
@@ -60,6 +61,8 @@
           includedLibraries.add(arg.substring('--include-lib='.length));
         } else if (arg.startsWith('--out=')) {
           outputDir = new Path.fromNative(arg.substring('--out='.length));
+        } else if (arg.startsWith('--pkg=')) {
+          pkgPath = arg.substring('--pkg='.length);
         } else {
           print('Unknown option: $arg');
           return;
@@ -69,7 +72,6 @@
   }
 
   final libPath = doc.scriptDir.append('../../sdk/');
-  final pkgPath = doc.scriptDir.append('../../pkg/');
 
   doc.cleanOutputDirectory(outputDir);
 
@@ -97,7 +99,7 @@
   final htmldoc = new Htmldoc();
   htmldoc.includeApi = true;
   htmldoc.documentLibraries(
-    <Path>[doc.scriptDir.append('../../sdk/lib/html/doc/html.dartdoc')],
+    <Path>[doc.scriptDir.append('../../tools/dom/doc/html.dartdoc')],
     libPath, pkgPath);
 
   // Process libraries.
diff --git a/utils/apidoc/apidoc.gyp b/utils/apidoc/apidoc.gyp
index baeae67..81a0330 100644
--- a/utils/apidoc/apidoc.gyp
+++ b/utils/apidoc/apidoc.gyp
@@ -20,6 +20,7 @@
       'dependencies': [
         '../../utils/compiler/compiler.gyp:dart2js',
         '../../runtime/dart-runtime.gyp:dart',
+        '../../pkg/pkg.gyp:pkg_packages',
       ],
       'includes': [
         '../../sdk/lib/core/corelib_sources.gypi',
@@ -45,10 +46,12 @@
             '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
             'apidoc.dart',
             '--out=<(PRODUCT_DIR)/api_docs',
+            '--pkg=<(PRODUCT_DIR)/packages/',
             '--mode=static',
             '--exclude-lib=dartdoc',
             '--exclude-lib=http',
             '--exclude-lib=oauth2',
+            '--exclude-lib=path',
             '--exclude-lib=webdriver',
             '--include-lib=matcher',
             '--include-lib=mock',
diff --git a/utils/pub/command_help.dart b/utils/pub/command_help.dart
index 33ef705..5ebf3cd 100644
--- a/utils/pub/command_help.dart
+++ b/utils/pub/command_help.dart
@@ -10,7 +10,7 @@
 import 'log.dart' as log;
 import 'pub.dart';
 
-/** Handles the `help` pub command. */
+/// Handles the `help` pub command. 
 class HelpCommand extends PubCommand {
   String get description => "Display help information for Pub.";
   String get usage => 'pub help [command]';
diff --git a/utils/pub/command_install.dart b/utils/pub/command_install.dart
index e5188f6..2263755 100644
--- a/utils/pub/command_install.dart
+++ b/utils/pub/command_install.dart
@@ -8,7 +8,7 @@
 import 'log.dart' as log;
 import 'pub.dart';
 
-/** Handles the `install` pub command. */
+/// Handles the `install` pub command. 
 class InstallCommand extends PubCommand {
   String get description => "Install the current package's dependencies.";
   String get usage => "pub install";
diff --git a/utils/pub/command_lish.dart b/utils/pub/command_lish.dart
index df0f21d..5afe32f 100644
--- a/utils/pub/command_lish.dart
+++ b/utils/pub/command_lish.dart
@@ -10,12 +10,13 @@
 
 import '../../pkg/args/lib/args.dart';
 import '../../pkg/http/lib/http.dart' as http;
+import '../../pkg/path/lib/path.dart' as path;
 import 'directory_tree.dart';
 import 'git.dart' as git;
+import 'http.dart';
 import 'io.dart';
 import 'log.dart' as log;
 import 'oauth2.dart' as oauth2;
-import 'path.dart' as path;
 import 'pub.dart';
 import 'validator.dart';
 
@@ -27,6 +28,8 @@
 
   ArgParser get commandParser {
     var parser = new ArgParser();
+    // TODO(nweiz): Use HostedSource.defaultUrl as the default value once we use
+    // dart:io for HTTPS requests.
     parser.addOption('server', defaultsTo: 'https://pub.dartlang.org',
         help: 'The package server to which to upload this package');
     return parser;
@@ -42,17 +45,17 @@
       // should report that error and exit.
       var newUri = server.resolve("/packages/versions/new.json");
       return client.get(newUri).chain((response) {
-        var parameters = _parseJson(response);
+        var parameters = parseJsonResponse(response);
 
         var url = _expectField(parameters, 'url', response);
-        if (url is! String) _invalidServerResponse(response);
+        if (url is! String) invalidServerResponse(response);
         cloudStorageUrl = new Uri.fromString(url);
         var request = new http.MultipartRequest('POST', cloudStorageUrl);
 
         var fields = _expectField(parameters, 'fields', response);
-        if (fields is! Map) _invalidServerResponse(response);
+        if (fields is! Map) invalidServerResponse(response);
         fields.forEach((key, value) {
-          if (value is! String) _invalidServerResponse(response);
+          if (value is! String) invalidServerResponse(response);
           request.fields[key] = value;
         });
 
@@ -64,44 +67,18 @@
         var location = response.headers['location'];
         if (location == null) throw new PubHttpException(response);
         return location;
-      }).chain((location) => client.get(location)).transform((response) {
-        var parsed = _parseJson(response);
-        if (parsed['success'] is! Map ||
-            !parsed['success'].containsKey('message') ||
-            parsed['success']['message'] is! String) {
-          _invalidServerResponse(response);
-        }
-        log.message(parsed['success']['message']);
-      });
+      }).chain((location) => client.get(location))
+          .transform(handleJsonSuccess);
     }).transformException((e) {
-      if (e is PubHttpException) {
-        var url = e.response.request.url;
-        if (url.toString() == cloudStorageUrl.toString()) {
-          // 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) {
-          var errorMap = _parseJson(e.response);
-          if (errorMap['error'] is! Map ||
-              !errorMap['error'].containsKey('message') ||
-              errorMap['error']['message'] is! String) {
-            _invalidServerResponse(e.response);
-          }
-          throw errorMap['error']['message'];
-        }
-      } else if (e is oauth2.ExpirationException) {
-        log.error("Pub's authorization to upload packages has expired and "
-        "can't be automatically refreshed.");
-        return _publish(packageBytes);
-      } else if (e is oauth2.AuthorizationException) {
-        var message = "OAuth2 authorization failed";
-        if (e.description != null) message = "$message (${e.description})";
-        log.error("$message.");
-        return oauth2.clearCredentials(cache).chain((_) =>
-            _publish(packageBytes));
-      } else {
-        throw e;
+      if (e is! PubHttpException) throw e;
+      var url = e.response.request.url;
+      if (url.toString() == cloudStorageUrl.toString()) {
+        // 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) {
+        handleJsonError(e.response);
       }
     });
   }
@@ -137,13 +114,6 @@
   Future<List<String>> get _filesToPublish {
     var rootDir = entrypoint.root.dir;
 
-    // TODO(rnystrom): listDir() returns real file paths after symlinks are
-    // resolved. This means if libDir contains a symlink, the resulting paths
-    // won't appear to be within it, which confuses relativeTo(). Work around
-    // that here by making sure we have the real path to libDir. Remove this
-    // when #7346 is fixed.
-    rootDir = new File(rootDir).fullPathSync();
-
     return Futures.wait([
       dirExists(join(rootDir, '.git')),
       git.isInstalled
@@ -166,20 +136,7 @@
             // Should instead only make these relative right before generating
             // the tree display (which is what really needs them to be).
             // Make it relative to the package root.
-            entry = relativeTo(entry, rootDir);
-
-            // TODO(rnystrom): dir.list() will include paths with resolved
-            // symlinks. In particular, we'll get paths to symlinked files from
-            // "packages" that reach outside of this package. Since the path
-            // has already been resolved, we don't even see "packages" in that
-            // path anymore.
-            // These should not be included in the archive. As a hack, ignore
-            // any file whose relative path is backing out of the root
-            // directory. Should do something cleaner.
-            var parts = path.split(entry);
-            if (!parts.isEmpty && parts[0] == '..') return null;
-
-            return entry;
+            return relativeTo(entry, rootDir);
           });
         }));
       });
@@ -192,31 +149,11 @@
     }));
   }
 
-  /// Parses a response body, assuming it's JSON-formatted. Throws a
-  /// user-friendly error if the response body is invalid JSON, or if it's not a
-  /// map.
-  Map _parseJson(http.Response response) {
-    var value;
-    try {
-      value = JSON.parse(response.body);
-    } catch (e) {
-      // TODO(nweiz): narrow this catch clause once issue 6775 is fixed.
-      _invalidServerResponse(response);
-    }
-    if (value is! Map) _invalidServerResponse(response);
-    return value;
-  }
-
   /// Returns the value associated with [key] in [map]. Throws a user-friendly
   /// error if [map] doens't contain [key].
   _expectField(Map map, String key, http.Response response) {
     if (map.containsKey(key)) return map[key];
-    _invalidServerResponse(response);
-  }
-
-  /// Throws an error describing an invalid response from the server.
-  void _invalidServerResponse(http.Response response) {
-    throw 'Invalid server response:\n${response.body}';
+    invalidServerResponse(response);
   }
 
   /// Validates the package. Throws an exception if it's invalid.
diff --git a/utils/pub/command_update.dart b/utils/pub/command_update.dart
index 6995a6d..1dda303 100644
--- a/utils/pub/command_update.dart
+++ b/utils/pub/command_update.dart
@@ -8,7 +8,7 @@
 import 'log.dart' as log;
 import 'pub.dart';
 
-/** Handles the `update` pub command. */
+/// Handles the `update` pub command. 
 class UpdateCommand extends PubCommand {
   String get description =>
     "Update the current package's dependencies to the latest versions.";
diff --git a/utils/pub/command_uploader.dart b/utils/pub/command_uploader.dart
new file mode 100644
index 0000000..618afc3
--- /dev/null
+++ b/utils/pub/command_uploader.dart
@@ -0,0 +1,82 @@
+// 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 command_uploader;
+
+import 'dart:io';
+import 'dart:uri';
+
+import '../../pkg/args/lib/args.dart';
+import '../../pkg/path/lib/path.dart' as path;
+import 'entrypoint.dart';
+import 'exit_codes.dart' as exit_codes;
+import 'http.dart';
+import 'io.dart';
+import 'log.dart' as log;
+import 'oauth2.dart' as oauth2;
+import 'pub.dart';
+
+/// Handles the `uploader` pub command.
+class UploaderCommand extends PubCommand {
+  final description = "Manage uploaders for a package on pub.dartlang.org.";
+  final usage = "pub uploader [options] {add/remove} <email>";
+  final requiresEntrypoint = false;
+
+  ArgParser get commandParser {
+    var parser = new ArgParser();
+    // TODO(nweiz): Use HostedSource.defaultUrl as the default value once we use
+    // dart:io for HTTPS requests.
+    parser.addOption('server', defaultsTo: 'https://pub.dartlang.org',
+        help: 'The package server on which the package is hosted');
+    parser.addOption('package', help: 'The package whose uploaders will be '
+        'modified\n'
+        '(defaults to the current package)');
+    return parser;
+  }
+
+  /// The URL of the package hosting server.
+  Uri get server => new Uri.fromString(commandOptions['server']);
+
+  Future onRun() {
+    if (commandOptions.rest.isEmpty) {
+      log.error('No uploader command given.');
+      this.printUsage();
+      exit(exit_codes.USAGE);
+    }
+
+    var command = commandOptions.rest.removeAt(0);
+    if (!['add', 'remove'].contains(command)) {
+      log.error('Unknown uploader command "$command".');
+      this.printUsage();
+      exit(exit_codes.USAGE);
+    } else if (commandOptions.rest.isEmpty) {
+      log.error('No uploader given for "pub uploader $command".');
+      this.printUsage();
+      exit(exit_codes.USAGE);
+    }
+
+    return new Future.immediate(null).chain((_) {
+      var package = commandOptions['package'];
+      if (package != null) return new Future.immediate(package);
+      return Entrypoint.load(path.current, cache)
+          .transform((entrypoint) => entrypoint.root.name);
+    }).chain((package) {
+      var uploader = commandOptions.rest[0];
+      return oauth2.withClient(cache, (client) {
+        if (command == 'add') {
+          var url = server.resolve("/packages/${encodeUriComponent(package)}"
+              "/uploaders.json");
+          return client.post(url, fields: {"email": uploader});
+        } else { // command == 'remove'
+          var url = server.resolve("/packages/${encodeUriComponent(package)}"
+              "/uploaders/${encodeUriComponent(uploader)}.json");
+          return client.delete(url);
+        }
+      });
+    }).transform(handleJsonSuccess).transformException((e) {
+      if (e is! PubHttpException) throw e;
+      handleJsonError(e.response);
+    });
+  }
+}
diff --git a/utils/pub/command_version.dart b/utils/pub/command_version.dart
index 5e2f005..bb56e69 100644
--- a/utils/pub/command_version.dart
+++ b/utils/pub/command_version.dart
@@ -6,7 +6,7 @@
 
 import 'pub.dart';
 
-/** Handles the `version` pub command. */
+/// Handles the `version` pub command. 
 class VersionCommand extends PubCommand {
   String get description => 'Print pub version.';
   String get usage => 'pub version';
@@ -15,4 +15,4 @@
   Future onRun() {
     printVersion();
   }
-}
\ No newline at end of file
+}
diff --git a/utils/pub/directory_tree.dart b/utils/pub/directory_tree.dart
index f5baa62..cffff62 100644
--- a/utils/pub/directory_tree.dart
+++ b/utils/pub/directory_tree.dart
@@ -5,8 +5,8 @@
 /// A simple library for rendering a list of files as a directory tree.
 library directory_tree;
 
+import '../../pkg/path/lib/path.dart' as path;
 import 'log.dart' as log;
-import 'path.dart' as path;
 
 /// Draws a directory tree for the given list of files. Given a list of files
 /// like:
@@ -50,7 +50,7 @@
 ///         |-- absolute_test.dart
 ///         |-- all_test.dart
 ///         |-- basename_test.dart
-///         |   (7 more...)
+///         | (7 more...)
 ///         |-- path_windows_test.dart
 ///         |-- relative_test.dart
 ///         '-- split_test.dart
@@ -109,7 +109,7 @@
     _draw(buffer, '$prefix$childPrefix', isLastChild, child, children[child]);
   }
 
-  if (childNames.length <= 10) {
+  if (name == null || childNames.length <= 10) {
     // Not too many, so show all the children.
     for (var i = 0; i < childNames.length; i++) {
       _drawChild(i == childNames.length - 1, childNames[i]);
@@ -123,7 +123,7 @@
     // Elide the middle ones.
     buffer.add(prefix);
     buffer.add(_getPrefix(name == null, isLast));
-    buffer.add('|   (${childNames.length - 6} more...)\n');
+    buffer.add('| (${childNames.length - 6} more...)\n');
 
     // Show the last few.
     _drawChild(false, childNames[childNames.length - 3]);
diff --git a/utils/pub/entrypoint.dart b/utils/pub/entrypoint.dart
index 56007e0..b52a139 100644
--- a/utils/pub/entrypoint.dart
+++ b/utils/pub/entrypoint.dart
@@ -14,39 +14,31 @@
 import 'version.dart';
 import 'version_solver.dart';
 
-/**
- * Pub operates over a directed graph of dependencies that starts at a root
- * "entrypoint" package. This is typically the package where the current
- * working directory is located. An entrypoint knows the [root] package it is
- * associated with and is responsible for managing the "packages" directory
- * for it.
- *
- * That directory contains symlinks to all packages used by an app. These links
- * point either to the [SystemCache] or to some other location on the local
- * filesystem.
- *
- * While entrypoints are typically applications, a pure library package may end
- * up being used as an entrypoint. Also, a single package may be used as an
- * entrypoint in one context but not in another. For example, a package that
- * contains a reusable library may not be the entrypoint when used by an app,
- * but may be the entrypoint when you're running its tests.
- */
+/// Pub operates over a directed graph of dependencies that starts at a root
+/// "entrypoint" package. This is typically the package where the current
+/// working directory is located. An entrypoint knows the [root] package it is
+/// associated with and is responsible for managing the "packages" directory
+/// for it.
+///
+/// That directory contains symlinks to all packages used by an app. These links
+/// point either to the [SystemCache] or to some other location on the local
+/// filesystem.
+///
+/// While entrypoints are typically applications, a pure library package may end
+/// up being used as an entrypoint. Also, a single package may be used as an
+/// entrypoint in one context but not in another. For example, a package that
+/// contains a reusable library may not be the entrypoint when used by an app,
+/// but may be the entrypoint when you're running its tests.
 class Entrypoint {
-  /**
-   * The root package this entrypoint is associated with.
-   */
+  /// The root package this entrypoint is associated with.
   final Package root;
 
-  /**
-   * The system-wide cache which caches packages that need to be fetched over
-   * the network.
-   */
+  /// The system-wide cache which caches packages that need to be fetched over
+  /// the network.
   final SystemCache cache;
 
-  /**
-   * Packages which are either currently being asynchronously installed to the
-   * directory, or have already been installed.
-   */
+  /// Packages which are either currently being asynchronously installed to the
+  /// directory, or have already been installed.
   final Map<PackageId, Future<PackageId>> _installs;
 
   Entrypoint(this.root, this.cache)
@@ -58,25 +50,21 @@
         new Entrypoint(package, cache));
   }
 
-  /**
-   * The path to this "packages" directory.
-   */
   // TODO(rnystrom): Make this path configurable.
+  /// The path to this "packages" directory.
   String get path => join(root.dir, 'packages');
 
-  /**
-   * Ensures that the package identified by [id] is installed to the directory.
-   * Returns the resolved [PackageId].
-   *
-   * If this completes successfully, the package is guaranteed to be importable
-   * using the `package:` scheme.
-   *
-   * This will automatically install the package to the system-wide cache as
-   * well if it requires network access to retrieve (specifically, if
-   * `id.source.shouldCache` is true).
-   *
-   * See also [installDependencies].
-   */
+  /// Ensures that the package identified by [id] is installed to the directory.
+  /// Returns the resolved [PackageId].
+  ///
+  /// If this completes successfully, the package is guaranteed to be importable
+  /// using the `package:` scheme.
+  ///
+  /// This will automatically install the package to the system-wide cache as
+  /// well if it requires network access to retrieve (specifically, if
+  /// `id.source.shouldCache` is true).
+  ///
+  /// See also [installDependencies].
   Future<PackageId> install(PackageId id) {
     var pendingOrCompleted = _installs[id];
     if (pendingOrCompleted != null) return pendingOrCompleted;
@@ -108,34 +96,28 @@
     return future;
   }
 
-  /**
-   * Installs all dependencies of the [root] package to its "packages"
-   * directory, respecting the [LockFile] if present. Returns a [Future] that
-   * completes when all dependencies are installed.
-   */
+  /// Installs all dependencies of the [root] package to its "packages"
+  /// directory, respecting the [LockFile] if present. Returns a [Future] that
+  /// completes when all dependencies are installed.
   Future installDependencies() {
-    return _loadLockFile()
+    return loadLockFile()
       .chain((lockFile) => resolveVersions(cache.sources, root, lockFile))
       .chain(_installDependencies);
   }
 
-  /**
-   * Installs the latest available versions of all dependencies of the [root]
-   * package to its "package" directory, writing a new [LockFile]. Returns a
-   * [Future] that completes when all dependencies are installed.
-   */
+  /// Installs the latest available versions of all dependencies of the [root]
+  /// package to its "package" directory, writing a new [LockFile]. Returns a
+  /// [Future] that completes when all dependencies are installed.
   Future updateAllDependencies() {
     return resolveVersions(cache.sources, root, new LockFile.empty())
       .chain(_installDependencies);
   }
 
-  /**
-   * Installs the latest available versions of [dependencies], while leaving
-   * other dependencies as specified by the [LockFile] if possible. Returns a
-   * [Future] that completes when all dependencies are installed.
-   */
+  /// Installs the latest available versions of [dependencies], while leaving
+  /// other dependencies as specified by the [LockFile] if possible. Returns a
+  /// [Future] that completes when all dependencies are installed.
   Future updateDependencies(List<String> dependencies) {
-    return _loadLockFile().chain((lockFile) {
+    return loadLockFile().chain((lockFile) {
       var versionSolver = new VersionSolver(cache.sources, root, lockFile);
       for (var dependency in dependencies) {
         versionSolver.useLatestVersion(dependency);
@@ -144,10 +126,8 @@
     }).chain(_installDependencies);
   }
 
-  /**
-   * Removes the old packages directory, installs all dependencies listed in
-   * [packageVersions], and writes a [LockFile].
-   */
+  /// Removes the old packages directory, installs all dependencies listed in
+  /// [packageVersions], and writes a [LockFile].
   Future _installDependencies(List<PackageId> packageVersions) {
     return cleanDir(path).chain((_) {
       return Futures.wait(packageVersions.map((id) {
@@ -159,14 +139,9 @@
       .chain(_linkSecondaryPackageDirs);
   }
 
-  /**
-   * Loads the list of concrete package versions from the `pubspec.lock`, if it
-   * exists. If it doesn't, this completes to an empty [LockFile].
-   *
-   * If there's an error reading the `pubspec.lock` file, this will print a
-   * warning message and act as though the file doesn't exist.
-   */
-  Future<LockFile> _loadLockFile() {
+  /// Loads the list of concrete package versions from the `pubspec.lock`, if it
+  /// exists. If it doesn't, this completes to an empty [LockFile].
+  Future<LockFile> loadLockFile() {
     var lockFilePath = join(root.dir, 'pubspec.lock');
 
     log.fine("Loading lockfile.");
@@ -181,9 +156,7 @@
     });
   }
 
-  /**
-   * Saves a list of concrete package versions to the `pubspec.lock` file.
-   */
+  /// Saves a list of concrete package versions to the `pubspec.lock` file.
   Future _saveLockFile(List<PackageId> packageIds) {
     var lockFile = new LockFile.empty();
     for (var id in packageIds) {
@@ -195,10 +168,8 @@
     return writeTextFile(lockFilePath, lockFile.serialize());
   }
 
-  /**
-   * Installs a self-referential symlink in the `packages` directory that will
-   * allow a package to import its own files using `package:`.
-   */
+  /// Installs a self-referential symlink in the `packages` directory that will
+  /// allow a package to import its own files using `package:`.
   Future _installSelfReference(_) {
     var linkPath = join(path, root.name);
     return exists(linkPath).chain((exists) {
@@ -210,11 +181,9 @@
     });
   }
 
-  /**
-   * If `bin/`, `test/`, or `example/` directories exist, symlink `packages/`
-   * into them so that their entrypoints can be run. Do the same for any
-   * subdirectories of `test/` and `example/`.
-   */
+  /// If `bin/`, `test/`, or `example/` directories exist, symlink `packages/`
+  /// into them so that their entrypoints can be run. Do the same for any
+  /// subdirectories of `test/` and `example/`.
   Future _linkSecondaryPackageDirs(_) {
     var binDir = join(root.dir, 'bin');
     var exampleDir = join(root.dir, 'example');
@@ -230,10 +199,8 @@
       .chain((_) => _linkSecondaryPackageDirsRecursively(webDir));
   }
 
-  /**
-   * Creates a symlink to the `packages` directory in [dir] and all its
-   * subdirectories.
-   */
+  /// Creates a symlink to the `packages` directory in [dir] and all its
+  /// subdirectories.
   Future _linkSecondaryPackageDirsRecursively(String dir) {
     return dirExists(dir).chain((exists) {
       if (!exists) return new Future.immediate(null);
@@ -251,10 +218,8 @@
   }
 
   // TODO(nweiz): roll this into [listDir] in io.dart once issue 4775 is fixed.
-  /**
-   * Recursively lists the contents of [dir], excluding hidden `.DS_Store` files
-   * and `package` files.
-   */
+  /// Recursively lists the contents of [dir], excluding hidden `.DS_Store`
+  /// files and `package` files.
   Future<List<String>> _listDirWithoutPackages(dir) {
     return listDir(dir).chain((files) {
       return Futures.wait(files.map((file) {
@@ -271,9 +236,7 @@
     }).transform(flatten);
   }
 
-  /**
-   * Creates a symlink to the `packages` directory in [dir] if none exists.
-   */
+  /// Creates a symlink to the `packages` directory in [dir] if none exists.
   Future _linkSecondaryPackageDir(String dir) {
     var to = join(dir, 'packages');
     return exists(to).chain((exists) {
diff --git a/utils/pub/git.dart b/utils/pub/git.dart
index 6defde3..b216735 100644
--- a/utils/pub/git.dart
+++ b/utils/pub/git.dart
@@ -2,9 +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.
 
-/**
- * Helper functionality for invoking Git.
- */
+/// Helper functionality for invoking Git.
 library git;
 
 import 'io.dart';
@@ -84,4 +82,4 @@
   });
 
   return completer.future;
-}
\ No newline at end of file
+}
diff --git a/utils/pub/git_source.dart b/utils/pub/git_source.dart
index 6327638..e54b6cf 100644
--- a/utils/pub/git_source.dart
+++ b/utils/pub/git_source.dart
@@ -11,9 +11,7 @@
 import 'source_registry.dart';
 import 'utils.dart';
 
-/**
- * A package source that installs packages from Git repos.
- */
+/// A package source that installs packages from Git repos.
 class GitSource extends Source {
   final String name = "git";
 
@@ -21,20 +19,18 @@
 
   GitSource();
 
-  /**
-   * Clones a Git repo to the local filesystem.
-   *
-   * The Git cache directory is a little idiosyncratic. At the top level, it
-   * contains a directory for each commit of each repository, named `<package
-   * name>-<commit hash>`. These are the canonical package directories that are
-   * linked to from the `packages/` directory.
-   *
-   * In addition, the Git system cache contains a subdirectory named `cache/`
-   * which contains a directory for each separate repository URL, named
-   * `<package name>-<url hash>`. These are used to check out the repository
-   * itself; each of the commit-specific directories are clones of a directory
-   * in `cache/`.
-   */
+  /// Clones a Git repo to the local filesystem.
+  ///
+  /// The Git cache directory is a little idiosyncratic. At the top level, it
+  /// contains a directory for each commit of each repository, named `<package
+  /// name>-<commit hash>`. These are the canonical package directories that are
+  /// linked to from the `packages/` directory.
+  ///
+  /// In addition, the Git system cache contains a subdirectory named `cache/`
+  /// which contains a directory for each separate repository URL, named
+  /// `<package name>-<url hash>`. These are used to check out the repository
+  /// itself; each of the commit-specific directories are clones of a directory
+  /// in `cache/`.
   Future<Package> installToSystemCache(PackageId id) {
     var revisionCachePath;
 
@@ -63,9 +59,7 @@
     });
   }
 
-  /**
-   * Ensures [description] is a Git URL.
-   */
+  /// Ensures [description] is a Git URL.
   void validateDescription(description, {bool fromLockFile: false}) {
     // A single string is assumed to be a Git URL.
     if (description is String) return;
@@ -85,9 +79,8 @@
     }
   }
 
-  /**
-   * Two Git descriptions are equal if both their URLs and their refs are equal.
-   */
+  /// Two Git descriptions are equal if both their URLs and their refs are
+  /// equal.
   bool descriptionsEqual(description1, description2) {
     // TODO(nweiz): Do we really want to throw an error if you have two
     // dependencies on some repo, one of which specifies a ref and one of which
@@ -96,9 +89,7 @@
       _getRef(description1) == _getRef(description2);
   }
 
-  /**
-   * Attaches a specific commit to [id] to disambiguate it.
-   */
+  /// Attaches a specific commit to [id] to disambiguate it.
   Future<PackageId> resolveId(PackageId id) {
     return _revisionAt(id).transform((revision) {
       var description = {'url': _getUrl(id), 'ref': _getRef(id)};
@@ -107,12 +98,10 @@
     });
   }
 
-  /**
-   * 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
-   * fails.
-   */
+  /// 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
+  /// fails.
   Future _ensureRepoCache(PackageId id) {
     var path = _repoCachePath(id);
     return exists(path).chain((exists) {
@@ -122,17 +111,13 @@
     });
   }
 
-  /**
-   * Returns a future that completes to the revision hash of [id].
-   */
+  /// Returns a future that completes to the revision hash of [id].
   Future<String> _revisionAt(PackageId id) {
     return git.run(["rev-parse", _getEffectiveRef(id)],
         workingDir: _repoCachePath(id)).transform((result) => result[0]);
   }
 
-  /**
-   * Returns the path to the revision-specific cache of [id].
-   */
+  /// Returns the path to the revision-specific cache of [id].
   Future<String> _revisionCachePath(PackageId id) {
     return _revisionAt(id).transform((rev) {
       var revisionCacheName = '${id.name}-$rev';
@@ -140,13 +125,12 @@
     });
   }
 
-  /**
-   * Clones the repo at the URI [from] to the path [to] on the local filesystem.
-   *
-   * If [mirror] is true, create a bare, mirrored clone. This doesn't check out
-   * the working tree, but instead makes the repository a local mirror of the
-   * remote repository. See the manpage for `git clone` for more information.
-   */
+  /// Clones the repo at the URI [from] to the path [to] on the local
+  /// filesystem.
+  ///
+  /// If [mirror] is true, create a bare, mirrored clone. This doesn't check out
+  /// the working tree, but instead makes the repository a local mirror of the
+  /// remote repository. See the manpage for `git clone` for more information.
   Future _clone(String from, String to, {bool mirror: false}) {
     // Git on Windows does not seem to automatically create the destination
     // directory.
@@ -157,43 +141,36 @@
     }).transform((result) => null);
   }
 
-  /**
-   * Checks out the reference [ref] in [repoPath].
-   */
+  /// Checks out the reference [ref] in [repoPath].
   Future _checkOut(String repoPath, String ref) {
     return git.run(["checkout", ref], workingDir: repoPath).transform(
         (result) => null);
   }
 
-  /**
-   * Returns the path to the canonical clone of the repository referred to by
-   * [id] (the one in `<system cache>/git/cache`).
-   */
+  /// Returns the path to the canonical clone of the repository referred to by
+  /// [id] (the one in `<system cache>/git/cache`).
   String _repoCachePath(PackageId id) {
     var repoCacheName = '${id.name}-${sha1(_getUrl(id))}';
     return join(systemCacheRoot, 'cache', repoCacheName);
   }
 
-  /**
-   * Returns the repository URL for [id].
-   *
-   * [description] may be a description or a [PackageId].
-   */
+  /// Returns the repository URL for [id].
+  ///
+  /// [description] may be a description or a [PackageId].
   String _getUrl(description) {
     description = _getDescription(description);
     if (description is String) return description;
     return description['url'];
   }
 
-  /**
-   * Returns the commit ref that should be checked out for [description].
-   *
-   * This differs from [_getRef] in that it doesn't just return the ref in
-   * [description]. It will return a sensible default if that ref doesn't exist,
-   * and it will respect the "resolved-ref" parameter set by [resolveId].
-   *
-   * [description] may be a description or a [PackageId].
-   */
+  /// Returns the commit ref that should be checked out for [description].
+  ///
+  /// This differs from [_getRef] in that it doesn't just return the ref in
+  /// [description]. It will return a sensible default if that ref doesn't
+  /// exist, and it will respect the "resolved-ref" parameter set by
+  /// [resolveId].
+  ///
+  /// [description] may be a description or a [PackageId].
   String _getEffectiveRef(description) {
     description = _getDescription(description);
     if (description is Map && description.containsKey('resolved-ref')) {
@@ -204,21 +181,17 @@
     return ref == null ? 'HEAD' : ref;
   }
 
-  /**
-   * Returns the commit ref for [description], or null if none is given.
-   *
-   * [description] may be a description or a [PackageId].
-   */
+  /// Returns the commit ref for [description], or null if none is given.
+  ///
+  /// [description] may be a description or a [PackageId].
   String _getRef(description) {
     description = _getDescription(description);
     if (description is String) return null;
     return description['ref'];
   }
 
-  /**
-   * Returns [description] if it's a description, or [PackageId.description] if
-   * it's a [PackageId].
-   */
+  /// Returns [description] if it's a description, or [PackageId.description] if
+  /// it's a [PackageId].
   _getDescription(description) {
     if (description is PackageId) return description.description;
     return description;
diff --git a/utils/pub/hosted_source.dart b/utils/pub/hosted_source.dart
index ba5119d..4b515ac 100644
--- a/utils/pub/hosted_source.dart
+++ b/utils/pub/hosted_source.dart
@@ -10,6 +10,7 @@
 
 // TODO(nweiz): Make this import better.
 import '../../pkg/http/lib/http.dart' as http;
+import 'http.dart';
 import 'io.dart';
 import 'log.dart' as log;
 import 'package.dart';
@@ -19,23 +20,17 @@
 import 'utils.dart';
 import 'version.dart';
 
-/**
- * A package source that installs packages from a package hosting site that
- * uses the same API as pub.dartlang.org.
- */
+/// A package source that installs packages from a package hosting site that
+/// uses the same API as pub.dartlang.org.
 class HostedSource extends Source {
   final name = "hosted";
   final shouldCache = true;
 
-  /**
-   * The URL of the default package repository.
-   */
+  /// The URL of the default package repository.
   static final defaultUrl = "http://pub.dartlang.org";
 
-  /**
-   * Downloads a list of all versions of a package that are available from the
-   * site.
-   */
+  /// Downloads a list of all versions of a package that are available from the
+  /// site.
   Future<List<Version>> getVersions(String name, description) {
     var parsed = _parseDescription(description);
     var fullUrl = "${parsed.last}/packages/${parsed.first}.json";
@@ -48,10 +43,8 @@
     });
   }
 
-  /**
-   * Downloads and parses the pubspec for a specific version of a package that
-   * is available from the site.
-   */
+  /// Downloads and parses the pubspec for a specific version of a package that
+  /// is available from the site.
   Future<Pubspec> describe(PackageId id) {
     var parsed = _parseDescription(id.description);
     var fullUrl = "${parsed.last}/packages/${parsed.first}/versions/"
@@ -64,9 +57,7 @@
     });
   }
 
-  /**
-   * Downloads a package from the site and unpacks it.
-   */
+  /// Downloads a package from the site and unpacks it.
   Future<bool> install(PackageId id, String destPath) {
     var parsedDescription = _parseDescription(id.description);
     var name = parsedDescription.first;
@@ -94,12 +85,10 @@
     }).transform((_) => true);
   }
 
-  /**
-   * The system cache directory for the hosted source contains subdirectories
-   * for each separate repository URL that's used on the system. Each of these
-   * subdirectories then contains a subdirectory for each package installed
-   * from that site.
-   */
+  /// The system cache directory for the hosted source contains subdirectories
+  /// for each separate repository URL that's used on the system. Each of these
+  /// subdirectories then contains a subdirectory for each package installed
+  /// from that site.
   String systemCacheDirectory(PackageId id) {
     var parsed = _parseDescription(id.description);
     var url = parsed.last.replaceAll(new RegExp(r"^https?://"), "");
@@ -114,13 +103,11 @@
   bool descriptionsEqual(description1, description2) =>
       _parseDescription(description1) == _parseDescription(description2);
 
-  /**
-   * Ensures that [description] is a valid hosted package description.
-   *
-   * There are two valid formats. A plain string refers to a package with the
-   * given name from the default host, while a map with keys "name" and "url"
-   * refers to a package with the given name from the host at the given URL.
-   */
+  /// Ensures that [description] is a valid hosted package description.
+  ///
+  /// There are two valid formats. A plain string refers to a package with the
+  /// given name from the default host, while a map with keys "name" and "url"
+  /// refers to a package with the given name from the host at the given URL.
   void validateDescription(description, {bool fromLockFile: false}) {
     _parseDescription(description);
   }
@@ -146,12 +133,10 @@
     throw ex;
   }
 
-  /**
-   * Parses the description for a package.
-   *
-   * If the package parses correctly, this returns a (name, url) pair. If not,
-   * this throws a descriptive FormatException.
-   */
+  /// Parses the description for a package.
+  ///
+  /// If the package parses correctly, this returns a (name, url) pair. If not,
+  /// this throws a descriptive FormatException.
   Pair<String, String> _parseDescription(description) {
     if (description is String) {
       return new Pair<String, String>(description, defaultUrl);
diff --git a/utils/pub/http.dart b/utils/pub/http.dart
new file mode 100644
index 0000000..0665c35
--- /dev/null
+++ b/utils/pub/http.dart
@@ -0,0 +1,134 @@
+// 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.
+
+/// Helpers for dealing with HTTP.
+library pub.http;
+
+import 'dart:io';
+import 'dart:json';
+
+// TODO(nweiz): Make this import better.
+import '../../pkg/http/lib/http.dart' as http;
+import 'curl_client.dart';
+import 'io.dart';
+import 'log.dart' as log;
+
+// TODO(nweiz): make this configurable
+/// The amount of time in milliseconds to allow HTTP requests before assuming
+/// they've failed.
+final HTTP_TIMEOUT = 30 * 1000;
+
+/// An HTTP client that transforms 40* errors and socket exceptions into more
+/// user-friendly error messages.
+class PubHttpClient extends http.BaseClient {
+  http.Client inner;
+
+  PubHttpClient([http.Client inner])
+    : 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.
+
+    // TODO(nweiz): remove this when issue 4061 is fixed.
+    var stackTrace;
+    try {
+      throw null;
+    } catch (_, localStackTrace) {
+      stackTrace = localStackTrace;
+    }
+
+    // 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).chain((streamedResponse) {
+      log.fine("Got response ${streamedResponse.statusCode} "
+               "${streamedResponse.reasonPhrase}.");
+
+      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 new Future.immediate(streamedResponse);
+      }
+
+      return http.Response.fromStream(streamedResponse).transform((response) {
+        throw new PubHttpException(response);
+      });
+    }).transformException((e) {
+      if (e is SocketIOException &&
+          e.osError != null &&
+          (e.osError.errorCode == 8 ||
+           e.osError.errorCode == -2 ||
+           e.osError.errorCode == -5 ||
+           e.osError.errorCode == 11004)) {
+        throw 'Could not resolve URL "${request.url.origin}".';
+      }
+      throw e;
+    }), HTTP_TIMEOUT, 'fetching URL "${request.url}"');
+  }
+}
+
+/// The HTTP client to use for all HTTP requests.
+final httpClient = new PubHttpClient();
+
+final curlClient = new PubHttpClient(new CurlClient());
+
+/// Handles a successful JSON-formatted response from pub.dartlang.org.
+///
+/// These responses are expected to be of the form `{"success": {"message":
+/// "some message"}}`. If the format is correct, the message will be printed;
+/// otherwise an error will be raised.
+void handleJsonSuccess(http.Response response) {
+  var parsed = parseJsonResponse(response);
+  if (parsed['success'] is! Map ||
+      !parsed['success'].containsKey('message') ||
+      parsed['success']['message'] is! String) {
+    invalidServerResponse(response);
+  }
+  log.message(parsed['success']['message']);
+}
+
+/// Handles an unsuccessful JSON-formatted response from pub.dartlang.org.
+///
+/// These responses are expected to be of the form `{"error": {"message": "some
+/// message"}}`. If the format is correct, the message will be raised as an
+/// error; otherwise an [invalidServerResponse] error will be raised.
+void handleJsonError(http.Response response) {
+  var errorMap = parseJsonResponse(response);
+  if (errorMap['error'] is! Map ||
+      !errorMap['error'].containsKey('message') ||
+      errorMap['error']['message'] is! String) {
+    invalidServerResponse(response);
+  }
+  throw errorMap['error']['message'];
+}
+
+/// Parses a response body, assuming it's JSON-formatted. Throws a user-friendly
+/// error if the response body is invalid JSON, or if it's not a map.
+Map parseJsonResponse(http.Response response) {
+  var value;
+  try {
+    value = JSON.parse(response.body);
+  } catch (e) {
+    // TODO(nweiz): narrow this catch clause once issue 6775 is fixed.
+    invalidServerResponse(response);
+  }
+  if (value is! Map) invalidServerResponse(response);
+  return value;
+}
+
+/// Throws an error describing an invalid response from the server.
+void invalidServerResponse(http.Response response) {
+  throw 'Invalid server response:\n${response.body}';
+}
+
+/// Exception thrown when an HTTP operation fails.
+class PubHttpException implements Exception {
+  final http.Response response;
+
+  const PubHttpException(this.response);
+
+  String toString() => 'HTTP error ${response.statusCode}: '
+      '${response.reasonPhrase}';
+}
diff --git a/utils/pub/io.dart b/utils/pub/io.dart
index 39a854d..8b53575 100644
--- a/utils/pub/io.dart
+++ b/utils/pub/io.dart
@@ -2,20 +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.
 
-/**
- * Helper functionality to make working with IO easier.
- */
+/// Helper functionality to make working with IO easier.
 library io;
 
 import 'dart:io';
 import 'dart:isolate';
+import 'dart:json';
 import 'dart:uri';
 
-// TODO(nweiz): Make this import better.
-import '../../pkg/http/lib/http.dart' as http;
-import 'curl_client.dart';
+import '../../pkg/path/lib/path.dart' as path;
 import 'log.dart' as log;
-import 'path.dart' as path;
 import 'utils.dart';
 
 bool _isGitInstalledCache;
@@ -25,11 +21,9 @@
 
 final NEWLINE_PATTERN = new RegExp("\r\n?|\n\r?");
 
-/**
- * Joins a number of path string parts into a single path. Handles
- * platform-specific path separators. Parts can be [String], [Directory], or
- * [File] objects.
- */
+/// Joins a number of path string parts into a single path. Handles
+/// platform-specific path separators. Parts can be [String], [Directory], or
+/// [File] objects.
 String join(part1, [part2, part3, part4, part5, part6, part7, part8]) {
   var parts = [part1, part2, part3, part4, part5, part6, part7, part8]
       .map((part) => part == null ? null : _getPath(part));
@@ -59,11 +53,9 @@
 /// Returns the path to [target] from [base].
 String relativeTo(target, base) => path.relative(target, from: base);
 
-/**
- * Asynchronously determines if [path], which can be a [String] file path, a
- * [File], or a [Directory] exists on the file system. Returns a [Future] that
- * completes with the result.
- */
+/// Asynchronously determines if [path], which can be a [String] file path, a
+/// [File], or a [Directory] exists on the file system. Returns a [Future] that
+/// completes with the result.
 Future<bool> exists(path) {
   path = _getPath(path);
   return Futures.wait([fileExists(path), dirExists(path)]).transform((results) {
@@ -71,11 +63,9 @@
   });
 }
 
-/**
- * Asynchronously determines if [file], which can be a [String] file path or a
- * [File], exists on the file system. Returns a [Future] that completes with
- * the result.
- */
+/// Asynchronously determines if [file], which can be a [String] file path or a
+/// [File], exists on the file system. Returns a [Future] that completes with
+/// the result.
 Future<bool> fileExists(file) {
   var path = _getPath(file);
   return log.ioAsync("Seeing if file $path exists.",
@@ -83,10 +73,8 @@
       (exists) => "File $path ${exists ? 'exists' : 'does not exist'}.");
 }
 
-/**
- * Reads the contents of the text file [file], which can either be a [String] or
- * a [File].
- */
+/// Reads the contents of the text file [file], which can either be a [String]
+/// or a [File].
 Future<String> readTextFile(file) {
   var path = _getPath(file);
   return log.ioAsync("Reading text file $path.",
@@ -101,17 +89,17 @@
       });
 }
 
-/**
- * Creates [file] (which can either be a [String] or a [File]), and writes
- * [contents] to it. Completes when the file is written and closed.
- */
-Future<File> writeTextFile(file, String contents) {
+/// Creates [file] (which can either be a [String] or a [File]), and writes
+/// [contents] to it. Completes when the file is written and closed.
+///
+/// If [dontLogContents] is true, the contents of the file will never be logged.
+Future<File> writeTextFile(file, String contents, {dontLogContents: false}) {
   var path = _getPath(file);
   file = new File(path);
 
   // Sanity check: don't spew a huge file.
   log.io("Writing ${contents.length} characters to text file $path.");
-  if (contents.length < 1024 * 1024) {
+  if (!dontLogContents && contents.length < 1024 * 1024) {
     log.fine("Contents:\n$contents");
   }
 
@@ -125,10 +113,8 @@
   });
 }
 
-/**
- * Asynchronously deletes [file], which can be a [String] or a [File]. Returns a
- * [Future] that completes when the deletion is done.
- */
+/// Asynchronously deletes [file], which can be a [String] or a [File]. Returns
+/// a [Future] that completes when the deletion is done.
 Future<File> deleteFile(file) {
   var path = _getPath(file);
   return log.ioAsync("delete file $path",
@@ -175,21 +161,17 @@
   return completer.future;
 }
 
-/**
- * Creates a directory [dir]. Returns a [Future] that completes when the
- * directory is created.
- */
+/// Creates a directory [dir]. Returns a [Future] that completes when the
+/// directory is created.
 Future<Directory> createDir(dir) {
   dir = _getDirectory(dir);
   return log.ioAsync("create directory ${dir.path}",
       dir.create());
 }
 
-/**
- * Ensures that [path] and all its parent directories exist. If they don't
- * exist, creates them. Returns a [Future] that completes once all the
- * directories are created.
- */
+/// Ensures that [path] and all its parent directories exist. If they don't
+/// exist, creates them. Returns a [Future] that completes once all the
+/// directories are created.
 Future<Directory> ensureDir(path) {
   path = _getPath(path);
   log.fine("Ensuring directory $path exists.");
@@ -222,22 +204,18 @@
   });
 }
 
-/**
- * Creates a temp directory whose name will be based on [dir] with a unique
- * suffix appended to it. If [dir] is not provided, a temp directory will be
- * created in a platform-dependent temporary location. Returns a [Future] that
- * completes when the directory is created.
- */
+/// Creates a temp directory whose name will be based on [dir] with a unique
+/// suffix appended to it. If [dir] is not provided, a temp directory will be
+/// created in a platform-dependent temporary location. Returns a [Future] that
+/// completes when the directory is created.
 Future<Directory> createTempDir([dir = '']) {
   dir = _getDirectory(dir);
   return log.ioAsync("create temp directory ${dir.path}",
       dir.createTemp());
 }
 
-/**
- * Asynchronously recursively deletes [dir], which can be a [String] or a
- * [Directory]. Returns a [Future] that completes when the deletion is done.
- */
+/// Asynchronously recursively deletes [dir], which can be a [String] or a
+/// [Directory]. Returns a [Future] that completes when the deletion is done.
 Future<Directory> deleteDir(dir) {
   dir = _getDirectory(dir);
 
@@ -245,57 +223,81 @@
       dir.delete(recursive: true)));
 }
 
-/**
- * Asynchronously lists the contents of [dir], which can be a [String] directory
- * path or a [Directory]. If [recursive] is `true`, lists subdirectory contents
- * (defaults to `false`). If [includeHiddenFiles] is `true`, includes files and
- * directories beginning with `.` (defaults to `false`).
- */
+/// Asynchronously lists the contents of [dir], which can be a [String]
+/// directory path or a [Directory]. If [recursive] is `true`, lists
+/// subdirectory contents (defaults to `false`). If [includeHiddenFiles] is
+/// `true`, includes files and directories beginning with `.` (defaults to
+/// `false`).
+///
+/// If [dir] is a string, the returned paths are guaranteed to begin with it.
 Future<List<String>> listDir(dir,
     {bool recursive: false, bool includeHiddenFiles: false}) {
-  final completer = new Completer<List<String>>();
-  final contents = <String>[];
+  Future<List<String>> doList(Directory dir, Set<String> listedDirectories) {
+    var contents = <String>[];
+    var completer = new Completer<List<String>>();
 
-  dir = _getDirectory(dir);
-  log.io("Listing directory ${dir.path}.");
-  var lister = dir.list(recursive: recursive);
-
-  lister.onDone = (done) {
-    // TODO(rnystrom): May need to sort here if it turns out onDir and onFile
-    // aren't guaranteed to be called in a certain order. So far, they seem to.
-    if (done) {
-      log.fine("Listed directory ${dir.path}:\n"
-                "${Strings.join(contents, '\n')}");
-      completer.complete(contents);
+    // Avoid recursive symlinks.
+    var resolvedPath = new File(dir.path).fullPathSync();
+    if (listedDirectories.contains(resolvedPath)) {
+      return new Future.immediate([]);
     }
-  };
+    listedDirectories = new Set<String>.from(listedDirectories);
+    listedDirectories.add(resolvedPath);
 
-  // TODO(nweiz): remove this when issue 4061 is fixed.
-  var stackTrace;
-  try {
-    throw "";
-  } catch (_, localStackTrace) {
-    stackTrace = localStackTrace;
+    log.io("Listing directory ${dir.path}.");
+    var lister = dir.list();
+
+    lister.onDone = (done) {
+      // TODO(rnystrom): May need to sort here if it turns out onDir and onFile
+      // aren't guaranteed to be called in a certain order. So far, they seem to.
+      if (done) {
+        log.fine("Listed directory ${dir.path}:\n"
+                  "${Strings.join(contents, '\n')}");
+        completer.complete(contents);
+      }
+    };
+
+    // TODO(nweiz): remove this when issue 4061 is fixed.
+    var stackTrace;
+    try {
+      throw "";
+    } catch (_, localStackTrace) {
+      stackTrace = localStackTrace;
+    }
+
+    var children = [];
+    lister.onError = (error) => completer.completeException(error, stackTrace);
+    lister.onDir = (file) {
+      if (!includeHiddenFiles && basename(file).startsWith('.')) return;
+      file = join(dir, basename(file));
+      contents.add(file);
+
+      // TODO(nweiz): don't manually recurse once issue 7358 is fixed. Note that
+      // once we remove the manual recursion, we'll need to explicitly filter
+      // out files in hidden directories.
+      if (recursive) {
+        children.add(doList(new Directory(file), listedDirectories));
+      }
+    };
+    lister.onFile = (file) {
+      if (!includeHiddenFiles && basename(file).startsWith('.')) return;
+      contents.add(join(dir, basename(file)));
+    };
+
+    return completer.future.chain((contents) {
+      return Futures.wait(children).transform((childContents) {
+        contents.addAll(flatten(childContents));
+        return contents;
+      });
+    });
   }
 
-  lister.onError = (error) => completer.completeException(error, stackTrace);
-  lister.onDir = (file) {
-    if (!includeHiddenFiles && basename(file).startsWith('.')) return;
-    contents.add(file);
-  };
-  lister.onFile = (file) {
-    if (!includeHiddenFiles && basename(file).startsWith('.')) return;
-    contents.add(file);
-  };
-
-  return completer.future;
+  return doList(_getDirectory(dir), new Set<String>());
 }
 
-/**
- * Asynchronously determines if [dir], which can be a [String] directory path
- * or a [Directory], exists on the file system. Returns a [Future] that
- * completes with the result.
- */
+/// Asynchronously determines if [dir], which can be a [String] directory path
+/// or a [Directory], exists on the file system. Returns a [Future] that
+/// completes with the result.
 Future<bool> dirExists(dir) {
   dir = _getDirectory(dir);
   return log.ioAsync("Seeing if directory ${dir.path} exists.",
@@ -304,11 +306,9 @@
                   "${exists ? 'exists' : 'does not exist'}.");
 }
 
-/**
- * "Cleans" [dir]. If that directory already exists, it will be deleted. Then a
- * new empty directory will be created. Returns a [Future] that completes when
- * the new clean directory is created.
- */
+/// "Cleans" [dir]. If that directory already exists, it will be deleted. Then a
+/// new empty directory will be created. Returns a [Future] that completes when
+/// the new clean directory is created.
 Future<Directory> cleanDir(dir) {
   return dirExists(dir).chain((exists) {
     if (exists) {
@@ -363,11 +363,9 @@
   return makeAttempt(null);
 }
 
-/**
- * Creates a new symlink that creates an alias from [from] to [to], both of
- * which can be a [String], [File], or [Directory]. Returns a [Future] which
- * completes to the symlink file (i.e. [to]).
- */
+/// Creates a new symlink that creates an alias from [from] to [to], both of
+/// which can be a [String], [File], or [Directory]. Returns a [Future] which
+/// completes to the symlink file (i.e. [to]).
 Future<File> createSymlink(from, to) {
   from = _getPath(from);
   to = _getPath(to);
@@ -393,13 +391,11 @@
   });
 }
 
-/**
- * Creates a new symlink that creates an alias from the `lib` directory of
- * package [from] to [to], both of which can be a [String], [File], or
- * [Directory]. Returns a [Future] which completes to the symlink file (i.e.
- * [to]). If [from] does not have a `lib` directory, this shows a warning if
- * appropriate and then does nothing.
- */
+/// Creates a new symlink that creates an alias from the `lib` directory of
+/// package [from] to [to], both of which can be a [String], [File], or
+/// [Directory]. Returns a [Future] which completes to the symlink file (i.e.
+/// [to]). If [from] does not have a `lib` directory, this shows a warning if
+/// appropriate and then does nothing.
 Future<File> createPackageSymlink(String name, from, to,
     {bool isSelfLink: false}) {
   // See if the package has a "lib" directory.
@@ -500,73 +496,9 @@
   return completer.future;
 }
 
-// TODO(nweiz): make this configurable
-/**
- * The amount of time in milliseconds to allow HTTP requests before assuming
- * they've failed.
- */
-final HTTP_TIMEOUT = 30 * 1000;
-
-/// An HTTP client that transforms 40* errors and socket exceptions into more
-/// user-friendly error messages.
-class PubHttpClient extends http.BaseClient {
-  final http.Client _inner;
-
-  PubHttpClient([http.Client inner])
-    : _inner = inner == null ? new http.Client() : inner;
-
-  Future<http.StreamedResponse> send(http.BaseRequest request) {
-    log.io("Sending HTTP request $request.");
-    // TODO(rnystrom): Log request body when it's available and plaintext.
-
-    // TODO(nweiz): remove this when issue 4061 is fixed.
-    var stackTrace;
-    try {
-      throw null;
-    } catch (_, localStackTrace) {
-      stackTrace = localStackTrace;
-    }
-
-    // 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).chain((streamedResponse) {
-      log.fine("Got response ${streamedResponse.statusCode} "
-               "${streamedResponse.reasonPhrase}.");
-
-      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 new Future.immediate(streamedResponse);
-      }
-
-      return http.Response.fromStream(streamedResponse).transform((response) {
-        throw new PubHttpException(response);
-      });
-    }).transformException((e) {
-      if (e is SocketIOException &&
-          e.osError != null &&
-          (e.osError.errorCode == 8 ||
-           e.osError.errorCode == -2 ||
-           e.osError.errorCode == -5 ||
-           e.osError.errorCode == 11004)) {
-        throw 'Could not resolve URL "${request.url.origin}".';
-      }
-      throw e;
-    }), HTTP_TIMEOUT, 'fetching URL "${request.url}"');
-  }
-}
-
-/// The HTTP client to use for all HTTP requests.
-final httpClient = new PubHttpClient();
-
-final curlClient = new PubHttpClient(new CurlClient());
-
-/**
- * Takes all input from [source] and writes it to [sink].
- *
- * Returns a future that completes when [source] is closed.
- */
+/// Takes all input from [source] and writes it to [sink].
+///
+/// Returns a future that completes when [source] is closed.
 Future pipeInputToInput(InputStream source, ListInputStream sink) {
   var completer = new Completer();
   source.onClosed = () {
@@ -590,9 +522,7 @@
   return completer.future;
 }
 
-/**
- * Buffers all input from an InputStream and returns it as a future.
- */
+/// Buffers all input from an InputStream and returns it as a future.
 Future<List<int>> consumeInputStream(InputStream stream) {
   if (stream.closed) return new Future.immediate(<int>[]);
 
@@ -732,16 +662,14 @@
   return fn(executable, args, options);
 }
 
-/**
- * Wraps [input] to provide a timeout. If [input] completes before
- * [milliseconds] have passed, then the return value completes in the same way.
- * However, if [milliseconds] pass before [input] has completed, it completes
- * with a [TimeoutException] with [description] (which should be a fragment
- * describing the action that timed out).
- *
- * Note that timing out will not cancel the asynchronous operation behind
- * [input].
- */
+/// Wraps [input] to provide a timeout. If [input] completes before
+/// [milliseconds] have passed, then the return value completes in the same way.
+/// However, if [milliseconds] pass before [input] has completed, it completes
+/// with a [TimeoutException] with [description] (which should be a fragment
+/// describing the action that timed out).
+///
+/// Note that timing out will not cancel the asynchronous operation behind
+/// [input].
 Future timeout(Future input, int milliseconds, String description) {
   var completer = new Completer();
   var timer = new Timer(milliseconds, (_) {
@@ -841,10 +769,8 @@
   return completer.future;
 }
 
-/**
- * Extracts a `.tar.gz` file from [stream] to [destination], which can be a
- * directory or a path. Returns whether or not the extraction was successful.
- */
+/// Extracts a `.tar.gz` file from [stream] to [destination], which can be a
+/// directory or a path. Returns whether or not the extraction was successful.
 Future<bool> extractTarGz(InputStream stream, destination) {
   destination = _getPath(destination);
 
@@ -1010,21 +936,7 @@
   return stream;
 }
 
-/**
- * Exception thrown when an HTTP operation fails.
- */
-class PubHttpException implements Exception {
-  final http.Response response;
-
-  const PubHttpException(this.response);
-
-  String toString() => 'HTTP error ${response.statusCode}: '
-      '${response.reasonPhrase}';
-}
-
-/**
- * Exception thrown when an operation times out.
- */
+/// Exception thrown when an operation times out.
 class TimeoutException implements Exception {
   final String message;
 
@@ -1033,9 +945,7 @@
   String toString() => message;
 }
 
-/**
- * Contains the results of invoking a [Process] and waiting for it to complete.
- */
+/// Contains the results of invoking a [Process] and waiting for it to complete.
 class PubProcessResult {
   final List<String> stdout;
   final List<String> stderr;
@@ -1046,11 +956,9 @@
   bool get success => exitCode == 0;
 }
 
-/**
- * Gets the path string for [entry], which can either already be a path string,
- * or be a [File] or [Directory]. Allows working generically with "file-like"
- * objects.
- */
+/// Gets the path string for [entry], which can either already be a path string,
+/// or be a [File] or [Directory]. Allows working generically with "file-like"
+/// objects.
 String _getPath(entry) {
   if (entry is String) return entry;
   if (entry is File) return entry.name;
@@ -1058,18 +966,14 @@
   throw 'Entry $entry is not a supported type.';
 }
 
-/**
- * Gets a [Directory] for [entry], which can either already be one, or be a
- * [String].
- */
+/// Gets a [Directory] for [entry], which can either already be one, or be a
+/// [String].
 Directory _getDirectory(entry) {
   if (entry is Directory) return entry;
   return new Directory(entry);
 }
 
-/**
- * Gets a [Uri] for [uri], which can either already be one, or be a [String].
- */
+/// Gets a [Uri] for [uri], which can either already be one, or be a [String].
 Uri _getUri(uri) {
   if (uri is Uri) return uri;
   return new Uri.fromString(uri);
diff --git a/utils/pub/lock_file.dart b/utils/pub/lock_file.dart
index d87ff08..80036b8 100644
--- a/utils/pub/lock_file.dart
+++ b/utils/pub/lock_file.dart
@@ -11,13 +11,9 @@
 import 'version.dart';
 import 'yaml/yaml.dart';
 
-/**
- * A parsed and validated `pubspec.lock` file.
- */
+/// A parsed and validated `pubspec.lock` file.
 class LockFile {
-  /**
-   * The packages this lockfile pins.
-   */
+  /// The packages this lockfile pins.
   Map<String, PackageId> packages;
 
   LockFile._(this.packages);
@@ -25,9 +21,7 @@
   LockFile.empty()
     : packages = <String, PackageId>{};
 
-  /**
-   * Parses the lockfile whose text is [contents].
-   */
+  /// Parses the lockfile whose text is [contents].
   factory LockFile.parse(String contents, SourceRegistry sources) {
     var packages = <String, PackageId>{};
 
@@ -78,9 +72,7 @@
     return new LockFile._(packages);
   }
 
-  /**
-   * Returns the serialized YAML text of the lock file.
-   */
+  /// Returns the serialized YAML text of the lock file.
   String serialize() {
     var packagesObj = <String, Map>{};
     packages.forEach((name, id) {
diff --git a/utils/pub/oauth2.dart b/utils/pub/oauth2.dart
index 78cd4c2..378614b 100644
--- a/utils/pub/oauth2.dart
+++ b/utils/pub/oauth2.dart
@@ -9,6 +9,7 @@
 
 // TODO(nweiz): Make this a "package:" URL, or something nicer than this.
 import '../../pkg/oauth2/lib/oauth2.dart';
+import 'http.dart';
 import 'io.dart';
 import 'log.dart' as log;
 import 'system_cache.dart';
@@ -62,7 +63,8 @@
 /// the [Future] returned by [fn] completes.
 ///
 /// This takes care of loading and saving the client's credentials, as well as
-/// prompting the user for their authorization.
+/// prompting the user for their authorization. It will also re-authorize and
+/// re-run [fn] if a recoverable authorization error is detected.
 Future withClient(SystemCache cache, Future fn(Client client)) {
   return _getClient(cache).chain((client) {
     var completer = new Completer();
@@ -82,6 +84,19 @@
       }
     });
     return completer.future;
+  }).transformException((e) {
+    if (e is ExpirationException) {
+      log.error("Pub's authorization to upload packages has expired and "
+          "can't be automatically refreshed.");
+      return withClient(cache, fn);
+    } else if (e is AuthorizationException) {
+      var message = "OAuth2 authorization failed";
+      if (e.description != null) message = "$message (${e.description})";
+      log.error("$message.");
+      return clearCredentials(cache).chain((_) => withClient(cache, fn));
+    } else {
+      throw e;
+    }
   });
 }
 
@@ -139,7 +154,7 @@
   _credentials = credentials;
   var path = _credentialsFile(cache);
   return ensureDir(dirname(path)).chain((_) =>
-      writeTextFile(path, credentials.toJson()));
+      writeTextFile(path, credentials.toJson(), dontLogContents: true));
 }
 
 /// The path to the file in which the user's OAuth2 credentials are stored.
@@ -199,4 +214,4 @@
     log.message('Successfully authorized.\n');
     return client;
   });
-}
\ No newline at end of file
+}
diff --git a/utils/pub/package.dart b/utils/pub/package.dart
index b8ee759..69b5483 100644
--- a/utils/pub/package.dart
+++ b/utils/pub/package.dart
@@ -10,15 +10,11 @@
 import 'source_registry.dart';
 import 'version.dart';
 
-/**
- * A named, versioned, unit of code and resource reuse.
- */
+/// A named, versioned, unit of code and resource reuse.
 class Package {
-  /**
-   * Loads the package whose root directory is [packageDir]. [name] is the
-   * expected name of that package (e.g. the name given in the dependency), or
-   * null if the package being loaded is the entrypoint package.
-   */
+  /// Loads the package whose root directory is [packageDir]. [name] is the
+  /// expected name of that package (e.g. the name given in the dependency), or
+  /// null if the package being loaded is the entrypoint package.
   static Future<Package> load(String name, String packageDir,
       SourceRegistry sources) {
     var pubspecPath = join(packageDir, 'pubspec.yaml');
@@ -41,84 +37,60 @@
     });
   }
 
-  /**
-   * The path to the directory containing the package.
-   */
+  /// The path to the directory containing the package.
   final String dir;
 
-  /**
-   * The name of the package.
-   */
+  /// The name of the package.
   String get name {
     if (pubspec.name != null) return pubspec.name;
     if (dir != null) return basename(dir);
     return null;
   }
 
-  /**
-   * The package's version.
-   */
+  /// The package's version.
   Version get version => pubspec.version;
 
-  /**
-   * The parsed pubspec associated with this package.
-   */
+  /// The parsed pubspec associated with this package.
   final Pubspec pubspec;
 
-  /**
-   * The ids of the packages that this package depends on. This is what is
-   * specified in the pubspec when this package depends on another.
-   */
+  /// The ids of the packages that this package depends on. This is what is
+  /// specified in the pubspec when this package depends on another.
   Collection<PackageRef> get dependencies => pubspec.dependencies;
 
-  /**
-   * Constructs a package with the given pubspec. The package will have no
-   * directory associated with it.
-   */
+  /// Constructs a package with the given pubspec. The package will have no
+  /// directory associated with it.
   Package.inMemory(this.pubspec)
     : dir = null;
 
-  /**
-   * Constructs a package. This should not be called directly. Instead, acquire
-   * packages from [load()].
-   */
+  /// Constructs a package. This should not be called directly. Instead, acquire
+  /// packages from [load()].
   Package._(this.dir, this.pubspec);
 
-  /**
-   * Returns a debug string for the package.
-   */
+  /// Returns a debug string for the package.
   String toString() => '$name $version ($dir)';
 }
 
-/**
- * An unambiguous resolved reference to a package. A package ID contains enough
- * information to correctly install the package.
- *
- * Note that it's possible for multiple distinct package IDs to point to
- * different directories that happen to contain identical packages. For example,
- * the same package may be available from multiple sources. As far as Pub is
- * concerned, those packages are different.
- */
+/// An unambiguous resolved reference to a package. A package ID contains enough
+/// information to correctly install the package.
+///
+/// Note that it's possible for multiple distinct package IDs to point to
+/// different directories that happen to contain identical packages. For
+/// example, the same package may be available from multiple sources. As far as
+/// Pub is concerned, those packages are different.
 class PackageId implements Comparable {
   /// The name of the package being identified.
   final String name;
 
-  /**
-   * The [Source] used to look up this package given its [description].
-   */
+  /// The [Source] used to look up this package given its [description].
   final Source source;
 
-  /**
-   * The package's version.
-   */
+  /// The package's version.
   final Version version;
 
-  /**
-   * The metadata used by the package's [source] to identify and locate it. It
-   * contains whatever [Source]-specific data it needs to be able to install
-   * the package. For example, the description of a git sourced package might
-   * by the URL "git://github.com/dart/uilib.git".
-   */
+  /// The metadata used by the package's [source] to identify and locate it. It
+  /// contains whatever [Source]-specific data it needs to be able to install
+  /// the package. For example, the description of a git sourced package might
+  /// by the URL "git://github.com/dart/uilib.git".
   final description;
 
   PackageId(this.name, this.source, this.version, this.description);
@@ -154,50 +126,36 @@
     return version.compareTo(other.version);
   }
 
-  /**
-   * Returns the pubspec for this package.
-   */
+  /// Returns the pubspec for this package.
   Future<Pubspec> describe() => source.describe(this);
 
-  /**
-   * Returns a future that completes to the resovled [PackageId] for this id.
-   */
+  /// Returns a future that completes to the resovled [PackageId] for this id.
   Future<PackageId> get resolved => source.resolveId(this);
 }
 
-/**
- * A reference to a package. Unlike a [PackageId], a PackageRef may not
- * unambiguously refer to a single package. It may describe a range of allowed
- * packages.
- */
+/// A reference to a package. Unlike a [PackageId], a PackageRef may not
+/// unambiguously refer to a single package. It may describe a range of allowed
+/// packages.
 class PackageRef {
   /// The name of the package being identified.
   final String name;
 
-  /**
-   * The [Source] used to look up the package.
-   */
+  /// The [Source] used to look up the package.
   final Source source;
 
-  /**
-   * The allowed package versions.
-   */
+  /// The allowed package versions.
   final VersionConstraint constraint;
 
-  /**
-   * The metadata used to identify the package being referenced. The
-   * interpretation of this will vary based on the [source].
-   */
+  /// The metadata used to identify the package being referenced. The
+  /// interpretation of this will vary based on the [source].
   final description;
 
   PackageRef(this.name, this.source, this.constraint, this.description);
 
   String toString() => "$name $constraint from $source ($description)";
 
-  /**
-   * Returns a [PackageId] generated from this [PackageRef] with the given
-   * concrete version.
-   */
+  /// Returns a [PackageId] generated from this [PackageRef] with the given
+  /// concrete version.
   PackageId atVersion(Version version) =>
     new PackageId(name, source, version, description);
 }
diff --git a/utils/pub/pub.dart b/utils/pub/pub.dart
index 835a09d..6fcecd9 100644
--- a/utils/pub/pub.dart
+++ b/utils/pub/pub.dart
@@ -2,25 +2,25 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/**
- * The main entrypoint for the pub command line application.
- */
+/// The main entrypoint for the pub command line application.
 library pub;
 
 import '../../pkg/args/lib/args.dart';
+import '../../pkg/path/lib/path.dart' as path;
 import 'dart:io';
 import 'dart:math';
+import 'http.dart';
 import 'io.dart';
 import 'command_help.dart';
 import 'command_install.dart';
 import 'command_lish.dart';
 import 'command_update.dart';
+import 'command_uploader.dart';
 import 'command_version.dart';
 import 'entrypoint.dart';
 import 'exit_codes.dart' as exit_codes;
 import 'log.dart' as log;
 import 'package.dart';
-import 'path.dart' as path;
 import 'pubspec.dart';
 import 'source.dart';
 import 'source_registry.dart';
@@ -30,15 +30,14 @@
 
 Version get pubVersion => new Version(0, 0, 0);
 
-/**
- * The commands that Pub understands.
- */
+/// The commands that Pub understands.
 Map<String, PubCommand> get pubCommands {
   var commands = {
     'help': new HelpCommand(),
     'install': new InstallCommand(),
     'publish': new LishCommand(),
     'update': new UpdateCommand(),
+    'uploader': new UploaderCommand(),
     'version': new VersionCommand()
   };
   for (var command in commands.values) {
@@ -49,10 +48,8 @@
   return commands;
 }
 
-/**
- * The parser for arguments that are global to Pub rather than specific to a
- * single command.
- */
+/// The parser for arguments that are global to Pub rather than specific to a
+/// single command.
 ArgParser get pubArgParser {
   var parser = new ArgParser();
   parser.addFlag('help', abbr: 'h', negatable: false,
@@ -141,7 +138,7 @@
   command.run(cache, globalOptions, commandArgs);
 }
 
-/** Displays usage information for the app. */
+/// Displays usage information for the app. 
 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();
@@ -187,14 +184,10 @@
 
   Entrypoint entrypoint;
 
-  /**
-   * A one-line description of this command.
-   */
+  /// A one-line description of this command.
   String get description;
 
-  /**
-   * How to invoke this command (e.g. `"pub install [package]"`).
-   */
+  /// How to invoke this command (e.g. `"pub install [package]"`).
   String get usage;
 
   /// Whether or not this command requires [entrypoint] to be defined. If false,
@@ -206,10 +199,8 @@
   /// documentation, but they will work when invoked on the command line.
   final aliases = const <String>[];
 
-  /**
-   * Override this to define command-specific options. The results will be made
-   * available in [commandOptions].
-   */
+  /// Override this to define command-specific options. The results will be made
+  /// available in [commandOptions].
   ArgParser get commandParser => new ArgParser();
 
   void run(SystemCache cache_, ArgResults globalOptions_,
@@ -285,14 +276,12 @@
     future.then((_) => exit(0));
   }
 
-  /**
-   * Override this to perform the specific command. Return a future that
-   * completes when the command is done or fails if the command fails. If the
-   * command is synchronous, it may return `null`.
-   */
+  /// Override this to perform the specific command. Return a future that
+  /// completes when the command is done or fails if the command fails. If the
+  /// command is synchronous, it may return `null`.
   Future onRun();
 
-  /** Displays usage information for this command. */
+  /// Displays usage information for this command. 
   void printUsage([String description]) {
     if (description == null) description = this.description;
 
diff --git a/utils/pub/pubspec.dart b/utils/pub/pubspec.dart
index 1ba4d06..8a1931d 100644
--- a/utils/pub/pubspec.dart
+++ b/utils/pub/pubspec.dart
@@ -11,23 +11,15 @@
 import 'version.dart';
 import 'yaml/yaml.dart';
 
-/**
- * The parsed and validated contents of a pubspec file.
- */
+/// The parsed and validated contents of a pubspec file.
 class Pubspec {
-  /**
-   * This package's name.
-   */
+  /// This package's name.
   final String name;
 
-  /**
-   * This package's version.
-   */
+  /// This package's version.
   final Version version;
 
-  /**
-   * The packages this package depends on.
-   */
+  /// The packages this package depends on.
   final List<PackageRef> dependencies;
 
   /// All pubspec fields. This includes the fields from which other properties
@@ -44,14 +36,12 @@
       dependencies = <PackageRef>[],
       fields = {};
 
-  /** Whether or not the pubspec has no contents. */
+  /// Whether or not the pubspec has no contents. 
   bool get isEmpty =>
     name == null && version == Version.none && dependencies.isEmpty;
 
-  /**
-   * Parses the pubspec whose text is [contents]. If the pubspec doesn't define
-   * version for itself, it defaults to [Version.none].
-   */
+  /// Parses the pubspec whose text is [contents]. If the pubspec doesn't define
+  /// version for itself, it defaults to [Version.none].
   factory Pubspec.parse(String contents, SourceRegistry sources) {
     var name = null;
     var version = Version.none;
@@ -190,4 +180,4 @@
   });
 
   return dependencies;
-}
\ No newline at end of file
+}
diff --git a/utils/pub/root_source.dart b/utils/pub/root_source.dart
index ebab17e..72e122e 100644
--- a/utils/pub/root_source.dart
+++ b/utils/pub/root_source.dart
@@ -8,12 +8,10 @@
 import 'pubspec.dart';
 import 'source.dart';
 
-/**
- * A source used only for the root package when doing version resolution. It
- * contains only the root package and is unable to install packages.
- *
- * This source cannot be referenced from a pubspec.
- */
+/// A source used only for the root package when doing version resolution. It
+/// contains only the root package and is unable to install packages.
+///
+/// This source cannot be referenced from a pubspec.
 class RootSource extends Source {
   final String name = "root";
   final bool shouldCache = false;
diff --git a/utils/pub/source.dart b/utils/pub/source.dart
index b086475..637cdd6 100644
--- a/utils/pub/source.dart
+++ b/utils/pub/source.dart
@@ -10,120 +10,98 @@
 import 'system_cache.dart';
 import 'version.dart';
 
-/**
- * A source from which to install packages.
- *
- * Each source has many packages that it looks up using [PackageId]s. The source
- * is responsible for installing these packages to the package cache.
- */
+/// A source from which to install packages.
+///
+/// Each source has many packages that it looks up using [PackageId]s. The
+/// source is responsible for installing these packages to the package cache.
 abstract class Source {
-  /**
-   * The name of the source. Should be lower-case, suitable for use in a
-   * filename, and unique accross all sources.
-   */
+  /// The name of the source. Should be lower-case, suitable for use in a
+  /// filename, and unique accross all sources.
   String get name;
 
   /// Whether or not this source is the default source.
   bool get isDefault => systemCache.sources.defaultSource == this;
 
-  /**
-   * Whether this source's packages should be cached in Pub's global cache
-   * directory.
-   *
-   * A source should be cached if it requires network access to retrieve
-   * packages. It doesn't need to be cached if all packages are available
-   * locally.
-   */
+  /// Whether this source's packages should be cached in Pub's global cache
+  /// directory.
+  ///
+  /// A source should be cached if it requires network access to retrieve
+  /// packages. It doesn't need to be cached if all packages are available
+  /// locally.
   bool get shouldCache;
 
-  /**
-   * The system cache with which this source is registered.
-   */
+  /// The system cache with which this source is registered.
   SystemCache get systemCache {
     assert(_systemCache != null);
     return _systemCache;
   }
 
-  /**
-   * The system cache variable. Set by [_bind].
-   */
+  /// The system cache variable. Set by [_bind].
   SystemCache _systemCache;
 
-  /**
-   * The root directory of this source's cache within the system cache.
-   *
-   * This shouldn't be overridden by subclasses.
-   */
+  /// The root directory of this source's cache within the system cache.
+  ///
+  /// This shouldn't be overridden by subclasses.
   String get systemCacheRoot => join(systemCache.rootDir, name);
 
-  /**
-   * Records the system cache to which this source belongs.
-   *
-   * This should only be called once for each source, by [SystemCache.register].
-   * It should not be overridden by base classes.
-   */
+  /// Records the system cache to which this source belongs.
+  ///
+  /// This should only be called once for each source, by
+  /// [SystemCache.register]. It should not be overridden by base classes.
   void bind(SystemCache systemCache) {
     assert(_systemCache == null);
     this._systemCache = systemCache;
   }
 
-  /**
-   * Get the list of all versions that exist for the package described by
-   * [description]. [name] is the expected name of the package.
-   *
-   * Note that this does *not* require the packages to be installed, which is
-   * the point. This is used during version resolution to determine which
-   * package versions are available to be installed (or already installed).
-   *
-   * By default, this assumes that each description has a single version and
-   * uses [describe] to get that version.
-   */
+  /// Get the list of all versions that exist for the package described by
+  /// [description]. [name] is the expected name of the package.
+  ///
+  /// Note that this does *not* require the packages to be installed, which is
+  /// the point. This is used during version resolution to determine which
+  /// package versions are available to be installed (or already installed).
+  ///
+  /// By default, this assumes that each description has a single version and
+  /// uses [describe] to get that version.
   Future<List<Version>> getVersions(String name, description) {
     return describe(new PackageId(name, this, Version.none, description))
       .transform((pubspec) => [pubspec.version]);
   }
 
-  /**
-   * Loads the (possibly remote) pubspec for the package version identified by
-   * [id]. This may be called for packages that have not yet been installed
-   * during the version resolution process.
-   *
-   * For cached sources, by default this uses [installToSystemCache] to get the
-   * pubspec. There is no default implementation for non-cached sources; they
-   * must implement it manually.
-   */
+  /// Loads the (possibly remote) pubspec for the package version identified by
+  /// [id]. This may be called for packages that have not yet been installed
+  /// during the version resolution process.
+  ///
+  /// For cached sources, by default this uses [installToSystemCache] to get the
+  /// pubspec. There is no default implementation for non-cached sources; they
+  /// must implement it manually.
   Future<Pubspec> describe(PackageId id) {
     if (!shouldCache) throw "Source $name must implement describe(id).";
     return installToSystemCache(id).transform((package) => package.pubspec);
   }
 
-  /**
-   * Installs the package identified by [id] to [path]. Returns a [Future] that
-   * completes when the installation was finished. The [Future] should resolve
-   * to true if the package was found in the source and false if it wasn't. For
-   * all other error conditions, it should complete with an exception.
-   *
-   * [path] is guaranteed not to exist, and its parent directory is guaranteed
-   * to exist.
-   *
-   * Note that [path] may be deleted. If re-installing a package that has
-   * already been installed would be costly or impossible,
-   * [installToSystemCache] should be implemented instead of [install].
-   *
-   * This doesn't need to be implemented if [installToSystemCache] is
-   * implemented.
-   */
+  /// Installs the package identified by [id] to [path]. Returns a [Future] that
+  /// completes when the installation was finished. The [Future] should resolve
+  /// to true if the package was found in the source and false if it wasn't. For
+  /// all other error conditions, it should complete with an exception.
+  ///
+  /// [path] is guaranteed not to exist, and its parent directory is guaranteed
+  /// to exist.
+  ///
+  /// Note that [path] may be deleted. If re-installing a package that has
+  /// already been installed would be costly or impossible,
+  /// [installToSystemCache] should be implemented instead of [install].
+  ///
+  /// This doesn't need to be implemented if [installToSystemCache] is
+  /// implemented.
   Future<bool> install(PackageId id, String path) {
     throw "Either install or installToSystemCache must be implemented for "
         "source $name.";
   }
 
-  /**
-   * Installs the package identified by [id] to the system cache. This is only
-   * called for sources with [shouldCache] set to true.
-   *
-   * By default, this uses [systemCacheDirectory] and [install].
-   */
+  /// Installs the package identified by [id] to the system cache. This is only
+  /// called for sources with [shouldCache] set to true.
+  ///
+  /// By default, this uses [systemCacheDirectory] and [install].
   Future<Package> installToSystemCache(PackageId id) {
     var path = systemCacheDirectory(id);
     return exists(path).chain((exists) {
@@ -135,61 +113,55 @@
     });
   }
 
-  /**
-   * Returns the directory in the system cache that the package identified by
-   * [id] should be installed to. This should return a path to a subdirectory of
-   * [systemCacheRoot].
-   *
-   * This doesn't need to be implemented if [shouldCache] is false, or if
-   * [installToSystemCache] is implemented.
-   */
-  String systemCacheDirectory(PackageId id) =>
-    join(systemCacheRoot, packageName(id.description));
+  /// Returns the directory in the system cache that the package identified by
+  /// [id] should be installed to. This should return a path to a subdirectory
+  /// of [systemCacheRoot].
+  ///
+  /// This doesn't need to be implemented if [shouldCache] is false, or if
+  /// [installToSystemCache] is implemented.
+  String systemCacheDirectory(PackageId id) {
+    throw 'Source.systemCacheDirectory must be implemented if shouldCache is '
+        'true and installToSystemCache is not implemented.';
+  }
 
-  /**
-   * When a [Pubspec] or [LockFile] is parsed, it reads in the description for
-   * each dependency. It is up to the dependency's [Source] to determine how
-   * that should be interpreted. This will be called during parsing to validate
-   * that the given [description] is well-formed according to this source. It
-   * should return if the description is valid, or throw a [FormatException] if
-   * not.
-   *
-   * [fromLockFile] is true when the description comes from a [LockFile], to
-   * allow the source to use lockfile-specific descriptions via [resolveId].
-   */
+  /// When a [Pubspec] or [LockFile] is parsed, it reads in the description for
+  /// each dependency. It is up to the dependency's [Source] to determine how
+  /// that should be interpreted. This will be called during parsing to validate
+  /// that the given [description] is well-formed according to this source. It
+  /// should return if the description is valid, or throw a [FormatException] if
+  /// not.
+  ///
+  /// [fromLockFile] is true when the description comes from a [LockFile], to
+  /// allow the source to use lockfile-specific descriptions via [resolveId].
   void validateDescription(description, {bool fromLockFile: false}) {}
 
-  /**
-   * Returns whether or not [description1] describes the same package as
-   * [description2] for this source. This method should be light-weight. It
-   * doesn't need to validate that either package exists.
-   *
-   * By default, just uses regular equality.
-   */
+  /// Returns whether or not [description1] describes the same package as
+  /// [description2] for this source. This method should be light-weight. It
+  /// doesn't need to validate that either package exists.
+  ///
+  /// By default, just uses regular equality.
   bool descriptionsEqual(description1, description2) =>
     description1 == description2;
 
-  /**
-   * For some sources, [PackageId]s can point to different chunks of code at
-   * different times. This takes such an [id] and returns a future that
-   * completes to a [PackageId] that will uniquely specify a single chunk of
-   * code forever.
-   *
-   * For example, [GitSource] might take an [id] with description
-   * `http://github.com/dart-lang/some-lib.git` and return an id with a
-   * description that includes the current commit of the Git repository.
-   *
-   * This will be called after the package identified by [id] is installed, so
-   * the source can use the installed package to determine information about the
-   * resolved id.
-   *
-   * The returned [PackageId] may have a description field that's invalid
-   * according to [validateDescription], although it must still be serializable
-   * to JSON and YAML. It must also be equal to [id] according to
-   * [descriptionsEqual].
-   *
-   * By default, this just returns [id].
-   */
+  /// For some sources, [PackageId]s can point to different chunks of code at
+  /// different times. This takes such an [id] and returns a future that
+  /// completes to a [PackageId] that will uniquely specify a single chunk of
+  /// code forever.
+  ///
+  /// For example, [GitSource] might take an [id] with description
+  /// `http://github.com/dart-lang/some-lib.git` and return an id with a
+  /// description that includes the current commit of the Git repository.
+  ///
+  /// This will be called after the package identified by [id] is installed, so
+  /// the source can use the installed package to determine information about
+  /// the resolved id.
+  ///
+  /// The returned [PackageId] may have a description field that's invalid
+  /// according to [validateDescription], although it must still be serializable
+  /// to JSON and YAML. It must also be equal to [id] according to
+  /// [descriptionsEqual].
+  ///
+  /// By default, this just returns [id].
   Future<PackageId> resolveId(PackageId id) => new Future.immediate(id);
 
   /// Returns the source's name.
diff --git a/utils/pub/source_registry.dart b/utils/pub/source_registry.dart
index 917e9a3..6bbcec2 100644
--- a/utils/pub/source_registry.dart
+++ b/utils/pub/source_registry.dart
@@ -6,27 +6,19 @@
 
 import 'source.dart';
 
-/**
- * A class that keeps track of [Source]s used for installing packages.
- */
+/// A class that keeps track of [Source]s used for installing packages.
 class SourceRegistry {
   final Map<String, Source> _map;
   Source _default;
 
-  /**
-   * Creates a new registry with no packages registered.
-   */
+  /// Creates a new registry with no packages registered.
   SourceRegistry() : _map = <String, Source>{};
 
-  /**
-   * Returns the default source, which is used when no source is specified.
-   */
+  /// Returns the default source, which is used when no source is specified.
   Source get defaultSource => _default;
 
-  /**
-   * Sets the default source. This takes a string, which must be the name of a
-   * registered source.
-   */
+  /// Sets the default source. This takes a string, which must be the name of a
+  /// registered source.
   void setDefault(String name) {
     if (!_map.containsKey(name)) {
       // TODO(nweiz): Real error-handling system
@@ -36,10 +28,8 @@
     _default = _map[name];
   }
 
-  /**
-   * Registers a new source. This source may not have the same name as a source
-   * that's already been registered.
-   */
+  /// Registers a new source. This source may not have the same name as a source
+  /// that's already been registered.
   void register(Source source) {
     if (_map.containsKey(source.name)) {
       // TODO(nweiz): Real error-handling system
@@ -49,15 +39,11 @@
     _map[source.name] = source;
   }
 
-  /**
-   * Returns `true` if there is a source named [name].
-   */
+  /// Returns `true` if there is a source named [name].
   bool contains(String name) => _map.containsKey(name);
 
-  /**
-   * Returns the source named [name]. Throws an error if no such source has been
-   * registered. If [name] is null, returns the default source.
-   */
+  /// Returns the source named [name]. Throws an error if no such source has
+  /// been registered. If [name] is null, returns the default source.
   Source operator[](String name) {
     if (name == null) {
       if (defaultSource != null) return defaultSource;
diff --git a/utils/pub/system_cache.dart b/utils/pub/system_cache.dart
index ce913e0..abd2348 100644
--- a/utils/pub/system_cache.dart
+++ b/utils/pub/system_cache.dart
@@ -18,34 +18,25 @@
 import 'utils.dart';
 import 'version.dart';
 
-/**
- * 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 cache.
- */
+/// 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
+/// cache.
 class SystemCache {
-  /**
-   * The root directory where this package cache is located.
-   */
+  /// The root directory where this package cache is located.
   final String rootDir;
 
   String get tempDir => join(rootDir, '_temp');
 
-  /**
-   * Packages which are currently being asynchronously installed to the cache.
-   */
+  /// Packages which are currently being asynchronously installed to the cache.
   final Map<PackageId, Future<Package>> _pendingInstalls;
 
-  /**
-   * The sources from which to install packages.
-   */
+  /// The sources from which to install packages.
   final SourceRegistry sources;
 
-  /**
-   * Creates a new package cache which is backed by the given directory on the
-   * user's file system.
-   */
+  /// Creates a new package cache which is backed by the given directory on the
+  /// user's file system.
   SystemCache(this.rootDir)
   : _pendingInstalls = new Map<PackageId, Future<Package>>(),
     sources = new SourceRegistry();
@@ -60,22 +51,18 @@
     return cache;
   }
 
-  /**
-   * Registers a new source. This source must not have the same name as a source
-   * that's already been registered.
-   */
+  /// Registers a new source. This source must not have the same name as a
+  /// source that's already been registered.
   void register(Source source) {
     source.bind(this);
     sources.register(source);
   }
 
-  /**
-   * Ensures that the package identified by [id] is installed to the cache,
-   * loads it, and returns it.
-   *
-   * It is an error to try installing a package from a source with `shouldCache
-   * == false` to the system cache.
-   */
+  /// Ensures that the package identified by [id] is installed to the cache,
+  /// loads it, and returns it.
+  ///
+  /// It is an error to try installing a package from a source with `shouldCache
+  /// == false` to the system cache.
   Future<Package> install(PackageId id) {
     if (!id.source.shouldCache) {
       throw new ArgumentError("Package $id is not cacheable.");
diff --git a/utils/pub/utils.dart b/utils/pub/utils.dart
index cdd989a..557e67d 100644
--- a/utils/pub/utils.dart
+++ b/utils/pub/utils.dart
@@ -2,16 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/**
- * Generic utility functions. Stuff that should possibly be in core.
- */
+/// Generic utility functions. Stuff that should possibly be in core.
 library utils;
 
 import 'dart:crypto';
 import 'dart:isolate';
 import 'dart:uri';
 
-/** A pair of values. */
+/// A pair of values.
 class Pair<E, F> {
   E first;
   F last;
@@ -29,7 +27,7 @@
 }
 
 // TODO(rnystrom): Move into String?
-/** Pads [source] to [length] by adding spaces at the end. */
+/// Pads [source] to [length] by adding spaces at the end.
 String padRight(String source, int length) {
   final result = new StringBuffer();
   result.add(source);
@@ -41,10 +39,8 @@
   return result.toString();
 }
 
-/**
- * Runs [fn] after [future] completes, whether it completes successfully or not.
- * Essentially an asynchronous `finally` block.
- */
+/// Runs [fn] after [future] completes, whether it completes successfully or
+/// not. Essentially an asynchronous `finally` block.
 always(Future future, fn()) {
   var completer = new Completer();
   future.then((_) => fn());
@@ -54,10 +50,8 @@
   });
 }
 
-/**
- * Flattens nested collections into a single list containing only non-list
- * elements.
- */
+/// Flattens nested collections into a single list containing only non-list
+/// elements.
 List flatten(Collection nested) {
   var result = [];
   helper(list) {
@@ -73,9 +67,7 @@
   return result;
 }
 
-/**
- * Asserts that [iter] contains only one element, and returns it.
- */
+/// Asserts that [iter] contains only one element, and returns it.
 only(Iterable iter) {
   var iterator = iter.iterator();
   assert(iterator.hasNext);
@@ -84,19 +76,16 @@
   return obj;
 }
 
-/**
- * Returns a set containing all elements in [minuend] that are not in
- * [subtrahend].
- */
+/// Returns a set containing all elements in [minuend] that are not in
+/// [subtrahend].
 Set setMinus(Collection minuend, Collection subtrahend) {
   var minuendSet = new Set.from(minuend);
   minuendSet.removeAll(subtrahend);
   return minuendSet;
 }
 
-/**
- * Replace each instance of [matcher] in [source] with the return value of [fn].
- */
+/// Replace each instance of [matcher] in [source] with the return value of
+/// [fn].
 String replace(String source, Pattern matcher, String fn(Match)) {
   var buffer = new StringBuffer();
   var start = 0;
@@ -109,9 +98,7 @@
   return buffer.toString();
 }
 
-/**
- * Returns whether or not [str] ends with [matcher].
- */
+/// Returns whether or not [str] ends with [matcher].
 bool endsWithPattern(String str, Pattern matcher) {
   for (var match in matcher.allMatches(str)) {
     if (match.end == str.length) return true;
@@ -119,15 +106,11 @@
   return false;
 }
 
-/**
- * Returns the hex-encoded sha1 hash of [source].
- */
+/// Returns the hex-encoded sha1 hash of [source].
 String sha1(String source) =>
   CryptoUtils.bytesToHex(new SHA1().update(source.charCodes).digest());
 
-/**
- * Returns a [Future] that completes in [milliseconds].
- */
+/// Returns a [Future] that completes in [milliseconds].
 Future sleep(int milliseconds) {
   var completer = new Completer();
   new Timer(milliseconds, completer.complete);
diff --git a/utils/pub/validator.dart b/utils/pub/validator.dart
index 5c0c850..63a2386 100644
--- a/utils/pub/validator.dart
+++ b/utils/pub/validator.dart
@@ -9,6 +9,8 @@
 import 'io.dart';
 import 'system_cache.dart';
 import 'utils.dart';
+import 'validator/dependency.dart';
+import 'validator/directory.dart';
 import 'validator/lib.dart';
 import 'validator/license.dart';
 import 'validator/name.dart';
@@ -44,7 +46,9 @@
       new LibValidator(entrypoint),
       new LicenseValidator(entrypoint),
       new NameValidator(entrypoint),
-      new PubspecFieldValidator(entrypoint)
+      new PubspecFieldValidator(entrypoint),
+      new DependencyValidator(entrypoint),
+      new DirectoryValidator(entrypoint)
     ];
 
     // TODO(nweiz): The sleep 0 here forces us to go async. This works around
diff --git a/utils/pub/validator/dependency.dart b/utils/pub/validator/dependency.dart
new file mode 100644
index 0000000..46cde9a
--- /dev/null
+++ b/utils/pub/validator/dependency.dart
@@ -0,0 +1,99 @@
+// 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 dependency_validator;
+
+import '../entrypoint.dart';
+import '../hosted_source.dart';
+import '../http.dart';
+import '../package.dart';
+import '../utils.dart';
+import '../validator.dart';
+import '../version.dart';
+
+/// A validator that validates a package's dependencies.
+class DependencyValidator extends Validator {
+  DependencyValidator(Entrypoint entrypoint)
+    : super(entrypoint);
+
+  Future validate() {
+    return Futures.forEach(entrypoint.root.pubspec.dependencies, (dependency) {
+      if (dependency.source is! HostedSource) {
+        return _warnAboutSource(dependency);
+      }
+
+      if (dependency.name == entrypoint.root.name) {
+        warnings.add('You don\'t need to explicitly depend on your own '
+                'package.\n'
+            'Pub enables "package:${entrypoint.root.name}" imports '
+                'implicitly.');
+        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') {
+        return _warnAboutConstraint(dependency);
+      }
+
+      return new Future.immediate(null);
+    });
+  }
+
+  /// Warn that dependencies should use the hosted source.
+  Future _warnAboutSource(PackageRef ref) {
+    return entrypoint.cache.sources['hosted']
+        .getVersions(ref.name, ref.name)
+        .transformException((e) => <Version>[])
+        .transform((versions) {
+      var constraint;
+      var primary = Version.primary(versions);
+      if (primary != null) {
+        constraint = _constraintForVersion(primary);
+      } else {
+        constraint = ref.constraint.toString();
+        if (!ref.constraint.isAny && ref.constraint is! Version) {
+          constraint = '"$constraint"';
+        }
+      }
+
+      warnings.add('Don\'t depend on "${ref.name}" from the ${ref.source.name} '
+              'source. Use the hosted source instead. For example:\n'
+          '\n'
+          'dependencies:\n'
+          '  ${ref.name}: $constraint\n'
+          '\n'
+          'Using the hosted source ensures that everyone can download your '
+              'package\'s dependencies along with your package.');
+    });
+  }
+
+  /// Warn that dependencies should have version constraints.
+  Future _warnAboutConstraint(PackageRef ref) {
+    return entrypoint.loadLockFile().transform((lockFile) {
+      var message = 'Your dependency on "${ref.name}" should have a version '
+          'constraint.';
+      var locked = lockFile.packages[ref.name];
+      if (locked != null) {
+        message = '$message For example:\n'
+          '\n'
+          'dependencies:\n'
+          '  ${ref.name}: ${_constraintForVersion(locked.version)}\n';
+      }
+      warnings.add("$message\n"
+          "Without a constraint, you're promising to support all future "
+          "versions of ${ref.name}.");
+    });
+  }
+
+  /// Returns the suggested version constraint for a dependency that was tested
+  /// against [version].
+  String _constraintForVersion(Version version) {
+    if (version.major != 0) return '">=$version <${version.major + 1}.0.0"';
+    return '">=$version <${version.major}.${version.minor}.'
+        '${version.patch + 1}"';
+  }
+}
diff --git a/utils/pub/validator/directory.dart b/utils/pub/validator/directory.dart
new file mode 100644
index 0000000..07ad933
--- /dev/null
+++ b/utils/pub/validator/directory.dart
@@ -0,0 +1,45 @@
+// 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 directory_validator;
+
+import '../entrypoint.dart';
+import '../io.dart';
+import '../validator.dart';
+
+/// A validator that validates a package's top-level directories.
+class DirectoryValidator extends Validator {
+  DirectoryValidator(Entrypoint entrypoint)
+    : super(entrypoint);
+
+  static final _PLURAL_NAMES = ["tools", "tests", "docs", "examples"];
+
+  Future validate() {
+    return listDir(entrypoint.root.dir).chain((dirs) {
+      return Futures.wait(dirs.map((dir) {
+        return dirExists(dir).transform((exists) {
+          if (!exists) return;
+
+          dir = basename(dir);
+          if (_PLURAL_NAMES.contains(dir)) {
+            // Cut off the "s"
+            var singularName = dir.substring(0, dir.length - 1);
+            warnings.add('Rename the top-level "$dir" directory to '
+                    '"$singularName".\n'
+                'The Pub layout convention is to use singular directory '
+                    'names.\n'
+                'Plural names won\'t be correctly identified by Pub and other '
+                    'tools.');
+          }
+
+          if (dir.contains(new RegExp(r"^samples?$"))) {
+            warnings.add('Rename the top-level "$dir" directory to "example".\n'
+                'This allows Pub to find your examples and create "packages" '
+                    'directories for them.\n');
+          }
+        });
+      }));
+    });
+  }
+}
diff --git a/utils/pub/validator/lib.dart b/utils/pub/validator/lib.dart
index 39b71af..b0dfbe5 100644
--- a/utils/pub/validator/lib.dart
+++ b/utils/pub/validator/lib.dart
@@ -29,13 +29,6 @@
         return new Future.immediate(null);
       }
 
-      // TODO(rnystrom): listDir() returns real file paths after symlinks are
-      // resolved. This means if libDir contains a symlink, the resulting paths
-      // won't appear to be within it, which confuses relativeTo(). Work around
-      // that here by making sure we have the real path to libDir. Remove this
-      // when #7346 is fixed.
-      libDir = new File(libDir).fullPathSync();
-
       return listDir(libDir).transform((files) {
         files = files.map((file) => relativeTo(file, libDir));
         if (files.isEmpty) {
diff --git a/utils/pub/validator/name.dart b/utils/pub/validator/name.dart
index 687cfc7..3d467c5 100644
--- a/utils/pub/validator/name.dart
+++ b/utils/pub/validator/name.dart
@@ -6,9 +6,9 @@
 
 import 'dart:io';
 
+import '../../../pkg/path/lib/path.dart' as path;
 import '../entrypoint.dart';
 import '../io.dart';
-import '../path.dart' as path;
 import '../validator.dart';
 
 /// Dart reserved words, from the Dart spec.
@@ -26,18 +26,35 @@
   Future validate() {
     _checkName(entrypoint.root.name, 'Package name "${entrypoint.root.name}"');
 
+    return _libraries.transform((libraries) {
+      for (var library in libraries) {
+        var libName = path.basenameWithoutExtension(library);
+        _checkName(libName, 'The name of "$library", "$libName",');
+      }
+
+      if (libraries.length == 1) {
+        var libName = path.basenameWithoutExtension(libraries[0]);
+        if (libName == entrypoint.root.name) return;
+        warnings.add('The name of "${libraries[0]}", "$libName", should match '
+            'the name of the package, "${entrypoint.root.name}".\n'
+            'This helps users know what library to import.');
+      }
+    });
+  }
+
+  /// Returns a list of all libraries in the current package as paths relative
+  /// to the package's root directory.
+  Future<List<String>> get _libraries {
     var libDir = join(entrypoint.root.dir, "lib");
     return dirExists(libDir).chain((libDirExists) {
       if (!libDirExists) return new Future.immediate([]);
       return listDir(libDir, recursive: true);
     }).transform((files) {
-      for (var file in files) {
-        file = relativeTo(file, libDir);
-        if (splitPath(file).contains("src")) continue;
-        if (path.extension(file) != '.dart') continue;
-        var libName = path.basenameWithoutExtension(file);
-        _checkName(libName, 'The name of "$file", "$libName",');
-      }
+      return files.map((file) => relativeTo(file, dirname(libDir)))
+          .filter((file) {
+        return !splitPath(file).contains("src") &&
+            path.extension(file) == '.dart';
+      });
     });
   }
 
diff --git a/utils/pub/version.dart b/utils/pub/version.dart
index 50174cc..f60ad19c 100644
--- a/utils/pub/version.dart
+++ b/utils/pub/version.dart
@@ -2,20 +2,18 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/**
- * Handles version numbers, following the [Semantic Versioning][semver] spec.
- *
- * [semver]: http://semver.org/
- */
+/// Handles version numbers, following the [Semantic Versioning][semver] spec.
+///
+/// [semver]: http://semver.org/
 library version;
 
 import 'dart:math';
 
 import 'utils.dart';
 
-/** A parsed semantic version number. */
+/// A parsed semantic version number.
 class Version implements Comparable, VersionConstraint {
-  /** No released version: i.e. "0.0.0". */
+  /// No released version: i.e. "0.0.0".
   static Version get none => new Version(0, 0, 0);
 
   static final _PARSE_REGEX = new RegExp(
@@ -25,22 +23,22 @@
       r'(\+([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?'  // Build.
       r'$');                                     // Consume entire string.
 
-  /** The major version number: "1" in "1.2.3". */
+  /// The major version number: "1" in "1.2.3".
   final int major;
 
-  /** The minor version number: "2" in "1.2.3". */
+  /// The minor version number: "2" in "1.2.3".
   final int minor;
 
-  /** The patch version number: "3" in "1.2.3". */
+  /// The patch version number: "3" in "1.2.3".
   final int patch;
 
-  /** The pre-release identifier: "foo" in "1.2.3-foo". May be `null`. */
+  /// The pre-release identifier: "foo" in "1.2.3-foo". May be `null`.
   final String preRelease;
 
-  /** The build identifier: "foo" in "1.2.3+foo". May be `null`. */
+  /// The build identifier: "foo" in "1.2.3+foo". May be `null`.
   final String build;
 
-  /** Creates a new [Version] object. */
+  /// Creates a new [Version] object.
   Version(this.major, this.minor, this.patch, {String pre, this.build})
     : preRelease = pre {
     if (major < 0) throw new ArgumentError(
@@ -51,9 +49,7 @@
         'Patch version must be non-negative.');
   }
 
-  /**
-   * Creates a new [Version] by parsing [text].
-   */
+  /// Creates a new [Version] by parsing [text].
   factory Version.parse(String text) {
     final match = _PARSE_REGEX.firstMatch(text);
     if (match == null) {
@@ -74,6 +70,20 @@
     }
   }
 
+  /// Returns the primary version out of a list of candidates. This is the
+  /// highest-numbered stable (non-prerelease) version. If there are no stable
+  /// versions, it's just the highest-numbered version.
+  static Version primary(List<Version> versions) {
+    var primary;
+    for (var version in versions) {
+      if (primary == null || (!version.isPreRelease && primary.isPreRelease) ||
+          (version.isPreRelease == primary.isPreRelease && version > primary)) {
+        primary = version;
+      }
+    }
+    return primary;
+  }
+
   bool operator ==(other) {
     if (other is! Version) return false;
     return compareTo(other) == 0;
@@ -84,9 +94,13 @@
   bool operator <=(Version other) => compareTo(other) <= 0;
   bool operator >=(Version other) => compareTo(other) >= 0;
 
+  bool get isAny => false;
   bool get isEmpty => false;
 
-  /** Tests if [other] matches this version exactly. */
+  /// Whether or not this is a pre-release version.
+  bool get isPreRelease => preRelease != null;
+
+  /// Tests if [other] matches this version exactly.
   bool allows(Version other) => this == other;
 
   VersionConstraint intersect(VersionConstraint other) {
@@ -136,11 +150,9 @@
     return buffer.toString();
   }
 
-  /**
-   * Compares the string part of two versions. This is used for the pre-release
-   * and build version parts. This follows Rule 12. of the Semantic Versioning
-   * spec.
-   */
+  /// Compares the string part of two versions. This is used for the pre-release
+  /// and build version parts. This follows Rule 12. of the Semantic Versioning
+  /// spec.
   int _compareStrings(String a, String b) {
     var aParts = _splitParts(a);
     var bParts = _splitParts(b);
@@ -175,10 +187,8 @@
     }
   }
 
-  /**
-   * Splits a string of dot-delimited identifiers into their component parts.
-   * Identifiers that are numeric are converted to numbers.
-   */
+  /// Splits a string of dot-delimited identifiers into their component parts.
+  /// Identifiers that are numeric are converted to numbers.
   List _splitParts(String text) {
     return text.split('.').map((part) {
       try {
@@ -191,33 +201,27 @@
   }
 }
 
-/**
- * A [VersionConstraint] is a predicate that can determine whether a given
- * version is valid or not. For example, a ">= 2.0.0" constraint allows any
- * version that is "2.0.0" or greater. Version objects themselves implement
- * this to match a specific version.
- */
+/// A [VersionConstraint] is a predicate that can determine whether a given
+/// version is valid or not. For example, a ">= 2.0.0" constraint allows any
+/// version that is "2.0.0" or greater. Version objects themselves implement
+/// this to match a specific version.
 abstract class VersionConstraint {
-  /**
-   * A [VersionConstraint] that allows no versions: i.e. the empty set.
-   */
+  /// A [VersionConstraint] that allows no versions: i.e. the empty set.
   factory VersionConstraint.empty() => const _EmptyVersion();
 
-  /**
-   * Parses a version constraint. This string is a space-separated series of
-   * version parts. Each part can be one of:
-   *
-   *   * A version string like `1.2.3`. In other words, anything that can be
-   *     parsed by [Version.parse()].
-   *   * A comparison operator (`<`, `>`, `<=`, or `>=`) followed by a version
-   *     string. There cannot be a space between the operator and the version.
-   *
-   * Examples:
-   *
-   *     1.2.3-alpha
-   *     <=5.1.4
-   *     >2.0.4 <=2.4.6
-   */
+  /// Parses a version constraint. This string is a space-separated series of
+  /// version parts. Each part can be one of:
+  ///
+  ///   * A version string like `1.2.3`. In other words, anything that can be
+  ///     parsed by [Version.parse()].
+  ///   * A comparison operator (`<`, `>`, `<=`, or `>=`) followed by a version
+  ///     string. There cannot be a space between the operator and the version.
+  ///
+  /// Examples:
+  ///
+  ///     1.2.3-alpha
+  ///     <=5.1.4
+  ///     >2.0.4 <=2.4.6
   factory VersionConstraint.parse(String text) {
     if (text.trim() == '') {
       throw new FormatException('Cannot parse an empty string.');
@@ -232,12 +236,10 @@
     return new VersionConstraint.intersection(constraints);
   }
 
-  /**
-   * Creates a new version constraint that is the intersection of [constraints].
-   * It will only allow versions that all of those constraints allow. If
-   * constraints is empty, then it returns a VersionConstraint that allows all
-   * versions.
-   */
+  /// Creates a new version constraint that is the intersection of
+  /// [constraints]. It will only allow versions that all of those constraints
+  /// allow. If constraints is empty, then it returns a VersionConstraint that
+  /// allows all versions.
   factory VersionConstraint.intersection(
       Collection<VersionConstraint> constraints) {
     var constraint = new VersionRange();
@@ -247,20 +249,17 @@
     return constraint;
   }
 
-  /**
-   * Returns `true` if this constraint allows no versions.
-   */
+  /// Returns `true` if this constraint allows no versions.
   bool get isEmpty;
 
-  /**
-   * Returns `true` if this constraint allows [version].
-   */
+  /// Returns `true` if this constraint allows all versions.
+  bool get isAny;
+
+  /// Returns `true` if this constraint allows [version].
   bool allows(Version version);
 
-  /**
-   * Creates a new [VersionConstraint] that only allows [Version]s allowed by
-   * both this and [other].
-   */
+  /// Creates a new [VersionConstraint] that only allows [Version]s allowed by
+  /// both this and [other].
   VersionConstraint intersect(VersionConstraint other);
 
   static VersionConstraint _parseSingleConstraint(String text) {
@@ -290,12 +289,10 @@
   }
 }
 
-/**
- * Constrains versions to a fall within a given range. If there is a minimum,
- * then this only allows versions that are at that minimum or greater. If there
- * is a maximum, then only versions less than that are allowed. In other words,
- * this allows `>= min, < max`.
- */
+/// Constrains versions to a fall within a given range. If there is a minimum,
+/// then this only allows versions that are at that minimum or greater. If there
+/// is a maximum, then only versions less than that are allowed. In other words,
+/// this allows `>= min, < max`.
 class VersionRange implements VersionConstraint {
   final Version min;
   final Version max;
@@ -321,7 +318,9 @@
 
   bool get isEmpty => false;
 
-  /** Tests if [other] matches falls within this version range. */
+  bool get isAny => !includeMin && !includeMax;
+
+  /// Tests if [other] matches falls within this version range.
   bool allows(Version other) {
     if (min != null && other < min) return false;
     if (min != null && !includeMin && other == min) return false;
@@ -415,6 +414,7 @@
   const _EmptyVersion();
 
   bool get isEmpty => true;
+  bool get isAny => false;
   bool allows(Version other) => false;
   VersionConstraint intersect(VersionConstraint other) => this;
   String toString() => '<empty>';
diff --git a/utils/pub/version_solver.dart b/utils/pub/version_solver.dart
index 1a84aa2..a4b70f8 100644
--- a/utils/pub/version_solver.dart
+++ b/utils/pub/version_solver.dart
@@ -2,39 +2,37 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/**
- * Attempts to resolve a set of version constraints for a package dependency
- * graph and select an appropriate set of best specific versions for all
- * dependent packages. It works iteratively and tries to reach a stable
- * solution where the constraints of all dependencies are met. If it fails to
- * reach a solution after a certain number of iterations, it assumes the
- * dependency graph is unstable and reports and error.
- *
- * There are two fundamental operations in the process of iterating over the
- * graph:
- *
- * 1.  Changing the selected concrete version of some package. (This includes
- *     adding and removing a package too, which is considering changing the
- *     version to or from "none".) In other words, a node has changed.
- * 2.  Changing the version constraint that one package places on another. In
- *     other words, and edge has changed.
- *
- * Both of these events have a corresponding (potentional) async operation and
- * roughly cycle back and forth between each other. When we change the version
- * of package changes, we asynchronously load the pubspec for the new version.
- * When that's done, we compare the dependencies of the new version versus the
- * old one. For everything that differs, we change those constraints between
- * this package and that dependency.
- *
- * When a constraint on a package changes, we re-calculate the overall
- * constraint on that package. I.e. with a shared dependency, we intersect all
- * of the constraints that its depending packages place on it. If that overall
- * constraint changes (say from "<3.0.0" to "<2.5.0"), then the currently
- * picked version for that package may fall outside of the new constraint. If
- * that happens, we find the new best version that meets the updated constraint
- * and then the change the package to use that version. That cycles back up to
- * the beginning again.
- */
+/// Attempts to resolve a set of version constraints for a package dependency
+/// graph and select an appropriate set of best specific versions for all
+/// dependent packages. It works iteratively and tries to reach a stable
+/// solution where the constraints of all dependencies are met. If it fails to
+/// reach a solution after a certain number of iterations, it assumes the
+/// dependency graph is unstable and reports and error.
+///
+/// There are two fundamental operations in the process of iterating over the
+/// graph:
+///
+/// 1.  Changing the selected concrete version of some package. (This includes
+///     adding and removing a package too, which is considering changing the
+///     version to or from "none".) In other words, a node has changed.
+/// 2.  Changing the version constraint that one package places on another. In
+///     other words, and edge has changed.
+///
+/// Both of these events have a corresponding (potentional) async operation and
+/// roughly cycle back and forth between each other. When we change the version
+/// of package changes, we asynchronously load the pubspec for the new version.
+/// When that's done, we compare the dependencies of the new version versus the
+/// old one. For everything that differs, we change those constraints between
+/// this package and that dependency.
+///
+/// When a constraint on a package changes, we re-calculate the overall
+/// constraint on that package. I.e. with a shared dependency, we intersect all
+/// of the constraints that its depending packages place on it. If that overall
+/// constraint changes (say from "<3.0.0" to "<2.5.0"), then the currently
+/// picked version for that package may fall outside of the new constraint. If
+/// that happens, we find the new best version that meets the updated constraint
+/// and then the change the package to use that version. That cycles back up to
+/// the beginning again.
 library version_solver;
 
 import 'dart:json';
@@ -49,15 +47,13 @@
 import 'utils.dart';
 import 'version.dart';
 
-/**
- * Attempts to select the best concrete versions for all of the transitive
- * dependencies of [root] taking into account all of the [VersionConstraint]s
- * that those dependencies place on each other and the requirements imposed by
- * [lockFile]. If successful, completes to a [Map] that maps package names to
- * the selected version for that package. If it fails, the future will complete
- * with a [NoVersionException], [DisjointConstraintException], or
- * [CouldNotSolveException].
- */
+/// Attempts to select the best concrete versions for all of the transitive
+/// dependencies of [root] taking into account all of the [VersionConstraint]s
+/// that those dependencies place on each other and the requirements imposed by
+/// [lockFile]. If successful, completes to a [Map] that maps package names to
+/// the selected version for that package. If it fails, the future will complete
+/// with a [NoVersionException], [DisjointConstraintException], or
+/// [CouldNotSolveException].
 Future<List<PackageId>> resolveVersions(SourceRegistry sources, Package root,
     LockFile lockFile) {
   log.message('Resolving dependencies...');
@@ -79,12 +75,10 @@
         _packages = <String, Dependency>{},
         _work = new Queue<WorkItem>();
 
-  /**
-   * Tell the version solver to use the most recent version of [package] that
-   * exists in whatever source it's installed from. If that version violates
-   * constraints imposed by other dependencies, an error will be raised when
-   * solving the versions, even if an earlier compatible version exists.
-   */
+  /// Tell the version solver to use the most recent version of [package] that
+  /// exists in whatever source it's installed from. If that version violates
+  /// constraints imposed by other dependencies, an error will be raised when
+  /// solving the versions, even if an earlier compatible version exists.
   void useLatestVersion(String package) {
     // TODO(nweiz): How do we want to detect and handle unknown dependencies
     // here?
@@ -141,17 +135,13 @@
     return _packages[package];
   }
 
-  /**
-   * Sets the best selected version of [package] to [version].
-   */
+  /// Sets the best selected version of [package] to [version].
   void setVersion(String package, Version version) {
     _packages[package].version = version;
   }
 
-  /**
-   * Returns the most recent version of [dependency] that satisfies all of its
-   * version constraints.
-   */
+  /// Returns the most recent version of [dependency] that satisfies all of its
+  /// version constraints.
   Future<Version> getBestVersion(Dependency dependency) {
     return dependency.getVersions().transform((versions) {
       var best = null;
@@ -177,15 +167,13 @@
     });
   }
 
-  /**
-   * Looks for a package that depends (transitively) on [dependency] and has its
-   * version locked in the lockfile. If one is found, enqueues an
-   * [UnlockPackage] work item for it and returns true. Otherwise, returns
-   * false.
-   *
-   * This does a breadth-first search; immediate dependers will be unlocked
-   * first, followed by transitive dependers.
-   */
+  /// Looks for a package that depends (transitively) on [dependency] and has
+  /// its version locked in the lockfile. If one is found, enqueues an
+  /// [UnlockPackage] work item for it and returns true. Otherwise, returns
+  /// false.
+  ///
+  /// This does a breadth-first search; immediate dependers will be unlocked
+  /// first, followed by transitive dependers.
   bool tryUnlockDepender(Dependency dependency, [Set<String> seen]) {
     if (seen == null) seen = new Set();
     // Avoid an infinite loop if there are circular dependencies.
@@ -224,43 +212,31 @@
   }
 }
 
-/**
- * The constraint solver works by iteratively processing a queue of work items.
- * Each item is a single atomic change to the dependency graph. Handling them
- * in a queue lets us handle asynchrony (resolving versions requires information
- * from servers) as well as avoid deeply nested recursion.
-*/
+/// The constraint solver works by iteratively processing a queue of work items.
+/// Each item is a single atomic change to the dependency graph. Handling them
+/// in a queue lets us handle asynchrony (resolving versions requires
+/// information from servers) as well as avoid deeply nested recursion.
 abstract class WorkItem {
-  /**
-   * Processes this work item. Returns a future that completes when the work is
-   * done. If `null` is returned, that means the work has completed
-   * synchronously and the next item can be started immediately.
-   */
+  /// Processes this work item. Returns a future that completes when the work is
+  /// done. If `null` is returned, that means the work has completed
+  /// synchronously and the next item can be started immediately.
   Future process(VersionSolver solver);
 }
 
-/**
- * The best selected version for a package has changed to [version]. If the
- * previous version of the package is `null`, that means the package is being
- * added to the graph. If [version] is `null`, it is being removed.
- */
+/// The best selected version for a package has changed to [version]. If the
+/// previous version of the package is `null`, that means the package is being
+/// added to the graph. If [version] is `null`, it is being removed.
 class ChangeVersion implements WorkItem {
   /// The name of the package whose version is being changed.
   final String package;
 
-  /**
-   * The source of the package whose version is changing.
-   */
+  /// The source of the package whose version is changing.
   final Source source;
 
-  /**
-   * The description identifying the package whose version is changing.
-   */
+  /// The description identifying the package whose version is changing.
   final description;
 
-  /**
-   * The new selected version.
-   */
+  /// The new selected version.
   final Version version;
 
   ChangeVersion(this.package, this.source, this.description, this.version) {
@@ -303,9 +279,7 @@
     });
   }
 
-  /**
-   * Get the dependencies at [version] of the package being changed.
-   */
+  /// Get the dependencies at [version] of the package being changed.
   Future<Map<String, PackageRef>> getDependencyRefs(VersionSolver solver,
       Version version) {
     // If there is no version, it means no package, so no dependencies.
@@ -325,14 +299,12 @@
   }
 }
 
-/**
- * A constraint that a depending package places on a dependent package has
- * changed.
- *
- * This is an abstract class that contains logic for updating the dependency
- * graph once a dependency has changed. Changing the dependency is the
- * responsibility of subclasses.
- */
+/// A constraint that a depending package places on a dependent package has
+/// changed.
+///
+/// This is an abstract class that contains logic for updating the dependency
+/// graph once a dependency has changed. Changing the dependency is the
+/// responsibility of subclasses.
 abstract class ChangeConstraint implements WorkItem {
   Future process(VersionSolver solver);
 
@@ -402,20 +374,14 @@
   }
 }
 
-/**
- * The constraint given by [ref] is being placed by [depender].
- */
+/// The constraint given by [ref] is being placed by [depender].
 class AddConstraint extends ChangeConstraint {
-  /**
-   * The package that has the dependency.
-   */
+  /// The package that has the dependency.
   final String depender;
 
-  /**
-   * The package being depended on and the constraints being placed on it. The
-   * source, version, and description in this ref are all considered constraints
-   * on the dependent package.
-   */
+  /// The package being depended on and the constraints being placed on it. The
+  /// source, version, and description in this ref are all considered
+  /// constraints on the dependent package.
   final PackageRef ref;
 
   AddConstraint(this.depender, this.ref);
@@ -434,21 +400,15 @@
   }
 }
 
-/**
- * [depender] is no longer placing a constraint on [dependent].
- */
+/// [depender] is no longer placing a constraint on [dependent].
 class RemoveConstraint extends ChangeConstraint {
-  /**
-   * The package that was placing a constraint on [dependent].
-   */
+  /// The package that was placing a constraint on [dependent].
   String depender;
 
-  /**
-   * The package that was being depended on.
-   */
+  /// The package that was being depended on.
   String dependent;
 
-  /** The constraint that was removed. */
+  /// The constraint that was removed.
   PackageRef _removed;
 
   RemoveConstraint(this.depender, this.dependent);
@@ -467,9 +427,9 @@
   }
 }
 
-/** [package]'s version is no longer constrained by the lockfile. */
+/// [package]'s version is no longer constrained by the lockfile.
 class UnlockPackage implements WorkItem {
-  /** The package being unlocked. */
+  /// The package being unlocked.
   Dependency package;
 
   UnlockPackage(this.package);
@@ -489,10 +449,8 @@
 // TODO(rnystrom): Instead of always pulling from the source (which will mean
 // hitting a server), we should consider caching pubspecs of uninstalled
 // packages in the system cache.
-/**
- * Maintains a cache of previously-loaded pubspecs. Used to avoid requesting
- * the same pubspec from the server repeatedly.
- */
+/// Maintains a cache of previously-loaded pubspecs. Used to avoid requesting
+/// the same pubspec from the server repeatedly.
 class PubspecCache {
   final SourceRegistry _sources;
   final Map<PackageId, Pubspec> _pubspecs;
@@ -500,16 +458,12 @@
   PubspecCache(this._sources)
       : _pubspecs = new Map<PackageId, Pubspec>();
 
-  /**
-   * Caches [pubspec] as the [Pubspec] for the package identified by [id].
-   */
+  /// Caches [pubspec] as the [Pubspec] for the package identified by [id].
   void cache(PackageId id, Pubspec pubspec) {
     _pubspecs[id] = pubspec;
   }
 
-  /**
-   * Loads the pubspec for the package identified by [id].
-   */
+  /// Loads the pubspec for the package identified by [id].
   Future<Pubspec> load(PackageId id) {
     // Complete immediately if it's already cached.
     if (_pubspecs.containsKey(id)) {
@@ -524,47 +478,33 @@
   }
 }
 
-/**
- * Describes one [Package] in the [DependencyGraph] and keeps track of which
- * packages depend on it and what constraints they place on it.
- */
+/// Describes one [Package] in the [DependencyGraph] and keeps track of which
+/// packages depend on it and what constraints they place on it.
 class Dependency {
-  /**
-   * The name of the this dependency's package.
-   */
+  /// The name of the this dependency's package.
   final String name;
 
-  /**
-   * The [PackageRefs] that represent constraints that depending packages have
-   * placed on this one.
-   */
+  /// The [PackageRefs] that represent constraints that depending packages have
+  /// placed on this one.
   final Map<String, PackageRef> _refs;
 
-  /**
-   * The currently-selected best version for this dependency.
-   */
+  /// The currently-selected best version for this dependency.
   Version version;
 
-  /**
-   * Whether this dependency should always select the latest version.
-   */
+  /// Whether this dependency should always select the latest version.
   bool useLatestVersion = false;
 
-  /**
-   * Gets whether or not any other packages are currently depending on this
-   * one. If `false`, then it means this package is not part of the dependency
-   * graph and should be omitted.
-   */
+  /// Gets whether or not any other packages are currently depending on this
+  /// one. If `false`, then it means this package is not part of the dependency
+  /// graph and should be omitted.
   bool get isDependedOn => !_refs.isEmpty;
 
-  /** The names of all the packages that depend on this dependency. */
+  /// The names of all the packages that depend on this dependency.
   Collection<String> get dependers => _refs.keys;
 
-  /**
-   * Gets the overall constraint that all packages are placing on this one.
-   * If no packages have a constraint on this one (which can happen when this
-   * package is in the process of being added to the graph), returns `null`.
-   */
+  /// Gets the overall constraint that all packages are placing on this one.
+  /// If no packages have a constraint on this one (which can happen when this
+  /// package is in the process of being added to the graph), returns `null`.
   VersionConstraint get constraint {
     if (_refs.isEmpty) return null;
     return new VersionConstraint.intersection(
@@ -606,15 +546,13 @@
         version = other.version,
         _refs = new Map<String, PackageRef>.from(other._refs);
 
-  /** Creates a copy of this dependency. */
+  /// Creates a copy of this dependency.
   Dependency clone() => new Dependency._clone(this);
 
   /// Return a list of available versions for this dependency.
   Future<List<Version>> getVersions() => source.getVersions(name, description);
 
-  /**
-   * Places [ref] as a constraint from [package] onto this.
-   */
+  /// Places [ref] as a constraint from [package] onto this.
   void placeConstraint(String package, PackageRef ref) {
     var requiredDepender = _requiredDepender();
     if (requiredDepender != null) {
@@ -648,17 +586,13 @@
     return dependers[1];
   }
 
-  /**
-   * Removes the constraint from [package] onto this.
-   */
+  /// Removes the constraint from [package] onto this.
   PackageRef removeConstraint(String package) => _refs.remove(package);
 }
 
-/**
- * Exception thrown when the [VersionConstraint] used to match a package is
- * valid (i.e. non-empty), but there are no released versions of the package
- * that fit that constraint.
- */
+/// Exception thrown when the [VersionConstraint] used to match a package is
+/// valid (i.e. non-empty), but there are no released versions of the package
+/// that fit that constraint.
 class NoVersionException implements Exception {
   final String package;
   final VersionConstraint constraint;
@@ -684,10 +618,8 @@
 }
 
 // TODO(rnystrom): Report the list of depending packages and their constraints.
-/**
- * Exception thrown when the most recent version of [package] must be selected,
- * but doesn't match the [VersionConstraint] imposed on the package.
- */
+/// Exception thrown when the most recent version of [package] must be selected,
+/// but doesn't match the [VersionConstraint] imposed on the package.
 class CouldNotUpdateException implements Exception {
   final String package;
   final VersionConstraint constraint;
@@ -699,11 +631,9 @@
       "The latest version of '$package', $best, does not match $constraint.";
 }
 
-/**
- * Exception thrown when the [VersionConstraint] used to match a package is
- * the empty set: in other words, multiple packages depend on it and have
- * conflicting constraints that have no overlap.
- */
+/// Exception thrown when the [VersionConstraint] used to match a package is
+/// the empty set: in other words, multiple packages depend on it and have
+/// conflicting constraints that have no overlap.
 class DisjointConstraintException implements Exception {
   final String package;
   final Map<String, PackageRef> _dependencies;
@@ -726,10 +656,8 @@
   }
 }
 
-/**
- * Exception thrown when the [VersionSolver] fails to find a solution after a
- * certain number of iterations.
- */
+/// Exception thrown when the [VersionSolver] fails to find a solution after a
+/// certain number of iterations.
 class CouldNotSolveException implements Exception {
   CouldNotSolveException();
 
@@ -737,10 +665,8 @@
       "Could not find a solution that met all version constraints.";
 }
 
-/**
- * Exception thrown when two packages with the same name but different sources
- * are depended upon.
- */
+/// Exception thrown when two packages with the same name but different sources
+/// are depended upon.
 class SourceMismatchException implements Exception {
   final String package;
   final String depender1;
@@ -758,10 +684,8 @@
   }
 }
 
-/**
- * Exception thrown when two packages with the same name and source but
- * different descriptions are depended upon.
- */
+/// Exception thrown when two packages with the same name and source but
+/// different descriptions are depended upon.
 class DescriptionMismatchException implements Exception {
   final String package;
   final String depender1;
diff --git a/utils/pub/yaml/composer.dart b/utils/pub/yaml/composer.dart
index c10e5e8..79aa274 100644
--- a/utils/pub/yaml/composer.dart
+++ b/utils/pub/yaml/composer.dart
@@ -2,35 +2,31 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/**
- * Takes a parsed YAML document (what the spec calls the "serialization tree")
- * and resolves aliases, resolves tags, and parses scalars to produce the
- * "representation graph".
- */
+part of yaml;
+
+/// Takes a parsed YAML document (what the spec calls the "serialization tree")
+/// and resolves aliases, resolves tags, and parses scalars to produce the
+/// "representation graph".
 class _Composer extends _Visitor {
-  /** The root node of the serialization tree. */
+  /// The root node of the serialization tree.
   _Node root;
 
-  /**
-   * Map from anchor names to the most recent representation graph node with
-   * that anchor.
-   */
+  /// Map from anchor names to the most recent representation graph node with
+  /// that anchor.
   Map<String, _Node> anchors;
 
-  /**
-   * The next id to use for the represenation graph's anchors. The spec doesn't
-   * use anchors in the representation graph, but we do so that the constructor
-   * can ensure that the same node in the representation graph produces the same
-   * native object.
-   */
+  /// The next id to use for the represenation graph's anchors. The spec doesn't
+  /// use anchors in the representation graph, but we do so that the constructor
+  /// can ensure that the same node in the representation graph produces the
+  /// same native object.
   int idCounter;
 
   _Composer(this.root) : this.anchors = <String, _Node>{}, this.idCounter = 0;
 
-  /** Runs the Composer to produce a representation graph. */
+  /// Runs the Composer to produce a representation graph.
   _Node compose() => root.visit(this);
 
-  /** Returns the anchor to which an alias node refers. */
+  /// Returns the anchor to which an alias node refers.
   _Node visitAlias(_AliasNode alias) {
     if (!anchors.containsKey(alias.anchor)) {
       throw new YamlException("no anchor for alias ${alias.anchor}");
@@ -38,10 +34,8 @@
     return anchors[alias.anchor];
   }
 
-  /**
-   * Parses a scalar node according to its tag, or auto-detects the type if no
-   * tag exists. Currently this only supports the YAML core type schema.
-   */
+  /// Parses a scalar node according to its tag, or auto-detects the type if no
+  /// tag exists. Currently this only supports the YAML core type schema.
   _Node visitScalar(_ScalarNode scalar) {
     if (scalar.tag.name == "!") {
       return setAnchor(scalar, parseString(scalar.content));
@@ -69,7 +63,7 @@
     throw new YamlException('undefined tag: "${scalar.tag.name}"');
   }
 
-  /** Assigns a tag to the sequence and recursively composes its contents. */
+  /// Assigns a tag to the sequence and recursively composes its contents.
   _Node visitSequence(_SequenceNode seq) {
     var tagName = seq.tag.name;
     if (tagName != "!" && tagName != "?" && tagName != _Tag.yaml("seq")) {
@@ -81,7 +75,7 @@
     return result;
   }
 
-  /** Assigns a tag to the mapping and recursively composes its contents. */
+  /// Assigns a tag to the mapping and recursively composes its contents.
   _Node visitMapping(_MappingNode map) {
     var tagName = map.tag.name;
     if (tagName != "!" && tagName != "?" && tagName != _Tag.yaml("map")) {
@@ -93,10 +87,8 @@
     return result;
   }
 
-  /**
-   * If the serialization tree node [anchored] has an anchor, records that
-   * that anchor is pointing to the representation graph node [result].
-   */
+  /// If the serialization tree node [anchored] has an anchor, records that
+  /// that anchor is pointing to the representation graph node [result].
   _Node setAnchor(_Node anchored, _Node result) {
     if (anchored.anchor == null) return result;
     result.anchor = '${idCounter++}';
@@ -104,13 +96,13 @@
     return result;
   }
 
-  /** Parses a null scalar. */
+  /// Parses a null scalar.
   _ScalarNode parseNull(String content) {
     if (!new RegExp("^(null|Null|NULL|~|)\$").hasMatch(content)) return null;
     return new _ScalarNode(_Tag.yaml("null"), value: null);
   }
 
-  /** Parses a boolean scalar. */
+  /// Parses a boolean scalar.
   _ScalarNode parseBool(String content) {
     var match = new RegExp("^(?:(true|True|TRUE)|(false|False|FALSE))\$").
       firstMatch(content);
@@ -118,7 +110,7 @@
     return new _ScalarNode(_Tag.yaml("bool"), value: match.group(1) != null);
   }
 
-  /** Parses an integer scalar. */
+  /// Parses an integer scalar.
   _ScalarNode parseInt(String content) {
     var match = new RegExp("^[-+]?[0-9]+\$").firstMatch(content);
     if (match != null) {
@@ -146,7 +138,7 @@
     return null;
   }
 
-  /** Parses a floating-point scalar. */
+  /// Parses a floating-point scalar.
   _ScalarNode parseFloat(String content) {
     var match = new RegExp(
         "^[-+]?(\.[0-9]+|[0-9]+(\.[0-9]*)?)([eE][-+]?[0-9]+)?\$").
@@ -175,7 +167,7 @@
     return null;
   }
 
-  /** Parses a string scalar. */
+  /// Parses a string scalar.
   _ScalarNode parseString(String content) =>
     new _ScalarNode(_Tag.yaml("str"), value: content);
 }
diff --git a/utils/pub/yaml/constructor.dart b/utils/pub/yaml/constructor.dart
index d52ef6e..73a62a8 100644
--- a/utils/pub/yaml/constructor.dart
+++ b/utils/pub/yaml/constructor.dart
@@ -2,27 +2,27 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/**
- * Takes a parsed and composed YAML document (what the spec calls the
- * "representation graph") and creates native Dart objects that represent that
- * document.
- */
+part of yaml;
+
+/// Takes a parsed and composed YAML document (what the spec calls the
+/// "representation graph") and creates native Dart objects that represent that
+/// document.
 class _Constructor extends _Visitor {
-  /** The root node of the representation graph. */
+  /// The root node of the representation graph.
   _Node root;
 
-  /** Map from anchor names to the most recent Dart node with that anchor. */
+  /// Map from anchor names to the most recent Dart node with that anchor.
   Map<String, dynamic> anchors;
 
   _Constructor(this.root) : this.anchors = {};
 
-  /** Runs the Constructor to produce a Dart object. */
+  /// Runs the Constructor to produce a Dart object.
   construct() => root.visit(this);
 
-  /** Returns the value of a scalar. */
+  /// Returns the value of a scalar.
   visitScalar(_ScalarNode scalar) => scalar.value;
 
-  /** Converts a sequence into a List of Dart objects. */
+  /// Converts a sequence into a List of Dart objects.
   visitSequence(_SequenceNode seq) {
     var anchor = getAnchor(seq);
     if (anchor != null) return anchor;
@@ -31,7 +31,7 @@
     return dartSeq;
   }
 
-  /** Converts a mapping into a Map of Dart objects. */
+  /// Converts a mapping into a Map of Dart objects.
   visitMapping(_MappingNode map) {
     var anchor = getAnchor(map);
     if (anchor != null) return anchor;
@@ -40,16 +40,14 @@
     return dartMap;
   }
 
-  /**
-   * Returns the Dart object that already represents [anchored], if such a thing
-   * exists.
-   */
+  /// Returns the Dart object that already represents [anchored], if such a
+  /// thing exists.
   getAnchor(_Node anchored) {
     if (anchored.anchor == null) return null;
     if (anchors.containsKey(anchored.anchor)) return anchors[anchored.anchor];
   }
 
-  /** Records that [value] is the Dart object representing [anchored]. */
+  /// Records that [value] is the Dart object representing [anchored].
   setAnchor(_Node anchored, value) {
     if (anchored.anchor == null) return value;
     anchors[anchored.anchor] = value;
diff --git a/utils/pub/yaml/deep_equals.dart b/utils/pub/yaml/deep_equals.dart
index 95c69c7..bce4aad 100644
--- a/utils/pub/yaml/deep_equals.dart
+++ b/utils/pub/yaml/deep_equals.dart
@@ -4,10 +4,8 @@
 
 library deep_equals;
 
-/**
- * Returns whether two objects are structurally equivalent. This considers NaN
- * values to be equivalent. It also handles self-referential structures.
- */
+/// Returns whether two objects are structurally equivalent. This considers NaN
+/// values to be equivalent. It also handles self-referential structures.
 bool deepEquals(obj1, obj2, [List parents1, List parents2]) {
   if (identical(obj1, obj2)) return true;
   if (parents1 == null) {
@@ -43,7 +41,7 @@
   }
 }
 
-/** Returns whether [list1] and [list2] are structurally equal. */
+/// Returns whether [list1] and [list2] are structurally equal. 
 bool _listEquals(List list1, List list2, List parents1, List parents2) {
   if (list1.length != list2.length) return false;
 
@@ -54,7 +52,7 @@
   return true;
 }
 
-/** Returns whether [map1] and [map2] are structurally equal. */
+/// Returns whether [map1] and [map2] are structurally equal. 
 bool _mapEquals(Map map1, Map map2, List parents1, List parents2) {
   if (map1.length != map2.length) return false;
 
@@ -66,10 +64,8 @@
   return true;
 }
 
-/**
- * Returns whether two doubles are equivalent. This differs from `d1 == d2` in
- * that it considers NaN to be equal to itself.
- */
+/// Returns whether two doubles are equivalent. This differs from `d1 == d2` in
+/// that it considers NaN to be equal to itself.
 bool _doubleEquals(double d1, double d2) {
   if (d1.isNaN && d2.isNaN) return true;
   return d1 == d2;
diff --git a/utils/pub/yaml/model.dart b/utils/pub/yaml/model.dart
index 2ba1416..57bf202 100644
--- a/utils/pub/yaml/model.dart
+++ b/utils/pub/yaml/model.dart
@@ -2,11 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+part of yaml;
+
 // This file contains the node classes for the internal representations of YAML
 // documents. These nodes are used for both the serialization tree and the
 // representation graph.
 
-/** A tag that indicates the type of a YAML node. */
+/// A tag that indicates the type of a YAML node.
 class _Tag {
   // TODO(nweiz): it would better match the semantics of the spec if there were
   // a singleton instance of this class for each tag.
@@ -17,10 +19,10 @@
 
   static const String YAML_URI_PREFIX = 'tag:yaml.org,2002:';
 
-  /** The name of the tag, either a URI or a local tag beginning with "!". */
+  /// The name of the tag, either a URI or a local tag beginning with "!".
   final String name;
 
-  /** The kind of the tag: SCALAR_KIND, SEQUENCE_KIND, or MAPPING_KIND. */
+  /// The kind of the tag: SCALAR_KIND, SEQUENCE_KIND, or MAPPING_KIND.
   final int kind;
 
   _Tag(this.name, this.kind);
@@ -29,10 +31,10 @@
   _Tag.sequence(String name) : this(name, SEQUENCE_KIND);
   _Tag.mapping(String name) : this(name, MAPPING_KIND);
 
-  /** Returns the standard YAML tag URI for [type]. */
+  /// Returns the standard YAML tag URI for [type].
   static String yaml(String type) => "tag:yaml.org,2002:$type";
 
-  /** Two tags are equal if their URIs are equal. */
+  /// Two tags are equal if their URIs are equal.
   operator ==(other) {
     if (other is! _Tag) return false;
     return name == other.name;
@@ -49,12 +51,12 @@
   int get hashCode => name.hashCode;
 }
 
-/** The abstract class for YAML nodes. */
+/// The abstract class for YAML nodes.
 abstract class _Node {
-  /** Every YAML node has a tag that describes its type. */
+  /// Every YAML node has a tag that describes its type.
   _Tag tag;
 
-  /** Any YAML node can have an anchor associated with it. */
+  /// Any YAML node can have an anchor associated with it.
   String anchor;
 
   _Node(this.tag, [this.anchor]);
@@ -69,15 +71,15 @@
   visit(_Visitor v);
 }
 
-/** A sequence node represents an ordered list of nodes. */
+/// A sequence node represents an ordered list of nodes.
 class _SequenceNode extends _Node {
-  /** The nodes in the sequence. */
+  /// The nodes in the sequence.
   List<_Node> content;
 
   _SequenceNode(String tagName, this.content)
     : super(new _Tag.sequence(tagName));
 
-  /** Two sequences are equal if their tags and contents are equal. */
+  /// Two sequences are equal if their tags and contents are equal.
   bool operator ==(other) {
     // Should be super != other; bug 2554
     if (!(super == other) || other is! _SequenceNode) return false;
@@ -95,50 +97,44 @@
   visit(_Visitor v) => v.visitSequence(this);
 }
 
-/** An alias node is a reference to an anchor. */
+/// An alias node is a reference to an anchor.
 class _AliasNode extends _Node {
   _AliasNode(String anchor) : super(new _Tag.scalar(_Tag.yaml("str")), anchor);
 
   visit(_Visitor v) => v.visitAlias(this);
 }
 
-/** A scalar node represents all YAML nodes that have a single value. */
+/// A scalar node represents all YAML nodes that have a single value.
 class _ScalarNode extends _Node {
-  /** The string value of the scalar node, if it was created by the parser. */
+  /// The string value of the scalar node, if it was created by the parser.
   final String _content;
 
-  /** The Dart value of the scalar node, if it was created by the composer. */
+  /// The Dart value of the scalar node, if it was created by the composer.
   final value;
 
-  /**
-   * Creates a new Scalar node.
-   *
-   * Exactly one of [content] and [value] should be specified. Content should be
-   * specified for a newly-parsed scalar that hasn't yet been composed. Value
-   * should be specified for a composed scalar, although `null` is a valid
-   * value.
-   */
+  /// Creates a new Scalar node.
+  ///
+  /// Exactly one of [content] and [value] should be specified. Content should
+  /// be specified for a newly-parsed scalar that hasn't yet been composed.
+  /// Value should be specified for a composed scalar, although `null` is a
+  /// valid value.
   _ScalarNode(String tagName, {String content, this.value})
    : _content = content,
      super(new _Tag.scalar(tagName));
 
-  /** Two scalars are equal if their string representations are equal. */
+  /// Two scalars are equal if their string representations are equal.
   bool operator ==(other) {
     // Should be super != other; bug 2554
     if (!(super == other) || other is! _ScalarNode) return false;
     return content == other.content;
   }
 
-  /**
-   * Returns the string representation of the scalar. After composition, this is
-   * equal to the canonical serialization of the value of the scalar.
-   */
+  /// Returns the string representation of the scalar. After composition, this
+  /// is equal to the canonical serialization of the value of the scalar.
   String get content => _content != null ? _content : canonicalContent;
 
-  /**
-   * Returns the canonical serialization of the value of the scalar. If the
-   * value isn't given, the result of this will be "null".
-   */
+  /// Returns the canonical serialization of the value of the scalar. If the
+  /// value isn't given, the result of this will be "null".
   String get canonicalContent {
     if (value == null || value is bool || value is int) return '$value';
 
@@ -190,10 +186,8 @@
 
   String toString() => '$tag "$content"';
 
-  /**
-   * Left-pads [str] with zeros so that it's at least [length] characters
-   * long.
-   */
+  /// Left-pads [str] with zeros so that it's at least [length] characters
+  /// long.
   String zeroPad(String str, int length) {
     assert(length >= str.length);
     var prefix = [];
@@ -206,15 +200,15 @@
   visit(_Visitor v) => v.visitScalar(this);
 }
 
-/** A mapping node represents an unordered map of nodes to nodes. */
+/// A mapping node represents an unordered map of nodes to nodes.
 class _MappingNode extends _Node {
-  /** The node map. */
+  /// The node map.
   Map<_Node, _Node> content;
 
   _MappingNode(String tagName, this.content)
     : super(new _Tag.mapping(tagName));
 
-  /** Two mappings are equal if their tags and contents are equal. */
+  /// Two mappings are equal if their tags and contents are equal.
   bool operator ==(other) {
     // Should be super != other; bug 2554
     if (!(super == other) || other is! _MappingNode) return false;
diff --git a/utils/pub/yaml/parser.dart b/utils/pub/yaml/parser.dart
index dcfc50a..8652ff4 100644
--- a/utils/pub/yaml/parser.dart
+++ b/utils/pub/yaml/parser.dart
@@ -2,21 +2,21 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/**
- * Translates a string of characters into a YAML serialization tree.
- *
- * This parser is designed to closely follow the spec. All productions in the
- * spec are numbered, and the corresponding methods in the parser have the same
- * numbers. This is certainly not the most efficient way of parsing YAML, but it
- * is the easiest to write and read in the context of the spec.
- *
- * Methods corresponding to productions are also named as in the spec,
- * translating the name of the method (although not the annotation characters)
- * into camel-case for dart style.. For example, the spec has a production named
- * `nb-ns-plain-in-line`, and the method implementing it is named
- * `nb_ns_plainInLine`. The exception to that rule is methods that just
- * recognize character classes; these are named `is*`.
- */
+part of yaml;
+
+/// Translates a string of characters into a YAML serialization tree.
+///
+/// This parser is designed to closely follow the spec. All productions in the
+/// spec are numbered, and the corresponding methods in the parser have the same
+/// numbers. This is certainly not the most efficient way of parsing YAML, but
+/// it is the easiest to write and read in the context of the spec.
+///
+/// Methods corresponding to productions are also named as in the spec,
+/// translating the name of the method (although not the annotation characters)
+/// into camel-case for dart style.. For example, the spec has a production
+/// named `nb-ns-plain-in-line`, and the method implementing it is named
+/// `nb_ns_plainInLine`. The exception to that rule is methods that just
+/// recognize character classes; these are named `is*`.
 class _Parser {
   static const TAB = 0x9;
   static const LF = 0xA;
@@ -110,73 +110,56 @@
   static const CHOMPING_KEEP = 1;
   static const CHOMPING_CLIP = 2;
 
-  /** The source string being parsed. */
+  /// The source string being parsed.
   final String s;
 
-  /** The current position in the source string. */
+  /// The current position in the source string.
   int pos = 0;
 
-  /** The length of the string being parsed. */
+  /// The length of the string being parsed.
   final int len;
 
-  /** The current (0-based) line in the source string. */
+  /// The current (0-based) line in the source string.
   int line = 0;
 
-  /** The current (0-based) column in the source string. */
+  /// The current (0-based) column in the source string.
   int column = 0;
 
-  /**
-   * Whether we're parsing a bare document (that is, one that doesn't begin with
-   * `---`). Bare documents don't allow `%` immediately following newlines.
-   */
+  /// Whether we're parsing a bare document (that is, one that doesn't begin
+  /// with `---`). Bare documents don't allow `%` immediately following
+  /// newlines.
   bool inBareDocument = false;
 
-  /**
-   * The line number of the farthest position that has been parsed successfully
-   * before backtracking. Used for error reporting.
-   */
+  /// The line number of the farthest position that has been parsed successfully
+  /// before backtracking. Used for error reporting.
   int farthestLine = 0;
 
-  /**
-   * The column number of the farthest position that has been parsed
-   * successfully before backtracking. Used for error reporting.
-   */
+  /// The column number of the farthest position that has been parsed
+  /// successfully before backtracking. Used for error reporting.
   int farthestColumn = 0;
 
-  /**
-   * The farthest position in the source string that has been parsed
-   * successfully before backtracking. Used for error reporting.
-   */
+  /// The farthest position in the source string that has been parsed
+  /// successfully before backtracking. Used for error reporting.
   int farthestPos = 0;
 
-  /**
-   * The name of the context of the farthest position that has been parsed
-   * successfully before backtracking. Used for error reporting.
-   */
+  /// The name of the context of the farthest position that has been parsed
+  /// successfully before backtracking. Used for error reporting.
   String farthestContext = "document";
 
-  /** A stack of the names of parse contexts. Used for error reporting. */
+  /// A stack of the names of parse contexts. Used for error reporting.
   List<String> contextStack;
 
-  /**
-   * Annotations attached to ranges of the source string that add extra
-   * information to any errors that occur in the annotated range.
-   */
+  /// Annotations attached to ranges of the source string that add extra
+  /// information to any errors that occur in the annotated range.
   _RangeMap<String> errorAnnotations;
 
-  /**
-   * The buffer containing the string currently being captured.
-   */
+  /// The buffer containing the string currently being captured.
   StringBuffer capturedString;
 
-  /**
-   * The beginning of the current section of the captured string.
-   */
+  /// The beginning of the current section of the captured string.
   int captureStart;
 
-  /**
-   * Whether the current string capture is being overridden.
-   */
+  /// Whether the current string capture is being overridden.
   bool capturingAs = false;
 
   _Parser(String s)
@@ -185,10 +168,8 @@
       contextStack = <String>["document"],
       errorAnnotations = new _RangeMap();
 
-  /**
-   * Return the character at the current position, then move that position
-   * forward one character. Also updates the current line and column numbers.
-   */
+  /// Return the character at the current position, then move that position
+  /// forward one character. Also updates the current line and column numbers.
   int next() {
     if (pos == len) return -1;
     var char = s.charCodeAt(pos++);
@@ -212,28 +193,22 @@
     return char;
   }
 
-  /**
-   * Returns the character at the current position, or the character [i]
-   * characters after the current position.
-   *
-   * Returns -1 if this would return a character after the end or before the
-   * beginning of the input string.
-   */
+  /// Returns the character at the current position, or the character [i]
+  /// characters after the current position.
+  ///
+  /// Returns -1 if this would return a character after the end or before the
+  /// beginning of the input string.
   int peek([int i = 0]) {
     var peekPos = pos + i;
     return (peekPos >= len || peekPos < 0) ? -1 : s.charCodeAt(peekPos);
   }
 
-  /**
-   * The truthiness operator. Returns `false` if [obj] is `null` or `false`,
-   * `true` otherwise.
-   */
+  /// The truthiness operator. Returns `false` if [obj] is `null` or `false`,
+  /// `true` otherwise.
   bool truth(obj) => obj != null && obj != false;
 
-  /**
-   * Consumes the current character if it matches [matcher]. Returns the result
-   * of [matcher].
-   */
+  /// Consumes the current character if it matches [matcher]. Returns the result
+  /// of [matcher].
   bool consume(bool matcher(int)) {
     if (matcher(peek())) {
       next();
@@ -242,17 +217,13 @@
     return false;
   }
 
-  /**
-   * Consumes the current character if it equals [char].
-   */
+  /// Consumes the current character if it equals [char].
   bool consumeChar(int char) => consume((c) => c == char);
 
-  /**
-   * Calls [consumer] until it returns a falsey value. Returns a list of all
-   * truthy return values of [consumer], or null if it didn't consume anything.
-   *
-   * Conceptually, repeats a production one or more times.
-   */
+  /// Calls [consumer] until it returns a falsey value. Returns a list of all
+  /// truthy return values of [consumer], or null if it didn't consume anything.
+  ///
+  /// Conceptually, repeats a production one or more times.
   List oneOrMore(consumer()) {
     var first = consumer();
     if (!truth(first)) return null;
@@ -265,13 +236,11 @@
     return null; // Unreachable.
   }
 
-  /**
-   * Calls [consumer] until it returns a falsey value. Returns a list of all
-   * truthy return values of [consumer], or the empty list if it didn't consume
-   * anything.
-   *
-   * Conceptually, repeats a production any number of times.
-   */
+  /// Calls [consumer] until it returns a falsey value. Returns a list of all
+  /// truthy return values of [consumer], or the empty list if it didn't consume
+  /// anything.
+  ///
+  /// Conceptually, repeats a production any number of times.
   List zeroOrMore(consumer()) {
     var out = [];
     var oldPos = pos;
@@ -284,16 +253,12 @@
     return null; // Unreachable.
   }
 
-  /**
-   * Just calls [consumer] and returns its result. Used to make it explicit that
-   * a production is intended to be optional.
-   */
+  /// Just calls [consumer] and returns its result. Used to make it explicit
+  /// that a production is intended to be optional.
   zeroOrOne(consumer()) => consumer();
 
-  /**
-   * Calls each function in [consumers] until one returns a truthy value, then
-   * returns that.
-   */
+  /// Calls each function in [consumers] until one returns a truthy value, then
+  /// returns that.
   or(List<Function> consumers) {
     for (var c in consumers) {
       var res = c();
@@ -302,10 +267,8 @@
     return null;
   }
 
-  /**
-   * Calls [consumer] and returns its result, but rolls back the parser state if
-   * [consumer] returns a falsey value.
-   */
+  /// Calls [consumer] and returns its result, but rolls back the parser state
+  /// if [consumer] returns a falsey value.
   transaction(consumer()) {
     var oldPos = pos;
     var oldLine = line;
@@ -325,13 +288,11 @@
     return res;
   }
 
-  /**
-   * Consumes [n] characters matching [matcher], or none if there isn't a
-   * complete match. The first argument to [matcher] is the character code, the
-   * second is the index (from 0 to [n] - 1).
-   *
-   * Returns whether or not the characters were consumed.
-   */
+  /// Consumes [n] characters matching [matcher], or none if there isn't a
+  /// complete match. The first argument to [matcher] is the character code, the
+  /// second is the index (from 0 to [n] - 1).
+  ///
+  /// Returns whether or not the characters were consumed.
   bool nAtOnce(int n, bool matcher(int c, int i)) => transaction(() {
     for (int i = 0; i < n; i++) {
       if (!consume((c) => matcher(c, i))) return false;
@@ -339,26 +300,20 @@
     return true;
   });
 
-  /**
-   * Consumes the exact characters in [str], or nothing.
-   *
-   * Returns whether or not the string was consumed.
-   */
+  /// Consumes the exact characters in [str], or nothing.
+  ///
+  /// Returns whether or not the string was consumed.
   bool rawString(String str) =>
     nAtOnce(str.length, (c, i) => str.charCodeAt(i) == c);
 
-  /**
-   * Consumes and returns a string of characters matching [matcher], or null if
-   * there are no such characters.
-   */
+  /// Consumes and returns a string of characters matching [matcher], or null if
+  /// there are no such characters.
   String stringOf(bool matcher(int)) =>
     captureString(() => oneOrMore(() => consume(matcher)));
 
-  /**
-   * Calls [consumer] and returns the string that was consumed while doing so,
-   * or null if [consumer] returned a falsey value. Automatically wraps
-   * [consumer] in `transaction`.
-   */
+  /// Calls [consumer] and returns the string that was consumed while doing so,
+  /// or null if [consumer] returned a falsey value. Automatically wraps
+  /// [consumer] in `transaction`.
   String captureString(consumer()) {
     // captureString calls may not be nested
     assert(capturedString == null);
@@ -402,9 +357,7 @@
     captureStart = pos;
   }
 
-  /**
-   * Adds a tag and an anchor to [node], if they're defined.
-   */
+  /// Adds a tag and an anchor to [node], if they're defined.
   _Node addProps(_Node node, _Pair<_Tag, String> props) {
     if (props == null || node == null) return node;
     if (truth(props.first)) node.tag = props.first;
@@ -412,14 +365,14 @@
     return node;
   }
 
-  /** Creates a MappingNode from [pairs]. */
+  /// Creates a MappingNode from [pairs].
   _MappingNode map(List<_Pair<_Node, _Node>> pairs) {
     var content = new Map<_Node, _Node>();
     pairs.forEach((pair) => content[pair.first] = pair.last);
     return new _MappingNode("?", content);
   }
 
-  /** Runs [fn] in a context named [name]. Used for error reporting. */
+  /// Runs [fn] in a context named [name]. Used for error reporting.
   context(String name, fn()) {
     try {
       contextStack.add(name);
@@ -430,11 +383,9 @@
     }
   }
 
-  /**
-   * Adds [message] as extra information to any errors that occur between the
-   * current position and the position of the cursor after running [fn]. The
-   * cursor is reset after [fn] is run.
-   */
+  /// Adds [message] as extra information to any errors that occur between the
+  /// current position and the position of the cursor after running [fn]. The
+  /// cursor is reset after [fn] is run.
   annotateError(String message, fn()) {
     var start = pos;
     var end;
@@ -446,26 +397,22 @@
     errorAnnotations[new _Range(start, end)] = message;
   }
 
-  /** Throws an error with additional context information. */
+  /// Throws an error with additional context information.
   error(String message) {
     // Line and column should be one-based.
     throw new SyntaxError(line + 1, column + 1,
         "$message (in $farthestContext)");
   }
 
-  /**
-   * If [result] is falsey, throws an error saying that [expected] was
-   * expected.
-   */
+  /// If [result] is falsey, throws an error saying that [expected] was
+  /// expected.
   expect(result, String expected) {
     if (truth(result)) return result;
     error("expected $expected");
   }
 
-  /**
-   * Throws an error saying that the parse failed. Uses [farthestLine],
-   * [farthestColumn], and [farthestContext] to provide additional information.
-   */
+  /// Throws an error saying that the parse failed. Uses [farthestLine],
+  /// [farthestColumn], and [farthestContext] to provide additional information.
   parseFailed() {
     var message = "invalid YAML in $farthestContext";
     var extraError = errorAnnotations[farthestPos];
@@ -473,14 +420,14 @@
     throw new SyntaxError(farthestLine + 1, farthestColumn + 1, message);
   }
 
-  /** Returns the number of spaces after the current position. */
+  /// Returns the number of spaces after the current position.
   int countIndentation() {
     var i = 0;
     while (peek(i) == SP) i++;
     return i;
   }
 
-  /** Returns the indentation for a block scalar. */
+  /// Returns the indentation for a block scalar.
   int blockScalarAdditionalIndentation(_BlockHeader header, int indent) {
     if (!header.autoDetectIndent) return header.additionalIndent;
 
@@ -514,16 +461,14 @@
     return spaces - indent;
   }
 
-  /** Returns whether the current position is at the beginning of a line. */
+  /// Returns whether the current position is at the beginning of a line.
   bool get atStartOfLine => column == 0;
 
-  /** Returns whether the current position is at the end of the input. */
+  /// Returns whether the current position is at the end of the input.
   bool get atEndOfFile => pos == len;
 
-  /**
-   * Given an indicator character, returns the type of that indicator (or null
-   * if the indicator isn't found.
-   */
+  /// Given an indicator character, returns the type of that indicator (or null
+  /// if the indicator isn't found.
   int indicatorType(int char) {
     switch (char) {
     case HYPHEN: return C_SEQUENCE_ENTRY;
@@ -1805,10 +1750,10 @@
   _Node s_l_blockScalar(int indent, int ctx) => transaction(() {
     if (!truth(s_separate(indent + 1, ctx))) return null;
     var props = transaction(() {
-      var props = c_ns_properties(indent + 1, ctx);
-      if (!truth(props)) return null;
+      var innerProps = c_ns_properties(indent + 1, ctx);
+      if (!truth(innerProps)) return null;
       if (!truth(s_separate(indent + 1, ctx))) return null;
-      return props;
+      return innerProps;
     });
 
     var node = or([() => c_l_literal(indent), () => c_l_folded(indent)]);
@@ -1931,7 +1876,7 @@
   String toString() => "Syntax error on line $line, column $column: $msg";
 }
 
-/** A pair of values. */
+/// A pair of values.
 class _Pair<E, F> {
   E first;
   F last;
@@ -1941,7 +1886,7 @@
   String toString() => '($first, $last)';
 }
 
-/** The information in the header for a block scalar. */
+/// The information in the header for a block scalar.
 class _BlockHeader {
   final int additionalIndent;
   final int chomping;
@@ -1951,38 +1896,33 @@
   bool get autoDetectIndent => additionalIndent == null;
 }
 
-/**
- * A range of characters in the YAML document, from [start] to [end] (inclusive).
- */
+/// A range of characters in the YAML document, from [start] to [end]
+/// (inclusive).
 class _Range {
-  /** The first character in the range. */
+  /// The first character in the range.
   final int start;
 
-  /** The last character in the range. */
+  /// The last character in the range.
   final int end;
 
   _Range(this.start, this.end);
 
-  /** Returns whether or not [pos] lies within this range. */
+  /// Returns whether or not [pos] lies within this range.
   bool contains(int pos) => pos >= start && pos <= end;
 }
 
-/**
- * A map that associates [E] values with [_Range]s. It's efficient to create new
- * associations, but finding the value associated with a position is more
- * expensive.
- */
+/// A map that associates [E] values with [_Range]s. It's efficient to create
+/// new associations, but finding the value associated with a position is more
+/// expensive.
 class _RangeMap<E> {
-  /** The ranges and their associated elements. */
+  /// The ranges and their associated elements.
   final List<_Pair<_Range, E>> contents;
 
   _RangeMap() : this.contents = <_Pair<_Range, E>>[];
 
-  /**
-   * Returns the value associated with the range in which [pos] lies, or null if
-   * there is no such range. If there's more than one such range, the most
-   * recently set one is used.
-   */
+  /// Returns the value associated with the range in which [pos] lies, or null
+  /// if there is no such range. If there's more than one such range, the most
+  /// recently set one is used.
   E operator[](int pos) {
     // Iterate backwards through contents so the more recent range takes
     // precedence. TODO(nweiz): clean this up when issue 2804 is fixed.
@@ -1993,7 +1933,7 @@
     return null;
   }
 
-  /** Associates [value] with [range]. */
+  /// Associates [value] with [range].
   operator[]=(_Range range, E value) =>
     contents.add(new _Pair<_Range, E>(range, value));
 }
diff --git a/utils/pub/yaml/visitor.dart b/utils/pub/yaml/visitor.dart
index 22ada8b..1d6282a 100644
--- a/utils/pub/yaml/visitor.dart
+++ b/utils/pub/yaml/visitor.dart
@@ -2,18 +2,20 @@
 // for 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 visitor pattern for YAML documents. */
+part of yaml;
+
+/// The visitor pattern for YAML documents.
 class _Visitor {
-  /** Returns [alias]. */
+  /// Returns [alias].
   visitAlias(_AliasNode alias) => alias;
 
-  /** Returns [scalar]. */
+  /// Returns [scalar].
   visitScalar(_ScalarNode scalar) => scalar;
 
-  /** Visits each node in [seq] and returns a list of the results. */
+  /// Visits each node in [seq] and returns a list of the results.
   visitSequence(_SequenceNode seq) => seq.content.map((e) => e.visit(this));
 
-  /** Visits each key and value in [map] and returns a map of the results. */
+  /// Visits each key and value in [map] and returns a map of the results.
   visitMapping(_MappingNode map) {
     var out = new YamlMap();
     for (var key in map.content.keys) {
diff --git a/utils/pub/yaml/yaml.dart b/utils/pub/yaml/yaml.dart
index 3918743..11984c3 100644
--- a/utils/pub/yaml/yaml.dart
+++ b/utils/pub/yaml/yaml.dart
@@ -15,16 +15,14 @@
 part 'composer.dart';
 part 'constructor.dart';
 
-/**
- * Loads a single document from a YAML string. If the string contains more than
- * one document, this throws an error.
- *
- * The return value is mostly normal Dart objects. However, since YAML mappings
- * support some key types that the default Dart map implementation doesn't
- * (null, NaN, booleans, lists, and maps), all maps in the returned document are
- * YamlMaps. These have a few small behavioral differences from the default Map
- * implementation; for details, see the YamlMap class.
- */
+/// Loads a single document from a YAML string. If the string contains more than
+/// one document, this throws an error.
+///
+/// The return value is mostly normal Dart objects. However, since YAML mappings
+/// support some key types that the default Dart map implementation doesn't
+/// (null, NaN, booleans, lists, and maps), all maps in the returned document
+/// are YamlMaps. These have a few small behavioral differences from the default
+/// Map implementation; for details, see the YamlMap class.
 loadYaml(String yaml) {
   var stream = loadYamlStream(yaml);
   if (stream.length != 1) {
@@ -33,21 +31,19 @@
   return stream[0];
 }
 
-/**
- * Loads a stream of documents from a YAML string.
- *
- * The return value is mostly normal Dart objects. However, since YAML mappings
- * support some key types that the default Dart map implementation doesn't
- * (null, NaN, booleans, lists, and maps), all maps in the returned document are
- * YamlMaps. These have a few small behavioral differences from the default Map
- * implementation; for details, see the YamlMap class.
- */
+/// Loads a stream of documents from a YAML string.
+///
+/// The return value is mostly normal Dart objects. However, since YAML mappings
+/// support some key types that the default Dart map implementation doesn't
+/// (null, NaN, booleans, lists, and maps), all maps in the returned document
+/// are YamlMaps. These have a few small behavioral differences from the default
+/// Map implementation; for details, see the YamlMap class.
 List loadYamlStream(String yaml) {
   return new _Parser(yaml).l_yamlStream().map((doc) =>
       new _Constructor(new _Composer(doc).compose()).construct());
 }
 
-/** An error thrown by the YAML processor. */
+/// An error thrown by the YAML processor.
 class YamlException implements Exception {
   String msg;
 
diff --git a/utils/pub/yaml/yaml_map.dart b/utils/pub/yaml/yaml_map.dart
index 0826cee..285027c 100644
--- a/utils/pub/yaml/yaml_map.dart
+++ b/utils/pub/yaml/yaml_map.dart
@@ -2,15 +2,15 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/**
- * This class wraps behaves almost identically to the normal Dart Map
- * implementation, with the following differences:
- *
- * * It allows null, NaN, boolean, list, and map keys.
- * * It defines `==` structurally. That is, `yamlMap1 == yamlMap2` if they have
- *   the same contents.
- * * It has a compatible [hashCode] method.
- */
+part of yaml;
+
+/// This class wraps behaves almost identically to the normal Dart Map
+/// implementation, with the following differences:
+///
+///  *  It allows null, NaN, boolean, list, and map keys.
+///  *  It defines `==` structurally. That is, `yamlMap1 == yamlMap2` if they
+///     have the same contents.
+///  *  It has a compatible [hashCode] method.
 class YamlMap implements Map {
   Map _map;
 
@@ -42,7 +42,7 @@
     return deepEquals(this, other);
   }
 
-  /** Wraps an object for use as a key in the map. */
+  /// Wraps an object for use as a key in the map.
   _wrapKey(obj) {
     if (obj != null && obj is! bool && obj is! List &&
         (obj is! double || !obj.isNan()) &&
@@ -54,14 +54,12 @@
     return new _WrappedHashKey(obj);
   }
 
-  /** Unwraps an object that was used as a key in the map. */
+  /// Unwraps an object that was used as a key in the map.
   _unwrapKey(obj) => obj is _WrappedHashKey ? obj.value : obj;
 }
 
-/**
- * A class for wrapping normally-unhashable objects that are being used as keys
- * in a YamlMap.
- */
+/// A class for wrapping normally-unhashable objects that are being used as keys
+/// in a YamlMap.
 class _WrappedHashKey {
   var value;
 
@@ -71,17 +69,15 @@
 
   String toString() => value.toString();
 
-  /** This is defined as both values being structurally equal. */
+  /// This is defined as both values being structurally equal.
   bool operator ==(other) {
     if (other is! _WrappedHashKey) return false;
     return deepEquals(this.value, other.value);
   }
 }
 
-/**
- * Returns the hash code for [obj]. This includes null, true, false, maps, and
- * lists. Also handles self-referential structures.
- */
+/// Returns the hash code for [obj]. This includes null, true, false, maps, and
+/// lists. Also handles self-referential structures.
 int _hashCode(obj, [List parents]) {
   if (parents == null) {
     parents = [];
@@ -99,8 +95,8 @@
         _hashCode(obj.values, parents);
     }
     if (obj is List) {
-      // This is probably a really bad hash function, but presumably we'll get this
-      // in the standard library before it actually matters.
+      // This is probably a really bad hash function, but presumably we'll get
+      // this in the standard library before it actually matters.
       int hash = 0;
       for (var e in obj) {
         hash ^= _hashCode(e, parents);
diff --git a/utils/tests/pub/curl_client_test.dart b/utils/tests/pub/curl_client_test.dart
index 98432e0..c040c2d 100644
--- a/utils/tests/pub/curl_client_test.dart
+++ b/utils/tests/pub/curl_client_test.dart
@@ -6,14 +6,210 @@
 
 import 'dart:io';
 import 'dart:isolate';
+import 'dart:json';
 import 'dart:uri';
 
 import '../../../pkg/unittest/lib/unittest.dart';
 import '../../../pkg/http/lib/http.dart' as http;
-import '../../../pkg/http/test/utils.dart';
 import '../../pub/curl_client.dart';
 import '../../pub/io.dart';
 
+// TODO(rnystrom): All of the code from here to the "---..." line was copied
+// from pkg/http/test/utils.dart and pkg/http/lib/src/utils.dart. It's copied
+// here because http/test/utils.dart is now using "package:" imports and this
+// is not. You cannot mix those because you end up with duplicate copies of the
+// same library in memory. Since curl_client is going away soon anyway, I'm
+// just copying the code here. Delete all of this when curl client is removed.
+
+/// 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);
+  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.
+  return new String.fromCharCodes(bytes);
+}
+
+/// The current server instance.
+HttpServer _server;
+
+/// The URL for the current server instance.
+Uri get serverUrl => new Uri.fromString('http://localhost:${_server.port}');
+
+/// A dummy URL for constructing requests that won't be sent.
+Uri get dummyUrl => new Uri.fromString('http://dartlang.org/');
+
+/// Starts a new HTTP server.
+void startServer() {
+  _server = new HttpServer();
+
+  _server.addRequestHandler((request) => request.path == '/error',
+      (request, response) {
+    response.statusCode = 400;
+    response.contentLength = 0;
+    response.outputStream.close();
+  });
+
+  _server.addRequestHandler((request) => request.path == '/loop',
+      (request, response) {
+    var n = int.parse(new Uri.fromString(request.uri).query);
+    response.statusCode = 302;
+    response.headers.set('location',
+        serverUrl.resolve('/loop?${n + 1}').toString());
+    response.contentLength = 0;
+    response.outputStream.close();
+  });
+
+  _server.addRequestHandler((request) => request.path == '/redirect',
+      (request, response) {
+    response.statusCode = 302;
+    response.headers.set('location', serverUrl.resolve('/').toString());
+    response.contentLength = 0;
+    response.outputStream.close();
+  });
+
+  _server.defaultRequestHandler = (request, response) {
+    consumeInputStream(request.inputStream).then((requestBodyBytes) {
+      response.statusCode = 200;
+      response.headers.contentType = new ContentType("application", "json");
+
+      var requestBody;
+      if (requestBodyBytes.isEmpty) {
+        requestBody = null;
+      } else if (request.headers.contentType.charset != null) {
+        var encoding = requiredEncodingForCharset(
+            request.headers.contentType.charset);
+        requestBody = decodeString(requestBodyBytes, encoding);
+      } else {
+        requestBody = requestBodyBytes;
+      }
+
+      var content = {
+        'method': request.method,
+        'path': request.path,
+        'headers': <String>{}
+      };
+      if (requestBody != null) content['body'] = requestBody;
+      request.headers.forEach((name, values) {
+        // These headers are automatically generated by dart:io, so we don't
+        // want to test them here.
+        if (name == 'cookie' || name == 'host') return;
+
+        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.outputStream.writeString(body, outputEncoding);
+      response.outputStream.close();
+    });
+  };
+
+  _server.listen("127.0.0.1", 0);
+}
+
+/// Stops the current HTTP server.
+void stopServer() {
+  _server.close();
+  _server = null;
+}
+
+/// A matcher that matches JSON that parses to a value that matches the inner
+/// matcher.
+Matcher parse(matcher) => new _Parse(matcher);
+
+class _Parse extends BaseMatcher {
+  final Matcher _matcher;
+
+  _Parse(this._matcher);
+
+  bool matches(item, MatchState matchState) {
+    if (item is! String) return false;
+
+    var parsed;
+    try {
+      parsed = JSON.parse(item);
+    } catch (e) {
+      return false;
+    }
+
+    return _matcher.matches(parsed, matchState);
+  }
+
+  Description describe(Description description) {
+    return description.add('parses to a value that ')
+      .addDescriptionOf(_matcher);
+  }
+}
+
+// TODO(nweiz): remove this once it's built in to unittest
+/// A matcher for StateErrors.
+const isStateError = const _StateError();
+
+/// A matcher for functions that throw StateError.
+const Matcher throwsStateError =
+    const Throws(isStateError);
+
+class _StateError extends TypeMatcher {
+  const _StateError() : super("StateError");
+  bool matches(item, MatchState matchState) => item is StateError;
+}
+
+/// A matcher for HttpExceptions.
+const isHttpException = const _HttpException();
+
+/// A matcher for functions that throw HttpException.
+const Matcher throwsHttpException =
+    const Throws(isHttpException);
+
+class _HttpException extends TypeMatcher {
+  const _HttpException() : super("HttpException");
+  bool matches(item, MatchState matchState) => item is HttpException;
+}
+
+/// A matcher for RedirectLimitExceededExceptions.
+const isRedirectLimitExceededException =
+    const _RedirectLimitExceededException();
+
+/// A matcher for functions that throw RedirectLimitExceededException.
+const Matcher throwsRedirectLimitExceededException =
+    const Throws(isRedirectLimitExceededException);
+
+class _RedirectLimitExceededException extends TypeMatcher {
+  const _RedirectLimitExceededException() :
+      super("RedirectLimitExceededException");
+
+  bool matches(item, MatchState matchState) =>
+    item is RedirectLimitExceededException;
+}
+
+// ----------------------------------------------------------------------------
+
 void main() {
   setUp(startServer);
   tearDown(stopServer);
@@ -58,11 +254,11 @@
           'content-type': [
             'application/x-www-form-urlencoded; charset=UTF-8'
           ],
-          'content-length': ['42'],
+          'content-length': ['40'],
           'x-random-header': ['Value'],
           'x-other-header': ['Other Value']
         },
-        'body': 'some-field=value&other-field=other%20value'
+        'body': 'some-field=value&other-field=other+value'
       })));
     }), completes);
   });
@@ -102,11 +298,11 @@
           'content-type': [
             'application/x-www-form-urlencoded; charset=UTF-8'
           ],
-          'content-length': ['42'],
+          'content-length': ['40'],
           'x-random-header': ['Value'],
           'x-other-header': ['Other Value']
         },
-        'body': 'some-field=value&other-field=other%20value'
+        'body': 'some-field=value&other-field=other+value'
       })));
     }), completes);
   });
diff --git a/utils/tests/pub/directory_tree_test.dart b/utils/tests/pub/directory_tree_test.dart
index e9f892b..8a45a6f 100644
--- a/utils/tests/pub/directory_tree_test.dart
+++ b/utils/tests/pub/directory_tree_test.dart
@@ -14,33 +14,60 @@
 
   test('up to ten files in one directory are shown', () {
     var files = [
-      "a.dart",
-      "b.dart",
-      "c.dart",
-      "d.dart",
-      "e.dart",
-      "f.dart",
-      "g.dart",
-      "h.dart",
-      "i.dart",
-      "j.dart"
+      "dir/a.dart",
+      "dir/b.dart",
+      "dir/c.dart",
+      "dir/d.dart",
+      "dir/e.dart",
+      "dir/f.dart",
+      "dir/g.dart",
+      "dir/h.dart",
+      "dir/i.dart",
+      "dir/j.dart"
     ];
     expect(generateTree(files), equals("""
-|-- a.dart
-|-- b.dart
-|-- c.dart
-|-- d.dart
-|-- e.dart
-|-- f.dart
-|-- g.dart
-|-- h.dart
-|-- i.dart
-'-- j.dart
+'-- dir
+    |-- a.dart
+    |-- b.dart
+    |-- c.dart
+    |-- d.dart
+    |-- e.dart
+    |-- f.dart
+    |-- g.dart
+    |-- h.dart
+    |-- i.dart
+    '-- j.dart
 """));
   });
 
   test('files are elided if there are more than ten', () {
     var files = [
+      "dir/a.dart",
+      "dir/b.dart",
+      "dir/c.dart",
+      "dir/d.dart",
+      "dir/e.dart",
+      "dir/f.dart",
+      "dir/g.dart",
+      "dir/h.dart",
+      "dir/i.dart",
+      "dir/j.dart",
+      "dir/k.dart"
+    ];
+    expect(generateTree(files), equals("""
+'-- dir
+    |-- a.dart
+    |-- b.dart
+    |-- c.dart
+    | (5 more...)
+    |-- i.dart
+    |-- j.dart
+    '-- k.dart
+"""));
+  });
+
+  test('files are not elided at the top level', () {
+    var files = [
       "a.dart",
       "b.dart",
       "c.dart",
@@ -57,7 +84,11 @@
 |-- a.dart
 |-- b.dart
 |-- c.dart
-|   (5 more...)
+|-- d.dart
+|-- e.dart
+|-- f.dart
+|-- g.dart
+|-- h.dart
 |-- i.dart
 |-- j.dart
 '-- k.dart
@@ -105,7 +136,7 @@
     |-- absolute_test.dart
     |-- all_test.dart
     |-- basename_test.dart
-    |   (7 more...)
+    | (7 more...)
     |-- path_windows_test.dart
     |-- relative_test.dart
     '-- split_test.dart
diff --git a/utils/tests/pub/io_test.dart b/utils/tests/pub/io_test.dart
new file mode 100644
index 0000000..01b1590
--- /dev/null
+++ b/utils/tests/pub/io_test.dart
@@ -0,0 +1,120 @@
+// 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 io_test;
+
+import '../../../pkg/unittest/lib/unittest.dart';
+import '../../pub/io.dart';
+
+main() {
+  group('listDir', () {
+    test('lists a simple directory non-recursively', () {
+      expect(withTempDir((path) {
+        var future = writeTextFile(join(path, 'file1.txt'), '')
+            .chain((_) => writeTextFile(join(path, 'file2.txt'), ''))
+            .chain((_) => createDir(join(path, 'subdir')))
+            .chain((_) => writeTextFile(join(path, 'subdir', 'file3.txt'), ''))
+            .chain((_) => listDir(path));
+        expect(future, completion(unorderedEquals([
+          join(path, 'file1.txt'),
+          join(path, 'file2.txt'),
+          join(path, 'subdir')
+        ])));
+        return future;
+      }), completes);
+    });
+
+    test('lists a simple directory recursively', () {
+      expect(withTempDir((path) {
+        var future = writeTextFile(join(path, 'file1.txt'), '')
+            .chain((_) => writeTextFile(join(path, 'file2.txt'), ''))
+            .chain((_) => createDir(join(path, 'subdir')))
+            .chain((_) => writeTextFile(join(path, 'subdir', 'file3.txt'), ''))
+            .chain((_) => listDir(path, recursive: true));
+        expect(future, completion(unorderedEquals([
+          join(path, 'file1.txt'),
+          join(path, 'file2.txt'),
+          join(path, 'subdir'),
+          join(path, 'subdir/file3.txt'),
+        ])));
+        return future;
+      }), completes);
+    });
+
+    test('ignores hidden files by default', () {
+      expect(withTempDir((path) {
+        var future = writeTextFile(join(path, 'file1.txt'), '')
+            .chain((_) => writeTextFile(join(path, 'file2.txt'), ''))
+            .chain((_) => writeTextFile(join(path, '.file3.txt'), ''))
+            .chain((_) => createDir(join(path, '.subdir')))
+            .chain((_) => writeTextFile(join(path, '.subdir', 'file3.txt'), ''))
+            .chain((_) => listDir(path, recursive: true));
+        expect(future, completion(unorderedEquals([
+          join(path, 'file1.txt'),
+          join(path, 'file2.txt')
+        ])));
+        return future;
+      }), completes);
+    });
+
+    test('includes hidden files when told to', () {
+      expect(withTempDir((path) {
+        var future = writeTextFile(join(path, 'file1.txt'), '')
+            .chain((_) => writeTextFile(join(path, 'file2.txt'), ''))
+            .chain((_) => writeTextFile(join(path, '.file3.txt'), ''))
+            .chain((_) => createDir(join(path, '.subdir')))
+            .chain((_) => writeTextFile(join(path, '.subdir', 'file3.txt'), ''))
+            .chain((_) {
+              return listDir(path, recursive: true, includeHiddenFiles: true);
+            });
+        expect(future, completion(unorderedEquals([
+          join(path, 'file1.txt'),
+          join(path, 'file2.txt'),
+          join(path, '.file3.txt'),
+          join(path, '.subdir'),
+          join(path, '.subdir/file3.txt')
+        ])));
+        return future;
+      }), completes);
+    });
+
+    test('returns the unresolved paths for symlinks', () {
+      expect(withTempDir((path) {
+        var dirToList = join(path, 'dir-to-list');
+        var future = writeTextFile(join(path, 'file1.txt'), '')
+            .chain((_) => writeTextFile(join(path, 'file2.txt'), ''))
+            .chain((_) => createDir(dirToList))
+            .chain((_) {
+              return createSymlink(
+                  join(path, 'file1.txt'),
+                  join(dirToList, 'link1'));
+            }).chain((_) => createDir(join(dirToList, 'subdir')))
+            .chain((_) {
+              return createSymlink(
+                  join(path, 'file2.txt'),
+                  join(dirToList, 'subdir', 'link2'));
+            }).chain((_) => listDir(dirToList, recursive: true));
+        expect(future, completion(unorderedEquals([
+          join(dirToList, 'link1'),
+          join(dirToList, 'subdir'),
+          join(dirToList, 'subdir/link2'),
+        ])));
+        return future;
+      }), completes);
+    });
+
+    test('works with recursive symlinks', () {
+      expect(withTempDir((path) {
+        var future = writeTextFile(join(path, 'file1.txt'), '')
+            .chain((_) => createSymlink(path, join(path, 'linkdir')))
+            .chain((_) => listDir(path, recursive: true));
+        expect(future, completion(unorderedEquals([
+          join(path, 'file1.txt'),
+          join(path, 'linkdir')
+        ])));
+        return future;
+      }), completes);
+    });
+  });
+}
diff --git a/utils/tests/pub/oauth2_test.dart b/utils/tests/pub/oauth2_test.dart
index f640e11..f3d38e0 100644
--- a/utils/tests/pub/oauth2_test.dart
+++ b/utils/tests/pub/oauth2_test.dart
@@ -71,7 +71,7 @@
       return consumeInputStream(request.inputStream).transform((bytes) {
         var body = new String.fromCharCodes(bytes);
         expect(body, matches(
-            new RegExp(r'(^|&)refresh_token=refresh%20token(&|$)')));
+            new RegExp(r'(^|&)refresh_token=refresh\+token(&|$)')));
 
         response.headers.contentType = new ContentType("application", "json");
         response.outputStream.writeString(JSON.stringify({
@@ -149,6 +149,36 @@
 
     run();
   });
+
+  test('with server-rejected credentials, authenticates again and saves '
+      'credentials.json', () {
+    var server = new ScheduledServer();
+    credentialsFile(server, 'access token').scheduleCreate();
+    var pub = startPubLish(server);
+
+    confirmPublish(pub);
+
+    server.handle('GET', '/packages/versions/new.json', (request, response) {
+      response.statusCode = 401;
+      response.headers.set('www-authenticate', 'Bearer error="invalid_token",'
+          ' error_description="your token sucks"');
+      response.outputStream.writeString(JSON.stringify({
+        'error': {'message': 'your token sucks'}
+      }));
+      response.outputStream.close();
+    });
+
+    expectLater(pub.nextErrLine(), equals('OAuth2 authorization failed (your '
+        'token sucks).'));
+    // TODO(rnystrom): The confirm line is run together with this one because
+    // in normal usage, the user will have entered a newline on stdin which
+    // gets echoed to the terminal. Do something better here?
+    expectLater(pub.nextLine(), equals(
+        'Looks great! Are you ready to upload your package (y/n)? '
+        'Pub needs your authorization to upload packages on your behalf.'));
+    pub.kill();
+    run();
+  });
 }
 
 void authorizePub(ScheduledProcess pub, ScheduledServer server,
@@ -181,7 +211,7 @@
   server.handle('POST', '/token', (request, response) {
     return consumeInputStream(request.inputStream).transform((bytes) {
       var body = new String.fromCharCodes(bytes);
-      expect(body, matches(new RegExp(r'(^|&)code=access%20code(&|$)')));
+      expect(body, matches(new RegExp(r'(^|&)code=access\+code(&|$)')));
 
       response.headers.contentType = new ContentType("application", "json");
       response.outputStream.writeString(JSON.stringify({
diff --git a/utils/tests/pub/pub.status b/utils/tests/pub/pub.status
index 4e6f9e3..86e5e4e 100644
--- a/utils/tests/pub/pub.status
+++ b/utils/tests/pub/pub.status
@@ -9,3 +9,6 @@
 # Pub only runs on the standalone VM, not the browser.
 [ $runtime == drt || $runtime == dartium || $runtime == opera ]
 *: Skip
+
+[ $system == windows ]
+io_test: Fail, Pass, Timeout # Issue 7505
diff --git a/utils/tests/pub/pub_lish_test.dart b/utils/tests/pub/pub_lish_test.dart
index b787ec9..6955578 100644
--- a/utils/tests/pub/pub_lish_test.dart
+++ b/utils/tests/pub/pub_lish_test.dart
@@ -79,35 +79,6 @@
   // TODO(nweiz): Once a multipart/form-data parser in Dart exists, we should
   // test that "pub lish" chooses the correct files to publish.
 
-  test('credentials are invalid', () {
-    var server = new ScheduledServer();
-    credentialsFile(server, 'access token').scheduleCreate();
-    var pub = startPubLish(server);
-
-    confirmPublish(pub);
-
-    server.handle('GET', '/packages/versions/new.json', (request, response) {
-      response.statusCode = 401;
-      response.headers.set('www-authenticate', 'Bearer error="invalid_token",'
-          ' error_description="your token sucks"');
-      response.outputStream.writeString(JSON.stringify({
-        'error': {'message': 'your token sucks'}
-      }));
-      response.outputStream.close();
-    });
-
-    expectLater(pub.nextErrLine(), equals('OAuth2 authorization failed (your '
-        'token sucks).'));
-    // TODO(rnystrom): The confirm line is run together with this one because
-    // in normal usage, the user will have entered a newline on stdin which
-    // gets echoed to the terminal. Do something better here?
-    expectLater(pub.nextLine(), equals(
-        'Looks great! Are you ready to upload your package (y/n)? '
-        'Pub needs your authorization to upload packages on your behalf.'));
-    pub.kill();
-    run();
-  });
-
   test('package validation has an error', () {
     var package = package("test_pkg", "1.0.0");
     package.remove("homepage");
diff --git a/utils/tests/pub/pub_test.dart b/utils/tests/pub/pub_test.dart
index 4ad65ad..fd8e5c7 100644
--- a/utils/tests/pub/pub_test.dart
+++ b/utils/tests/pub/pub_test.dart
@@ -27,11 +27,12 @@
     -v, --verbose         Shortcut for "--verbosity=all"
 
     Available commands:
-      help      Display help information for Pub.
-      install   Install the current package's dependencies.
-      publish   Publish the current package to pub.dartlang.org.
-      update    Update the current package's dependencies to the latest versions.
-      version   Print pub version.
+      help       Display help information for Pub.
+      install    Install the current package's dependencies.
+      publish    Publish the current package to pub.dartlang.org.
+      update     Update the current package's dependencies to the latest versions.
+      uploader   Manage uploaders for a package on pub.dartlang.org.
+      version    Print pub version.
 
     Use "pub help [command]" for more information about a command.
     """;
diff --git a/utils/tests/pub/pub_uploader_test.dart b/utils/tests/pub/pub_uploader_test.dart
new file mode 100644
index 0000000..d4b2a1d
--- /dev/null
+++ b/utils/tests/pub/pub_uploader_test.dart
@@ -0,0 +1,187 @@
+// 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_uploader_test;
+
+import 'dart:io';
+import 'dart:json';
+
+import 'test_pub.dart';
+import '../../../pkg/unittest/lib/unittest.dart';
+import '../../pub/utils.dart';
+import '../../pub/io.dart';
+
+final USAGE_STRING = '''
+    Manage uploaders for a package on pub.dartlang.org.
+
+    Usage: pub uploader [options] {add/remove} <email>
+    --server     The package server on which the package is hosted
+                 (defaults to "https://pub.dartlang.org")
+
+    --package    The package whose uploaders will be modified
+                 (defaults to the current package)
+    ''';
+
+ScheduledProcess startPubUploader(ScheduledServer server, List<String> args) {
+  var tokenEndpoint = server.url.transform((url) =>
+      url.resolve('/token').toString());
+  args = flatten(['uploader', '--server', tokenEndpoint, args]);
+  return startPub(args: args, tokenEndpoint: tokenEndpoint);
+}
+
+main() {
+  group('displays usage', () {
+    test('when run with no arguments', () =>
+        runPub(args: ['uploader'], output: USAGE_STRING, exitCode: 64));
+
+    test('when run with only a command', () =>
+        runPub(args: ['uploader', 'add'], output: USAGE_STRING, exitCode: 64));
+
+    test('when run with an invalid command', () => runPub(
+        args: ['uploader', 'foo', 'email'],
+        output: USAGE_STRING, exitCode: 64));
+  });
+
+  test('adds an uploader', () {
+    var server = new ScheduledServer();
+    credentialsFile(server, 'access token').scheduleCreate();
+    var pub = startPubUploader(server, ['--package', 'pkg', 'add', 'email']);
+
+    server.handle('POST', '/packages/pkg/uploaders.json', (request, response) {
+      expect(consumeInputStream(request.inputStream).transform((bodyBytes) {
+        expect(new String.fromCharCodes(bodyBytes), equals('email=email'));
+
+        response.headers.contentType = new ContentType("application", "json");
+        response.outputStream.writeString(JSON.stringify({
+          'success': {'message': 'Good job!'}
+        }));
+        response.outputStream.close();
+      }), completes);
+    });
+
+    expectLater(pub.nextLine(), equals('Good job!'));
+    pub.shouldExit(0);
+
+    run();
+  });
+
+  test('removes an uploader', () {
+    var server = new ScheduledServer();
+    credentialsFile(server, 'access token').scheduleCreate();
+    var pub = startPubUploader(server, ['--package', 'pkg', 'remove', 'email']);
+
+    server.handle('DELETE', '/packages/pkg/uploaders/email.json',
+        (request, response) {
+      response.headers.contentType = new ContentType("application", "json");
+      response.outputStream.writeString(JSON.stringify({
+        'success': {'message': 'Good job!'}
+      }));
+      response.outputStream.close();
+    });
+
+    expectLater(pub.nextLine(), equals('Good job!'));
+    pub.shouldExit(0);
+
+    run();
+  });
+
+  test('defaults to the current package', () {
+    normalPackage.scheduleCreate();
+
+    var server = new ScheduledServer();
+    credentialsFile(server, 'access token').scheduleCreate();
+    var pub = startPubUploader(server, ['add', 'email']);
+
+    server.handle('POST', '/packages/test_pkg/uploaders.json',
+        (request, response) {
+      response.headers.contentType = new ContentType("application", "json");
+      response.outputStream.writeString(JSON.stringify({
+        'success': {'message': 'Good job!'}
+      }));
+      response.outputStream.close();
+    });
+
+    expectLater(pub.nextLine(), equals('Good job!'));
+    pub.shouldExit(0);
+
+    run();
+  });
+
+  test('add provides an error', () {
+    var server = new ScheduledServer();
+    credentialsFile(server, 'access token').scheduleCreate();
+    var pub = startPubUploader(server, ['--package', 'pkg', 'add', 'email']);
+
+    server.handle('POST', '/packages/pkg/uploaders.json', (request, response) {
+      response.statusCode = 400;
+      response.headers.contentType = new ContentType("application", "json");
+      response.outputStream.writeString(JSON.stringify({
+        'error': {'message': 'Bad job!'}
+      }));
+      response.outputStream.close();
+    });
+
+    expectLater(pub.nextErrLine(), equals('Bad job!'));
+    pub.shouldExit(1);
+
+    run();
+  });
+
+  test('remove provides an error', () {
+    var server = new ScheduledServer();
+    credentialsFile(server, 'access token').scheduleCreate();
+    var pub = startPubUploader(server,
+        ['--package', 'pkg', 'remove', 'e/mail']);
+
+    server.handle('DELETE', '/packages/pkg/uploaders/e%2Fmail.json',
+        (request, response) {
+      response.statusCode = 400;
+      response.headers.contentType = new ContentType("application", "json");
+      response.outputStream.writeString(JSON.stringify({
+        'error': {'message': 'Bad job!'}
+      }));
+      response.outputStream.close();
+    });
+
+    expectLater(pub.nextErrLine(), equals('Bad job!'));
+    pub.shouldExit(1);
+
+    run();
+  });
+
+  test('add provides invalid JSON', () {
+    var server = new ScheduledServer();
+    credentialsFile(server, 'access token').scheduleCreate();
+    var pub = startPubUploader(server, ['--package', 'pkg', 'add', 'email']);
+
+    server.handle('POST', '/packages/pkg/uploaders.json', (request, response) {
+      response.outputStream.writeString("{not json");
+      response.outputStream.close();
+    });
+
+    expectLater(pub.nextErrLine(), equals('Invalid server response:'));
+    expectLater(pub.nextErrLine(), equals('{not json'));
+    pub.shouldExit(1);
+
+    run();
+  });
+
+  test('remove provides invalid JSON', () {
+    var server = new ScheduledServer();
+    credentialsFile(server, 'access token').scheduleCreate();
+    var pub = startPubUploader(server, ['--package', 'pkg', 'remove', 'email']);
+
+    server.handle('DELETE', '/packages/pkg/uploaders/email.json',
+        (request, response) {
+      response.outputStream.writeString("{not json");
+      response.outputStream.close();
+    });
+
+    expectLater(pub.nextErrLine(), equals('Invalid server response:'));
+    expectLater(pub.nextErrLine(), equals('{not json'));
+    pub.shouldExit(1);
+
+    run();
+  });
+}
diff --git a/utils/tests/pub/test_pub.dart b/utils/tests/pub/test_pub.dart
index 80137a0..c9c8cc0 100644
--- a/utils/tests/pub/test_pub.dart
+++ b/utils/tests/pub/test_pub.dart
@@ -17,13 +17,15 @@
 import 'dart:uri';
 
 import '../../../pkg/oauth2/lib/oauth2.dart' as oauth2;
+import '../../../pkg/path/lib/path.dart' as path;
 import '../../../pkg/unittest/lib/unittest.dart';
+import '../../../pkg/http/lib/testing.dart';
 import '../../lib/file_system.dart' as fs;
 import '../../pub/entrypoint.dart';
 import '../../pub/git_source.dart';
 import '../../pub/hosted_source.dart';
+import '../../pub/http.dart';
 import '../../pub/io.dart';
-import '../../pub/path.dart' as path;
 import '../../pub/sdk_source.dart';
 import '../../pub/system_cache.dart';
 import '../../pub/utils.dart';
@@ -509,6 +511,10 @@
  */
 bool _abortScheduled = false;
 
+/// The time (in milliseconds) to wait for the entire scheduled test to
+/// complete.
+final _TIMEOUT = 30000;
+
 /**
  * Runs all the scheduled events for a test case. This should only be called
  * once per test case.
@@ -549,9 +555,9 @@
     return true;
   });
 
-  future.chain((_) => cleanup()).then((_) {
-    asyncDone();
-  });
+  timeout(future, _TIMEOUT, 'waiting for a test to complete')
+      .chain((_) => cleanup())
+      .then((_) => asyncDone());
 }
 
 /// Get the path to the root "util/test/pub" directory containing the pub tests.
@@ -566,7 +572,7 @@
  * Schedules a call to the Pub command-line utility. Runs Pub with [args] and
  * validates that its results match [output], [error], and [exitCode].
  */
-void schedulePub({List<String> args, Pattern output, Pattern error,
+void schedulePub({List args, Pattern output, Pattern error,
     Future<Uri> tokenEndpoint, int exitCode: 0}) {
   _schedule((sandboxDir) {
     return _doPub(runProcess, sandboxDir, args, tokenEndpoint)
@@ -596,37 +602,36 @@
   });
 }
 
-/**
- * A shorthand for [schedulePub] and [run] when no validation needs to be done
- * after Pub has been run.
- */
-void runPub({List<String> args, Pattern output, Pattern error,
-    int exitCode: 0}) {
+/// A shorthand for [schedulePub] and [run] when no validation needs to be done
+/// after Pub has been run.
+///
+/// Any futures in [args] will be resolved before the process is started.
+void runPub({List args, Pattern output, Pattern error, int exitCode: 0}) {
   schedulePub(args: args, output: output, error: error, exitCode: exitCode);
   run();
 }
 
 /// Starts a Pub process and returns a [ScheduledProcess] that supports
 /// interaction with that process.
-ScheduledProcess startPub({List<String> args}) {
+///
+/// Any futures in [args] will be resolved before the process is started.
+ScheduledProcess startPub({List args, Future<Uri> tokenEndpoint}) {
   var process = _scheduleValue((sandboxDir) =>
-      _doPub(startProcess, sandboxDir, args));
+      _doPub(startProcess, sandboxDir, args, tokenEndpoint));
   return new ScheduledProcess("pub", process);
 }
 
 /// Like [startPub], but runs `pub lish` in particular with [server] used both
 /// as the OAuth2 server (with "/token" as the token endpoint) and as the
 /// package server.
-ScheduledProcess startPubLish(ScheduledServer server, {List<String> args}) {
-  var process = _scheduleValue((sandboxDir) {
-    return server.url.chain((url) {
-      var tokenEndpoint = url.resolve('/token');
-      if (args == null) args = [];
-      args = flatten(['lish', '--server', url.toString(), args]);
-      return _doPub(startProcess, sandboxDir, args, tokenEndpoint);
-    });
-  });
-  return new ScheduledProcess("pub lish", process);
+///
+/// Any futures in [args] will be resolved before the process is started.
+ScheduledProcess startPubLish(ScheduledServer server, {List args}) {
+  var tokenEndpoint = server.url.transform((url) =>
+      url.resolve('/token').toString());
+  if (args == null) args = [];
+  args = flatten(['lish', '--server', tokenEndpoint, args]);
+  return startPub(args: args, tokenEndpoint: tokenEndpoint);
 }
 
 /// Handles the beginning confirmation process for uploading a packages.
@@ -649,10 +654,16 @@
 /// Calls [fn] with appropriately modified arguments to run a pub process. [fn]
 /// should have the same signature as [startProcess], except that the returned
 /// [Future] may have a type other than [Process].
-Future _doPub(Function fn, sandboxDir, List<String> args, Uri tokenEndpoint) {
+Future _doPub(Function fn, sandboxDir, List args, Future<Uri> tokenEndpoint) {
   String pathInSandbox(path) => join(getFullPath(sandboxDir), path);
 
-  return ensureDir(pathInSandbox(appPath)).chain((_) {
+  return Futures.wait([
+    ensureDir(pathInSandbox(appPath)),
+    _awaitObject(args),
+    tokenEndpoint == null ? new Future.immediate(null) : tokenEndpoint
+  ]).chain((results) {
+    var args = results[1];
+    var tokenEndpoint = results[2];
     // Find a Dart executable we can use to spawn. Use the same one that was
     // used to run this script itself.
     var dartBin = new Options().executable;
@@ -703,6 +714,18 @@
   });
 }
 
+/// Use [client] as the mock HTTP client for this test.
+///
+/// Note that this will only affect HTTP requests made via http.dart in the
+/// parent process.
+void useMockClient(MockClient client) {
+  var oldInnerClient = httpClient.inner;
+  httpClient.inner = client;
+  _scheduleCleanup((_) {
+    httpClient.inner = oldInnerClient;
+  });
+}
+
 Future<Directory> _setUpSandbox() => createTempDir();
 
 Future _runScheduled(Directory parentDir, List<_ScheduledEvent> scheduled) {
@@ -1419,7 +1442,8 @@
   /// Reads the next line of stdout from the process.
   Future<String> nextLine() {
     return _scheduleValue((_) {
-      return timeout(_stdout.chain(readLine), _SCHEDULE_TIMEOUT,
+      return timeout(_stdout.chain((stream) => readLine(stream)),
+          _SCHEDULE_TIMEOUT,
           "waiting for the next stdout line from process $name");
     });
   }
@@ -1427,7 +1451,8 @@
   /// Reads the next line of stderr from the process.
   Future<String> nextErrLine() {
     return _scheduleValue((_) {
-      return timeout(_stderr.chain(readLine), _SCHEDULE_TIMEOUT,
+      return timeout(_stderr.chain((stream) => readLine(stream)),
+          _SCHEDULE_TIMEOUT,
           "waiting for the next stderr line from process $name");
     });
   }
@@ -1559,7 +1584,8 @@
       var requestCompleteCompleter = new Completer();
       handlerCompleter.complete((request, response) {
         expect(request.method, equals(method));
-        expect(request.path, equals(path));
+        // TODO(nweiz): Use request.path once issue 7464 is fixed.
+        expect(new Uri.fromString(request.uri).path, equals(path));
 
         var future = handler(request, response);
         if (future == null) future = new Future.immediate(null);
diff --git a/utils/tests/pub/validator_test.dart b/utils/tests/pub/validator_test.dart
index d9877eb..96a8f03 100644
--- a/utils/tests/pub/validator_test.dart
+++ b/utils/tests/pub/validator_test.dart
@@ -9,9 +9,13 @@
 
 import 'test_pub.dart';
 import '../../../pkg/unittest/lib/unittest.dart';
+import '../../../pkg/http/lib/http.dart' as http;
+import '../../../pkg/http/lib/testing.dart';
 import '../../pub/entrypoint.dart';
 import '../../pub/io.dart';
 import '../../pub/validator.dart';
+import '../../pub/validator/dependency.dart';
+import '../../pub/validator/directory.dart';
 import '../../pub/validator/lib.dart';
 import '../../pub/validator/license.dart';
 import '../../pub/validator/name.dart';
@@ -29,6 +33,12 @@
   expectLater(schedulePackageValidation(fn), pairOf(isEmpty, isNot(isEmpty)));
 }
 
+Validator dependency(Entrypoint entrypoint) =>
+  new DependencyValidator(entrypoint);
+
+Validator directory(Entrypoint entrypoint) =>
+  new DirectoryValidator(entrypoint);
+
 Validator lib(Entrypoint entrypoint) => new LibValidator(entrypoint);
 
 Validator license(Entrypoint entrypoint) => new LicenseValidator(entrypoint);
@@ -46,7 +56,10 @@
 
     test('looks normal', () {
       dir(appPath, [libPubspec("test_pkg", "1.0.0")]).scheduleCreate();
+      expectNoValidationError(dependency);
+      expectNoValidationError(lib);
       expectNoValidationError(license);
+      expectNoValidationError(name);
       expectNoValidationError(pubspecField);
       run();
     });
@@ -102,6 +115,24 @@
       expectNoValidationError(lib);
       run();
     });
+
+    test('has an unconstrained dependency on "unittest"', () {
+      dir(appPath, [
+        libPubspec("test_pkg", "1.0.0", [
+          {'hosted': 'unittest'}
+        ])
+      ]).scheduleCreate();
+      expectNoValidationError(dependency);
+      run();
+    });
+
+    test('has a nested directory named "tools"', () {
+      dir(appPath, [
+        dir("foo", [dir("tools")])
+      ]).scheduleCreate();
+      expectNoValidationError(directory);
+      run();
+    });
   });
 
   group('should consider a package invalid if it', () {
@@ -210,7 +241,7 @@
       run();
     });
 
-    test('has a package name that is a Dart identifier', () {
+    test('has a package name that is a Dart reserved word', () {
       dir(appPath, [libPubspec("operator", "1.0.0")]).scheduleCreate();
       expectValidationError(name);
       run();
@@ -243,7 +274,7 @@
       run();
     });
 
-    test('has a library name that is a Dart identifier', () {
+    test('has a library name that is a Dart reserved word', () {
       dir(appPath, [
         libPubspec("test_pkg", "1.0.0"),
         dir("lib", [file("operator.dart", "int i = 0;")])
@@ -252,6 +283,15 @@
       run();
     });
 
+    test('has a single library named differently than the package', () {
+      file(join(appPath, "lib", "test_pkg.dart"), '').scheduleDelete();
+      dir(appPath, [
+        dir("lib", [file("best_pkg.dart", "int i = 0;")])
+      ]).scheduleCreate();
+      expectValidationWarning(name);
+      run();
+    });
+
     test('has no lib directory', () {
       dir(join(appPath, "lib")).scheduleDelete();
       expectValidationError(lib);
@@ -274,5 +314,259 @@
       expectValidationError(lib);
       run();
     });
+
+    group('has a dependency with a non-hosted source', () {
+      group('where a hosted version of that dependency exists', () {
+        test("and should suggest the hosted package's primary version", () {
+          useMockClient(new MockClient((request) {
+            expect(request.method, equals("GET"));
+            expect(request.url.path, equals("/packages/foo.json"));
+
+            return new Future.immediate(new http.Response(JSON.stringify({
+              "name": "foo",
+              "uploaders": ["nweiz@google.com"],
+              "versions": ["3.0.0-pre", "2.0.0", "1.0.0"]
+            }), 200));
+          }));
+
+          dir(appPath, [
+            libPubspec("test_pkg", "1.0.0", [
+              {'git': 'git://github.com/dart-lang/foo'}
+            ])
+          ]).scheduleCreate();
+
+          expectLater(schedulePackageValidation(dependency),
+              pairOf(isEmpty, someElement(contains(
+                  '  foo: ">=2.0.0 <3.0.0"'))));
+
+          run();
+        });
+
+        test("and should suggest the hosted package's prerelease version if "
+            "it's the only version available", () {
+          useMockClient(new MockClient((request) {
+            expect(request.method, equals("GET"));
+            expect(request.url.path, equals("/packages/foo.json"));
+
+            return new Future.immediate(new http.Response(JSON.stringify({
+              "name": "foo",
+              "uploaders": ["nweiz@google.com"],
+              "versions": ["3.0.0-pre", "2.0.0-pre"]
+            }), 200));
+          }));
+
+          dir(appPath, [
+            libPubspec("test_pkg", "1.0.0", [
+              {'git': 'git://github.com/dart-lang/foo'}
+            ])
+          ]).scheduleCreate();
+
+          expectLater(schedulePackageValidation(dependency),
+              pairOf(isEmpty, someElement(contains(
+                  '  foo: ">=3.0.0-pre <4.0.0"'))));
+
+          run();
+        });
+
+        test("and should suggest a tighter constraint if the primary version "
+            "is pre-1.0.0", () {
+          useMockClient(new MockClient((request) {
+            expect(request.method, equals("GET"));
+            expect(request.url.path, equals("/packages/foo.json"));
+
+            return new Future.immediate(new http.Response(JSON.stringify({
+              "name": "foo",
+              "uploaders": ["nweiz@google.com"],
+              "versions": ["0.0.1", "0.0.2"]
+            }), 200));
+          }));
+
+          dir(appPath, [
+            libPubspec("test_pkg", "1.0.0", [
+              {'git': 'git://github.com/dart-lang/foo'}
+            ])
+          ]).scheduleCreate();
+
+          expectLater(schedulePackageValidation(dependency),
+              pairOf(isEmpty, someElement(contains(
+                  '  foo: ">=0.0.2 <0.0.3"'))));
+
+          run();
+        });
+      });
+
+      group('where no hosted version of that dependency exists', () {
+        test("and should use the other source's version", () {
+          useMockClient(new MockClient((request) {
+            expect(request.method, equals("GET"));
+            expect(request.url.path, equals("/packages/foo.json"));
+
+            return new Future.immediate(new http.Response("not found", 404));
+          }));
+
+          dir(appPath, [
+            libPubspec("test_pkg", "1.0.0", [
+              {
+                'git': {'url': 'git://github.com/dart-lang/foo'},
+                'version': '>=1.0.0 <2.0.0'
+              }
+            ])
+          ]).scheduleCreate();
+
+          expectLater(schedulePackageValidation(dependency),
+              pairOf(isEmpty, someElement(contains(
+                  '  foo: ">=1.0.0 <2.0.0"'))));
+
+          run();
+        });
+
+        test("and should use the other source's unquoted version if it's "
+            "concrete", () {
+          useMockClient(new MockClient((request) {
+            expect(request.method, equals("GET"));
+            expect(request.url.path, equals("/packages/foo.json"));
+
+            return new Future.immediate(new http.Response("not found", 404));
+          }));
+
+          dir(appPath, [
+            libPubspec("test_pkg", "1.0.0", [
+              {
+                'git': {'url': 'git://github.com/dart-lang/foo'},
+                'version': '0.2.3'
+              }
+            ])
+          ]).scheduleCreate();
+
+          expectLater(schedulePackageValidation(dependency),
+              pairOf(isEmpty, someElement(contains('  foo: 0.2.3'))));
+
+          run();
+        });
+      });
+    });
+
+    group('has an unconstrained dependency', () {
+      group('and it should not suggest a version', () {
+        test("if there's no lockfile", () {
+          dir(appPath, [
+            libPubspec("test_pkg", "1.0.0", [
+              {'hosted': 'foo'}
+            ])
+          ]).scheduleCreate();
+
+          expectLater(schedulePackageValidation(dependency),
+              pairOf(isEmpty, everyElement(isNot(contains("\n  foo:")))));
+
+          run();
+        });
+
+        test("if the lockfile doesn't have an entry for the dependency", () {
+          dir(appPath, [
+            libPubspec("test_pkg", "1.0.0", [
+              {'hosted': 'foo'}
+            ]),
+            file("pubspec.lock", JSON.stringify({
+              'packages': {
+                'bar': {
+                  'version': '1.2.3',
+                  'source': 'hosted',
+                  'description': {
+                    'name': 'bar',
+                    'url': 'http://pub.dartlang.org'
+                  }
+                }
+              }
+            }))
+          ]).scheduleCreate();
+
+          expectLater(schedulePackageValidation(dependency),
+              pairOf(isEmpty, everyElement(isNot(contains("\n  foo:")))));
+
+          run();
+        });
+      });
+
+      group('with a lockfile', () {
+        test('and it should suggest a constraint based on the locked '
+            'version', () {
+          dir(appPath, [
+            libPubspec("test_pkg", "1.0.0", [
+              {'hosted': 'foo'}
+            ]),
+            file("pubspec.lock", JSON.stringify({
+              'packages': {
+                'foo': {
+                  'version': '1.2.3',
+                  'source': 'hosted',
+                  'description': {
+                    'name': 'foo',
+                    'url': 'http://pub.dartlang.org'
+                  }
+                }
+              }
+            }))
+          ]).scheduleCreate();
+
+          expectLater(schedulePackageValidation(dependency),
+              pairOf(isEmpty, someElement(contains(
+                  '  foo: ">=1.2.3 <2.0.0"'))));
+
+          run();
+        });
+
+        test('and it should suggest a concrete constraint if the locked '
+            'version is pre-1.0.0', () {
+          dir(appPath, [
+            libPubspec("test_pkg", "1.0.0", [
+              {'hosted': 'foo'}
+            ]),
+            file("pubspec.lock", JSON.stringify({
+              'packages': {
+                'foo': {
+                  'version': '0.1.2',
+                  'source': 'hosted',
+                  'description': {
+                    'name': 'foo',
+                    'url': 'http://pub.dartlang.org'
+                  }
+                }
+              }
+            }))
+          ]).scheduleCreate();
+
+          expectLater(schedulePackageValidation(dependency),
+              pairOf(isEmpty, someElement(contains(
+                  '  foo: ">=0.1.2 <0.1.3"'))));
+
+          run();
+        });
+      });
+    });
+
+    test('has a hosted dependency on itself', () {
+      dir(appPath, [
+        libPubspec("test_pkg", "1.0.0", [
+          {'hosted': {'name': 'test_pkg', 'version': '>=1.0.0'}}
+        ])
+      ]).scheduleCreate();
+
+      expectValidationWarning(dependency);
+
+      run();
+    });
+
+    group('has a top-level directory named', () {
+      setUp(scheduleNormalPackage);
+
+      var names = ["tools", "tests", "docs", "examples", "sample", "samples"];
+      for (var name in names) {
+        test('"$name"', () {
+          dir(appPath, [dir(name)]).scheduleCreate();
+          expectValidationWarning(directory);
+          run();
+        });
+      }
+    });
   });
 }